PCA技术降维

https://www.zybuluo.com/ssdf93/note/54643

下面是我的kaggle比赛解题报告的第一弹,本人现在是小白菜,所以从简单的题目开始,如果大神看了,见笑了。

这个题目就是手写数字识别,比较经典的分类题目,它的数据取自MNIST项目

数据分析

数据中训练数据大约是74M,测试数据大约50M.

数据内容是28*28=784个像素,其中训练数据的第1列是该实例对应的数字,也就是label.该数据有42,000个数据样例

训练数据没有label,该数据有28,000个样例

最后提交的格式如下

ImageIdLabel
11
23
......

环境介绍

本文使用 CMD Markdown 编写
代码编写环境: Sublime Text 3
代码运行环境: MacX OS 10.10 + python 2.7.6
使用到的包: numpy,scikit-learn,pandas,csv

题目分析

这个题目第一看到,我就想到是使用KNN算法,第k临近算法,具体思路如下

看测试样例和训练样例最近的是哪个,就将其标签赋值给它

使用scikit-learn 代码如下

 
 
  1. import pandas as pd
  2. import numpy as np
  3. import csv as csv
  4. from sklearn.neighbors import KNeighborsClassifier
  5. train_raw=pd.read_csv('train.csv',header=0)
  6. test_raw=pd.read_csv('test.csv',header=0)
  7. knn = KNeighborsClassifier()
  8. train = train_raw.values
  9. test = test_raw.values
  10. print 'Start training'
  11. knn.fit(train[0::,1::],train[0::,0])
  12. print 'Start predicting'
  13. out=knn.predict(test)
  14. print 'Start writing!'
  15. n,m=test.shape
  16. ids = range(1,n+1)
  17. predictions_file = open("out.csv","wb")
  18. open_file_object = csv.writer(predictions_file)
  19. open_file_object.writerows(["ImageId","Label"])
  20. open_file_object.writerows(zip(ids,out)
  21. predictions_file.close()
  22. print 'All is done'

对这个程序的核心部分做一下说明,通常sklearn的分类器用法如下

 
 
  1. clf = SomeAlgorithmClassifier()
  2. clf.fit(train_X,train_y)
  3. out=clf.predict(test)

先申请某个算法的实体,然后用训练数据对模型进行训练,最后将模型应用到测试数据样例上,得到分类结果.
其中在申请算法实体的时候可以对模型的参数进行设定,具体见scikit-learn的官方手册

可是这个程序运行了好久,大概30分钟以上,最后提交的结果,正确率0.96800,虽然很高了,但是相比大家的还是有差距,所以只排在了大约248/492,还没进50%,不甘心,于是想一想有不有什么更优的方法


其他方法

尝试了使用svm,决策树,可是比较慢,至少一个小时没有出结果,于是放弃这种直接套用算法的方法.

使用降维技术

由于其特征实在太多,700多个,所以有必要实行降维,降维准备降到100个特征,80个特征,50个特征,30个特征,10个特征.

常常使用的方法是PCA技术,也就是主成分分析法,就是分析各个特征之间的相关性,通过计算其协方差矩阵的特征值,将其按特征值由大到小排列,在通常情况下,只选取前面少部分特征便能够近似代表整个所有的特征了.

同样使用scikit-learn
首先降到100维

 
 
  1. import pandas as pd
  2. import numpy as np
  3. import csv as csv
  4. from sklearn.neighbors import KNeighborsClassifier
  5. from sklearn.decomposition import RandomizedPCA
  6. train_raw=pd.read_csv('train.csv',header=0)
  7. test_raw=pd.read_csv('test.csv',header=0)
  8. knn = KNeighborsClassifier()
  9. train = train_raw.values
  10. test = test_raw.values
  11. print 'Start PCA to 100'
  12. train_x=train[0::,1::]
  13. pca = RandomizedPCA(n_components=100, whiten=True).fit(train_x)
  14. train_x_pca=pca.transform(train_x)
  15. test_x_pca=pca.transform(test)
  16. print 'Start training'
  17. knn.fit(train_x_pca,train[0::,0])
  18. print 'Start predicting'
  19. out=knn.predict(test_x_pca)
  20. print 'Start writing!'
  21. n,m=test_x_pca.shape
  22. ids = range(1,n+1)
  23. predictions_file = open("out_pca_100.csv","wb")
  24. open_file_object = csv.writer(predictions_file)
  25. open_file_object.writerow(["ImageId","Label"])
  26. open_file_object.writerows(zip(ids,out))
  27. predictions_file.close()
  28. print 'All is done'

提交上去了,结果真是令人沮丧,正确率才0.93743,还没有降维前的高.

我们可以看一看pca能够代表原始数据的比例,使用pca.explained_variance_ratio_

 
 
  1. t=pca.explained_variance_ratio_
  2. print sum(t[:30])
  3. print sum(t[:50])
  4. print sum(t[:70])
  5. print sum(t)

结果如下

 
 
  1. 0.731860948899
  2. 0.825551303121
  3. 0.874579424778
  4. 0.914284586422

最终的结果是0.914,已经可以代表大部分结果了.注意到将其降维到50维仍可以近似代表大多数数据的特征

又试了一下50和30维,其准确率分别为0.95429和0.96314,还是没有超过原始数据

由此看来,通过PCA降维后的数据通过KNN算法对于这个测试数据貌似不能获得更高的准确率,但看到其准确率在逐步上升,是否会有一个最大值要优于原始数据通过KNN算法得到的结果.

于是测试了一下30维,结果结果是0.96957,排名188/492,总算是进入前40%了.

看看是否能够有更好的突破,接下来我们就以30维和50维作为我们测试其他算法的主要数据.

下面首先使用SVM,我们使用50维来进行测试,代码如下:

 
 
  1. import pandas as pd
  2. import numpy as np
  3. import csv as csv
  4. from sklearn.neighbors import KNeighborsClassifier
  5. from sklearn.decomposition import RandomizedPCA
  6. from sklearn.cross_validation import train_test_split
  7. from sklearn.metrics import accuracy_score
  8. from sklearn import svm
  9. train_raw=pd.read_csv('train.csv',header=0)
  10. test_raw=pd.read_csv('test.csv',header=0)
  11. train = train_raw.values
  12. test = test_raw.values
  13. print 'Start PCA to 50'
  14. train_x=train[0::,1::]
  15. train_label=train[::,0]
  16. pca = RandomizedPCA(n_components=50, whiten=True).fit(train_x)
  17. train_x_pca=pca.transform(train_x)
  18. test_x_pca=pca.transform(test)
  19. a_train, b_train, a_label, b_label = train_test_split(train_x_pca, train_label, test_size=0.33, random_state=23323)
  20. print a_train.shape
  21. print a_label.shape
  22. print 'Start training'
  23. rbf_svc = svm.SVC(kernel='rbf')
  24. rbf_svc.fit(a_train,a_label)
  25. print 'Start predicting'
  26. b_predict=rbf_svc.predict(b_train)
  27. score=accuracy_score(b_label,b_predict)
  28. print "The accruacy socre is ", score
  29. print 'Start writing!'
  30. out=rbf_svc.predict(test_x_pca)
  31. n,m=test_x_pca.shape
  32. ids = range(1,n+1)
  33. predictions_file = open("out3.csv","wb")
  34. open_file_object = csv.writer(predictions_file)
  35. open_file_object.writerow(["ImageId","Label"])
  36. open_file_object.writerows(zip(ids,out))
  37. predictions_file.close()
  38. print 'All is done'

在这个程序里,我将原来的测试数据1/3分出来用来进行检验,使用了train_test_split函数
最终的准确率是0.97843,排名156/594,还有进步.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值