主成分分析 matlab手把手教操作、SPSS、python實例分析


更新:

  這次決定用matlab手把手一步一步實現一遍。

是一個的觀測矩陣,觀測向量的樣本均值M,由下式給出:

  Matlab中我們給出矩陣.

       

  用a,b度量矩陣X的行列數並分別計算每一列計算M的值

     

  樣本均值是散列圖的中心,對,令

   

矩陣的列

具有零樣本均值,這樣的B稱為平均偏差形式。

     

主成分分析的目標是找到一個正交矩陣,確定一個變量代換,並具有新的變量y1,...,yp兩兩無關的性質,且整理后的方差具有遞減順序。

變量的正交變換說明,每一個觀測向量Xk得到一個“新名稱”Yk,使得,注意到Yk相對於以P的列為基的坐標向量。為對角形,P記為正交矩陣,它的列是單位特征向量,那么.

 

(樣本)協方差矩陣是一個矩陣S,其定義為:

   

由於任何具有形式的矩陣是半正定的,所以S也是半正定的。

 

數據的總方差是指S中對角線上方差的綜合。一般地,一個方陣S中對角元素之和稱為矩陣的跡,記作tr(S),這樣

{總方差}=tr{S}

S中的元素稱為xixj的協方差。   

    

將特征值從大到小排序,取貢獻率到90%的前k個特征。

     

可得到P、D

    

 下面貼完整代碼:

 

clc;
clear all;
close all;

X=[2.5 2.4;
   0.5 0.7;
   2.2 2.9;
   1.9 2.2;
   3.1 3.0;
   2.3 2.7;
   2 1.6;
   1 1.1;
   1.5 1.6;
   1.1 0.9;];
X=X'

% X=[74 87 84 88 74 86 69 73 64;
%    85 83 83 77 69 84 74 85 84;
%    83 91 89 85 87 86 83 86 85;
%    69 100 82 96 84 82 97 98 76;
%    97 48 89 36 46 53 88 89 97;
%    59 98 93 94 98 100 79 83 61;];
% X=X';

% X=[2 0 -1.4;
%    2.2 0.2 -1.5;
%    2.4 0.1 -1;
%    1.9 0 -1.2;];
% X=X';
[a,b]=size(X);
M=sum(X)/a;


for i=1:b
    B(:,i)=X(:,i)-M(i);
    %B=zscore(X);
end

S=1/(a-1)*B*B';
[vector,value]=eig(S);
vector
value=diag(value)
varine=sum(value);

[value_sort,subscript]=sort(value,'descend');
value_sort;
subscript;
value_sort=value_sort/sum(value_sort);
compare=0;
sign=0;
for i=1:b
    if compare<0.9
        sign=sign+1;
        compare=compare+value_sort(i);
    end
end

for i=1:sign
    P(:,i)=vector(:,subscript(i));
end
P

D=zeros(sign,sign);
for i=1:sign
    D(i,i)=value(subscript(i));
end
D

  

 


 

  主成分分析(Principal Component Analysis,PCA), 是一種統計方法。通過正交變換將一組可能存在相關性的變量轉換為一組線性不相關的變量,轉換后的這組變量叫主成分。

  主成分分析,是考察多個變量間相關性一種多元統計方法,研究如何通過少數幾個主成分來揭示多個變量間的內部結構,即從原始變量中導出少數幾個主成分,使它們盡可能多地保留原始變量的信息,且彼此間互不相關.通常數學上的處理就是將原來P個指標作線性組合,作為新的綜合指標。

  簡單說,主成分分析的作用是降維。通過降維將原來多變量解釋的問題,映射到更少指標,轉換成少變量的可解釋性問題。但是注意經過主成分分析后的變量與原變量不存在邏輯關系,僅僅是存在線性組合的關系。[1]

 一、算法原理:


 

輸入:樣本集D={x1,x2...xm};

   低維空間維數d'.

過程:

1.對所有樣本進行中心化:

2.計算樣本的協方差矩陣XXT

3.對協方差矩陣XXT做特征值分解;

4.取最大的d'個特征值所對應的特征向量w1,w2...wd';

