#!/usr/bin/python
#-*- coding: utf-8 -*-
优点:计算代价不高,易于理解和实现
缺点:容易欠拟合,分类精度可能不高
适用数据类型:数值型、标称型
类似阶跃函数,而阶跃函数的瞬间跳跃过程在数学上比较难处理
sigmoid函数在z=0处的取值为0.5,取值范围为0-1
因此可以将\(\sigma (z) < 0.5\)的结果归为分类0,将\(\sigma (z) > 0.5\)的结果归类为分类1
为每个特征\(x_i\)分配一个回归系数(权重)\(wi\)
只需计算\(\sigma (\sum^{n}{i=0} {w_i \cdot x_i})\),若小于0.5则分为类0,若大于0.5则分为类1
记\(z = w_0x_0 + w_1x_1 + w_2x_2 + ... = w^Tx\)
其中最重要的是找到回归系数
梯度上升法:查找局部最大值,沿梯度方向探寻,不断逼近实际的最大值
函数\(f(x,y)\)的梯度记为
$$\triangledown f(x,y) = \left( \begin{array}{ccc}
\frac{\partial f(x,y)}{\partial x} \\\
\frac{\partial f(x,y)}{\partial y}
\end{array} \right)$$
梯度上升算法的迭代公式
$$w := w + \alpha \triangledown_w f(w)$$
其中,w为回归系数向量,\(\alpha\)为步长,\(\triangledown_w\)为梯度,f(w)为待求最大值的函数
类似的,梯度下降算法的迭代公式为\(w := w + \alpha \triangledown_w f(w)\),用于毕竟最小值
通常采用迭代的方式,直到达到某个条件(如迭代次数达到某个值,或算法达到某个误差范围内)为止
已知一组100个的数据,共3个特征值,构成100x3的矩阵D;以及一组对应的二分类标签向量F(元素为0或1,长度100,假设是列向量)
import logRegres
dataArr, labelMat = logRegres.loadDataSet()
weights = logRegres.gradAscent(dataArr, labelMat)
print weights
# numpy.martix的getA方法,将矩阵转换为对应的数组返回
logRegres.plotBestFit(weights.getA())
梯度上升算法每次更新回归系数都需要遍历一次数据集,当样本、特征数量比较庞大时,计算复杂度会变得非常高;
可以采用随机梯度上升算法代替,
随机梯度上升算法每次只用一个样本点来更新回归系数,可以在新样本到来时进行增量式的更新,是一种在线学习算法
weights = logRegres.stocGradAscent0(np.array(dataArr), labelMat)
logRegres.plotBestFit(weights)
分类效果并不是很好
但我们更关注的是——随机梯度上升算法是否收敛?
运行随机梯度上升算法进行多次迭代——
总体上看,三个参数随迭代次数的增加收敛,而且参数X1和X2能较快收敛;
但曲线存在着明显的局部波动,这不是我们所期望的
weights = logRegres.stocGradAscent1(np.array(dataArr), labelMat)
logRegres.plotBestFit(weights)
分类效果比改进前好得多
已经很接近梯度上升算法,但计算量却要小的多~
改进后参数随迭代次数的变化:
可以看到,局部波动明显改善,而且收敛速度也更快