python實戰因子分析和主成分分析 SVD奇異值分解的基本原理和運用

課程視頻教程入口

歡迎各位同學學習《python實戰因子分析和主成分分析

騰訊課堂入口(推薦,有優惠券):

https://ke.qq.com/course/3485943

網易雲課堂入口

https://study.163.com/course/courseMain.htm?courseId=1211631809&share=2&shareId=400000000398149

(微信二維碼掃一掃報名)

課程目錄

章節1python編程環境搭建
課時1Anaconda下載安裝
課時2Anaconda快速入門指南
課時3Anaconda Navigator導航器
課時4python第三方包安裝(pip和conda install)
課時5Python非官方擴展包下載地址

章節2python項目實戰主成分分析PCA
課時6邊際效應基本概念
課時7模型維度與邊際效應,變量越多越好嗎?
課時8kaggle模型一定最好嗎?降維在企業建模實際意義
課時9降維方法好不好,測試爲準
課時10python主成分分析關鍵代碼解讀
課時11python主成分分析與機器學習建模結合項目實戰
課時12PCA主成分降維在人臉識別應用-附代碼

章節3python項目實戰因子分析factor analysis
課時13因子分析基本思想和使用限制條件
課時14python sklearn因子分析實戰乳腺癌數據集
課時15python因子分析第三方包訓練模型,結果讓人喫驚
課時16因子分析-KMO和巴特利球形度檢驗
課時17因子分析-python繪製碎石圖
課時18因子分析旋轉方法rotation
課時19因子分析-累計方差貢獻率
課時20SPSS因子分析項目實操

章節4附錄
課時21課程腳本和數據資料下載地址

 

課程腳本

 

課程部分文字介紹

 

 

因子分析基礎概念

因子分析是一種統計方法,可用於描述觀察到的相關變量之間的變異性,即潛在的未觀察到的變量數量可能更少(稱爲因子)。例如,六個觀察變量的變化可能主要反映了兩個未觀察(基礎)變量的變化。因子分析搜索這種聯合變化,以響應未觀察到的潛在變量。將觀察到的變量建模爲潛在因素以及“錯誤”項的線性組合。
簡而言之,變量的因子加載量化了變量與給定因子相關的程度。
因子分析方法背後的一個普遍原理是,有關觀察到的變量之間的相互依賴性的信息可以稍後用於減少數據集中的變量集。因子分析通常用於生物學,心理計量學,人格理論,市場營銷,產品管理,運營研究和財務。在有大量觀察到的變量被認爲反映較少數量的基礎/潛在變量的數據集時,這可能會有所幫助。它是最常用的相互依存技術之一,當相關變量集顯示出系統的相互依存關係時使用,其目的是找出產生共同性的潛在因素。

 

因子分析分爲兩類

 

因子分析重要部分是二變量相關性矩陣和因子的相關性

pattern matrix中灰色部分就是變量值高的,灰色變量具有代表性

 

 因子分析算法步驟 

圖片

因子分析是一種相關性分析方法,用於在大量變量中尋找和描述潛在因子

因子分析確認變量的相關性,把相關性強的變量歸類爲一個潛在因子

 

最早因子分析應用於二戰後IQ測試。科學家試圖把測試的所有變量綜合爲一個因子,IQ得分

下面表格數據,變量有1-6,其中變量1,3,4有相關性,它們可以融合爲一個因子

一般來說,大量變量可以降維到少數幾個因子。

紫色的變量1,3,4有相關性,可以歸爲一個因子

橙色變量2,6有相關性可以歸爲一個因子

綜合上述,變量1,3,4歸爲一個因子

變量2,6,歸爲一個因子

變量5歸爲一個因子

這個數據集的6個變量降低維度到3個因子。

因子分析步驟:

1.因子分析假設條件

2.找到因子的方法

3.決定因子是否重要

4.檢驗因子裏變量的交互性

 

 

 

 因子分析假設

假設很重要,如果不符合假設條件,則報告可行性很差

 

因子分析有6個假設條件

1.沒有異常值

2.足夠樣本量

3.沒有完美多重相關性

4.不需要符合方差齊性

5.變量符合線性

6.數據符合間隔性

數據沒有異常值,下例中1247943太大,屬於異常值,應該排除

 

變量數量要多於因子數量

數據不能完全多重相關性

下表數據變量1*2得到變量2,變量1*3得到變量3

homoscedasticity方差齊性

變量不需要滿足方差齊性

 變量符合線性,方差分析基於線性前提

 

方差分析的變量至少是定距變量

分類變量,例如男女,定序變量1,2,3是均勻等差,也不行

(1) Norminal Data 定類變量:變量的不同取值僅僅代表了不同類的事物,這樣的變量叫定類變量。問卷的人口特徵中最常使用的問題,而調查被訪對象的“性別”,就是 定類變量。對於定類變量,加減乘除等運算是沒有實際意義的。

(2) Ordinal Data定序變量:變量的值不僅能夠代表事物的分類,還能代表事物按某種特性的排序,這樣的變量叫定序變量。問卷的人口特徵中最常使用的問題“教育程度“,以及態度量表題目等都是定序變量,定序變量的值之間可以比較大小,或者有強弱順序,但兩個值的差一般沒有什麼實際意義。

(3)Interval Data 定距變量:變量的值之間可以比較大小,兩個值的差有實際意義,這樣的變量叫定距變量。有時問卷在調查被訪者的“年齡”和“每月平均收入”,都是定距變量。

(4) Ratio Data 定比變量, 有絕對0點,如質量,高度。定比變量與定距變量在市場調查中一般不加以區分,它們的差別在於,定距變量取值爲“0”時,不表示“沒有”,僅僅是取值爲0。定比變量取值爲“0”時,則表示“沒有”。

 

 

