回归是一种来自统计的技术,用于在目标数量连续时预测所需目标数量的值。通过房屋面积来预测房屋的价格就是一个典型的回归问题,如下图所示:
回归模型训练和预测的步骤:
(1)导入需要的工具库。
(2)对数据预处理,包括导入数据集、处理数据、特征工程等操作,具体为缺失值处理、连续型特征归一化、类别型特征转化等。
(3)训练模型。选择合适的机器学习模型,利用训练集对模型进行训练,达到最佳拟合效果。
(4)预测结果。将待预测的数据集输入到训练好的模型中,得到预测结果。
假定因变量 Y Y Y与自变量 X X X呈线性相关,则可以采用线性模型找出自变量 X X X和因变量 Y Y Y的关系,以便预测新的自变量 X X X的值,这就是线性回归模型
。
from sklearn.model_selection import train_test_split
new_test_pca_16 = new_test_pca_16.fillna(0)
train = new_train_pca_16[new_test_pca_16.columns]
target = new_train_pca_16['target']
# 切分数据,训练数据为80%,验证数据为20%
train_data, test_data, train_target, test_target = train_test_split(train, target, test_size=0.2, random_state=0)
然后,模型训练的基本套路如下:
1)导入对于的模型类 from sklearn.xxx import xxx
2)获取对于模型类的对象 xx = xxx()
3)用数据去训练模型(训练模型参数) xx.fit(data,target)或xx.fit_transform(train_data,train_target)。后者(fit_transform)是在前者的基础上增加了数据处理(特征工程等一些方法)
4)使用训练好的模型(对象)去对测试数据进行预测或分类 xx.predict(test_data)
5)通过各种评价指标计算得分 score = xyz(test_target,predict)
这里使用sklearn调用线性回归模型进行预测:
from sklearn.metrics import mean_squared_error # 评价指标
# 从sklearn库中导入线性回归模型
from sklearn.linear_model import LinearRegression
clf = LinearRegression()
clf.fit(train_data, train_target)
test_predict = clf.predict(test_data)
score = mean_squared_error(test_target, test_predict)
print("LinearRegression: ", score)
# LinearRegression: 0.14565628375662207
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error
scores = []
for i in range(1, 10):
knf = KNeighborsRegressor(n_neighbors=i)
knf.fit(train_data, train_target)
test_predict = knf.predict(test_data)
score = mean_squared_error(test_target, test_predict)
scores.append(score)
plt.figure(figsize=(13, 8))
plt.plot(range(1, 10), scores)
plt.title('KNeighborsRegressor K-MSE')
plt.xlabel('k')
plt.ylabel('MSE score')
from sklearn.tree import DecisionTreeRegressor
DTR = DecisionTreeRegressor()
DTR.fit(train_data, train_target)
test_pred = DTR.predict(test_data)
score = mean_squared_error(test_target, test_pred)
print("DecisionTreeRegressor", score)
# DecisionTreeRegressor 0.3483485778546713
from sklearn.ensemble import RandomForestRegressor
clf = RandomForestRegressor(n_estimators=200) # 200棵树模型
clf.fit(train_data, train_target)
test_predict = clf.predict(test_data)
score = mean_squared_error(test_target, clf.predict(test_data))
print('RandomForestRegressor score', score)
# RandomForestRegressor score 0.1669636684508218
LightGBM的设计思路主要集中在减小数据对内存与计算性能的使用,以及减少多机器并行计算时的通讯代价。
LightGBM可以看作是XGBoost
的升级豪华版,在获得与XGBoost近似精度的同时,又提供了更快的训练速度与更少的内存消耗。
LightGBM的主要优点:
LightGBM的主要缺点:
LightGBM核心超参数:
LightGBM优化:
1. Histogram算法
直方图算法的基本思想是先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。在遍历数据的时候,根据离散化的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。
使用直方图算法有很多优点。首先,最明显就是内存消耗的降低,直方图算法不仅不需要额外存储预排序的结果,而且可以只保存特征离散化后的值,而这个值一般用 8 位整型存储就足够了,内存消耗可以降低为原来的1/8。
然后在计算上的代价也大幅降低,预排序算法每遍历一个特征就要计算一次分裂增益,而直方图算法只需要计算k次(k可以认为是常数),时间复杂度从O(#datafeature)优化到O(K#features).
但是,Histogram算法并不是完美的。由于特征被离散化后。找到的并不是很精确的分割点,所以会对结果产生影响。但在不同的数据集上的结果表明,离散化的分割点对最终的精度影响并不是很大,甚至有时候会更好一点。
2. 带深度限制的Leaf_wise的叶子生长策略
在 Histogram 算法之上,LightGBM 进行进一步的优化。首先它抛弃了大多数 GBDT 工具使用的按层生长 (level-wise
) 的决策树生长策略,而使用了带有深度限制的按叶子生长 (leaf-wise
) 算法。Level-wise 过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上 Level-wise 是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。
Leaf-wist则是一种更高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。Leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最深度的限制,在保证高效率的同时防止过拟合。
3. 直方图加速
LightGBM另一个优化是Histogram做差加速。一个观察到的现象:一个叶子的直方图可以由它的父节点的直方图与它兄弟的直方图做差得到。通常构造直方图,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的K个桶。利用这个方法,LightGBM可以在构造一个叶子的直方图后,可以用非常微小的代价得到它兄弟叶子的直方图,在速度上可以提升一倍。
4. 直接支持类别特征
实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,转化到多维的0/1特征,降低了空间和时间的效率。而类别特征的使用是在实践中很常用的。基于这个考虑,LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1展开。并在决策树算法上增加了类别特征的决策规则。
5. LightGBM并行优化
LightGBM还具有支持高效并行的优点。LightGBM原生支持并行学习,目前支持特征并行和数据并行的两种。
SVR(Support Vector Regression)是支持向量机在线性回归模型中的应用。支持向量机主要用于分类。这类模型的优势在采用核函数后,可以自动升维拟合,提高拟合效果,并且参数计算量并没有增加。
from sklearn.neighbors import KNeighborsRegressor # K近邻回归
from sklearn.linear_model import LinearRegression # 线性回归
from sklearn.tree import DecisionTreeRegressor # 决策树回归
from sklearn.ensemble import RandomForestRegressor # 随机森林
from sklearn.svm import SVR #支持向量回归
import lightgbm as lgb # LightGBM模型
from sklearn.metrics import mean_squared_error # 评价指标 MSE
from sklearn.model_selection import train_test_split # 数据集切分
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
对训练集进行切分,得到80%的训练数据和20%验证数据:
# 采用PCA保留16维特征的数据
new_test_pca_16 = new_test_pca_16.fillna(0)
train = new_train_pca_16[new_test_pca_16.columns]
target = new_train_pca_16['target']
# 切分数据,训练数据为80%,验证数据为20%
train_data, test_data, train_target, test_target = train_test_split(train, target, test_size=0.2, random_state=0)
clf = LinearRegression()
clf.fit(train_data, train_target)
test_predict = clf.predict(test_data)
score = mean_squared_error(test_target, test_predict)
print("LinearRegression: ", score)
# LinearRegression: 0.14565628375662207
优点:模型简单,部署方便,回归权重可以用于结果分析;训练快。
缺点:精度低,特征存在一定的共线性问题。
使用技巧:需要进行归一化处理,建议进行一定的特征选择,尽量避免高度相关的特征同时存在。
根据之前的k值曲线图选择最佳K值:
reg_KNN = KNeighborsRegressor(n_neighbors=6)
reg_KNN.fit(train_data, train_target)
test_pred = reg_KNN.predict(test_data)
score = mean_squared_error(test_target, reg_KNN.predict(test_data))
print("KNeighborsRegressor MSE: ", score)
# KNeighborsRegressor MSE: 0.18288669593425605
优点:模型简单,易于理解,对于数据量小的情况方便修改,可视化方便
缺点:计算量大,不适合数据量大的情况;需要调参数。
使用技巧:特征需要归一化,重要的特征可以适当加一定比例的权重。
clf = RandomForestRegressor(n_estimators=200) # 200棵树模型
clf.fit(train_data, train_target)
test_predict = clf.predict(test_data)
score = mean_squared_error(test_target, clf.predict(test_data))
print('RandomForestRegressor score', score)
# RandomForestRegressor score 0.1669636684508218
优点:使用方便,特征无须做过多变换,精度较高;模型并行训练快。
缺点:结果不容易解释
使用技巧:参数调节,提高精度。
本题结果:比较合适
reg_lgb = lgb.LGBMRegressor(
learning_rate=0.01,
max_depth=-1,
n_estimators=5000,
boosting_type='gbdt',
random_state=2019,
objective='regression',
)
#训练模型
reg_lgb.fit(train_data, train_target)
score = mean_squared_error(test_target, reg_lgb.predict(test_data))
print('LightGBM socre ', score)
#LightGBM socre 0.156274722993209
优点:精度高。
缺点:训练时间长,模型复杂。
使用技巧:有效的验证集防止过拟合;参数搜索。
本题结果:适用。
[1] 《阿里云天池大赛赛题解析——机器学习篇》
[2] 机器学习(三):基于LightGBM的分类预测
[3] 机器学习算法-lightGBM
[4] LightGBM回归预测模型构建 - 含GBM调参方法
[5] LightGBM+遗传算法 调参优化
[6] 机器学习之lightGBM模型