1. 程式人生 > >5. Logistic回歸

5. Logistic回歸

時間 條件 決策 1+n 們的 marker from 等等 pandas

一、介紹 Logistic回歸是廣泛應用的機器學習算法,雖然名字裏帶“回歸”,但是它實際上是一種分類方法,主要用於兩分類問題(即輸出只有兩種,分別代表兩個類別)。 面對一個回歸或者分類問題,建立代價函數(損失函數),使用最優化算法(梯度上升法、改進的隨機梯度上升法),找到最佳擬合參數,將數據擬合到一個logit函數(或者叫做logistic函數)中,得到定性變量y,比如y=0或1,從而預測事件發生的概率。 二、線性回歸 從線性回歸說,多維空間中存在的樣本點,用特征的線性組合去擬合空間中點的分布和軌跡。如下圖所示: 技術分享圖片
線性回歸能對連續值結果進行預測,現實生活中存在另一種分類-----是與否的二分類問題。比如醫生需要判斷病人是否生病,銀行要判斷一個人的信用程度是否達到可以給他發信用卡的程度,郵件收件箱要自動對郵件分類為正常郵件和垃圾郵件等等。 當然,既然能夠用線性回歸預測出連續值結果,那根據結果設定一個閾值是不是就可以解決這個問題了呢?事實是,對於很標準的情況,確實可以。下圖中X為數據點腫瘤的大小,Y為觀測結果是否是惡性腫瘤。如hθ(x)所示,構建線性回歸模型,然後設定一個閾值0.5,預測hθ(x)≥0.5的這些點為惡性腫瘤,而hθ(x)<0.5為良性腫瘤。 技術分享圖片
上圖中突然有一個wrong的數據點,再根據設定的0.5,得出的分類就是錯誤的(良性腫瘤錯誤認為是惡性腫瘤),而現實生活中分類問題的數據,會比上述舉例更復雜,借助線性回歸+閾值的方式,很難完成一個魯棒性很好的分類器。 相比線性回歸,邏輯回歸: 1. 線性回歸的結果是一個連續值,值的範圍是無法限定的,假設回歸的結果都是無法限定的值,那做出一個判定就很難了。能將結果做一個映射,輸出(0,1) 的一個概率值,這個問題就很清楚了。有這樣一個簡單的函數,可以做到這樣的映射---sigmoid函數。 說明:sigmoid函數圖像可以看出,函數 hθ(x) = g(z): 在z=0的時候.函數值
1/2,隨著 z 逐漸變小函數值趨於0,z 逐漸變大函數值逐漸趨於1,而這正是一個概率的範圍。 我們定義線性回歸的預測函數為hθ(x) = θTX,那麽邏輯回歸的輸出hθ(x) = g( θTX ),其中 g( z ) 函數就是上述sigmoid函數. hθ(x) = g( θTX ) ≥ 0.5, 則 θTX ≥ 0, 意味著類別為 1; hθ(x) = g( θTX ) < 0.5, 則 θTX < 0, 意味著類別為 0; 所以可以認為 θTX =0 是一個決策邊界,當它 >0 或 <0 時,邏輯回歸模型預測出不同的分類結果。 技術分享圖片 2. 邏輯回歸可以做出直線、圓或者是曲線這樣的判定邊界,比較好地將兩類樣本分開。 說明:假設 hθ(x)=g(θ01X12X2),其中θ012分別取-3, 1, 1。則當?3+X1+X2 ≥ 0時, y = 1即類別為1; 則X1+X2 = 3是一個判定邊界,圖形表示如下,剛好把圖上的兩類點區分開來: 技術分享圖片 假設hθ(x) 比較復雜,hθ(x) = g(θ01X12X2+ θ3 X12+ θ4X22) ,其中θ0 1 2,θ3 4別取-1, 0, 0,1,1,則當 -1 + x12+x22 ≥ 0 時,y = 1即類別為1; x12+x22 = 1是一個判定邊界,圖形表示如下: 技術分享圖片 所以,只要我們的hθ(x)設計足夠合理,準確的說是g(θTx)中θTx足夠復雜,能在不同的情形下,擬合出不限於線性的判定邊界。 技術分享圖片 技術分享圖片 技術分享圖片 三、求解θ 假設我們有n個獨立的訓練樣本{(x1, y1) ,(x2, y2),…, (xn, yn)},類別y = {0, 1}。那每一個觀察到的樣本(xi, yi)出現的概率是: 技術分享圖片 y的取值為0 或 1,所以,上式等價於: 技術分享圖片 那整個樣本集,n個獨立的樣本出現的似然函數為(因為每個樣本都是獨立的,所以n個樣本出現的概率就是它們各自出現的概率相乘): 技術分享圖片 連乘不好處理,取自然對數,轉成相加: 技術分享圖片 經過化簡得到: 技術分享圖片 該似然函數在這裏表示的是:參數取值為θ時,取得當前這個樣本集的可能性。使參數為θ的似然函數L(θ)極大化,然後極大值對應的θ就是我們的估計。 假如需要求如下函數的最大值: 技術分享圖片 函數的導數為: 技術分享圖片 所以 x=1.5即取得函數的最大值1.25。 同樣的,我們對剛剛的對數似然函數logL(θ)即l(θ)求導: 技術分享圖片 然後我們令該導數為0,你會很失望的發現,它無法解析求解。 終於可以說梯度上升了……利用叠代公式: 技術分享圖片 參數α叫學習率,就是每一步走多遠,這個參數蠻關鍵的。如果設置的太多,那麽很容易就在最優值附近徘徊,因為步伐太大了。它帶來的好處是能很快的從遠離最優值的地方回到最優值附近,只是在最優值附近的時候,它有心無力了。但如果設置的太小,那收斂速度就太慢了,向蝸牛一樣,雖然會落在最優的點,但是速度太慢。所以學習率可以改進,開始叠代時,學習率大,慢慢的接近最優值的時候,學習率變小就可以了,即隨機梯度下降算法。 所以,最終我們計算過程(訓練過程)如下: 1. 根據權重和訓練樣本計算估計值 技術分享圖片 2.計算誤差 技術分享圖片 3. 叠代更新
技術分享圖片 叠代停止條件:到達限定叠代次數 或者 誤差 <= 設定誤差的最小值。 說明:以上過程中,n 和 m等價,w 和 θ等價。 四、 代碼
 1 import numpy as np
 2 import re
 3 from pandas import DataFrame
 4 import time as time
 5 import matplotlib.pyplot as plt
 6 import math
 7 
 8 def get_data(filename):                 #讀取數據
 9     f = open(filename)
