机器学习算法竞赛实战(三)

模型训练

线性模型

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)

随机森林

随即森林算法就是通过集成学习的思想将多个决策树集成在一起。

构造过程

  1. 随机抽样,训练决策树
  2. 随机选取属性做节点分裂属性
  3. 重复步骤2直到不能再分裂
  4. 建立大量决策树形成森林

优缺点

随机森林的优点非常明显:不仅可以解决分类和回归问题,还可以同时处理类别特征和数值特征,不容易过拟合,非常稳定。

随机森林计算更加复杂。

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 np
import pandas as pd
from sklearn.model_selection import KFold
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import OneHotEncoder
import lightgbm as lgb

from matplotlib import colors
from matplotlib.ticker import PercentFormatter
import matplotlib.pyplot as plt
import time
import warnings
warnings.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 ExtraTreesRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import Ridge, Lasso
from math import sqrt
# 依然采用5折交叉验证
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)

机器学习算法竞赛实战(三)
https://www.spacezxy.top/2021/10/22/ML-Pratice/ML-Algorithm-pratice-3/
作者
Xavier ZXY
发布于
2021年10月22日
许可协议