数据集特征提取_基于PCA算法实现鸢尾花数据集的特征提取任务
PCA算法的必要性
多變量大數據集無疑會為研究和應用提供豐富的信息,但是許多變量之間可能存在相關性,從而增加了問題分析的復雜性。如果分別對每個指標進行分析,分析往往是孤立的,不能完全利用數據中的信息,因此盲目減少指標會損失很多有用的信息,從而產生錯誤的結論。
因此如果可以在減少需要分析的指標同時,盡量減少原指標包含信息的損失,那么將有利于算法模型的搭建。由于各變量之間存在一定的相關關系,因此可以考慮將關系緊密的變量變成盡可能少的新變量,使這些新變量是兩兩不相關的,那么就可以用較少的綜合指標分別代表存在于各個變量中的各類信息。PCA算法就屬于這類降維算法。
我們所使用的數據集
Iris 鳶尾花數據集是一個經典數據集,在統計學習和機器學習領域都經常被用作示例。數據集內包含 3 類共 150 條記錄,每類各 50 個數據,每條記錄都有 4 項特征:花萼長度、花萼寬度、花瓣長度、花瓣寬度。數據集的部分數據如下所示:
可以看出這個數據集中的數據分為5列,也就是5個特征,5個維度,這5個列分別是:鳶尾花的花萼長度、花萼寬度、花瓣長度、 花瓣寬度、以及花的類別。這樣的5個維度很難通過可視化的方式,所以下面我們將通過PCA算法來完成降維的操作,將5維數據將成2維。
數據的讀取
下面我們先讀取文件中的數據,并且為每列數據指定其列名,這樣更加的有利于查看我們讀取到數據。
import numpy as npimport pandas as pddf=pd.read_csv('iris.data')df.columns=['sepal_len','sepal_wid','petal_len','petal_wid','class']print(df.hean())部分數據
可視化
可視化代碼
可視化效果
數據的處理
下面我們對數據進行處理,也就是標準化我們的數據集,將數據屬性(按列進行)減去其均值,并除以其方差。得到的結果是,對于每個屬性/每列來說所有數據都聚集在0附近,方差為1
標準化
標準化完成之后,我們下面的任務是求出協方差矩陣,我們最終算出來的協方差矩陣中的每一個元素表示特征i和特征j之間的之間的協方差,協方差可以理解為兩個特征之間的相關性,如果值為正就表示正相關,越大越正相關,如果值為負就表示負相關,越小就表示越負相關,如果值為0就表示不相關。下面我們求出這個樣本的協方差矩陣。協方差矩陣的對角線為1,也就是自身和自身的相關系數都是1。
均值
然后使用協方差矩陣公式求出這個數據集的協方差矩陣。這個公式是我們自己寫的,實際上在python中已經封裝了這種類似的方法
協方差
使用np.cov傳遞過去數據集,就可以直接獲取到這個數據集中的協方差,我們傳遞的參數要是X_std的轉值值,轉置完成之后我們獲取到的新矩陣的每一行都是原矩陣中的每一列,也就是說現在的矩陣中的有四行,每一行為數據集中特征的所有數據。
求解特征向量和特征值
我們再來回顧一下我們的任務,我們這個數據集X是150*4的,我們的任務是將其變為150*2的,也就是將成兩維,那么可以通過150*4*[4*2]=150*2來完成,所以我們下面的任務是如何構建出到這個[4*2]矩陣呢?
特征值和特征向量
我們使用已經封裝好的np.linalg.eig方法來獲取到了協方差矩陣的特征值和特征向量,一個特征值對應一個特征向量,所以四個特征值對應四個特征向量,也就是說特征值2.92442837,而這個特征值所對應的特征向量就是[ 0.52308496, -0.25956935, 0.58184289, 0.56609604]特征向量矩陣豎著看,每一列是一個特征矩陣,我們現在的任務是在這四個特征向量中選出兩個特征向量(最具代表性的),我們的選擇方案是:特征值越大對應的特征向量越重要。
我們第一步是將封裝成一個列表,列表中的元素是元組,元組為(特征值,特征值所對的特征向量)然后按照特征值進行排序,排序的結果不僅是特征值的排序結果,同時也是特征向量的排序結果排序完成之后就是eig_pairs
eig_pairs[0]為(2.9244283691111144, array([ 0.52308496, -0.25956935, 0.58184289, 0.56609604]))eig_pairs[1]為(0.9321523302535064, array([-0.36956962, -0.92681168, -0.01912775, -0.06381646]))eig_pairs[0][1]為array([ 0.52308496, -0.25956935, 0.58184289, 0.56609604])eig_pairs[1][1]為array([-0.36956962, -0.92681168, -0.01912775, -0.06381646])所以此時我們獲取到的eig_pairs[0][1]和eig_pairs[1][1]就是我們想要獲取到的特征向量,此時我們將其轉成4*1,然后兩個結合到一起就是我們想要的4*2矩陣了。
接下來我們要使用原始數據集矩陣乘以這個4*2矩陣,就是我們想要的降維之后的矩陣Y了。
當我們獲取到Y的時候我們的PCA降維就完成了,我們的成功的將原來的數據集降成了兩個維度的數據集。
代碼實現
import numpy as npimport pandas as pdfrom matplotlib import pyplot as pltimport mathfrom sklearn.preprocessing import StandardScalerdf = pd.read_csv('iris.data')df.columns=['sepal_len', 'sepal_wid', 'petal_len', 'petal_wid', 'class']X = df.ix[:,0:4].valuesy = df.ix[:,4].valuesX_std = StandardScaler().fit_transform(X)mean_vec = np.mean(X_std, axis=0)cov_mat = np.cov(X_std.T)eig_vals, eig_vecs = np.linalg.eig(cov_mat)#創建一個(特征值,特征向量)元組列表eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i]) for i in range(len(eig_vals))]print eig_pairs#特征向量從高到低排序eig_pairs.sort(key=lambda x: x[0], reverse=True)matrix_w = np.hstack((eig_pairs[0][1].reshape(4,1), eig_pairs[1][1].reshape(4,1)))Y = X_std.dot(matrix_w)print Y特征的可視化
每個子圖分別是每個特征在不同類型鳶尾花的情況
代碼實現:
label_dict = {1: 'Iris-Setosa', 2: 'Iris-Versicolor', 3: 'Iris-Virgnica'}feature_dict = {0: 'sepal length [cm]', 1: 'sepal width [cm]', 2: 'petal length [cm]', 3: 'petal width [cm]'}plt.figure(figsize=(8, 6))for cnt in range(4): plt.subplot(2, 2, cnt+1) for lab in ('Iris-setosa', 'Iris-versicolor', 'Iris-virginica'): print cnt print y==lab print(X[y==lab, cnt]) print lab plt.hist(X[y==lab, cnt], label=lab, bins=10, alpha=0.3,) plt.xlabel(feature_dict[cnt]) plt.legend(loc='upper right', fancybox=True, fontsize=8)plt.tight_layout()plt.show()尋找最優特征
我們剛才要找到兩個特征值中特征值最大的那兩個特征,我們前面的方案是排序sort的方式,如果從可視化的角度,為了讓大家可以通過看圖一眼就看出究竟哪幾個的特征最大,我們可以使用如下這種方式:
選取特征最大
該圖有兩個,一個柱狀圖,一個折線圖,柱狀圖為特征值,折線圖中可以看出是逐漸增加的,這個折線圖是這樣的折線折線圖的第一部分是第一個特征值,第二部分是第一個特征值+第二個特征值,第三部分是第一個特征值+第二個特征值+第三個特征值,第四部分是第三部分是第一個特征值+第二個特征值+第三個特征值++第四個特征值,這樣我們就可以看哪哪一部分變化特別大了,就表示這這特征值大,這個特征值就是我們所需要的。
代碼實現
tot = sum(eig_vals)#計算特征值和var_exp = [(i / tot) * 100 for i in sorted(eig_vals, reverse=True)]cum_var_exp = np.cumsum(var_exp)#逐漸累加plt.figure(figsize=(6, 4))#畫圖,柱狀圖是var_exp,折線圖是cum_var_expplt.bar(range(4), var_exp, alpha=0.5, align='center', label='individual explained variance')plt.step(range(4), cum_var_exp, where='mid', label='cumulative explained variance')plt.ylabel('Explained variance ratio')plt.xlabel('Principal components')plt.legend(loc='best')plt.tight_layout()plt.show()降維之后的效果
這個橫軸表示特征sepal_len,縱軸表示sepal_wid,其中有三個顏色,每個顏色表示鳶尾花的類別,實現的代碼為
plt.figure(figsize=(6, 4))for lab, col in zip(('Iris-setosa', 'Iris-versicolor', 'Iris-virginica'),('blue', 'red', 'green')): plt.scatter(X[y==lab, 0], X[y==lab, 1], label=lab, c=col)plt.xlabel('sepal_len')plt.ylabel('sepal_wid')plt.legend(loc='best')plt.tight_layout()plt.show()上面我們只用了兩個特征,可以看出紅的和綠的分的不是很開,因為我們已經降維了Y,所以我們可以使用已經降維的數據來畫圖,效果為:
這樣降維之后的數據畫圖,可以看出藍色和綠色很是清晰。實現的代碼為
Y = X_std.dot(matrix_w)plt.figure(figsize=(6, 4))for lab, col in zip(('Iris-setosa', 'Iris-versicolor', 'Iris-virginica'), ('blue', 'red', 'green')): plt.scatter(Y[y==lab, 0], Y[y==lab, 1], label=lab, c=col)plt.xlabel('Principal Component 1')plt.ylabel('Principal Component 2')plt.legend(loc='lower center')plt.tight_layout()plt.show()總結
以上是生活随笔為你收集整理的数据集特征提取_基于PCA算法实现鸢尾花数据集的特征提取任务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内部矩阵维度必须一致simulink_简
- 下一篇: 怎么知道电脑是32位还是64位_vnc