博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
机器学习实战:基于逻辑回归模型的信用卡欺诈检测
阅读量:2051 次
发布时间:2019-04-28

本文共 8561 字,大约阅读时间需要 28 分钟。

某银行为提升信用卡反欺诈检测能力,提供了脱敏后的一份个人交易记录。考虑数据本身的隐私性,数据提供之初已经进行了类似PCA的处理,并得到了若干数据特征。在不需要做额外特征提取工作的情况下,本项目意在通过逻辑回归模型的调优,得到较为准确可靠的反欺诈检测方法,分析过程中使用到了Python Pandas, Numpy, Matplotlib, Seaborn以及机器学习库Scikit-Learn等。

数据链接:

链接:https://pan.baidu.com/s/11uT0CHYPenX_67qTdr-Tjg
密码:b9xo

完整代码实现如下:

下采样完整代码:

import pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom sklearn.preprocessing import StandardScalerfrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import LogisticRegressionfrom sklearn.model_selection import KFold,cross_val_score #cross_val_score交叉验证from sklearn.metrics import confusion_matrix,recall_score,classification_reportfrom sklearn.model_selection import cross_val_predictdata = pd.read_csv('/Users/hxx/Downloads/creditcard.csv')print(data.head())#查看数据样本是否均衡(正负样本是否均衡)pd.value_counts(data['Class'],sort=True).sort_index()#print(pd.value_counts(data['Class'],sort=True).sort_index())#value_count计算某列属性中属性不为1的值有多少个count_classes = pd.value_counts(data['Class'],sort=True).sort_index()#value_counts()是一种查看表格某列中有多少个不同值的快捷方法,并计算每个不同值有在该列中有多少重复值。count_classes.plot(kind='bar')##简单的pandas也可以画图,kind=bar画的条状图,kind=line画的线性图plt.title('Fraud class histogrm')plt.xlabel('Class')plt.ylabel('Frequency')plt.show()#从上图中可以发现,正反数据比例不均衡,因此引入采样对数据进行调整#采样分为下采样和上采样,下采样就是对数据量大的进行减少,上采样就是对数据量较少的进行添加数据#  预处理#我们从数据中发现Amount这个属性对应的数据值与其他属性数据相差过大,因此进行标准化处理#标准化就是对数据先减去均值在处以标准差,去均值的好处使数据关于原点对称,除以标准差好处使各个维度的数据取值范围尽可能的相同data['normAmount'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1,1))#Fit()简单来说,就是求得训练集X的均值啊,方差啊,最大值啊,最小值啊这些训练集X固有的属性。可以理解为一个训练过程#Transform()在Fit的基础上,进行标准化,降维,归一化等操作(看具体用的是哪个工具,如PCA,StandardScaler等)#fit_transform(Data)对部分数据先拟合fit,找到该part的整体指标,如均值、方差、最大值最小值等等,然后对Data进行转换transform,从而实现数据的标准化、归一化等等#reshape(a,b)函数中a代表行数,b代表列数,就是转换成a行b列,但是-1代表未指定,因此这边normAmount就是多少行一列的数据data = data.drop(['Time','Amount'],axis=1)#去掉Time列和Amount列,axis=1代表的列print(data.head())#  下采样X = data.iloc[:,data.columns != 'Class']y = data.iloc[:,data.columns == 'Class']#data.iloc函数是基于位置索引,添加条件进行过滤number_records_fraud = len(data[data.Class==1])fraud_indices = np.array(data[data.Class==1].index)#用一个数组将class==1的对应的索引记录下来normal_indices = np.array(data[data.Class==0].index)#得到class==0的对应的索引#随机选取class==1的索引,个数为class==1的个数random_normal_indices = np.random.choice(normal_indices,number_records_fraud,replace=False)#replace指定为False时,采样不会重复#将class==1和class==0的索引集合起来under_sample_data = np.concatenate([fraud_indices,random_normal_indices])#从下采样的索引取回对应的其他属性的值under_sample_data = data.iloc[under_sample_data,:]#把索引还原成对应的数据X_undersample = under_sample_data.iloc[:,under_sample_data.columns!='Class']#下采样中x的训练数据集y_undersample = under_sample_data.iloc[:,under_sample_data.columns=='Class']#下采样中y的标签数据集print("正常样本的占比:",len(under_sample_data[under_sample_data.Class==0])/len(under_sample_data))print("异常样本的占比:",len(under_sample_data[under_sample_data.Class==1])/len(under_sample_data))print("下采样策略的总体样本数量:",len(under_sample_data))#  数据集的划分X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=0)#random_state是设置随机种子与random seed作用相同,随机种子确定下来,他会随机做,但是固定模式#print("原始训练集包含样本数量:",len(X_train))#print("原始测试集包含样本数量:",len(X_test))#print("原始样本总数:",len(X))#  下采样数据集的划分X_train_undersample,X_test_undersample,y_train_undersample,y_test_undersample = train_test_split(X_undersample,y_undersample,test_size=0.3,random_state=0)print("下采样训练集包含样本数量:",len(X_train_undersample))print("下采样试集包含样本数量:",len(X_test_undersample))print("下采样样本总数:",len(under_sample_data))def print_Kfold_scores(X_train_data,y_train_data):    #KFold表示k折交叉验证    fold = KFold(5,shuffle=False)#将训练/测试数据集划分5个互斥子集,每次用其中一个子集当作验证集,剩下的4个作为训练集,进行5次训练和测试,得到5个结果.shuffle=False就是不重新洗牌获得的数据一样    #定义不同力度的正则化惩罚力度    c_param_range = [0.01,0.1,1,10,100]    #展示结果用的表格    results_table = pd.DataFrame(columns=['C_parameter','Mean recall score'])    results_table['C_parameter'] = c_param_range    j = 0    for c_param in c_param_range:        print('-----------------------')        print('正则化惩罚力度:',c_param)        print('-----------------------')        print('')        recall_accs = []        for iteration , indices in enumerate(fold.split(X_train_data)):            #print('X_train_data.iloc[indices[0],:]',X_train_data.iloc[indices[0],:])            #print('y_train_data.iloc[indices[0],:]',y_train_data.iloc[indices[0],:])            #print('X_train_data.iloc[indices[1],:]',X_train_data.iloc[indices[1],:])			#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标            lr = LogisticRegression(C = c_param,penalty='l2')			#训练模型,注意索引不要给错,训练的时候一定传入的是训练集,所以x和y的索引都是0            lr.fit(X_train_data.iloc[indices[0],:],y_train_data.iloc[indices[0],:].values.ravel())			#建立好模型后,预测模型结果,这里用的是验证机,索引为1            y_pred_undersample = lr.predict(X_train_data.iloc[indices[1],:].values)			#有了预测结果后进行评估,这里recall_score需要引入预测值和真实值            recall_acc = recall_score(y_train_data.iloc[indices[1],:],y_pred_undersample)			#一会还要算平均,所以每一步结果保存起来            recall_accs.append(recall_acc)            print('Iteration',iteration,':召回率:',recall_acc)        results_table.loc[j,'Mean recall score'] = np.mean(recall_accs)        j+=1        print('')        print('平均召回率',np.mean(recall_accs))        print('')    best_c =results_table.loc[results_table['Mean recall score'].astype('float32').idxmax()]['C_parameter']    print('*************************')    print('效果最好的模型所选参数=',best_c)    return best_cbest_c = print_Kfold_scores(X_train_undersample,y_train_undersample)lr = LogisticRegression(C = best_c,penalty='l2')lr.fit(X_train_undersample,y_train_undersample)#用下采样x和y的训练集训练模型y_pred_undersample = lr.predict(X_test)#用真正的x测试集进行预测recall = recall_score(y_test,y_pred_undersample)#将真正的x测试集结果与y的测试集得到召回率print('召回率:',recall)