因子分析報告可信度

殘差小於5%,KMO大於0.8,解釋方差大於60%較好。

 

 

 

 

教育案例因子分析實例

 what are the percentages of disciplinary placements,Afican-American,Hispanic,white,economically disadvantaged,limited English proficiency,at risk ,and special education students in Texas independent schooll districts in 2011?

 2011年德克薩斯州獨立學區的學科配置,非裔美國人,西班牙裔,白人,經濟地位不利,英語能力有限,處於風險中,以及特殊教育學生的百分比是多少?

 

因子分析問題

下面八個變量是否存在相關性?學科配置,非裔美國人,西班牙裔,白人,經濟地位不利,英語能力有限,處於風險中,以及特殊教育學生比例

 

 因子分析工具選擇:

1.spss

2.python

 

檢驗五項

1.描述性統計

2.共線矩陣

3.bartlett kmo檢驗

4.方差總量解釋

5. 特徵根圖

6.旋轉成分矩陣

 

 

 

 

 KMO檢驗

 一般KMO值大於0.8參考意義較大

下圖KMO值=0.54,說明相關性一般,可以勉強進行因子分析。

bartlett顯著性0,拒絕零假設(變量無相關性),得到變量有顯著相關性,有時候,bartlett意義不大

 

 

 

KMO(Kaiser-Meyer-Olkin)檢驗統計量是用於比較變量間簡單相關係數和偏相關係數的指標。主要應用於多元統計的因子分析。KMO統計量是取值在0和1之間。
當所有變量間的簡單相關係數平方和遠遠大於偏相關係數平方和時,KMO值接近1.KMO值越接近於1,意味着變量間的相關性越強,原有變量越適合作因子分析;當所有變量間的簡單相關係數平方和接近0時,KMO值接近0.KMO值越接近於0,意味着變量間的相關性越弱,原有變量越不適合作因子分析。

 Bartlett's球狀檢驗是一種數學術語。用於檢驗相關陣中各變量間的相關性,是否爲單位陣,即檢驗各個變量是否各自獨立。因子分析前,首先進行KMO檢驗和巴特利球體檢驗。在因子分析中,若拒絕原假設,則說明可以做因子分析,若不拒絕原假設,則說明這些變量可能獨立提供一些信息,不適合做因子分析。

 如果變量間彼此獨立,則無法從中提取公因子,也就無法應用因子分析法。Bartlett球形檢驗判斷如果相關陣是單位陣,則各變量獨立因子分析法無效。由SPSS檢驗結果顯示Sig.<0.05(即p值<0.05)時,說明各變量間具有相關性,因子分析有效。

 

 

有些情況下,bartlett檢驗意義不大

共線矩陣

西班牙後裔比例與黑人比例中度衝突

西班牙後裔比例與白人比例嚴重衝突

西班牙後裔比例英語水平-0.54相關性,即西班牙後裔英語不好

非洲美國後裔比例與白人30%正相關衝突

英語水平差和經濟收入低0.577正相關,與風險因子0.44正相關

 

 

scree plot 

縱座標:特徵根值

橫座標:因子數量

 

 

 

方差解釋

elgenvalue特徵根選擇大於1的因子,前三個因子特徵根大於1,累計解釋力度得到73.887%

 

 

 我們的分析產生了3個旋轉後的因子

 

 

 旋轉的成分矩陣分析

 

 

component1:西班牙裔比例,白人比例,黑人比例與經濟落後,英語水平低,風險因素比較突出,這些因子可以歸類爲ethnicity種族問題

第二個因子:特殊需求(special education佔比最大0.812)

第三個因子:黑人因子,佔比0.96

 

因子旋轉(factor rotation)下圖:主成分1的列數來看,所有值都>0.5, 即主成分1能共同解釋所有變量,而對每個變量x_i只能解釋其中少部分信息,因子含糊不清,需要旋轉。 而且主成分1解釋了:財政收入,固定資產投資,社會消費品零售總額, 這三個變量難以綜合解釋。圖片


旋轉後,因子1能解釋2,3,4,6變量,含義比旋轉前要清晰。
因子1:財政收入,固定資產投資,年末總人口,社會消費品零售總額 -------命名爲:經濟水平
因子2:人均GDP,居民消費水平--------命名爲:消費水平
圖片

因子旋轉的目的使因子含義更加清楚,以便對因子命名和解釋。

旋轉方法:正交旋轉和斜交旋轉。

正交旋轉是指座標軸總是保持垂直90度旋轉,這樣新生成因子可保持不變。

斜交旋轉座標軸夾角是任意的,生成因子不能保證不相關。

實際中更多應用正交旋轉Varimax法。


旋轉方法:
Varimax
quartimax
equamax
direct oblimin(斜交旋轉)

 

 

數學模型 設原始的p個變量爲x1,x2......x_p, 要尋找k個因子(k<p)爲f1, f2, .......f_k,因子f_i和原始變量x_i的關係可表示爲

 

圖片


載荷 a_ij
含義與主成分類似。 a_ij爲第i個變量x_i與第j個因子f_j之間的線性相關係數,反映x_i和f_j之間的相關程度,也稱載荷。

f_i:公因子common factor  
 因子f_i出現在每個原始變量與因子的線性組合中,稱爲公因子。

特殊因子:代表公因子以外因素影響。 


共同度量:h_i**2
考察x_i的信息能夠被k個公因子所解釋的程度。它是用k個公因子對第i個變量的方差貢獻率來表示的,稱爲變量x_i的共同度量(communality)
計算公式如下圖:
共同度量值越大,說明提出的公因子對原始變量的解釋能力越強。

