教程丨機器學習演算法:從頭開始構建邏輯回歸模型

教程丨機器學習演算法:從頭開始構建邏輯回歸模型

來自專欄量子位28 人贊了文章

原作:Rohith Gandhi

郭一璞 編譯自 Hacher Noon

量子位 出品 | 公眾號 QbitAI

邏輯回歸是繼線性回歸之後最著名的機器學習演算法。

在很多方面,線性回歸和邏輯回歸是相似的,不過最大的區別在於它們的用途,線性回歸演算法用於預測,但邏輯回歸用於分類任務。

分類任務很常見,比如把電子郵件分為垃圾郵件和非垃圾郵件、把腫瘤分為惡性或者良性、把網站分為危險站點或正常站點,機器學習演算法就可以完成這些任務。

其中,邏輯回歸演算法就是一種分類演算法,簡單粗暴,但有用。

現在,開始深入研究邏輯回歸。

Sigmoid函數(Logistic函數)

邏輯回歸演算法使用具有獨立預測因子的線性方程來預測,預測值可以是從負無窮到正無窮之間的任何值。

我們需要讓演算法的輸出為類變數,比如用0表示非,用1表示是。

因此,我們將線性方程的輸出壓縮到[0,1]的範圍內。

為了壓縮0和1之間的預測值,我們使用sigmoid函數:

△ 線性方程和sigmoid函數

△ 壓縮輸出-h

我們取線性方程的輸出(z)並給出返回壓縮值h的函數g(x),h將位於0到1的範圍內。為了理解sigmoid函數如何壓縮,我們畫出了sigmoid函數的圖形:

△ sigmoid函數圖形

如圖可見,sigmoid函數當x>0時,y逐漸向1靠近;當x<0時,y逐漸向0靠近。

成本函數(cost function)

由於我們試圖預測類別值,不能使用和線性回歸演算法中相同的成本函數。

所以,我們使用損失函數的對數來計算錯誤分類的成本。

考慮到計算上面這個函數的梯度實在太難了,,我們把它寫成下面這個樣子:

計算梯度

我們取相對於每個參數(θ_0,θ_1,…)的成本函數的偏導數來獲得梯度,有了這些梯度,我們可以更新θ_0,θ_1,…的值。

現在,開始召喚微積分大法:

△ 梯度

如果看懂了,那你的微積分學得棒棒的。

不過,如果微積分大法召喚失敗……就直接照著上面的式子做吧。

寫代碼

現在方程終於搞定了,開始寫代碼。

我們用NumPy來從頭構建模型,用IRIS(鳶尾花)數據集來訓練和測試演算法。

1import pandas as pd 2 3df = pd.read_csv(/Users/rohith/Documents/Datasets/Iris_dataset/iris.csv) ## Load data 4df = df.drop([Id],axis=1) 5rows = list(range(100,150)) 6df = df.drop(df.index[rows]) ## Drop the rows with target values Iris-virginica 7Y = [] 8target = df[Species] 9for val in target:10 if(val == Iris-setosa):11 Y.append(0)12 else:13 Y.append(1)14df = df.drop([Species],axis=1)15X = df.values.tolist()

我們用pandas來載入數據。

IRIS數據集有三個目標值,分別是弗吉尼亞鳶尾、山鳶尾、變色鳶尾。但是因為要實現的是二進位的分類演算法,所以此處先把弗吉尼亞鳶尾剔除。

△ 變色鳶尾(左)和山鳶尾(右),圖源百度百科

現在,只剩下兩個目標值用來分類了。

之後,從數據集中提取獨立變數和因變數,現在可以繼續準備訓練集和測試集了。

1from sklearn.utils import shuffle 2from sklearn.cross_validation import train_test_split 3import numpy as np 4 5X, Y = shuffle(X,Y) 6 7x_train = [] 8y_train = [] 9x_test = []10y_test = []1112x_train, x_test, y_train, y_test = train_test_split(X, Y, train_size=0.9)1314x_train = np.array(x_train)15y_train = np.array(y_train)16x_test = np.array(x_test)17y_test = np.array(y_test)1819x_1 = x_train[:,0]20x_2 = x_train[:,1]21x_3 = x_train[:,2]22x_4 = x_train[:,3]2324x_1 = np.array(x_1)25x_2 = np.array(x_2)26x_3 = np.array(x_3)27x_4 = np.array(x_4)2829x_1 = x_1.reshape(90,1)30x_2 = x_2.reshape(90,1)31x_3 = x_3.reshape(90,1)32x_4 = x_4.reshape(90,1)3334y_train = y_train.reshape(90,1)

我們清洗了數據,並且把它們分為了訓練集和測試集,訓練集中有90個數據,測試集中有10個數據。由於數據集中有四個預測因子,所以我們提取每個特徵並將其存儲在各個向量中。

