当前位置:   article > 正文

DataWhale Task3 特征工程_df_train.isnull().sum s=)/df_train.shapeo

df_train.isnull().sum s=)/df_train.shapeo
 Task03 啦,希望能坚持学完,继续加油!自己在可视化和时间变量的处理上不太熟练,以后要多多练习呀~
  • 1

先把用到的库调用下

 import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
from tqdm import tqdm  #这个库没怎么用过
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn.preprocessing import MinMaxScaler
import xgboost as xgb
import lightgbm as lgb
from catboost import CatBoostRegressor
import warnings
from sklearn.model_selection import StratifiedKFold, KFold
from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, log_loss
warnings.filterwarnings('ignore')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

一、数据预处理

数据EDA部分我们已经对数据的大概和某些特征分布有了了解,数据预处理部分一般我们要处理一些EDA阶段分析出来的问题,这里介绍了数据缺失值的填充,时间格式特征的转化处理,某些对象类别特征的处理。
首先我们查找出数据中的对象特征和数值特征:

numerical_fea=list(df_train.select_dtypes(exclude=['object']).columns)
label='isDefault' #移除目标变量
numerical_fea.remove(label)
numerical_fea #数值特征

category_fea=list(filter(lambda x: x not in numerical_fea,list(df_train.columns)))
category_fea #对象特征
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 在比赛中数据预处理是必不可少的一部分,对于缺失值的填充往往会影响比赛的结果,在比赛中不妨尝试多种填充然后比较结果选择结果最优的一种;
  • 比赛数据相比真实场景的数据相对要“干净”一些,但是还是会有一定的“脏”数据存在,清洗一些异常值往往会获得 意想不到的效果。

1.1 缺失值的填充

# 查看缺失值数量
df_train.isnull().sum()
df_train.isnull().sum()/df_train.shape[0]#查看变量缺失值比例
  • 1
  • 2
  • 3

在这里插入图片描述

1.1.1 按照中位数填补缺失的数值型变量

#按照平均数填充数值型特征
df_train[numerical_fea] =df_train[numerical_fea].fillna(df_train[numerical_fea].median())
df_test[numerical_fea] =df_test[numerical_fea].fillna(df_test[numerical_fea].median())
  • 1
  • 2
  • 3

1.1.2 按照众数填补缺失的类别型特征

#按照众数填充类别型特征
df_train[category_fea] = df_train[category_fea].fillna(df_train[category_fea].mode())
df_test[category_fea] =df_test[category_fea].fillna(df_train[category_fea].mode())
  • 1
  • 2
  • 3

在这里插入图片描述

1.2 时间格式处理

df_train['issueDate'].min()
#转化成时间格式
for data in [df_train, df_test]:
    data['issueDate'] = pd.to_datetime(data['issueDate'],format='%Y-%m-%d')
    startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
    #构造时间特征
    data['issueDateDT'] = data['issueDate'].apply(lambda x: x-startdate).dt.days
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
df_train['employmentLength'].value_counts(dropna=False).sort_index()
  • 1

在这里插入图片描述

1.3 对象类型特征转化到数值

  • 对 employmentLength(就业年限(年))进行处理
def employmentLength_to_int(s):
    if pd.isnull(s):
        return s
    else:
        return np.int8(s.split()[0])
for data in [df_train, df_test]:
    data['employmentLength'].replace(to_replace='10+ years', value='10 years', inplace=True)
    data['employmentLength'].replace('< 1 year', '0 years', inplace=True)
    data['employmentLength'] = data['employmentLength'].apply(employmentLength_to_int)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述

  • 对 earliesCreditLine(借款人最早报告的信用额度开立的月份)进行预处理
 df_train['earliesCreditLine'].sample(5) #处理之前
  • 1

在这里插入图片描述

for data in [df_train, df_test]:
    data['earliesCreditLine'] = data['earliesCreditLine'].apply(lambda s: int(s[-4:]))  #只取年份
  • 1
  • 2

在这里插入图片描述

1.4 类别特征处理

部分类别特征

查看类别数