方差貢獻率:
:第j個公因子的方差貢獻率g_j**2
方差貢獻率表示第j個 公因子對變量x_i所提供的方差總和,反應了第j個公因子的相對重要程度。方差貢獻率越大表明該公因子對x_i的貢獻越大。




圖片

變量共同度量表,由該表可知,所有變量的共同度量都是在90%以上,因此提取的公因子對原始變量解釋力很強。

圖片


 

 因子得分 

 

spss操作:分析步驟---得分---保存爲變量
程序自動統計得到結果 

圖片



 
因子得分(factor score)

 

就是每個因子在每個樣本上的具體取值。每個因子的得分實際上由下列因子得分函數給出

因子得分是各變量的線性組合。
圖片  


經過程序運算,x_i不是原始變量,而是標準化變量

圖片



圖片




 f1=[-0.105,0.18,0.3,0.372,-0.104,0.281]

 

f2=[0.43,0.171,-0.026,-0.237,0.429,0.022]

 

beijing=[50467,11171514,3296.4,1581,16770,3275.2]

 

 

 

coefficient=[0.691141,0.308859]

 

 

 

f1_score=[]

 

f2_score=[]

 

for i in range(len(f1)):

 

    score1=f1[i]*beijing[i]

 

    score2=f2[i]*beijing[i]

 

    f1_score.append(score1)

 

    f2_score.append(score2)

 

 

 

f1_sum=sum(f1_score)

 

f2_sum=sum(f2_score)

 

 

 

 

 

factor_score=coefficient[0]*f1_sum+coefficient[1]*f2_sum


>>> factor_score
1985481.5535567512

