摘要
本文所使用的数据集来自Kaggle上经典的Digit Recognizer项目。
该项目最早是用传统的机器学习方法做的,例如SVC,决策树等,之后随即森林RandomForest的出现显著提升了模型的性能,其后XGBoost以其出色的表现一度制霸kaggle上的诸多项目,这种情形一直持续到神经网络被发掘出来之后,例如该项目使用卷积神经网络CNN能得到十分优越的效果。下图给出了该项目使用不同方法所能得到的最佳分数。
由于我是初次接触Kaggle项目,因此打算从传统的机器学习方法入手,以加深自己对机器学习的理解,同时提高模型的性能,本文首先将采用SVC来训练数字识别模型。
准备数据
在Kaggle上下载数据集压缩包,解压后得到train.csv,test.csv以及sample_submission.csv三个文件。文件格式说明见官网。
接下来编写python代码加载模型。
首先导入所需的包:
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
然后使用pandas的read_csv函数加载数据:
labeled_images = pd.read_csv('~/data/train.csv')
images = labeled_images.iloc[:, 1:].values / 255 # 对所有灰度图像的像素值进行归一化处理
labels = labeled_images.iloc[:, :1].values
print('images shape: ', images.shape) # 查看训练集的大小
print('labels shape: ', labels.shape)
train_images, test_images, train_labels, test_labels =
train_test_split(images, labels, random_state=0) # 分割数据
上述的iloc表示以索引来获取数据的位置,逗号左边表示行,右边表示列,1:表示获取第2到最后一列(索引从0开始,所以1是第二列)。因此labels获取csv文件中的第1列,images获取到第2到最后一列。由于read_csv函数返回的是DataFrame类型,因此需要通过.values将其转换为numpy.ndarray类型。
调整参数,训练模型
本文以参数gamma为例,简单说明调参过程。
gamma = [0.035, 0.040, 0.045]
scores = []
for g in gamma:
clf = SVC(gamma=g)
clf.fit(train_images, train_labels.ravel())
scores.append(clf.score(test_images, test_labels.ravel()))
print(scores)
然后使用plt来绘制参数和分数的关系:
plt.plot(gamma, scores, 'o-', label='gamma', color = 'r')
plt.legend(loc='best')
plt.xlabel('gamma')
plt.ylabel('score')
plt.show()
需要注意的是,要对train_labels和test_labels调用ravel函数,从而将列向量转换为行向量,否则会有DataConversionWarning:
DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().
y = column_or_1d(y, warn=True)
测试结果表明gamma=0.040时达到最优(此前我还做了其他实验,例如gamma=[0.001, 0.01, 0.1, 1]等,并一步步缩小测试范围)。
(此处无图)
得出结果
找到最优参数后,便可以把测试集喂给模型,得出结果了:
clf = SVC(gamma=0.04)
clf.fit(train_images, train_labels)
print(clf.score(test_images, test_labels))
test_data = pd.read_csv('~/data/test.csv')
test_data[test_data > 0] = 1
results = clf.predict(test_data)
print(results)
df = pd.DataFrame(results) #将ndarray转换为DataFrame格式
df.index.name = 'ImageId'
df.index += 1
df.columns = ['Label']
df.to_csv('~/data/submission.csv', header=True) #输出csv文件
将submission.csv提交至Kaggle后,便可以得到最终分数。
总结
机器学习模型的训练步骤如下:
1. 清洗数据(本文无需此步骤);
2. 特征工程(提取特征,增强特征等);
3. 调整参数,训练模型;
4. 得出结果。
尽管本文没有提及特征工程,但是事实上特征工程是训练模型过程中非常重要的部分。之后我会尝试更多的关注特征,而不是在调整参数上。