上采样完整代码如下:

import pandas as pdimport numpy as npfrom sklearn.preprocessing import StandardScalerfrom imblearn.over_sampling import SMOTEfrom sklearn.metrics import confusion_matrixfrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import confusion_matrix,recall_scorefrom sklearn.model_selection import KFold,cross_val_score #cross_val_score交叉验证data = pd.read_csv('/Users/hxx/Downloads/creditcard.csv')dataMatrix = np.mat(data)X = dataMatrix[:,:-1]#除了最后一列其他的都为x数据集y = dataMatrix[:,-1]#最后一列为y的数据集print(len(y))#标准化scaler = StandardScaler().fit(X)dataStand = scaler.transform(X)print(dataStand[:5,:])#将数据集划分0.7和0.3x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=0)oversample = SMOTE()#实例化#我们只是对训练数据集的少样本进行生成,不需要懂测试集x_train_oversample,y_train_oversample = oversample.fit_sample(x_train,y_train)#print(len(y_train))#过采样前训练数据集的数量199364#print(len(y_train_oversample))#过采样后训练数据集的数量398038def print_Kfold_scores(X_train_data,y_train_data):    #KFold表示k折交叉验证    fold = KFold(5,shuffle=False)#将训练/测试数据集划分5个互斥子集,每次用其中一个子集当作验证集,剩下的4个作为训练集,进行5次训练和测试,得到5个结果.shuffle=False就是不重新洗牌获得的数据一样    #定义不同力度的正则化惩罚力度    c_param_range = [0.01,0.1,1,10,100]    #展示结果用的表格    results_table = pd.DataFrame(columns=['C_parameter','Mean recall score'])    results_table['C_parameter'] = c_param_range    j = 0    for c_param in c_param_range:        print('-----------------------')        print('正则化惩罚力度:',c_param)        print('-----------------------')        print('')        recall_accs = []        for iteration , (train,test) in enumerate(fold.split(X_train_data,y_train_data)):            lr = LogisticRegression(C = c_param,penalty='l2')#l2正则化            x_train,x_test,y_train,y_test=X_train_data[train],X_train_data[test],y_train_data[train],y_train_data[test]            #训练            lr.fit(x_train,y_train)            #预测            y_pred_undersample = lr.predict(x_test)            #计算召回率            recall_acc = recall_score(y_test,y_pred_undersample)            #一会还要算平均,所以每一步结果保存起来            recall_accs.append(recall_acc)            print('Iteration',iteration,':召回率:',recall_acc)        results_table.loc[j,'Mean recall score'] = np.mean(recall_accs)        j+=1        print('')        print('平均召回率',np.mean(recall_accs))        print('')    best_c =results_table.loc[results_table['Mean recall score'].astype('float32').idxmax()]['C_parameter']    print('*************************')    print('效果最好的模型所选参数=',best_c)    return best_cbest_c = print_Kfold_scores(x_train_oversample,y_train_oversample)#上采样x和y的训练集#下面是真正的测试lr = LogisticRegression(C=best_c,penalty='l2')lr.fit(x_train_oversample,y_train_oversample)#用上采样x和y的训练集训练模型y_pred_oversample = lr.predict(x_test)#用真正的x测试集进行预测recall = recall_score(y_test,y_pred_oversample)#将真正的x测试集结果与y的测试集得到召回率print('召回率1:',recall)

