逻辑回归

逻辑回归是应用非常广泛的一个分类机器学习算法,它将数据拟合到一个logit函数(或者叫做logistic函数)中,从而能够完成对事件发生的概率进行预测。

构建逻辑回归模型步骤:

  • 导入数据
  • 预处理数据
  • 对不平衡的数据进行下采样(或者过采样)处理
  • 把处理之后的数据进行切分,切分为训训练集和测试集
  • 对训练集进行交叉验证,同时寻找最佳的正则化参数以减少过拟合
  • 使用最佳的正则化参数对处理之后的数据进行训练并预测,观察召回率和精确率
  • 使用最佳的正则化参数对处理之后的数据进行训练并预测,观察召回率和精确率
  • 修改阈值以获得更好的召回率和精确率

1. 数据与任务

信用卡欺诈数据

1
2
3
4
5
6
7
8
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

%matplotlib inline

data = pd.read_csv("creditcard.csv")
data.head()
图片说明 图片说明

要使用逻辑回归对数据进行建模 任务:二分类, 把数据分为有欺诈和无欺诈的两种数据

2. 使用sklearn进行数据预处理

公式为:(X-mean)/std 计算时对每个属性/每列分别进行。

Standardization标准化:将特征数据的分布调整成标准正太分布,也叫高斯分布,也就是使得数据的均值维0,方差为1

标准化的原因在于如果有些特征的方差过大,则会主导目标函数从而使参数估计器无法正确地去学习其他特征。

标准化的过程为两步:去均值的中心化(均值变为0);方差的规模化(方差变为1)。

在sklearn.preprocessing中提供了一个scale的方法,可以实现以上功能。如下面所示:

1
2
3
4
5
6
x = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
# 将每一列特征标准化为标准正太分布,注意,标准化是针对每一列而言的
x_scale = preprocessing.scale(x)
x_scale

preprocessing这个模块还提供了一个实用类StandarScaler,它可以在训练数据集上做了标准转换操作之后,把相同的转换应用到测试训练集中。
可以对训练数据,测试数据应用相同的转换,以后有新的数据进来也可以直接调用,不用再重新把数据放在一起再计算一次了。

1
2
3
4
5
6
7
8
9
# 调用fit方法,根据已有的训练数据创建一个标准化的转换器
scaler = preprocessing.StandardScaler().fit(x)

scaler

StandardScaler(copy=True, with_mean=True, with_std=True)

# 使用上面这个转换器去转换训练数据x,调用transform方法
scaler.transform(x)

StandardScaler()中可以传入两个参数:with_mean,with_std.这两个都是布尔型的参数,默认情况下都是true,但也可以自定义成false.即不要均值中心化或者不要方差规模化为1.

1. 处理数据 数据下采样

1.1 预处理数据,修改列”Amount”数据分布
1
2
3
4
5
6
7
# 导入预处理sklearn中预处理模块的标准化模块
from sklearn.preprocessing import StandardScaler

if 'Amount' in data.columns:
# 转化特征为新的特征
data['normAount'] = StandardScaler().fit_transform(data['Amount'].reshape(-1, 1)) # reshape:改变数组的形状,参数为改变后的行列数
# fit_transform:对数据进行变换 矩阵旋转:-1表示自动识别 根据另一个矩阵列(行)数确定本行(列)数

1.2 数据处理,去除不需要的特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 去掉两个没用的特征(列) axis=1表示对每一行去做这个操作,axis=0表示对每一列做相同的这个操作
if ('Time') in data.columns:
data = data.drop(['Time'], axis=1)
if ('Amount') in data.columns:
data = data.drop(['Amount'], axis=1)
print(data.columns, len(data.columns))

# 1.2.1 数据图形化展示(1的数据太少索引看上去没有)
count_classes = pd.value_counts(data['Class'], sort=True).sort_index() # 画图显示按某列分类之后的数据数量比例
count_classes.plot(kind = 'bar') # bar:条形图
plt.xlabel("Class")
plt.ylabel("Frequency")

# 1.2.2 原数据特征和分类
X = data.loc[:, data.columns != "Class"]
y = data.loc[:, data.columns == 'Class']
print ("SHAPE", X.shape, y.shape)

# Class为0的数量远远大于1的数据,需要使数据个数相近 解决方案: 1.下采样(多的数据抽取部分) 2.过采样(少的数据生成更多)
图片说明 图片说明

3.下采样

把数据相对多的减少,可减少为和数据少的数量相同的数量

1.3 区分正常数据和异常数据: 通过特征’Class’区分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1.3.1 异常数据-信息
number_records = data[data.Class == 1]
# 1.3.2 异常数据个数
number_records_fraud = len(number_records)
# 1.3.3 异常数据索引
<