零基础入门金融风控-贷款违约预测TASK 4
- 4.建模以及调参
-
- 4.1逻辑回归模型
- 4.2决策树
- 4.3集成方法
-
- 4.3.1分类
- 4.3.2 boosting
- 4.3.3 bagging
- 4.3.4 stacking
- 4.4 数据集划分
- 4.5 建模
4.建模以及调参
4.1逻辑回归模型
1.逻辑回归算法的名字里虽然带有“回归”二字,但实际上逻辑回归算法是用来解决分类问题的。简单来说, 逻辑回归(Logistic Regression)是一种用于解决==二分类==(0 or 1)问题的机器学习方法,用于估计某种事物的*可能性*。
2.logisitc回归的结果并非数学定义中的概率值,不可以直接当做概率值来用。
逻辑回归的优缺点:
优点:
1.速度快,计算量仅仅与特征的数目有关;
2.简单易于理解,直接看到各个特征的权重;
3.能容易地更新模型吸收新的数据;
4.适合二分类问题,不需要缩放输入特征。
缺点:
1.对数据和场景的适应能力有局限性,不如决策树算法适应性那么强;
2.逻辑回归需要预先处理缺省值和异常值;
3.不能解决非线性问题,因为其决策是线性的;
逻辑回归算法原理:
假设函数(Hypothesis function):即Sigmoid函数:
损失函数(Cost Function):
梯度下降(Gradient Descent):我们使用梯度下降算法来求解逻辑回归模型参数。
正则化(Regularization):
当模型的参数过多时,很容易遇到过拟合的问题。这时就需要有一种方法来控制模型的复杂度,典型的做法在优化目标中加入正则项,通过惩罚过大的参数来防止过拟合。
在scikit-learn里,逻辑回归模型由类sklearn.linear_model.LogisticRegression实现。
4.2决策树
1.决策树(decision tree)是一种依托于策略抉择而建立起来的树。机器学习中,决策树是一个预测模型;他代表的是对象属性与对象值之间的一种映射关系。
2.决策树可以是二叉树或非二叉树,也可以把他看作是 if-else 规则的集合,也可以认为是在特征空间上的条件概率分布。
决策树的优点:
1.决策树算法中学习简单的决策规则建立决策树模型的过程非常容易理解,
2.决策树模型可以可视化,非常直观
3.应用范围广,可用于分类和回归,而且非常容易做多类别的分类
4.能够处理数值型和连续的样本特征
5.数据不需要预处理,不需要归一化,不需要处理缺失数据。
决策树的缺点:
1.很容易在训练数据中生成复杂的树结构,造成过拟合(overfitting)。
剪枝可以缓解过拟合的负作用,常用方法是限制树的高度、叶子节点中的最少样本数量。
2.学习一棵最优的决策树被认为是NP-Complete问题。实际中的决策树是基于启发式的贪心算法建立的,这种算法不能保证建立全局最优的决策树(Random Forest 引入随机能缓解这个问题)。容易得到局部最优解。
4.3集成方法
集成学习是通过训练弱干个弱学习器,并通过一定的结合策略,从而形成一个强学习器。
4.3.1分类
1.同质(homogeneous)的,即集成中仅包含同种类型的一个体学习器,像“决策树集成”中就仅包含决策树,“神经网络集成”中就全是神经网络。同质集成中的个体学习器又称为基学习器(base learner),相应的学习算法也被称为基学习算法(base learning algorithm)。
2.异质(heterogenous)的,相对同质,异质集成中的个体学习其就是由不同的学习算法生成的,这是,个体学习器就被称为组件学习器(component learner)。
同质学习器按照个体学习器之间是否存在依赖关系可以分为两类:
第一个:是个体学习器之间存在强依赖关系,一系列个体学习器基本都需要串行生成,代表算法是boosting系列算法;
第二个:是个体学习器之间不存在强依赖关系,一系列个体学习器可以并行生成,代表算法是bagging和随机森林(Random Forest)系列算法。
4.3.2 boosting
训练过程为阶梯状,基模型按次序一一进行训练(实现上可以做到并行),
基模型的训练集按照某种策略每次都进行一定的转化。
对所有基模型预测的结果进行线性综合产生最终的预测结果。
基于boosting的集成模型有:
1 AdaBoost(Adaptive Boosting)
2 .GBM(Gradient Boosting Machine): Gradient Boosting中最有代表性的就是GBDT
3.XGBoost:Extreme Gradient Boosting: 是GBDT的一种高效实现
4.LightGBM: GBDT模型的另一个进化版本
Gradient Boosting Decision Tree(GBDT):
从名称上来讲包含三个部分:Decision Tree、Boosting、Gradient Boosting。
是一种使用gradient作为信息,将不同的弱分类decision trees进行加权,从而获得较好性能的方法。
4.3.3 bagging
从训练集从进行子抽样组成每个基模型所需要的子训练集,对所有基模型预测的结果进行综合产生最终的预测结果。
4.3.4 stacking
将训练好的所有基模型对训练基进行预测,第j个基模型对第i个训练样本的预测值将作为新的训练集中
第i个样本的第j个特征值,最后基于新的训练集进行训练。同理,预测的过程也要先经过所有基模型的预测形成新的测试集,最后再对测试集进行预测。
4.4 数据集划分
把分类错误的样本数占样本总数的比列称为“错误率”(error rate),相应的,1-错误率=精度。
我们把学习器在训练集上的误差称为“训练误差”,在新样本上的误差称为“泛化误差”。
当学习器把训练样本学得太好了的时候,很可能已经把训练样本自身的一些特点当做了所有潜在样本都具有的一般性质,导致学习器的泛化性能下降,称之为“过拟合”;而对训练样本的一般性质尚未学好,称为“欠拟合”。
要评估学习器的泛化性能,需要使用一个测试集:划分方法如下:
1.留出法
“留出法”直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T,即D=S∪T,S∩T=null;而不同的划分将导致不同的训练集与测试集,相应的,模型评估的结果也会有差别
。因此,单次使用留出法得到的估计结果往往不够稳定可靠。留出法中常见的做法是将大约2/3-4/5的样本用于训练,剩余样本用于测试。
2.交叉验证法
“交叉验证法”将数据集D划分为k个大小相似的互斥子集,即D=D1∪D2∪…Dk,Di∩Dj=null,每个子集Di都尽可能保持数据分布的一致性,即从总体数据D中通过分层采样得到。然后,每次使用k-1个子集的并集
作为训练集,余下的那个作为测试集;这样就可以进行k次训练和测试,最终返回的是这k个测试结果的均值。交叉验证法评估结果的稳定性和保真性在很大程度上取决于k的取值,故交叉验证法称为
“k折交叉验证”,k的取值常有5,10,20。
3.自助法
“自助法”每次随机从m个样本的数据集D中挑选一个样本,将其拷贝放入D1,然后再将样本放回初始数据集D中,使得该样本在下次采样时仍有可能被采到;这个过程重复执行m次后,我们就得到了包含m个样本的数据集
D1;显然,D中有一部分样本会在D1中多次出现,而另一部分样本不出现。可以做一个简单的估计,样本在m次采样中始终不被采到的概率是(1-1/m)的m次方,当m取无穷大时,概率值是1/e,约等于0.368,通过
自助采样,初始数据集D中约有36.8%的样本未出现在D1中,将D1作为训练集,D-D1作为测试集。
总结:
对于数据集充足的时候,通常采用留出法,或者K折交叉验证;
对于数据集小且难以有效划分时,采用自助法;
对于数据集小且可以有效划分的时候使用留出法。
4.5 建模
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt train = pd.read_csv('datawhale-data/train.csv')
testA = pd.read_csv('datawhale-data/testA.csv')data = pd.concat([train, testA], axis=0, ignore_index=True)
data['employmentLength'].replace(to_replace='10+ years', value='10 years', inplace=True)
data['employmentLength'].replace('< 1 year', '0 years', inplace=True)def employmentLength_to_int(s):if pd.isnull(s):return selse:return np.int8(s.split()[0])
data['employmentLength'] = data['employmentLength'].apply(employmentLength_to_int)
data['earliesCreditLine'] = data['earliesCreditLine'].apply(lambda s: int(s[-4:]))data = pd.get_dummies(data, columns=['grade', 'subGrade', 'homeOwnership', 'verificationStatus', 'purpose', 'regionCode'], drop_first=True)
for f in ['employmentTitle', 'postCode', 'title']:data[f+'_cnts'] = data.groupby([f])['id'].transform('count')data[f+'_rank'] = data.groupby([f])['id'].rank(ascending=False).astype(int)del data[f]
features = [f for f in data.columns if f not in ['id','issueDate','isDefault']]
train = data[data.isDefault.notnull()].reset_index(drop=True)
test = data[data.isDefault.isnull()].reset_index(drop=True)
x_train = train[features]
x_test = test[features]
y_train = train['isDefault']
import lightgbm as lgb
from sklearn.model_selection import StratifiedKFold, KFold
from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, log_loss
folds = 5
seed = 2020
kf = KFold(n_splits=folds, shuffle=True, random_state=seed)
train = np.zeros(x_train.shape[0])
test = np.zeros(x_test.shape[0])
cv_scores = []
for i, (train_index, valid_index) in enumerate(kf.split(x_train, y_train)):
print('************************************ {} ************************************'.format(str(i+1)))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]train_matrix = lgb.Dataset(trn_x, label=trn_y)valid_matrix = lgb.Dataset(val_x, label=val_y)params = {
'boosting_type': 'gbdt','objective': 'binary','metric': 'auc','min_child_weight': 5,'num_leaves': 2 ** 5,'lambda_l2': 10,'feature_fraction': 0.8,'bagging_fraction': 0.8,'bagging_freq': 4,'learning_rate': 0.1,'seed': 2020,'nthread': 28,'n_jobs':24,'silent': True,'verbose': -1,}model = lgb.train(params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix], verbose_eval=200,early_stopping_rounds=200)val_pred = model.predict(val_x, num_iteration=model.best_iteration)test_pred = model.predict(x_test, num_iteration=model.best_iteration)train[valid_index] = val_predtest = test_pred / kf.n_splitscv_scores.append(roc_auc_score(val_y, val_pred))print(cv_scores)