Python-sklearn机器学习的第一个样例(5)

Step 5: 分类

虽然数据清理令人厌烦,但它却是数据分析的关键步骤。如果我们跳过这个阶段直接进入建模,会导致错误的数据模型。

记住:错误的数据导致错误的模型。永远要从检查数据开始。

现在我们已经尽可能地把数据清洗了,并且对数据集的分布和关系有了初步的认识。接下来的重要步骤就是把数据集分为:训练集和测试集。

训练集是数据集的一个随机子集,用于训练模型。

测试集也是数据集的一个随机子集(与训练集互斥分开),用于验证模型的准确性。

尤其对于我们这样一个比较稀疏的数据集来说,容易造成“过度拟合”,就是说对训练集的拟合度过高,以至于不能处理哪些没有见过的数据。这就是为什么我们要把数据集分开,用训练集建模,而用测试集评价模型。

需要注意的是,一旦我们把数据集划分为训练集和测试集,那么我们在建模的过程中,就不能再使用测试集的任何数据,否则就是作弊哦。

In [61]:
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]
Out[61]:
array([[ 5.1,  3.5,  1.4,  0.2],
       [ 4.9,  3. ,  1.4,  0.2],
       [ 4.7,  3.2,  1.3,  0.2],
       [ 4.6,  3.1,  1.5,  0.2],
       [ 5. ,  3.6,  1.4,  0.2]])

下面要划分数据集

In [62]:
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”,这样逐步划分出所有字段的分类。

下面是一个决策树分类器的例子:

Python-sklearn机器学习的第一个样例(5)

决策树模型的一个有趣的特征是“尺度不变性(scale-invariant)”,就是说特征值的尺度规模,不会影响模型的表现。换句话说,一个特征值的范围是从0到1,还是从0到1000,决策树分类的处理方式是一样的。

对于决策树,我们可以使用许多参数进行调优,但目前我们用最基本的决策树模型。

In [63]:
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)
Out[63]:
0.97368421052631582

哇,我们的分类模型准确率达到了97%,而且这么轻易就实现了哦。

可是,别高兴太早,这也许是瞎猫碰上死耗子。因为模型的准确率,是依赖训练集和测试集的取样不同,在大约80%到100%之间变化。

In [64]:
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)
f:\Anaconda3\lib\site-packages\statsmodels\nonparametric\kdetools.py:20: VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
  y = X[:m/2+1] + np.r_[0,X[m/2+1:],0]*1j
Out[64]:
<matplotlib.axes._subplots.AxesSubplot at 0x2100be8278>
Python-sklearn机器学习的第一个样例(5)

问题很明显,模型的表现与训练集的选择有很大关系。这种现象被称为“过度拟合”,模型针对训练集的分类表现太好,以至于对那些没有见过的数据则表现很差。