scikit-learn学习笔记(五)Logistic regression(逻辑回归)
邏輯函數(logistic function)
為了更好地解釋邏輯回歸,讓我們首先了解一下邏輯函數。邏輯函數由于它的S形,有時也被稱為sigmoid函數。
現在我要引入比值比(odds ratio)的概念,它可以被寫成p(1?p),其中的p代表正事件(positive event)的概率,正事件并不是代表好的方面的概率,而是代表我們想要預測的事件。比如:病人患有某種疾病的概率。我們把正事件的類標簽設置為1。比值比的對數稱為Logit函數,它可以寫成如下形式:
logit(p)=logp(1?p)
它的函數圖像如下:
從圖像上我們可以看出,logit函數輸入0到1的值并把它們轉換為整個實數范圍內的值。上面的p代表正事件的概率,因此在給定特征向量x的條件下,類別y=1的概率可以寫成P(y=1|x)。大家都知道概率的范圍為0到1,如果我把這個概率傳遞給logit函數那么它的輸出范圍是整個實數,因此如果我用某些合適的權重向量w參數化特征向量x后,可以有如下等式:
logit(P(y=1|x))=w0x0+w1x1+?+wnxn=∑i=0nwixi
但是在實際應用中,我們更想求的是P(y=1|x),因此,我們需要找到logit函數的反函數,通過輸入用權重向量w來參數化的x,來輸出我們想要知道的正事件的概率,即P(y=1|x)。而這個反函數就是我們的sigmoid函數,它可以寫成S(h)=11+e?h,公式中的h為樣本特征和權重的線性組合,即,w0x0+w1x1+?+wnxn。下面我們來畫出這個函數圖像的樣子:
import matplotlib.pyplot as plt import numpy as npdef sigmoid(h):return 1.0 / (1.0 + np.exp(-h))h = np.arange(-10, 10, 0.1) # 定義x的范圍,像素為0.1 s_h = sigmoid(h) # sigmoid為上面定義的函數 plt.plot(h, s_h) plt.axvline(0.0, color='k') # 在坐標軸上加一條豎直的線,0.0為豎直線在坐標軸上的位置 plt.axhspan(0.0, 1.0, facecolor='1.0', alpha=1.0, ls='dotted') # 加水平間距通過坐標軸 plt.axhline(y=0.5, ls='dotted', color='k') # 加水線通過坐標軸 plt.yticks([0.0, 0.5, 1.0]) # 加y軸刻度 plt.ylim(-0.1, 1.1) # 加y軸范圍 plt.xlabel('h') plt.ylabel('$S(h)$') plt.show()從上圖我們可以看出,函數接收整個實數范圍的輸入,輸出0到1之間的數。
因此S(w0x0+w1x1+?+wnxn)=P(y=1|x;w),
這個概率我們可以解釋成:給定用權重w參數化后的特征x,樣本屬于類別1的概率。通過階躍函數(step function),我們可以得到如下公式:
f(n)={1,0,if S(h)?≥0.5otherwise
還有一個等價的公式如下:
f(n)={1,0,if h?≥0.0otherwise
實際上,很多應用不只僅僅是想得到一個類標簽,而是算出屬于某個類別的概率。比如邏輯回歸就是這樣的,它不僅僅是告訴你是否患有疾病,而是告訴你有多大概率患有這個疾病。
在上面的例子當中,我們一直都看到權重w的出現,那么我們如何學習出最佳的權重w呢?在告訴你答案之前,讓我們先復習一下最大似然估計(maximum likelihood)的概念。
最大似然估計(maximum likelihood)
這個方法的本質就是:選擇最佳的參數值w,來最大化我們樣本數據的可能性。
假設我們給定樣本X1,X2,X3,…,Xn,那么我可以寫出一個關于參數w的可能性函數,如下:
lik(w)=f(X1,X2,X3,…,Xn
|w)
實際上,可能性函數就是樣本數據作為參數w的函數的概率。
如果X1,X2,X3,…,Xn相互之間是獨立的,可能性函數可以簡化成如下形式:
lik(w)=∏1nf(Xi|w)
但是,如果我們有很多的樣本數據呢?這時,你就會乘上很多項,這些項通常都很小,可能性函數就會變得很小。因此,你應該采用log可能性函數。第一,如果在可能性很小的時候它可以防止潛在的數值下溢;第二,我們把乘積轉換為求和,這可以使我們更加容易求得函數的導數。第三,log函數是單調的,最大化可能性函數的值也就是最大化log可能性函數的值。log可能性函數公式如下:
l(w)=log(lik(w))=∑inlog(f(Xi|w))
下面,我舉2個例子來應用一下這個強大的工具:
1、假設你口袋里有2枚硬幣,1枚硬幣出現正面的概率為p=0.5,另1枚硬幣出現正面的概率為p=0.8,現在你從口袋里隨機拿出一枚硬幣(你并不知道拿的是哪枚硬幣),然后隨機投擲4次,出現3次正面,1次反面。你覺得你拿出的是哪枚硬幣?或者哪枚硬幣的最大似然估計更大?
答:通過問題我們可以得出這個是屬于二項分布。它的概率為P(x|n,p)=(nx)px(1?p)n?x.現在,我們來寫出log可能性函數:
l(0.5)=?0.6021
l(0.8)=?0.3876
因此當p為0.8時,使可能性函數更大,所以我更可能拿出的是正面概率為p=0.8的硬幣。
2、假設Xi~N(μ,σ2),并且相互之間是獨立的。求出最佳參數?
答:log可能性函數如下:
因為我們想找到參數μ和σ使得可能性函數最大,因此我們需要找到它們的偏導:
?12σ2∑i=1n(Xi?μ)2)=?1σ2∑i=1n(Xi?μ)
讓兩個偏導都等于0,然后求出最佳參數。
μ=1n∑i=1nXi=Xˉ
掌握了最大似然估計,現在你就可以知道邏輯回歸cost函數的由來了。
邏輯回歸的cost函數
現在,我們可以用可能性函數來定義上面的權重w了。公式如下:
L(w)=∏i=1nP(y(i)|x(i);w)=∏i=1nS(h(i))y(i)(1?S(h(i)))1?y(i)
上面公式中的h為假設函數w0x0+w1x1+?+wnxn,把上面的函數加上對數,公式如下:
l(w)=log(L(w))=∑i=1ny(i)log(S(h(i)))+(1?y(i))log(1?S(h(i)))
現在,我們的目的是最大化log可能性函數,找到一個最佳的權重w。我們可以在上面的log可能性函數前加上負號,用梯度下降算法來最小化這個函數?,F在,我得到了邏輯回歸的cost函數如下:
J(w)=?∑i=1ny(i)log(S(h(i)))+(1?y(i))log(1?S(h(i)))
- n:訓練集樣本總數
- S:sigmoid函數
- h:假設函數
假設我們只有一個樣本,現在我們可以把上面的cost函數拆分成分段函數如下:
J(w)=????log(S(h)),?log(1?S(h)),if y = 1if y = 0
我們把邏輯回歸的cost函數做成了圖像如上。當實際類別為1時,如果我們預測為1則需要很小的cost,如果我們預測為0則需要很大的cost;反過來,當實際類別為0時,如果我們預測為0則需要很小的cost,如果我們預測為1則需要很大的cost。
Iris數據集概述
首先,我們取得數據,下面這個鏈接中有數據的詳細介紹,并可以下載數據集。
https://archive.ics.uci.edu/ml/datasets/Iris
從數據的說明上,我們可以看到Iris有4個特征,3個類別。但是,我們為了數據的可視化,我們只保留2個特征(sepal length和petal length)。讓我們先看看數據集的散點圖吧!
下面,我們進入Ipython命令行。
import pandas as pd import matplotlib.pyplot as plt import numpy as npdf = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None) # 加載Iris數據集作為DataFrame對象 X = df.iloc[:, [0, 2]].values # 取出2個特征,并把它們用Numpy數組表示plt.scatter(X[:50, 0], X[:50, 1],color='red', marker='o', label='setosa') # 前50個樣本的散點圖 plt.scatter(X[50:100, 0], X[50:100, 1],color='blue', marker='x', label='versicolor') # 中間50個樣本的散點圖 plt.scatter(X[100:, 0], X[100:, 1],color='green', marker='+', label='Virginica') # 后50個樣本的散點圖 plt.xlabel('petal length') plt.ylabel('sepal length') plt.legend(loc=2) # 把說明放在左上角,具體請參考官方文檔 plt.show()從上圖我們可以看出,數據集是線性可分的。為了更好地演示效果,我只用setosa和versicolor這兩個類別。
接下來,我們要用強大的scikit-learn來擬合模型。
下面,我將用scikit-learn來訓練一個邏輯回歸模型:
from sklearn import datasets import numpy as np from sklearn.cross_validation import train_test_splitiris = datasets.load_iris() X = iris.data[:, [2, 3]] y = iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)from sklearn.preprocessing import StandardScaler sc = StandardScaler() sc.fit(X_train) X_train_std = sc.transform(X_train) X_test_std = sc.transform(X_test)X_combined_std = np.vstack((X_train_std, X_test_std)) y_combined = np.hstack((y_train, y_test))from sklearn.linear_model import LogisticRegression lr = LogisticRegression(C=1000.0, random_state=0) lr.fit(X_train_std, y_train) lr.predict_proba(X_test_std[0,:]) # 查看第一個測試樣本屬于各個類別的概率 plot_decision_regions(X_combined_std, y_combined, classifier=lr, test_idx=range(105,150)) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.legend(loc='upper left') plt.show() 從上圖我們看到邏輯回歸模型把類別很好地分開了。
總結
以上是生活随笔為你收集整理的scikit-learn学习笔记(五)Logistic regression(逻辑回归)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TensorFLow 常用错误总结
- 下一篇: linux的lsof命令详解