二种类别的点在平面上分布,我想找到一条直线,将平面划为两半边,每一边的点类别尽可能的统一,如何找到效果最佳的分界线,这就是最佳拟合问题,也叫作回归问题。
这次,代码很少。logRegres.py
# coding:utf-8 from numpy import * #=============================================================================== # 数据集 #=============================================================================== def loadDataSet(): dataMat = []; labelMat = [] fr = open(‘testSet.txt‘) for line in fr.readlines(): lineArr = line.strip().split() dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) labelMat.append(int(lineArr[2])) return dataMat,labelMat #=============================================================================== # 近似阶跃函数 #=============================================================================== def sigmoid(inX): return 1.0/(1+exp(-inX)) #=============================================================================== # 梯度上升求回归系数 #=============================================================================== def gradAscent(dataMatIn, classLabels): dataMatrix = mat(dataMatIn) # NumPy矩阵 labelMat = mat(classLabels).transpose() # Numpy nx1阶矩阵 m,n = shape(dataMatrix) alpha = 0.001 # 步长 maxCycles = 500 weights = ones((n,1)) for k in range(maxCycles): #反复拟合数据集 h = sigmoid(dataMatrix*weights) #预测分类的矩阵 error = (labelMat - h) #离差值矩阵 weights = weights + alpha * dataMatrix.transpose()* error #新的回归系数 return weights #=============================================================================== # 测试 #=============================================================================== if __name__ == ‘__main__‘: dataArr, labelMat = loadDataSet() #print dataArr print gradAscent(dataArr, labelMat)
需要注意的要点:
sigmoid函数,这是一个模拟0-1阶跃过程的函数,当给出的自变量x越多且密集时,函数在x=0处越接近垂直跃变,函数值按四舍五入法决定取0还是1,这就是判断类别所属的过程。
代码中的梯度上升法,使用了特征总残差来代替偏导数,而且是每上升一次遍历一次数据集,效率可想而知,所以有各种优化的方法,比如步长渐短,非顺序样本等处理,可以让回归过程尽快趋于稳定。
最后所得结果就是最佳线性回归系数,使用它绘制的直线就是该方法的最佳拟合分界,当然就实际而言,曲线的分界效果更好,但这样一来就是非线性了,回归方程也会高于一次了。
机器学习算法的代码实现之第四章节:回归之梯度上升法,布布扣,bubuko.com
原文地址:http://my.oschina.net/u/1860580/blog/290053