前一篇博客介绍了线性回归,纵使可以撇开 y 是离散值得事实,给定 x, 使用线性回归对 y 进行预测,可以找到很多示例说明这种预测结果不会很好,比如说,房价不可能随着面积大小线性增长。并且当我们知道 y 的取值范围在{0,1}时,预测结果大于 1 或者小于 0 已经没有了意义。怎样解决这个问题?可以使用逻辑回归。
逻辑回归于线性回归有很多相似之处,最大的不同在于他们的因变量不同。线性回归用来预测连续变量的值,而逻辑回归是用来求分类的,可以用来解决二分类问题,也可以用于解决多分类问题,但是解决二分类问题更为常见。
g(z)=11+e−z
称为logistic 函数或者 sigmod 函数。函数图像如下所示:
g(z) 的导数 g′(z) 为:
g′(z)=ddz11+e−z=1(1+e−z)2)(e−z)=1(1+e−z)⋅(1−1(1+e−z))=g(z)(1−g(z)).
hθ(x)=g(θTx)=11+e−θTx
假设有:
P(y=1|x;θ)=hθ(x)
P(y=0|x;θ)=1−hθ(x)
更为一般的形式 :
P(y|x;θ)=(hθ(x))y((1−hθ(x)))1−y
最大似然函数为:
L(θ)=p(y⃗ |X;θ)=∏i=1mp(y(i)|x(i);θ)=∏i=1m(hθ(x(i)))y(i)(1−hθ(x(i)))1−y(i)
上式求对数得:
l(θ)=logL(θ)=∑i=1my(i)logh(x(i))+(1−y(i))log(1−h(x(i))))
对 l(θ) 求导得:
∂∂θjl(θ)=(y1g(θTx)−(1−y)11−g(θTx))∂∂θjg(θTx)=(y1g(θTx)−(1−y)11−g(θTx))g(θTx)(1−g(θTx))∂∂θjθTx=(y(1−g(θTx)−(1−y)g(θTx)xj)=(y−hθ(x))xj
所以随机梯度下降规则为 :
θj:=θj(y(i)−hθ(x(i)))(xj)(i)
实验代码如下 :
# 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