PCA的python实现

PCA的python实现

原理部分:

https://blog.csdn.net/ws_developer/article/details/81634059这篇博客介绍的很详细,让我在本子上记了不少东西。

实现:

1.直接调用函数

# -*- coding: utf-8 -*-
"""
Created on Sun Nov  3 10:10:52 2019

@author: Administrator
"""
from sklearn import datasets,decomposition
import matplotlib.pyplot as plt

#Data
digits=datasets.load_digits()
x=digits.data
y=digits.target

#Model
pca=decomposition.PCA()

pca.fit(x)

plt.figure()
plt.plot(pca.explained_variance_,'k')
plt.xlabel('n_components',fontsize=16)
plt.ylabel('explained_variance',fontsize=16)
plt.show()

2.手动实现PCA

# -*- coding: utf-8 -*-
"""
PCA
利用 Numpy Pandas Matplotlib 实现&可视化
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import datasets

        
digits=datasets.load_digits()  
x=digits.data
y=digits.target

class DimensionValueError(ValueError):
    '''定义异常类'''
    pass

class PCA(object):
    '''定义PCA类'''
    
    def __init__(self,x,n_components=None):
        """x的数据结构应为ndarray"""
        self.x=x
        self.dimension=x.shape[1]#维数为列向量的个数
        
        if n_components and n_components>=self.dimension:
            raise DimensionValueError("n_components error")
            
        self.n_components=n_components
    
    '''(1.将原始数据按列组成N行M列的矩阵X)'''

        
    def cov(self):
        '''3.求x的协方差矩阵x_cov'''
        x_T=np.transpose(self.x)#矩阵转置
        print("矩阵x的转置x_T:")
        x_cov=np.cov(x_T)#协方差矩阵
        print("矩阵x的协方差矩阵x_cov:")
        return x_cov
            
    def get_feature(self):
        '''4.求协方差矩阵C的特征值a和特征向量b,并且返回过渡矩阵P'''
        from numpy import linalg as LA #使用前单独import一下
        x_cov=self.cov()
        
        a,b=np.linalg.eig(x_cov)#a是特征值,b是a对应的特征向量
        print("特征值a:")
        print(a)
        print("特征值b:")
        print(b)
        m=a.shape[0]#计算特征值/特征向量个数
        c=np.hstack((a.reshape(m,1),b))#沿着水平方向将数组堆叠起来
        c_df=pd.DataFrame(c)
        c_df_sort=c_df.sort_values(0,ascending=False)#将特征向量按对应的特征值大小从上到下安航排列成矩阵
        print("得到了排好序的特征向量矩阵c_df_sort为:")
        print(c_df_sort)
        print("以上是得到的排好序的特征向量矩阵c_df_sort")
        return c_df_sort
        
    def explained_varience_(self):
        c_df_sort=self.get_feature()
        return c_df_sort.values[:,0]
    
    def paint_varience_(self):
        '''将方差可视化'''
        explained_varience_=self.explained_varience_()
        plt.figure()
        plt.plot(explained_varience_,'k')
        plt.xlabel('n_components',fontsize=16)
        plt.ylabel('explained_varience_',fontsize=16)
        plt.show()
        
    def reduce_dimension(self):
        '''6.指定维度降维和根据方差贡献率自动降维'''
        c_df_sort=self.get_feature() #获得过渡矩阵P
        varience= self.explained_varience_()
        print("varience:")
        print(varience)
        
        #指定降维维数
        if self.n_components:
            p=c_df_sort.values[0:self.n_components,1:]
            y=np.dot(p,np.transpose(self.x))#做矩阵乘法Y=PX ,即矩阵叉乘
            return np.transpose(y)
        
        #根据方差贡献率自动降维
        varience_sum=sum(varience)#方差总和
        varience_radio=varience/varience_sum#每个方差所占方差总和的比例/
        
        varience_contribution=0#初始化方差贡献率=0,加下来计算
        for R in range(self.dimension):
            varience_contribution+=varience_radio[R]#前R个方差贡献度之和
            if varience_contribution>=0.99:
                break
            
        p=c_df_sort.values[0:R+1,1:]#取前R个特征向量
        y=np.dot(p,np.transpose(self.x))#矩阵叉乘得到降维后的结果矩阵Y=PX
        return np.transpose(y)
        
if __name__=='__main__':
    pca=PCA(x)
    y=pca.reduce_dimension()
    pca.paint_varience_()
    
    
    
    
    
    
    

主要使用了线性代数的知识。

1的结果

2的结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值