運算結果和答案不符合,說明 x_i不是原始變量,而是標準化變量

 

 

 

 

 

 特徵根 eigenvalues['aɪgən,væljuː]

 

表中初始特徵值就是特徵根,實際上就是本例中的6個主軸長度。

特徵根 eigenvalues
---即主軸或方差,當特徵根小於1時,就不再選作主成分了。選擇特徵根大於1的值
主成分的累計方差貢獻率達到80%以上的前幾個主成分,都可以選作最後的主成分。 

 

 

 

 

 

碎石圖scree plot 

 

 scree[skriː] 小石子;岩屑堆

 

A scree plot displays the eigenvalues associated with a component or factor in descending order versus the number of the component or factor. You can use scree plots in principal components analysis and factor analysis to visually assess which components or factors explain most of the variability in the data. 碎石圖用於主成分分析或因子分析

橫軸是因子,縱軸是特徵值 
觀察第五個因素後,斜率慢慢變緩,前五個因素解釋了大部分原因。 

圖片


A factor analysis was conducted on 12 different characteristics of job applicants. This scree plot shows that 5 of those factors explain most of the variability because the line starts to straighten after factor 5. The remaining factors explain a very small proportion of the variability and are likely unimportant.

 

The ideal pattern in a scree plot is a steep curve, followed by a bend and then a flat or horizontal line. Retain those components or factors in the steep curve before the first point that starts the flat line trend. You might have difficulty interpreting a scree plot. Use your knowledge of the data and the results from the other approaches of selecting components or factors to help decide the number of important components or factors.

 

碎石圖中,前三個因子特徵根值大於1,可以被篩選

 

 

 

 

 

載荷圖Loading Plot

 

The loading plot is a plot of the relationship between the original variables and the subspace dimension. It is used to interpret relationships between variables.載荷圖解釋原始變量和主成分關係

圖片 
橫座標表示第一主成分與原始變量之間的相關係數;縱軸表示第二主成分與原始變量之間相關係數。
這樣每個變量對應的主成分載荷就對應座標系中一個點,比如,人均GDP變量對應點是(0.67,0.725)。這樣6個變量就有6個點。相關係數的點越遠離座標軸原點,主成分對原始變量的代表性就越大。
圖中,人均GDP和居民消費水平幾乎重合

 

 

 

 

 

 

 

主成分分析-降維 

 

主成分分析principal component analysis
通過考察變量相關性,找到幾個主成分(principal component)來代表原來的多個變量。
同時使她們儘量保留原始變量的信息。
這些變量 彼此不相關,數量遠少於原始變量個數,從而達到數據降維目的。

圖片



圖中可見兩個變量x1和x2存在相關關係,它們信息有重疊。如果把兩個變量用一個新的變量表示,同時這一新變量可能包含原來的兩個變量的信息,這就是降維過程。
散點圖形成一個橢圓形輪廓,包含一個長軸和一個短軸,稱爲主軸。
在橢圓長軸方向,數據變化大,攜帶大部分數據變化信息。
在橢圓短軸方向,數據變化小。攜帶小部分數據變化信息。
因此用長軸y1方向就可以代表原來x1和x2兩個變量信息,這樣兩個變量降維到一個變量,達到降維目的。
橢圓中,長短軸相差越大,長軸變量代表性就越好 ,降維越合理。
圖片

多維變量情形類似,只不過是一個高維橢圓,無法直接觀察。由於每個變量有一個座標軸,因此有幾個變量就有幾個主軸。
首先找出橢圓球各個主軸,再用代表大多數數據信息的最長几個軸作爲新變量,這樣降維就完成了。
找出的新變量是原來變量的線性組合,叫做主成分。

圖片

圖片

 

 

 

 

 

三個提取因子方法

 

 

 

 

 

 

實戰

實戰1-尋找美國總統因子

變量包括:年齡,性別,種族等等

 

性別,種族屬於分類變量,不適合因子分析

 

 

學生教學能力分爲兩個因子:

 

量化能力:數學得分,編程得分,物理得分

 

口語能力:英語,言語推理得分

 

 

 

 

 

sklearn主成分官網

 

http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html

 

 

 

 

 

 

sklearn.decomposition.PCA 中文介紹網址

 

https://www.cnblogs.com/pinard/p/6243025.html

 

1. scikit-learn PCA類介紹

 

    在scikit-learn中,與PCA相關的類都在sklearn.decomposition包中。最常用的PCA類就是sklearn.decomposition.PCA,我們下面主要也會講解基於這個類的使用的方法。

 

    除了PCA類以外,最常用的PCA相關類還有KernelPCA類,在原理篇我們也講到了,它主要用於非線性數據的降維,需要用到核技巧。因此在使用的時候需要選擇合適的核函數並對核函數的參數進行調參。

 

    另外一個常用的PCA相關類是IncrementalPCA類,它主要是爲了解決單機內存限制的。有時候我們的樣本量可能是上百萬+,維度可能也是上千,直接去擬合數據可能會讓內存爆掉, 此時我們可以用IncrementalPCA類來解決這個問題。IncrementalPCA先將數據分成多個batch,然後對每個batch依次遞增調用partial_fit函數,這樣一步步的得到最終的樣本最優降維。

 

    此外還有SparsePCA和MiniBatchSparsePCA。他們和上面講到的PCA類的區別主要是使用了L1的正則化,這樣可以將很多非主要成分的影響度降爲0,這樣在PCA降維的時候我們僅僅需要對那些相對比較主要的成分進行PCA降維,避免了一些噪聲之類的因素對我們PCA降維的影響。SparsePCA和MiniBatchSparsePCA之間的區別則是MiniBatchSparsePCA通過使用一部分樣本特徵和給定的迭代次數來進行PCA降維,以解決在大樣本時特徵分解過慢的問題,當然,代價就是PCA降維的精確度可能會降低。使用SparsePCA和MiniBatchSparsePCA需要對L1正則化參數進行調參。

 

 

 

2. sklearn.decomposition.PCA參數介紹

 

    下面我們主要基於sklearn.decomposition.PCA來講解如何使用scikit-learn進行PCA降維。PCA類基本不需要調參,一般來說,我們只需要指定我們需要降維到的維度,或者我們希望降維後的主成分的方差和佔原始維度所有特徵方差和的比例閾值就可以了。

 

    現在我們對sklearn.decomposition.PCA的主要參數做一個介紹:

 

    1)n_components:這個參數可以幫我們指定希望PCA降維後的特徵維度數目。最常用的做法是直接指定降維到的維度數目,此時n_components是一個大於等於1的整數。當然,我們也可以指定主成分的方差和所佔的最小比例閾值,讓PCA類自己去根據樣本特徵方差來決定降維到的維度數,此時n_components是一個(0,1]之間的數。當然,我們還可以將參數設置爲"mle", 此時PCA類會用MLE算法根據特徵的方差分佈情況自己去選擇一定數量的主成分特徵來降維。我們也可以用默認值,即不輸入n_components,此時n_components=min(樣本數,特徵數)。

 

    2)whiten :判斷是否進行白化。所謂白化,就是對降維後的數據的每個特徵進行歸一化,讓方差都爲1.對於PCA降維本身來說,一般不需要白化。如果你PCA降維後有後續的數據處理動作,可以考慮白化。默認值是False,即不進行白化。

 

    3)svd_solver:即指定奇異值分解SVD的方法,由於特徵分解是奇異值分解SVD的一個特例,一般的PCA庫都是基於SVD實現的。有4個可以選擇的值:{‘auto’, ‘full’, ‘arpack’, ‘randomized’}。randomized一般適用於數據量大,數據維度多同時主成分數目比例又較低的PCA降維,它使用了一些加快SVD的隨機算法。 full則是傳統意義上的SVD,使用了scipy庫對應的實現。arpack和randomized的適用場景類似,區別是randomized使用的是scikit-learn自己的SVD實現,而arpack直接使用了scipy庫的sparse SVD實現。默認是auto,即PCA類會自己去在前面講到的三種算法裏面去權衡,選擇一個合適的SVD算法來降維。一般來說,使用默認值就夠了。

 

    除了這些輸入參數外,有兩個PCA類的成員值得關注。第一個是explained_variance_,它代表降維後的各主成分的方差值。方差值越大,則說明越是重要的主成分。第二個是explained_variance_ratio_,它代表降維後的各主成分的方差值佔總方差值的比例,這個比例越大,則越是重要的主成分。

 

 

 

SVD奇異值分解的基本原理和運用

 

https://www.cnblogs.com/NextNight/p/6212575.html

 

SVD奇異值分解:

 

   SVD是一種可靠的正交矩陣分解法。可以把A矩陣分解成U,∑,VT三個矩陣相乘的形式。(Svd(A)=[U*∑*VT],A不必是方陣,U,VT必定是正交陣,S是對角陣<以奇異值爲對角線,其他全爲0>)

 

     用途

 

     信息檢索(LSA:隱性語義索引,LSA:隱性語義分析),分解後的奇異值代表了文章的主題或者概念,信息檢索的時候同義詞,或者說同一主題下的詞會映射爲同一主題,這樣就可以提高搜索效率

 

     數據壓縮:通過奇異值分解,選擇能量較大的前N個奇異值來代替所有的數據信息,這樣可以降低噪聲,節省空間。

 

        推薦系統:主要是降噪,矩陣變換至低維空間,方便計算(目前沒有意識到它對推薦精確度的提升有什麼具體作用)。

 

     原理:矩陣分解,矩陣變換,數據降維

 

 

 

2、PCA對象的屬性

 

 

 

components_ :返回具有最大方差的成分。

 

explained_variance_ratio_:返回 所保留的n個成分各自的方差百分比。

 

