PCA降维

3 篇文章 0 订阅
3 篇文章 0 订阅

关于PCA算法在机器学习中是经常会用到,特别在维度数比较大的情况下,为了提取主要的维度成分,使用PCA对维度进行降维操作,一方面在保证数据高精确性情况下,另一方面减少维度数量,降低由于维度带来的运算资源的消耗及运算的时间消耗 。PCA能够有效解决因维度带来的灾难。

关于PCA的原理在很多书本、博客等地方都有所介绍,关于原理在这里不再详述。在这里我主要介绍PCA在matlab及python的实现。

关于matlab的实现:

%% 打开文件
fileID = fopen('FIFA2018 Statistics.csv','r','n','utf-8');
%% 加载表头
C = textscan(fileID,'%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s',1,'delimiter',',','EmptyValue',0,'EndOfLine','\r\n');
%% 每次读取数据均为全量读取
%% 加载数据 ,不要 diff_max_login_time 和 shensu_detail_flag 字段
data=textscan(fileID,'%s %s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %s %f %s %s %f %f %f','delimiter',',','EmptyValue',0,'EndOfLine','\r\n');
%% 关闭文件
fclose(fileID);

%% 归一化
data=cat(2,data{5:10})';
[pn,minp,maxp]=premnmx(data);

%% 调动PCA提取个指标的特征,以95%的信息为主
% [p,princ,egenvalue]=princomp(pn');
%  p主成分系数
%  princ主成分得分
%  egenvalue主成分的特征根

[coeff, score, latent, tsquared, explained] = pca(pn');
% coeff 主成分系数,一列一个主成分系数
% score 主成分得分,
% latent 主成分的特征根
% tsquared 是Hotelling的T2检验,Hotelling的T2检验统计量是描述每一测量值与数据中心距离的统计量,用它可以找到数据中的极值点:
% explained 为各主成分的贡献率

%% 求累计贡献率
sum_explained=cumsum(explained,1);
%% 得到累计贡献率>95%的主成分个数
pos=find(sum_explained>95);

%% 根据累计贡献率>95%为准,计算每个uid的分值
contribute = zeros(size(pn,2),1);
for k=1:pos(1)
    contribute = explained(k,1)/100.*score(:,k) + contribute;
end

主要成分系数:

特征根:

关于python的实现:

# -*- coding: utf-8 -*-
"""
Created on Tue Jul 31 20:52:42 2018

@author: linxiaojie
"""

import numpy as np
import pandas as pd


'''通过方差的百分比来计算将数据降到多少维是比较合适的,
函数传入的参数是特征值和百分比percentage,返回需要降到的维度数num'''
def eigValPct(eigVals,percentage):
    sortArray=np.sort(eigVals) #使用numpy中的sort()对特征值按照从小到大排序
    sortArray=sortArray[-1::-1] #特征值从大到小排序
    arraySum=np.sum(sortArray) #数据全部的方差arraySum
    tempSum=0
    num=0
    for i in sortArray:
        tempSum+=i
        num+=1
        if tempSum>=arraySum*percentage:
            return num

'''pca函数有两个参数,其中dataMat是已经转换成矩阵matrix形式的数据集,列表示特征;
其中的percentage表示取前多少个特征需要达到的方差占比,默认为0.9'''
def pca(dataMat,percentage=0.9):
    meanVals=np.mean(dataMat,axis=0)  #对每一列求平均值,因为协方差的计算中需要减去均值
    
    meanRemoved=dataMat-meanVals
    
    covMat=np.cov(meanRemoved,rowvar=0)  #cov()计算方差
        
    eigVals,eigVects=np.linalg.eig(np.mat(covMat))  #利用numpy中寻找特征值和特征向量的模块linalg中的eig()方法
    
    print(eigVects)
    
    k=eigValPct(eigVals,percentage) #要达到方差的百分比percentage,需要前k个向量
    
    eigValInd=np.argsort(eigVals)  #对特征值eigVals从小到大排序
    
    eigValInd=eigValInd[:-(k+1):-1] #从排好序的特征值,从后往前取k个,这样就实现了特征值的从大到小排列
    
    redEigVects=eigVects[:,eigValInd]   #返回排序后特征值对应的特征向量redEigVects(主成分)
    
    lowDDataMat=meanRemoved*redEigVects #将原始数据投影到主成分上得到新的低维数据lowDDataMat
    
    reconMat=(lowDDataMat*redEigVects.T) + meanVals   #得到重构数据reconMat
    
    return lowDDataMat,reconMat, eigVals, eigVects

# 对目标进行归一化操作,其中归一化的范围为[-1,1]之间,其中一列一个样本
def np_premnmx(data_array):
   min_1=np.min(data_array, axis=1)[:,np.newaxis]   # 按行求最小值
   max_1=np.max(data_array, axis=1)[:,np.newaxis]   # 按行求最大值
   an=2*(data_array-min_1)/(max_1-min_1)-1          # 矩阵点除 
   return an,min_1,max_1 

if __name__ == "__main__":
    df = pd.read_csv('FIFA2018 Statistics.csv')
    values = df.values
    # 转换为numpy的array
    source_data = values[:,4:10].astype('float32').T
    # 对矩阵按列进行归一化
    dataMat, min_1,max_1 = np_premnmx(source_data)
    # 进行pca分析
    lowDDataMat,reconMat, eigVals, eigVects = pca(dataMat.T,percentage=0.95)
    

主要成分系数:

特征根:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值