美文网首页
8.数据降维--LDA线性判别

8.数据降维--LDA线性判别

作者: 羽天驿 | 来源:发表于2020-04-06 16:09 被阅读0次

一、线性判别的原理

import warnings
warnings.filterwarnings('ignore')
import numpy as np

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

from sklearn import datasets
X,y = datasets.load_iris(True)
X[:5]
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2]])
# 矩阵运算,投影,原来的值,不同了呀
'''n_components : int, optional (default=None)
    Number of components (<= min(n_classes - 1, n_features)) for
    dimensionality reduction. If None, will be set to
    min(n_classes - 1, n_features).'''
# n_features = 4
# n_classes = 3
# <= min(3 - 1, 4) = 2)
lda = LinearDiscriminantAnalysis(solver= 'eigen',n_components=2)
lda.fit(X,y)
X_lda = lda.transform(X)
X_lda[:5]
array([[6.01716893, 7.03257409],
       [5.0745834 , 5.9344564 ],
       [5.43939015, 6.46102462],
       [4.75589325, 6.05166375],
       [6.08839432, 7.24878907]])

自己手动计算

第一步计算总的散度矩阵,协方差 St :scatter total


St = np.cov(X,rowvar=False,bias = True)
St
array([[ 0.68112222, -0.04215111,  1.26582   ,  0.51282889],
       [-0.04215111,  0.18871289, -0.32745867, -0.12082844],
       [ 1.26582   , -0.32745867,  3.09550267,  1.286972  ],
       [ 0.51282889, -0.12082844,  1.286972  ,  0.57713289]])

第二步 计算类内的散度矩阵Sw :scatter within


Sw = np.zeros(shape = (4,4))
for i in range(3):
    index = y == i
    Sw += np.cov(X[index],rowvar=False,bias = True)/3 # 一类数据
Sw
array([[0.259708  , 0.09086667, 0.164164  , 0.03763333],
       [0.09086667, 0.11308   , 0.05413867, 0.032056  ],
       [0.164164  , 0.05413867, 0.181484  , 0.041812  ],
       [0.03763333, 0.032056  , 0.041812  , 0.041044  ]])

第三步,计算类间的散度矩阵,Sb ,scatter between


Sb = St - Sw
Sb
array([[ 0.42141422, -0.13301778,  1.101656  ,  0.47519556],
       [-0.13301778,  0.07563289, -0.38159733, -0.15288444],
       [ 1.101656  , -0.38159733,  2.91401867,  1.24516   ],
       [ 0.47519556, -0.15288444,  1.24516   ,  0.53608889]])
# scipy 是高级的科学计算工具包,相对numpy来说,更多的,高级方法
from scipy import linalg

第四步,计算特征值和特征向量,考虑类间散度矩阵,类内的散度矩阵,排序

values,vectors = linalg.eigh(Sb,Sw)
vect =vectors[:,values.argsort()[::-1]]

第五步,筛选特征向量,进行矩阵运算

result = X.dot(vect[:,[0,1]])
result[:5]
array([[6.01716893, 7.03257409],
       [5.0745834 , 5.9344564 ],
       [5.43939015, 6.46102462],
       [4.75589325, 6.05166375],
       [6.08839432, 7.24878907]])
X_lda[:5]
array([[6.01716893, 7.03257409],
       [5.0745834 , 5.9344564 ],
       [5.43939015, 6.46102462],
       [4.75589325, 6.05166375],
       [6.08839432, 7.24878907]])

二、代码实例:

import warnings
warnings.filterwarnings('ignore')
import numpy as np
# LDA 线性判别
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.decomposition import PCA

from sklearn import datasets

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
# 上课示例代码,工作数据会复杂一些
# 官网提供,经典案例,学以致用!
X,y = datasets.load_iris(True)
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2,random_state = 512)

相通的

老师两种一种是:知识传播者

另一种老师:授人以渔

奇异值(非满秩矩阵),特征值(满秩矩阵),线性代数中概念

A = X - X.mean(axis = 0)
B = np.cov(A,rowvar=False)# B是一个方阵,四行四列
B
array([[ 0.68569351, -0.042434  ,  1.27431544,  0.51627069],
       [-0.042434  ,  0.18997942, -0.32965638, -0.12163937],
       [ 1.27431544, -0.32965638,  3.11627785,  1.2956094 ],
       [ 0.51627069, -0.12163937,  1.2956094 ,  0.58100626]])
# B 是一个方阵,4*4
# 矩阵有秩 = 4,满秩的
# B矩阵的秩 < 4 ,非满秩矩阵,奇异矩阵
np.linalg.matrix_rank(B)
4
# 矩阵C,奇异矩阵
C = np.array([[1,2,3,4],[2,4,6,8],[2,6,1,3],[-1,2,0,6]])
display(C)
np.linalg.matrix_rank(C) # 奇异矩阵
array([[ 1,  2,  3,  4],
       [ 2,  4,  6,  8],
       [ 2,  6,  1,  3],
       [-1,  2,  0,  6]])