cate_features = ['grade', 'subGrade', 'employmentTitle', 'homeOwnership',
'verificationStatus', 'purpose', 'postCode', 'regionCode', \
'applicationType', 'initialListStatus', 'title', 'policyCode']
for f in cate_features:
    print(f, '类型数:', df_train[f].nunique())
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述
注意: 这一步感觉没有看出什么实质性的差别?

# 类型数在2之上,又不是高维稀疏的,且纯分类特征
for data in [data_train, data_test_a]:
data = pd.get_dummies(data, columns=['subGrade', 'homeOwnership', 'verificationStatus',
'purpose', 'regionCode'], drop_first=True)
  • 1
  • 2
  • 3
  • 4

二、异常值处理

  1. 当你发现异常值后,一定要先分清是什么原因导致的异常值,然后再考虑如何处理。首先,如果这一异常值并不代表一种规律性的,而是极其偶然的现象,或者说你并不想研究这种偶然的现象,这时可以将其删除。其次,如果异常值存在且代表了一种真实存在的现象,那就不能随便删除。在现有的欺诈场景中很多时候欺诈数据本身相对于正常数据勒说就是异常的,我们要把这些异常点纳入,重新拟合模型,研究其规律。能用监督的用监督模型,不能用的还可以考虑用异常检测的算法来做。
  2. 注意test的数据不能删。

2.1 基于3segama原则

  • 在统计学中,如果一个数据分布近似正态,那么大约 68% 的数据值会在均值的一个标准差范围内,大约 95% 会在 两个标准差范围内,大约 99.7% 会在三个标准差范围内。
#编写函数
def find_outliers_by_3segama(data,fea):
    data_std = np.std(data[fea])
    data_mean = np.mean(data[fea])
    outliers_cut_off = data_std * 3
    lower_rule = data_mean - outliers_cut_off
    upper_rule = data_mean + outliers_cut_off
    data[fea+'_outliers'] = data[fea].apply(lambda x:str('异常值') if x > upper_rule or x <
    lower_rule else '正常值')
    return data
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
numerical_fea.remove('issueDate')
numerical_fea  #去掉日期变量
  • 1
  • 2
df_train = df_train.copy()
for fea in numerical_fea:
    df_train = find_outliers_by_3segama(df_train,fea)
    print(df_train[fea+'_outliers'].value_counts())
    print(df_train.groupby(fea+'_outliers')['isDefault'].sum())
    print('\n')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
删除异常值

for fea in numerical_fea:
    df_train = df_train[df_train[fea+'_outliers']=='正常值']
    df_train = df_train.reset_index(drop=True)
  • 1
  • 2
  • 3

在这里插入图片描述

2.2 基于箱型图

总结一句话: 四分位数会将数据分为三个点和四个区间,IQR = Q3 -Q1,下触须=Q1 − 1.5x IQR,上触须=Q3+ 1.5x IQR;
在这里插入图片描述

  • 和3σ原则相比,箱线图依据实际数据绘制,真实、直观地表现出了数据分布的本来面貌,且没有对数据作任何限制性要求(3σ原则要求数据服从正态分布或近似服从正态分布),其判断异常值的标准以四分位数和四分位距为基础。四分位数给出了数据分布的中心、散布和形状的某种指示,具有一定的鲁棒性,即25%的数据可以变得任意远而不会很大地扰动四分位数,所以异常值通常不能对这个标准施加影响。鉴于此,箱线图识别异常值的结果比较客观,因此在识别异常值方面具有一定的优越性。
  • 箱型图提供了识别异常值的一个标准,即异常值通常被定义为小于QL-1.5IQR或大于QU+1.5IQR的值。其中,QL称为下四分位数,表示全部观察值中有四分之一的数据取值比它小;QU称为上四分位数,表示全部观察值中有四分之一的数据取值比它大;IQR称为四分位数间距,是上四分位数QU与下四分位数QL之差,其间包含了全部观察值的一半。

