机器学习——学习笔记:LightGBM
一、原理
LightGBM(Light Gradient Boosting Machine)是XGBoost的“优化升级版”,核心思想同样是“集成弱模型(决策树)形成强模型”,但通过两大关键优化实现了“更快的训练速度”和“更低的内存占用”。
具体来说,LightGBM在XGBoost“逐步纠错”(梯度提升)的基础上,做了两个革命性优化:
- 遍历数值→遍历区间:
- 遍历数值:传统决策树(包括XGBoost)需要遍历特征的“每一个数值”来寻找最优分裂点(比如年龄特征的25、26、27…每个值都试一次);
- 遍历区间:LightGBM会先把连续特征分成“若干区间(直方图)”(比如年龄分[18-25,26-35,36-45]),只需遍历区间就能找分裂点——相当于“把1000个零散数据归为10组,只算10次”,速度大幅提升。
- 按层生长(Level-wise)→按叶子生长(Leaf-wise):
- 按层生长:XGBoost每次给所有叶子节点都分裂一次,哪怕有些叶子贡献很小;
- 按叶子生长:LightGBM每次只选“对损失减少最大的叶子节点”分裂,跳过贡献小的叶子——相当于“优先给重要的部分精装修,不重要的部分简化处理”,既减少计算量,又能让树更精准。
二、应用场景
LightGBM和XGBoost同属“梯度提升树”,核心应用场景一致,但LightGBM在大规模数据(百万/千万级样本)上优势更明显,因为它能更快处理数据:
- 分类任务:用户churn(流失)预测、信用违约判断、医疗影像分类(需先做特征工程);
- 回归任务:电商销量预测、房价预测、用户LTV(生命周期价值)预测;
- 排序任务:推荐系统物品排序、搜索引擎结果排序(如APP商店应用排序)
三、适用的数据特征
LightGBM对数据的兼容性比XGBoost更强,尤其优化了对“高维、大数据”的支持:
1、数据类型:
优先支持结构化数据(表格数据,如CSV/Excel),对非结构化数据(文本、图像)需先做特征工程(如文本转TF-IDF、图像提CNN特征);
原生支持类别型特征:无需手动做独热编码(One-Hot),只需通过参数categorical_feature指定,模型会自动优化处理(XGBoost需手动编码,否则会把类别当数值处理,导致错误)。
2、数据规模:
最适合百万级以上样本、百维以上特征的数据:小数据(万级样本)下,LightGBM和XGBoost效果差异不大,但LightGBM仍能更快训练;
对缺失值不敏感:和XGBoost一样,可自动处理缺失值(默认将缺失值分配到增益大的叶子节点)。
3、特征特点:
支持高cardinality类别特征(如用户ID、商品ID,类别数上万):通过直方图分箱减少计算量,避免XGBoost处理高基数特征时的内存爆炸问题。
四、优缺点
LightGBM的核心竞争力是“快+省内存”,但也有特定场景下的不足:
1、优点
(1)训练速度极快:直方图分箱+Leaf-wise生长,比XGBoost快10-100倍,尤其大数据下优势明显;
(2)内存占用低:直方图存储特征,比XGBoost节省70%-90%内存;
(3)原生支持类别特征:无需手动编码,减少特征工程工作量;
(4)精度不低于XGBoost:Leaf-wise生长能聚焦重要特征,在很多任务上精度略高于XGBoost;
(5)支持并行训练:可并行处理特征分箱和分裂点查找,进一步提速。
2、缺点
(1)小数据易过拟合:Leaf-wise生长会优先分裂重要叶子,小数据下可能过度细化(学噪声),需调参控制;
(2)对异常值略敏感:直方图分箱可能将异常值归为一个区间,若异常值多,会影响分裂准确性;
(3)解释性仍较弱:和XGBoost一样,集成模型不如单棵决策树直观,需依赖特征重要性解释。
五、使用方法与核心参数
1、基础实战
import lightgbm as lgb
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 1、准备数据
data = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
data.data, data.target, test_size = 0.2, random_state = 42
)
# 2、定义模型与参数
model = lgb.LGBMClassifier(
objective = 'multiclass',
num_leaves = 31,
max_depth = -1,
learning_rate = 0.1,
n_estimators = 100,
subsample = 0.8,
colsample_bytree = 0.8,
categorical_feature = [],
random_state = 42
)
# 3、训练模型
model.fit(
X_train, y_train,
eval_set = [(X_test, y_test)],
eval_metric = "multi_logloss",
early_stopping_rounds = 50,
verbose = 10
)
# 4、预测与评估
y_pred = model.predict(X_test, num_iteration = model.best_iteration_)
print("准确率:", accuracy_score(y_test, y_pred))
# 5、特征重要性
lgb.plot_importance(model, importance_type = "gain")
2、核心参数
|
参数类别 |
参数名 |
含义与作用 |
注意事项 |
|
目标函数 |
objective |
定义任务类型: -二分类:binary(输出概率); -多分类:multiclass(需指定num_class); -回归:regression(默认,平方误差)。 |
和XGBoost类似,但多分类无需写multi:softmax,更简洁。 |
|
树结构控制(特有) |
num_leaves |
每棵树的最大叶子节点数(默认31)。 →核心参数:叶子数越多,树越复杂(易过拟合);越少,树越简单(易欠拟合)。 |
不要大于2^max_depth(否则树会过深),小数据建议设15-31,大数据可设63-127。 |
|
max_depth |
树的最大深度(默认-1,不限制)。 →辅助参数:若num_leaves太大,可设max_depth=5-10限制树深,防过拟合。 |
与XGBoost不同,LightGBM主要靠num_leaves控制复杂度,max_depth是“兜底”参数。 |
|
|
min_child_samples |
叶子节点的最小样本数(默认20)。 →防过拟合:样本数越少,越容易学噪声;值越大,树越保守。 |
比XGBoost的min_child_weight更直观(直接按样本数,而非权重和)。 |
|
|
直方图优化(特有) |
bin_construct_sample_cnt |
构建直方图时的采样数(默认50000)。 →平衡速度与精度:采样数越多,直方图越准,但速度越慢;反之越快。 |
百万级样本设1e5-5e5,千万级以上可设1e6。 |
|
histogram_pool_size |
直方图缓存池大小(默认-1,自动分配)。 →内存优化:若内存不足,可设smaller值(如2048MB)。 |
仅当训练报“内存不足”时调整。 |
|
|
采样与正则 |
subsample |
训练每棵树时的样本采样比例(默认1.0)。 →防过拟合:如0.8表示用80%样本训练,增加随机性。 |
和XGBoost一致,建议0.7-0.9。 |
|
colsample_bytree |
训练每棵树时的特征采样比例(默认1.0)。 →防过拟合:如0.8表示用80%特征,减少冗余特征影响。 |
和XGBoost一致,高维特征建议0.5-0.8。 |
|
|
reg_alpha/reg_lambda |
L1/L2正则化系数(默认0/0)。 →防过拟合:值越大,正则化越强,抑制参数过大。 |
和XGBoost一致,建议从0.1开始尝试,逐步增大。 |
|
|
训练控制 |
learning_rate |
学习率(默认0.1)。 →控制每棵树的贡献度:小学习率(如0.01)需配合多树(如1000),精度高但慢;大学习率(如0.3)快但易震荡。 |
和XGBoost一致,建议用早停法(early_stopping_rounds)配合小学习率。 |
|
n_estimators |
树的数量(默认100)。 →弱模型总数:太少易欠拟合,太多易过拟合(但早停法可自动停止)。 |
建议设100-1000,配合早停法无需手动调小。 |
|
|
类别特征(特有) |
categorical_feature |
指定类别特征的列索引(如[2,3])。 →原生支持:无需手动编码,模型会自动对类别特征做优化分裂(比独热编码更高效)。 |
必须传入“列索引”(如Pandas数据框的df.columns.get_indexer(["性别","职业"])),不能传列名。 |
六、常见问题与解决方案
|
常见问题 |
症状 |
解决方案(核心参数调整) |
|
过拟合(训练准,测试差) |
训练集准确率99%,测试集仅80%;或验证集损失先降后升。 |
1.减少num_leaves(如从63→31):降低树复杂度; 2.增加min_child_samples(如从20→50):限制叶子节点最小样本数; 3.减小subsample/colsample_bytree(如从1.0→0.8):增加采样随机性; 4.增大reg_alpha/reg_lambda(如从0→1):加强正则化; 5.缩短early_stopping_rounds(如从50→30):更早停止训练。 |
|
欠拟合(训练测试都差) |
训练集准确率80%,测试集78%;或损失始终很高。 |
1.增加num_leaves(如从31→63):提高树复杂度; 2.减少min_child_samples(如从50→20):允许叶子节点有更少样本; 3.增大learning_rate并增加n_estimators(如0.01→0.1,100→500):让模型有更多学习机会; 4.关闭正则化(reg_alpha=0,reg_lambda=0):减少约束; 5.补充特征:增加交互特征(如“收入×年龄”)或统计特征(如“近30天消费次数”)。 |
|
训练速度慢 |
百万级样本训练超过1小时;或每轮迭代耗时久。 |
1.增大bin_construct_sample_cnt(如从5e4→1e6):减少直方图构建时间; 2.减小num_leaves(如从63→31):减少每棵树的计算量; 3.增大subsample/colsample_bytree(如从0.7→0.9):减少采样时间(注意:可能增加过拟合风险); 4.开启并行:设置num_threads=-1(用所有CPU核心); 5.数据预处理:删除冗余特征(如相关性>0.9的特征),减少特征维度。 |
|
内存不足 |
训练时报“OutofMemory”;或程序崩溃。 |
1.减小bin_construct_sample_cnt(如从1e6→5e4):减少直方图内存占用; 2.设置histogram_pool_size(如histogram_pool_size=2048,单位MB):限制直方图缓存; 3.分块训练:用lgb.Dataset的chunk_size参数分块加载数据; 4.降低数据精度:将float64转为float32(减少一半内存); 5.删减样本:若样本过多,可随机采样部分数据(如80%样本)。 |
|
类别特征处理错误 |
模型对类别特征的预测效果差;或报“类别特征格式错误”。 |
1.确保categorical_feature传入的是“列索引”(非列名); 2.对高基数类别特征(如用户ID),先做“目标编码”(TargetEncoding)再传入,避免直接用原生处理; 3.若类别特征有缺失值,需先填充(如用“未知”标签),再指定为类别特征。 |
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)