美文网首页
信用卡欺诈数据分析与建模

信用卡欺诈数据分析与建模

作者: weills_ch | 来源:发表于2018-05-26 18:40 被阅读0次

数据集是来自kaggle上的信用卡进行交易的数据。此数据集显示两天内发生的交易,其中284,807笔交易中有492笔被盗刷。数据集非常不平衡,被盗刷占所有交易的0.172%。其中数据特征v1,v2....v28是某些特征,银行为了保密,并没有提供具体代表的内容,Class是响应变量,如果发生被盗刷,则取值1,否则为0。Amount为消费金额。

首先来看下具体数据内容:

data = pd.read_csv("/Users/weillschang/Desktop/jupyter notebook/creditcard_fraud/creditcard.csv")
data.head()

输出内容


image

看下class值的分布情况

data['Class'].value_counts()

其中class =0的有284315 class=1也就是属于欺诈类型的有492,两者比例超过500,典型的样本分布不均衡。
对于机器学习常见的分类问题,从训练模型的角度来看,比较理想的情况下是正类和负类样本的数量相差不多,如果某类的样本数量很少,那么自然所能提供的信息就很少,用这些不平衡的数据训练出来的模型,其预测结果偏向训练数据数据比较多的哪一类,比如在正负样本比例为9:1是,当预测精度90%时,即使模型将结果全部划分为90%的那一类,其准确度也有90%,而这是没有意义的,自然我们需要对其进行处理

样本不均衡问题

对样本不均衡的处理通常有以下三种方式,这里有参考这个这篇博客数据不均衡的处理

  • 欠采样
    抛弃数据集中样本数量较多的类别,来缓解不平衡问题,,缺点是会丢失多数类样本中的一些重要信息。
  • 过采样
    对训练集里面过少的样本进行新的数据合成,来达到数据平衡的问题,这里比较经典的算法是SMOTE算法,他会从相近的几个样本中,加入随机噪声,随机扰动一个特征,来生成新的数据实例
  • 权重值的调整
    也就是说调整权重值,将少数样本权重设置为一个较大权重,多数样本设置一个较小权重。

对于信用卡欺诈这个问题,面对不平衡超过500,如果用欠采样的话,会丢弃20多万条数据,这很可能会导致丢失很多重要的信息,而权重调整这里也并不容易找到合适的权重值,这里采用过采样来合成新数据

数据预处理

在合成数据之前我们需要对数据进行常规的预处理,将可能的特征属性进行标准化处理,因为算法都假设所有数据集的所有特征集中在0附近,并且有相同的方差,如果某个特征方差远大于其他特征方差,那么该特征可能在目标函数中占得权重更大,而且差距太大的话,这会对收敛速度产生很大的影响,甚至可能不收敛,这里采用sk-learn自带的StandardScaler来进行处理

from sklearn.preprocessing import StandardScaler

data['Amount'] = StandardScaler().fit_transform(data['Amount'].reshape(-1, 1))
data.drop(['Time'],axis=1)

处理后该列数据会变成均值为0,方差为1的一列数据。

使用SMOTE 算法进行数据合成

SMOTE算法很简单,可以说是K 近邻算法的逆操作,以欧氏距离为标准计算它到少数类样本集中所有样本的距离,得到其k近邻后,在从其K 近邻中随机选择N个样本, 在从这些样本与原来的样本之间随机构建生成一个新的数据。
如下:

## 先对数据集进行分割,按30% 划分
from imblearn.over_sampling import SMOTE
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.cross_validation import KFold, cross_val_score
from sklearn.metrics import confusion_matrix,recall_score,classification_report 
X = data.loc[:, data.columns != 'Class']
Y = data.loc[:, data.columns == 'Class']
features_train, features_test, labels_train, labels_test = train_test_split(X,   Y,   test_size=0.2,  random_state=0)
  ## sample 生成
oversampler=SMOTE(random_state=0)
new_features,new_labels=oversampler.fit_sample(features_train,labels_train)

这样数据合成之后,二者便会有相同的样本数了,接下来便可以进行逻辑回归生成模型

模型的生成与调参

对于有监督学习算法,过拟合比欠拟合有时更难处理,尤其是过多的特征与过少的数据,最会容易导致过拟合问题
解决过拟合问题,通常有增加数据集,和减少模型复杂度(比如减少学习特征,让某个特征不被模型学习到),而正则化则是减少模型复杂度的一种方法
正则化中我们将保留所有的特征变量,但是会减小特征变量的数量级(参数数值的大小θ(j))。
sk_learn 逻辑回归算法,提供了c值也就是正则化系数倒数供我们选择,c值越小,对应越强的正则化,越强的正则化越能得到一个更简单的假设曲线,也就越能减少过拟合的风险(可以,这很“奥体姆剃刀”),下面使用不同的c值进行准确率的计算

from sklearn.linear_model import LogisticRegression
fold = KFold(len(os_labels),5,shuffle=False) 
c_param_range = [0.01,0.1,1,10,100]
for c_param in c_param_range:
    print('C parameter: ', c_param)
    listacc=[]
    for iteration, indices in enumerate(fold,start=1):
       
        lr = LogisticRegression(C = c_param, penalty = 'l1')
        lr.fit(new_features.iloc[indices[0],:],new_labels.iloc[indices[0],:].values.ravel())
        predicted_data=lr.predict(new_features.iloc[indices[1],:].values)
        recall_acc = recall_score(new_labels.iloc[indices[1],:].values,predicted_data)
        listacc.append(recall_acc)
        print" recall score = {}".format(recall_acc)
    print "mean_acc:{}".format(float(sum(listacc))/len(listacc))