n_components_:返回所保留的成分個數n。

 

mean_:

 

noise_variance_:

 

 

 

 

 

3、PCA對象的方法

 

  • fit(X,y=None)
fit()可以說是scikit-learn中通用的方法,每個需要訓練的算法都會有fit()方法,它其實就是算法中的“訓練”這一步驟。因爲PCA是無監督學習算法,此處y自然等於None。

 

 

 

fit(X),表示用數據X來訓練PCA模型。

 

 

 

函數返回值:調用fit方法的對象本身。比如pca.fit(X),表示用X對pca這個對象進行訓練。

 

 

 

  • fit_transform(X)
用X來訓練PCA模型,同時返回降維後的數據。

 

newX=pca.fit_transform(X),newX就是降維後的數據。

 

 

 

  • inverse_transform()
將降維後的數據轉換成原始數據,X=pca.inverse_transform(newX)

 

 

 

  • transform(X)
將數據X轉換成降維後的數據。當模型訓練好後,對於新輸入的數據,都可以用transform方法來降維。

 

 

 

此外,還有get_covariance()、get_precision()、get_params(deep=True)、score(X, y=None)等方法,以後用到再補充吧。

 

 

 

 

 

 sklearn 因子分析官網

 

http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.FactorAnalysis.html

 

 

 

 

 

 

 

 

 

 

3. PCA實例

 

    下面我們用一個實例來學習下scikit-learn中的PCA類使用。爲了方便的可視化讓大家有一個直觀的認識,我們這裏使用了三維的數據來降維。

 

    首先我們生成隨機數據並可視化,代碼如下:

 

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
from sklearn.datasets.samples_generator import make_blobs
# X爲樣本特徵,Y爲樣本簇類別, 共1000個樣本,每個樣本3個特徵,共4個簇
X, y = make_blobs(n_samples=10000, n_features=3, centers=[[3,3, 3], [0,0,0], [1,1,1], [2,2,2]], cluster_std=[0.2, 0.1, 0.2, 0.2], 
                  random_state =9)
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20)
plt.scatter(X[:, 0], X[:, 1], X[:, 2],marker='o')

複製代碼

 

 三維數據的分佈圖如下:

    我們先不降維,只對數據進行投影,看看投影后的三個維度的方差分佈,代碼如下:

 

from sklearn.decomposition import PCA
pca = PCA(n_components=3)
pca.fit(X)
print pca.explained_variance_ratio_
print pca.explained_variance_

 

 輸出如下:

[ 0.98318212  0.00850037  0.00831751]
[ 3.78483785  0.03272285  0.03201892]

    可以看出投影后三個特徵維度的方差比例大約爲98.3%:0.8%:0.8%。投影后第一個特徵佔了絕大多數的主成分比例。

    現在我們來進行降維,從三維降到2維,代碼如下:

pca = PCA(n_components=2)
pca.fit(X)
print pca.explained_variance_ratio_
print pca.explained_variance_

 輸出如下:

[ 0.98318212  0.00850037]
[ 3.78483785  0.03272285]

    這個結果其實可以預料,因爲上面三個投影后的特徵維度的方差分別爲:[ 3.78483785  0.03272285  0.03201892],投影到二維後選擇的肯定是前兩個特徵,而拋棄第三個特徵。

    爲了有個直觀的認識,我們看看此時轉化後的數據分佈,代碼如下:

 

X_new = pca.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o')
plt.show()

 輸出的圖如下:

    可見降維後的數據依然可以很清楚的看到我們之前三維圖中的4個簇。

    現在我們看看不直接指定降維的維度,而指定降維後的主成分方差和比例。

pca = PCA(n_components=0.95)
pca.fit(X)
print pca.explained_variance_ratio_
print pca.explained_variance_
print pca.n_components_

 我們指定了主成分至少佔95%,輸出如下:

[ 0.98318212]
[ 3.78483785]
1

    可見只有第一個投影特徵被保留。這也很好理解,我們的第一個主成分佔投影特徵的方差比例高達98%。只選擇這一個特徵維度便可以滿足95%的閾值。我們現在選擇閾值99%看看,代碼如下:

 

pca = PCA(n_components=0.99)
pca.fit(X)
print pca.explained_variance_ratio_
print pca.explained_variance_
print pca.n_components_

 此時的輸出如下:

[ 0.98318212  0.00850037]
[ 3.78483785  0.03272285]
2

    這個結果也很好理解,因爲我們第一個主成分佔了98.3%的方差比例,第二個主成分佔了0.8%的方差比例,兩者一起可以滿足我們的閾值。

    最後我們看看讓MLE算法自己選擇降維維度的效果,代碼如下:

 

pca = PCA(n_components='mle')
pca.fit(X)
print pca.explained_variance_ratio_
print pca.explained_variance_
print pca.n_components_

 輸出結果如下:

[ 0.98318212]
[ 3.78483785]
1

    可見由於我們的數據的第一個投影特徵的方差佔比高達98.3%,MLE算法只保留了我們的第一個特徵。

 

# -*- coding: utf-8 -*-
"""
Created on Thu Apr 5 22:44:32 2018

@author: Administrator
"""
from sklearn.datasets import load_breast_cancer
from sklearn.decomposition import PCA
import numpy as np


X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
pca = PCA(n_components=2)
pca.fit(X)
#保留兩個因子
PCA(copy=True, n_components=2, whiten=False)

#可以看到第一個特徵的單個變量方差貢獻率已經到達0.99,意味着幾乎保留了所有的信息。所以只保留一個特徵即可
print("two component explained_variance_ratio_:")
print(pca.explained_variance_ratio_)
'''
[ 0.99244289 0.00755711]
'''