10     data = DataFrame(columns=[x0,x1,x2,label]) #構造DataFrame存放數據,列名為x與y
11     line = f.readline()
12     line = line.strip()
13     p = re.compile(r\s+)              #由於數據由若幹個空格分隔,構造正則表達式分隔
14     while line:
15         line = line.strip()
16         linedata = p.split(line)
17         data.set_value(len(data),[x0,x1,x2,label],[1,float(linedata[0]),float(linedata[1]),int(linedata[2])]) #數據存入DataFrame
18         line = f.readline()
19     return np.array(data.loc[:,[x0,x1,x2]]),np.array(data[label])
20 def sigmoid(x):
21     return 1.0/(1+np.exp(-x))
22 def stocGradAscent(dataMat,labelMat,alpha = 0.01):   #隨機梯度上升
23     start_time = time.time()                         #記錄程序開始時間
24     m,n = dataMat.shape
25     weights = np.ones((n,1))                         #分配權值為1
26     for i in range(m):
27         h = sigmoid(np.dot(dataMat[i],weights).astype(int64)) #註意:這裏兩個二維數組做內積後得到的dtype是object,需要轉換成int64
28         error = labelMat[i]-h                        #誤差
29         weights = weights + alpha*dataMat[i].reshape((3,1))*error #更新權重
30     duration = time.time()-start_time
31     print(time:,duration)
32     return weights
33 def gradAscent(dataMat,labelMat,alpha = 0.01,maxstep = 1000): #批量梯度上升
34     start_time = time.time()
35     m,n = dataMat.shape
36     weights = np.ones((n,1))
37     for i in range(maxstep):
38         h = sigmoid(np.dot(dataMat,weights).astype(int64))  #這裏直接進行矩陣運算
39         labelMat = labelMat.reshape((100,1))                  #label本為一維,轉成2維
40         error = labelMat-h                                    #批量計算誤差
41         weights = weights + alpha*np.dot(dataMat.T,error)     #更新權重
42     duration = time.time()-start_time
43     print(time:,duration)
44     return weights
45 def betterStoGradAscent(dataMat,labelMat,alpha = 0.01,maxstep = 150):
46     start_time = time.time()
47     m,n = dataMat.shape
48     weights = np.ones((n,1))
49     for j in range(maxstep):
50         for i in range(m):
51             alpha = 4/(1+i+j) + 0.01                         #設置更新率隨叠代而減小
52             h = sigmoid(np.dot(dataMat[i],weights).astype(int64))
53             error = labelMat[i]-h
54             weights = weights + alpha*dataMat[i].reshape((3,1))*error
55     duration = time.time()-start_time
56     print(time:,duration)
57     return weights
58 def show(dataMat, labelMat, weights):
59     #dataMat = np.mat(dataMat)
60     #labelMat = np.mat(labelMat)
61     m,n = dataMat.shape
62     min_x = min(dataMat[:, 1])
63     max_x = max(dataMat[:, 1])
64     xcoord1 = []; ycoord1 = []
65     xcoord2 = []; ycoord2 = []
66     for i in range(m):
67         if int(labelMat[i]) == 0:
68             xcoord1.append(dataMat[i, 1]); ycoord1.append(dataMat[i, 2])
69         elif int(labelMat[i]) == 1:
70             xcoord2.append(dataMat[i, 1]); ycoord2.append(dataMat[i, 2])
71     fig = plt.figure()
72     ax = fig.add_subplot(111)
73     ax.scatter(xcoord1, ycoord1, s=30, c="red", marker="s")
74     ax.scatter(xcoord2, ycoord2, s=30, c="green")
75     x = np.arange(min_x, max_x, 0.1)
76     y = (-float(weights[0]) - float(weights[1])*x) / float(weights[2])
77     ax.plot(x, y)
78     plt.xlabel("x1"); plt.ylabel("x2")
79     plt.show()
80 
81 if __name__==__main__:
82     dataMat,labelMat = get_data(data1.txt)
83     weights = gradAscent(dataMat,labelMat)
84     show(dataMat,labelMat,weights)

 
參考: http://blog.csdn.net/han_xiaoyang/article/details/49123419 https://www.cnblogs.com/chenyang920/p/7426187.html http://blog.csdn.net/u011197534/article/details/53492915?utm_source=itdadao&utm_medium=referral http://blog.csdn.net/zouxy09/article/details/8537620



來自為知筆記(Wiz)



5. Logistic回歸