Home >> Blog >> 使用 Python PCA (scikit-learn)

使用 Python PCA (scikit-learn)

在之前的SEO搜尋引擎優化教學中介紹了使用 Python 的邏輯回歸。學到的一件事是,您可以通過更改優化算法來加速機器學習算法的擬合。加速機器學習算法的一種更常見的方法是使用主成分分析 (PCA)。如果你的學習算法因為輸入維度太高而太慢,那麼使用 PCA 來加速它可能是一個合理的選擇。這可能是 PCA 最常見的應用。PCA 的另一個常見應用是數據可視化。

為了了解使用 PCA 進行數據可視化的價值,本教學的第一部分將介紹應用 PCA 後 IRIS 數據集的基本可視化。第二部分使用 PCA 在 MNIST 數據集上加速機器學習算法(邏輯回歸)。

讓我們開始吧!

本教學中使用的程式碼如下

用於數據可視化的 PCA

PCA 加速機器學習算法

用於數據可視化的 PCA

對於許多機器學習應用程式來說,能夠可視化您的數據會有所幫助。可視化 2 或 3 維數據並不是那麼具有挑戰性。然而,即使是本教學這一部分中使用的 Iris 數據集也是 4 維的。您可以使用 PCA 將 4 維數據減少為 2 或 3 維,以便您可以繪製並希望更好地理解數據。

加載虹膜數據集

Iris 數據集是 scikit-learn 附帶的數據集之一,不需要從某些外部網站下載任何文件。下面的程式碼將加載 iris 數據集。

將熊貓導入為 pd
url = " https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data "
# 將數據集加載到 Pandas DataFrame
df = pd.read_csv(url, names=['sepal length','sepal width','petal length','petal width','target'])

使用 Python 的 PCA (scikit-learn)

標準化數據

PCA 受比例影響,因此您需要在應用 PCA 之前對數據中的特徵進行比例縮放。使用StandardScaler可幫助您將數據集的特徵標準化為單位尺度(均值 = 0 和方差 = 1),這是許多機器學習算法的最佳性能的要求。如果您想查看不縮放數據可能產生的負面影響,scikit-learn 有一個關於不標準化數據的影響的部分。

從 sklearn.preprocessing 導入 StandardScaler
特徵= ['萼片長度','萼片寬度','花瓣長度','花瓣寬度']
# 分離出特徵
x = df.loc[:, features].values
# 分離出目標
y = df.loc[:,['target']].values
# 標準化特徵
x = StandardScaler().fit_transform(x)

使用 Python 的 PCA (scikit-learn)

PCA 投影到 2D

原始數據有 4 列(萼片長度、萼片寬度、花瓣長度和花瓣寬度)。在本節中,程式碼將 4 維的原始數據投影為 2 維。我應該注意到,在降維之後,通常沒有為每個主成分分配特定的含義。新組件只是變化的兩個主要維度。

從 sklearn.decomposition 導入 PCA
pca = PCA(n_components=2)
principalComponents = pca.fit_transform(x)
principalDf = pd.DataFrame(data = principalComponents
, columns = ['主成分 1', '主成分 2'])

使用 Python 的 PCA (scikit-learn)

finalDf = pd.concat([principalDf, df[['target']]], axis = 1)

沿軸 = 1 連接 DataFrame。finalDf 是繪製數據之前的最終 DataFrame。

使用 Python 的 PCA (scikit-learn)

可視化 2D 投影

本節只是繪製二維數據。請注意,在下圖中,這些類似乎彼此分離得很好。

p style="padding: 10px; border: 1px solid gray;">fig = plt.figure(figsize = (8,8))
ax = fig.add_subplot(1,1,1)
ax.set_xlabel('Principal Component 1', fontsize = 15)
ax.set_ylabel('Principal Component 2', fontsize = 15)
ax.set_title('2 分量 PCA', fontsize = 20)
目標 = ['Iris-setosa', 'Iris-versicolor', 'Iris-virginica']
顏色 = ['r', 'g', 'b']
用於目標,zip 中的顏色(目標,顏色):
indicesToKeep = finalDf['target'] == target
ax.scatter(finalDf.loc[indicesToKeep, '主成分 1']
, finalDf.loc[indicesToKeep, '主成分 2']
, c = color
, s = 50)
ax.legend (目標)
ax.grid()

使用 Python 的 PCA (scikit-learn)

解釋方差

解釋的方差告訴您可以將多少信息(方差)歸因於每個主成分。這很重要,因為雖然您可以將 4 維空間轉換為 2 維空間,但這樣做會丟失一些方差(信息)。通過使用屬性explain_variance_ratio_,您可以看到第一個主成分包含 72.77% 的方差,第二個主成分包含 23.03% 的方差。這兩個組件一起包含 95.80% 的信息。

pca.explained_variance_ratio_

PCA 加速機器學習算法

