Logistic Regression
最近在Github上学习机器学习,主要是在黄海广博士的项目下学习吴恩达的机器学习教程,做下笔记。
如有需要:链接自取(click)
预测函数 Predict Function
分类问题中的y值只有0或1,所以当使用线性回归在做分类问题时,y值就会超过或者低于1,这显然不是我们想要的。

所以预测函数需要一些约束(约束感觉有点奇妙),这里就引入了逻辑(sigmod)函数g(z),如下。
h θ ( X ) = g ( θ T X ) = 1 1 + e − θ T X h_\theta(X)=g(\theta^TX)=\frac{1}{1+e^{-\theta^TX}} hθ(X)=g(θTX)=1+e−θTX1
g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+e−z1
数学分析:
上面为该函数的图像保证了预测值在0到1之间。
h θ ( X ) > = 0.5 → θ T X > = 0 → h_\theta(X)>=0.5\to\theta^TX>=0\to hθ(X)>=0.5→θTX>=0→预测y为1。
h θ ( X ) < 0.5 → θ T X < 0 → h_\theta(X)<0.5\to\theta^TX<0\to hθ(X)<0.5→θTX<0→预测y为0。
代码分析:
def sigmod(z):
return 1/(1+np.exp(-z))
同时这也是和线性回归非常不同的一点,逻辑回归的公式和线性回归的公式十分相像,但是基本的预测函数是不同的。
判定边界 Decision Boundary
假设只有两个特征,他们的分布如下图所示:
模型为 θ T X = θ 0 + θ 1 x 1 + θ 2 x 2 \theta^TX=\theta_0+\theta_1x_1+\theta_2x_2 θTX=θ0+θ1x1+θ2x2,可知 θ T X = 0 \theta^TX=0 θTX=0是一条分界线,上面预测为1,下面预测为0。
这里需要弄清楚的就是,判定边界并不是数据的特征,而是这个预测函数,这个模型的特征,为什么这么说呢?因为如果建立模型的时候,不再是这个模型(二次,三次都可以),判定边界就会随之改变。
代价函数 Cost Function
逻辑函数的代价函数:
J ( θ ) = 1 m ∑ i = 1 m C o s t ( h θ ( x ( i ) ) − y ( i ) ) J(\theta)=\frac{1}{m}\sum_{i=1}^mCost(h_\theta(x^{(i)})-y^{(i)}) J(θ)=m1∑i=1mCost(hθ(x(i))−y(i))
C o s t ( h θ ( x ) , y ) = − y log ( h θ ( x ) ) − ( 1 − y ) log ( 1 − h θ ( x ) ) Cost(h_\theta(x),y)=-y\log(h_\theta(x))-(1-y)\log(1-h_\theta(x)) Cost(hθ(x),y)=−ylog(hθ(x))−(1−y)log(1−hθ(x))
Cost函数图
数学分析:
当y=1,然而预测值接近0时,你所需要付出的代价就非常大;
同理,可理解其他的。
代码分析:
def Cost(theta,X,y):
theta=np.matrix(theta.values)
X=np.matrix(X.values)
y=np.matrix(y.values)
first=np.multiply(-y,np.log(sigmod(theta.[email protected])))
second=np.multiply((1-y),np.log(1-sigmod(theta.[email protected])))
#这里都是矩阵计算,first和second相当于将每个训练元组的Cost算了出来,并且
#列成一列矩阵,而np.sum()就当于数学公式中的自动求和。
return np.sum(first-second)/len(X)
梯度下降 Gradient Descent
正如前面所说逻辑回归和线性回归公式大部分看上去是相同的,比如这里梯度下降的最后简化公式。
Repeat{
θ j : = θ j − α ∂ ∂ θ j J ( θ ) = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j:=\theta_j-\alpha\frac{\partial}{\partial\theta_j}J(\theta)=\theta_j-\alpha\frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} θj:=θj−α∂θj∂J(θ)=θj−αm1∑i=1m(hθ(x(i))−y(i))xj(i)
}
数据分析:
这与线性回归的理解相同,也是一步一步的去找到最优解。
代码分析:
def gradient(theta,X,y):
#这里只是在算J(θ)的梯度
theta=np.matrix(theta.values)
X=np.matrix(X.values)
y=np.matrix(y.values)
parameters=int(theta.ravel().shape[1])
grad=np.zeros(parameters)
error=sigmod(X*theta.T)-y
for i in range(parameters):
term=np.multiply(error,X[:,i])
grad[i]=np.sum(term)/len(X)
#自动求和在除以m就好了
return grad
#直接调用函数在寻找最有模型参数
import scipy.optimize as opt
res=opt.fmin_tnc(func=cost,x0=theta,fprime=gradient,args=(X,y))
Scipy优化算法 fmin_tnc
Scipy优化算法简介(click)
fmin_tnc()适用于有约束(再次提到)的多元函数问题,提供梯度信息,使用截断牛顿法。
最常使用的参数 | 介绍 |
---|---|
func | 优化的目标函数 |
x0 | 初值 |
fprime | 提供优化函数func的梯度函数,不然优化函数func必须返回函数值和梯度,或者设置approx_grad=True |
approx_grad | 如果设置为True,会给出近似梯度 |
args | 元组,是传递给优化函数的参数 |
返回值 | 介绍 |
---|---|
x | 数组,返回优化问题的目标值(模型参数) |
nfeval | 整数,目标优化函数被调用的次数 |
rc | Ruturn Code |
多类别分类 Multiclass Classification
当y可以等于1,2,3…时,就需要多类别分类,只需要将一种情况看作1,另外其他的所有情况都看作0作为一次 h θ ( 1 ) ( X ) h_\theta^{(1)}(X) hθ(1)(X)就可以了,然后还会存在更多的 h θ ( 2 ) ( X ) h_\theta^{(2)}(X) hθ(2)(X)等等。
取 m a x ( h θ ( i ) ( X ) ) max(h_\theta^{(i)}(X)) max(hθ(i)(X))的最大的i,将其分为i类。
正则化 Regularization
正则化是为了防止出现过拟合的问题,也就是说避免让判定边界都十分接近每一个点(overfitting or high varance),所以我们需要加上一个惩罚系数λ。
代价函数:
J ( θ ) = 1 2 m [ ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 + ∑ j = 1 n θ j 2 ] = 1 m ∑ i = 1 m C o s t ( h θ ( x ( i ) ) ) + 1 2 m ∑ j = 1 n θ j 2 J(\theta)=\frac{1}{2m}[\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2+\sum_{j=1}^n\theta_j^2]=\frac{1}{m}\sum_{i=1}^mCost(h_\theta(x^{(i)}))+\frac{1}{2m}\sum_{j=1}^n\theta_j^2 J(θ)=2m1[∑i=1m(hθ(x(i))−y(i))2+∑j=1nθj2]=m1∑i=1mCost(hθ(x(i)))+2m1∑j=1nθj2
梯度下降:
这里有一个约定,不惩罚系数 θ 0 \theta_0 θ0
同时惩罚系数不能过大,不然就只剩 θ 0 \theta_0 θ0了
Repeat until convergence{
θ 0 : = θ 0 − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x 0 ( i ) \theta_0:=\theta_0-\alpha\frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_0^{(i)} θ0:=θ0−αm1∑i=1m(hθ(x(i))−y(i))x0(i)
θ j : = θ j − α [ 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x 0 ( i ) + λ m θ j ] \theta_j:=\theta_j-\alpha[\frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_0^{(i)}+\frac{\lambda}{m}\theta_j] θj:=θj−α[m1∑i=1m(hθ(x(i))−y(i))x0(i)+mλθj]
}
代码分析:
def Cost(theta,X,y,learningRate):
theta=np.matrix(theta.values)
X=np.matrix(X.values)
y=np.matrix(y.values)
first=np.multiply(-y,np.log(sigmod(theta.[email protected])))
second=np.multiply((1-y),np.log(1-sigmod(theta.[email protected])))
reg=(learningRate/(2*len(X))*np.sum(np.power(theta[:,1:theta.shape[1]],2))
#注意这里的theta的范围
return np.sum(first-second)/len(X)+reg
def gradientReg(theta,X,y,learningRate):
#这里只是在算J(θ)的梯度
theta=np.matrix(theta.values)
X=np.matrix(X.values)
y=np.matrix(y.values)
parameters=int(theta.ravel().shape[1])
grad=np.zeros(parameters)
error=sigmod(X*theta.T)-y
for i in range(parameters):
term=np.multiply(error,X[:,i])
grad[i]=np.sum(term)/len(X)
if i!=0:
grad[i]+=learningRate/len(X)*theta[:,i]
return grad
#同时拥有了目标优化函数和梯度函数就可使用上述的优化方法了。
sklearn.linear_model.LogisticRegression
学习链接(click)