目录
原理推导
先来回顾一下线性回归算法得到的结果:输入特征数据,输出一个具体的值,可以把输出值当作一 个得分值。此时如果想做一个分类任务,要判断一个输入数据是正例还是负例,就可以比较各自的得分值,如果正例的得分值高,那么就说明这个输入数据属于正例类别。
例如,在图5-9中分别计算当前输入属于猫和狗类别的得分值,通过其大小确定最终的分类结果。但是在分类任务中用数值来表示结果还是不太恰当,如果能把得分值转换成概率值,就变得容易理解。假设正例的概率值是0.02,那么负例就是1–0.02=0.98(见图5-10)。
那么如何得到这个概率值呢?先来介绍下Sigmoid函数,定义如下:
在Sigmoid函数中,自变量z可以取任意实数,其结果值域为[0,1],相当于输入一个任意大小的得分 值,得到的结果都在[0,1]之间,恰好可以把它当作分类结果的概率值。
判断最终分类结果时,可以选择以0.5为阈值来进行正负例类别划分,例如输入数据所对应最终的结果为0.7,因0.7大于0.5,就归为正例(见图5-11)。
下面梳理一下计算流程,首先得到得分值,然后通过Sigmoid函数转换成概率值,公式如下:
这个公式与线性回归方程有点相似,仅仅多了Sigmoid函数这一项。x依旧是特征数据,θ依旧是每个特征所对应的参数。下面对正例和负例情况分别进行分析。
由于是二分类任务,当正例概率为时,负例概率必为
。对于标签的选择,当y=1时为正例,y=0时为负例。为什么选择0和1呢?其实只是一个代表,为了好化简。在推导过程中,如果分别考虑正负例情况,计算起来十分麻烦,也可以将它们合并起来:
将两个式子合二为一,用一个通项来表示,目的是为了更方后续的求解推导。
逻辑回归求解
之前在推导线性回归的时候得出了目标函数,然后用梯度下降方法进行优化求解,这里貌似只多一项Sigmoid函数,求解的方式还是一样的。首先得到似然函数:
对上式两边取对数,进行化简,结果如下:
这里有一点区别,之前在最小二乘法中求的是极小值,自然用梯度下降,但是现在要求的目标却是 极大值(极大似然估计),通常在机器学习优化中需要把上升问题转换成下降问题,只需取目标函数的相反数即可:
此时,只需求目标函数的极小值,按照梯度下降的方法,照样去求偏导:
上式下标i表示样本,也就是迭代过程中,选择的样本编号;下标j表示特征编号,也是参数编号,因为参数θ和数据特征是一一对应的关系。观察可以发现,对求偏导,最后得到的结果也是乘以
,这表示要对哪个参数进行更新,需要用其对应的特征数据,而与其他特征无关。
得到上面这个偏导数后,就可以对参数进行更新,公式如下:
这样就得到了在逻辑回归中每一个参数该如何进行更新,求解方法依旧是迭代优化的思想。找到最 合适的参数θ,任务也就完成了。最后来总结一下逻辑回归的优点。
1.简单实用,在机器学习中并不是一味地选择复杂的算法,简单高效才是王道。
2.结果比较直观,参数值的意义可以理解,便于分析。
3.简单的模型,泛化能力更强,更通用。
项目实战--信用卡欺诈检测
数据分析与预处理
假设有一份信用卡交易记录,遗憾的是数据经过了脱敏处理,只知道其特征,却不知道每一个字段 代表什么含义,没关系,就当作是一个个数据特征。在数据中有两种类别,分别是正常交易数据和异常 交易数据,字段中有明确的标识符。要做的任务就是建立逻辑回归模型,以对这两类数据进行分类,看起来似乎很容易,但实际应用时会出现各种问题等待解决。
似乎很容易,但实际应用时会出现各种问题等待解决。 熟悉任务目标后,第一个想法可能是直接把数据传到算法模型中,得到输出结果就好了。其实并不是这样,在机器学习建模任务中,要做的事情还是很多的,包括数据预处理、特征提取、模型调参等, 每一步都会对最终的结果产生影响。既然如此,就要处理好每一步,其中会涉及机器学习中很多细节, 这些都是非常重要的,基本上所有实战任务都会涉及这些问题,所以大家也可以把这份解决方案当作一个套路。
数据读取与分析
先把任务所需的工具包导入进来,有了这些武器,处理数据就轻松多了:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
信用卡交易记录数据是一个.csv文件,里面包含近30万条数据,规模很大,首先使用Pandas工具包读取数据。
data=pd.read_csv("./data/creditcard.csv")
data.head()
如上图所示,原始数据为个人交易记录,该数据集总共有31列,其中数据特征有30列,Time列暂时不考虑,Amount列表示贷款的金额,Class列表示分类结果,若Class为0代表该条交易记录正常,若Class为1代表交易异常。
拿到这样一份原始数据之后,直观感觉就是数据已经是处理好的特征,只需要对其进行建模任务即 可。但是,上述输出结果只展示了前5条交易记录并且发现全部是正常交易数据,在实际生活中似乎正常交易也占绝大多数,异常交易仅占一少部分,那么,在整个数据集中,样本分布是否均衡呢?也就是说,在Class列中,正常数据和异常数据的比例是多少?绘制一份图表更能清晰说明:
count_classes=pd.value_counts(data['Class'],sort=True).sort_index()
count_classes.plot(kind='bar')
plt.xlabel('Class')
plt.ylabel('Frequency')
上述代码首先计算出Class列中各个指标的个数,也就是0和1分别有多少个。为了更直观地显示,数据绘制成条形图,从上图中可以发现,似乎只有0没有1(仔细观察,其实是1的比例太少),说明数据中绝大多数是正常数据,异常数据极少。
这个问题看起来有点严峻,数据极度不平衡会对结果造成什么影响呢?模型会不会一边倒呢?认为 所有数据都是正常的,完全不管那些异常的,因为异常数据微乎其微,这种情况出现的可能性很大。我们的任务目标就是找到异常数据,如果模型不重视异常数据,结果就没有意义了,所以,首先要做的就是改进不平衡数据。
在机器学习任务中,加载数据后,首先应当观察数据是否存在问题,先把问题处理掉,再考虑特征提取与建模任务。
样本不均衡解决方案
那么,如何解决数据标签不平衡问题呢?首先,造成数据标签不平衡的最根本的原因就是它们的个 数相差悬殊,如果能让它们的个数相差不大,或者比例接近,这个问题就解决了。基于此,提出以下两种解决方案。
(1)下采样。既然异常数据比较少,那就让正常样本和异常样本一样少。例如正常样本有30W个, 异常样本只有500个,若从正常样本中随机选出500个,它们的比例就均衡了。虽然下采样的方法看似很简单,但是也存在瑕疵,即使原始数据很丰富,下采样过后,只利用了其中一小部分,这样对结果会不会有影响呢?
(2)过采样。不想放弃任何有价值的数据,只能让异常样本和正常样本一样多,怎么做到呢?异常样本若只有500个,此时可以对数据进行变换,假造出来一些异常数据,数据生成也是现阶段常见的一种套路。虽然数据生成解决了异常样本数量的问题,但是异常数据毕竟是造出来的,会不会存在问题呢?
这两种方案各有优缺点,到底哪种方案效果更好呢?需要进行实验比较。
在开始阶段,应当多提出各种解决和对比方案,尽可能先把全局规划制定完整,如果只是想一步做一步,会做大量重复性操作,降低效率。
特征标准化
既然已经有了解决方案,是不是应当按照制订的计划准备开始建模任务呢?还差好多步,首先要对数据进行预处理,可能大家觉得机器学习的核心就是对数据建模,其实建模只是其中一部分,通常更多的时间和精力都用于数据处理中,例如数据清洗、特征提取等,这些并不是小的细节&