HW9-第七讲:使用集成算法建立个人银行反欺诈模型-

浏览: 1876

1、背景介绍:

C银行信用卡中心在对欺诈风险和反欺诈技术作了充分研究之后,融合内外部数据,

建立以评分模型为支撑的欺诈识别和防范系统,以满足精细化管理的需要。

本次作业根据“FRAUD_TRAIN_Samp.csv”,引自《SAS金融数据挖掘与建模》,建立信用卡申请反欺诈模型。

2、主要变量说明如下:

#无-组合算法为黑箱模型,无需知道变量含义

3、作业安排:

3.1 基础知识:

      1)比较逻辑回归、决策树、神经网络、组合算法的适用场景和优缺点。

3.2 案例解答步骤如下:

     1)使用决策树、神经网络、组合算法建立反欺诈模型,比较三个模型的表现。

     2)自学绘制PR曲线:横轴为精确度(Precise),纵轴为召回率(Recall)。

 #%%
import os
import pandas as pd

os.chdir(r'D:\Learningfile\天善学院\280_Ben_八大直播八大案例配套课件\提交-第七讲:使用集成算法建立个人银行反欺诈模型\作业')
data=pd.read_excel('FRAUD_TRAIN_Samp.xlsx')
#%%
data.target.value_counts()
#%%
data.F81.value_counts()
#%%
data.F74.value_counts()
#%%
data.F75.value_counts()
#%%
data.F80.value_counts()
#%%
import numpy as np

dict_F81={'无等级':0,
np.nan:0,
'平衡':1,
'稳健':1,
'成长':1,
'进取':1,
'保守':1}

data['F81']=data['F81'].map(dict_F81)

#%%
dict_F75={'M':1,
'F':0,
np.nan:2}
data.F75=data.F75.map(dict_F75)

#%%缺失值处理
data1=data.copy()

data1=data1.drop(['csr_id','F74','F80'],axis=1)

data1=data1.fillna(0)

#%%
from sklearn.cross_validation import train_test_split
data_X=data1.iloc[:,1:]
data_y=data1.iloc[:,0]
train_X,test_X,train_y,test_y=train_test_split(data_X,data_y,test_size=0.4, train_size=0.6, random_state=12345)

#%%

#采样
from imblearn.combine import SMOTETomek
kos = SMOTETomek(random_state=0) # 综合采样
X_kos, y_kos = kos.fit_sample(train_X, train_y)

#%%
#决策树建模
from sklearn.tree import DecisionTreeClassifier
from sklearn import metrics
from sklearn.model_selection import GridSearchCV

clf = DecisionTreeClassifier(criterion='gini', random_state=1234)
param_grid = {'max_depth':[4,12,13,14], 'max_leaf_nodes':[4,12,30,31,32]}
cv = GridSearchCV(clf, param_grid=param_grid, scoring='f1')

cv.fit(X_kos, y_kos)

predict_test = cv.predict(test_X)
test_proba = cv.predict_proba(test_X)[:, 1]
#%%

from sklearn import metrics
fpr_test, tpr_test, th_test = metrics.roc_curve(test_y, test_proba)
print('AUC = %6.4f' %metrics.auc(fpr_test, tpr_test))

#print(metrics.classification_report(test_y, predict_test))
#%%
cv.best_params_

#%%
#神经网络建模
#标准化
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
scaler.fit(train_X)

scaled_train_data = scaler.transform(train_X)
scaled_test_data = scaler.transform(test_X)
# In[5]:
from sklearn.neural_network import MLPClassifier

mlp = MLPClassifier(hidden_layer_sizes=(10,),
activation='logistic', alpha=0.1, max_iter=1000)

mlp.fit(scaled_train_data, train_y)
mlp
#%%
predict_test2 = mlp.predict(scaled_test_data)
test_proba2 = mlp.predict_proba(scaled_test_data)[:, 1]

from sklearn import metrics
fpr_test2, tpr_test2, th_test2 = metrics.roc_curve(test_y, test_proba2)
print('AUC = %6.4f' %metrics.auc(fpr_test2, tpr_test2))
#print(metrics.classification_report(test_y, predict_test2))
#%%
##RF建模
import sklearn.ensemble as ensemble
from sklearn.ensemble import RandomForestClassifier
param_grid = {
'criterion':['entropy','gini'],
'max_depth':[4,5,6,7],
'n_estimators':[24,26,28], #决策树个数-随机森林特有参数
'max_features':[0.02,0.04,0.4], #每棵决策树使用的变量占比-随机森林特有参数
'min_samples_split':[74,75,78]
}

rfc = RandomForestClassifier()
rfccv = GridSearchCV(estimator=rfc, param_grid=param_grid, scoring='roc_auc', cv=4,n_jobs=-1)
rfccv.fit(train_X, train_y)
test_est3 = rfccv.predict(test_X)
test_proba3 = rfccv.predict_proba(test_X)[:, 1]
fpr_test3,tpr_test3,th_test3=metrics.roc_curve(test_y,test_proba3)
print('RF ROC')
print('ROC=%.4f' %metrics.auc(fpr_test3,tpr_test3))
#%%
rfccv.best_params_



#%%
#首先对n_estimators进行网格搜索
param_test1= {'n_estimators':range(10,71,10)}
gsearch1= GridSearchCV(estimator =RandomForestClassifier(min_samples_split=100,
min_samples_leaf=20,max_depth=8,max_features='sqrt' ,random_state=10),
param_grid =param_test1, scoring='roc_auc',cv=5)
gsearch1.fit(train_X, train_y)
gsearch1.grid_scores_,gsearch1.best_params_, gsearch1.best_score_

