1.梯度上升优化

1). 伪代码:

所有回归系数初始化为1-------------------weights = ones((colNum,1))

重复r次:

  计算整个数据集的梯度gradient

  使用alpha*gradient更新回归系数的向量

  返回回归系数weights

2). 迭代r次的代码:

  

for k in range(r):              #heavy on matrix operations
        h = sigmoid(dataMatrix*weights)     #matrix mult
        error = (labelMat - h)              #vector subtraction
        weights = weights + alpha * dataMatrix.transpose()* error #matrix mult

 

2.随机梯度上升

梯度上升算法每次更新回归系数都要遍历整个数据集(批处理),样本集数十亿时复杂度相当高。

一种改进方法是一次仅用一个样本点来更新回归系数(在线学习),该方法称为“随机梯度上升算法”。

1). 伪代码:

  所有回归系数初始化为1

  对数据集中每个样本:

    计算该样本梯度gradient

    使用alpha*gradient更新回归系数的向量

  返回回归系数weights

2). 用每个样本点更新回归系数代码:

for i in range(m):
        h = sigmoid(sum(dataMatrix[i]*weights))
        error = classLabels[i] - h
        weights = weights + alpha * error * dataMatrix[i]

 

3. 1与2比较:

1加载的是列表,用numpy.mat()转成矩阵计算,计算中是向量运算。2加载数据时就已通过numpy.array()转换列表数据为数组数据类型,计算中是数值运算。

 

4. 改进随机梯度上升

一种判断优化算法优劣的可靠方法是看它是否收敛,也就是说参数是否达到了稳定值,是否还会不断变化。

将2在整个数据集运行200次,绘制出X0,X1,X2三个回归系数的变化情况。发现1)系数2较快达到稳定值,2)大波动停止后,还有周期性小波动,原因是存在一些不能正确分类的样本点(数据及非线性可分),在每次迭代时引发系数剧烈改变。

期望改进:1)避免来回波动,从而收敛到某个值;2)加快收敛速度

改进随机梯度上升算法更新回归系数代码:

for j in range(numIter):
        dataIndex = range(m)
        for i in range(m):
            alpha = 4/(1.0+j+i)+0.0001    #apha decreases with iteration, does not 
            randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant
            h = sigmoid(sum(dataMatrix[randIndex]*weights))
            error = classLabels[randIndex] - h
            weights = weights + alpha * error * dataMatrix[randIndex]
            del(dataIndex[randIndex])

 改进之处:

1)alpha = 4/(1.0+j+i)+0.0001,alpha在每次迭代中都会作调整,缓解数据波动或高频波动。alpha每次减少1/(j+i),j是迭代次数,i表示本次迭代中第i个选出来的样本,当j<<max(i)时,alpha就不是严格下降的。类似模拟退火等其他优化算法中避免参数严格下降。另alpha永远不会减小到0,因为存在常数项,保证在多次迭代后新数据仍有影响。如要处理的问题是动态变化,可适当加大上述常数项,确保新值获得更大回归系数。

2)通过随机选取样本更新回归系数,减小周期波动。这种方法每次随机从列表中选出一个值,然后从列表删除改值(再进行下次迭代)。

效果:与梯度上升分割数据效果差不多,但迭代次数远小于后者,前者20次,后者500次。另系数周期性波动有缓解。

 

5.画图

 Andrew Ng在Cousera ML课中用Octave绘制Decision Boundary,本节中用python matplot实现相同分隔线绘制。本节中还有参数在迭代中变化情况的绘制。

 

6.数据预处理

数据集来自UCI机器学习数据库http://archive.ics.uci.edu/ml/datasets/Horse+Colic。该数据集有的指标比较主观,有的难以测量(如疼痛程度等)。另数据集有30%数据缺失。

比较用Pandas,R,和Excel处理数据集中缺失值,Excel处理如此次数据量不大、结构不复杂的数据集较为方便。

用Excel将数据集保存为文本分隔文件,缺失值全部用0替换,NumPy数据类型不允许包含缺失值。选择0来替换,恰好适用于Logistic回归。回归系数更新公式如下:

weights = weights + alpha * error * dataMatrix[randIndex]

如果dataMatrix某个特征对应值为0,那么系数将不做更新。