Kaggle经典案例手——写数字识别
一、数据集下载
进入kaggle官网找到Digit Recognizer界面如下:
下载之后数据是三个csv文件,test.csv是测试集,train.csv是训练集,sample_submission.csv是提交样例。最后我们的结果就是要按照sample_submission.csv这种格式提交。
二、初探数据
我自己一直比较喜欢用pycharm,但是pycharm默认的设置在打开很多行、列的时候会自动的默认省略了,所以需要一些设置才能查看全部的数据
import pandas as pd
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 设置value的显示长度为100,默认为50
pd.set_option('max_colwidth', 100)
# 设置1000列的时候才换行
pd.set_option('display.width', 1000)
pandas是常用的python数据处理包 ,具体教程可以参考之前的pandas(好像忘了上传后面再补上吧),它能够把csv文件读入成dataframe格式。看到初始的数据如下:
import pandas as pd
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 设置value的显示长度为100,默认为50
pd.set_option('max_colwidth', 100)
# 设置1000列的时候才换行
pd.set_option('display.width', 1000)
train_data1 = pd.read_csv('F:\\Kaggle_Dataset\\Digit Recognizer\\digit-recognizer\\train.csv')
print(train_data1)
数据量太大了,读取速度太慢了,读取结果是这样的
emmm,看上去好乱,也看不出来啥名堂。
那算了,用info试试看
print(train_data1.info())
结果如下:
看上去好像稍微好点了额,一共有42000行数据,785列数据。
算了算了,还是老老实实用excel打开看一下数据吧。
从上面表格可以看出,第一列是420001的向量trainLabel,是识别出来的数字,其他列42000784的特征向量集trainData。
训练集的数据大概就是上面这样了,下面我们把label和维度分开。
# Train_data 中存储了训练集的784个特征,Test_data存储了测试集的784个特征,train_lable则存储了训练集的标签# 可以看出这道题是典型的监督学习问题
train_data1 = pd.read_csv('F:\\Kaggle_Dataset\\Digit Recognizer\\digit-recognizer\\train.csv')
train_data = train_data1.values[:,1:]train_label = train_data1.values[:,0]
test_data1 = pd.read_csv('F:\\Kaggle_Dataset\\Digit Recognizer\\digit-recognizer\\test.csv')
test_data = test_data1.values[:,0:]
三、数据展示
将训练集数据展示出来
def showPic(data):
plt.figure(figsize=(7, 7))
# 查看前70幅图
for digit_num in range(0, 70):
plt.subplot(7, 10, digit_num + 1)
grid_data = data[digit_num].reshape(28, 28) # reshape from 1d to 2d pixel array
plt.imshow(grid_data, interpolation="none", cmap="afmhot")
plt.xticks([])
plt.yticks([])
# plt.tight_layout()
plt.show()
showPic(train_data)
来看下当前的维度,一共有784个维度,如果不做降维处理的话,就是一共784维的特征。 如果就把这784维特征丢进去会是什么样的效果呢? 事实是,用原始数据集+不加特征的选择(或者降维)的方法,我用SVM方法跑了半天也没出个结果。
四、PCA降维
PCA主成分分析方法
In a nutshell, PCA is a linear transformation algorithm that seeks to project the original features of our data onto a smaller set of features ( or subspace ) while still retaining most of the information.
大概意思是,主成分分析不会丢失原始信息,新的特征是原始特征的线性组合。
Explained Variance 累计贡献率 又名 累计方差贡献率 不要简单理解为 解释方差,它是 PCA 降维维度的重要指标,一般选取累计贡献率在90%左右的维度作为PCA 降维的参考维度。在识别算法的实现过程中,当我们求得某一数据库各类别特征参考维度时,取最大维度作为每一类特征的维度,即可实现数据降维。现对数据求取累计贡献率
def getcomponent(inputdata):
pca = PCA()
pca.fit(inputdata)
# 累计贡献率 又名 累计方差贡献率 不要简单理解为 解释方差!!!
EV_List = pca.explained_variance_
EVR_List = []
for j in range(len(EV_List)):
EVR_List.append(EV_List[j] / EV_List[0])
for j in range(len(EVR_List)):
if (EVR_List[j] < 0.10):
print('Recommend %d:' % j)
return j
getcomponent(train_data)
结果为:
n_components:
意义:PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
类型:int 或者 string,缺省时默认为None,所有成分被保留。
赋值为int,比如n_components=1,将把原始数据降到一个维度。
赋值为string,比如n_components='mle',将自动选取特征个数n,使得满足所要求的方差百分比。
whiten:
类型:bool,缺省时默认为False
意义:白化,使得每个特征具有相同的方差。
根据上面的测试结果
我们可以将主成分保留为22个。
代码如下:
pca = PCA(n_components=22, whiten=True)
train_x = pca.fit_transform(train_data)
test_x = pca.transform(test_data) # 数据转换
print(train_data.shape, train_x.shape)
对训练集做个测试:
def test(train_x, train_label):
start = datetime.now()
model = svm.SVC(kernel='rbf', C=10)
metric = cross_val_score(model, train_x, train_label, cv=5, scoring='accuracy').mean()
end = datetime.now()
print('CV use: %f' % ((end - start).seconds))
print('Offline Accuracy is %f ' % (metric))
test(train_x, train_label)
五、完整代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn import svm
from datetime import datetime
from sklearn.model_selection import cross_val_score
import warnings
#删除警告的
warnings.filterwarnings("ignore", category=FutureWarning, module="sklearn", lineno=196)
train = pd.read_csv('F:\\Kaggle_Dataset\\Disaster\\titanic\\train.csv')
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 设置value的显示长度为100,默认为50
pd.set_option('max_colwidth', 100)
# 设置1000列的时候才换行
pd.set_option('display.width', 1000)
# Train_data 中存储了训练集的784个特征,Test_data存储了测试集的784个特征,train_lable则存储了训练集的标签
# 可以看出这道题是典型的监督学习问题
train_data1 = pd.read_csv('F:\\Kaggle_Dataset\\Digit Recognizer\\digit-recognizer\\train.csv')
train_data = train_data1.values[:,1:]
train_label = train_data1.values[:,0]
test_data1 = pd.read_csv('F:\\Kaggle_Dataset\\Digit Recognizer\\digit-recognizer\\test.csv')
test_data = test_data1.values[:,0:]
print(train_data)
def showPic(data):
plt.figure(figsize=(7, 7))
# 查看前70幅图
for digit_num in range(0, 70):
plt.subplot(7, 10, digit_num + 1)
grid_data = data[digit_num].reshape(28, 28) # reshape from 1d to 2d pixel array
plt.imshow(grid_data, interpolation="none", cmap="afmhot")
plt.xticks([])
plt.yticks([])
# plt.tight_layout()
plt.show()
showPic(train_data)
# 初始数据有784个维度,现在需要对其降维处理,使用主成分分析法
'''
def getcomponent(inputdata):
pca = PCA()
pca.fit(inputdata)
# 累计贡献率 又名 累计方差贡献率 不要简单理解为 解释方差!!!
EV_List = pca.explained_variance_
EVR_List = []
for j in range(len(EV_List)):
EVR_List.append(EV_List[j] / EV_List[0])
for j in range(len(EVR_List)):
if (EVR_List[j] < 0.10):
print('Recommend %d:' % j)
return j
getcomponent(train_data)
'''
pca = PCA(n_components=22, whiten=True)
train_x = pca.fit_transform(train_data)
test_x = pca.transform(test_data) # 数据转换
print(train_data.shape, train_x.shape)
def test(train_x, train_label):
start = datetime.now()
model = svm.SVC(kernel='rbf', C=10)
metric = cross_val_score(model, train_x, train_label, cv=5, scoring='accuracy').mean()
end = datetime.now()
print('CV use: %f' % ((end - start).seconds))
print('Offline Accuracy is %f ' % (metric))
test(train_x, train_label)
# 最终使用pca+svm
SVM_model = svm.SVC(kernel='rbf', C=10)
pca = PCA(n_components=22,whiten=True)
resultname = 'PCA_SVM'
# modeltest(train_x,train_label,SVM_model)
SVM_model.fit(train_x,train_label)
test_y = SVM_model.predict(test_x)
pred = [[index + 1, x] for index, x in enumerate(test_y)]
np.savetxt(resultname+'.csv', pred, delimiter=',', fmt='%d,%d', header='ImageId,Label',comments='')
print('预测完成')
把结果提交到了kaggle上看了一下。成绩还是很一般啊。后面如果有时间就接着用卷积神经网络实现一次看看结果。先这样吧。