三、数据分箱

  • 特征分箱的目的:
    a. 从模型效果上来看,特征分箱主要是为了降低变量的复杂性,减少变量噪音对模型的影响,提高自变量和因变量的相关度。从而使模型更加稳定。
  • 数据分桶的对象:
    a. 将连续变量离散化
    b. 将多状态的离散变量合并成少状态
  • 分箱的原因:
    a. 数据的特征内的值跨度可能比较大,对有监督和无监督中如k-均值聚类它使用欧氏距离作为相似度函数来测量数据点之间的相似度。都会造成大吃小的影响,其中一种解决方法是对计数值进行区间量化即数据分桶也叫做数据分箱,然后使用量化后的结果。
  • 分箱的优点:
    a. 处理缺失值:当数据源可能存在缺失值,此时可以把null单独作为一个分箱。
    b. 处理异常值:当数据中存在离群点时,可以把其通过分箱离散化处理,从而提高变量的鲁棒性(抗干扰能力)。例如,age若出现200这种异常值,可分入“age > 60”这个分箱里,排除影响。
    c. 业务解释性:我们习惯于线性判断变量的作用,当x越来越大,y就越来越大。但实际x与y之间经常存在着非线性关系,此时可经过WOE变换。
  • 特别要注意一下分箱的基本原则:
    a. (1)最小分箱占比不低于5%
    b. (2)箱内不能全部是好客户
    c. (3)连续箱单调

3.1 固定宽度分箱

  • 当数值横跨多个数量级时,最好按照 10 的幂(或任何常数的幂)来进行分组:09、1099、100999、10009999,等等。固定宽度分箱非常容易计算,但如果计数值中有比较大的缺口,就会产生很多没有任何数据的空箱子。
 -# 通过除法映射到间隔均匀的分箱中,每个分箱的取值范围都是loanAmnt/1000
df_train['loanAmnt_bin1'] = np.floor_divide(df_train['loanAmnt'], 1000)
  • 1
  • 2
## 通过对数函数映射到指数宽度分箱
df_train['loanAmnt_bin2'] = np.floor(np.log10(df_train['loanAmnt']))
  • 1
  • 2

3.2 分位数分箱

df_train['loanAmnt_bin3'] = pd.qcut(df_train['loanAmnt'], 10, labels=False)
  • 1

pd.qcut()函数详细介绍
pd.cut()函数介绍

3.3 卡方分箱(选做)

卡方分箱及其他分箱方法的尝试下次补上!!

四、特征交互

  • 交互特征的构造非常简单,使用起来却代价不菲。如果线性模型中包含有交互特征对,那它的训练时间和评分时间就会从 O(n) 增加到
    O(n2),其中 n 是单一特征的数量。

4.1 特征和特征之间组合

for col in ['grade', 'subGrade']:
    temp_dict = df_train.groupby([col])['isDefault'].agg(['mean']).reset_index().rename(columns={'mean': col + '_target_mean'}) #变成DataFrame
    temp_dict.index = temp_dict[col].values # 索引变成类别变量
    temp_dict
    temp_dict = temp_dict[col + '_target_mean'].to_dict() #变成字典, 方便后续直接数据映射
    temp_dict
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

for col in ['grade', 'subGrade']:
    temp_dict = df_train.groupby([col])['isDefault'].agg(['mean']).reset_index().rename(columns={'mean': col + '_target_mean'})
    temp_dict.index = temp_dict[col].values
    temp_dict = temp_dict[col + '_target_mean'].to_dict()
    df_train[col + '_target_mean'] = df_train[col].map(temp_dict) #直接映射
    df_test[col + '_target_mean'] = df_test_[col].map(temp_dict) #直接映射
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4.2 特征和特征之间衍生

其他衍生变量 mean 和 std

  • 主要了解transform的用法
for df in [data_train, data_test_a]:
	for item in ['n0','n1','n2','n2.1','n4','n5','n6','n7','n8','n9','n10','n11','n12','n13','n14']:
	df['grade_to_mean_' + item] = df['grade'] / df.groupby([item])['grade'].transform('mean')  #如果不用transform,只会得到n0几个类别的grade的均值,transform转化成对应Dataframe,使得Dataframe中每一个n0的值都有对应的grader的均值
	df['grade_to_std_' + item] = df['grade'] / df.groupby([item])['grade'].transform('std')
  • 1
  • 2
  • 3
  • 4
  • 代码结果显示出区别:
    在这里插入图片描述
    在这里插入图片描述

