-
matlab开发-Merton结构信用模型矩阵WiseSolver
2019-08-27 20:37:20matlab开发-Merton结构信用模型矩阵WiseSolver。Matrixwise计算公司资产价值、波动性、债务价值、利差、违约概率、出口回收率 -
python 模型 欺诈概率_python信用卡欺诈模型,最大似然参数设置/混淆矩阵
2020-12-20 02:59:45#定义画混淆矩阵的函数def plot_confusion_matrix(cm, classes,title='Confusionmatrix',cmap=plt.cm.Blues):"""This function prints andplots the confusion matrix."""plt.imshow(cm,interpolation='nearest', ...#定义画混淆矩阵的函数
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')
#引入数据库
import itertools
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
from sklearn.model_selection import
train_test_split
from sklearn.metrics import confusion_matrix
#引入数据库
#混淆矩阵
lr=LogisticRegression(C=0.01,penalty='l1')
lr.fit(X_train_undersample,y_train_undersample.values.ravel())
y_pred_undersample_proba=lr.predict_proba(X_test_undersample.values)
#这里改成计算结果的概率值
# 指定阈值
thresholds =
[0.1,0.2,0.3,0.4,0.5,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_undersample_proba[:,1]
> i
#取大于概率的的值
#
画出3*3的子图
plt.subplot(3,3,j)
j += 1
# Compute confusion
matrix
cnf_matrix =
confusion_matrix(y_test_undersample,y_test_predictions_high_recall)
np.set_printoptions(precision=2)
#小数点后面显示2位
print("Recall metric
in the testing dataset: ",
cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))
#计算recall值
# Plot
non-normalized confusion matrix
class_names =
[0,1]
plot_confusion_matrix(cnf_matrix, classes=class_names,
title='Threshold >= %s'%i)
#还有问题。
-
机器学习之信用卡欺诈案例(混淆矩阵、数据预处理、模型评估)
2018-12-12 23:30:49数据说明:这一份数据是信用卡的消费使用数据,其中数据涉及到一些隐私的内容,里面的相关数据特征已经经过了处理,我们拿到的数据并不是最原始的数据。我们通过逻辑回归来预测信用卡异常的数据。 观察数据 代码:...1.案例背景
-
数据说明:这一份数据是信用卡的消费使用数据,其中数据涉及到一些隐私的内容,里面的相关数据特征已经经过了处理,我们拿到的数据并不是最原始的数据。我们通过逻辑回归来预测信用卡异常的数据。
-
观察数据
代码:
import pandas as pd import numpy as np import matplotlib.pyplot as plt data = pd.read_csv('data/creditcard.csv') data.head() print(data)
time 对我们来说是没有用的,我们待会会将这一部分去掉。amount代表着交易的金额。在V1~V28 的数据比较小,而amount数据都比较大,所以要对数据进行预处理操作。
属于0 这个类是正常的,属于1 这个类是异常的。我们的目的是进行分类任务。绝大多数样本是正样本,少数样本是负样本。
2.样本不平衡的解决方案
# 观察样本的分布规则 count_classes = pd.value_counts(data['Class'],sort=True) count_classes.plot(kind='bar') plt.title("Fraud class histogram") plt.xlabel("Class") plt.ylabel("Frequency") plt.show()
从中可以观察到,正负样本不均衡。
这里有两种解决方案:1.下采样 :让0和1 两个样本一样小 2. 过采样: 对1号 样本进行生成,让 0 和 1 这两个样本一样多。
我们在这里并没有说amount特征比较重要,所以这里先进行归一化操作!
from sklearn.preprocessing import StandardScaler data['normAmount'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1, 1)) data = data.drop(['Time','Amount'],axis=1) print(data.head())
这里得到了我们可以直接使用的特征数据。
-
下采样策略
# 下采样,使得两个样本同样少 X = data.ix[:, data.columns != 'Class'] y = data.ix[:, data.columns == 'Class'] # Number of data points in the minority class number_records_fraud = len(data[data.Class == 1])# 计算异常样本的个数 fraud_indices = np.array(data[data.Class == 1].index) # 异常样本在原数据的索引值 # Picking the indices of the normal classes normal_indices = data[data.Class == 0].index # 获得原数据正常样本的索引值 # Out of the indices we picked, randomly select "x" number (number_records_fraud) random_normal_indices = np.random.choice(normal_indices, number_records_fraud, replace = False) # 通过索引进行随机的选择 random_normal_indices = np.array(random_normal_indices) # Appending the 2 indices under_sample_indices = np.concatenate([fraud_indices,random_normal_indices]) # 将class=1和class=0 的选出来的索引值进行合并 # Under sample dataset under_sample_data = data.iloc[under_sample_indices,:] X_undersample = under_sample_data.ix[:, under_sample_data.columns != 'Class'] y_undersample = under_sample_data.ix[:, under_sample_data.columns == 'Class'] # Showing ratio print("Percentage of normal transactions: ", len(under_sample_data[under_sample_data.Class == 0])/len(under_sample_data)) print("Percentage of fraud transactions: ", len(under_sample_data[under_sample_data.Class == 1])/len(under_sample_data)) print("Total number of transactions in resampled data: ", len(under_sample_data))
Percentage of normal transactions: 0.5
Percentage of fraud transactions: 0.5
Total number of transactions in resampled data: 984
-
3.交叉验证
-
目的
交叉验证法的作用就是尝试利用不同的训练集/验证集划分来对模型做多组不同的训练/验证,来应对单独测试结果过于片面以及训练数据不足的问题。(就像通过多次考试,才通知哪些学生是比较比较牛B的)
交叉验证的做法就是将数据集粗略地分为比较均等不相交的k份,然后取其中的一份进行测试,另外的k-1份进行训练,然后求得error的平均值作为最终的评价,具体算法流程如下:
-
在有监督(supervise)的机器学习中,数据集常被分成2~3个,即:训练集(train set),验证集(validation set),测试集(test set)
一个形象的比喻:
**训练集-----------**学生的课本;学生 根据课本里的内容来掌握知识。
验证集------------作业,通过作业可以知道 不同学生学习情况、进步的速度快慢。
测试集-----------考试,考的题是平常都没有见过,考察学生举一反三的能力。
传统上,一般三者切分的比例是:6:2:2,验证集并不是必须的。
为什么要测试集
a)训练集直接参与了模型调参的过程,显然不能用来反映模型真实的能力(防止课本死记硬背的学生拥有最好的成绩,即防止过拟合)
b)验证集参与了人工调参(超参数)的过程,也不能用来最终评判一个模型(刷题库的学生不能算是学习好的学生)。
c) 所以要通过最终的考试(测试集)来考察一个学(模)生(型)真正的能力**(期末考试)**
但是仅凭一次考试就对模型的好坏进行评判显然是不合理的,所以接下来就要介绍交叉验证法
from sklearn.model_selection import train_test_split # Whole dataset X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3, random_state = 0) print("Number transactions train dataset: ", len(X_train)) print("Number transactions test dataset: ", len(X_test)) print("Total number of transactions: ", len(X_train)+len(X_test)) # Undersampled dataset 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("") print("Number transactions train dataset: ", len(X_train_undersample)) print("Number transactions test dataset: ", len(X_test_undersample)) print("Total number of transactions: ", len(X_train_undersample)+len(X_test_undersample))
Number transactions train dataset: 199364
Number transactions test dataset: 85443
Total number of transactions: 284807Number transactions train dataset: 688
Number transactions test dataset: 296
Total number of transactions: 984
这里我们对整个数据集和下采样的数据集都进行切分,原因是我们对数据集的训练是通过下采样的数据集,测试的时候使用的是原始的数据集里面的测试的部分,下采样的数据测试的部分可能没有原始部分当中的一些特征。
4.模型评估方法
首先我们举个例子说一下,精度:
假设我们在医院中有1000个病人,其中990个为正样本(正常),10个为负样本(癌症),我们的目的是找出其中的10个负样本,假如我们的模型将多有的1000个病人都预测为正样本,虽然精度有99%,但是并没有找到找到我们所要的10个负样本,所以这个模型是没什么用的,因为一个癌症病人都找不出来。所以在建立模型的时候,我们应该想好怎么去评估这个模型。
召回率: 假设我们检测到2个负样本,recall = 2 /10。更能说明问题。
5.正则化惩罚项
这里同样举了一个例子:
含义就是把整个模型中的所有权重w的绝对值加起来除以样本数量,其中是一个惩罚的权重,可以称为正则化系数或者惩罚系数,表示对惩罚的重视程度。如果很重视结构风险,即不希望结构风险太大,我们就加大,迫使整个损失函数向着权值w减小的方向移动,换句话说,w的值越多、越大,整个因子的值就越大,也就是越不简洁,
以最简单的线性分类为例,假设样本特征为X=[1,1,1,1],模型1的权重W1=[1,0,0,0],模型二权重W2=[0.25,0.25,0.25,0.25],虽然W1X=W2X=1;但是权重W1只关注一个特征(像素点),其余特征点都无效,模型具体、复杂、明显,能识别“正方形棉布材质的彩色手帕”,在训练集上训练完后容易导致过拟合,因为测试数据只要在这个像素点发生些许变化,分类结果就相差很大,而模型2的权重W2关注所有特征(像素点),模型更加简洁均匀、抽象,能识别“方形”,泛化能力强。通过L2正则化惩罚之后,模型1的损失函数会增加(λ/(24))(12)=λ/8,模型2的损失函数会增加(λ/(24))(4*(1/4)2)=λ/32,显然,模型2的更加趋向让损失函数值更小。
#Recall = TP/(TP+FN) from sklearn.linear_model import LogisticRegression from sklearn.model_selection import KFold, cross_val_score from sklearn.metrics import confusion_matrix,recall_score,classification_report def printing_Kfold_scores(x_train_data, y_train_data): fold = KFold(n_splits=5,shuffle=False) # Different C parameters c_param_range = [0.01, 0.1, 1, 10, 100] results_table = pd.DataFrame(index=range(len(c_param_range), 2), columns=['C_parameter', 'Mean recall score']) results_table['C_parameter'] = c_param_range # the k-fold will give 2 lists: train_indices = indices[0], test_indices = indices[1] j = 0 for c_param in c_param_range: print('-------------------------------------------') print('C parameter: ', c_param) print('-------------------------------------------') print('') recall_accs = [] for iteration, indices in enumerate(fold.split(x_train_data)): # Call the logistic regression model with a certain C parameter lr = LogisticRegression(C=c_param, penalty='l1',solver='liblinear') # Use the training data to fit the model. In this case, we use the portion of the fold to train the model # with indices[0]. We then predict on the portion assigned as the 'test cross validation' with indices[1] lr.fit(x_train_data.iloc[indices[0], :], y_train_data.iloc[indices[0], :].values.ravel()) # Predict values using the test indices in the training data y_pred_undersample = lr.predict(x_train_data.iloc[indices[1], :].values) # Calculate the recall score and append it to a list for recall scores representing the current c_parameter recall_acc = recall_score(y_train_data.iloc[indices[1], :].values, y_pred_undersample) recall_accs.append(recall_acc) print('Iteration ', iteration, ': recall score = ', recall_acc) # The mean value of those recall scores is the metric we want to save and get hold of. results_table.ix[j, 'Mean recall score'] = np.mean(recall_accs) j += 1 print('') print('Mean recall score ', np.mean(recall_accs)) print('') best_c = results_table.loc[results_table['Mean recall score'].values.argmax()]['C_parameter'] # Finally, we can check which C parameter is the best amongst the chosen. print('*********************************************************************************') print('Best model to choose from cross validation is with C parameter = ', best_c) print('*********************************************************************************') return best_c best_c = printing_Kfold_scores(X_train_undersample,y_train_undersample)
6.混淆矩阵
import itertools 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') import itertools lr = LogisticRegression(C = best_c, penalty = 'l1',solver='liblinear') lr.fit(X_train_undersample,y_train_undersample.values.ravel()) y_pred_undersample = lr.predict(X_test_undersample.values) # Compute confusion matrix cnf_matrix = confusion_matrix(y_test_undersample,y_pred_undersample) np.set_printoptions(precision=2) print("Recall metric in the testing dataset: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1])) # Plot non-normalized confusion matrix class_names = [0,1] plt.figure() plot_confusion_matrix(cnf_matrix , classes=class_names , title='Confusion matrix') plt.show() # 在原始的数据集上进行计算 lr = LogisticRegression(C = best_c, penalty = 'l1',solver='liblinear') lr.fit(X_train_undersample,y_train_undersample.values.ravel()) y_pred = lr.predict(X_test.values) # Compute confusion matrix cnf_matrix = confusion_matrix(y_test,y_pred) np.set_printoptions(precision=2) print("Recall metric in the testing dataset: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1])) # Plot non-normalized confusion matrix class_names = [0,1] plt.figure() plot_confusion_matrix(cnf_matrix , classes=class_names , title='Confusion matrix') plt.show()
说明:对于下采样得到的数据集,虽然召回率比较低,但是误杀还是很多很多
7.逻辑回归阈值对结果的影响
# 对thresholds 的 选取 lr = LogisticRegression(C=0.01, penalty='l1',solver='liblinear') lr.fit(X_train_undersample, y_train_undersample.values.ravel()) y_pred_undersample_proba = lr.predict_proba(X_test_undersample.values) thresholds = [0.1, 0.2, 0.3, 0.4, 0.5, 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_undersample_proba[:, 1] > i plt.subplot(3, 3, j) j += 1 # Compute confusion matrix cnf_matrix = confusion_matrix(y_test_undersample, y_test_predictions_high_recall) np.set_printoptions(precision=2) print("Recall metric in the testing dataset: ", cnf_matrix[1, 1] / (cnf_matrix[1, 0] + cnf_matrix[1, 1])) # Plot non-normalized confusion matrix class_names = [0, 1] plot_confusion_matrix(cnf_matrix , classes=class_names , title='Threshold >= %s' % i) plt.show()
Recall metric in the testing dataset: 1.0
Recall metric in the testing dataset: 1.0
Recall metric in the testing dataset: 1.0
Recall metric in the testing dataset: 0.9727891156462585
Recall metric in the testing dataset: 0.9183673469387755
Recall metric in the testing dataset: 0.8639455782312925
Recall metric in the testing dataset: 0.8163265306122449
Recall metric in the testing dataset: 0.7551020408163265
Recall metric in the testing dataset: 0.5850340136054422说明:从以上的实验可以看出,对于阈值,也就是sigmoid函数得出的结果大于的分界值,应该设置为0.5或者0.6比较合适。
8.SMOTE样本生成策略
- 算法简介:
# 对数据进行过采样 import pandas as pd 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 credit_cards=pd.read_csv('data/creditcard.csv') columns=credit_cards.columns # The labels are in the last column ('Class'). Simply remove it to obtain features columns features_columns=columns.delete(len(columns)-1) features=credit_cards[features_columns] labels=credit_cards['Class'] features_train, features_test, labels_train, labels_test = train_test_split(features, labels, test_size=0.2, random_state=0) oversampler=SMOTE(random_state=0) os_features,os_labels=oversampler.fit_sample(features_train,labels_train) print('上采样后,1的样本的个数为:',len(os_labels[os_labels==1])) os_features = pd.DataFrame(os_features) os_labels = pd.DataFrame(os_labels) print('上采样的后进行交叉验证:') best_c = printing_Kfold_scores(os_features,os_labels) lr = LogisticRegression(C = best_c, penalty = 'l1',solver='liblinear') lr.fit(os_features,os_labels.values.ravel()) y_pred = lr.predict(features_test.values) # Compute confusion matrix cnf_matrix = confusion_matrix(labels_test,y_pred) np.set_printoptions(precision=2) print("Recall metric in the testing dataset: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1])) # Plot non-normalized confusion matrix class_names = [0,1] plt.figure() plot_confusion_matrix(cnf_matrix , classes=class_names , title='Confusion matrix') plt.show()
过采样明显减少了误杀的数量,所以在实验当中较经常使用的是生成数据而不是减少数据,但是数据一旦多起来,运行时间也变长了。
9.参考文档
[Somte算法和Python代码实现]:(https://blog.csdn.net/wyl2289/article/details/82620553 )
[深度学习(九)正则化惩罚项]:https://blog.csdn.net/hzqgangtiexia/article/details/80509352
[Logistic回归建模分类实例——信用卡欺诈监测(上)]:https://blog.csdn.net/tintinetmilou/article/details/72478960
[ 训练集、验证集、测试集以及交验验证的理解 - kieven2008的专栏 - CSDN博客]:https://blog.csdn.net/kieven2008/article/details/81582591 -
-
基于经济周期的信用风险转移矩阵实证研究
2020-03-11 13:02:13基于经济周期的信用风险转移矩阵实证研究,李静一,秦学志,本文研究了基于经济周期和Z模型的信用风险转移矩阵的构建方法,并选用1993-2007年上市公司的实际数据,实证构建了经济周期不同阶段� -
大数据分析实战-信用卡欺诈检测(六)-混淆矩阵
2021-02-02 15:56:07大数据分析实战-信用卡欺诈检测(一...混淆矩阵中用到的指标值前面已经解释过,既然已经训练好模型,就可以展示其结果,这里用到 Matplotlib 工具包,大家可以把下面的代码当成一个混淆矩阵模板,用的时候,只需传入自混淆矩阵
预测结果明确之后,还可以更直观地进行展示,这时候混淆矩阵就派上用场了。
混淆矩阵中用到的指标值前面已经解释过,既然已经训练好模型,就可以展示其结果,这里用到 Matplotlib 工具包,大家可以把下面的代码当成一个混淆矩阵模板,用的时候,只需传入自己的数据即可∶
def plot_confusion_matrix(cm,classes,title='Confusion matrix',cmap=plt.cm.Blues): """ 定义并绘制混淆矩阵 """ plt.imshow(cm,interpolation='nearest',cmap=cmap) plt.title(title) plt.colorbar() tick_marks=np.arange(len(classes)) plt.xticks(tick_marks,classes) 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')
定义好混淆矩阵的画法之后,需要传入实际预测结果,调用之前的逻辑回归模型,得到测试结果,再把数据的真实标签值传进去即可∶
#使用下采样数据进行训练测试 import itertools lr = LogisticRegression(C = best_c, penalty = 'l2') # 训练数据 lr.fit(X_train_undersample,y_train_undersample.values.ravel()) # 预测 y_pred_undersample = lr.predict(X_test_undersample.values) # 计算混淆矩阵 cnf_matrix=confusion_matrix(y_test_undersample,y_pred_undersample) np.set_printoptions(precision=2) # 通过混淆矩阵计算召回率 print("Recall metric in the testing dataset: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1])) # 画出非标准化的混淆矩阵 class_names = [0,1] plt.figure() plot_confusion_matrix(cnf_matrix , classes=class_names , title='Confusion matrix') plt.show()
在这份数据集中,目标任务是二分类,所以只有0和1,主对角线上的值就是预测值和真实值一致的情况,深色区域代表模型预测正确(真实值和预测值一致),其余位置代表预测错误。数值11代表11个样本数据本来是异常的,模型却将它预测成为正常,相当于"漏检"。数值7代表有7个样本数据本来是正常的,却把它当成异常的识别出来,相当于"误杀"。
最终得到的召回率值约为 0.925,看起来是一个还不错的指标,但是还有没有问题呢?
用下采样的数据集进行建模,并且测试集也是下采样的测试集,在这份测试集中,异常样本和正常样本的比例基本均衡,因为已经对数据集进行过处理。但是实际的数据集并不是这样的,相当于在测试时用理想情况来代替真实情况,这样的检测效果可能会偏高,所以,值得注意的是,在测试的时候,需要使用原始数据的测试集,才能最具代表性,只需要改变传入的测试数据即可,代码如下∶
#使用下采样数据进行训练,使用原始数据进行测试 lr = LogisticRegression(C = best_c, penalty = 'l2') lr.fit(X_train_undersample,y_train_undersample.values.ravel()) y_pred = lr.predict(X_test.values) cnf_matrix = confusion_matrix(y_test,y_pred) np.set_printoptions(precision=2) print("Recall metric in the testing dataset: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1])) class_names = [0,1] plt.figure() plot_confusion_matrix(cnf_matrix , classes=class_names , title='Confusion matrix') plt.show()
还记得在切分数据集的时候,我们做了两手准备吗?不仅对下采样数据集进行切分,而且对原始数据集也进行了切分。这时候就派上用场了,得到的召回率值为0.925,虽然有所下降,但是整体来说还是可以的。在实际的测试中,不仅需要考虑评估方法,还要注重实际应用情况,再深入混淆矩阵中,看看还有哪些实际问题。
上图中左下角的数值为 11,看起来没有问题,说明有11个漏检的。但是,右上角有一个数字格外显眼——7949,意味着有7949个样本被误杀。好像之前用下采样数据集进行测试的时候没有注意到这一点,因为只有 20个样本被误杀。但是,在实际的测试集中却出现了这样的事∶整个测试集一共只有 100多个异常样本,模型却误杀掉 7949个,有点夸张了,根据实际业务需求,后续肯定要对检测出来的异常样本做一些处理,比如冻结账号、电话询问等,如果误杀掉这么多样本,实际业务也会出现问题。
阈值对结果的影响
回想一下逻辑回归算法原理,通过Sigmoid函数将得分值转换成概率值,那么,怎么得到具体的分类结果呢? 默认情况下,模型都是以 0.5 为界限来划分类别∶
可以说 0.5 是一个经验值,但是并不是固定不变的,实践时可以根据自己的标准来指定该阈值大小。如果阈值设置得大一些,相当于要求变得严格,只有非常异常的样本,才能当作异常;如果阈值设置得比较小,相当于宁肯错杀也不肯放过,只要有一点异常就通通抓起来。
在sklearn工具包中既可以用.predict()函数得到分类结果,相当于以0.5为默认阈值,也可以用.predict proba()函数得到其概率值,而不进行类别判断,代码如下∶
#使用下采样数据训练与测试(不同的阈值对结果的影响) lr = LogisticRegression(C = 0.01, penalty = 'l2') lr.fit(X_train_undersample,y_train_undersample.values.ravel()) y_pred_undersample_proba = lr.predict_proba(X_test_undersample.values) thresholds = [0.1,0.2,0.3,0.4,0.5,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_undersample_proba[:,1] > i plt.subplot(3,3,j) j += 1 # Compute confusion matrix cnf_matrix = confusion_matrix(y_test_undersample,y_test_predictions_high_recall) np.set_printoptions(precision=2) print("Recall metric in the testing dataset: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1])) # Plot non-normalized confusion matrix class_names = [0,1] plot_confusion_matrix(cnf_matrix , classes=class_names , title='Threshold >= %s'%i) Recall metric in the testing dataset: 0.9863945578231292 Recall metric in the testing dataset: 0.9455782312925171 Recall metric in the testing dataset: 0.9319727891156463 Recall metric in the testing dataset: 0.8979591836734694 Recall metric in the testing dataset: 0.8707482993197279 Recall metric in the testing dataset: 0.8571428571428571 Recall metric in the testing dataset: 0.8503401360544217 Recall metric in the testing dataset: 0.8163265306122449 Recall metric in the testing dataset: 0.7687074829931972
代码中设置 0.1~0.9多个阈值,并且确保每一次建模都使用相同的参数,将得到的概率值与给定阈值进行比较来完成分类任务。
现在观察一下输出结果,当阈值比较小的时候,可以发现召回率指标非常高,第一个子图竟然把所有样本都当作异常的,但是误杀率也是很高的,实际意义并不大。随着阈值的增加,召回率逐渐下降,也就是漏检的逐步增多,而误杀的慢慢减少,这是正常现象。
当阈值趋于中间范围时,看起来各有优缺点,当阈值等于0.5 时,召回率偏高,但是误杀的样本个数有点多。当阈值等于0.6时,召回率有所下降,但是误杀样本数量明显减少。那么,究竟选择哪一个阈值比较合适呢?这就需要从实际业务的角度出发,看一看实际问题中,到底需要模型更符合哪一个标准。
-
混淆矩阵评价指标_机器学习系列篇2-模型的评价机制
2021-01-07 05:05:57比如你申请信用卡时候,银行会预测你将来是否逾期不还钱,或者不还钱的概率。这里我们讨论一下,一旦有了这种模型,怎么去评价一个模型的效果。机器学习模型可以广泛的应用在不同的领域,比如预测房价或者股票,预测...工作中很多时候我们需要预测一个事件发生的概率或者事件所属类别。比如你申请信用卡时候,银行会预测你将来是否逾期不还钱,或者不还钱的概率。这里我们讨论一下,一旦有了这种模型,怎么去评价一个模型的效果。
机器学习模型可以广泛的应用在不同的领域,比如预测房价或者股票,预测图片中的动物属于哪一种动物,也可以帮助机器人优化行走路线。在这里我们着重强调在机器学习领域常见的一种应用,二分类模型,比如预测客户是否会逾期。在深入理解机器学习模型的具体的建模技术手段,流程和底层算法原理之前,我们可以先了解如何通过量化的方法去评价一个模型好坏。二分类机器学习模型的输出形式有两种,一种是直接给出预测的种类,第二种是给出每一分类的概率。
- 1 基于混淆矩阵
对于给出预测种类的模型,最直接的评价方式是查看混淆矩阵(confusionmatrix), 如下图所示:
从上图的混淆矩阵中可以看到,待评价的数据样本中,真正的正样本数量P, 真正的负样本数量N, 正样本被模型预测为正样本的数量TP, 正样本被模型预测为负样本的数量FN, 负样本被模型预测为正样本的数量FP, 以及负样本被模型预测为负样本的数量TN。显然,TP 和TN的数量越高,FN和FP的数量越小,就说明模型预测越好。基于这几个数量值,我们进一步总结出得出下面的几个不同的评价指标:
- 精确率(precision) = TP/(TP+FP), 其意义在于,在所有预测为正样本的结果中,到底有多少是真正的正样本。
- 召回率(recall) = TP/(TP+FN), 其意义在于,在所有正样本中,到底有多少被正确的预测为正样本。
- 准确率(accuracy) = (TP+TN)/ (P+N), 其意义在于,所有样本中,多少预测正确,即正样本被预测为正样本,负样本被预测为负样本。
- F1 score = 2*precision*recall/(precision+ recall), 其意义在于把precision 和 recall两个指标综合起来,给出一个更全面的评价指标。类似的评分还有其他形式,但本质上都是对precision 和recall的一个加权平均,试图给出一个更加综合的评价指标。
上面的公式可能有些抽象,我们举个例子。如果是电商公司需要预测什么用户会去网站买东西,那就需要模型人员给出一个营销模型,从而决定对什么样的人推送广告。精确率,关心的就是所有被推送广告的人中,到底有多少人会真正来买东西,是我们的客户?而召回率就是,假设我们预先被告知某个城市有10万人肯定是我们客户(具体是谁我们不知道),那么我们根据模型推送了广告以后,到底这10万人中我们覆盖了多少人?
合理的利用上面几个指标来评价模型,需要结合具体的业务和数据。比如,了解数据的不平衡性对使用什么指标来评价有很大帮助。对于高度不平衡的数据,准确率通常是一个具有欺骗性的指标。假如数据里面99%的标签为正样本,那么,即使一个随机模型,准确率都能达到99%,但这样的模型显然不是我们希望得到的模型。这个时候精确率和召回率就能更加公正的评价一个模型。
但对于大多数模型而言,往往我们又不可能同时提高精确率和召回率。提高精确率的同时往往会牺牲召回率,反之亦然。如何取舍,更多要取决于当前的业务。比如重大疾病预测模型,提高召回率是第一位的,这是因为漏诊病人的重大疾病和把病人小病误诊为重大疾病相比,前者的危害要高得多。相反,对于网购业务中羊毛党客户的预测模型,如何提高精确率就更加重要。这是因为,把普通消费者误判为羊毛党会极大的损害用户体验。
- 2 ROC曲线
许多分类模型的输出结果是连续性数值,比如逻辑回归给出概率,随机森林给出多棵树的投票结果,支撑向量机算法给出离分类边界的距离等。这些连续数值有的可以直接被解释为概率,有的可以用刻度的方法转换为概率。如果设定一定的阈值,比如0.5, 那么概率大于0.5 的可以当作一个分类,小等于0.5则被预测为另一个分类。一旦选择这种基于阈值的分类办法,模型评价便可以用上节所述的混淆矩阵方法。
但是直接基于输出概率评价模型,可以得到一个更加全面客观的评价方法。问题的核心在于,设定什么样的阈值更加合理。我们可以在0和1之间选定任意的阈值,不同的阈值会导致不同的模型效果。有的阈值可以使模型得到较高的精确率,有的阈值可以使模型得到更高的召回率。因此我们可以针对许多不同的阈值,得到一系列不同的指标,从而全面的去评价一个模型。
ROC (Receiver Operating Characteristic) 曲线是一种常用的全面评价模型的方法,对每一个选定的阈值,我们计算出对应的(1)True Positive Rate (TPR) = TP/P, (2) False Positive Rate (FPR) = FP/N. 假如我们选择阈值为1(意思就是我们认为模型输出值大于1的为正样本),那么TPR 和 FPR都为0,因为概率最大也就为1,便没有样本被预测为正样本。假如我们选择阈值为0(意思就是我们认为模型输出值大于0的为正样本),那么TPR 和FPR 都为1,因为所有样本都被预测为正样本。按照这样的逻辑,每一个可能的阈值都会给出对应的TPR(Y坐标)和FPR (X坐标), 从而得到下图所示的类似的ROC曲线。
ROC曲线下的积分面积被称作AUCscore,反映了模型的一个比较全面的评价指标。AUC score的大小应该在0.5 和 1之间。原因在于,即使一个随机模型可以给出一条(0,0) 到(1,1)的对角线,面积正好为0.5。ROC曲线也给出了一个选择阈值的直观方法,使用者可以明确的知道某一个阈值对应的TPR 和 FPR, 从而根据业务选择最佳的阈值。假设某个阈值点对应的TPR为0.7, 而FPR为0.1, 那么意味者, 70%的正样本会被正确预测,但是10%的负样本也会被误判为正样本。对于金融网贷业务而言,这正是通过率和对应风险值的权衡问题。10%负样本虽然比例不大,但是如果业务底层数据的负样本远远大于正样本数,那么通过阈值的负样本绝对数量也会大于正样本数量。在这种情况下,可能更好的阈值选择是,TPR比较低,比如0.3, 但是FPR也更低,比如0.05,从而对通过阈值的负样本绝对数量进行一个控制。对于金融风控而言,负样本就是会逾期不还钱的客户。
另一个常用的评价指标是KS值,其实也和ROC曲线有直接关系。每一对TPR 和 FPR差的最大值就是KS, 在上图中,则反映为ROC曲线本身和(0,0)-(1,1)坐标对角线的之间,在y方向的最大距离即是KS值。这样我们可以看出,KS指标和AUCscore 是高度相关的。但不同的是,AUC score 是一个更加全面的评价,尤其是当ROC 曲线由于某种原因显得不大规则和平滑的时候;KS值可能只在某个特别阈值下的过度拟合结果,从而不能正真代表模型的质量。
- 3 Lift分析
Lift 分析方法在市场分析和BI领域运用广泛,也是依赖于模型输出的连续概率值。比如市场营销时候,需要建立营销模型,从而对所有目标客户的营销成功概率进行预测。在经费和人力有限的时情况下,营销人员可以把目标客户按成功概率进行排序,从而营销最有可能前N个客户。
用Lift方法来分析模型效果的具体步骤为:
- 把客户按照预测的概率排序后分组,比如10等分,第一组为概率排名在前10%的客户。
- 计算每组里面的转化率,即每组里面营销成功的客户数量除以每组的客户总数。
通过上面步骤获得数据,我们可以获得下图所示的曲线。
我们来理解一下上图的含义。左图中横坐标为,按照我们的分组方法,我们每完成一个组,即每联系10%的客户比例。纵坐标为累计的真实客户转换比例。左图中的对角线是一个基准线,意思就是,假如我们的客户分组一开始是随机的,那么我们每完成10%的客户营销和联系,我们的真实客户数量也只会增加10%。如果要覆盖一个城市的所有真正客户,除非我们把城市中每个人都联系到(我们当然知道不是每个人都是客户),否则我们永远转化不了这个城市所有的潜在真正客户。左图中的黑色曲线则代表了在模型的帮助下,我们的进展速度。第一个分组完成以后,我们可能已经能覆盖30%的真正客户,第二个分组完成后,这个数量累计增加到50%,以此类推。显然,这样的增长率要快得多,我们不需要营销所有的人即能转化到多数的真正客户。右图的数字更加好理解,是两条曲线转化率的商。
从上图我们可以很清楚的看到模型的效果。假设所有目标客户群体有1万人,而我们把所有1万人的客户营销之后,最终会转化成功1000个客户。那么如果没有模型的帮助,我们只能随机的随机营销客户,那么每联系1万人里面10%的用户,就会营销成功1000人里面的10%的最终客户。但是模型对客户进行了排序,在模型的帮助下,我们营销了1万人里面的前10%客户,已经可以获得1000个最终客户里面的30%。Lift分析方法,可以帮助营销人员在同样的人力物力下,获得更多的客户。
-
手把手教你用R语言建立信用评分模型(完结篇)— —打分卡转换
2017-07-26 17:56:22http://github.com/frankhlchi/R-scorecard (点击原文链接即可)打分卡转换我们在上一部分,我们已经基本完成了建模相关的工作,并用混淆矩阵验证了模型的预测能力。接下来的步骤,就是将Logistic模型转换为标准... -
lda 协方差矩阵_「手把手教你」使用Logistic回归、LDA和QDA模型预测指数涨跌
2020-12-30 11:08:591 引言机器学习(Machine Learning)是人工智能(AI)的重要组成部分,目前已广泛应用于数据挖掘、自然语言处理、信用卡欺诈检测、证券市场分析等领域。量化投资作为机器学习在投资领域内最典型的应用之一,已经越来越... -
数据科学 案例5 Logistic回归之构建初始信用评级和分类模型检验(代码)
2020-02-26 09:57:27数据科学 案例5 Logistic回归之构建初始信用评级和分类模型检验(代码)8 逻辑回归1、导入数据和数据清洗2、衍生变量:3、分类变量的相关关系3.1 交叉表3.2 列联表4、线性回归4.1 数据预处理(字符型转化为数值型,... -
Creditmetrics模型
2012-11-09 14:14:301.转换矩阵(Transition Matrix):它是一个信用等级的信用工具转移到另一个信用等级的概率矩阵; 2.信用工具的在险价值VaR:信用工具的价值取决于其信用等级; 3.信用计量模型的一个基本特点就是从资产组合并不是... -
决策树分类评估指标之混淆矩阵
2019-10-07 10:20:20问题的提出 如果决策树的目标是尽量捕获少数类,则准确率模型评估的意义不大,需要新的模型评估指标。简单来看,只需要查看模型...比如银行在判断”一个申请信用卡的客户是否会出现违约行为“的时候,如果一个客户被... -
中国电信计费模型:数据模型
2009-03-31 11:18:209.2 数据模型实体CRUD矩阵 346 第10章 数据中间层设计 356 10.1 总体设计 356 10.2 统计要素层设计 357 10.2.1 长途话务量分析 357 10.2.2 长途中继话务分析 359 10.2.3 本地网话务量分析 360 10.2.4 市话跳表中间表... -
分类模型评价指标-ROC AUC
2019-11-20 15:12:37垃圾邮件识别中,我们希望识别出所有信用坏的用户以及重要邮件(Negative),所以希望选精确率高的模型。 例如识别吸毒模型,肿瘤识别模型中,我们希望不漏判吸毒者以及阳性肿瘤患者(positive),所以选召回率高的... -
信用分建模
2020-12-07 13:19:25信用分模型 目前有nnn个样本,每个样本表示一个贷款客户的信息。则第iii个样本表示为xi.yi{x_i.y_i}xi.yi,其中 y∈{0,1}y\in \{0,1\}y∈{0,1} 写成矩阵的形式: X={1x1,1x1,2...x1,r1x2,1x2,2...x2,r............. -
机器学习实战之信用卡欺诈案列
2019-03-17 14:34:39信用卡逾期数据挖掘项目简介导入数据首先进行数据预处理对数据进行下采样处理:开始进行训练绘制混淆矩阵调优保存模型 项目简介 使用信用卡是普遍的当今社会。信用卡诈骗案检测是一项艰巨的任务,信用卡诈骗罪的侦查... -
python机器学习 二分类 混淆矩阵_读书笔记(11)Logistic 回归分类算法及应用
2021-01-07 16:07:40金融企业想要将用户划分为不同的信用等级;某件商品在接下来的一个月内是否被销售;根据人体内的某个肿瘤特征,判断其是否为恶性肿瘤等此类二分类问题,我们应该如何解决呢?前面我们已经介绍过无监督学习的K-means... -
二分类混淆矩阵结构_二分类任务的一种简单且可解释的性能指标
2021-01-04 14:09:45机器学习模型的核心应用是二分类任务。从用于诊断测试的医学领域到为消费者提供信用风险决策的领域,有很多领域。建立分类器的技术多种多样,从简单的决策树到逻辑回归,再到最近利用多层神经网... -
信用卡诈骗分析
2019-08-04 11:40:00项目通过描述性分析探索诈骗案的相关特点和模式,再通过机器学习算法创建预测模型、调参,并通过混淆矩阵等方法选择模型。 2.数据清理 2.1导入数据 library(data.table) # fread() # 载入数据 cards<-... -
论文研究-C5.0分类算法及在银行个人信用评级中的应用.pdf
2019-09-19 17:42:54因此在决策树C4.5算法基础上详细研究了C5.0算法及相应的Boosting技术,并嵌入Boosting算法技术, 构造了成本矩阵和Cost-sensitive tree,以此建立基于C5.0算法的银行个人信用评级模型,用来对德国某银行的个人信贷数据... -
CreditCard_Fraud_Detection:利用Logistic回归实现信用卡欺诈检测-源码
2021-02-04 01:17:08逻辑回归阈值对结果的影响(通过重复矩阵的可视化以及召回率来体现) 过采样策略(SMOTE算法) 如何运行? 信用卡数据集为“ creditcard.csv”,地址为: ://myblogs-photos-1256941622.cos.ap-chengdu.myqcloud -
机器学习笔记-逻辑回归实战案例-信用卡欺诈检测
2020-10-09 21:33:32机器学习笔记-逻辑回归实战案例-信用卡欺诈检测 基于creditcard.csv实现数据,建立逻辑回归模型,对数据进行分类 环境:python 3.7.5 and pycharm 2020.1.2 ...混淆矩阵3.分类阈值对结果的影响过采样方法1.SMOT -
机器学习-逻辑回归信用卡欺诈案例
2020-07-29 17:41:27使用 标准化 上采样 下采样 对数据预处理,使用交叉验证,正则惩罚调试训练模型,混淆矩阵分析结果 -
大数据分析实战-信用卡欺诈检测(七)-过采样方案及项目总结
2021-02-02 18:47:30大数据分析实战-信用卡欺诈检测(六)-混淆矩阵 过采样 SMOTE 数据生成策略 如何才能让异常样本与正常样本一样多呢?这里需要对少数样本进行生成,这可不是复制粘贴,一模一样的样本是没有用的,需要采用一些策略,最... -
基于逻辑回归的信用卡欺诈检测
2019-06-30 12:14:39本文是我学习唐宇迪老师的课程做的整理,仅供自己复习。 目录(一)导入需要使用的...画混淆矩阵(confusion matrix)4.过采样(SMOTE) (一)导入需要使用的包 import pandas as pd import matplotlib.pyplot as ... -
论文笔记——庞素琳,巩吉璋.C5.0分类算法在银行个人信用评级中的应用.2009
2018-08-20 15:44:41研究方法:在决策树C4.5的基础上详细研究了C5.0算法及相应的Boosting技术,并嵌入Boosting算法技术,构造了成本矩阵和Cost Sensitive tree,如此建立基于C5.0算法的商业银行个人信用评价模型,用来对德国某银行的... -
机器学习项目实战----信用卡欺诈检测(二)
2019-10-08 13:20:32可以对比真实值与预测值之间的差异,可以计算当前模型衡量的指标值。 这里精度的表示:(136+138)/(136+13+9+138)。之前有提到recall=TP/(TP+FN),在这里的表示具体如下: 下面定义绘制混淆矩阵的函数:... -
2.信用卡欺诈案例——19.10.7
2019-10-03 22:07:052.逻辑回归模型的实施(交叉验证,正则化惩罚系数c,判定阈值的设定) 3.简单的数据预处理(标准化) 4.精度,召回率以及混淆矩阵的概念 import numpy as np import pandas as pd import matplotlib.pyplot as ... -
机器学习(四):逻辑回归实战——信用卡欺诈检测
2019-07-26 18:57:55文章目录1、数据2、样本不均衡解决方案3、交叉验证4、模型评估方法5、正则化惩罚6、混淆矩阵7、逻辑回归阈值对于结果的影响8、SMOTE算法 1、数据 数据链接在此 https://pan.baidu.com/s/1APgU4cTAaM9zb8_xAIc41Q密码... -
SAS EM(五)贷款评分卡制作(数据集+实战)(小白上手简易版)
2020-10-08 02:18:42目标:建立模型预测贷款申请的信用状态,选择最优的模型来预测和减少损失 创建流程图 输入数据源 SAS内置数据集,SAMPSIO.DMAGECR 设置目标变量 设置先验概率 定制损失矩阵 建立的模型...