我们都知道,信用卡诈骗相对于违约来说比例极低,但是危害重大,如何通过以往的交易数据分析出眉笔交易是否正常呢?
算法:
逻辑回归,logistic 其实是分类,主要解决二分类问题,当然也可以解决多分类问题。
算法:
展示图:
函数以0.5为中心,x无穷大则y接近于1,x无穷小则y接近于0。将0视为发生,将1视为不会发生,则测试值更接近那一边,就被分到哪边,从而达到分类效果。
模型公式:
from sklearn.linear_model import LogisticRegression
LogisticRegression(penalty,solver,max_liter,n_jobs)
1、penalty:惩罚项,取值为|1或|2,默认为|2
2、solver:代表的是逻辑回归损函数的优化方法,默认为liblinear,适用于数据量小的数集,数据集较大可用sag或saga.
3、max_iter:选代次数,默认为10.
4、n_jobs:拟合和预测的时候CPU的核,默认为1.
模型评估方法:
这里先介绍下数据预测的四种情况:TP、FP、TN、FN。我们用第二个字母 P 或 N 代表预测为正例还是负例,P 为正,N 为负。第一个字母 T 或 F 代表的是预测结果是否正确,T 为正确,F 为错误。
所以四种情况分别为:
TP:预测为正,判断正确;
FP:预测为正,判断错误;
TN:预测为负,判断正确;
FN:预测为负,判断错误。
我们知道样本总数 =TP+FP+TN+FN,预测正确的样本数为 TP+TN,因此准确率 Accuracy = (TP+TN)/(TP+TN+FN+FP)。
由于数据的比例差别特别大,所以不能用普通的方法去预测准确率,这里要用到,精确率和召回率,F1值。
精确率 P = TP/ (TP+FP),对应上面诈骗分子这个例子,在所有判断为诈骗分子的人数中,真正是诈骗分子的比例。
召回率 R = TP/ (TP+FN),也称为查全率。代表的是诈骗分子被正确识别出来的个数与诈骗分子总数的比例。
综合精确率与召回率才能真正判断,模型好坏,所以这里用F1值,F1越大拟合越好。
建模与可视化步骤:
1、数据加载与探索
2、数据规范化,特征选择,准备训练集与测试集
3、模型建立,代入训练集与测试集
4、预测样本的置信分数
5、求混淆矩阵值,混淆矩阵可视化
用cm = confusion_matrix(test_y, predict_y),# 代入真实值与预测值,形成tp,tn,fp,fn四维数组,然后计算精确率,召回率和F1值;将数据代入形成混淆矩阵可视化。
6、用precision,recall,thresholds=precision_recall_curve(test_y,score_y)计算精确率、召回率,阀值用于可视化。
具体代码:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import itertools
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix,precision_recall_curve
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import warnings
warnings.filterwarnings('ignore')
#1、数据加载与探索
data=pd.read_csv("E:/数据学习网站/credit_fraud/creditcard.csv")
plt.rcParams["font.sans-serif"]=["SimHei"]
#绘制类别分布
# plt.figure()
# ax=sns.countplot(x='Class',data=data)
# plt.title("类别分布")
# plt.show()
#2、数据规范化与特征选择
data["Amount_Norm"]=StandardScaler().fit_transform(data['Amount'].values.reshape(-1,1))#将数值转化为1列数组(-1 相当于自适应行数与列数)
y=np.array(data.Class.tolist())
data=data.drop(['Time','Amount','Class'],axis=1)
x=np.array(data.as_matrix())
train_x,test_x,train_y,test_y=train_test_split(x,y,test_size=0.1,random_state=33)
#3、模型建立
model=LogisticRegression()
model.fit(train_x,train_y)
predict_y=model.predict(test_x)
#4预测样本的置信分数
score_y=model.decision_function(test_x)
#5、求混淆矩阵值,混淆矩阵可视化
def plot_confusion_matrix(cm,classes,normalize=False,title="混淆矩阵展示图",cmap=plt.cm.Blues):
plt.figure()
plt.imshow(cm,interpolation="nearest",cmap=cmap)
plt.title(title)
tick_marks=np.arange(len(classes))#图像刻度值
plt.xticks(tick_marks,classes,rotation=0)#x轴刻度数,刻度范围
plt.yticks(tick_marks,classes)#y轴刻度数,刻度范围
thresh=cm.max()/2.
for i,j in itertools.product(range(cm.shape[0]),range(cm.shape[1])):
plt.text(j,i,cm[i,j],
horizontalalignment='center',
color="white" if cm[i,j]>thresh else "black")
plt.xlabel("真实值")#标签
plt.ylabel("预测值")
plt.show()
def show_metrics():
tp=cm[1,1]
fn=cm[1,0]
fp=cm[0,1]
tn=cm[0,0]
x1 = format(tp / (tp + fp)) # 精确率
y1 = format(tp / (tp + fn))
print('精确率:',x1)
print('召回率:',y1)
print('F1值:',format(2*(((tp/(tp+fp))*(tp/(tp+fn)))/((tp/(tp+fp))+(tp/(tp+fn))))))
#执行函数
cm = confusion_matrix(test_y, predict_y) # 混淆矩阵计算,代入真实值与预测值,形成tp,tn,fp,fn四维数组
class_names=[0,1]
plot_confusion_matrix(cm, classes=class_names, title="逻辑回归 混淆矩阵")# 图像函数执行
show_metrics()
#6、绘制精确率召回线
def plot_precision_recall():
plt.step(recall, precision, color='g', alpha=0.2, where='post')#曲线分段,代入x=召回值,y=精确值
plt.fill_between(recall,precision,step='post',alpha=0.2,color='g')#绘制填充多边形,代入x=召回值,y=精确值
plt.plot(recall,precision,linewidth=2)
plt.xlim([0.0,1])#获取当前值的y限制
plt.ylim([0.0,1.05])
plt.xlabel('召回率')
plt.title('精确率')
plt.title('精确率-召回率 曲线')
plt.show()
#计算精确率、召回率,阀值用于可视化
precision,recall,thresholds=precision_recall_curve(test_y,score_y)#代入真实值与估计的概率(置信分数),得到精确率、召回率
plot_precision_recall()
结果显示:
精确率:0.841
召回率:0.617
F1值:0.712
如图混淆矩阵,tp=28414,fp=7,tn=23,fn=37
这里也可用SVM.LinerSVC()来试一试:
结果:
精确率: 0.8333333333333334
召回率: 0.6666666666666666
F1值: 0.7407407407407408
通过F1值的对比:
最终的结果是SVM.LinerSVC()模型的准确率>LogisticRegression()
????我前面介绍那么久逻辑回归干嘛!!本篇重点是比例失衡时的模型评估方法啦!
数据:
链接:https://pan.baidu.com/s/14F8WuX0ZJntdB_r1EC08HA 提取码:58gp
自己可以动手试试呀~