#自動保留因子,現在我們將n_components設置成"mle",發現自動保留了一個特徵。
pca_auto=PCA(n_components='mle')
pca_auto.fit(X)
print("mle explained_variance_ratio_:")
print(pca_auto.explained_variance_ratio_)
'''
[ 0.99244289]
'''

pca1=PCA(n_components=1)
#返回降維後的數據newData
newData=pca1.fit_transform(X)
#將降維後的數據轉換成原始數據,X=pca.inverse_transform(newX)
#測試結果不對
original_data=pca1.inverse_transform(newData)

'''
cancer=load_breast_cancer()
data=cancer.data
pca_cancer=PCA(n_components='mle')
pca_cancer.fit(data)
print("cancer data explained_variance_ratio_:")
print(pca_cancer.explained_variance_ratio_)
'''

 

乳腺癌分類器因子分析腳本

# -*- coding: utf-8 -*-
"""
Created on Thu Apr  5 23:32:12 2018
 
@author: [email protected]
"""
 
import numpy as np
import matplotlib.pyplot as plt
 
from sklearn import linear_model, decomposition, datasets
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_breast_cancer
 
cancer=load_breast_cancer()
 
logistic = linear_model.LogisticRegression()
 
pca = decomposition.PCA()
pipe = Pipeline(steps=[('pca', pca), ('logistic', logistic)])
 
digits = load_breast_cancer()
X_digits = cancer.data
y_digits = digits.target
 
# Plot the PCA spectrum
pca.fit(X_digits)
 
plt.figure(1, figsize=(4, 3))
plt.clf()
plt.axes([.2, .2, .7, .7])
plt.plot(pca.explained_variance_, linewidth=2)
plt.axis('tight')
plt.xlabel('n_components')
plt.ylabel('explained_variance_')
 
# Prediction
n_components = [10, 20, 30]
Cs = np.logspace(-4, 4, 3)
 
# Parameters of pipelines can be set using ‘__’ separated parameter names:
estimator = GridSearchCV(pipe,
                         dict(pca__n_components=n_components,
                              logistic__C=Cs))
estimator.fit(X_digits, y_digits)
 
plt.axvline(estimator.best_estimator_.named_steps['pca'].n_components,
            linestyle=':', label='n_components chosen')
plt.legend(prop=dict(size=12))
plt.show()

 

我們可以看到,取第一個因子就可以解釋95%方差了。

 

乳腺癌細胞數據,下面腳本解釋了一個主成分就解釋了0.98以上癌細胞方差,這和隨機森林效果類似,spss和python統計結果相差較大。spss提供因子解讀效果好,python計算的值更加準確,乳腺癌細胞,一個特徵因子就可以解釋0.98成分。

 

 

# -*- coding: utf-8 -*-
"""
Created on Thu Apr 5 23:32:12 2018
@author: Administrator

pca =PCA(n_components='mle')報錯
elif n_components >= 1 and n_components < .8 * min(X.shape):

TypeError: '>=' not supported between instances of 'str' and 'int'
"""

import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model, decomposition, datasets
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_breast_cancer
from sklearn.decomposition import PCA

cancer=load_breast_cancer()
pca =PCA(n_components=0.98)
#pca= PCA(n_components='mle')

digits = load_breast_cancer()
X_digits = cancer.data
y_digits = digits.target

# Plot the PCA spectrum
pca.fit(X_digits)
print (pca.explained_variance_ratio_)
print (pca.explained_variance_)
print (pca.n_components_)

#計算協方差
pca.get_covariance()
#Estimated precision of data.計算數據估計的準確性
pca.get_precision()

'''
返回模型參數
{'copy': True,
'iterated_power': 'auto',
'n_components': 0.98,
'random_state': None,
'svd_solver': 'auto',
'tol': 0.0,
'whiten': False}
'''
pca.get_params(deep=True)
#返回降維後的數據
new_data=pca.fit_transform(X_digits)
#返回原始數據,測試結果和原始數據不一致
origin_data=pca.inverse_transform(new_data)

 

 

 

  

 

PCA隨機數測試腳本

 

# -*- coding: utf-8 -*-
"""
Created on Sun Apr  8 23:39:10 2018
 
@author:[email protected]
 
scikit中的make_blobs方法常被用來生成聚類算法的測試數據,直觀地說,make_blobs會根據
用戶指定的特徵數量、中心點數量、範圍等來生成幾類數據,這些數據可用於測試聚類算法的效果
"""
 
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.datasets.samples_generator import make_blobs
 
from sklearn.decomposition import PCA
 
 
# X爲樣本特徵,Y爲樣本簇類別, 共1000個樣本,每個樣本3個特徵,共4個簇
X, y = make_blobs(n_samples=10000, n_features=3, centers=[[3,3, 3], [0,0,0], [1,1,1], [2,2,2]], cluster_std=[0.2, 0.1, 0.2, 0.2],
                  random_state =9)
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20)
plt.scatter(X[:, 0], X[:, 1], X[:, 2],marker='o')
 
'''
我們先不降維,只對數據進行投影,看看投影后的三個維度的方差分佈.
可以看出投影后三個特徵維度的方差比例大約爲98.3%:0.8%:0.8%。投影后第一個特徵佔了絕大多數的主成分比例。
'''
pca = PCA(n_components=3)
pca.fit(X)
print (pca.explained_variance_ratio_)
print (pca.explained_variance_)
 
'''
現在我們來進行降維,從三維降到2維
'''
pca1 = PCA(n_components=2)
pca1.fit(X)
print (pca1.explained_variance_ratio_)
print (pca1.explained_variance_)
 
'''
可見降維後的數據依然可以很清楚的看到我們之前三維圖中的4個簇
'''
X_new = pca1.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='o')
plt.show()
 
