運用sklearn進行主成分分析(PCA)程式碼實現

Charzueus發表於2020-08-12

運用sklearn進行主成分分析(PCA)程式碼實現

  一、前言及回顧

  二、sklearn的PCA類介紹

  三、分類結果區域視覺化函式

  四、10行程式碼完成葡萄酒資料集分類

  五、完整程式碼

  六、總結

 


 

一、前言及回顧

從上一篇《PCA資料降維原理及python應用(葡萄酒案例分析)》,我們知道,主成分分析PCA是一種無監督資料壓縮技術,上一篇逐步自行寫程式碼能夠讓我更好地理解PCA內部實現機制,那知識熟悉以及技術成熟後我們可以運用什麼提高編碼效率?

答案就是:基於sklearn的主成分分析程式碼實現,使用PCA類進行無監督資料降維,仍然以葡萄酒資料集wine.data為案例,本文將運用sklearn封裝的PCA類來實現,提高編碼效率,而且會感覺十分簡單,前提需要學習理解PCA實現原理及步驟。

 這裡回顧:《PCA資料降維原理及python應用(葡萄酒案例分析)》

二、sklearn的PCA類介紹

sklearn中的PCA類相當於一個轉換器,首先用訓練資料來擬合模型,以葡萄酒資料集為例,通過邏輯迴歸轉化樣本資料,實現了主成分分析以及特徵提取,直接呼叫PCA類即可。

三、分類結果區域視覺化函式

為了在分類結果區別決策區域並視覺化表示,這裡編寫plot_decision_region函式。

def plot_decision_regions(x, y, classifier, resolution=0.02):
    markers = ['s', 'x', 'o', '^', 'v']
    colors = ['r', 'g', 'b', 'gray', 'cyan']
    cmap = ListedColormap(colors[:len(np.unique(y))])
 
    x1_min, x1_max = x[:, 0].min() - 1, x[:, 0].max() + 1
    x2_min, x2_max = x[:, 1].min() - 1, x[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))
    z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    z = z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, z, alpha=0.4, cmap=cmap)
 
    for idx, cc in enumerate(np.unique(y)):
        plt.scatter(x=x[y == cc, 0],
                    y=x[y == cc, 1],
                    alpha=0.6,
                    c=cmap(idx),
                    edgecolor='black',
                    marker=markers[idx],
                    label=cc)

四、10行程式碼完成葡萄酒資料集分類

10行感覺是否很簡單,確實關鍵步驟呼叫PCA類和plt畫圖總共10行。

程式碼如下:

pca = PCA(n_components=2) # 前兩個主成分
lr = LogisticRegression() # 邏輯迴歸來擬合模型
x_train_pca = pca.fit_transform(x_train_std)
x_test_pca = pca.fit_transform(x_test_std)
lr.fit(x_train_pca, y_train)
plot_decision_regions(x_train_pca, y_train, classifier=lr)
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.legend(loc='lower left')
plt.show()

這裡看出使用到的主成分也是前兩個,使用邏輯迴歸對訓練資料進行擬合,建立模型。

來看看結果就是這樣。訓練集上的分類效果還是很不錯,跟上次自己實現的PCA幾乎一樣,這次加上了區域的邊界劃分,更加直觀!

測試集上呢?居然是這樣!

觀察一下,發現好像也不是分類錯誤,而是發生映象反轉了。造成這種差異的原因是,在測試集上的特徵向量正負方向問題,所以需要將測試資料乘以-1反轉映象,從而得到正確的影像。

上面測試資料的pca直接乘以-1,修改為:

x_test_pca = pca.fit_transform(x_test_std) * -1  # 預測時候特徵向量正負問題,乘-1反轉映象

這時候映象反轉就對了:看效果在測試集上的分類也不錯。

當然,資料載入以及標準化處理還是原來的方法。

# load data
df_wine = pd.read_csv('D:\\PyCharm_Project\\maching_learning\\wine_data\\wine.data', header=None)  # 本地載入
 
# split the data,train:test=7:3
x, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, stratify=y, random_state=0)
 
# standardize the feature 標準化單位方差
sc = StandardScaler()
x_train_std = sc.fit_transform(x_train)
x_test_std = sc.fit_transform(x_test)

五、完整程式碼

這裡完整給出程式碼,並實現訓練效果和測效果子圖的對比。

from sklearn.linear_model import LogisticRegression
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
 
 
def plot_decision_regions(x, y, classifier, resolution=0.02):
    markers = ['s', 'x', 'o', '^', 'v']
    colors = ['r', 'g', 'b', 'gray', 'cyan']
    cmap = ListedColormap(colors[:len(np.unique(y))])
 
    x1_min, x1_max = x[:, 0].min() - 1, x[:, 0].max() + 1
    x2_min, x2_max = x[:, 1].min() - 1, x[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))
    z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    z = z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, z, alpha=0.4, cmap=cmap)
 
    for idx, cc in enumerate(np.unique(y)):
        plt.scatter(x=x[y == cc, 0],
                    y=x[y == cc, 1],
                    alpha=0.6,
                    c=cmap(idx),
                    edgecolor='black',
                    marker=markers[idx],
                    label=cc)
 
 
def main():
    # load data
    # df_wine = pd.read_csv('D:\\PyCharm_Project\\maching_learning\\wine_data\\wine.data', header=None)  # 本地載入
    df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data',
                          header=None)  # 伺服器載入
 
    # split the data,train:test=7:3
    x, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, stratify=y, random_state=0)
 
    # standardize the feature 標準化單位方差
    sc = StandardScaler()
    x_train_std = sc.fit_transform(x_train)
    x_test_std = sc.fit_transform(x_test)
 
    pca = PCA(n_components=2)
    lr = LogisticRegression()
    x_train_pca = pca.fit_transform(x_train_std)
    x_test_pca = pca.fit_transform(x_test_std) * -1  # 預測時候特徵向量正負問題,乘-1反轉映象
    lr.fit(x_train_pca, y_train)
    plt.figure(figsize=(6, 7), dpi=100)  # 畫圖高寬,畫素
    plt.subplot(2, 1, 1)
    plot_decision_regions(x_train_pca, y_train, classifier=lr)
    plt.title('Training Result')
    plt.xlabel('PC1')
    plt.ylabel('PC2')
    plt.legend(loc='lower left')
 
    plt.subplot(2, 1, 2)
    plot_decision_regions(x_test_pca, y_test, classifier=lr)
    plt.title('Testing Result')
    plt.xlabel('PC1')
    plt.ylabel('PC2')
    plt.legend(loc='lower left')
    plt.tight_layout()  # 子圖間距
    plt.show()
 
 
if __name__ == '__main__':
    main()

六、總結

這次學到了基於sklearn的主成分分析程式碼實現,使用PCA類進行無監督資料降維,明顯感受到編碼效率提高許多,而且會感覺十分簡單,前提需要學習理解PCA實現原理及步驟,接下來準備學習第二種降維技術LDA,大夥來一起學習,分享學習成果!

 

我的部落格園:https://www.cnblogs.com/chenzhenhong/p/13491526.html

我的CSDN:基於sklearn的主成分分析(PCA)程式碼實現


 

版權宣告:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。

 

本文連結:https://blog.csdn.net/Charzous/article/details/107958972

 

相關文章