1## Logistic Regression 2import numpy as np 3 4def sigmoid(x): 5 return (1 / (1 + np.exp(-x))) 6 7m = 90 8alpha = 0.0001 910theta_0 = np.zeros((m,1))11theta_1 = np.zeros((m,1))12theta_2 = np.zeros((m,1))13theta_3 = np.zeros((m,1))14theta_4 = np.zeros((m,1))151617epochs = 018cost_func = []19while(epochs < 10000):20 y = theta_0 + theta_1 * x_1 + theta_2 * x_2 + theta_3 * x_3 + theta_4 * x_421 y = sigmoid(y)2223 cost = (- np.dot(np.transpose(y_train),np.log(y)) - np.dot(np.transpose(1-y_train),np.log(1-y)))/m2425 theta_0_grad = np.dot(np.ones((1,m)),y-y_train)/m26 theta_1_grad = np.dot(np.transpose(x_1),y-y_train)/m27 theta_2_grad = np.dot(np.transpose(x_2),y-y_train)/m28 theta_3_grad = np.dot(np.transpose(x_3),y-y_train)/m29 theta_4_grad = np.dot(np.transpose(x_4),y-y_train)/m3031 theta_0 = theta_0 - alpha * theta_0_grad32 theta_1 = theta_1 - alpha * theta_1_grad33 theta_2 = theta_2 - alpha * theta_2_grad34 theta_3 = theta_3 - alpha * theta_3_grad35 theta_4 = theta_4 - alpha * theta_4_grad3637 cost_func.append(cost)38 epochs += 1

我們用0來初始化參數(θ_0,θ_1,…)。當我們使用線性方程來計算這些值時,這些值將被壓縮到0到1的範圍內。

然後計算成本。

可以用成本函數計算每個參數的梯度,並通過將梯度與α相乘來更新它們的值,α是演算法的學習率。一萬次之後,我們的演算法會收斂到最小值。

現在,終於可以找出那10個測試集的數據,開始測試了。

1from sklearn.metrics import accuracy_score 2 3test_x_1 = x_test[:,0] 4test_x_2 = x_test[:,1] 5test_x_3 = x_test[:,2] 6test_x_4 = x_test[:,3] 7 8test_x_1 = np.array(test_x_1) 9test_x_2 = np.array(test_x_2)10test_x_3 = np.array(test_x_3)11test_x_4 = np.array(test_x_4)1213test_x_1 = test_x_1.reshape(10,1)14test_x_2 = test_x_2.reshape(10,1)15test_x_3 = test_x_3.reshape(10,1)16test_x_4 = test_x_4.reshape(10,1)1718index = list(range(10,90))1920theta_0 = np.delete(theta_0, index)21theta_1 = np.delete(theta_1, index)22theta_2 = np.delete(theta_2, index)23theta_3 = np.delete(theta_3, index)24theta_4 = np.delete(theta_4, index)2526theta_0 = theta_0.reshape(10,1)27theta_1 = theta_1.reshape(10,1)28theta_2 = theta_2.reshape(10,1)29theta_3 = theta_3.reshape(10,1)30theta_4 = theta_4.reshape(10,1)3132y_pred = theta_0 + theta_1 * test_x_1 + theta_2 * test_x_2 + theta_3 * test_x_3 + theta_4 * test_x_433y_pred = sigmoid(y_pred)3435new_y_pred =[]36for val in y_pred:37 if(val >= 0.5):38 new_y_pred.append(1)39 else:40 new_y_pred.append(0)4142print(accuracy_score(y_test,new_y_pred))

提前準備好的測試集和訓練集的特徵十分相似,但是因為測試示例的數量只有10個,所以我們把θ_0,θ_1,θ_2,θ_3和θ_4的值從90×1剪切到10×1,計算了測試類別並檢查模型的精確度。

△ 哎呦不錯

完美!模型準確度100%!

雖然邏輯回歸演算法非常強大,但我們使用的數據集並不是很複雜,所以我們的模型能夠達到100%的準確度。

我們還可以畫出一萬次訓練的成本函數圖:

1import matplotlib.pyplot as plt 23cost_func = np.array(cost_func)4cost_func = cost_func.reshape(10000,1)5plt.plot(range(len(cost_func)),cost_func)

△ 您的成本函數請查收

不過,現在你可能覺得這個演算法的代碼太多了。為了縮短代碼行數,我們用上了scikit學習庫。scikit學習庫有一個內置的邏輯回歸類別,我們可以直接接入使用。

1from sklearn.metrics import accuracy_score2from sklearn.linear_model import LogisticRegression34clf = LogisticRegression()5clf.fit(x_train,y_train)6y_pred = clf.predict(x_test)7print(accuracy_score(y_test,y_pred))

看,代碼已經被縮減到10行以內了。用scikit學習庫,我們的模型準確率依然100%。

原文鏈接:

https://hackernoon.com/introduction-to-machine-learning-algorithms-logistic-regression-cbdd82d81a36?

hackernoon.com

歡迎大家關注我們的專欄:量子位 - 知乎專欄

誠摯招聘

量子位正在招募編輯/記者,工作地點在北京中關村。期待有才氣、有熱情的同學加入我們!相關細節,請在量子位公眾號(QbitAI)對話界面,回復「招聘」兩個字。

量子位 QbitAI · 頭條號簽約作者

?? ? 追蹤AI技術和產品新動態


推薦閱讀:

Sklearn參數詳解—LR模型
邏輯回歸分類
一種分類----邏輯回歸
邏輯回歸——深度學習花書第五章(四)

TAG:機器學習 | 演算法 | 邏輯回歸 |