逻辑回归(Logistics Regression)是广义线性模型中的一种,其取值为0或1,服从伯努利分布。而伯努利家族的正则响应函数就是sigmoid函数,因此逻辑回归为什么选用sigmoid函数的理论原因。同时,sigmoid函数好处有:
1. 将现行分类器的响应值 <w , x> (内积) 映射到一个概率上;
2. 将实域上的数映射到P(y=1|w,x)上,满足逻辑回归的要求。
逻辑回归可以用于二分类问题,只能解决线性可分的情况,不能用于线性不可分。
对于输入向量X,其属于y=1的概率为:
$P(y=1|X,W)=h(X)=\frac{1}{1+{{e}^{-WX}}}$
其属于y=0的概率为:
$P(y=0|X,W)=1-P(y=0|X,W)=1-h(X)=\frac{{{e}^{-WX}}}{1+{{e}^{-WX}}}$
对于逻辑回归函数,其属于y的概率为:
$P(y|X,W)=h{{(X)}^{y}}\cdot {{(1-h(X))}^{1-y}}.$
逻辑回归模型需要求得参数向量W,可以使用极大似然估计求解。假设有m个样本,则似然函数为:
\[{{\text{L}}_{\text{W}}}=\prod\limits_{i=1}^{m}{\left[ h{{({{X}_{i}})}^{{{y}_{i}}}}\cdot {{(1-h({{X}_{i}}))}^{1-{{y}_{i}}}} \right]}\]
取对数可得损失函数:
${{l}_{W}}=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}\log (h({{X}_{i}}))+(1-{{y}_{i}})\log (1-h({{X}_{i}})) \right]}$
根据极大似然估计的理论,要使得参数最优,则似然函数需要最大,因此上式需要求最大值: $\underset{W}{\mathop{\max }}\,\text{ }{{l}_{W}}$
逻辑回归损失函数是一个凸函数,其凸优化求解方法有很多,如梯度下降、随机梯度下降、牛顿法等。
逻辑函数的损失函数进一步化简过程如下:
${{l}_{W}}=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}\log (h({{X}_{i}}))+(1-{{y}_{i}})\log (1-h({{X}_{i}})) \right]}$
$\text{ }=\text{ }\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}(\log (h({{X}_{i}})-\log (1-h({{X}_{i}}))))+\log (1-h({{X}_{i}})) \right]}$
$\text{ }=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}\log (\frac{h({{X}_{i}})}{1-h({{X}_{i}})})+\log (1-h({{X}_{i}})) \right]}$
$\text{ }=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}\log (\frac{1}{{{e}^{-W{X}_{i}}}})+\log (\frac{{{e}^{-W{X}_{i}}}}{1+{{e}^{-W{X}_{i}}}}) \right]}$
$\text{ }=\sum\limits_{i=1}^{m}{\left[ -{{y}_{i}}\log ({{e}^{-W{X}_{i}}})+\log (\frac{1}{1+{{e}^{W{X}_{i}}}}) \right]}$
$\text{ }=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}W{X}_{i}-\log (1+{{e}^{W{X}_{i}}}) \right]}$
其中,第四步到第五步的化简,上下同除$e^{W{X}_{i}}$。
对损失函数求导,可得到其梯度,过程如下:
$\frac{\partial {{l}_{W}}}{\partial W}=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}W{{X}_{i}}-\log (1+{{e}^{W{{X}_{i}}}}) \right]}$
$=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}{{X}_{i}}-\frac{{{e}^{W{{X}_{i}}}}\cdot {{X}_{i}}}{1+{{e}^{W{{X}_{i}}}}} \right]}$
$=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}{{X}_{i}}-{{X}_{i}}\cdot \frac{{{e}^{W{{X}_{i}}}}}{1+{{e}^{W{{X}_{i}}}}} \right]}=\sum\limits_{i=1}^{m}{\left[ {{y}_{i}}{{X}_{i}}-{{X}_{i}}\cdot \frac{1}{1+{{e}^{-W{{X}_{i}}}}} \right]}$
$\text{=}\sum\limits_{i=1}^{m}{\left[ {{X}_{i}}({{y}_{i}}-P(y|X,W)) \right]}$
由上式可以看出,逻辑回归的参数W的梯度是每个样本标签值与其计算值的偏差乘以该样本的对应值,然后对所有样本累计求和,如下图所示。
逻辑回归的Python代码如下:
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 17 13:33:28 2018
@author: zhang
"""
##针对梯度上升求最大似然估计,可先设置大一点的步长与0.02, 求取一个初步的最优解, 然后设置小一点的步长,进一步求取精度更高的参数
import numpy as np
import time
from sklearn.datasets import load_breast_cancer
from sklearn.cross_validation import train_test_split
def load_data ():
dataSet = load_breast_cancer()
return dataSet.data, dataSet.target
def sigmoid (X):
return 1.0 / (1.0 + np.exp(-X))
def LR_train (train_x, train_y, maxCycle, alpha):
numSamples, numFeatures = np.shape(train_x)
weights = np.ones((numFeatures, ))
# 需要注意 np.ones((numFeatures, )) 和 np.ones((numFeatures, 1)) 的区别,虽然其数值是一样的,但是索引不同
# 此处选择第一种是为了与数据集中的形式匹配
for i in range(maxCycle):
#梯度下降,用到所有样本, 通过所有样本找到梯度,然后调整权重, 需要多次迭代才能收敛(实验为500次)
# output =sigmoid(np.dot(train_x, weights))
# err = train_y - output
# weights = weights + alpha * np.dot(train_x.transpose(), err)
# SGD 随机梯度下降,每次用单个样本计算梯度方向,此处为因此用到所有样本计算梯度,收敛快,迭代次数少(实验为10次)。因样本少,所以
# 两者计算时间相差不大,当数据量大时,SGD理论收敛要快计算时长要少
for i in range(numSamples):
output =sigmoid(np.dot(train_x[i,:], weights))
err = train_y[i,] - output
weights = weights + alpha * np.dot(train_x[i,:].transpose(), err)
return weights
def LR_test (test_x, test_y, weights):
numSamples, numFeatures = np.shape(test_x)
count = 0
for i in range(numSamples):
if sigmoid(np.dot(test_x[i,:], weights)) > 0.5:
predict = 1
else:
predict = 0
if predict == test_y[i,]:
count = count + 1
return float(count/numSamples)
if __name__ == "__main__":
data, label = load_data()
startTime = time.time()
train_x, test_x , train_y, test_y=train_test_split(data, label,test_size=0.25, random_state=33)
weights = LR_train (train_x, train_y, 10, 0.01)
accuracy = LR_test (test_x, test_y, weights)
print("准确率:"+ str(accuracy))
print("计算时长:" +str(time.time() - startTime))
来源:oschina
链接:https://my.oschina.net/u/4395983/blog/4247784