# 机器学习——从线性回归到逻辑回归【附详细推导和代码】

2019/04/10 10:10

<br>

<br>

<br>

<br>

## 逻辑回归

<br>

$\sigma(x)= \frac{1}{1+e^{-x}}$

<br>

## 损失函数

<br>

$P(y|x)=\hat{y}^y(1-\hat{y})^{1-y}$

$\log P(y|x)=y\log \hat{y} + (1-y)\log (1-\hat{y})$

$J(\theta)=-\frac{1}{m}Y\log \hat{Y} + (1-Y)\log (1-\hat{Y})$

<br>

## 硬核推导

<br>

\begin{aligned} (\frac{1}{1+e^{-x}})'&=\frac{e^{-x}}{(1+e^{-x})^2} \ &=\frac{1+e^{-x}-1}{(1+e^{-x})^2} \ &=\frac{1}{1+e^{-x}}\cdot (1-\frac{1}{1+e^{-x}}) \ &=\sigma(x) (1-\sigma(x)) \end{aligned}

$J(\theta)=-\frac{1}{m}Y\log \sigma(\theta) + (1 - Y)\log( 1- \sigma(\theta))$

\begin{aligned} \frac{\partial}{\partial \theta}J(\theta)&=-\frac{1}{m}(Y\cdot \frac{1}{\sigma(\theta)}\cdot \sigma'(\theta)+(1-Y)\cdot \frac{1}{1-\sigma(\theta)}\cdot \sigma'(\theta)\cdot(-1)) \ &=-\frac{1}{m}(Y\cdot \frac{1}{\sigma(\theta)}\cdot \sigma(\theta)(1-\sigma(\theta))\cdot X-(1-Y)\cdot \frac{1}{1-\sigma(\theta)}\cdot \sigma(\theta)(1-\sigma(\theta))\cdot X) \ &=-\frac{1}{m}(Y(1-\sigma(\theta)) - \sigma(\theta)+Y\cdot \sigma(\theta))\cdot X\ &=-\frac{1}{m}(\sigma(\theta) - Y)\cdot X\ &=-\frac{1}{m}(\hat{Y} - Y)\cdot X \end{aligned}

<br>

## 代码实战

<br>

import numpy as np
X1 = np.random.rand(50, 1)/2 + 0.5
X2 = np.random.rand(50, 1)/2 + 0.5
y = X1 + X2
Y = y > 1.4
Y = Y + 0
x = np.c_[np.ones(len(Y)), X1, X2]
return x, Y


def sigmoid(x):
return 1.0/(1+np.exp(-x))

X = np.mat(data)
Y = np.mat(classLabels)
m, n = np.shape(dataMat)
# 学习率
alpha = 0.01
iterations = 10000
wei = np.ones((n, 1))
for i in range(iterations):
y_hat = sigmoid(X * wei)
error = Y - y_hat
wei = wei + alpha * X.transpose()*error
return wei


import matplotlib.pyplot as plt
def plotPic():
#获取梯度
n = np.shape(dataMat)[0]
xc1 = []
yc1 = []
xc2 = []
yc2 = []
#数据按照正负类别划分
for i in range(n):
if int(labelMat[i]) == 1:
xc1.append(dataMat[i][1])
yc1.append(dataMat[i][2])
else:
xc2.append(dataMat[i][1])
yc2.append(dataMat[i][2])
fig = plt.figure()
ax.scatter(xc1, yc1, s=30, c='red', marker='s')
ax.scatter(xc2, yc2, s=30, c='green')
#绘制分割线
x = np.arange(0.5, 1, 0.1)
y = (-weis[0]- weis[1]*x)/weis[2]
ax.plot(x, y)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()


<br>

### 随机梯度下降版本

<br>

def stocGradAscent(data, classLab, iter_cnt):
X = np.mat(data)
Y = np.mat(classLab)
m, n = np.shape(dataMat)
weis = np.ones((n, 1))
for j in range(iter_cnt):
for i in range(m):
# 使用反比例函数优化学习率
alpha = 4 / (1.0 + j + i) + 0.01
randIdx = int(np.random.uniform(0, m))
y_hat = sigmoid(np.sum(X[randIdx] * weis))
error = Y[randIdx] - y_hat
weis = weis + alpha * X[randIdx].transpose()*error
return weis


0
0 收藏

0 评论
0 收藏
0