逻辑回归
|深度之眼华逸聪笔记|
简介
逻辑回归是一个判别模型,他利用非线性函数(sigmoid)函数将压缩到(0,1)的空间里
公式
p ( y ∣ x i , θ = s i g m o i d ( θ x ) = 1 1 + exp ( − θ T x ) ) p(y|x_i,\theta = sigmoid(\theta x)=\frac{1}{1+\exp(-\theta^Tx)}) p(y∣xi,θ=sigmoid(θx)=1+exp(−θTx)1)
X
∈
R
n
,
θ
是
参
数
X\in R_n,\theta是参数
X∈Rn,θ是参数
P
(
Y
=
1
∣
X
)
=
exp
(
w
x
+
b
)
1
+
exp
(
w
x
+
b
)
…
(
1
)
P(Y=1|X) = \frac{\exp(wx+b)}{1+\exp(wx+b)} \dots(1)
P(Y=1∣X)=1+exp(wx+b)exp(wx+b)…(1)
P ( Y = 0 ∣ X ) = 1 1 + exp ( w x + b ) … ( 2 ) P(Y=0|X)=\frac{1}{1+\exp(wx+b)}\dots(2) P(Y=0∣X)=1+exp(wx+b)1…(2)
学习过程
###公式推导
对于给定的训练数据集 T = ( x 1 , y i ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) , y i ∈ ( 0 , 1 ) T = {(x_1,y_i),(x_2,y_2),\cdots,(x_N,y_N)},yi\in (0,1) T=(x1,yi),(x2,y2),⋯,(xN,yN),yi∈(0,1)可以用极大似然估计对参数进行估计:
令 上 述 ( 1 ) 式 为 π ( x ) , ( 2 ) 为 1 − π ( x ) 令上述(1)式为\pi(x),(2)为1-\pi(x) 令上述(1)式为π(x),(2)为1−π(x)
∏ i = 1 N ( π ( x i ) i y [ 1 − π ( x i ) ] 1 − y i \prod_{i=1}^{N}(\pi(x_i)^y_i[1-\pi(xi)]^{1-y_i} i=1∏N(π(xi)iy[1−π(xi)]1−yi
L ( w ) = l o g ( ∏ i = 1 N ( π ( x i ) i y [ 1 − π ( x i ) ] 1 − y i ) = ∑ i = 1 N ( y i l o g π ( x i ) ) + ( 1 − y i ) l o g ( 1 − π ( x i ) ) = ∑ i = 1 N ( y i l o g π ( x i ) 1 − π ( x i ) + l o g ( 1 − π ( x i ) ) ) = ∑ i = 1 N [ y i ( w i x i ) ] − l o g ( 1 + exp ( w x ) ) \begin{aligned}L(w)&=log(\prod_{i=1}^{N}(\pi(x_i)^y_i[1-\pi(xi)]^{1-y_i})\\ &= \sum_{i=1}^{N}(y_ilog\pi(x_i))+(1-y_i)log(1-\pi(x_i))\\&= \sum_{i=1}^{N}(y_ilog\frac{\pi(x_i)}{1-\pi(x_i)}+log(1-\pi(x_i)))\\&=\sum_{i=1}^{N}[yi(w_ix_i)]-log(1+\exp(wx)) \end{aligned} L(w)=log(i=1∏N(π(xi)iy[1−π(xi)]1−yi)=i=1∑N(yilogπ(xi))+(1−yi)log(1−π(xi))=i=1∑N(yilog1−π(xi)π(xi)+log(1−π(xi)))=i=1∑N[yi(wixi)]−log(1+exp(wx))
从而得出L(w)对w的偏导数为 ∑ i = 1 N ( y i x i − x i 1 1 + exp ( w i x i ) ) \sum_{i=1}{N}(yixi-x_i\frac{1}{1+\exp(w_ix_i)}) ∑i=1N(yixi−xi1+exp(wixi)1)
之后可以通过最优化算法拟合最佳的分类边界。
优化问题
w i = w i − 1 + α ▽ f ( w ) w_i = w_{i-1}+\alpha\bigtriangledown f(w) wi=wi−1+α▽f(w)
其中,w是参数, α \alpha α为学习率, ▽ f ( w ) \bigtriangledown f(w) ▽f(w)为梯度
1.初始化回归系数
重复下面步骤直至收敛
2.计算整个数据集的梯度
3.使用学习率乘以梯度来更新参数w
4.返回参数
自编程实现
import numpy as np
import time
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
class LogisticRegression:
def __init__(self,learn_rate=0.1,max_iter=10000,tol=1e-2):
self.__w = None
self.__learn_rate = learn_rate
self.__max_iter = max_iter
self.__tol = tol
def processor(self,X):
'''
加入截距项
:param X:需要加工的变量
:return: 加工完的变量
'''
row = X.shape[0]
y = np.ones(row).reshape(row,1)
X_proced = np.hstack((X,y))
return X_proced
def sigmoid(self,x):
return 1/(1+np.exp(-x))
def fit(self,X_train,y_train):
'''
用梯度下降拟合函数
:param X_train:训练集的特征
:param y_train: 训练集的输出
:return:
'''
X = self.processor(X_train)
y = y_train.T
self.__w = np.zeros((1,X.shape[1]),dtype='float64')#初始化参数
k = 0
for loop in range(self.__max_iter):
z = -np.dot(X,self.__w.T)
grad=y-self.sigmoid(z)
grad = X * grad
grad = np.sum(grad,axis=0)#计算梯度
if (np.abs(grad) <= self.__tol).all():#停止条件
break
self.__w += self.__learn_rate * grad#更新权重
k += 1
print("迭代次数:{}次".format(k))
print("最终梯度:{}".format(grad))
print("最终权重:{}".format(self.__w[0]))
def predict(self,X):
'''
预测函数
:param X:特征
:return:输出
'''
X = self.processor(X)
y = self.sigmoid(np.dot(X,self.__w.T))
y[np.where(y>0.5)] = 1
y[np.where(y < 0.5)] = 0
return y
def score(self,X_test,y_test):
'''
计算评分
:param X_test:
:param y_test:
:return: 正确率
'''
y_c = self.predict(X_train)
error = np.sum(np.abs((y_test.T-y_c)))/y_c.shape[0]
return 1-error