转载地址:http://jfulf.baihongyu.com/

你可能感兴趣的文章
教你如何优雅地魔改 Grafana 主题,太实用了!
查看>>
让我们来看看回到单体的 Istio 到底该怎么部署
查看>>
超详细的网络抓包神器 tcpdump 使用指南
查看>>
iTerm2 都不会用,还敢自称老司机?(上)
查看>>
两个奇技淫巧,将 Docker 镜像体积减小 99%
查看>>
Istio 1.5 部署指南修正版
查看>>
不要轻易使用 Alpine 镜像来构建 Docker 镜像,有坑!
查看>>
Kubectl exec 背后到底发生了什么?
查看>>
程序员涨薪宝典
查看>>
什么?终止一个容器竟然用了 10 秒钟,这不能忍!
查看>>
Openshift 4.4 静态 IP 离线安装系列(一):准备离线资源
查看>>
万字长文,说透了 Openshift4 的安装过程!
查看>>
Envoy 中文指南系列:Envoy 介绍
查看>>
[译] BeyondProd:云原生安全的一种新方法(Google, 2019)
查看>>
什么?VMware Fusion 也能 docker run 了?
查看>>
教你玩转微服务的装逼指南!
查看>>
Envoy 中文指南系列:Sidecar 模式
查看>>
面试官邪魅一笑:你猜一个 TCP 重置报文的序列号是多少?
查看>>
Envoy 中文指南系列: 安装
查看>>
最华丽的 Kubernetes 桌面客户端:Lens
查看>>