這一節主要將邏輯迴歸模型應用到鶯尾花數據集進行分類
our features were measured from each sample: the length and the width of the sepals and petals, in centimeters.
數據集包含 Setosa、Versicolor 和 Virginica 3 個種類,這三個類別標籤就是我們想要預測的量,即因變量。其中每個種類包含有 50 個數據,每個數據包含 4 種變量(特徵),這 4 種變量就是我們要分析的自變量,分別是:花瓣長度、花瓣寬度、花萼長度和花萼寬度。
1. 從單變量說起
先看一個簡單的問題:請利用花萼長度這一特徵(自變量)來對 setosa 和 versicolor 兩類(因變量)進行分類。
(1)讀取兩類數據
df = iris.query("species == ('setosa', 'versicolor')")
y_0 = pd.Categorical(df['species']).codes
x_n = 'sepal_length'
x_0 = df[x_n].values
(2)查看一下數據格式
(3)建立邏輯迴歸模型
with pm.Model() as model_0:
alpha = pm.Normal('alpha', mu=0, sd=10)
beta = pm.Normal('beta', mu=0, sd=10)
mu = alpha + pm.math.dot(x_0, beta)
theta = pm.Deterministic('theta', 1 / (1 + pm.math.exp(-mu)))
bd = pm.Deterministic('bd', -alpha/beta)
yl = pm.Bernoulli('yl', p=theta, observed=y_0)
start = pm.find_MAP()
step = pm.NUTS()
trace_0 = pm.sample(5000, step, start, nchains=1)
varnames = ['alpha', 'beta', 'bd']
pm.traceplot(trace_0, varnames)
plt.savefig('B04958_05_05.png', dpi=300, figsize=(5.5, 5.5))
這裏需要注意兩點:
- 變量 theta 表示什麼? 變量 theta 是對 mu 應用邏輯函數之後的值,表示 ;
- 變量 bd 表示什麼? 變量 bd 表示決策邊界,位於決策左側的 x 值屬於類別0,位於決策右側的 x 值屬於類別1。
接下來證明爲什麼 bd = ?
假設分類出錯的代價是對稱的,即 p=0.5 決定着區分 0類與 1類,所以有:
(4)將後驗的總結打印出來,然後將 bd 與通過另外一種方式得到的值進行比較
(5)現在我們將數據及擬合的Sigmoid曲線畫出來
注意:這裏的曲線是 ,並不是 。
另外,上述模型找的決策邊界95%HPD區間(紅色區域)並不能很好地區分數據集。可能是模型不夠好,也可能是隻根據這一個特徵很難區分這兩個類別,顯然這裏應該是後者。
(6)使用模型做預測
給定若干個 花萼長度 返回他們分類結果爲versicolor(1類)的概率值
def classify(n, threshold):
"""
A simple classifying function
"""
n = np.array(n)
mu = trace_0['alpha'].mean() + trace_0['beta'].mean() * n
prob = 1 / (1 + np.exp(-mu))
return prob, prob >= threshold
classify([5, 5.5, 6], 0.5)
可以看到,三個樣本點屬於 1類 的概率分別是(0.14, 0.59, 0.93)。
2. 多元邏輯迴歸
與多變量線性迴歸類似,多元邏輯迴歸使用了多個自變量。這裏講根據花萼長度與花萼寬度結合在一起對 setosa 與 versicolor 進行分類。
(1)讀取兩類數據
df = iris.query("species == ('setosa', 'versicolor')")
y_1 = pd.Categorical(df['species']).codes
x_n = ['sepal_length', 'sepal_width']
x_1 = df[x_n].values
#x_1 = (x_1 - x_1.mean(axis=0))/x_1.std(axis=0)
#x_1 = (x_1 - x_1.mean(axis=0))
(2)查看一下數據格式
(3)建立邏輯迴歸模型
with pm.Model() as model_1:
# We define the prioris
alpha = pm.Normal('alpha', mu=0, sd=10)
beta = pm.Normal('beta', mu=0, sd=2, shape=len(x_n))
mu = alpha + pm.math.dot(x_1, beta)
# Aplly the logistic linking function
theta = 1 / (1 + pm.math.exp(-mu))
# Compute the boundary decision
bd = pm.Deterministic('bd', -alpha/beta[1] - beta[0]/beta[1] * x_1[:,0])
# Define the likelihood
yl = pm.Bernoulli('yl', p=theta, observed=y_1)
# Sampling
#start = pm.find_MAP()
#step = pm.NUTS()
#trace_1 = pm.sample(5000, step, start)
trace_1 = pm.sample(5000, nchains=1)
chain_1 = trace_1[100:]
pm.traceplot(chain_1)
plt.savefig('B04958_05_07.png', dpi=300, figsize=(5.5, 5.5))
現在我們看看二元邏輯迴歸的決策邊界(一條直線):
思考一下爲什麼現在 bd 是100個曲線(每個曲線對於一個數據點)?
(4)現在我們將數據及擬合的Sigmoid曲線畫出來
對於多元邏輯迴歸,這裏還有幾個問題需要交代。
3. 多元邏輯迴歸細節
3.1 處理相關變量
相關變量是什麼?相關變量會引發什麼問題?相關變量是指兩個變量之間存在一定的相關關係(比如線性關係),相關變量限制模型的能力更弱,即不能給予模型足夠多的限制。
那麼如何解決這個問題呢?
- 不使用相關變量;
- 使用攜帶信息的先驗;
- 使用弱先驗。
3.2 處理類別不平衡數據
類別不平衡會使得決策邊界向樣本量更少的類別偏移,而且不確定性會更大。
3.3 如何解決類別不平衡的問題
給數據加入更多的先驗信息。
3.4 解釋邏輯迴歸係數
係數 的意義是:當 增加單位量的時候,發生比的對數增量。
發生比:
3.5 Softmax迴歸
使用完整的數據集(4個特徵)進行分類(3類),這個作爲一個練習,代碼我會附在項目源碼中。
項目源碼:https://github.com/dhuQChen/BayesianAnalysis