Python-sklearn机器学习的第一个样例(5)
Step 5: 分类
虽然数据清理令人厌烦,但它却是数据分析的关键步骤。如果我们跳过这个阶段直接进入建模,会导致错误的数据模型。
记住:错误的数据导致错误的模型。永远要从检查数据开始。
现在我们已经尽可能地把数据清洗了,并且对数据集的分布和关系有了初步的认识。接下来的重要步骤就是把数据集分为:训练集和测试集。
训练集是数据集的一个随机子集,用于训练模型。
测试集也是数据集的一个随机子集(与训练集互斥分开),用于验证模型的准确性。
尤其对于我们这样一个比较稀疏的数据集来说,容易造成“过度拟合”,就是说对训练集的拟合度过高,以至于不能处理哪些没有见过的数据。这就是为什么我们要把数据集分开,用训练集建模,而用测试集评价模型。
需要注意的是,一旦我们把数据集划分为训练集和测试集,那么我们在建模的过程中,就不能再使用测试集的任何数据,否则就是作弊哦。
iris_data_clean = pd.read_csv('iris-data-clean.csv')
# We're using all four measurements as inputs
# 注意到 scikit-learn 要求所有的记录都要用“列表”list形式表示, e.g.,
# [ [val1, val2, val3],
# [val1, val2, val3],
# ... ]
# 所以,我们要把输入数据集转化为一个列表的列表(a list of lists)
# We can extract the data in this format from pandas like this:
all_inputs = iris_data_clean[['sepal_length_cm', 'sepal_width_cm',
'petal_length_cm', 'petal_width_cm']].values
# Similarly, we can extract the classes
all_classes = iris_data_clean['class'].values
# Make sure that you don't mix up the order of the entries
# all_inputs[5] inputs should correspond to the class in all_classes[5]
# Here's what a subset of our inputs looks like:
all_inputs[:5]
下面要划分数据集
from sklearn.cross_validation import train_test_split
(training_inputs,
testing_inputs,
training_classes,
testing_classes) = train_test_split(all_inputs, all_classes, train_size=0.75, random_state=1)
下面用决策树的方法进行分类建模。
决策树的理论其实并不复杂,简单来说,决策树分类就是要求回答一系列的“Yes/No”,这样逐步划分出所有字段的分类。
下面是一个决策树分类器的例子:
决策树模型的一个有趣的特征是“尺度不变性(scale-invariant)”,就是说特征值的尺度规模,不会影响模型的表现。换句话说,一个特征值的范围是从0到1,还是从0到1000,决策树分类的处理方式是一样的。
对于决策树,我们可以使用许多参数进行调优,但目前我们用最基本的决策树模型。
from sklearn.tree import DecisionTreeClassifier
# Create the classifier
decision_tree_classifier = DecisionTreeClassifier()
# Train the classifier on the training set
decision_tree_classifier.fit(training_inputs, training_classes)
# Validate the classifier on the testing set using classification accuracy
decision_tree_classifier.score(testing_inputs, testing_classes)
哇,我们的分类模型准确率达到了97%,而且这么轻易就实现了哦。
可是,别高兴太早,这也许是瞎猫碰上死耗子。因为模型的准确率,是依赖训练集和测试集的取样不同,在大约80%到100%之间变化。
model_accuracies = []
for repetition in range(1000):
(training_inputs,
testing_inputs,
training_classes,
testing_classes) = train_test_split(all_inputs, all_classes, train_size=0.75)
decision_tree_classifier = DecisionTreeClassifier()
decision_tree_classifier.fit(training_inputs, training_classes)
classifier_accuracy = decision_tree_classifier.score(testing_inputs, testing_classes)
model_accuracies.append(classifier_accuracy)
sb.distplot(model_accuracies)
问题很明显,模型的表现与训练集的选择有很大关系。这种现象被称为“过度拟合”,模型针对训练集的分类表现太好,以至于对那些没有见过的数据则表现很差。