雖然還有其他方法可以加速機器學習算法,但一種鮮為人知的方法是使用 PCA。在本節中,我們不使用 IRIS 數據集,因為該數據集只有 150 行和 4 個特徵列。手寫數字的 MNIST 數據庫更合適,因為它有 784 個特徵列(784 個維度)、一個包含 60,000 個示例的訓練集和一個包含 10,000 個示例的測試集。

下載和加載數據

您還可以將data_home 參數添加到fetch_mldata以更改下載數據的位置。

從 sklearn.datasets 導入 fetch_openml
mnist = fetch_openml('mnist_784')

您下載的圖像包含在mnist.data中,形狀為 (70000, 784),這意味著有 70,000 張圖像,具有 784 個維度(784 個特徵)。

標籤(整數 0-9)包含在mnist.target中。特徵是 784 維(28 x 28 圖像),標籤只是從 0 到 9 的數字。

將數據拆分為訓練集和測試集

下面的程式碼執行訓練測試拆分,將 6/7 的數據放入訓練集,將 1/7 的數據放入測試集。

從 sklearn.model_selection 導入 train_test_split
# test_size:測試集使用原始數據的比例
train_img, test_img, train_lbl, test_lbl = train_test_split(mnist.data, mnist.target, test_size=1/7.0, random_state=0)

標準化數據

這一段中的文字幾乎是之前所寫內容的精確副本。PCA 受比例影響,因此您需要在應用 PCA 之前對數據中的特徵進行比例縮放。您可以將數據轉換為單位規模(均值 = 0 和方差 = 1),這是許多機器學習算法的最佳性能的要求。StandardScaler有助於標準化數據集的特徵。請注意,您適合訓練集並在訓練集和測試集上進行轉換。如果您想查看不縮放數據可能產生的負面影響,scikit-learn 有一個關於不標準化數據的影響的部分。

從 sklearn.preprocessing 導入 StandardScaler
scaler = StandardScaler()
# 僅適合訓練集。
scaler.fit(train_img)
# 將變換應用於訓練集和測試集。
train_img = scaler.transform(train_img)
test_img = scaler.transform(test_img)

導入和應用 PCA

請注意,下面的程式碼中的組件數參數為 0.95。這意味著 scikit-learn 選擇最小數量的主成分,以便保留 95% 的方差。

從 sklearn.decomposition 導入 PCA
# 創建模型實例
pca = PCA(.95)

在訓練集上擬合 PCA。注意:您僅在訓練集上擬合 PCA。

pca.fit(train_img)

注意:您可以在使用pca.n_components_擬合模型後找出 PCA 選擇了多少組件。在這種情況下,95% 的方差相當於 330 個主成分。

將映射(變換)應用於訓練集和測試集。

train_img = pca.transform(train_img)
test_img = pca.transform(test_img)

將邏輯回歸應用於轉換後的數據

第 1 步:導入您要使用的模型

在 sklearn 中,所有機器學習模型都實現為 Python 類

從 sklearn.linear_model 導入 LogisticRegression

第 2 步:創建模型的實例。

# 所有未指定的參數都設置為默認值
# 默認求解器非常慢,這就是為什麼它被更改為 'lbfgs'logisticRegr
= LogisticRegression(solver = 'lbfgs')

第 3 步:在數據上訓練模型,存儲從數據中學到的信息

模型正在學習數字和標籤之間的關係

物流Regr.fit(train_img,train_lbl)

第 4 步:預測新數據(新圖像)的標籤

使用模型在模型訓練過程中學到的信息

下面的程式碼預測一個觀察結果

# 預測一次觀察(圖像)
logisticRegr.predict(test_img[0].reshape(1,-1))

下面的程式碼一次預測多個觀察結果

# 預測一次觀察(圖像)
logisticRegr.predict(test_img[0:10])

測量模型性能

雖然準確率並不總是機器學習算法的最佳指標(準確率、召回率、F1 分數、ROC 曲線等會更好),但為了簡單起見,這裡使用它。

logisticRegr.score(test_img, test_lbl)

PCA後擬合Logistic回歸的時機

本教學這一部分的重點是展示您可以使用 PCA 來加速機器學習算法的擬合。下表顯示了使用 PCA 後在我的 MacBook 上擬合邏輯回歸需要多長時間(每次保留不同數量的方差)。

使用 Python 的 PCA (scikit-learn)

從壓縮表示重建圖像

本教學的前面部分已經演示了使用 PCA 將高維數據壓縮為低維數據。我想簡單提一下,PCA 還可以將數據(低維數據)的壓縮表示恢復為原始高維數據的近似值。

使用 Python 的 PCA (scikit-learn)

結束的想法

由於 PCA 有許多不同的用途,希望這篇文章對你正在做的任何事情都有幫助。下一個機器學習教學將介紹如何加速 Scikit-Learn 模型訓練。如果您對本教學有任何問題或想法,請隨時在Line中與我們聯繫。