下采样及过采样·交叉验证及混淆矩阵【知识整理】

综述

学生党整理一些关于数据分析的知识:主要整理了下采样和过采样这两个采样方式。采用召回率(Recall)作为评估标准,此外还采用了交叉验证划分样本引人正则惩罚项对切分的训练数据循环验证、用混淆矩阵展示最优结果。进一步探究两种采样方式的优劣。

代码模块

调用库

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

数据样例

拿到数据后我们需要明确我们的目标是什么,要采用那些方法实现。
我们现在以一组病人数据为例,先读入数据:

data = pd.read_csv('creditcard.csv')
print(data.head())

结果如下:

   Time        V1        V2        V3  ...       V27       V28  Amount  Class
0   0.0 -1.359807 -0.072781  2.536347  ...  0.133558 -0.021053  149.62      0
1   0.0  1.191857  0.266151  0.166480  ... -0.008983  0.014724    2.69      0
2   1.0 -1.358354 -1.340163  1.773209  ... -0.055353 -0.059752  378.66      0
3   1.0 -0.966272 -0.185226  1.792993  ...  0.062723  0.061458  123.50      0
4   2.0 -1.158233  0.877737  1.548718  ...  0.219422  0.215153   69.99      0

[5 rows x 31 columns]

每个样本都有31个特征,现在我们要分析病人是不是癌症病人这个特征和其他30个特征的关系。首先病人是否患癌症是个二分类问题。
绘制条形图观察Class特征:

count_class = pd.value_counts(data['Class'],sort=True).sort_index()
count_class.plot(kind = 'bar',color = 'darkblue')
plt.xlabel('Class')
plt.ylabel('Freqquency')
plt.show()

结果如下:
在这里插入图片描述
明显看出大部分病人未患癌症,极小部分的病人才患有癌症。显然我们的样本是不平衡的,所以我们采用下采样或过采样的方法,让患癌和未患癌的样本数量平衡。

下采样

目前两个样本的数量不同,为了让样本一样少,从 0 号样本中选取和 1 号样本数量一同的样本量
首先,让每个特征的重要性相同,对数据做归一化或者标准化处理,消除数字上的差异:

from sklearn.preprocessing import StandardScaler
# 数据标准化
data['normAmount'] = StandardScaler().fit_transform(data['Amount'].values.reshape(-1,1))#-1为自动识别,在元素个数固定时一个量可以自己算
data = data.drop(['Time','Amount'],axis=1) #去除不需要的特征
print(data.head())

下采样处理:

X = data.ix[:,data.columns != 'Class']
y = data.ix[:,data.columns == 'Class']

# 让0和1 一样少
number_one = len(data[data['Class'] == 1])
fruad_indices = np.array(data[data.Class == 1].index)

number_zero = len(data[data['Class'] == 0].index)

random_normal_indices = np.random.choice(number_zero,number_one,replace=False)
random_normal_indices = np.array(random_normal_indices)

under_sample_indices = np.concatenate([fruad_indices,random_normal_indices])
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']

#显示下采样后的数据
print("Perentage of normal transactions:",len(under_sample_data[under_sample_data.Class == 0])/len(under_sample_data))
print("Perentage 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))

结果显示:

Perentage of normal transactions: 0.5
Perentage of fraud transactions: 0.5
Total number of transactions in resampled data: 984

划分训练集和测试集

数据切分:(旧版库为sklearn.cross_validation):

  • 原始数据
from sklearn.model_selection import train_test_split
#原始数据
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3,random_state= 0) #测试数据为30%
print('Number trainsactions train dataset:',len(X_train))
print('Number trainsactions test dataset:',len(X_test))
print('Number trainsactions dataset:',len(X_train)+len(X_test))

结果:

Number trainsactions train dataset: 199364
Number trainsactions test dataset: 85443
Number trainsactions dataset: 284807
  • 样本数据
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) #测试数据为30%
print('Number trainsactions train dataset:',len(X_train_undersample))
print('Number trainsactions test dataset:',len(X_test_undersample))
print('Number trainsactions dataset:',len(X_train_undersample)+len(X_test_undersample))

结果:

Number trainsactions train dataset: 688
Number trainsactions test dataset: 296
Number trainsactions dataset: 984

交叉验证

交叉验证:将train分成3份(A,B,C),这时我们训练A+B测试C,再训练A+C测试B及B+C训练验证A。这样的过程叫交叉验证,3次评估的均值表示模型效果。
再进行交叉验证之前我要先解决评估标准的问题:二分类问题中只采用精度作为评估标准是不可靠的,再对小概率事件做预测时,例如1000个病人中有10个是患癌症的。当你的模型预测出来全部为正时,你的精度得到99%,显然是不正确的。所以我们还要采用Recall召回率(查全率),即预测出癌症人数的准确度(预测人数/实际人数)作为评价标准。具体的检验方式为:

相关(Relevant),正类 无关(NonRelevant),负类
被检索到 \newline (Retrieved) true postives(TP) false positives(FP)
未被检索到 \newline (NonRetrieved) false negatives(FN) true negatives(TN)

对于本文的数据案例来看,我们支持原假设未患癌症为 positives 那么正确判断的为TP和TN,错误判断的为FP和FN。
计算公式为: R e c a

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值