概要
-
逻辑回归即使用一个超平面将整个空间一分为二,并且在边界附近赋予连续(即不是非黑即白,而是可以有0-1之间的小数概率)的概率估计的二分类方法。
-
逻辑回归使用\(θX\)作为划分数据的边界。
-
逻辑回归使用
\[
g( Z) =\frac{1}{1+e^{Z}}
\]
替代离散的分布函数,其中,g(Z)即概率统计中的分布函数,可根据极大似然估计得到使用已有样本点估计的近似值:从理论上来讲,此时的似然函数应该是最大的,可以用梯度上升法求之。 对边界的理解 — 显然,Z=θX这个“超平面”可以作为划分整个空间的依据。本来到这里就可以用分段函数完成估计了,但是(1)分布函数是离散的,(2)并且不利于计算靠近分界时的概率,所以引入了S函数使分布函数连续化且能估计在边界附近的概率值,一举两得。
对代价函数的证明与理解
-
在证明的时候,本来是要分别讨论y=1和y=0时的分布函数的,在得出代价函数的时候使用了一个技巧统一了公式
-
我们知道,在实际情况下的点为\((y_{i},X_{i})\),而\(y_i\)只能为0或1,所以有如下讨论:
\[h(X)=p(y=1|X_{i},θ)\] 显然,只有以上这个等式我们并不能用到y=0的点,所以有如下公式:
\[1-h(X)=p(y=0|X_{i},θ)\]
二者相乘后就得到了统一后的结果: \[
h(X_{i})^{y_{i}}*(1-h(X_{i})^{1-y_{i}}=p(y_{i}|X_{i},θ)
\]
我们的目的就是要使以上式子最大化(极大似然的原理:我们观测到的一组数据是n个相互独立的随机变量的观测值,将它们出现的概率乘起来即得到整个观测值出现的概率,而我们观测到的现象一定是出现概率最大的那个结果,所以带入数据后整个式子的值最大)。
接下来就是熟悉的极大似然估计的步骤了,由极大似然估计法要将其最大化,利用高数知识,函数取对数后求导,令导数为零可以解出θ值(而在计算机中则使用梯度上升等方法得到结果)
对其取对数可得逻辑回归的代价函数(与其他回归的代价函数类似,但此处因为是极大似然估计,是求其最大值) \[
L(θ)=-\frac{1}{m}[\sum_{i-1}^{m}y^{i}logh_{θ}(x^{i}+(1-y^{i})log(1-h_{θ}(x^{i}))]
\]
-
接下来就是手工求导出公式并使用梯度下降等算法了,可以愉快的逻辑回归了:) 对\(θ_{i}\)求偏导: \[
\frac{\partial}{\partial{θ_{i}} }L(θ)=(y-h(x))x_{i}
\] -
梯度上升: \[
θ_{i}=θ_{i}+α(y-h(x))x_{i}
\]
贴上手写的浮肿的代码(文件已传github):
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
import numpy as npimport matplotlib.pylab as plotclass Logistic: ''' 特征系数θ ''' theta = np.zeros((1, 1)) ''' 梯度上升循环次数 ''' cycleNum = 10000 ''' 特征向量X、标记向量y ''' X = np.zeros((1, 1)) Y = np.zeros((1, 1)) alpha = 1 def z(self, X): # z函数,决定z函数的形式 注:这里的X是向量不是矩阵 return X.dot(self.theta.transpose()) def h(self, x): return 1.0 / (1 + np.exp(-self.z(x))) def fit(self, X, Y): cx=np.ones((X.shape[0],1)) self.X = np.c_[cx,X] self.Y = Y self.theta = np.random.random((1, self.X.shape[1])) # 由于theta使用random函数导致其为二维而不是一维。 i = 0 j = 0 while j < self.cycleNum: dtheta = np.zeros((1, self.X.shape[1])) # print(self.theta) # print(self.theta[0][0] / self.theta[0][1]) while i <= self.Y.shape[0] - 1: dtheta += (self.Y[i] - self.h(self.X[i])) * self.X[i] i += 1 i = 0 # 初始化i self.theta = self.theta + self.alpha * dtheta j += 1 def predict(self, vX): output = self.h(vX) if output < 0.5: return 0 else: return 1if __name__ == '__main__': lineSplit = [] x_train = [] y_train = [] with open("testSet-LR.txt", 'r') as f: lines = f.readlines() for line in lines: lineSplit = (line.strip().split()) x_train.append([float(lineSplit[0]), float(lineSplit[1])]) y_train.append([int(lineSplit[2])]) x_train = np.array(x_train) y_train = np.array(y_train) logis = Logistic() logis.alpha = 100 logis.cycleNum = 30000 logis.fit(x_train, y_train) xop = [] yop = [] xpe = [] ype = [] i = 0 while i <= x_train.shape[0] - 1: if y_train[i] == 1: xop.append(x_train[i][0]) yop.append(x_train[i][1]) else: xpe.append(x_train[i][0]) ype.append(x_train[i][1]) i += 1 fig=plot.figure() plot.scatter(xop, yop, color="red") plot.scatter(xpe, ype, color="blue") plot.xlim((-10,20 )) plot.ylim((-10, 20)) X = np.linspace(-10, 10, 30) Y = -X * logis.theta[0][1] / logis.theta[0][2] - logis.theta[0][0] / logis.theta[0][2] plot.plot(X, Y) plot.show() fig.savefig('lr.jpg') |
参考资料:用最大似然估计求逻辑回归参数
- source:hachp1.github.io
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论