4.3 其他特征衍生的尝试(选做)

-【还没来得及尝试,以后一定要补上!!!】

五、特征编码

one-hot编码和label-hot编码的区别
one-hot编码和label-encode编码,这个链接里包含了label-encode和one-hot编码的官方文档,官方文档看起来更加容易理解!

5.1 one-hot 编码

5.2 label-encode编码

  • label-encode:subGrade,postCode,title高维类别特征需要进行转换
for col in tqdm(['employmentTitle', 'postCode', 'title','subGrade']):
    le = LabelEncoder() #调用labelencoder
    le.fit(list(df_train[col].astype(str).values) +list(df_test[col].astype(str).values)) #匹配要编码的类别,变量在训练集和测试机的合并类别
    df_train[col] = le.transform(list(df_train[col].astype(str).values))#讲变量类别编码赋值给原变量
    df_test[col] = le.transform(list(df_test[col].astype(str).values))
    print('Label Encoding 完成')
    # list(le.inverse_transform([2, 2, 1])) inverse_transform代码可以看到编码后的类别对应的数值
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

5.3 归一化

  1. 对特征做归一化,去除相关性高的特征
  2. 归一化目的是让训练过程更好更快的收敛,避免特征大吃小的问题
  3. 去除相关性是增加模型的可解释性,加快预测过程。
  4. 举例归一化过程

#伪代码
for fea in [要归一化的特征列表]:
	data[fea] = ((data[fea] - np.min(data[fea])) / (np.max(data[fea]) - np.min(data[fea])))
  • 1
  • 2
  • 3

六、特征选择

贴一个特征选择的详细介绍链接,知乎
特征选择技术可以精简掉无用的特征,以降低最终模型的复杂性,它的最终目的是得到一个简约模型,在不降低预测准确率或对预测准确率影响不大的情况下提高计算速度。特征选择不是为了减少训练时间(实际上,一些技术会增加总体训练时间),而是为了减少模型评分时间。

6.1 Filter

6.1.1 方差选择法

  • 方差选择法中,先要计算各个特征的方差,然后根据设定的阈值,选择方差大于阈值的特征
from sklearn.feature_selection import VarianceThreshold
VarianceThreshold(threshold=3).fit_transform(X_train)
#threshold为方差的阈值,返回值是特征选择后的数据
  • 1
  • 2
  • 3

6.1.2 相关系数法(pearson 相关系数)

  • 皮尔森相关系数是一种最简单的,可以帮助理解特征和响应变量之间关系的方法,该方法衡量的是变量之间的线性相关性。
    结果的取值区间为 [-1,1] , -1 表示完全的负相关, +1表示完全的正相关,0 表示没有线性相关。
from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr
#选择K个最好的特征,返回选择特征后的数据
#第一个参数为计算评估特征是否好的函数,该函数输入特征矩阵和目标向量,
#输出二元组(评分,P值)的数组,数组第i项为第i个特征的评分和P值。在此定义为计算相关系数
#参数k为选择的特征个数
SelectKBest(k=5).fit_transform(train,target_train)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6.1.3 卡方检验

  1. 经典的卡方检验是用于检验自变量对因变量的相关性。 假设自变量有N种取值,因变量有M种取值,考虑自变量等于i且因变量等于j的样本频数的观察值与期望的差距。 其统计量如下: χ2=Σ(A−T)2T,其中A为实际值,T为理论值
  2. (注:卡方只能运用在正定矩阵上,否则会报错Input X must be non-negative)
  3. 卡方检验是一种对分类数据的频数进行分析的假设检验方法,用于检验在某个分类变量下,每个类别的行为或特征有无差异,即验证分类自变量对分类因变量是否造成影响。

卡方值描述两个事件的独立性或者描述观察值与期望值的差异程度。

在这里插入图片描述
卡方检验原假设为观察值频数与期望值频数一致。检验类型一般分为以下两种:

  • 拟合优度检验:对一个分类变量的检验,如检验硬币是否均匀。自由度=分类变量类型个数-1。

  • 独立性检验(列联分析):对两个分类变量的检验,比如性别因素对是否吃早餐这一事件是否造成影响。自由度=(分类自变量类型个数-1)*(分类因变量类型个数-1)。

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
#参数k为选择的特征个数
SelectKBest(chi2, k=5).fit_transform(train,target_train)
  • 1
  • 2
  • 3
  • 4
