前一篇博客介绍了线性回归,纵使可以撇开 y 是离散值得事实,给定 x, 使用线性回归对 y 进行预测,可以找到很多示例说明这种预测结果不会很好,比如说,房价不可能随着面积大小线性增长。并且当我们知道 y 的取值范围在{0,1}时,预测结果大于 1 或者小于 0 已经没有了意义。怎样解决这个问题?可以使用逻辑回归。
逻辑回归于线性回归有很多相似之处,最大的不同在于他们的因变量不同。线性回归用来预测连续变量的值,而逻辑回归是用来求分类的,可以用来解决二分类问题,也可以用于解决多分类问题,但是解决二分类问题更为常见。
称为logistic 函数或者 sigmod 函数。函数图像如下所示:
![](http://onm4pqoqp.bkt.clouddn.com/sigmodfunction.png)
假设有:
更为一般的形式 :
最大似然函数为:
上式求对数得:
对
所以随机梯度下降规则为 :
实验代码如下 :
# encoding=utf-8
import numpy as np
def gradAscent(dataMatIn, classLabels):
dataMatrix = np.mat(dataMatIn) # 数据列表转换成矩阵
labelMat = np.mat(classLabels).transpose() # 类标签列表转换成矩阵
m, n = np.shape(dataMatrix) # 得到dataMatrix矩阵大小
alpha = 0.001 # 每次上升的步长
maxCycles = 500 # 迭代次数
weights = np.ones((n, 1))
for k in range(maxCycles):
h = sigmoid(dataMatrix * weights) # 计算假设函数h(列向量)
error = (labelMat - h) # 类标签和假设函数的误差
weights = weights + alpha * dataMatrix.transpose() * error # 对weights进行迭代更新
return weights
def sigmoid(inX):
return 1.0 / (1 + np.exp(-inX))
def loadDataSet():
dataMat = []
labelMat = []
fr = open('../resources/lr.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
if __name__ == '__main__':
data, lable = loadDataSet()
weights = gradAscent(data, lable)
print(weights)
源代码以及实验数据存储在github