92scikit-learn 機(jī)器學(xué)習(xí)入門實(shí)戰(zhàn)--PCA 主成分分析應(yīng)用

PCA 主成分分析應(yīng)用

主成分分析

主成分分析 是多元線性統(tǒng)計(jì)里面的概念,它的英文是 Principal Components Analysis,簡稱 PCA。主成分分析旨在降低數(shù)據(jù)的維數(shù),通過保留數(shù)據(jù)集中的主要成分來簡化數(shù)據(jù)集。簡化數(shù)據(jù)集在很多時(shí)候是非常必要的,因?yàn)閺?fù)雜往往就意味著計(jì)算資源的大量消耗。通過對數(shù)據(jù)進(jìn)行降維,我們就能在結(jié)果不受影響或受略微影響的同時(shí),減少模型學(xué)習(xí)時(shí)間。
特別強(qiáng)調(diào)的是,本次實(shí)驗(yàn)所說的降維,不是指降低 NumPy 數(shù)組的維度,而是特指減少樣本的特征數(shù)量。

image.png

上圖展示了把三維空間的數(shù)據(jù)降維到二維空間的過程。
下面,介紹一下 scikit-learn 中 PCA 方法的參數(shù)定義及簡單使用,這是完成 PCA 主成分分析的基礎(chǔ)。

sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False, svd_solver='auto')

其中:
n_components= 表示需要保留主成分(特征)的數(shù)量。
copy= 表示針對原始數(shù)據(jù)降維還是針對原始數(shù)據(jù)副本降維。當(dāng)參數(shù)為 False 時(shí),降維后的原始數(shù)據(jù)會(huì)發(fā)生改變,這里默認(rèn)為 True。
whiten= 白化表示將特征之間的相關(guān)性降低,并使得每個(gè)特征具有相同的方差。
svd_solver= 表示奇異值分解 SVD 的方法。有 4 個(gè)參數(shù),分別是:auto, full, arpack, randomized。

我們生成一個(gè)最容易可視化降維過程的二維數(shù)據(jù)集來看下:

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
%matplotlib inline

plt.style.use('seaborn')  # 樣式美化

# 當(dāng)我們設(shè)置相同的seed時(shí),每次生成的隨機(jī)數(shù)也相同,如果不設(shè)置seed,則每次生成的隨機(jī)數(shù)都會(huì)不一樣
np.random.seed(1)
X = np.dot(np.random.random(size=(2, 2)),
           np.random.normal(size=(2, 200))).T  # 生成二維數(shù)據(jù)
plt.plot(X[:, 0], X[:, 1], 'o')
plt.axis('equal')

我們可以看到數(shù)據(jù)有一個(gè)明確的趨勢。PCA 要做的就是在數(shù)據(jù)中找到主軸,并解釋這些軸在描述數(shù)據(jù)分布中的重要性:

# 導(dǎo)入 PCA 估計(jì)器
from sklearn.decomposition import PCA

pca = PCA(n_components=2)  # 保留兩個(gè)特征(維度)
pca.fit(X)
print(pca.explained_variance_)
print(pca.components_)

我們看到了兩個(gè)輸出,要了解這些數(shù)字的含義,讓我們將其視為向量在數(shù)據(jù)點(diǎn)上繪制出來:

plt.plot(X[:, 0], X[:, 1], 'o', alpha=0.5)

for length, vector in zip(pca.explained_variance_, pca.components_):
    v = vector * 3 * np.sqrt(length)
    plt.plot([0, v[0]], [0, v[1]], '-k', lw=3)  # lw設(shè)置線寬
plt.axis('equal')

繪圖結(jié)果來看,一個(gè)向量比另一個(gè)向量長。從某種意義上講,這告訴我們數(shù)據(jù)中的這個(gè)方向比另一個(gè)方向更“重要”,而這種方向上的“重要性”是用方差來量化的。當(dāng)然這也告訴我們,在不損失大量信息的情況下完全可以忽略第二個(gè)主要成分。讓我們看看如果僅保留 95%的方差,數(shù)據(jù)將是什么樣子:

clf = PCA(0.95)  # 保存 95%的方差
X_trans = clf.fit_transform(X)
print(X.shape)
print(X_trans.shape)

在使用 PCA 降維時(shí),我們也會(huì)使用到 PCA.fit() 方法。.fit() 是 scikit-learn 訓(xùn)練模型的通用方法,但是該方法本身返回的是模型的參數(shù)。所以,通常我們會(huì)使用 PCA.fit_transform() 方法直接返回降維后的數(shù)據(jù)結(jié)果。
上面結(jié)果來看,通過舍棄 5%的方差,數(shù)據(jù)從 2 維變成了 1 維,相當(dāng)于壓縮了 50%。讓我們看看壓縮后的數(shù)據(jù)是什么樣的:

# 將降維后的數(shù)據(jù)轉(zhuǎn)換成原始數(shù)據(jù)的維度,才能繪圖
X_new = clf.inverse_transform(X_trans)
plt.plot(X[:, 0], X[:, 1], 'o', alpha=0.2)
plt.plot(X_new[:, 0], X_new[:, 1], 'ob', alpha=0.8)
plt.axis('equal')

暗一點(diǎn)的是原始數(shù)據(jù),而亮一點(diǎn)的是投影版本。我們看到將這個(gè)數(shù)據(jù)集的方差截?cái)?5%再重新投影之后,數(shù)據(jù)“最重要”的功能得以保留,并且我們將數(shù)據(jù)壓縮了 50%,這也就是降維的意義:如果可以在較低維度上得到近似數(shù)據(jù)集,則我們可以更輕松地查看它或?qū)⒏鼜?fù)雜的模型擬合到數(shù)據(jù)中。