3
#  x + y = 3
#  2x + y = 4
# x = 1 y = 2
X1 = np.array([[1,1],[2,1]])
np.linalg.matrix_rank(X1)#满秩矩阵,方程有解!!!唯一解!
2
# x+ y = 3
# 2x + 2y = 6
# x,y ?
X2 = np.array([[1,1],[2,2]])
np.linalg.matrix_rank(X2)#非满秩,方程无解(无穷多个解,无解)!!!奇异矩阵
1

对矩阵B(鸢尾花,属性协方差),特征值和特征向量以及SVD奇异值分解

B是满秩矩阵

# linalg ---->linear(线性) algebra(代数)
# 特征值
l,v = np.linalg.eig(B)
display(l,v)
array([4.22824171, 0.24267075, 0.0782095 , 0.02383509])



array([[ 0.36138659, -0.65658877, -0.58202985,  0.31548719],
       [-0.08452251, -0.73016143,  0.59791083, -0.3197231 ],
       [ 0.85667061,  0.17337266,  0.07623608, -0.47983899],
       [ 0.3582892 ,  0.07548102,  0.54583143,  0.75365743]])

验证特征值特征和特征向量

Av = \lambda v

B.dot(v)
array([[ 1.52802986, -0.15933489, -0.04552026,  0.00751967],
       [-0.35738162, -0.17718882,  0.04676231, -0.00762063],
       [ 3.62221038,  0.04207247,  0.00596239, -0.01143701],
       [ 1.51493333,  0.01831704,  0.0426892 ,  0.01796349]])
l[0]*(v[:,0])
array([ 1.52802986, -0.35738162,  3.62221038,  1.51493333])
l[1]*v[:,1]
array([-0.15933489, -0.17718882,  0.04207247,  0.01831704])
l[2]*v[:,2]
array([-0.04552026,  0.04676231,  0.00596239,  0.0426892 ])
l[3]*v[:,3]
array([ 0.00751967, -0.00762063, -0.01143701,  0.01796349])

验证奇异值分解

# X3不是方阵
X3  = np.random.randint(0,10,size = (3,5)) # X3.shape = m*n m = 3,n = 5
X3
array([[5, 6, 1, 3, 3],
       [8, 9, 4, 1, 8],
       [8, 8, 8, 6, 0]])
# 奇异值分解
U,sigma,V = np.linalg.svd(X3)
display(U,sigma,V)
array([[-0.394634  ,  0.14426999,  0.90744156],
       [-0.65332272,  0.65038133, -0.38752233],
       [-0.64609088, -0.74578167, -0.16240772]])



array([21.76187304,  7.3624042 ,  2.49316791])



array([[-0.56835544, -0.61651107, -0.37573291, -0.26255874, -0.29457408],
       [-0.00568467,  0.102249  , -0.43741935, -0.46065099,  0.76549187],
       [ 0.05525797,  0.26379556, -0.7788924 ,  0.54563353, -0.15155575],
       [ 0.13517964, -0.65062123,  0.09163103,  0.56508074,  0.48031863],
       [-0.80969921,  0.34141348,  0.228953  ,  0.31911029,  0.27124375]])

A = U\sum V

sigma2 = np.eye(N = 3,M = 5)
for i in range(3):
    sigma2[i,i] = sigma[i]
sigma2
array([[21.76187304,  0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  7.3624042 ,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  2.49316791,  0.        ,  0.        ]])
X3
array([[5, 6, 1, 3, 3],
       [8, 9, 4, 1, 8],
       [8, 8, 8, 6, 0]])
U.dot(sigma2).dot(V)
array([[ 5.00000000e+00,  6.00000000e+00,  1.00000000e+00,
         3.00000000e+00,  3.00000000e+00],
       [ 8.00000000e+00,  9.00000000e+00,  4.00000000e+00,
         1.00000000e+00,  8.00000000e+00],
       [ 8.00000000e+00,  8.00000000e+00,  8.00000000e+00,
         6.00000000e+00, -1.45763702e-15]])

使用LDA线性判别,进行数据的降维

lda = LinearDiscriminantAnalysis(solver='eigen', n_components = 2)
lda.fit(X_train,y_train)#有监督
X_train_lda = lda.transform(X_train)#训练数据
X_test_lda = lda.transform(X_test)
X_lda.shape
(150, 2)
knn = KNeighborsClassifier()
knn.fit(X_train_lda,y_train)
knn.score(X_test_lda,y_test)
0.9666666666666667
pca = PCA(n_components=2)
pca.fit(X_train)# 无监督学习,没有目标值y
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)
X_train_pca.shape
(120, 2)
knn = KNeighborsClassifier()
knn.fit(X_train_pca,y_train)
knn.score(X_test_pca,y_test)
0.9

相关文章

网友评论

      本文标题:8.数据降维--LDA线性判别

      本文链接:https://www.haomeiwen.com/subject/kaajphtx.html