1.Logistic回歸
人們將已知存在的數(shù)據(jù)點(diǎn)利用一條直線進(jìn)行擬合(該直線被稱為最佳擬合直線)的過程稱為回歸。
而今天介紹的Logistic回歸分類的主要思想就是依據(jù)現(xiàn)有已分類的數(shù)據(jù)樣本建立回歸公式,以此進(jìn)行分類。
“回歸”源于最佳擬合,而Logistic回歸中訓(xùn)練分類器的做法就是利用一些最優(yōu)算法尋找符合最佳擬合的擬合參數(shù)。
1.1 Logistic分布
設(shè)X是連續(xù)的隨機(jī)變量,且具有如下的分布函數(shù)和密度函數(shù):
 = P(X\leq{x}) = \frac{1}{1+\exp^{-\frac{(x-\mu)}{\gamma}}}$$)
 = F'(X) = \frac{\exp{-\frac{x-\mu}{\gamma}}}{\gamma(1+\exp{-\frac{x-\mu}{\gamma}})^2}$$)
其中μ為位置參數(shù),γ > 0為形狀參數(shù)。
下圖是F(X),f(X)的大致圖像,人們又把F(X)函數(shù)成為sigmoid函數(shù)(以后會(huì)經(jīng)常見到它)。
import matplotlib.pyplot as plt
import numpy as np
import scipy
x = np.linspace(-5, 5)
y1 = 1/(1 + np.exp(- x))
y2 = np.exp(- x)/(1 + np.exp(- x))**2
fig1 = plt.figure()
plt.xlabel('x')
plt.ylabel('F(x)')
plt.plot(x, y1, linewidth = 2.0)
fig2 = plt.figure()
plt.xlabel('x')
plt.ylabel('f(x)')
plt.plot(x, y2, linewidth = 2.0)
plt.show()
1.2 二項(xiàng)式Logistic回歸
從以上的Logistic分布定義中引申出一種分類模型,就是下面要介紹的二項(xiàng)式Logistic回歸模型。
在上述X中,將其分為0、1兩類。即隨機(jī)變量X的取值為實(shí)數(shù),其分類變量定義為Y,每個(gè)x所屬類別可以通過條件概率分布P(Y|X)進(jìn)行表示。
條件概率分布如下:
 = \frac{\exp(\omega \cdot x+b)}{1+\exp(\omega \cdot x+b)}$$)
 = \frac{1}{1+\exp(\omega \cdot x+b)}$$)
x∈Rn是輸入,Y∈ {0, 1}是輸出,ω∈Rn為權(quán)值向量,b∈R為偏置,ω·x為ω和x的內(nèi)積。
這里將ω和x進(jìn)行擴(kuò)充,即},\omega ^{(2)},...,\omega ^{(n)},b }$)和},x{(2)},...,x^{(n)},1}$)
此時(shí)的Logistic回歸模型如下:
 = \frac{\exp(\omega \cdot x)}{1+\exp(\omega \cdot x)}$$)
 = \frac{1}{1+\exp(\omega \cdot x)}$$)
在考慮一個(gè)事件發(fā)生為p,則不發(fā)生的概率為1-p,那么這個(gè)事件發(fā)生的幾率(odds)為p/(1-p)。對數(shù)幾率(log odds)為
 = \log{\frac{p}{1-p}}$$)