'''
現在我們看看不直接指定降維的維度,而指定降維後的主成分方差和比例
我們指定了主成分至少佔95%,輸出如下:
 
[ 0.98318212]
[ 3.78483785]
1
 
可見只有第一個投影特徵被保留。這也很好理解,我們的第一個主成分佔投影特徵的方差比例高達98%。
只選擇這一個特徵維度便可以滿足95%的閾值。
'''
pca2 = PCA(n_components=0.95)
pca2.fit(X)
print (pca2.explained_variance_ratio_)
print (pca2.explained_variance_)
print (pca2.n_components_)
 
'''
我們現在選擇閾值99%看看
 此時的輸出如下:
 
[ 0.98318212  0.00850037]
[ 3.78483785  0.03272285]
2
    這個結果也很好理解,因爲我們第一個主成分佔了98.3%的方差比例,第二個主成分佔了0.8%的方差比例,兩者一起可以滿足我們的閾值。
'''
pca3 = PCA(n_components=0.99)
pca3.fit(X)
print (pca3.explained_variance_ratio_)
print (pca3.explained_variance_)
print (pca3.n_components_)
 
'''
最後我們看看讓MLE算法自己選擇降維維度的效果
 輸出結果如下:
 
[ 0.98318212]
[ 3.78483785]
1
 
    可見由於我們的數據的第一個投影特徵的方差佔比高達98.3%,MLE算法只保留了我們的第一個特徵。
'''
pca4 = PCA(n_components='mle') 
#pca4 = PCA()
pca4.fit(X)
print (pca4.explained_variance_ratio_)
print (pca4.explained_variance_)
print (pca4.n_components_)

 

 

 

 

人臉識別實戰  

測試後準確率不是百分之百

算法步驟:

1.用主成分對1850個特徵值降維

2.用svc向量機對人類識別,分類,預測準確性

3.用GridSearchCV網格調參,自動調參(適用於小數據集)

 http://scikit-learn.org/stable/auto_examples/applications/plot_face_recognition.html#sphx-glr-auto-examples-applications-plot-face-recognition-py

The dataset used in this example is a preprocessed excerpt of the “Labeled Faces in the Wild”, aka LFW:

http://vis-www.cs.umass.edu/lfw/lfw-funneled.tgz (233MB)

Expected results for the top 5 most represented people in the dataset:

 

     
Ariel Sharon 0.67 0.92 0.77 13
Colin Powell 0.75 0.78 0.76 60
Donald Rumsfeld 0.78 0.67 0.72 27
George W Bush 0.86 0.86 0.86 146
Gerhard Schroeder 0.76 0.76 0.76 25
Hugo Chavez 0.67 0.67 0.67 15
Tony Blair 0.81 0.69 0.75 36
avg / total 0.80 0.80 0.80 322

 

GridSearchCV,它存在的意義就是自動調參,只要把參數輸進去,就能給出最優化的結果和參數。但是這個方法適合於小數據集,一旦數據的量級上去了,很難得出結果。這個時候就是需要動腦筋了。數據量比較大的時候可以使用一個快速調優的方法——座標下降它其實是一種貪心算法:拿當前對模型影響最大的參數調優,直到最優化再拿下一個影響最大的參數調優,如此下去,直到所有的參數調整完畢。這個方法的缺點就是可能會調到局部最優而不是全局最優,但是省時間省力,巨大的優勢面前,還是試一試吧,後續可以再拿bagging再優化。

 

# -*- coding: utf-8 -*-
"""
Created on Thu Apr  5 22:44:32 2018
 
@author: Administrator
"""
from __future__ import print_function
 
from time import time
import logging
import matplotlib.pyplot as plt
 
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import fetch_lfw_people
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.decomposition import PCA
from sklearn.svm import SVC
 
 
print(__doc__)
 
# Display progress logs on stdout
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')
 
 
# #############################################################################
# Download the data, if not already on disk and load it as numpy arrays
 
lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)
 
# introspect the images arrays to find the shapes (for plotting)
n_samples, h, w = lfw_people.images.shape
 
# for machine learning we use the 2 data directly (as relative pixel
# positions info is ignored by this model)
X = lfw_people.data
n_features = X.shape[1]
 
# the label to predict is the id of the person
y = lfw_people.target
target_names = lfw_people.target_names
n_classes = target_names.shape[0]
 
print("Total dataset size:")
print("n_samples: %d" % n_samples)
print("n_features: %d" % n_features)
print("n_classes: %d" % n_classes)
 
 
# #############################################################################
# Split into a training set and a test set using a stratified k fold
 
# split into a training and testing set
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42)
 
 
# #############################################################################
# Compute a PCA (eigenfaces) on the face dataset (treated as unlabeled
# dataset): unsupervised feature extraction / dimensionality reduction
n_components = 150
 
print("Extracting the top %d eigenfaces from %d faces"
      % (n_components, X_train.shape[0]))
t0 = time()
pca = PCA(n_components=n_components, svd_solver='randomized',
          whiten=True).fit(X_train)
print("done in %0.3fs" % (time() - t0))
 
eigenfaces = pca.components_.reshape((n_components, h, w))
 
print("Projecting the input data on the eigenfaces orthonormal basis")
t0 = time()
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)
print("done in %0.3fs" % (time() - t0))
 
 
# #############################################################################
# Train a SVM classification model
 
print("Fitting the classifier to the training set")
t0 = time()
param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5],
              'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }
clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)
clf = clf.fit(X_train_pca, y_train)
print("done in %0.3fs" % (time() - t0))
print("Best estimator found by grid search:")
print(clf.best_estimator_)
 
 
# #############################################################################
# Quantitative evaluation of the model quality on the test set
 
