LDA线性判别分析Python程序

本文介绍了如何使用Python实现LDA线性判别分析,包括数据标准化、类内散度矩阵和类间散度矩阵的计算,以及特征向量的选择。通过对比 sklearn 中 LDA 的降维结果,探讨了不同实现方式的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

理论讲解

需要导入的包

# -*- coding: utf-8 -*-
import numpy as np 
import csv
from matplotlib import pyplot as plt
import math

导入数据集

def read_iris():
    from sklearn.datasets import load_iris
    from sklearn import preprocessing
    data_set = load_iris()
    data_x = data_set.data 
    label = data_set.target + 1
    #preprocessing.scale(data_x, axis=0, with_mean=True, with_std=True, copy=False) 
    return data_x,label

iris数据集
有三类,4个特征
初始类标签是从0开始的,加一后从1开始。
preprocessing.scale(data_x, axis=0, with_mean=True, with_std=True, copy=False)
是对数据进行标准化


    # 特征均值,计算每类的均值,返回一个向量
def class_mean(data,label,clusters):
    mean_vectors = [] 
    for cl in range(1,clusters+1):
        mean_vectors.append(np.mean(data[label==cl,],axis=0))
    #print mean_vectors
    return mean_vectors

输入特征数据集,类标签,类别个数
计算每类数据的均值
用于计算散度矩阵

    # 计算类内散度
def within_class_SW(data,label,clusters):
    m = data.shape[1]
    S_W = np.zeros((m,m))
    mean_vectors = class_mean(data,label,clusters)
    for cl ,mv in zip(range(1,clusters+1),mean_vectors):
        class_sc_mat = np.zeros((m,m))
        # 对每个样本数据进行矩阵乘法 
        for row  in data[label == cl]:
            row ,mv =row.reshape(4,1),mv.reshape(4,1)
            class_sc_mat += (row-mv).dot((row-mv).T)
        S_W +=class_sc_mat
    #print S_W 
    return S_W

计算类内散度,散度矩阵式 mm 的对称矩阵, m 是特征(属性)的个数
首先计算类内均值
对每一类中的每条数据减去均值进行矩阵乘法(列向量乘以行向量,所得的矩阵秩为1,线代中讲过 )
相加,就是类内散度矩阵


def between_class_SB(data,label,clusters):
    m = data.shape[1]
    all_mean =np.mean(data,axis = 0)
    S_B = np.zeros((m,m))
    mean_vectors = class_mean(data,label,clusters)
    for cl ,mean_vec in enumerate(mean_vectors):
        n = data[label==cl+1,:].shape[0]
        mean_vec = mean_vec.reshape(4,1) # make column vector
        all_mean = all_mean.reshape(4,1)# make column vector
        S_B += n * (mean_vec - all_mean).dot((mean_vec - all_mean).T)
    #print S_B 
    return S_B

计算类间散度矩阵,这里某一类的特征用改类的均值向量体现。
C个秩为1的矩阵的和,数据集中心是整体数据的中心,S_B是秩为C-1

def lda():
    data,label=read_iris();
    clusters = 3
    S_W = within_class_SW(data,label,clusters)
    S_B = between_class_SB(data,label,clusters)
    eig_vals, eig_vecs = np.linalg.eig(np.linalg.inv(S_W).dot(S_B))
    #print S_W 
    #print S_B 
    for i in range(len(eig_vals)):
        eigvec_sc = eig_vecs[:,i].reshape(4,1)
        print('\nEigenvector {}: \n{}'.format(i+1, eigvec_sc.real))
        print('Eigenvalue {:}: {:.2e}'.format(i+1, eig_vals[i].real))
    eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i]) for i in range(len(eig_vals))]
    eig_pairs = sorted(eig_pairs, key=lambda k: k[0], reverse=True)
    W = np.hstack((eig_pairs[0][1].reshape(4,1), eig_pairs[1][1].reshape(4,1)))
    print 'Matrix W:\n', W.real
        print data.dot(W)
    return W 

类内散度矩阵 S

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值