輸出:投影矩陣W*=(w1,w2...wd') .[2]


 

二、PCA原理

  

  

  

 

 

 

三、SPSS進行主成分分析

  由於SPSS本身就是一個用於數據分析的軟件,因此操作簡單無需編程,即可直觀感受主成分分析帶來的效果。

  先胡亂編制了一些數據:

  

  

  在SPSS里,點擊分析->降維->因子,在彈出的對話框中,將需要分析的變量都送入變量欄中。根據個人需要在描述、提取、旋轉、得分、選項中勾選。此處我們注意在提取勾選主成分。

  

 

點擊“確定”: 

  

  

最后我們可以看到提取了兩個主成分

  

 

  

觀察兩個主成分中的貢獻率,我們會發現第一個主成分包含貢獻率較高的項為數學、物理、化學、生物,實際意義即理科,第二主成分包含歷史、地理,即文科。具有良好解釋性。

 

四、python代碼實現主成分分析

pca.py

# -*- coding: utf-8 -*-
"""
Created on Sun Feb 28 10:04:26 2016
PCA source code
@author: liudiwei
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#計算均值,要求輸入數據為numpy的矩陣格式,行表示樣本數,列表示特征    
def meanX(dataX):
    return np.mean(dataX,axis=0)#axis=0表示按照列來求均值,如果輸入list,則axis=1


#計算方差,傳入的是一個numpy的矩陣格式,行表示樣本數,列表示特征    
def variance(X):
    m, n = np.shape(X)
    mu = meanX(X)
    muAll = np.tile(mu, (m, 1))    
    X1 = X - muAll
    variance = 1./m * np.diag(X1.T * X1)
    return variance

#標准化,傳入的是一個numpy的矩陣格式,行表示樣本數,列表示特征    
def normalize(X):
    m, n = np.shape(X)
    mu = meanX(X)
    muAll = np.tile(mu, (m, 1))    
    X1 = X - muAll
    X2 = np.tile(np.diag(X.T * X), (m, 1))
    XNorm = X1/X2
    return XNorm

"""
參數:
	- XMat:傳入的是一個numpy的矩陣格式,行表示樣本數,列表示特征    
	- k:表示取前k個特征值對應的特征向量
返回值:
	- finalData:參數一指的是返回的低維矩陣,對應於輸入參數二
	- reconData:參數二對應的是移動坐標軸后的矩陣
"""  
def pca(XMat, k):
    average = meanX(XMat) 
    m, n = np.shape(XMat)
    data_adjust = []
    avgs = np.tile(average, (m, 1))
    data_adjust = XMat - avgs
    covX = np.cov(data_adjust.T)   #計算協方差矩陣
    featValue, featVec=  np.linalg.eig(covX)  #求解協方差矩陣的特征值和特征向量
    index = np.argsort(-featValue) #按照featValue進行從大到小排序
    finalData = []
    if k > n:
        print("k must lower than feature number")
        return
    else:
        #注意特征向量時列向量,而numpy的二維矩陣(數組)a[m][n]中,a[1]表示第1行值
        selectVec = np.matrix(featVec.T[index[:k]]) #所以這里需要進行轉置
        finalData = data_adjust * selectVec.T 
        reconData = (finalData * selectVec) + average  
    return finalData, reconData

def loaddata(datafile):
    return np.array(pd.read_csv(datafile,sep="\t",header=-1)).astype(np.float)


def plotBestFit(data1, data2):	  
    dataArr1 = np.array(data1)
    dataArr2 = np.array(data2)
    
    m = np.shape(dataArr1)[0]
    axis_x1 = []
    axis_y1 = []
    axis_x2 = []
    axis_y2 = []
    for i in range(m):
        axis_x1.append(dataArr1[i,0])
        axis_y1.append(dataArr1[i,1])
        axis_x2.append(dataArr2[i,0]) 
        axis_y2.append(dataArr2[i,1])				  
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(axis_x1, axis_y1, s=50, c='red', marker='s')
    ax.scatter(axis_x2, axis_y2, s=50, c='blue')
    plt.xlabel('x1'); plt.ylabel('x2');
    plt.savefig("outfile.png")
    plt.show()	

#簡單測試
#數據來源:http://www.cnblogs.com/jerrylead/archive/2011/04/18/2020209.html
def test():
    X = [[2.5, 0.5, 2.2, 1.9, 3.1, 2.3, 2, 1, 1.5, 1.1],
         [2.4, 0.7, 2.9, 2.2, 3.0, 2.7, 1.6, 1.1, 1.6, 0.9]]
    XMat = np.matrix(X).T  
    k = 2
    return pca(XMat, k)

#根據數據集data.txt
def main():    
    datafile = "data.txt"
    XMat = loaddata(datafile)
    k = 2
    return pca(XMat, k)
    
if __name__ == "__main__":
    finalData, reconMat = main()
    plotBestFit(finalData, reconMat)

 

data.txt

5.1	3.5	1.4	0.2
4.9	3.0	1.4	0.2
4.7	3.2	1.3	0.2
4.6	3.1	1.5	0.2
5.0	3.6	1.4	0.2
5.4	3.9	1.7	0.4
4.6	3.4	1.4	0.3
5.0	3.4	1.5	0.2
4.4	2.9	1.4	0.2
4.9	3.1	1.5	0.1
5.4	3.7	1.5	0.2
4.8	3.4	1.6	0.2
4.8	3.0	1.4	0.1
4.3	3.0	1.1	0.1
5.8	4.0	1.2	0.2
5.7	4.4	1.5	0.4
5.4	3.9	1.3	0.4
5.1	3.5	1.4	0.3
5.7	3.8	1.7	0.3
5.1	3.8	1.5	0.3
5.4	3.4	1.7	0.2
5.1	3.7	1.5	0.4
4.6	3.6	1.0	0.2
5.1	3.3	1.7	0.5
4.8	3.4	1.9	0.2
5.0	3.0	1.6	0.2
5.0	3.4	1.6	0.4
5.2	3.5	1.5	0.2
5.2	3.4	1.4	0.2
4.7	3.2	1.6	0.2
4.8	3.1	1.6	0.2
5.4	3.4	1.5	0.4
5.2	4.1	1.5	0.1
5.5	4.2	1.4	0.2
4.9	3.1	1.5	0.1
5.0	3.2	1.2	0.2
5.5	3.5	1.3	0.2
4.9	3.1	1.5	0.1
4.4	3.0	1.3	0.2
5.1	3.4	1.5	0.2
5.0	3.5	1.3	0.3
4.5	2.3	1.3	0.3
4.4	3.2	1.3	0.2
5.0	3.5	1.6	0.6
5.1	3.8	1.9	0.4
4.8	3.0	1.4	0.3
5.1	3.8	1.6	0.2
4.6	3.2	1.4	0.2
5.3	3.7	1.5	0.2
5.0	3.3	1.4	0.2
7.0	3.2	4.7	1.4
6.4	3.2	4.5	1.5
6.9	3.1	4.9	1.5
5.5	2.3	4.0	1.3
6.5	2.8	4.6	1.5
5.7	2.8	4.5	1.3
6.3	3.3	4.7	1.6
4.9	2.4	3.3	1.0
6.6	2.9	4.6	1.3
5.2	2.7	3.9	1.4
5.0	2.0	3.5	1.0
5.9	3.0	4.2	1.5
6.0	2.2	4.0	1.0
6.1	2.9	4.7	1.4
5.6	2.9	3.6	1.3
6.7	3.1	4.4	1.4
5.6	3.0	4.5	1.5
5.8	2.7	4.1	1.0
6.2	2.2	4.5	1.5
5.6	2.5	3.9	1.1
5.9	3.2	4.8	1.8
6.1	2.8	4.0	1.3
6.3	2.5	4.9	1.5
6.1	2.8	4.7	1.2
6.4	2.9	4.3	1.3
6.6	3.0	4.4	1.4
6.8	2.8	4.8	1.4
6.7	3.0	5.0	1.7
6.0	2.9	4.5	1.5
5.7	2.6	3.5	1.0
5.5	2.4	3.8	1.1
5.5	2.4	3.7	1.0
5.8	2.7	3.9	1.2
6.0	2.7	5.1	1.6
5.4	3.0	4.5	1.5
6.0	3.4	4.5	1.6
6.7	3.1	4.7	1.5
6.3	2.3	4.4	1.3
5.6	3.0	4.1	1.3
5.5	2.5	4.0	1.3
5.5	2.6	4.4	1.2
6.1	3.0	4.6	1.4
5.8	2.6	4.0	1.2
5.0	2.3	3.3	1.0
5.6	2.7	4.2	1.3
5.7	3.0	4.2	1.2
5.7	2.9	4.2	1.3
6.2	2.9	4.3	1.3
5.1	2.5	3.0	1.1
5.7	2.8	4.1	1.3
6.3	3.3	6.0	2.5
5.8	2.7	5.1	1.9
7.1	3.0	5.9	2.1
6.3	2.9	5.6	1.8
6.5	3.0	5.8	2.2
7.6	3.0	6.6	2.1
4.9	2.5	4.5	1.7
7.3	2.9	6.3	1.8
6.7	2.5	5.8	1.8
7.2	3.6	6.1	2.5
6.5	3.2	5.1	2.0
6.4	2.7	5.3	1.9
6.8	3.0	5.5	2.1
5.7	2.5	5.0	2.0
5.8	2.8	5.1	2.4
6.4	3.2	5.3	2.3
6.5	3.0	5.5	1.8
7.7	3.8	6.7	2.2
7.7	2.6	6.9	2.3
6.0	2.2	5.0	1.5
6.9	3.2	5.7	2.3
5.6	2.8	4.9	2.0
7.7	2.8	6.7	2.0
6.3	2.7	4.9	1.8
6.7	3.3	5.7	2.1
7.2	3.2	6.0	1.8
6.2	2.8	4.8	1.8
6.1	3.0	4.9	1.8
6.4	2.8	5.6	2.1
7.2	3.0	5.8	1.6
7.4	2.8	6.1	1.9
7.9	3.8	6.4	2.0
6.4	2.8	5.6	2.2
6.3	2.8	5.1	1.5
6.1	2.6	5.6	1.4
7.7	3.0	6.1	2.3
6.3	3.4	5.6	2.4
6.4	3.1	5.5	1.8
6.0	3.0	4.8	1.8
6.9	3.1	5.4	2.1
6.7	3.1	5.6	2.4
6.9	3.1	5.1	2.3
5.8	2.7	5.1	1.9
6.8	3.2	5.9	2.3
6.7	3.3	5.7	2.5
6.7	3.0	5.2	2.3
6.3	2.5	5.0	1.9
6.5	3.0	5.2	2.0
6.2	3.4	5.4	2.3
5.9	3.0	5.1	1.8

  代碼運行結果:

 

參考文獻:

[1] https://baike.baidu.com/item/%E4%B8%BB%E6%88%90%E5%88%86%E5%88%86%E6%9E%90/829840?fr=aladdin

[2]周志華,機器學習,清華大學出版社,2016年1月1版.

 

2019-03-09

00:05:40


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM