可以先参考官方说明文档
基本参数说明:
estimator: 指定要使用的模型
param_grid: 指定要搜索的参数
scoring: 指定在搜索时, estimator的评分函数:
1.可用的预设的评分函数在这里(搜索sklearn.metrics)可以看到
2.可以通过sklearn.metrics.make_scorer(myfunc, greater_is_better=?)来自定义评分函数, 如果greater_is_better=True, 那么评分就是真实的分数, 是个>0的数; 如果greater_is_better=False, 那么评分就是真实的分数相反数, 是<0的数
3.自定义评分函数时的参数次序为myfunc(y_true, y_pred), 两个不要搞反了, 函数只能返回1个数
cv: 指定训练、验证集的划分
1.使用PredefinedSplit可以指定每次fold的验证集
2.理解PredefinedSplit可以看官方的小例子以及StackOverflow上的解答
3.如何不用交叉验证, 而用预设的验证集?看后面的代码示例
4.使用RepeatedKFold(n_splits=splits, n_repeats=repeats)可以做splits折交叉验证,做repeats次(比如splits=10, repeats=2, 则第一次,用1种参数跑10折得到10次结果,第二次重新划分10折,还是用一样的参数跑10折。这样相当于使用一样的参数不一样的train/val划分跑了20次 )
refit:表示搜索完后, 是否用最好的参数在给定的整个数据集上(忽略了cv参数, 包含了训练、验证集)拟合1个模型
1.如果refit=True, 可通过best_estimator_获取这个模型(注意这个模型不是只在训练集上拟合的, 而是在原先GridSearchCV.fit(X_whole,Y_whole)给定的整个数据集上(训练集+验证集)拟合的)。
2.如果refit=False, 则没有best_estimator_这个属性
搜索完毕后可以通过gsearch.best_params_来得到最优的参数. 结合原模型的预设参数default_params = gbm.get_params(), 通过update来更新找到的最优参数: default_params.update(gsearch.best_params_)
最后重新初始化模型gbm = LGBMRegressor(**default_params),并且fit就可以了
gbm.fit(x_train, train_y)
其他参数, 以后用到再看看
gbm = LGBMRegressor(boosting_type='gbdt',
num_leaves=20, # Maximum tree leaves for base learners.
max_depth=2, # Maximum tree depth for base learners, <=0 means no limit.
learning_rate=0.1, n_estimators=30,
subsample_for_bin=200000, objective='regression_l1', class_weight=None,
min_split_gain=0., min_child_weight=1e-3,
min_child_samples=20, #Minimum number of data needed in a child (leaf).
subsample=1.,
subsample_freq=0, # 0 means disable bagging; k means perform bagging at every k iteration
colsample_bytree=1., # <1 means LightGBM will randomly select part of features on each iteration (tree)
reg_alpha=0., # L1 regularization term on weights.
reg_lambda=0.,# L2 regularization term on weights.
random_state=2019,
n_jobs=-1, silent=True,
importance_type='gain' # The type of feature importance to be filled into feature_importances_. If ‘split’, result contains numbers of times the feature is used in a model. If ‘gain’, result contains total gains of splits which use the feature.
)
"""
---------------------------------
网格搜索
"""
parameters = {
'objective': ['regression', 'regression_l1'],
'max_depth': [2,3,4,5],
# 'num_leaves': [20,25,30,35],
# 'n_estimators': [20,25,30,35],
# 'min_child_samples': [15,20,25,30],
# 'subsample_freq': [0,2,5],
# 'subsample': [0.7,0.8,0.9,1],
# 'colsample_bytree': [0.8,0.9,1]
}
tridx = -np.ones(x_train.shape[0])
vaidx = np.zeros(x_val.shape[0])
def mape_my(t, p):
return np.abs((t - p)/t).mean()
scorer = make_scorer(mape_my, greater_is_better=False)
# tridx所有元素=-1表示用来训练的, vaidx所有元素=0表示用来验证的. tridx和vaidx对应下面的x_search(y_search)
# tridx值=-1表示肯定参与训练
# 参与验证的元素vaidx必须>=0
# =0表示第一次cross validation的验证集, 其他不等于0的为训练集
# =1表示第二次cross validation的验证集, 其他不等于1的为训练集, 以此类推
ps = PredefinedSplit(test_fold=np.hstack([tridx, vaidx]))
gsearch = GridSearchCV(gbm, param_grid=parameters, # 前面已经用预定义了一些参数来初始化gbm, 这里只搜索'objective'和'max_depth'
scoring=scorer,
cv=ps, verbose=10,
refit=False # You need to set refit=False (not a default option), otherwise the grid search will refit the estimator on the whole dataset (ignoring cv) after the grid search completes.
)
x_search = np.vstack([x_train, x_val])
y_search = np.concatenate([train_y, val_y],0)
gsearch.fit(x_search, y_search) # 搜索最优参数
print('参数的最佳取值:{0}'.format(gsearch.best_params_))
print('最佳模型得分:{0}'.format(gsearch.best_score_))
default_params = gbm.get_params() # 得到前面预定义的参数
default_params.update(gsearch.best_params_) # 更新最优的参数
gbm = LGBMRegressor(**default_params)
raise ValueError
"""
---------------------------------
接下来可以只用train set而不用val set拟合1个模型
gbm.fit(x_train, train_y,
verbose=True
)
"""