模型训练
线性模型
Lasso回归
Least absolute shrinkage and selection
operator,是对普通的线性回归使用L1正则进行优化。 \[
\min{||Y-X\theta||_2^2 + \lambda||\theta||_1}
\]
其中,(惩罚项)的系数,通过改变,基本上可以控制惩罚项。
1 2 from sklearn.linear_model import Lasso lasso_model = Lasso(alpha =0.1, normalize =True )
Ridge回归
Ridge回归是对普通的线性回归使用L2正则进行优化,对特征的权重系数设置了惩罚项。
\[
\min{||Y-X\theta||_2^2 + \lambda||\theta||_2^2}
\]
1 2 from sklearn.linear_model import Ridge Ridge_model = Ridge(alpha=0.05 , normalize=True )
面对非常大的数据集时,若使用Lasso回归进行训练,当存在相关的特征时,Lasso只保留其中的一个特征,而将其他的特征设置为零,这会导致一些信息丢失,从而降低模型的准确性。若使用Ridge回归,虽然能降低模型的负责性,但并不会减少特征的数量,模型可能会很复杂,因此可能会导致模型性能不佳。
树模型
随机森林(Random Forest,RF)
梯度提升树(GBDT)
随机森林
随即森林算法就是通过集成学习的思想将多个决策树集成在一起。
构造过程
随机抽样,训练决策树
随机选取属性做节点分裂属性
重复步骤2直到不能再分裂
建立大量决策树形成森林
优缺点
随机森林的优点非常明显:不仅可以解决分类和回归问题,还可以同时处理类别特征和数值特征,不容易过拟合,非常稳定。
随机森林计算更加复杂。
1 2 from sklearn.ensemble import RandomForestClassifier rf = RandomForestClassifier(max_features='auto' , obb_score=True , random_state=1 , n_jobs=1 )
梯度提升树
梯度提升树(GBDT)是基于Boosting改进而得的。
XGBoost
采用稀疏感知算法
近似数学习
并行计算,分布式计算
核外计算
有效地处理缺失值
LightGBM
比XGBoost准确性更高,训练时间更短
支持并行树增强
将连续特征提取为离散特征
通过使用按叶分割而不是按级别分割来获得更高精度,加快目标函数的收敛过程,并在非常复杂的树捕获训练数据的底层模式。
CatBoost
支持类别特征
提出一种全新的梯度提升机制(Ordered
Boosting),不仅可以减少过拟合的风险,也大大提高了准确性
支持开箱即用的GPU训练
训练中使用了组合类别特征,利用特征之间的联系,极大丰富了特征维度。
神经网络
多层感知机
多层感知机(MLP)也可以称作深度神经网络(Deep Neural Networks,
DNN)。
卷积神经网络
能够有效地将大数据量的图片降维成小数据量,简化复杂问题
能够有效保留图像特征,并且符合图像处理的原则。
循环神经网络
循环神经网络(RNN)是神经网络的一种扩展,更擅长对序列数据进行建模处理。
模型融合
构建多样性
特征多样性
构建多个有差异的特征集并分别建立模型,可以使特征存在于不同的超空间,从而建立的多个模型有不同的泛化误差,最终模型融合时可以起到互补的效果。
样本多样性
具体做法是将数据集切分成多份,然后分别建立模型。很多树模型在训练的时候会进行采样,主要目的是防止过拟合,从而提升预测的准确性。
模型多样性
不同模型对数据的表达能力是不同的。
训练模型融合
Bagging
Bagging的思想很简答,即从训练集中有返回地取出数据(Bootstraping),这些数据构成样本集,然后用样本训练弱分类器。重复上述过程多次,取平均值或者采用投票机制得到模型融合的最终结果。
Boosting
首先训练一个弱分类器,并把这个弱分类器分错类的样本记录下来,同时给予这个弱分类器一定的权重;然后建立一个新的弱分类器,新的弱分类器基于前面记录的错误样本进行训练,同时,我们也给予这个分类器一个权重。
训练结果融合
加权法
Stacking
通过新的模型来学习每个分类器的权重。
构建的新模型一般是简单模型
使用多个模型进行Stacking融合会有比较好的效果。
Blending
Blending融合是建立一个Holdout集,将不相交的数据集用于不同层的训练,这样可以很大程度上降低过拟合的风险。
假设我们构造两层Blending,将训练及按5:5的比例分为两部分(train_one和train_two),测试集为test
第一层用train_one训练多个模型,将此模型对train_two和test的预测结果合并到原始特征集中,作为第二层的
特征集。第二层用train_two的特征集和标签训练新的模型,然后对test预测得到最终的融合结果。
实战案例
1 2 3 4 5 6 7 8 9 10 11 12 13 import numpy as npimport pandas as pdfrom sklearn.model_selection import KFoldfrom sklearn.metrics import mean_squared_errorfrom sklearn.preprocessing import OneHotEncoderimport lightgbm as lgbfrom matplotlib import colors from matplotlib.ticker import PercentFormatter import matplotlib.pyplot as pltimport timeimport warningswarnings .filterwarnings('ignore')
1 2 3 4 5 6 7 8 9 10 11 train = pd.read_csv('train.csv' ) test = pd.read_csv('test.csv' ) all_data = pd.concat((train,test)) all_data = pd.get_dummies(all_data) all_data = all_data.fillna(all_data.mean()) x_train = all_data[:train.shape[0 ]] x_test = all_data[train.shape[0 ]:] y_train = train.SalePrice
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 from sklearn.ensemble import ExtraTreesRegressorfrom sklearn.ensemble import RandomForestRegressorfrom sklearn.metrics import mean_squared_errorfrom sklearn.linear_model import Ridge, Lassofrom math import sqrt kf = KFold(n_splits=5 , shuffle=True , random_state=2020 ) class SklearnWrapper (object ): def __init__ (self, clf, seed=0 , params=None ): params['random_state' ] = seed self.clf = clf(**params) def train (self, x_train, y_train ): self.clf.fit(x_train, y_train) def predict (self, x ): return self.clf.predict(x)def get_oof (clf ): oof_train = np.zeros((x_train.shape[0 ],)) oof_test = np.zeros((x_test.shape[0 ],)) oof_test_skf = np.empty((5 , x_test.shape[0 ])) for i, (train_index, valid_index) in enumerate (kf.split(x_train, y_train)): trn_x, trn_y, val_x, val_y = x_train.iloc[train_index], y_train[train_index],\ x_train.iloc[valid_index], y_train[valid_index] clf.train(trn_x, trn_y) oof_train[valid_index] = clf.predict(val_x) oof_test_skf[i, :] = clf.predict(x_test) oof_test[:] = oof_test_skf.mean(axis=0 ) return oof_train.reshape(-1 , 1 ), oof_test.reshape(-1 , 1 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 et_params = { 'n_estimators' : 100 , 'max_features' : 0.5 , 'max_depth' : 12 , 'min_samples_leaf' : 2 , } rf_params = { 'n_estimators' : 100 , 'max_features' : 0.2 , 'max_depth' : 12 , 'min_samples_leaf' : 2 , } rd_params={'alpha' : 10 } ls_params={ 'alpha' : 0.005 } et = SklearnWrapper(clf=ExtraTreesRegressor, seed=2020 , params=et_params) rf = SklearnWrapper(clf=RandomForestRegressor, seed=2020 , params=rf_params) rd = SklearnWrapper(clf=Ridge, seed=2020 , params=rd_params) ls = SklearnWrapper(clf=Lasso, seed=2020 , params=ls_params) et_oof_train, et_oof_test = get_oof(et) rf_oof_train, rf_oof_test = get_oof(rf) rd_oof_train, rd_oof_test = get_oof(rd) ls_oof_train, ls_oof_test = get_oof(ls)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 def stack_model (oof_1, oof_2, oof_3, oof_4, predictions_1, predictions_2, predictions_3, predictions_4, y ): train_stack = np.hstack([oof_1, oof_2, oof_3, oof_4]) test_stack = np.hstack([predictions_1, predictions_2, predictions_3, predictions_4]) oof = np.zeros((train_stack.shape[0 ],)) predictions = np.zeros((test_stack.shape[0 ],)) scores = [] for fold_, (trn_idx, val_idx) in enumerate (kf.split(train_stack, y)): trn_data, trn_y = train_stack[trn_idx], y[trn_idx] val_data, val_y = train_stack[val_idx], y[val_idx] clf = Ridge(random_state=2020 ) clf.fit(trn_data, trn_y) oof[val_idx] = clf.predict(val_data) predictions += clf.predict(test_stack) / 5 score_single = sqrt(mean_squared_error(val_y, oof[val_idx])) scores.append(score_single) print (f'{fold_+1 } /{5 } ' , score_single) print ('mean: ' ,np.mean(scores)) return oof, predictions oof_stack , predictions_stack = stack_model(et_oof_train, rf_oof_train, rd_oof_train, ls_oof_train, \ et_oof_test, rf_oof_test, rd_oof_test, ls_oof_test, y_train)