降維
降維
機器學習領域中所謂的降維就是指採用某種對映方法,將原高維空間中的資料點對映到低維度的空間中。降維的本質是學習一個對映函式 f : x->y,其中x是原始資料點的表達,目前最多使用向量表達形式。 y是資料點對映後的低維向量表達,通常y的維度小於x的維度(當然提高維度也是可以的)。
降維有什麼作用呢?
- 資料在低維下更容易處理、更容易使用;
- 相關特徵,特別是重要特徵更能在資料中明確的顯示出來;如果只有兩維或者三維的話,更便於視覺化展示;
- 去除資料噪聲
- 降低演算法開銷
PCA
PCA是不考慮樣本類別輸出的無監督降維技術。
總結一下PCA的演算法步驟:
設有m條n維資料。
1)將原始資料按列組成n行m列矩陣X
2)將X的每一行(代表一個屬性欄位)進行零均值化,即減去這一行的均值
3)求出協方差矩陣
4)求出協方差矩陣的特徵值及對應的特徵向量
5)將特徵向量按對應特徵值大小從上到下按行排列成矩陣,取前k行組成矩陣P
6)即為降維到k維後的資料
例項分析(以二維特徵舉例):
現在假設有一組資料如下:
行代表了樣例,列代表特徵,這裡有10個樣例,每個樣例兩個特徵。
第一步,分別求x和y的平均值,然後對於所有的樣例,都減去對應的均值。這裡x的均值是1.81,y的均值是1.91,得到
第二步,求特徵協方差矩陣,如果資料是3維,那麼協方差矩陣是
因為這裡只有x和y,所以協方差矩陣為
對角線上分別是x和y的方差,非對角線上是協方差。協方差是衡量兩個變數同時變化的變化程度。協方差大於0表示x和y若一個增,另一個也增;小於0表示一個增,一個減。如果x和y是統計獨立的,那麼二者之間的協方差就是0;但是協方差是0,並不能說明x和y是獨立的。協方差絕對值越大,兩者對彼此的影響越大,反之越小。協方差是沒有單位的量,因此,如果同樣的兩個變數所採用的量綱發生變化,它們的協方差也會產生樹枝上的變化。
第三步,求協方差的特徵值和特徵向量,得到
上面是兩個特徵值,下面是對應的特徵向量,這裡的特徵向量都歸一化為單位向量。
第四步,將特徵值按照從大到小的順序排序,選擇其中最大的k個,然後將其對應的k個特徵向量分別作為列向量組成特徵向量矩陣。
這裡特徵值只有兩個,我們選擇其中最大的那個,這裡是1.28402771,對應的特徵向量是(-0.677873399, -0.735178656)T。
第五步,將樣本點投影到選取的特徵向量上。
得到的結果是
* (-0.677873399, -0.735178656)T=
這樣,就將原始樣例的n維特徵變成了k維,這k維就是原始特徵在k維上的投影。
程式碼實現:
from sklearn.decomposition import PCA import numpy as np from sklearn.preprocessing import StandardScaler x=np.array([[10001,2,55], [16020,4,11], [12008,6,33], [13131,8,22]]) X_scaler = StandardScaler() x = X_scaler.fit_transform(x) pca = PCA(n_components=2) pca.fit(x) Z=pca.transform(x)
LDA
LDA是一種監督學習的降維技術,也就是說它的資料集的每個樣本是有類別輸出的。這點和PCA不同。LDA的思想可以用一句話概括,就是“投影后類內方差最小,類間方差最大”。什麼意思呢? 我們要將資料在低維度上進行投影,投影后希望每一種類別資料的投影點儘可能的接近,而不同類別的資料的類別中心之間的距離儘可能的大。
LDA演算法步驟:
1) 計算類內散度矩陣
2) 計算類間散度矩陣
3) 計算矩陣
4)計算的最大的d個特徵值和對應的d個特徵向量,得到投影矩陣 [Math Processing Error] W
5) 對樣本集中的每一個樣本特徵,轉化為新的樣本
6) 得到輸出樣本集
部分程式碼實現:
# -*- coding: utf-8 -*- """ Created on Fri Dec1 10:49:37 2017 LDA_learning @author: BruceWong """ import pandas as pd import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn import datasets from sklearn.discriminant_analysis import LinearDiscriminantAnalysis import numpy as np def main(): iris = datasets.load_iris() #典型分類資料模型 #這裡我們資料統一用pandas處理 data = pd.DataFrame(iris.data, columns=iris.feature_names) data['class'] = iris.target #這裡只取兩類 #data = data[data['class']!=2] #為了視覺化方便,這裡取兩個屬性為例 X = data[data.columns.drop('class')] Y = data['class'] #劃分資料集 X_train, X_test, Y_train, Y_test =train_test_split(X, Y) lda = LinearDiscriminantAnalysis(n_components=2) lda.fit(X_train, Y_train) #顯示訓練結果 print(lda.means_) #中心點 print(lda.score(X_test, Y_test)) #score是指分類的正確率 print(lda.scalings_)#score是指分類的正確率 X_2d = lda.transform(X) #現在已經降到二維X_2d=np.dot(X-lda.xbar_,lda.scalings_) #對於二維資料,我們做個視覺化 #區域劃分 lda.fit(X_2d,Y) h = 0.02 x_min, x_max = X_2d[:, 0].min() - 1, X_2d[:, 0].max() + 1 y_min, y_max = X_2d[:, 1].min() - 1, X_2d[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) Z = lda.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.contourf(xx, yy, Z, cmap=plt.cm.Paired) #做出原來的散點圖 class1_x = X_2d[Y==0,0] class1_y = X_2d[Y==0,1] l1 = plt.scatter(class1_x,class1_y,color='b',label=iris.target_names[0]) class1_x = X_2d[Y==1,0] class1_y = X_2d[Y==1,1] l2 = plt.scatter(class1_x,class1_y,color='y',label=iris.target_names[1]) class1_x = X_2d[Y==2,0] class1_y = X_2d[Y==2,1] l3 = plt.scatter(class1_x,class1_y,color='r',label=iris.target_names[2]) plt.legend(handles = [l1, l2, l3], loc = 'best') plt.grid(True) plt.show() if __name__ == '__main__': main()
兩者對比
1、相同點
(1)兩者的作用是用來降維的
(2)兩者都假設符合高斯分佈
2、不同點
(1)LDA是有監督的降維方法,PCA是無監督的。
(2)LDA降維最多降到類別數K-1的維數,PCA沒有這個限制。
(3)LDA更依賴均值,如果樣本資訊更依賴方差的話,效果將沒有PCA好。
(4)LDA可能會過擬合數據。
參考部落格:https://blog.csdn.net/Chenzhi_2016/article/details/79451201