#%%
#这样我们得到了最佳的弱学习器迭代次数,接着我们对决策树最大深度max_depth和内部节点再划分所需最小样本数min_samples_split进行网格搜索。
param_test2= {'max_depth':range(2,8,1), 'min_samples_split':range(3,21,5)}
gsearch2= GridSearchCV(estimator = ensemble.RandomForestClassifier(n_estimators= 40,
min_samples_leaf=20,max_features='sqrt' ,oob_score=True,random_state=10),
param_grid = param_test2,scoring='roc_auc',iid=False, cv=5)
gsearch2.fit(train_X, train_y)
gsearch2.grid_scores_,gsearch2.best_params_, gsearch2.best_score_
#%%

rfc.fit(train_X,train_y)
print(rfc.oob_score_)
#%%
#已经取了三个最优参数,看看现在模型的袋外分数:

rf1= RandomForestClassifier(n_estimators= 40, max_depth=3, min_samples_split=3,
min_samples_leaf=20,max_features='sqrt' ,oob_score=True,random_state=10)
rf1.fit(train_X, train_y)
print(rf1.oob_score_)
#输出结果为:0.9485
#可见此时我们的袋外分数有一定的提高。也就是时候模型的泛化能力增强了。
#对于内部节点再划分所需最小样本数min_samples_split,我们暂时不能一起定下来,因为这个还和决策树其他的参数存在关联。
#下面我们再对内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf一起调参。
#%%
#再对内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf一起调参
param_test3= {'min_samples_split':range(3,30,5), 'min_samples_leaf':range(10,81,10)}
gsearch3= GridSearchCV(estimator = RandomForestClassifier(n_estimators= 40,max_depth=3,
max_features='sqrt' ,oob_score=True, random_state=10),
param_grid = param_test3,scoring='roc_auc',iid=False, cv=5)
gsearch3.fit(train_X, train_y)
gsearch3.grid_scores_,gsearch2.best_params_, gsearch2.best_score_

#%%
#最后我们再对最大特征数max_features做调参:
param_test4= {'max_features':range(3,11,2)}
gsearch4= GridSearchCV(estimator = RandomForestClassifier(n_estimators= 40,max_depth=3, min_samples_split=3,
min_samples_leaf=50 ,oob_score=True, random_state=10),
param_grid = param_test4,scoring='roc_auc',iid=False, cv=5)
gsearch4.fit(train_X, train_y)
gsearch4.grid_scores_,gsearch4.best_params_, gsearch4.best_score_

#%%
#用我们搜索到的最佳参数,我们再看看最终的模型拟合:
rf2= RandomForestClassifier(n_estimators= 40, max_depth=3, min_samples_split=3,
min_samples_leaf=50,max_features=5 ,oob_score=True, random_state=10)
rf2.fit(train_X, train_y)
print(rf2.oob_score_)
#此时的输出为:0.9485
#可见此时模型的袋外分数基本没有提高,主要原因是0.9485已经是一个很高的袋外分数了,如果想进一步需要提高模型的泛化能力,我们需要更多的数据。

#%%
test_est31 = rf2.predict(test_X)
test_proba31 = rf2.predict_proba(test_X)[:, 1]
fpr_test31,tpr_test31,th_test31=metrics.roc_curve(test_y,test_proba31)
print('rf ROC')
print('ROC=%.4f' %metrics.auc(fpr_test31,tpr_test31))

#%%
#Adaboost算法
param_grid = {
#'base_estimator':['DecisionTreeClassifier'],
'learning_rate':[0.1,0.3,0.5,0.7,1]
}

abc = ensemble.AdaBoostClassifier(n_estimators=100,algorithm='SAMME')
abccv = GridSearchCV(estimator=abc, param_grid=param_grid, scoring='roc_auc', cv=4,n_jobs=-1)
abccv.fit(train_X, train_y)
test_est4 = abccv.predict(test_X)
test_proba4 = abccv.predict_proba(test_X)[:, 1]
print("abc classifier accuracy:")
print(metrics.classification_report(test_y,test_est4))

fpr_test4,tpr_test4,th_test4=metrics.roc_curve(test_y,test_proba4)
print('adaboost ROC')
print('ROC=%.4f' %metrics.auc(fpr_test4,tpr_test4))
#%%
abccv.best_params_

# In[ ]:
#GBDT
param_grid = {
'loss':['deviance','exponential'],
'learning_rate':[0.1,0.3,0.8],
'n_estimators':[26,28,30,32], #决策树个数-GBDT特有参数
'max_depth':[4,5,6], #单棵树最大深度-GBDT特有参数
'min_samples_split':[2,15,20,25]
}

gbc = ensemble.GradientBoostingClassifier()
gbccv = GridSearchCV(estimator=gbc, param_grid=param_grid, scoring='roc_auc', cv=4,n_jobs=-1)
gbccv.fit(train_X, train_y)
test_est5 = gbccv.predict(test_X)
test_proba5 = gbccv.predict_proba(test_X)[:, 1]
print("gradient boosting accuracy:")
print(metrics.classification_report(test_y,test_est5))

fpr_test5,tpr_test5,th_test5=metrics.roc_curve(test_y,test_proba5)
print('gbdt ROC')
print('ROC=%.4f' %metrics.auc(fpr_test5,tpr_test5))
#%%
gbccv.best_params_


#%%
#PR曲线
from sklearn.metrics import precision_recall_curve
import matplotlib.pyplot as plt

precision,recall,threshold=precision_recall_curve(test_y, test_proba3)

plt.figure(figsize=[6,6])
plt.plot(precision,recall)
plt.ylabel('recall')
plt.xlabel('precision')
plt.title('pr curve')
plt.show()

推荐 0
本文由 行者无疆01 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册