数据预处理流程
思路
import pandas as pd
import numpy as np
数据读取
train = pd.read_csv("preprocess/train.csv")
test = pd.read_csv("preprocess/test.csv")
随机森林模型预测
特征选择–皮尔逊相关系数
(train.shape, test.shape)
((201917, 1700), (123623, 1699))
# 提取特征名称
features = train.columns.tolist()
features.remove('card_id')
features.remove("target")
featureSelect = features
# 计算相关系数
corr = []
for fea in featureSelect:
corr.append(abs(train[[fea,'target']].fillna(0).corr().values[0][1]))
# 取 top300 的特征进行建模,具体数量可选
se = pd.Series(corr, index=featureSelect).sort_values(ascending=False)
feature_select = ['card_id'] + se[:300].index.tolist()
# 输出结果
train = train[feature_select + ['target']]
test = test[feature_select]
网格搜索调参
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV
Name | Description |
---|---|
criterion | 规则评估指标或损失函数,默认基尼系数,可选信息熵 |
splitter | 树模型生长方式,默认以损失函数取值减少最快方式生长,可选随机根据某条件进行划分 |
max_depth | 树的最大生长深度,类似max_iter,即总共迭代几次 |
min_samples_split | 内部节点再划分所需最小样本数 |
min_samples_leaf | 叶节点包含最少样本数 |
min_weight_fraction_leaf | 叶节点所需最小权重和 |
max_features | 在进行切分时候最多带入多少个特征进行划分规则挑选 |
random_state | 随机数种子 |
max_leaf_nodes | 叶节点最大个数 |
min_impurity_decrease | 数据集再划分至少需要降低的损失值 |
min_impurity_split | 数据集再划分所需最低不纯度,将在0.25版本中移除 |
class_weight | 各类样本权重 |
然后是关于网格搜索工具的选择。随着sklearn不断完善,有越来越多的网格搜索工具可供选择,但整体来看其实就是在效率和精度之间做权衡,有些网格搜索工具由于是全域枚举(如GridSearchCV),所以执行效率较慢、但结果精度有保障,而如果愿意牺牲精度换执行效率,则也有很多工具可以选择,如RandomizedSearchCV。当然,在最新的sklearn版本中,还出现了一种更高效的搜索策略——HalvingGridSearchCV,该方法先两两比对、然后逐层筛选的方法来进行参数筛选,并且同时支持HalvingGridSearchCV和HalvingRandomSearchCV。注意,这是sklearn最新版、也就是0.24版才支持的功能,该功能的出现也是0.24版最大的改动之一,而该功能的加入,也将进一步减少网格搜索所需计算资源、加快网格搜索的速度。
围绕本次竞赛的数据,在实际执行网格搜索的过程中,建议先使用RandomizedSearchCV确定大概范围,然后再使用GridSearchCV高精度搜索具体参数取值。当然,如果是使用最新版的sklearn,也可以考虑使用Halving方法进行搜索。在公开课讲解过程中,由于时间有限,此处我们在大致确定最优参数范围的前提下设置在一个相对较小的参数空间内来进行搜索:
features = train.columns.tolist()
features.remove("card_id")
features.remove("target")
parameter_space = {
"n_estimators": [79, 80, 81],
"min_samples_leaf": [29, 30, 31],
"min_samples_split": [2, 3],
"max_depth": [9, 10],
"max_features": ["auto", 80]
}
clf = RandomForestRegressor(criterion="mse",
n_jobs=64,
random_state=22)
# train[feature].isnull().sum
grid = GridSearchCV(clf, parameter_space, cv=2, scoring="neg_mean_squared_error")
grid.fit(train[features].values, train['target'].values)
GridSearchCV(cv=2, estimator=RandomForestRegressor(n_jobs=64, random_state=22),
param_grid={'max_depth': [9, 10], 'max_features': ['auto', 80],
'min_samples_leaf': [29, 30, 31],
'min_samples_split': [2, 3],
'n_estimators': [79, 80, 81]},
scoring='neg_mean_squared_error')
grid.best_estimator_
RandomForestRegressor(max_depth=10, max_features=80, min_samples_leaf=31,
n_estimators=80, n_jobs=64, random_state=22)