序
特征工程之后,我们基本了解了数据集的概貌,通过缺失值处理、异常值处理、归一化、独热编码、特征构造等一系列方法对数据进行了预处理,并根据不同模型的数据要求对数据进行了一定的转化,从而进行下一步模型的学习过程。以下就是对数据进行处理后,训练模型的过程代码。其实可以先使用随机森林等方法先做一步特征筛选的工作,我这里没有做特征的筛选,而且先复现了数据准备,模型构造和调参的过程。若是模型初步表现不错且较稳定,我会后续做特征筛选或特征构造,进一步提高模型的分数。
数据准备
导入第三方库
import pandas as pd
import numpy as np
import lightgbm as lgb
import warnings
import matplotlib.pyplot as plt
from sklearn import metrics
from sklearn.model_selection import KFold, train_test_split, cross_val_score, GridSearchCV, StratifiedKFold
from sklearn.metrics import roc_auc_score
from bayes_opt import BayesianOptimization
import datetime
import pickle
import seaborn as sns
'''
sns 相关设置
@return:
"""
# 声明使用 Seaborn 样式
sns.set()
# 有五种seaborn的绘图风格,它们分别是:darkgrid, whitegrid, dark, white, ticks。默认的主题是darkgrid。
sns.set_style("whitegrid")
# 有四个预置的环境,按大小从小到大排列分别为:paper, notebook, talk, poster。其中,notebook是默认的。
sns.set_context('talk')
# 中文字体设置-黑体
plt.rcParams['font.sans-serif'] = ['SimHei']
# 解决保存图像是负号'-'显示为方块的问题
plt.rcParams['axes.unicode_minus'] = False
# 解决Seaborn中文显示问题并调整字体大小
sns.set(font='SimHei')
'''
warnings.filterwarnings('ignore')
pd.options.display.max_columns = None
pd.set_option('display.float_format', lambda x: '%.2f' % x)
读取数据
train = pd.read_csv(r'D:\Users\Felixteng\Documents\Pycharm Files\loanDefaultForecast\data\train.csv')
testA = pd.read_csv(r'D:\Users\Felixteng\Documents\Pycharm Files\loanDefaultForecast\data\testA.csv')
压缩数据
def reduce_mem_usage(df):
'''
遍历DataFrame的所有列并修改它们的数据类型以减少内存使用
:param df: 需要处理的数据集
:return:
'''
start_mem = df.memory_usage().sum() / 1024 ** 2 # 记录原数据的内存大小
print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))
for col in df.columns:
col_type = df[col].dtypes
if col_type != object: # 这里只过滤了object格式,如果代码中还包含其他类型,要一并过滤
c_min = df[col].min()
c_max = df[col].max()
if str(col_type)[:3] == 'int': # 如果是int类型的话,不管是int64还是int32,都加入判断
# 依次尝试转化成in8,in16,in32,in64类型,如果数据大小没溢出,那么转化
if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
df[col] = df[col].astype(np.int8)
elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
df[col] = df[col].astype(np.int16)
elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
df[col] = df[col].astype(np.int32)
elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
df[col] = df[col].astype(np.int64)
else: # 不是整形的话,那就是浮点型
if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
df[col] = df[col].astype(np.float16)
elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
df[col] = df[col].astype(np.float32)
else:
df[col] = df[col].astype(np.float64)
else: # 如果不是数值型的话,转化成category类型
df[col] = df[col].astype('category')
end_mem = df.memory_usage().sum() / 1024 ** 2 # 看一下转化后的数据的内存大小
print('Memory usage after optimization is {:.2f} MB'.format(end_mem))
print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem)) # 看一下压缩比例
return df
train = reduce_mem_usage(train)
testA = reduce_mem_usage(testA)
del testA['n2.2']
del testA['n2.3']
简单建模
'''
Tips1:金融风控的实际项目多涉及到信用评分,因此需要模型特征具有较好的可解释性,所以目前在实际项目中多还是以逻辑回归作为基础模型。
但是在比赛中以得分高低为准,不需要严谨的可解释性,所以大多基于集成算法进行建模。
Tips2:因为逻辑回归的算法特性,需要提前对异常值、缺失值数据进行处理(参考task3部分)
Tips3:基于树模型的算法特性,异常值、缺失值处理可以跳过,但是对于业务较为了解的同学也可以自己对缺失异常值进行处理,效果可能会更优于模型处理的结果。
注:以下建模的源数据参考baseline进行了相应的特征工程,对于异常缺失值未进行相应的处理操作
'''
建模之前的数据处理
为了方便起见,把训练集和测试集合并处理
data = pd.concat([train, testA], axis=0, ignore_index=True)
category特征不能直接训练,需要处理转换
'''
['grade', 'subGrade', 'employmentLength', 'issueDate', 'earliesCreditLine']
先处理'employmentLength', 'issueDate', 'earliesCreditLine'这三个特征;'grade'和'subGrade'做one-hot编码
'''
‘employmentLength’ - 转换为数值
data.groupby('employmentLength')['id'].count()
'''10年以上算10年,1年一下算0年'''
data['employmentLength'].replace(to_replace='10+ years', value='10 years', inplace=True)
data['employmentLength'].replace(to_replace='< 1 year', value='0 year', inplace=True)
def employmentLength_to_int(s):
if pd.isnull(s):
return s
else:
return np.int8(s.split()[0])
data['employmentLength'] = data['employmentLength'].apply(employmentLength_to_int)
‘earliesCreditLine’ - 分别提取年份和月份做拼接
data['earliesCreditLine_year'] = data['earliesCreditLine'].apply(lambda x: x[-4:])
data['earliesCreditLine_month'] = data['earliesCreditLine'].apply(lambda x: x[0:3])
def month_re(x):
if x == 'Jan':
return '01'
elif x == 'Feb':
return '02'
elif x == 'Mar':
return '03'
elif x == 'Apr':
return '04'
elif x == 'May':
return '05'
elif x == 'Jun':
return '06'
elif x == 'Jul':
return '07'
elif x == 'Aug':
return '08'

最低0.47元/天 解锁文章
348

被折叠的 条评论
为什么被折叠?