from sklearn.feature_selection import SelectKBest 
from sklearn.feature_selection import chi2

SelectKBest(chi2,k=2).fit_transform(X_train,Y_train)
#选择k个最好的特征,返回选择特征后的数据
  • 1
  • 2
  • 3
  • 4
  • 5

6.1.4 F检验

  • f_classif 用于特征为连续变量、输出为离散变量的分类问题,是基于方差分析的检验,检验的是不同类别下特征的均值。

  • f_regression用于特征和输出均为连续变量的回归问题,是基于样本相关系数的检验,理论上可以用t检验代替,但sklearn将其转化成了一个F值。

from sklearn.feature_selection import SelectKBest 
from sklearn.feature_selection import f_classif, f_regression

SelectKBest(f_classif,k=2).fit_transform(X_train,Y_train)    #分类问题
SelectKBest(f_regression,k=2).fit_transform(X_train,Y_train) #回归问题
  • 1
  • 2
  • 3
  • 4
  • 5

6.1.5 互信息法

  • 经典的互信息也是评价自变量对因变量的相关性的。 在feature_selection库的SelectKBest类结合最大信息系数法可以用于选择特征,相关代码如下:
from sklearn.feature_selection import SelectKBest
from minepy import MINE
#由于MINE的设计不是函数式的,定义mic方法将其为函数式的,
#返回一个二元组,二元组的第2项设置成固定的P值0.5
def mic(x, y):
	m = MINE()
	m.compute_score(x, y)
	return (m.mic(), 0.5)
#参数k为选择的特征个数
SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T,
k=2).fit_transform(train,target_train)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

6.2 Wrapper(RFE)

6.2.1 递归特征消除法

  • 递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征, 再基于新的特征集进行下一轮训练。 在feature_selection库的RFE类可以用于选择特征,相关代码如下(以逻辑 回归为例):
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
#递归特征消除法,返回特征选择后的数据
#参数estimator为基模型
#参数n_features_to_select为选择的特征个数
RFE(estimator=LogisticRegression(),
n_features_to_select=2).fit_transform(train,target_train)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6.3 Embedded

6.3.1 基于惩罚项的特征选择法

  • 基于惩罚项的特征选择法 使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。
    在feature_selection库的SelectFromModel类结合逻辑回归模型可以用于选择特征,相关代码如下:
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
#带L1惩罚项的逻辑回归作为基模型的特征选择
SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(train,target_train)
  • 1
  • 2
  • 3
  • 4

6.3.2 基于树模型的特征选择

  • 基于树模型的特征选择 树模型中GBDT也可用来作为基模型进行特征选择。在feature_selection库的SelectFromModel类结合GBDT模型可以用于选择特征,相关代码如下:
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier
#GBDT作为基模型的特征选择
SelectFromModel(GradientBoostingClassifier()).fit_transform(train,target_train)
  • 1
  • 2
  • 3
  • 4

总结:这次时间仓促,没有预留出足够的时间完成Task3,基本上只是简单的运行了一下代码,后面自己私下要花时间多理解本次任务的代码,多根据数据情况去想着怎么去预处理以及怎么根据实际情况去衍生新的变量。加油!

补充:

  • 本数据集中我们删除非入模特征后,并对缺失值填充,然后用计算协方差的方式看一下特征间相关性,然后进行模型训练
 - # 删除不需要的数据,subGrade 贷款等级之子级[类别太多,没有细分】先直接 删除了这个变量
for data in [df_train, df_test]:
    data.drop(['issueDate','id','subGrade'], axis=1,inplace=True)
  • 1
  • 2
  • 3
"纵向用缺失值上面的值替换缺失值"
df_train = df_train.fillna(axis=0,method='ffill')
  • 1
  • 2