penalty参数选择l1正则化范式,比较适合模型的特征非常多,同时希望将一些不重要的特征系数归零,从而让模型系数更加稀疏,权重值更低
这里衡量精度采用recall_score,也就是召回率,而不是准确率和正确率。

召回率=TP/(TP+FN)
也就是真正为正例的样本中,正确预测为正例的比例
这里以欺诈为正例。

也就是说假设真的欺诈数目有10个,我们正确预测到了其中9个,其召回率也就是0.9。
如上图最终输出结果为

.....
('C parameter: ', 0.01)
 recall score = 0.922580645161
 recall score = 0.901315789474
 recall score = 0.931415292686
 recall score = 0.922632197931
 recall score = 0.921346215144
mean_acc:0.919858028079
('C parameter: ', 0.1)
 recall score = 0.922580645161
 recall score = 0.907894736842
 recall score = 0.932123492309
 recall score = 0.924105032919
 recall score = 0.922500302261
mean_acc:0.921840841899
('C parameter: ', 1)
 recall score = 0.916129032258
 recall score = 0.907894736842
 recall score = 0.932167754786
 recall score = 0.924324859037
 recall score = 0.922687154461
mean_acc:0.920640707477
.......

这里选取recall平均值最大的c值,即为0.1
接下来,把预测结果的结果精度显示在一个混淆矩阵里面,看下当前预测结果,(绘制混淆矩阵代码,参考自网上)

from sklearn.cross_validation import KFold, cross_val_score
from sklearn.metrics import confusion_matrix,recall_score,classification_report 
import itertools
from sklearn.linear_model import LogisticRegression
def plot_confusion_matrix(cm, classes,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    """
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=0)
    plt.yticks(tick_marks, classes)

    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.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
image

单单看召回率还是不错,可是右上角的还有1045个的误杀(即将正常的判断为欺诈),接下来考虑设置不同的判断阈值来做更严格的划分并画出混淆矩阵,默认的是0.5 即将将结果划分为超过50%一侧的值。

lr = LogisticRegression(C = 0.1, penalty = 'l1')
lr.fit(new_features,new_labels.values.ravel())
y_pred_proba = lr.predict_proba(features_test.values)
from __future__ import division 
thresholds = [0.6,0.7,0.8,0.9]

plt.figure(figsize=(10,10))

j = 1
for i in thresholds:
    y_test_predictions_high_recall = y_pred_proba[:,1] > i
    
    plt.subplot(3,3,j)
    j += 1
    
    cnf_matrix = confusion_matrix(labels_test,y_test_predictions_high_recall)
    np.set_printoptions(precision=2)

    print "Recall:{}".format(cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))
   
    class_names = [0,1]
    plot_confusion_matrix(cnf_matrix
                          , classes=class_names
                          , title='Threshold >= %s'%i) 

结果如下


image

很明显 随着判断阈值越大(即判断的要求更严格),召回率是下降趋势的,但是误杀的概率则明显下降,综合来看0.8附近是个相对比较合理的值。

相关文章

  • 信用卡欺诈数据分析与建模

    数据集是来自kaggle上的信用卡进行交易的数据。此数据集显示两天内发生的交易,其中284,807笔交易中有492...

  • 啦啦啦

    反欺诈机器学习专家 城市:杭州、上海、北京、深圳 1、负责互联网行业各种业务场景下,数据特征分析与数据建模,挖掘欺...

  • 金融欺诈数据分析

    数据集:金融欺诈数据 目标:对数据集建模,预测金融行为是否是欺诈行为 数据可视化展示EDA 首先导入需要使用的包和...

  • 金融反欺诈项目

    构建信用卡反欺诈预测模型 本项目需解决的问题 本项目通过利用信用卡的历史交易数据,进行机器学习,构建信用卡反欺诈预...

  • 2018-11-12

    关于举办 “大数据建模与分析挖掘应用”实战培训班的通知 一、课程简介 大数据建模与分析挖掘技术已经逐步地应用到...

  • 2018-12-26

    关于举办 “大数据建模与分析挖掘应用”实战培训班的通知 一、课程简介 大数据建模与分析挖掘技术已经逐步地应用到...

  • 机器学习_学习计划

    书籍《跟着迪哥学Python数据分析与机器学习实战》 学习进度: 4-3 第六章 信用卡欺诈检测 4-4 第六章 ...

  • 2019-03-04

    关于举办 “大数据建模与分析挖掘应用”实战培训班的通知 一、课程简介 大数据建模与分析挖掘技术已经逐步地应用到新兴...

  • 苏州10月大数据建模与分析挖掘应用实战培训班

    大数据建模与分析挖掘应用实战培训班 1.培训简介 大数据建模与分析挖掘技术已经逐步地应用到新兴互联网企业(如电子商...

  • 2019-07-14

    “大数据建模与分析挖掘应用”实战研讨会的通知 一、研讨会简介 大数据建模与分析挖掘技术已经逐步地应用到新兴互联网企...

网友评论

      本文标题:信用卡欺诈数据分析与建模

      本文链接:https://www.haomeiwen.com/subject/jjppjftx.html