赞
踩
信贷业务又称为信贷资产或贷款业务,是商业银行最重要的资产业务,通过放款收回本金和利息,扣除成本后获得利润,所以信贷是商业银行的主要赢利手段。
XGBoost是一套提升树可扩展的机器学习系统。目标是设计和构建高度可扩展的端到端提升树系统。提出了一个理论上合理的加权分位数略图来计算候选集。引入了一种新颖的稀疏感知算法用于并行树学习。提出了一个有效的用于核外树形学习的缓存感知块结构。用缓存加速寻找排序后被打乱的索引的列数据的过程。XGBoost是一个树集成模型,他将K(树的个数)个树的结果进行求和,作为最终的预测值。
使用机器学习建模的一般流程。分为两大部分:数据处理和模型学习。第一部分需要大量的知识对原始数据进行清理及特征提取;第二部分模型学习,涉及长时间的模型参数调整,调整方向和策略需要根据经验来灵活调整。当模型效果不理想时,考虑的调整策略:
1. Logistic函数
Logistic回归模型中的因变量只有1和0(发生于不发生)两种。假设在p个独立自变量x1,x2…xp作用下,y取1的概率是p = P(y = 1|X)取0的概率是1-p,取1和取0的概率之比为:P/(1-P);称为事件的优势比(odds),对odds取自然对数得Logistic变换。
2.Logistic回归建模步骤
(a)根据分析目的设置指标变量(因变量和自变量),然后收集数据,根据收集到的数据,对特征再次进行筛选;
#特征重要程度情况 ax = xgb.plot_importance(model) fig = ax.figure fig.set_size_inches(15,10) |
(b)y取1的概率是p= P(y= 1|X), 取0概率是1-p。用
ln(p/(1−p))和自变量列出线性回归方程,估计出模型中的回归系数;
(c)进行模型检验。模型有效性的检验指标有很多,最基本的有正确率,其次有混淆矩阵、ROC曲线、KS值等。
(d)模型应用:输入自变量的取值,就可以得到预测变量的值,或者根据预测变量的值去控制自变量的取值。
实例:
gender | age | dist | edu | job | lmt | basicLevel | x_0 | x_1 |
2 | 27 | 640500 | 0 | 8 | 5.963 | 3 | 0 | 0 |
2 | 25 | 640600 | 0 | 3 | 6.467 | 3 | 0 | 0 |
2 | 37 | 641200 | 70 | 5 | 0.596 | 1 | 0 | 0 |
2 | 29 | 340821 | 0 | 4 | 6.3 | 3 | 0 | 0 |
2 | 22 | 732628 | 0 | 2 | 6.7 | 2 | 0 | 0 |
利用Scikit-Learn对这个数据进行逻辑回归分析。首先进行特征筛选,特征筛选的方法有很多,主要包含在Scikit_Learn 的feature_ selection 库中,比较简单的有通过F检验(f_ regression)来给出各个特征的F值和p值,从而可以筛选变量(选择F值大的或者p值小的特征)。其次有递归特征消除( Recursive Feature Elimination, RFE)和稳定性选择(StabilitySelection)等比较新的方法。这里使用了稳定性选择方法中的随机逻辑回归进行特征筛选,然后利用筛选后的特征建立逻辑回归模型,输出平均正确率。
3.数据源内容解读
数据集,可以看到数据样本中有很多列属性。
train_df = pd.read_csv("D:/files/train.csv") test_df = pd.read_csv("D:/files/test.csv") |
4.Python主要数据预处理函数
在数据挖掘中,海量的原始数据中存在着大量不完整(有缺失值)、不一致、有异常的数据,严重影响到数据挖掘建模的执行效率,甚至可能导致挖掘结果的偏差,所以进行数据清洗就显得尤为重要,数据清洗完成后接着进行或者同时进行数据集成、转换、规约等一系列的处理,该过程就是数据预处理。数据预处理一方面是要提高数据的质量,另一方面是要让数据更好地适应特定的挖掘技术或工具。
5.二分类
对于二分类模型,其实既可以构建分类器,也可以构建回归。
# predict train predict_train = model.predict(dtrain) train_auc = evaluate_score(predict_train, y_train) # predict validate predict_valid = model.predict(dvalid) valid_auc = evaluate_score(predict_valid, y_valid) print('train auc = {:.7f} , valid auc = {:.7f}\n'.format(train_auc, valid_auc)) |
数据处理需要花费大量的精力,说明在机器学习中数据准备的工作很重要,有了好的数据才能预测出好的分类结果,对于二分类问题,一般情况下,首选逻辑回归。
#模型训练 model = xgb.train(dict(xgb_params), dtrain, evals=watchlist, verbose_eval=50, early_stopping_rounds=100, num_boost_round=4000) |
#利用最佳迭代次数,再次利用全量数据训练模型 print('---> training on total dataset to predict test and submit') model = xgb.train(dict(xgb_params), dtrain_all, num_boost_round=best_num_boost_rounds) # predict validate predict_valid = model.predict(dvalid) valid_auc = evaluate_score(predict_valid, y_valid) print('预测的验证集 AUC 指标:', valid_auc) |
===> feature count: 103 scale_pos_weight = 1 train: 91826, valid: 10203, test: 30000 [0] train-auc:0.50000 valid-auc:0.50000 Multiple eval metrics have been passed: 'valid-auc' will be used for early stopping. Will train until valid-auc hasn't improved in 100 rounds. [50] train-auc:0.64097 valid-auc:0.65167 [100] train-auc:0.65153 valid-auc:0.67749 [150] train-auc:0.67276 valid-auc:0.72217 [200] train-auc:0.68959 valid-auc:0.73652 [250] train-auc:0.71319 valid-auc:0.73802 [300] train-auc:0.74216 valid-auc:0.73880 Stopping. Best iteration: [241] train-auc:0.70966 valid-auc:0.73982 train auc = 0.7646057 , valid auc = 0.7385212 ---> cv train to choose best_num_boost_round [0] train-auc:0.50000 test-auc:0.50000 [100] train-auc:0.65790 test-auc:0.64860 [200] train-auc:0.69347 test-auc:0.66955 [300] train-auc:0.74312 test-auc:0.68096 [400] train-auc:0.79174 test-auc:0.69092 [500] train-auc:0.81697 test-auc:0.69518 [600] train-auc:0.83385 test-auc:0.69656 |
查看预测结果
""" 定义方法:评价得分模型 """ def evaluate_score(predict, y_true): #通过sklearn的roc_curve函数计算false positive rate和true positive rate以及对应的thresholds #理论上thresholds应该取遍所有的predict(即模型预测值) #thresholds就是predict(即模型预测值)逆序排列后的结果 false_positive_rate, true_positive_rate, thresholds = roc_curve(y_true, predict, pos_label=1) auc_score = auc(false_positive_rate, true_positive_rate)#计算ROC曲线下的面积 return auc_score train_df.head()#返回数据 y_train_all = train_df['target'] del train_df['id'] del train_df['target'] train_df.head() |
#ROC 曲线 fpr, tpr, _ = roc_curve(y_valid, predict_valid) roc_auc = auc(fpr, tpr) plt.figure(figsize=(10,10)) plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % roc_auc) plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--') plt.xlim([-0.02, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC curve') plt.legend(loc="lower right") plt.show() |
train_df = pd.read_csv("D:/files/train.csv")#将csv文件读入并转化为数据框形式 test_df = pd.read_csv("D:/files/test.csv")#将csv文件读入并转化为数据框形式 """ 训练集样本数: (102029, 105) 测试集样本数: (30000, 105) """ print("训练集样本数:", train_df.shape)#读取矩阵长度,如shape[0]是读取矩阵第一维的长度 print("测试集样本数:", test_df.shape)#读取矩阵长度,如shape[0]是读取矩阵第一维的长度 |
#违约用户数量分布 plt.figure(figsize=(10,6))#表示figure 的大小为宽、长(单位为inch) #使用normalize=True参数进行计数排序得出占比,赋值给train_df的target tmp = train_df["target"].value_counts(normalize=True)#train.csv的DA列 _, ax = plt.subplots()#返回一个包含figure和axes对象的元组 sns.barplot(x=tmp.index.tolist(), y=tmp.values, ci=None, ax=ax)#按坐标绘制条形图 #将一个可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标 for i, j in enumerate(tmp.sort_index()):#根据列数据/行数据排序 #可视化text()函数 ax.text(i, j, round(j, 5), ha="center", fontsize=12) del tmp gc.collect()#清理内存 plt.show()#按坐标绘制条形图,显示该条形图 |
#违约用户性别分布 plt.figure(figsize=(10,6))#表示figure 的大小为宽、长(单位为inch) #使用normalize=True参数进行计数排序得出占比,赋值给train_df的gender tmp = train_df["gender"].value_counts(normalize=True) #返回一个包含figure和axes对象的元组 _, ax = plt.subplots() sns.barplot(x=tmp.index.tolist(), y=tmp.values, ci=None, ax=ax)#按坐标绘制条形图 for i, j in enumerate(tmp.sort_index()):#根据列数据/行数据排序 ax.text(i, j, round(j, 5), ha="center", fontsize=12) #可视化text()函数 del tmp gc.collect()#清理内存 plt.show() |
#违约用户年龄分布 plt.figure(figsize=(20,6)) # 对 年龄 age 维度进行统计不同值出现的个数,数值进行归一化处理 tmp = train_df["age"].value_counts(normalize=True) ax = plt.subplot(111)#单个整数编码的子绘图网格参数,“111”表示“1×1网格,第一子图 sns.barplot(x=tmp.index.tolist(), y=tmp.values, ci=None, ax=ax)#按坐标绘制条形图 for i, j in enumerate(tmp.sort_index()):#根据列数据/行数据排序 ax.text(i, j, round(j, 5), ha="center", fontsize=12)#可视化text()函数 del tmp gc.collect()#清理内存 plt.show()# |
#违约用户工作单位类型分布 plt.figure(figsize=(20,6)) # 对 用户工作单位类型 job 维度进行统计不同值出现的个数,数值进行归一化处理 tmp = train_df["job"].value_counts(normalize=True) ax = plt.subplot(111)#单个整数编码的子绘图网格参数,“111”表示“1×1网格,第一子图 sns.barplot(x=tmp.index.tolist(), y=tmp.values, ci=None, ax=ax)#按坐标绘制条形图 for i, j in enumerate(tmp.sort_index()):#根据列数据/行数据排序 ax.text(i, j, round(j, 5), ha="center", fontsize=12)#可视化text()函数 del tmp gc.collect()#清理内存 plt.show() |
# 不同借贷产品类型的违约比例分布 将数据集按照借贷产品类型进行分组统计,分别计算不同组违约的比例 plt.figure(figsize=(20,6)) tmp = train_df.groupby("loanProduct")["target"].mean().to_frame("ratio").reset_index() #返回一个包含figure和axes对象的元组 _, ax = plt.subplots() sns.barplot(x="loanProduct", y="ratio", ci=None, data=tmp, ax=ax) # DataFrame,数组或数组列表,可选 for i, j in enumerate(tmp["ratio"]):#根据列数据/行数据排序 ax.text(i, j, round(j, 5), ha="center", fontsize=12) del tmp gc.collect()#清理内存 plt.show() |
#不同借贷产品类型的违约随时间变化趋势 tmp_1 = train_df.loc[train_df["loanProduct"] == 1, "target"].rolling(500).mean().dropna().reset_index(drop=True) tmp_2 = train_df.loc[train_df["loanProduct"] == 2, "target"].rolling(500).mean().dropna().reset_index(drop=True) tmp_3 = train_df.loc[train_df["loanProduct"] == 3, "target"].rolling(500).mean().dropna().reset_index(drop=True) plt.figure(figsize=(20,6))#违约用户工作单位类型分布 ax = plt.subplot(131)#建立子图 tmp_1.plot(ax=ax) ax = plt.subplot(132) tmp_2.plot(ax=ax) ax = plt.subplot(133) tmp_3.plot(ax=ax) plt.show() |
8 预授信金额分布
#预授信金额分布 plt.figure(figsize=(15, 5)) ax = plt.subplot(121) sns.kdeplot(train_df[train_df['target'] == 1]['lmt']) ax.set_title('Normal User') ax = plt.subplot(122) sns.kdeplot(train_df[train_df['target'] == 0]['lmt']) ax.set_title('Risk User') plt.show() |
#基础评级分布 plt.figure(figsize=(15, 5)) ax = plt.subplot(121) sns.countplot(train_df[train_df['target'] == 1]['basicLevel']) ax.set_title('Normal User') ax = plt.subplot(122) sns.countplot(train_df[train_df['target'] == 0]['basicLevel']) ax.set_title('Risk User') plt.show() |
10 用户的民族分布情况
#用户的民族分布情况 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.countplot(train_df[train_df['target'] == 1]['ethnic']) ax.set_title('Normal User') ax = plt.subplot(122) sns.countplot(train_df[train_df['target'] == 0]['ethnic']) ax.set_title('Risk User') plt.show() |
#用户最高学历分布情况 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.countplot(train_df[train_df['target'] == 1]['highestEdu']) ax.set_title('Normal User') ax = plt.subplot(122) sns.countplot(train_df[train_df['target'] == 0]['highestEdu']) ax.set_title('Risk User') plt.show() |
12 用户的联系人关系分布
#用户的联系人关系分布 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.countplot(train_df[train_df['target'] == 1]['linkRela']) ax.set_title('Normal User') ax = plt.subplot(122) sns.countplot(train_df[train_df['target'] == 0]['linkRela']) ax.set_title('Risk User') plt.show() |
#用户申请信用卡时段分布 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.countplot(train_df[train_df['target'] == 1]['setupHour']) ax.set_title('Normal User') ax = plt.subplot(122) sns.countplot(train_df[train_df['target'] == 0]['setupHour']) ax.set_title('Risk User') plt.show() |
#用户申请信用卡时段分布 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.countplot(train_df[train_df['target'] == 1]['weekday']) ax.set_title('Normal User') ax = plt.subplot(122) sns.countplot(train_df[train_df['target'] == 0]['weekday']) ax.set_title('Risk User') plt.show() |
15 用户失效信用卡数分布
#用户失效信用卡数分布 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.countplot(train_df[train_df['target'] == 1]['ncloseCreditCard']) ax.set_title('Normal User') ax = plt.subplot(122) sns.countplot(train_df[train_df['target'] == 0]['ncloseCreditCard']) ax.set_title('Risk User') plt.show() |
#用户未支付个人贷款金额分布 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.kdeplot(train_df[train_df['target'] == 1]['unpayIndvLoan']) ax.set_title('Normal User') ax = plt.subplot(122) sns.kdeplot(train_df[train_df['target'] == 0]['unpayIndvLoan']) ax.set_title('Risk User') plt.show() |
17 用户未支付其他贷款金额分布
#用户未支付其他贷款金额分布 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.kdeplot(train_df[train_df['target'] == 1]['unpayNormalLoan']) ax.set_title('Normal User') ax = plt.subplot(122) sns.kdeplot(train_df[train_df['target'] == 0]['unpayNormalLoan']) ax.set_title('Risk User') plt.show() |
18 用户五年内未支付贷款金额
#用户五年内未支付贷款金额 plt.figure(figsize=(20, 5)) ax = plt.subplot(121) sns.kdeplot(train_df[train_df['target'] == 1]['5yearBadloan']) ax.set_title('Normal User') ax = plt.subplot(122) sns.kdeplot(train_df[train_df['target'] == 0]['5yearBadloan']) ax.set_title('Risk User') plt.show() |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。