PCA 手寫數(shù)字?jǐn)?shù)據(jù)集應(yīng)用

降維在二維數(shù)據(jù)上似乎表現(xiàn)得沒有那么重要,但是在可視化高維數(shù)據(jù)時(shí),投影和降維非常有用。讓我們看一下 PCA 在我們之前看過的手寫數(shù)字識別數(shù)據(jù)中的應(yīng)用:

# 導(dǎo)入數(shù)據(jù)集模塊
from sklearn.datasets import load_digits
digits = load_digits()  # 載入數(shù)據(jù)集
X = digits.data
y = digits.target

pca = PCA(n_components=2)  # 從 64 維降維到 2 維
Xproj = pca.fit_transform(X)
print(X.shape)  # 查看原數(shù)據(jù)
print(Xproj.shape)  # 查看降維后的數(shù)據(jù)

# 繪制降維后的數(shù)據(jù)散點(diǎn)圖
plt.scatter(Xproj[:, 0], Xproj[:, 1], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('nipy_spectral', 10))
plt.colorbar()  # 繪制色標(biāo)

我們將 64 維的數(shù)據(jù)降到了 2 維,并將其可視化繪制出來,這使我們對數(shù)字之間的關(guān)系有了一個(gè)概念,并且使我們無需參考標(biāo)簽即可查看數(shù)字的布局。
之前,我們用支持向量機(jī)完成了分類,即預(yù)測哪一張圖像代表哪一個(gè)數(shù)字。現(xiàn)在,我們采用相同的數(shù)據(jù)集完成聚類分析,即將全部數(shù)據(jù)集聚為 10 個(gè)類別。
我們將降到 2 維后的數(shù)據(jù)聚為 10 類,并將聚類后的結(jié)果、聚類中心點(diǎn)、聚類決策邊界繪制出來。

from sklearn.cluster import KMeans

pca = PCA(n_components=2)  # 從 64 維降維到 2 維
Xproj = pca.fit_transform(X)

# 建立 K-Means 并輸入數(shù)據(jù)
model = KMeans(n_clusters=10)
model.fit(Xproj)

# 計(jì)算聚類過程中的決策邊界
x_min, x_max = Xproj[:, 0].min() - 1, Xproj[:, 0].max() + 1
y_min, y_max = Xproj[:, 1].min() - 1, Xproj[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, .05),
                     np.arange(y_min, y_max, .05))  # 生成網(wǎng)格點(diǎn)坐標(biāo)矩陣

result = model.predict(np.c_[xx.ravel(), yy.ravel()])

# 繪制決策邊界
result = result.reshape(xx.shape)
plt.figure(figsize=(10, 5))
plt.contourf(xx, yy, result, cmap=plt.cm.Greys)  # 繪制填充色
plt.scatter(Xproj[:, 0], Xproj[:, 1], c=y, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('nipy_spectral', 10))  # 繪制數(shù)據(jù)散點(diǎn)圖
plt.colorbar()  # 繪制色標(biāo)

# 繪制聚類中心點(diǎn)
center = model.cluster_centers_
plt.scatter(center[:, 0], center[:, 1], marker='p',
            linewidths=2, color='b', edgecolors='w', zorder=20)

# 圖像參數(shù)設(shè)置
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)

圖中,不同的色塊區(qū)域代表一類。這里色塊的顏色沒有意義,只表示類別。散點(diǎn)代表數(shù)據(jù),散點(diǎn)的顏色表示數(shù)據(jù)原始類別。我們可以看出,雖然原始數(shù)據(jù)已經(jīng)降到了 2 維,但某幾個(gè)數(shù)字的依舊有明顯的成團(tuán)現(xiàn)象。
除此之外,我們還可以使用分類方法來對比降維前后的數(shù)據(jù)表現(xiàn)。我們使用隨機(jī)森林方法對數(shù)據(jù)進(jìn)行分類,并通過交叉驗(yàn)證得到準(zhǔn)確度結(jié)果。

from sklearn.ensemble import RandomForestClassifier  # 導(dǎo)入隨機(jī)森林估計(jì)器
from sklearn.model_selection import cross_val_score  # 導(dǎo)入交叉驗(yàn)證

model = RandomForestClassifier()

# 5 折交叉驗(yàn)證平均準(zhǔn)確度
s1 = cross_val_score(model, X, y, cv=5).mean()  # 原始維度數(shù)據(jù)
s2 = cross_val_score(model, Xproj, y, cv=5).mean()  # 降維后的數(shù)據(jù)
print(s1)
print(s2)

你可以看到,實(shí)際上準(zhǔn)確度并不是特別低。也就是說,在客觀條件限制下,我們往往可以以更少維度的數(shù)據(jù)訓(xùn)練出準(zhǔn)確度可以勉強(qiáng)接受的模型。

其他降維估計(jì)器

scikit-learn 還包含許多其他無監(jiān)督學(xué)習(xí)的降維估計(jì)器,你可以嘗試其他的降維方法:
sklearn.decomposition.IncrementalPCA:增量主成分分析(IPCA)
sklearn.decomposition.SparsePCA:PCA 變體,包括 L1 正則
sklearn.decomposition.FastICA:獨(dú)立成分分析
sklearn.decomposition.NMF:非負(fù)矩陣分解
sklearn.manifold.LocallyLinearEmbedding:基于局部鄰域幾何的非線性流形學(xué)習(xí)
sklearn.manifold.IsoMap:基于稀疏圖算法的非線性流形學(xué)習(xí)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容