print("Predicting people's names on the test set")
t0 = time()
y_pred = clf.predict(X_test_pca)
print("done in %0.3fs" % (time() - t0))
 
print(classification_report(y_test, y_pred, target_names=target_names))
print(confusion_matrix(y_test, y_pred, labels=range(n_classes)))
 
 
# #############################################################################
# Qualitative evaluation of the predictions using matplotlib
 
def plot_gallery(images, titles, h, w, n_row=3, n_col=4):
    """Helper function to plot a gallery of portraits"""
    plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
    plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)
    for i in range(n_row * n_col):
        plt.subplot(n_row, n_col, i + 1)
        plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)
        plt.title(titles[i], size=12)
        plt.xticks(())
        plt.yticks(())
 
 
# plot the result of the prediction on a portion of the test set
 
def title(y_pred, y_test, target_names, i):
    pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1]
    true_name = target_names[y_test[i]].rsplit(' ', 1)[-1]
    return 'predicted: %s\ntrue:      %s' % (pred_name, true_name)
 
prediction_titles = [title(y_pred, y_test, target_names, i)
                     for i in range(y_pred.shape[0])]
 
plot_gallery(X_test, prediction_titles, h, w)
 
# plot the gallery of the most significative eigenfaces
 
eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])]
plot_gallery(eigenfaces, eigenface_titles, h, w)
 
plt.show()

 

  

輸出結果

Total dataset size:
n_samples: 1288
n_features: 1850
n_classes: 7
Extracting the top 150 eigenfaces from 966 faces
done in 0.215s
Projecting the input data on the eigenfaces orthonormal basis
done in 0.023s
Fitting the classifier to the training set
done in 23.334s
Best estimator found by grid search:
SVC(C=1000.0, cache_size=200, class_weight='balanced', coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma=0.001, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
Predicting people's names on the test set
done in 0.049s
                   precision    recall  f1-score   support

     Ariel Sharon       0.50      0.69      0.58        13
     Colin Powell       0.80      0.85      0.82        60
  Donald Rumsfeld       0.69      0.74      0.71        27
    George W Bush       0.91      0.89      0.90       146
Gerhard Schroeder       0.82      0.72      0.77        25
      Hugo Chavez       0.83      0.67      0.74        15
       Tony Blair       0.88      0.83      0.86        36

      avg / total       0.84      0.83      0.83       322

[[  9   0   3   1   0   0   0]
 [  2  51   2   4   0   1   0]
 [  5   0  20   2   0   0   0]
 [  2   8   2 130   3   0   1]
 [  0   1   0   3  18   1   2]
 [  0   2   0   1   1  10   1]
 [  0   2   2   2   0   0  30]]

 

 

 

spss應用

 http://jingyan.baidu.com/article/cbf0e500f0a4572eaa28931a.html

因子分析是一種數據簡化的技術,通過研究衆多變量之間的內部依賴關係,探求觀測數據中的基本結構,並用少數幾個假想變量來表示其基本的數據結構。

工具/原料

  • SPSS軟件

  • 數據

1.因子分析

  1. 1

    1.因子分析

    (1)主要思路:降維    簡化數據結構

    (2)目的:將(具有錯綜複雜關係的)變量  綜合爲  (數量較少的)  因子

    以再現   原始變量與因子的關係,  通過不同的因子,對變量進行分類

    消除     相關性,在信息損失最小的情況下,降維

    (3)步驟

    選取因子分析的變量(選相關性較大的,利於降維)――標準化處理;

    根據樣本、估計隨機向量的協方差矩陣或相關矩陣;

    選擇一種方法――估計因子載荷陣,計算關鍵統計特徵;

    進行因子旋轉,使因子含義清晰化,並命名,利用因子解釋變量的構成;

    計算每個因子在各樣本上的得分,得出新的因子得分變量――進一步分析。

    (4)如何分析

    檢驗變量間偏相關度KMO值>0.6,才適合做因子分析;

    調整因子個數,顯示共同特徵後即可命名。

  2. 2

    2.因子分析操作步驟

    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
  3. 3

    3.看看結果吧

    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    END

2.主成分分析

  1.  

    1.主成分分析與因子分析各自特點

    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
  2.  

    2.操作步驟

    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
  3.  

    3.看看結果吧

    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
    大數據分析-SPSS因子與主成分分析
  4.  

 

 

spss-因子分析/主成分分析-乳腺癌細胞

數據來源from sklearn.datasets import load_breast_cancer

KMO指數>0.8,說明變量相關性很強,適合因子分析或主成分分析

Bartlett的sig顯著性爲0,說明也OK,只是bartlett在某些場景參考意義不大

 

從方差解釋來看,癌細胞受到6個因子共同決定,而非單一因素決定,和之前蒙特卡洛模擬結論一致

隨機森林測試和因子分析的方差解釋相差較大,隨機森林更加準確,因子分析方差解釋僅做參考

 

 

 

 

主成分圖

 

旋轉後因子圖,經過和主成分比較,旋轉後因子成分變量參數很多大於0.9,比較顯著,主成分中大於0.9的變量很少

Extraction Method: Principal Component Analysis.
Rotation Method: Varimax with Kaiser Normalization.
Rotation converged in 11 iterations.

 

因子總結結果:

 

 隨機森林測試結果,1000顆樹

 

 

歡迎各位同學學習《python機器學習-乳腺癌細胞挖掘》課程,包含主成分分析和因子分析的python實戰介紹,鏈接地址爲

python機器學習-乳腺癌細胞挖掘( 博主親自錄製)

騰訊課堂報名地址

網易雲課堂報名地址

(微信二維碼掃一掃報名,推薦騰訊課堂報名,有優惠券)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章