前言-lightgbm是什么?
LightGBM 是一个梯度 boosting 框架, 使用基于学习算法的决策树. 它是分布式的, 高效的, 装逼的, 它具有以下优势:
- 速度和内存使用的优化
- 减少分割增益的计算量
- 通过直方图的相减来进行进一步的加速
- 减少内存的使用 减少并行学习的通信代价
- 稀疏优化
- 准确率的优化
- Leaf-wise (Best-first) 的决策树生长策略
- 类别特征值的最优分割
- 网络通信的优化
- 并行学习的优化
- 特征并行
- 数据并行
- 投票并行
- GPU 支持可处理大规模数据
前言-这是什么?
这是强化版本的lightgbm的Python用户指南,由FontTian个人在Lightgbm官方文档的基础上改写,旨在能够更快的让lightgbm的学习者学会在python中使用lightgbm,类似文章可以参考在Python中使用XGBoost
相关参考请看最后
引用
import lightgbm as lgb
数据格式
LightGBM Python 版本的模型能够从以下格式中加载数据:
- libsvm/tsv/csv/txt format file
- NumPy 2D array(s), pandas DataFrame, SciPy sparse matrix
- LightGBM binary file
各种格式我们这里不在太多叙述,详细请参考原文档
以下示例代码是本次所使用的,具体的数据请前往github下载。
import numpy as np
import pandas as pd
def GetNewDataByPandas():
wine = pd.read_csv("../Data/UCI/wine/wine.csv")
wine['alcohol**2'] = pow(wine["alcohol"], 2)
wine['volatileAcidity*alcohol'] = wine["alcohol"] * wine['volatile acidity']
y = np.array(wine.quality)
X = np.array(wine.drop("quality", axis=1))
columns = np.array(wine.columns)
return X, y, columns
之后我们对数据进行分割和转换,同时这里也给出一个使用lightgbm进行数据保存的例子
from sklearn.model_selection import train_test_split
# Read wine quality data from file
X, y, wineNames = GetNewDataByPandas()
# split data to [[0.8,0.2],01]
x_train_all, x_predict, y_train_all, y_predict = train_test_split(X, y, test_size=0.10, random_state=100)
x_train, x_test, y_train, y_test = train_test_split(x_train_all, y_train_all, test_size=0.2, random_state=100)
train_data = lgb.Dataset(data=x_train,label=y_train)
test_data = lgb.Dataset(data=x_test,label=y_test)
train_data.save_binary("../Data/UCI/wine/wine_lightgbm_train.bin")
同时我们还可以在lightgbm加载数据的时候同时指明类别特征,这对模型精度提升有一定的好处。
train_data = lgb.Dataset(data, label=label, feature_name=['c1', 'c2', 'c3'], categorical_feature=['c3'])
同样的权重也可以通过参数weight
添加,特征名称则可以通过参数feature_name
指明
参数设置
模型参数设置如下,具体参数可以参考官方文档列表,如果有需要,也可以参考ApacheCN开源社区提供的中文版本,因为目前社区页面正在大改,所以这里只给出github的地址,这个是不会变的
要注意的一点是如果直接使用lgb训练模型,而不是lightgbm提供的sklearn接口,那么我们就需要参数列表中的objective
这一项来控制模型所处理的问题,默认为回归regression
,除此之外还有加入l1或者l2惩罚项的回归-regression_l1
和regression_l2
。二分类问题请使用binary
,多分类问题请multiclass
。其他更多内容请直接参考前面给出的链接。
- Booster parameters:
param = {'num_leaves':31, 'num_trees':100, 'objective':'regression'}
param['metric'] = 'rmse'
当然你也可以同时设置两个目标损失函数,不过我们这里就暂时不需要了。
param['metric'] = ['auc', 'binary_logloss']
训练与模型持久化
我们可以通过train
方法来进行训练,然后通过save_model
方法来存储模型。加载模型则需要使lgb.Booster()
方法。
# Training a model requires a parameter list and data set:
num_round = 10
bst = lgb.train(param, train_data, num_round, valid_sets=[test_data])
# After training, the model can be saved:
bst.save_model('model.txt')
# A saved model can be loaded:
bst = lgb.Booster(model_file='model.txt') #init model
[1] valid_0's rmse: 0.776822
[2] valid_0's rmse: 0.745311
...
[100] valid_0's rmse: 0.568459
交叉验证
# Training with 5-fold CV:
num_round = 10
lgb.cv(param, train_data, num_round, nfold=5)
{'rmse-mean': [0.7752979247352452,
0.7504569754070066,
...
0.623599205645095],
'rmse-stdv': [0.012997665079702762,
0.010725846259504226,
...
0.031637346872895655,
0.03154536582175296]}
早停
当我们拥有评价数据集的时候也就可以使用早停来获取更好的模型效果。评价数据集需要通过valid_sets
来设置,早停阈值则通过early_stopping_rounds
,这一参数在cv
方法与train
方法中都是通用的。
这个方法在最小化的评价函数(或者说度量函数)如(L2,log loss,等)和最大化的评价函数如(NDCG,AUC,等)上都是有效的。不过要注意的是,如果你使用不止一个评价函数,他们中的每一个都将被用于早停。
bst = lgb.train(param, train_data, num_round, valid_sets=[test_data], early_stopping_rounds=10)
bst.save_model('model.txt', num_iteration=bst.best_iteration)
[1] valid_0's rmse: 0.776822
Training until validation scores don't improve for 10 rounds.
[2] valid_0's rmse: 0.745311
...
[77] valid_0's rmse: 0.569041
Early stopping, best iteration is:
[67] valid_0's rmse: 0.568264
<lightgbm.basic.Booster at 0x7f4db097a208>
在cv中使用方法相同,同时也要保证最起码需要一个评价函数,多个评价函数时,也会同时使用其中的每一个用于早停。而交叉验证中的结果则会使用评级函数历史上最后一个,也就是只要添加了early_stopping_rounds
参数,那么交叉验证也就会默认会使用早停后的结果。
# Use earlystoppping and training with 5-fold CV:
num_round = 10
lgb.cv(param, train_data, num_round, nfold=5,early_stopping_rounds=10)
{'rmse-mean': [0.7752979247352452,
0.7504569754070065,
...
0.6162297019817496,
0.6158322957365135],
'rmse-stdv': [0.012997665079702762,
0.010725846259504221,
...
0.02396647921855839]}
预测
如果需要在预测中使用早停,请使用num_iteration=bst.best_iteration
。效果如下
ypred = bst.predict(x_predict, num_iteration=bst.best_iteration)
from sklearn.metrics import mean_squared_error
RMSE = np.sqrt(mean_squared_error(y_predict, ypred))
print("RMSE of predict :",RMSE)
RMSE of predict : 0.5956830546692128