用Python试一下PCA和SVM

python之whl文件下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/
Python教程之RUNOOK:https://www.runoob.com/python3/python3-data-type.html
Python教程之廖雪峰大神:https://www.liaoxuefeng.com/wiki/1016959663602400

环境

win7,x64,python3.6

# python版本查看
python --version

安装模块

numpy,mkl,scipy,sklearn(scikit_learn),matplotlib等等
在windows系统中打开命令行窗口cmd,然后使用pip install numpy安装。但是有的时候报错,这个时候直接去开头给的那个下载whl文件的地址下载需要的whl文件,然后pip install E://XX.whl。具体如下:

pip install numpy
pip install scipy
pip install scikit-learn
# 如果出错,用下面这个试试
# pip install --user --ignore-installed  scikit-learn
# 要卸载某个包
# pip uninstall XX
# 检查一下是否正确安装,以及能否正常导入
# 先打开Python,然后输入
import sklearn
# 或者
from sklearn import datasets
# 可以用下面的语句来查看版本信息
# 注意:需要查看某个module的version,需要先import
# 此外,version前后都是两个下划线
scipy.__version__

关于numpy-mkl我安装了这个:
用Python试一下PCA和SVM_第1张图片

读入数据

每一个txt文件中是141×6670的矩阵,每一行是把相应的时间点上的116×116的脑区相关系数R的矩阵的右上角张开后得到的,不包含对角线元素。
一共是68个数据文件,rA*开头的是Alcohol的数据,rP开头的是Placebo的数据。
Python如何把txt的文件读进来:
1.用fp=fopen('C://')的方式,具体如下面这个链接中的文章:
Python读写txt文本文件
2.上面的方法是直接读入,数据之间是以\t以及\n的形式分隔开的,不符合Python常用的List格式,所以又用了下面这个链接中给的方法:
python:如何将txt文件中的数值数据读入到list中,且在list中存在的格式为float类型或者其他数值类型
但是PCA好像需要的是array数据,于是:
python:将txt文档中是数值型数据读入到array数组中
另外一篇:
Python 读取TXT文本数据并存为 array

#-*-coding:UTF-8 -*-
import numpy as np
def loadDatadet(infile,k):
    f=open(infile,'r')
    sourceInLine=f.readlines()
    dataset=[]
    for line in sourceInLine:
        temp1=line.strip('\n')
        temp2=temp1.split('\t')
        dataset.append(temp2)
    for i in range(0,len(dataset)):
        for j in range(k):
            dataset[i].append(float(dataset[i][j]))
        del(dataset[i][0:k])
    return dataset
infile='C:/Users/Ellie/Desktop/rA01.txt'
k=6670
# k是数据的列数
infile=np.array(loadDatadet(infile,k))
#print('dataset=',infile)

判断变量的类型,可以使用type(X)或者isinstance(X,list)其中x为变量名,isinstance可以判断是否为int,list,tuple,dict,str。
使用type(infile)发现上述的代码得到的inflie变量是一个numpy.ndarray的变量
关于这种变量类型可以看:Python: NumPy中的多维数组ndarray

PCA

下列代码的出处是用Python的sklearn库进行PCA(主成分分析)

import numpy as np
from sklearn.decomposition import PCA
#X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) 
# 这里我打算用一下上面获得的numpy.ndarray的数据试试,即infile,然后失败了
pca = PCA(n_components='mle')
pca.fit(infile)
# PCA(copy=True, n_components=2, whiten=False)
print(pca.explained_variance_ratio_)
#[ 0.99244291]

再次数据转换

以下代码来自python:如何将txt文件中的数值数据读入到list中,且在list中存在的格式为float类型或者其他数值类型

import numpy as np
def loadDatadet(infile,k):
    f=open(infile,'r')
    sourceInLine=f.readlines()
    dataset=[]
    for line in sourceInLine:
        temp1=line.strip('\n')
        temp2=temp1.split('\t')
        dataset.append(temp2)
    for i in range(0,len(dataset)):
        for j in range(k):
            dataset[i].append(float(dataset[i][j]))
           # dataset[i].append(eval(dataset[i][j]))
        del(dataset[i][0:k])
    return dataset
infile='C:/Users/Ellie/Desktop/rA01.txt'
k=6
# k=6670
infile=loadDatadet(infile,k)
#print('dataset=',infile)

这一步之后,使用isinstance(infile,list)得到True的结果,说明的确是转成了一个list。然后接下来用这个文章里给的方法把list转成array。也就是:

