在前面的几篇文章中,笔者陆续介绍了几种决策树的生成算法以及常见的集成模型。接下来在这篇文章中,笔者将以泰坦尼克号生还预测(分类)为例来进行实战演示;并且还会介绍相关的数据预处理方法,例如缺失值填充和类型特征转换等。
1 数据集预处理
我们本次用到的数据集为泰坦尼克号生还预测数据集(公众号回复”数据集“即可获取),原始数据集一共包含891个样本,12个特征维度。但是需要注意的是,这12个特征维度不一定都会用到,我们只选择我们认为有用的就行;同时存在一些样本的某些特征维度出现缺失值的状况,因此我们需要对其进行填充。
1.1 读取数据集
该数据集一共包含两个文件,其中一个为训练集,另一个为测试集。下载完成后放在本代码所在目录的data
目录中即可。接着我们可以通过如下代码来读入数据并查看信息:
def load_data():
titanic = pd.read_csv('./data/titanic_train.csv')
print(titanic.info())
#结果
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890#数据集一共有891个样本0-890
Data columns (total 12 columns):#一共12列特征
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64#该列特征为整型,无缺失值
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object #该列特征为类别类型,无缺失值
4 Sex 891 non-null object
5 Age 714 non-null float64#该列特征为浮点型,有891-714个缺失值
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
可以发现数据集一共包含有12个特征,同时还存在部分缺失值。但在最后我们只会选取部分特征维度,并会对缺失值进行补全。
1.2 特征选择
对于特征的选择那就是仁者见仁智者见智了,你可以都用上,也可以只选择你认为对最后预测结果有影响的特征。在本示例中,我们选择'Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare','Embarked'
这7个特征维度,其分别表示船舱等级、性别、年龄、乘客在船上兄弟姐妹/配偶的数量、乘客在船上父母/孩子的数量、船票费用和登船港口。当然,'Survived'
这一列特征是作为我们最终进行预测的类标。通过如下代码便可完成特征的选择工作:
selected_features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare','Embarked']
x_train = train[selected_features]
y_train = train['Survived']
x_test = test[selected_features]
print(x_train.info())
print(x_test.info())
#结果:
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Pclass 891 non-null int64
1 Sex 891 non-null object
2 Age 714 non-null float64
3 SibSp 891 non-null int64
4 Parch 891 non-null int64
5 Fare 891 non-null float64
6 Embarked 889 non-null object
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Pclass 418 non-null int64
1 Sex 418 non-null object
2 Age 332 non-null float64
3 SibSp 418 non-null int64
4 Parch 418 non-null int64
5 Fare 417 non-null float64
6 Embarked 418 non-null object
由于该数据集来自kaggle竞赛,所以,测试集中并没有包含类标'Survived'
这一列。
1.3 缺失值填充
从上面的输出结果可以看出,在训练集和测试集中特征'Age','Embarked','Fare'
存在缺失值的情况。且特征'Age'
和'Fare'
均为浮点型,对于浮点型的缺失值一般采用该特征维度所有值的平均作为填充;而特征'Embarked'
为类型值,对于类型值的缺失一般采用该特征维度出现次数最多的类型值进行填充。因此下面开始分别用这两种方法来进行缺失值的补充。
x_train['Age'].fillna(x_train['Age'].mean(),inplace=True) # 以均值填充
print(x_train['Embarked'].value_counts())# 统计每个类别的样本数
x_train['Embarked'].fillna('S',inplace=True) #'S'出现次数最多,因此以'S'进行填充
x_test['Age'].fillna(x_test['Age'].mean(),inplace=True)
x_test['Fare'].fillna(x_test['Fare'].mean(),inplace=True)
print(x_train.info())
print(x_test.info())
#结果:
S 644
C 168
Q 77
2 Age 891 non-null float64
6 Embarked 891 non-null object
2 Age 418 non-null float64
5 Fare 418 non-null float64
1.4 特征值转换
从上面的信息可知,特征'Sex','Embarked'
为字符形式类型特征取值,所以需要对其进行转换。
x_train.loc[x_train['Sex'] == 'male', 'Sex'] = 0
x_train.loc[x_train['Sex'] == 'female', 'Sex'] = 1
x_train.loc[x_train['Embarked'] == 'S', 'Embarked'] = 0
x_train.loc[x_train['Embarked'] == 'C', 'Embarked'] = 1
x_train.loc[x_train['Embarked'] == 'Q', 'Embarked'] = 2
x_test.loc[x_test['Sex'] == 'male', 'Sex'] = 0
x_test.loc[x_test['Sex'] == 'female', 'Sex'] = 1
x_test.loc[x_test['Embarked'] == 'S', 'Embarked'] = 0
x_test.loc[x_test['Embarked'] == 'C', 'Embarked'] = 1
x_test.loc[x_test['Embarked'] == 'Q', 'Embarked'] = 2
print(x_test)
#结果:
[[3 0 34.5 ... 0 7.8292 2]
[3 1 47.0 ... 0 7.0 0]
[2 0 62.0 ... 0 9.6875 2]
...
[3 0 38.5 ... 0 7.25 0]
[3 0 nan ... 0 8.05 0]
[3 0 nan ... 1 22.3583 1]]
到此为止我们就算是把数据预处理工作给完成了,下面开始通过随机森林来进行分类任务。
2 生还预测
下面我们通过前面介绍的随机森林来对乘客生还情况进行预测。同时,为了能够找到一个更加准确的模型,我们还通过并行搜索来寻找超参数。
def random_forest():
x_train, y_train, x_test = load_data()
model = RandomForestClassifier()
paras = {'n_estimators': np.arange(10, 100, 10), 'criterion': ['gini', 'entropy'], 'max_depth': np.arange(5, 50, 5)}
gs = GridSearchCV(model, paras, cv=5, verbose=1,n_jobs=-1)
gs.fit(x_train, y_train)
y_pre = gs.predict(x_test)
print('best score:', gs.best_score_)
print('best parameters:', gs.best_params_)
print(y_pre)
#结果:
Fitting 5 folds for each of 162 candidates, totalling 810 fits
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done 34 tasks | elapsed: 2.0s
[Parallel(n_jobs=-1)]: Done 184 tasks | elapsed: 5.8s
[Parallel(n_jobs=-1)]: Done 434 tasks | elapsed: 13.1s
[Parallel(n_jobs=-1)]: Done 784 tasks | elapsed: 23.5s
[Parallel(n_jobs=-1)]: Done 810 out of 810 | elapsed: 24.6s finished
best score: 0.8350323269097985
best parameters: {'criterion': 'entropy', 'max_depth': 10, 'n_estimators': 90}
[0 0 0 0 1 0 0 0 1 0 0 0 1 0 1 1 0 0 0.......0 0]
从最后的输出结果可以看到,一共有162个候选模型,由于采用了5折交叉验证所以一共需要拟合810次。当划分标准为信息熵,决策树的最大深度为10,基分类器的个数为90时在训练集上的分类准确率最高为0.835。同时,最后我们也得到了在测试集上的预测结果。
3 总结
在本篇文章中,笔者以泰坦尼克号生还预测数据集为例,详细的展示了从数据预处理到模型预测的每一个步骤;包括:读取数据集、特征选择、缺失值补充和特征转换和模型选择等。本次内容就到此结束,感谢阅读!
若有任何疑问与见解,请发邮件至moon-hotel@hotmail.com并附上文章链接,青山不改,绿水长流,月来客栈见!
引用
[1] 示例代码:关注公众号回复“示例代码”即可直接获取!
