作者:童蒙
編輯:amethyst
引言
在實際的應(yīng)用中,有時候我們會遇到數(shù)據(jù)的維度太少,我們需要新生成新的維度,可以用我們之前的分享(如何自動化進行特征工程);有時候維度太多,這時候我們就需要降維了。降維的方法有許多,我們這里介紹了sklearn中介紹的7種,供大家學(xué)習(xí)和收藏。
1 PCA
1.1 普通PCA
主成分分析(PCA)用于將多維的數(shù)據(jù)集分解為一組具有最大方差的連續(xù)正交分量。在sklearn這個包中,PCA是一個transformer對象,使用fit方法可以選擇前n個主成分,并且用于投射到新的數(shù)據(jù)中。
PCA有兩種實現(xiàn)方式,一種是特征值分解去實現(xiàn),一種是奇異值分解去實現(xiàn)。特征值分解是一個提取矩陣特征很不錯的方法,但是它只是對方陣而言的,如果不使用SVD,PCA只會尋找每個特征的中心,但并不會對數(shù)據(jù)進行縮放(scaled)。使用參數(shù)whiten=True ,可以將數(shù)據(jù)投射到奇異空間中,并且將每個組分縮放到方差為1,這個對于后續(xù)分析中,假設(shè)每個特征是isotropy 是很有幫助的,例如SVM和Kmeans聚類。
PCA不僅僅是對高維數(shù)據(jù)進行降維,更重要的是經(jīng)過降維去除了噪聲,發(fā)現(xiàn)了數(shù)據(jù)中的模式。PCA把原先的n個特征用數(shù)目更少的m個特征取代,新特征是舊特征的線性組合,這些線性組合最大化樣本方差,盡量使新的m個特征互不相關(guān)。
SVD是一種矩陣分解法,把一個大矩陣分解成易于處理的形式,這種形式可能是兩個或多個矩陣的乘積。
參數(shù)
- n_components:可以是int,float,或者“mle”。如果是int,那么是選擇對應(yīng)的主成分數(shù),如果是float,那么會自動合適的組成份數(shù),使得方差大于float;如果是“mle”,會自動地選擇合適的主成分。
- whiten :白化,使得每個特征具有相同的方差。
屬性 - components_ :返回具有最大方差的成分。
- explained_variance_: 各個主成分的解釋的方差。
- explained_variance_ratio_ :返回所保留的n個成分各自的方差百分比。
- n_components_:返回所保留的成分個數(shù)n。
方法 - fit() : 對PCA進行訓(xùn)練。
- fit_transform(): 訓(xùn)練后,進行降維。
- inverse_transform():將降維后的數(shù)據(jù)轉(zhuǎn)化成原始數(shù)據(jù)。
- transform() : 對訓(xùn)練好的模型,進行轉(zhuǎn)換。
實例
例子1 :基本的使用
import numpy as np
from sklearn.decomposition import PCA
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
pca = PCA(n_components=2)
pca.fit(X)
print(pca.explained_variance_ratio_) ### 獲得每個主成分解釋的比例
print(pca.singular_values_)
例子2:獲取每個主成分與特征的關(guān)系
from sklearn.datasets import load_iris
iris = load_iris()
from sklearn.decomposition import PCA
pca = PCA(3)
X, y = iris.data, iris.target
X_proj = pca.fit_transform(X)
for component in pca.components_:
print(" + ".join("%.2f x %s" % (value, name) for value, name in zip(component, iris.feature_names)))
## 查看累積曲線
print(pca.explained_variance_ratio_.cumsum())
1.2 增量PCA(IPCA)
PCA雖然很有用,但是需要將數(shù)據(jù)全部都存入內(nèi)存,因此當當要分解的數(shù)據(jù)集太大,會導(dǎo)致內(nèi)存很大。這時候,增量主成分分析(IPCA)通常用作主成分分析(PCA)的替代,可以通過部分計算的方式,獲得跟PCA一樣的結(jié)果。
- 使用partial_fit方法,可以分塊的讀取數(shù)據(jù)。
- 如果是稀疏矩陣或者是內(nèi)存文件,使用的是numpy.memmap。
IPCA使用與輸入數(shù)據(jù)樣本數(shù)無關(guān)的內(nèi)存量為輸入數(shù)據(jù)建立低秩近似。它仍然依賴于輸入數(shù)據(jù)功能,但更改批量大小可以控制內(nèi)存使用量。
該函數(shù),增加了一個batch_size的參數(shù),用來控制批次,其余都一樣,至此不再贅述。
實例
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA
from scipy import sparse
X, _ = load_digits(return_X_y=True)
transformer = IncrementalPCA(n_components=7, batch_size=200)
# either partially fit on smaller batches of data
transformer.partial_fit(X[:100, :])
# or let the fit function itself divide the data into batches
X_sparse = sparse.csr_matrix(X)
X_transformed = transformer.fit_transform(X_sparse)
X_transformed.shape
1.3 使用隨機化的SVD的PCA
對于大型矩陣的分解,我們往往會想到用SVD算法。然而當矩陣的維數(shù)與奇異值個數(shù)k上升到一定程度時,SVD分解法往往因為內(nèi)存溢出而失敗。因此,Randomized SVD算法,相比于SVD,它更能適應(yīng)大型矩陣分解的要求,且速度更快。
此外,在某些場景下,我們期望丟掉某些lower sigular values,來達到減少噪音,保留盡可能多的方差,從而達到更好的預(yù)測效果。比如人臉的識別,如果是64X64的像素,那么整個維度有4096個。我們利用這個方法,可以保留重要的維度,從而利于后續(xù)的分析。
使用svd_solver='randomized'可以實現(xiàn)隨機化的SVD,來去掉部分的奇異矩陣。
1.4 Kernel PCA
主成分分析(Principal Components Analysis, PCA)適用于數(shù)據(jù)的線性降維。而核主成分分析(Kernel PCA,KPCA)可實現(xiàn)數(shù)據(jù)的非線性降維,用于處理線性不可分的數(shù)據(jù)集。kernel的選擇有 {'linear', 'poly', 'rbf', 'sigmoid', 'cosine', 'precomputed'},默認是'linear'。
詳細說明見官方說明,與普通的PCA差不多。
1.5 稀疏化PCA 和minibatchsparsePCA
SparsePCA 期望找到一組可以最優(yōu)地重構(gòu)數(shù)據(jù)的稀疏主成分。稀疏性的大小由參數(shù)alpha給出的L1懲罰系數(shù)來控制。Mini-batch sparse PCA是sparsePCA的變種,提高了速度,但是降低了精度。
主成分分析(PCA)的缺點是,該方法提取的成分是一種密集表達式,即用原始變量的線性組合表示時,它們的系數(shù)是非零的。這可能會使解釋模型變得困難。在許多情況下,真實的基礎(chǔ)分量可以更自然地想象為稀疏向量;例如,在人臉識別中,主成分會只包含部分的圖像,映射到人臉的某些部分。稀疏主成分產(chǎn)生了一種更簡潔的、可解釋的表示,清楚地強調(diào)是哪些原始特征導(dǎo)致了樣本之間的差異。
通過調(diào)節(jié)alpha來調(diào)整懲罰度,alpha越大,越導(dǎo)致許多系數(shù)為0。
2 截斷SVD
TruncatedSVD是普通SVD的一個變種,只計算用戶指定的前K個奇異值。TSVD通常用于語義分析中,是LSA的其中的一部分,可以解決一詞多義和一義多詞的問題。
LSA潛在語義分析的目的,就是要找出詞(terms)在文檔和查詢中真正的含義,也就是潛在語義,從而解決上節(jié)所描述的問題。具體說來就是對一個大型的文檔集合使用一個合理的維度建模,并將詞和文檔都表示到該空間,比如有2000個文檔,包含7000個索引詞,LSA使用一個維度為100的向量空間將文檔和詞表示到該空間,進而在該空間進行信息檢索。而將文檔表示到此空間的過程就是SVD奇異值分解和降維的過程。降維是LSA分析中最重要的一步,通過降維,去除了文檔中的“噪音”,也就是無關(guān)信息(比如詞的誤用或不相關(guān)的詞偶爾出現(xiàn)在一起),語義結(jié)構(gòu)逐漸呈現(xiàn)。相比傳統(tǒng)向量空間,潛在語義空間的維度更小,語義關(guān)系更明確。
使用例子如下:
svd = TruncatedSVD(opts.n_components)
svd.fit(X)
svd.transform(X)
3 字典學(xué)習(xí)
3.1 使用預(yù)定義的字典來稀疏化編碼
用事先預(yù)定義好的字典來對矩陣進行稀疏化編碼,達到降維和簡化的目的。就像人類的所有語言都是由單詞組成一樣,因此使用已知的詞典可以減少維度;其次,稀疏化可以減少計算的成本,讓后續(xù)的計算更快。
這個對象沒有fit的方法,transformation方法會將數(shù)據(jù)表示為盡可能少的字典原子的線性組合??梢杂胻ransform_method來控制初始化參數(shù),有以下幾種:
- Orthogonal matching pursuit (Orthogonal Matching Pursuit (OMP)):常用于圖像處理中。
- Least-angle regression (Least Angle Regression)
- Lasso computed by least-angle regression
- Lasso using coordinate descent (Lasso)
- Thresholding :速度很快,但是會產(chǎn)生出不準確的重構(gòu)結(jié)構(gòu),一般用于文本中。
coder = SparseCoder(dictionary=D, transform_n_nonzero_coefs=n_nonzero,
transform_alpha=alpha, transform_algorithm=algo)
x = coder.transform(y.reshape(1, -1))
3.2 通用字典學(xué)習(xí)
使用的函數(shù)為sklearn.decomposition.DictionaryLearning,會找到一個可以將fitted data足夠好稀疏化的字典。
將數(shù)據(jù)表示為一個overcomplete的字典這個過程,同大腦處理數(shù)據(jù)的過程類似。這個方法在圖像補丁的字典學(xué)習(xí)已被證明在諸如圖像完成、修復(fù)和去噪以及監(jiān)督識別任務(wù)的圖像處理任務(wù)中給出良好的結(jié)果。
dict_learner = DictionaryLearning(
n_components=15, transform_algorithm='lasso_lars', random_state=42,
)
X_transformed = dict_learner.fit_transform(X)
3.3 小批次字典學(xué)習(xí)
使用函數(shù)為sklearn.decomposition.MiniBatchDictionaryLearning,是一種快速的,但是精確度降低的版本,適應(yīng)于大數(shù)據(jù)集合。
默認情況下,MiniBatchDictionaryLearning將數(shù)據(jù)分成小批量,并通過在指定次數(shù)的迭代中循環(huán)使用小批量,以在線方式進行優(yōu)化。但是,目前它沒有退出迭代的停止條件。也可以用partial_fit來實現(xiàn)小批次的fit。
4 因子分析
從變量中提取共性因子。
因子分析要求原有變量間具有較強的相關(guān)性,否則,因子分析無法提取變量間的共性特征,如果相關(guān)系數(shù)小于0.3,則變量間的共線性較小,不適合因子分析;因子分析得到因子和原變量的關(guān)系,因此能夠?qū)σ蜃舆M行解釋。
因子分析可以產(chǎn)生與 PCA 相似的特征(載荷矩陣的列)。不過,不能對這些特征做出任何一般性的說明(例如他們是否正交)。
使用的函數(shù)為sklearn.decomposition.FactorAnalysis。
5 獨立成分分析-ICA
使用的函數(shù)為sklearn.decomposition.FastICA,ICA可以提取出一系列的主成分,彼此最大的獨立。因此,ICA一般不用于降維,而用于區(qū)分疊加信號。ICA不考慮noise,為了使模型正確,必須使用whitening,可以使用whiten這個參數(shù)。
ICA 通常用于分離混合信號(稱為盲源分離的問題),也可以作為一種非線性降維方法,可以找到具有一些稀疏性的特征。
主成分分析假設(shè)源信號間彼此非相關(guān),獨立成分分析假設(shè)源信號間彼此獨立。
主成分分析認為主元之間彼此正交,樣本呈高斯分布;獨立成分分析則不要求樣本呈高斯分布。
6 非負矩陣分解
非負矩陣分解,顧名思義就是,將非負的大矩陣分解成兩個非負的小矩陣。在數(shù)據(jù)矩陣不包含負值的情況下,應(yīng)用NMF而不是PCA或其變體。
NMF可以產(chǎn)生可以代表數(shù)據(jù)的主成分,從而可以來解釋整個模型。
參數(shù)init,可以用來選擇初始化的方法,不同的方法對結(jié)果會有不同的表現(xiàn)。
import numpy as np
X = np.array([[1, 1], [2, 1], [3, 1.2], [4, 1], [5, 0.8], [6, 1]])
from sklearn.decomposition import NMF
model = NMF(n_components=2, init='random', random_state=0)
W = model.fit_transform(X)
H = model.components_
X_new = np.array([[1, 0], [1, 6.1], [1, 0], [1, 4], [3.2, 1], [0, 4]])
W_new = model.transform(X_new)
在PCA處理中,假使將特征降維為600個,那么降維后的每個人臉都包含了600個特征(所以我們看到降維后的人臉有種“伏地魔”的感覺 ,這是因為降維處理相當于刪去了部分細節(jié)特征,導(dǎo)致一部分信息丟失,在圖片中最直觀的體現(xiàn)就是變模糊)。而在NMF的處理中,這1000個特征相當于是被分離了。相當于,一張人臉是由鼻子、耳朵等這些獨立的特征疊加出來的。
7 Latent Dirichlet Allocation (LDA)
LDA是文檔主題生成模型,對離散數(shù)據(jù)集(如文本語料庫)的集合的生成概率模型。它也是一個主題模型,用于從文檔集合中發(fā)現(xiàn)抽象主題。LDA是一種非監(jiān)督機器學(xué)習(xí)技術(shù),可以用來識別大規(guī)模文檔集(document collection)或語料庫(corpus)中潛藏的主題信息。
sklearn.decomposition.LatentDirichletAllocation是用于進行LDA的函數(shù)。
lda = LatentDirichletAllocation(n_components=5,
random_state=0)
lda.fit(X)
本文主體來源于sklearn的降維這一章,里面有許多數(shù)學(xué)的知識,還是需要大家自己好好的學(xué)習(xí)。
本文對PCA介紹比較詳細,但是對于其他的介紹的比較簡單,其實各自都有很多的用途,等小編學(xué)習(xí)后跟大家分享。
文章中許多內(nèi)容是借鑒網(wǎng)上的內(nèi)容,如果有侵權(quán),請跟我們聯(lián)系,我們會盡快修改。
參考資料
1、http://www.itdecent.cn/p/1adef2d6dd88
2、http://www.itdecent.cn/p/e574e91070ad
3、https://scikit-learn.org/stable/modules/decomposition.html#decompositions
4、https://shankarmsy.github.io/posts/pca-sklearn.html
5、https://mp.weixin.qq.com/s/Tl9ssjmGdeyNrNuIReo1aw
6、https://www.cnblogs.com/eczhou/p/5433856.html
7、https://scikit-learn.org/stable/auto_examples/applications/plot_face_recognition.html#sphx-glr-auto-examples-applications-plot-face-recognition-py
8、https://blog.csdn.net/fkyyly/article/details/84665361 LSA(Latent semantic analysis)
9、https://blog.csdn.net/fjssharpsword/article/details/74964127
10、http://www.itdecent.cn/p/e90900a3d03a