data_array = np.array(infile)

但是生成的data_array还是numpy.ndarray类型,然后使用PCA还是报错,好像是因为infile中的数据是str类型而不是float类型,于是我使用type(infile[0][0])查看了一下第一行第一列的数字,发现类型的确是str,而非参考文章中说的转成了float。
试一下这个:

type(eval(infile[0][0]))
#float
type(float(infile[0][0]))
#float

eval和float都可以将infile中的单个str变量转换成float类型,但是在上述的数据转换代码中float或者eval函数都没有将infile中的str变量转换成float形式,我觉得有点迷_(¦3」∠)_

我改了一下上面转换数据的代码,如下:

def loadDatadet(infile,k):
    f=open(infile,'r')
    sourceInLine=f.readlines()
    dataset=[]
    for line in sourceInLine:
        temp1=line.strip('\n')
        temp2=temp1.split('\t')
        temp2=temp2[0:-1]    # 这里我删掉了最后一个元素
        for l in range(0,len(temp2)):
          temp2[l]=float(temp2[l])
        dataset.append(temp2)
    return dataset
infile='C:/Users/Ellie/Desktop/rA01.txt'
# 由于我使用了整个txt中的数据,而不是只选择前k列,所以可以不需要k这个变量
# k=6
# k=6670
infile=loadDatadet(infile,k)
#print('dataset=',infile)

现在再使用type(infile[0][0])得到的结果是float了,len(infile)得到的结果是141(表示有141行),len(infile[0])得到的结果是6670(表示有6670列)。
接着再试试PCA!
发现上面使用的pca = PCA(n_components='mle')会产生错误:n_components=‘mle’ is only supported if n_samples >= n_features
所以改成了下面的代码

import numpy as np
from sklearn.decomposition import PCA
#X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) 
# 这里我打算用一下上面获得的numpy.ndarray的数据试试,即infile,然后失败了
#pca = PCA(n_components='mle')  #改成下面这一行
pca = PCA(n_components=2)
#pca = PCA(n_components=4)  #这个得到的结果是[0.050329096 0.25107173 0.08610606 0.04222297]后面两个解释的方差很小,所以还是选用2个主成分
pca.fit(infile)
# PCA(copy=True, n_components=2, whiten=False)
print(pca.explained_variance_ratio_)
#[0.050329096 0.25107173]

用下面的代码查看降维后的数据:

newX=pca.fit_transform(infile)  #newX就是降维后的数据

!!我发现了一篇超级良心的文章:用scikit-learn学习主成分分析(PCA)

待续…

1.用Kernel PCA?

  • Kernel PCA用于非线性数据的降维,需要对核函数和参数进行调节。有需要可以看这一篇:机器学习算法(降维)总结及sklearn实践——主成分分析(PCA)、核PCA、LLE、流形学习

2.PCA的参数优化

  • PCA的参数优化主要是针对Kernel PCA的,参考可以同上一个问题。

3.PCA得到的数据如何在SVM中使用?

  • PCA得到降维后的数据为new_infile=infile.fit_transform或者new_infile=infile.transform,那么就应该用这个降维的数据放入SVM中使用。那么就又有一个问题,得到了两个主成分,那么获得的数据是可以在平面坐标中表示出来的么?

4.怎么使用SVM?

5.交叉验证方法?
6.PCA是分别针对每一个数据进行降维吗?那么每一个数据降维得到的主成分可能是不同的,这些主成分对应的是什么东西呢?用这些东西来进行SVM的分类的话,主成分可以作为不同数据之间可以比较的成分吗?好迷啊_(¦3」∠)_

  • 应该是把所有数据(68个)的所有维度(每个数据有141×6670)都放进去,一起做PCA。预想的数据组织形式应该是infile=np.ndarray([infile1,infile2,...,infile68])
  • 降维后得到的数据就是new_infile=infile.transform?
  • 因为所有的数据一同放入,所以得到的主成分是可以相互比较的?可以放入SVM中进行分类。

关于Kernel PCA这一篇文章容易看:机器学习算法(降维)总结及sklearn实践——主成分分析(PCA)、核PCA、LLE、流形学习

关于SVM实现,这篇文章可能不错:python svm pca实践(一)

先看一下这一篇:PCA降维及python实现,好像有一点启发,代码部分

其它:
整篇都是代码的:PCA+SVM模型保存与使用

你可能感兴趣的:(fMRI,Python)