將上述Logistic回歸模型代入其中可以得到:
}{1-P(Y = 1\mid x)}} = \omega \cdot x$$)
可以看出輸出Y = 1的對數(shù)幾率是輸入x的線性函數(shù),即Y可以用x的線性函數(shù)表示。自然地,在Logistic回歸模型中,x的線性函數(shù)值ω·x越接近于+∞,其概率越接近于1,反之,ω·x越接近于-∞,其概率越接近于0。
1.3 參數(shù)估計(jì)
假設(shè)給定訓(xùn)練數(shù)據(jù)集,(x_2,y_2),...,(x_N,y_N)}$)
其中,xi∈Rn,yi ∈ {0,1},利用極大似然估計(jì)法估計(jì)模型參數(shù)。
設(shè) =\pi (x)$,則$P(Y=0\mid x) =1-\pi (x)$)
似然函數(shù)為:]{y_i}[1-\pi(x_i)]{1-y_i}$$)
對數(shù)似然函數(shù)為:
此時(shí)對L(ω)求最大值,即得到ω的估計(jì)值。
為此,后續(xù)利用梯度下降法或者擬牛頓法進(jìn)行該值的求解。
假設(shè)ω的極大似然估計(jì)值為ω',那么Logistic模型為:
 = \frac{\exp(\omega' \cdot x)}{1+\exp(\omega' \cdot x)}$$)
 = \frac{1}{1+\exp(\omega' \cdot x)}$$)
1.4 梯度法求解估計(jì)值
對上述L(ω)中的ω求導(dǎo),得到:
令L(ω) = 0,可以求得其最大的L(ω)對應(yīng)的ω',但由于無法直接求解,故采用梯度下降法進(jìn)行求解。
由上求導(dǎo)過程可以知道,L(ω) 的梯度為
 =\sum_{i=1}^{N}{y_i - \pi(x_i)}x_i$$)
故迭代公式(此處為梯度上升算法)為
}x_i$$)
其中α為步長,當(dāng) \mid\mid < \varepsilon$) 即可求得最大的ω,ε為誤差。
2、Logistic分類器實(shí)現(xiàn)
仍然使用這份數(shù)據(jù)進(jìn)行算法實(shí)現(xiàn)
以下列數(shù)據(jù)集為例,進(jìn)行Logistic分類器的設(shè)計(jì)。
編號 | 色澤 | 根蒂 | 敲聲 | 紋理 | 臍部 | 觸感 | 密度 | 含糖率 | 好瓜 |
---|---|---|---|---|---|---|---|---|---|
1 | 青綠 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.697 | 0.460 | 是 |
2 | 烏黑 | 蜷縮 | 沉悶 | 清晰 | 凹陷 | 硬滑 | 0.774 | 0.376 | 是 |
3 | 烏黑 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.634 | 0.264 | 是 |
4 | 青綠 | 蜷縮 | 沉悶 | 清晰 | 凹陷 | 硬滑 | 0.608 | 0.318 | 是 |
5 | 淺白 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.556 | 0.215 | 是 |
6 | 青綠 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 軟粘 | 0.403 | 0.237 | 是 |
7 | 烏黑 | 稍蜷 | 濁響 | 稍糊 | 稍凹 | 軟粘 | 0.481 | 0.149 | 是 |
8 | 烏黑 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 硬滑 | 0.437 | 0.211 | 是 |
9 | 烏黑 | 稍蜷 | 沉悶 | 稍糊 | 稍凹 | 硬滑 | 0.666 | 0.091 | 否 |
10 | 青綠 | 硬挺 | 清脆 | 清晰 | 平坦 | 軟粘 | 0.243 | 0.267 | 否 |
11 | 淺白 | 硬挺 | 清脆 | 模糊 | 平坦 | 硬滑 | 0.245 | 0.057 | 否 |
12 | 淺白 | 蜷縮 | 濁響 | 模糊 | 平坦 | 軟粘 | 0.343 | 0.099 | 否 |
13 | 青綠 | 稍蜷 | 濁響 | 稍糊 | 凹陷 | 硬滑 | 0.639 | 0.161 | 否 |
14 | 淺白 | 稍蜷 | 沉悶 | 稍糊 | 凹陷 | 硬滑 | 0.657 | 0.198 | 否 |
15 | 烏黑 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 軟粘 | 0.360 | 0.37 | 否 |
16 | 淺白 | 蜷縮 | 濁響 | 模糊 | 平坦 | 硬滑 | 0.593 | 0.042 | 否 |
17 | 青綠 | 蜷縮 | 沉悶 | 稍糊 | 稍凹 | 硬滑 | 0.719 | 0.103 | 否 |
2.1 解析數(shù)據(jù)文件
上一篇的《樸素貝葉斯法》已經(jīng)利用了Pandas對讀入的數(shù)據(jù)文件進(jìn)行解析并進(jìn)行啞變量處理,下面即封裝好的解析代碼:
#導(dǎo)入numpy和pandas庫
import numpy as np
import pandas as pd
#解析數(shù)據(jù)文件
def loadDataSet(filename):
dataSet = pd.read_csv(filename, sep = '\t', index_col = '編號')
#啞變量處理
featureDict = []
new_dataSet = pd.DataFrame()
for i in range(len(dataSet.columns)):
featureList = dataSet[dataSet.columns[i]]
classSet = list(set(featureList))
count = 0
for feature in classSet:
d = dict()
if isinstance(feature, float):#判斷是否為連續(xù)變量
continue
else:
featureList[featureList == feature] = count
d[feature] = count
count += 1
featureDict.append(d)
new_dataSet = pd.concat([new_dataSet, featureList], axis = 1)
dataMat = [list(new_dataSet.loc[i][:-1]) for i in range(1,len(new_dataSet) + 1)]
labelMat = list(new_dataSet[new_dataSet.columns[-1]])
return dataMat, labelMat
filename = 'data.txt'
dataMat, labelMat = loadDataSet(filename)
import pprint
pprint.pprint(dataMat)
pprint.pprint(labelMat)
[[1, 1, 2, 2, 0, 0, 0.69700000000000006, 0.46000000000000002],
[0, 1, 1, 2, 0, 0, 0.77400000000000002, 0.376],
[0, 1, 2, 2, 0, 0, 0.63400000000000001, 0.26400000000000001],
[1, 1, 1, 2, 0, 0, 0.60799999999999998, 0.318],
[2, 1, 2, 2, 0, 0, 0.55600000000000005, 0.215],
[1, 2, 2, 2, 1, 1, 0.40299999999999997, 0.23699999999999999],
[0, 2, 2, 0, 1, 1, 0.48100000000000004, 0.14899999999999999],
[0, 2, 2, 2, 1, 0, 0.43700000000000006, 0.21100000000000002],
[0, 2, 1, 0, 1, 0, 0.66599999999999993, 0.090999999999999998],
[1, 0, 0, 2, 2, 1, 0.24299999999999999, 0.26700000000000002],
[2, 0, 0, 1, 2, 0, 0.245, 0.057000000000000002],
[2, 1, 2, 1, 2, 1, 0.34299999999999997, 0.099000000000000005],
[1, 2, 2, 0, 0, 0, 0.63900000000000001, 0.161],
[2, 2, 1, 0, 0, 0, 0.65700000000000003, 0.19800000000000001],
[0, 2, 2, 2, 1, 1, 0.35999999999999999, 0.37],
[2, 1, 2, 1, 2, 0, 0.59299999999999997, 0.042000000000000003],
[1, 1, 1, 0, 1, 0, 0.71900000000000008, 0.10300000000000001]]
[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
可以看到,該操作將字符串型的分類變量解析成為了數(shù)值型的分類變量,從而方便了將要進(jìn)行的數(shù)值運(yùn)算。
2.2 利用梯度上升法求最佳回歸系數(shù)
在前面的定義中,Logistic分布函數(shù)$F(X)$又被稱為sigmoid函數(shù),其對數(shù)幾率為
}{1-P(Y = 1\mid x)}} = \omega \cdot x$$)
即將sigmoid函數(shù)的輸入可以看作是:
}x{(1)}+\omega {(2)}x{(2)}+,...,+\omega {(n)}x{(n)} = \omega^{T} \cdot x$$)
由此,定義下面的代碼進(jìn)行梯度上升法的實(shí)現(xiàn):
#定義Sigmoid函數(shù)
def sigmoid(inX):
return 1.0/(1 + np.exp(- inX))
#隨機(jī)的梯度上升法
def gradAscent(dataMatIn, classLabels, numIter = 150):
#獲得行數(shù)和列數(shù),即樣本數(shù)和特征數(shù)
m, n = np.shape(dataMatIn)
#權(quán)重初始化
weights = np.ones(n)
for j in range(numIter):
dataIndex = range(m)
for i in range(m):
alpha = 4/(1.0 + j + i) + 0.01
randIndex = int(np.random.uniform(0, len(dataIndex)))
h = sigmoid(sum(dataMatIn[randIndex] * weights))
error = classLabels[randIndex] - h
weights = weights + np.dot(alpha * error, dataMatIn[randIndex])
return weights
weights = gradAscent(dataMat, labelMat)
print(weights)
[-1.91739131 -2.37320272 3.30085298 1.32020706 -2.30328752 0.58413608
0.84630395 -0.63702599]
2.3 分類器設(shè)計(jì)
由上,求出了相應(yīng)的輸入特征對應(yīng)權(quán)重,利用對數(shù)幾率公式,可以簡單實(shí)現(xiàn)分類的效果,相關(guān)設(shè)計(jì)代碼如下:
def classfy(testdir, weights):
dataMat, labelMat = loadDataSet(testdir)
dataMat = np.mat(dataMat)
weights = np.mat(weights)
h = sigmoid(dataMat * weights.transpose())
h = h.tolist()
m = len(h)
error = 0.0
for i in range(m):
if h[i][0] > 0.5:
print(int(labelMat[i]),'is classfied as: 1')
if int(labelMat[i])!=1:
error += 1
print('error')
else:
print(int(labelMat[i]),'is classfied as: 0')
if int(labelMat[i])!=0:
error += 1
print('error')
print('error rate is:','%.4f' %(error/m))
classfy(filename, weights)
1 is classfied as: 1
1 is classfied as: 1
1 is classfied as: 1
1 is classfied as: 1
1 is classfied as: 1
1 is classfied as: 1
1 is classfied as: 1
1 is classfied as: 1
0 is classfied as: 0
0 is classfied as: 0
0 is classfied as: 0
0 is classfied as: 0
0 is classfied as: 1
error
0 is classfied as: 0
0 is classfied as: 1
error
0 is classfied as: 0
0 is classfied as: 0
error rate is: 0.1176
將訓(xùn)練的數(shù)據(jù)樣本進(jìn)行測試,可以看出上述分類中,只有兩個(gè)樣本被分類錯(cuò)誤了,準(zhǔn)確度達(dá)到了88.24%,分類效果不錯(cuò)。
2.4 Scikit - Learn庫簡單實(shí)現(xiàn)Logistic分類
下面的代碼是簡單通過Scikit - Learn庫實(shí)現(xiàn)Logistic的分類:
from sklearn.linear_model import LogisticRegression
X, Y = loadDataSet(filename)
clf = LogisticRegression()
clf.fit(X, Y)
y_pred = clf.predict(X)
accuracy = np.mean(Y == y_pred)
print('準(zhǔn)確度為:', accuracy)
準(zhǔn)確度為: 0.882352941176
?
可以看出,上述實(shí)現(xiàn)的準(zhǔn)確度與設(shè)計(jì)的分類器的準(zhǔn)確度基本一樣,效果不錯(cuò)。
3、總結(jié)
Logist回歸分類的優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):計(jì)算代價(jià)低,易于理解和實(shí)現(xiàn);
- 缺點(diǎn):易欠擬合,分類精度普遍不高。
本文實(shí)現(xiàn)過程中使用的數(shù)據(jù)樣本量較少,結(jié)果也較為單一,后續(xù)可以通過訓(xùn)練和測試較多樣本量的數(shù)據(jù),來感受其作用。
4、 參考文獻(xiàn)
[1] 李航. 統(tǒng)計(jì)學(xué)習(xí)方法.清華大學(xué)出版社,2012
[2] Peter Harrington. 機(jī)器學(xué)習(xí)實(shí)戰(zhàn). 人民郵電出版社,2013
[3] http://blog.csdn.net/lsldd/article/details/41551797