相比于XGBoost,LightGBM官网的文档、Github写得都不敢让人恭维(缺少细节、案例语焉不详)。因此本篇从实际使用角度来介绍用法,就显得更有意义了。
LightGBM号称的速度快不是没有成本的,它底层依赖了一些并行处理的库文件,因此在安装的时候会遇到各种问题。笔者已经单独写了一篇短文分享,详见本人CSDN博客《Mac环境下安装LightGBM的苦难记》。
假设你已经排除万难,成功为python安装了LightGBM,我们来看看怎么使用。
类似于XGBoost,LightGBM也有自己的一套读写数据、训练、预测的接口API,但是我们还是更习惯用sklearn那一套接口来操作数据,还好它也提供了同样的接口封装(源代码可以参 考(https://github.com/microsoft/LightGBM/blob/master/python-package/lightgbm/sklearn.py)。
接照sklearn那套接口,我们可以猜想核心的流程是:
读入数据 -> 拆分训练集/测试集 -> .fit -> .predict -> score
我们先给出一个完整的代码:
import lightgbm as lgb
#用一个我们熟悉的数据来实践
from sklearn.datasets import load_breast_cancer
X,y = load_breast_cancer(return_X_y=True)
len(X),len(y)
#拆分数据
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state = 0)
len(X_train)
#创建lightgbm分类器实例
clf = lgb.LGBMClassifier(num_leaves=31,
learning_rate=0.05,
n_estimators=100)
#拟合数据来训练
clf = clf.fit(X_train, y_train)
#预测
y_pred = clf.predict(X_test)
#看准确率
from sklearn.metrics import accuracy_score
print("准确率: %f" % accuracy_score(y_pred,y_test))
#看F1-score
from sklearn.metrics import f1_score
y_predict = clf.predict(X_test)
print("Micro-F1: %f" % f1_score(y_test,y_predict, average='micro'))
print("Macro-F1: %f" % f1_score(y_test,y_predict, average='macro'))
打印结果如下:
准确率: 0.947368
Micro-F1: 0.947368
Macro-F1: 0.944928
下面简单解剖一下上述代码。
其中.fit 是一个关键步骤,我们看github上的源代码可以发现.fit的方法定义中有:
self._Booster = train(params, train_set,
self.n_estimators, valid_sets=valid_sets, valid_names=eval_names,
early_stopping_rounds=early_stopping_rounds,
evals_result=evals_result, fobj=self._fobj, feval=feval,
verbose_eval=verbose, feature_name=feature_name,
callbacks=callbacks, init_model=init_model)
可见内部还是用原生的train方法来实现的,其中train_set是把训练的自变量与目标变量又组装到了一起:
def _construct_dataset(X, y, sample_weight, init_score, group, params,
categorical_feature='auto'):
return Dataset(X, label=y, weight=sample_weight, group=group,
init_score=init_score, params=params,
categorical_feature=categorical_feature)
train_set = _construct_dataset(_X, _y, sample_weight, init_score, group, params,
categorical_feature=categorical_feature)
其中.predict的定义如下:
def predict(self, X, raw_score=False, num_iteration=None,
pred_leaf=False, pred_contrib=False, **kwargs):
if self._n_features is None:
raise LGBMNotFittedError("Estimator not fitted, call `fit` before exploiting the model.")
if not isinstance(X, (DataFrame, DataTable)):
X = _LGBMCheckArray(X, accept_sparse=True, force_all_finite=False)
n_features = X.shape[1]
if self._n_features != n_features:
raise ValueError("Number of features of the model must "
"match the input. Model n_features_ is %s and "
"input n_features is %s "
% (self._n_features, n_features))
return self._Booster.predict(X, raw_score=raw_score, num_iteration=num_iteration,
pred_leaf=pred_leaf, pred_contrib=pred_contrib, **kwargs)
可见这里是使用了原生的self._Booster.predict接口。
事实上,受到lightGBM算法思想的启发,sklearn中也提供了一个类似的集成学习算法:HistGradientBoostingClassifier
,如官网所说:
由于该算法目前还处于实验阶段,所以在导入前还要额外导入一个包:
frofrom sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
clf = HistGradientBoostingClassifier(max_iter=100).fit(X_train, y_train)
clf.score(X_test, y_test) #是的,这一步直接可得到在测试集上的准确率分数,相当于先对X_test做了predict,再求accuracy_score
打印结果:0.9736842105263158,比上面使用的lightGBM还高了一些。
其实大家通过最近几篇的代码实践可能也感受到了,有了sklearn这个大杀器定下的接口调用套路,现在主流的学习算法都可以快速上手了,节约了很多探索的时间。所以,实际工作中如果不需要自己去优化算法,而只是进行应用的话,重点已经不是算法本身了,而是特征变量如何提取,即特征工程成为了影响最终项目结果的关键环节。
本篇我们继续从代码实践的角度来快速上手体验LightGBM的用法,以供大家参考使用。下一篇我们将从算法原理的角度上来聊聊。毕竟只懂得工程的算法接口使用,是无法应付深层级的需求的,例如你可能无法回答某一种算法为什么适用场景A而不适用场景B,如果有人提出需求说想在某个细节上进行优化,你可能也无法给出评估建议。因此,想真正消化某一个机器学习算法,是需要了解接口调用+算法原理+源代码实现这样三层的。
敬请继续关注本公众号推送内容。如果您在阅读中有所收获,也请将本公众号转发给你身边打算入门机器学习的朋友~