幸运的是,交叉验证是一个很简单的避免过拟合的方法。交叉验证,你将你的数据分成一些数字部分(或子类)。我们使用 3 作为一个例子。然后你这样做:
合并第一二部分,训练一个模型,在第三部分上做预测。
合并第一三部分,训练一个模型,在第二部分上做预测。
合并第二三部分,训练一个模型,在第一部分上做预测。
这种方式,评价我们生成的预测的精度的整个数据集和曾经训练我们的模型没有相同的数据。
9: 预测
我们可以使用极好的 scikit-learn 库来做预测。我们将使用skelearn的一个助手来将数据分成交叉验证的子类,然后用每一个子类分别来训练算法做预测。最后,我们将得到一个预测列表,每一个列表项包含了相关子类的预测数据。
# Import the linear regression class
from sklearn.linear_model import LinearRegression
# Sklearn also has a helper that makes it easy to do cross validation
from sklearn.cross_validation import KFold
# The columns we'll use to predict the target
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]
# Initialize our algorithm class
alg = LinearRegression()
# Generate cross validation folds for the titanic dataset. It return the row indices corresponding to train and test.
# We set random_state to ensure we get the same splits every time we run this.
kf = KFold(titanic.shape[0], n_folds=3, random_state=1)
predictions = []
for train, test in kf:
# The predictors we're using the train the algorithm. Note how we only take the rows in the train folds.
train_predictors = (titanic[predictors].iloc[train,:])
# The target we're using to train the algorithm.
train_target = titanic["Survived"].iloc[train]
# Training the algorithm using the predictors and target.
alg.fit(train_predictors, train_target)
# We can now make predictions on the test fold
test_predictions = alg.predict(titanic[predictors].iloc[test,:])
predictions.append(test_predictions)
10:测试(评价)误差
现在我们有了预测结果,我们可以测试我们的误差了。
第一步我们需要先定义误差的度量标准,所以我们先算出我们模型的精度。从Kaggle竞赛的描述,误差的度量标准是正确预测的百分比。我们将使用这个相同的度量标准来测试我们本地模型的性能。
这个度量标准将基本上是 predictions 中找到的值和他们在 titanic['Survived'] 的副本中准确对应的值的数量然后再除以乘客的总数。
在我们这么做之前,我们需要先将三个预测数据集合并到一个列中。因为每一个预测数据集是一个numpy(python科学计算库[注:真正的科学计算库应该是scipy,而numpy主要是矩阵数组等数据处理运算])数组,我们可以使用一个numpy方法将他们连接到一个列里。
算出 predictions 预测值中和 titanic["Survived"] 副本中准确相同的值的比例。这个计算结过应该是一个浮点数(小数)并将它赋值给变量 accuracy 。
import numpy as np
# The predictions are in three separate numpy arrays. Concatenate them into one.
# We concatenate them on axis 0, as they only have one axis.
predictions = np.concatenate(predictions, axis=0)
# Map predictions to outcomes (only possible outcomes are 1 and 0)
predictions[predictions > .5] = 1
predictions[predictions <=.5] = 0
accuracy = sum(predictions[predictions == titanic['Survived']])/(titanic['Survived'].count())
11:逻辑回归
我们有了我们的第一个预测结果!可是结果并不是很好,只有78.3%的正确率。在视频中,我们曾提到一种方式使线性回归的输出值介于 0 和 1 之间。这种方法叫做逻辑回归 。
一个好的方法就是将逻辑回归当成是线性回归的逻辑输出,所以他的值就是 0 和1 。用 逻辑函数 logit function 来完成。输入任何值到逻辑函数都将通过“压缩”极值匹配成 0 和 1 。这对我们来说非常完美,因为我们只关心两种输出结果。
Sklearn 有一个逻辑回归的类我们可以使用。通过使用一个 Sklearn 助手函数可以使我们所有的交叉验证和测试变得更简单。
12:处理测试集
我们的正确度已经可以了,但是还不是非常好。我们任然可以尝试一些方法来使它变得更好,在下一个任务将会讨论。