logo资料库

机器学习实战:基于逻辑回归模型的信用卡欺诈检测.pdf

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
机器学习实战:基于逻辑回归模型的信用卡欺诈检测 机器学习实战:基于逻辑回归模型的信用卡欺诈检测 某银行为提升信用卡反欺诈检测能力,提供了脱敏后的一份个人交易记录。考虑数据本身的隐私性,数据提供之初已经进行了 类似PCA的处理,并得到了若干数据特征。在不需要做额外特征提取工作的情况下,本项目意在通过逻辑回归模型的调优, 得到较为准确可靠的反欺诈检测方法,分析过程中使用到了Python Pandas, Numpy, Matplotlib, Seaborn以及机器学习库 Scikit-Learn等。 数据链接: 链接:https://pan.baidu.com/s/11uT0CHYPenX_67qTdr-Tjg 密码:b9xo 完整代码实现如下: 下采样完整代码: import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.model_selection import KFold,cross_val_score #cross_val_score交叉验证 from sklearn.metrics import confusion_matrix,recall_score,classification_report from sklearn.model_selection import cross_val_predict data = 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_c
best_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 pd import numpy as np from sklearn.preprocessing import StandardScaler from imblearn.over_sampling import SMOTE from sklearn.metrics import confusion_matrix from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import confusion_matrix,recall_score from 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.3 x_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))#过采样后训练数据集的数量398038 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 , (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_c best_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) 作者:要好好学习呀!
分享到:
收藏