1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 【数据挖掘】主成分分析Python实现

【数据挖掘】主成分分析Python实现

时间:2023-01-20 10:49:26

相关推荐

【数据挖掘】主成分分析Python实现

目录

前言数据预处理导入库读取数据将五种癌症数据集合并进行主成分分析计算样本均值计算样本协方差矩阵计算特征值和特征向量计算累计方差贡献率特征向量选取结果可视化数据降维降维前降维后写在最后

前言

是对一个数据挖掘作业的记录,数据集是老师提供的几种癌症的数据,我是直接在Jupyter中写的,中间会输出一些内容验证之类的

主要是参照这位写的:参考的大佬

数据预处理

导入库

import numpy as npimport pandas as pdimport matplotlib.pyplot as plt

读取数据

# 读取数据,查看数据的规模BLCA_data = pd.read_csv(r'数据集/BLCA/rna.csv')print('BLCA',BLCA_data.shape)BRCA_data = pd.read_csv(r'数据集/BRCA/rna.csv')print('BRCA',BRCA_data.shape)KIRC_data = pd.read_csv(r'数据集/KIRC/rna.csv')print('KIRC',KIRC_data.shape)LUAD_data = pd.read_csv(r'数据集/LUAD/rna.csv')print('LUAD',LUAD_data.shape)PAAD_data = pd.read_csv(r'数据集/PAAD/rna.csv')print('PAAD',PAAD_data.shape)

BLCA (3217, 400)BRCA (3217, 1032)KIRC (3217, 489)LUAD (3217, 491)PAAD (3217, 177)

# 查看其中一种类型癌症数据集的前6行BLCA_data.head(6)

6 rows × 400 columns

# 查看另一种癌症数据集的前6行BRCA_data.head(6)

6 rows × 1032 columns

经过上面的分析可以知道对于不同的数据集,它们的行数和行标签都是相同的,但列数和列标签都是不同的

所以对于这些数据集来说,行标签可以看作是数据的不同特征,而每一列则对应一个样本的数据

保留第一个数据集的第一列,然后将其与后面几个数据集除第一列之外的列进行合并

则:

BLCA:1-400

BRCA:401-1431

KIRC:1432-1919

LUAD:1920-2409

PAAD:2410-2585

将五种癌症数据集合并

# 将5种癌症数据集的除gene_id列之外的列进行合并DataSet = pd.concat([BLCA_data,BRCA_data.iloc[:,1:],KIRC_data.iloc[:,1:],LUAD_data.iloc[:,1:],PAAD_data.iloc[:,1:]], axis=1)DataSet.head(6)

6 rows × 2585 columns

对数据集进行转置,之后每一行对应一个样本数据,每一列表示一个样本特征

DataSet = DataSet.TDataSet.head(6)

6 rows × 3217 columns

# 此时第一行为特征标签,将非数据的这一行去掉DataSet = DataSet.iloc[1:,:]

DataSet.iloc[:6,:]

6 rows × 3217 columns

# 重新设置数据类型,此时DataSet为一个2584x3217的浮点数矩阵DataSet = DataSet.astype('float32')print(DataSet.shape)

(2584, 3217)

进行主成分分析

计算样本均值

Mean_vec = np.mean(DataSet, axis=0)print('样本的均值:\n',Mean_vec)

样本的均值:0-1.1615481-0.4741332-1.2511743 2.4122484 0.266737... 3212 0.5217863213 1.3030513214 0.1335733215 0.7748023216 0.601425Length: 3217, dtype: float32

计算样本协方差矩阵

'''# 纯数据运算Cov_mat = (DataSet-Mean_vec).T.dot(DataSet-Mean_vec)/(DataSet.shape[0]-1)print('协方差矩阵:\n',Cov_mat)'''

# 使用numpy中计算协方差的函数'''协方差矩阵用于衡量两个变量之间相互依赖的程度由于有3217个feature,故协方差矩阵的规模为3217x3217'''Cov_mat = np.cov(DataSet.T)print('样本协方差矩阵:\n',Cov_mat)Cov_mat.shape

样本协方差矩阵:[[ 0.12676448 -0.02361515 0.02157561 ... 0.00519793 0.009049920.00673015][-0.02361515 1.00118482 -0.0053748 ... 0.07527039 -0.177148640.0090866 ][ 0.02157561 -0.0053748 0.13757093 ... 0.00533166 -0.001342670.00309703]...[ 0.00519793 0.07527039 0.00533166 ... 0.22596547 0.029699780.01703536][ 0.00904992 -0.17714864 -0.00134267 ... 0.02969978 0.203644390.04410373][ 0.00673015 0.0090866 0.00309703 ... 0.01703536 0.044103730.13098872]](3217, 3217)

计算特征值和特征向量

