1. 程式人生 > >Python梯度下降法實現二元邏輯迴歸

Python梯度下降法實現二元邏輯迴歸

Python梯度下降法實現二元邏輯迴歸

二元邏輯迴歸假設函式

在這裡插入圖片描述
定義當函式值大於等於0.5時,結果為1,當函式值小於0.5時,結果為0.函式的值域是(0, 1)。

二元邏輯迴歸的損失函式

在這裡插入圖片描述
上圖為二元邏輯迴歸的概率公式,則代價函式可以表示為
在這裡插入圖片描述
損失函式求偏倒數為
在這裡插入圖片描述

可以發現和線性迴歸的結果是一樣的,只不過是假設函式h發生了變化。

正則化

為了避免過擬合,通常在代價函式後加一個正則化項,針對二元邏輯迴歸,填加正則化項,
1 2

j = 1 n θ j 2
\frac{1}{2}\sum_{j=1}^{n}\theta _{j}^{2}
這樣,隨時函式後就應該新增一項
1 m j
= 1 n θ j \frac{1}{m}\sum_{j=1}^{n}\theta _{j}

Python程式碼實現

import numpy as np
import matplotlib.pyplot as plt

# 特徵數目
n = 2
# 構造訓練集
X1 = np.arange(-2., 2., 0.02)
m = len(X1)

X2 = X1 + np.random.randn(m)
# print(X1, X2)
one = np.full(m, 1.0)
Y = 1 / (np.full(m, 1.0) + np.exp(-(0.1 * np.random.randn(m)-np.full(m, 0.6) + 5*X1 + 2 * X2)))
# Y
Y = np.array([np.int(round(i)) for i in Y])


# 梯度下降法
theta = np.random.rand(n+1)
print(theta)
X = np.vstack([np.full(m, 1), X1, X2]).T
# 前一次的theta
pre = np.zeros(n + 1)
diff = 1e-10
max_loop = 10000
alpha = 0.01
lamda = 1
now_diff = 0
while max_loop > 0:
    #sum = np.zeros(n + 1)
    sum = np.sum([(1 / (1. + np.exp(- np.dot(theta, X[i]))) - Y[i])*X[i] for i in range(m)], axis=0)
    # for i in range(m):
    #    sum += (1 / (1. + np.exp(- np.dot(theta, X[i]))) - Y[i])*X[i]
    theta = theta - (alpha * sum + alpha * lamda * theta)
    print("還差 %d 次" % max_loop, "theta = ", theta)
    now_diff = np.linalg.norm(theta - pre)
    if(now_diff <= diff):
        break
    pre = theta
    max_loop -= 1

# 列印
print("find theta : ", theta, "now_diff : ", now_diff)

# 畫出平測試例子圖
X_1 = np.array([(X1[i], X2[i]) for i in range(m) if Y[i] == 1])
X_0 = np.array([(X1[i], X2[i]) for i in range(m) if Y[i] == 0])
plt.scatter(X_1[:, 0], X_1[:, 1], c='r', marker='o')
plt.scatter(X_0[:, 0], X_0[:, 1], c='g', marker='v')


# 畫出求得的模型圖
point1 = np.arange(-2, 2, 0.02)
point2 = (theta[0] + theta[1] * point1)/(-theta[2])

plt.plot(point1, point2)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()

效果圖如下
在這裡插入圖片描述