邏輯迴歸的概念
邏輯:邏輯,源自古典希臘語 (logos),最初的意思是“詞語”或“言語”,引申意思是“思維”或“推理”。 1902年,教育家嚴復將其意譯爲“名學”,音譯爲“邏輯”。
迴歸:迴歸是統計學的一個重要概念,其本意是根據之前的數據預測一個準確的輸出值。
邏輯迴歸是目前使用最爲廣泛的一種學習算法,用於解決分類問題。與線性迴歸算法一樣,也是監督學習算法。
分類問題爲什麼不用線性迴歸
對於分類問題分類,y 取值爲0 或者1。如果使用線性迴歸,那麼線性迴歸模型的輸出值可能遠大於1,或者遠小於0。導致代價函數很大。
邏輯函數
邏輯函數(logical function)是一種描述數字電路特點的工具。輸出量是高、低電平,可以用二元常量(0,1)來表示。
邏輯迴歸模型
hθ(x) =
關於這個模型爲了方便後面sigmoid函數的計算我們需要對其求導,求導過程如下:
代價函數
這裏用到的代價函數與我們之前用到的不同,需要用交叉熵代價函數
J(θ) =
因爲y的取值不是0就是1,所以這樣寫可以直接在一方爲0是另一個可以計算
該代價函數J(θ)是一個凸函數,並且沒有局部最優值;
因爲代價函數是凸函數,無論在哪裏初始化,最終達到這個凸函數的最小值點。
邏輯迴歸的梯度下降
在得到代價函數以後,便可以用梯度下降算法來求得能使代價函數最小的參數了。
代碼實現
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 讀取數據
data_train = np.loadtxt(r'C:\Users\shy\PycharmProjects\untitled\week4\mushroomTrain.txt',delimiter=',')
data_test = np.loadtxt(r'C:\Users\shy\PycharmProjects\untitled\week4\mushroomTest.txt',delimiter=',')
# 提取數據
train_x,train_y = data_train[:,:-1],data_train[:,-1]
test_x,test_y = data_test[:,:-1],data_test[:,-1]
# 數據預處理
def proPeross(x,y):
# 特徵縮放
x -= np.mean(x,axis=0)
x /= np.std(x,axis=0,ddof=1)
# 數據初始化
x = np.c_[np.ones(len(x)),x]
y = np.c_[y]
return x,y
train_x,train_y = proPeross(train_x,train_y)
test_x,test_y = proPeross(test_x,test_y)
# 激活函數
def g(z):
h = 1.0/(1+np.exp(-z))
return h
def model(x,theta):
z = np.dot(x,theta)
h = g(z)
return h
# 代價
def costFunc(h,y,R):
m = len(h)
J = -1.0/m*np.sum(y*np.log(h)+(1-y)*np.log(1-h)) + R
return J
# 梯度下降
def draeDesc(x, y, alpha=0.01, iter_num=100, lamba=60):
m,n = x.shape
theta = np.zeros((n,1))
J_history = np.zeros(iter_num)
for i in range(iter_num):
h = model(x,theta)
theta_r = theta.copy()
theta_r[0] = 0
R = lamba/(2 * m)*np.sum(np.square(theta_r))
J_history[i] = costFunc(h,y,R)
deltaTheta = 1.0/m * (np.dot(x.T,h-y)+lamba*theta_r)
theta -= alpha*deltaTheta
return J_history,theta
J_history,theta = draeDesc(train_x,train_y)
# 準確率
def score(h, y):
count = 0
for i in range(len(h)):
if np.where(h[i] >= 0.5,1,0) == y[i]:
count += 1
return count/len(h)
# 獲得預測值
train_h =model(train_x,theta)
test_h = model(test_x,theta)
print('訓練集準測率爲',score(train_h,train_y))
print('測試集準測率爲',score(test_h,test_y))
# 畫圖
def draw(x,y,title):
plt.title(title)
plt.scatter(x[y[:,0]==0,2],x[y[:,0]==0,3],label='負相關')
plt.scatter(x[y[:,0]==1,2],x[y[:,0]==1,3],label='正相關')
plt.legend()
plt.show()
draw(train_x,train_y,'訓練集')
效果展示