x_train = df_train.drop(['isDefault','id'], axis=1)
#计算协方差
data_corr = x_train.corrwith(df_train.isDefault) #计算相关性
result = pd.DataFrame(columns=['features', 'corr'])
result['features'] = data_corr.index
result['corr'] = data_corr.values
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
#当然也可以直接看图
data_numeric = data_train[numerical_fea]
correlation = data_numeric.corr()

f , ax = plt.subplots(figsize = (7, 7))
plt.title('Correlation of Numeric Features with Price',y=1,size=16)
sns.heatmap(correlation,square = True,  vmax=0.8)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

features = [f for f in data_train.columns if f not in ['id','issueDate','isDefault'] and '_outliers' not in f]
x_train = data_train[features]
x_test = data_test_a[features]
y_train = data_train['isDefault']
  • 1
  • 2
  • 3
  • 4
def cv_model(clf, train_x, train_y, test_x, clf_name):
    folds = 5
    seed = 2020
    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)

    train = np.zeros(train_x.shape[0])
    test = np.zeros(test_x.shape[0])

    cv_scores = []

    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print('************************************ {} ************************************'.format(str(i+1)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]

        if clf_name == "lgb":
            train_matrix = clf.Dataset(trn_x, label=trn_y)
            valid_matrix = clf.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 = clf.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(test_x, num_iteration=model.best_iteration)
            
            # print(list(sorted(zip(features, model.feature_importance("gain")), key=lambda x: x[1], reverse=True))[:20])
                
        if clf_name == "xgb":
            train_matrix = clf.DMatrix(trn_x , label=trn_y)
            valid_matrix = clf.DMatrix(val_x , label=val_y)
            
            params = {'booster': 'gbtree',
                      'objective': 'binary:logistic',
                      'eval_metric': 'auc',
                      'gamma': 1,
                      'min_child_weight': 1.5,
                      'max_depth': 5,
                      'lambda': 10,
                      'subsample': 0.7,
                      'colsample_bytree': 0.7,
                      'colsample_bylevel': 0.7,
                      'eta': 0.04,
                      'tree_method': 'exact',
                      'seed': 2020,
                      'nthread': 36,
                      "silent": True,
                      }
            
            watchlist = [(train_matrix, 'train'),(valid_matrix, 'eval')]
            
            model = clf.train(params, train_matrix, num_boost_round=50000, evals=watchlist, verbose_eval=200, early_stopping_rounds=200)
            val_pred  = model.predict(valid_matrix, ntree_limit=model.best_ntree_limit)
            test_pred = model.predict(test_x , ntree_limit=model.best_ntree_limit)
                 
        if clf_name == "cat":
            params = {'learning_rate': 0.05, 'depth': 5, 'l2_leaf_reg': 10, 'bootstrap_type': 'Bernoulli',
                      'od_type': 'Iter', 'od_wait': 50, 'random_seed': 11, 'allow_writing_files': False}
            
            model = clf(iterations=20000, **params)
            model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
                      cat_features=[], use_best_model=True, verbose=500)
            
            val_pred  = model.predict(val_x)
            test_pred = model.predict(test_x)
            
        train[valid_index] = val_pred
        test = test_pred / kf.n_splits
        cv_scores.append(roc_auc_score(val_y, val_pred))
        
        print(cv_scores)
        
    print("%s_scotrainre_list:" % clf_name, cv_scores)
    print("%s_score_mean:" % clf_name, np.mean(cv_scores))
    print("%s_score_std:" % clf_name, np.std(cv_scores))
    return train, test
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
def lgb_model(x_train, y_train, x_test):
    lgb_train, lgb_test = cv_model(lgb, x_train, y_train, x_test, "lgb")
    return lgb_train, lgb_test

def xgb_model(x_train, y_train, x_test):
    xgb_train, xgb_test = cv_model(xgb, x_train, y_train, x_test, "xgb")
    return xgb_train, xgb_test

def cat_model(x_train, y_train, x_test):
    cat_train, cat_test = cv_model(CatBoostRegressor, x_train, y_train, x_test, "cat")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
lgb_train, lgb_test = lgb_model(x_train, y_train, x_test)
  • 1

在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/142847
推荐阅读
  

闽ICP备14008679号