EigenValues, EigenVector = np.linalg.eig(Cov_mat)# 数据特征量较大,这里计算结果为复数,统一取其实部EigenValues = EigenValues.realEigenVector = EigenVector.realprint('特征值:\n',EigenValues)print('特征向量:\n',EigenVector)

特征值:[ 2.31279350e+02 1.46770122e+02 8.81143724e+01 ... 2.86122668e-172.84073038e-17 -3.1215e-17]特征向量:[[ 0.00030864 -0.00113702 -0.00123991 ... -0.00242919 -0.002773210.00190791][-0.02456387 0.02533867 -0.05603828 ... 0.00124872 0.00140361-0.00075202][-0.00023562 -0.00033786 -0.00340553 ... -0.00034539 -0.000392860.00087827]...[-0.00238575 0.00450426 -0.01746374 ... -0.00422026 -0.004229030.00272333][ 0.00781593 -0.02092816 0.00775456 ... 0.01314091 0.012727750.01905482][-0.0030166 -0.01263667 -0.0111954 ... 0.02344654 0.031394160.01099676]]

# EigenPairs[i][0]表示一个特征值,EigenPairs[i][1]表示该特征值所对应的特征向量EigenPairs = [(np.abs(EigenValues[i]), EigenVector[:,i]) for i in range(len(EigenValues))]EigenPairs.sort(key=lambda x:x[0], reverse=True)print('特征值降序排列:')for i in EigenPairs:print(i[0])

特征值降序排列:231.2793503404339146.7701215257230688.11437236590861......1.6398199526831266e-181.4276145590349296e-181.4276145590349296e-18

计算累计方差贡献率

# 计算方差贡献率tot = sum(EigenValues)var_exp = [(i/tot)*100 for i in sorted(EigenValues, reverse=True)]print(var_exp)# 累计方差贡献率Cum_var_exp = np.cumsum(var_exp)Cum_var_exp

[18.501009256397158, 11.740760136661512, ... , -1.3125279499634018e-16, -2.0754934203007648e-16]array([ 18.50100926, 30.24176939, 37.29040913, ..., 100., 100. , 100.])

特征向量选取

## 这里为方便作图,选取特征值较大的前两维的特征向量Matrix = np.hstack((EigenPairs[0][1].reshape(DataSet.shape[1], 1),EigenPairs[1][1].reshape(DataSet.shape[1], 1)))print('Matrix:\n',Matrix)

Matrix:[[ 0.00030864 -0.00113702][-0.02456387 0.02533867][-0.00023562 -0.00033786]...[-0.00238575 0.00450426][ 0.00781593 -0.02092816][-0.0030166 -0.01263667]]

结果可视化

数据降维

# tmp主要是将DaraSet转成array类型HighDimSet = DataSet.iloc[:,:].values# 将原数据矩阵乘以选取的特征向量进行降维LowDimSet = HighDimSet.dot(Matrix)LowDimSet

array([[ -2.78179211, 7.81840477],[-13.39504631, 7.30085955],[-16.8183728 , 3.87839756],...,[ -5.81835218, 8.30323684],[ -8.52738732, 8.17363152],[ -6.97177986, 11.89669388]])

降维前

# LabelSet标识哪一行样本属于哪种癌症LabelSet = ['BLCA']*399+['BRCA']*1031+['KIRC']*488+['LUAD']*490+['PAAD']*176LabelSet = np.array(LabelSet)LabelSet

array(['BLCA', 'BLCA', 'BLCA', ..., 'PAAD', 'PAAD', 'PAAD'], dtype='<U4')

# 选取两种特征对不同的癌症种类进行区分plt.figure(figsize=(10,6), dpi=80)plt.xlim(-3,3)plt.ylim(-3,3)for lab,color in zip(('BLCA', 'BRCA', 'KIRC', 'LUAD', 'PAAD'),('red','yellow','green','blue','purple')):plt.scatter(HighDimSet[LabelSet==lab,0],HighDimSet[LabelSet==lab,1],label=lab,c=color)plt.xlabel('feature 1')plt.ylabel('feature 2')plt.legend(loc='upper right')plt.show()

降维后

plt.figure(figsize=(10,6), dpi=80)plt.xlim(-25,40)plt.ylim(-30,25)for lab,color in zip(('BLCA', 'BRCA', 'KIRC', 'LUAD', 'PAAD'),('red','yellow','green','blue','purple')):plt.scatter(LowDimSet[LabelSet==lab,0],LowDimSet[LabelSet==lab,1],label=lab,c=color)plt.xlabel('principal component 1')plt.ylabel('principal component 2')plt.legend(loc='upper right')plt.show()

写在最后

文章仅作记录,至于原理还有很多不懂的地方,结果我也不知道该是什么样的,把用这么多维特征来区分的事物降到两维来进行区分,我自己感觉已经很神奇了哈哈!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。