概率統計基礎(四): 方差分析

這次概率統計學習基於:Datawhale概率統計組隊學習文檔

1. 寫在前面

這次藉着在Datawhale組織的概率統計專題學習的機會再重新溫習一遍數學基礎,所謂機器學習和深度學習, 背後的邏輯都是數學, 所以數學基礎在這個領域非常關鍵, 而統計學又是重中之重, 機器學習從某種意義上來說就是一種統計學習, 所以這次依然是感謝組織的這次學習機會, 這一版塊是整理概率統計的相關內容, 具體知識點可以看上面的鏈接文檔, 基礎知識點整理的很全了,所以這次又是站在了大佬的肩膀上前行, 主要是其中的重點知識進行整理和補充, 然後補充一些代碼實現上的內容。

今天是概率統計學習的最後一篇文章了, 叫做方差分析, 屬於數理統計的內容了, 通過這四篇文章,就把概率統計的重點內容過了一下, 文章結束的時候也會簡單做一個總結。 而今天的重點放在方差分析這塊, 這一塊在實際中還是很常用的, 首先會介紹一點方差分析中的概念, 然後重點介紹單因素方差分析的原理以及補充python的實現代碼, 最後是雙因素方差分析的原理及python實現。通過今天的內容, 可以簡單的用python玩方差分析了。

大綱如下

  • 關於方差分析, 我們需要了解的
  • 單因素方差分析原理及python實現
  • 雙因素方差分析原理及python實現

Ok, let’s go!

2. 關於方差分析,我們需要了解的

關於方差分析的詳細描述, 可以參考上面的學習文檔, 這裏依然是補充一些不一樣的知識, 這樣纔有意思。

方差分析(ANOVA)是數理統計中很常用的內容, 那麼到底是幹什麼用的呢? 在科學試驗和生產實踐中, 影響某一事物的因素往往很多, 比如化工生產中, 像原料成分, 劑量, 反應溫度, 壓力等等很多因素都會影響產品的質量, 有些因素影響較大, 有些影響較小, 爲了使生產過程穩定, 保證優質高產, 就有必要找出對產品質量有顯著影響的因素。 怎麼找呢? 就需要試驗, 方差分析就是根據試驗的結果進行分析, 鑑別各個有關因素對試驗結果影響程度的有效方法。而根據涉及到的因素個數的不同, 又可以把方差分析分爲單因素方差分析、多因素方差分析等。

下面我們先重點研究單因素方差分析, 通過一個例子,引出方差分析中的幾個概念:

某保險公司想了解一下某險種在不同的地區是否有不同的索賠額。 於是他們就蒐集了四個不同地區一年的索賠額情況的記錄如下表:
在這裏插入圖片描述
嘗試判斷一下, 地區這個因素是否對與索賠額產生了顯著的影響?

這個問題就是單因素方差分析的問題, 具體解決方法後面會說, 首先先由這個例子弄清楚幾個概念:

  1. 試驗指標: 方差分析中, 把考察的試驗結果稱爲試驗指標, 上面例子裏面的“索賠額”。
  2. 因素: 對試驗指標產生影響的原因稱爲因素, 如上面的“地區”
  3. 水平: 因素中各個不同狀態, 比如上面我們有A1, A2, A3, A4四個狀態, 四個水平。

這個類比的話, 就類似於y就是試驗指標, 某個類別特徵x
就是因素, 類別特徵x的不同取值就是水平。那麼通過方差分析, 就可以得到某個類別特徵對於y的一個影響程度了吧, 這會幫助分析某個類別特徵的重要性喲!

那麼如何進行單因素方差分析呢?

3. 單因素方差分析原理及python實現

在解決上面的問題之前, 我們得看看單因素方差分析的原理, 也就是把上面的例子概括爲一般性的問題, 分析一下解法。

所謂單因素方差分析, 就是僅考慮有一個因素A對試驗指標的影響。 假如因素A有r個水平, 分別在第i個水平下進行多次獨立的觀測, 所得到的試驗指標數據如下:
在這裏插入圖片描述
注意這裏的nin_i不一定一樣, 上面的例子。 各總體間相互獨立, 因此我們會有下面的模型:
在這裏插入圖片描述
簡單解釋一下上面這個在說啥: XijX_{ij}就是第ii個水平的第jj個觀測值, 上面例子裏面就是第ii個地區第jj次的索賠額。 μi\mu_i表示第ii個水平的理論均值, 後面的ϵi\epsilon_i表示的隨機誤差, 假設這個服從正態。第一個等式的意思就是某個觀測值可以用某水平下的均值加一個誤差來表示。

如果我們想判斷某個因素A對於試驗指標是否有顯著影響, 很直觀的就是我們看看因素A不同的水平下試驗指標的理論均值是否有顯著差異, 即理論均值是否完全相同, 如果有顯著差異, 就說明不同的水平對試驗指標影響很大, 即A對試驗指標有顯著影響。這也是方差分析的目標, 故把問題轉換成了比較不同水平下試驗指標的均值差異。 顯著在這裏的意思是差異達到的某種程度。

基於上面的分析, 我們就可以把方差分析也看成一個檢驗假設的問題, 並有了原假設和備擇假設:

  • H0H_0: μ1=μ2=...=μr\mu_1=\mu_2=...=\mu_r
  • H1H_1: μ1,μ2,...μr\mu_1, \mu_2, ...\mu_r不全相等

那麼這個假設檢驗的問題怎麼驗證呢? 我們得先分析一下, 爲啥各個XijX_{ij}會有差異? 從上面的模型中, 我們可以看到Xij=μi+ϵijX_{ij}=\mu_i+\epsilon_{ij}, 所以第一個可能就是μi\mu_i可能有差異, 比如μ1>μ2\mu_1>\mu_2, 那麼X1jX_{1j}很容易就大於X2jX_{2j}。 另一個可能就是隨機誤差的存在。 在這樣的啓發下,我們得找一個衡量全部XijX_{ij}之間差異的量, 就是下面這個了:
ST=i=1rj=1ni(XijXˉ)2S_T = \sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(X_{i j}-\bar{X}\right)^{2}
這個叫做總偏差平方和,如果這個越大, 就表示XijX_{ij}之間的差異就越大。這裏的Xˉ=i=1rj=1niXij/n\bar{X} = \sum_{i=1}^{r} \sum_{j=1}^{n_{i}}X_{ij} / nn=n1+n2,...+n2n=n_1+n_2,...+n_2表示總的觀測值個數。

接下來,我們把這個平方和分解開爲兩部分:一部分是由於因素A引起的差異, 這個叫做效應平方和SAS_A, 另一部分是由於隨機誤差引起的差異, 這個叫做誤差平方和SES_E

關於SES_E, 先固定一個ii, 此時對應的所有觀測值Xi1,Xi2,...XiniX_{i1}, X_{i2}, ...X_{in_i}, 他們之間的差異與每個水平的理論平均值就沒有關係了, 而是取決於隨機誤差, 反應這些觀察值差異程度的量j=1ni(XijXˉi)2\sum_{j=1}^{n_{i}}\left(X_{i j}-\bar{X}_{i}\right)^{2}, 其中Xˉi=(Xi1+Xi2++Xin)/ni,i=1,2,,r\bar{X}_{i}=\left(X_{i 1}+X_{i 2}+\cdots+X_{i n}\right) / n_{i}, \quad i=1,2, \cdots, r 。綜合所有的水平, 就可以得到誤差平方和的公式如下:
SE=i=1rj=1ni(XijXˉi)2S_{E}=\sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(X_{i j}-\bar{X}_{i }\right)^{2}
而上面兩者相減, 就會得到效應平方和SAS_A
SA=i=1rni(XˉiXˉ)2S_{A}=\sum_{i=1}^{r} n_{i}\left(\bar{X}_{i }-\bar{X}\right)^{2}
具體詳細推導這裏就不寫了, 可以看上面的文檔。由於Xˉi\bar X_i可以看作是每個水平的理論平均值的估計, 所以如果每個水平理論平均值越大, Xˉi\bar X_i的差異也會越大, 所以SAS_A可以衡量不同水平之間的差異程度。

通過上面的分析,我們會得到下面的結論:

  1. ST=SA+SES_T=S_A+S_E (這個分解式爲上面模型的方差分析)
  2. SEσ2χ2(nr)\frac{S_{E}}{\sigma^{2}} \sim \chi^{2}(n-r)
    這個是因爲SE=i=1rj=1ni(XijXˉi)2S_{E}=\sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(X_{i j}-\bar{X}_{i }\right)^{2}, 後面這部分的加和如果除以σ2\sigma^2的話會服從自由度爲ni1n_i-1的卡方(具體看第二篇卡方分佈的定義), 那麼前面又一個r水平的累加, 根據卡方分佈的可加性可得這個東西服從nrn-r的卡方
  3. H0H_0爲真的時候, SAσ2χ2(r1)\frac{S_{A}}{\sigma^{2}} \sim \chi^{2}(r-1)

我們上面說SAS_A可以衡量不同水平之間的差異程度。那麼我們直觀的看就是如果SAS_A比較大的時候, 說明不同水平之間的差異程度比較大了, 這時候就應該拒絕H0H_0, 但是我們看到上面的檢驗統計量裏面σ2\sigma^2我們是不知道的, 所以爲了抵消掉這個未知量, 我們最終構造的檢驗統計量爲:
F=SA/(r1)SE/(nr)F(r1,nr)F=\frac{S_{A} /(r-1)}{S_{E} /(n-r)} \sim F(r-1, n-r)
這時候構造出了F統計量。在原假設成立的時候, SAS_A是偏小的, 那麼當FF大於某個值的時候,我們就拒絕原假設。那麼這個值是多大呢? 我們會先給出一個顯著水平α\alpha, 如果FF大於了Fα(r1,nr)F_\alpha(r-1, n-r),這時候我們就拒絕原假設。 當然這裏面確實省略了很多細節過程, 因爲這個東西涉及到了假設檢驗的底層原理,由於時間原因這裏先不補, 後期如果有機會, 會補上假設檢驗的底層思想(這個得涉及參數估計, 檢驗統計量及常見分佈等知識), 所以這裏先記住這個結論, 這裏主要是看看如何用代碼實現單因素方差分析。

基於上面的分析, 會得到一個單因素試驗方差分析表:
在這裏插入圖片描述
這個表就把上面所有的分析都給總結好了。 但實際使用中, 我們肯定是不會手算的, 並且一般也不看F的值, 我們是看p值的。

下面就用python實現一下上面的那個索賠額的例子, 看看單因素方差分析是怎麼做的:

import pandas as pd
import numpy as np

from scipy import stats
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm

# 這是那四個水平的索賠額的觀測值
A1 = [1.6, 1.61, 1.65, 1.68, 1.7, 1.7, 1.78]
A2 = [1.5, 1.64, 1.4, 1.7, 1.75]
A3 = [1.6, 1.55, 1.6, 1.62, 1.64, 1.60, 1.74, 1.8]
A4 = [1.51, 1.52, 1.53, 1.57, 1.64, 1.6]

data = [A1, A2, A3, A4]
# 方差的齊性檢驗
w, p = stats.levene(*data)
if p < 0.05:
    print('方差齊性假設不成立')

# 成立之後, 就可以進行單因素方差分析
f, p = stats.f_oneway(*data)
print(f, p)      #  2.06507381767795 0.13406910483160134

上面這段程序應該很容易懂吧, 首先前面是把數據構造出來, 然後進行一個方差的齊性檢驗, 這個用stats.levene函數, 這個的作用是要保證方差在每個水平上某種程度上(顯著水平)是一致的, 這時候才能進行後面的均值分析, 因爲方差分析的實質是檢驗多個水平的均值是否有顯著差異,如果各個水平的觀察值方差差異太大,只檢驗均值之間的差異就沒有意義了,所以要進行方差齊性檢驗。

後面通過stats.f_oneway函數就可以直接算出檢驗假設的f值和p值。 我們這裏關注的是p值, 拿p值和給出的α\alpha(一般是0.05)比, 如果p>αp>\alpha, 我們就接受原假設, 否則拒絕原假設, 這個例子中p是0.134, 大於α, 故接受原假設,認爲不同的地區的索賠額沒有顯著差異。

所以單因素方差這塊一般是懂了原理之後, 用軟件去分析, 能看懂就算入門了。當然這個如果手算的話, 思路就是需要先求Xˉ,Xˉi\bar X, \bar X_i, 然後根據上面的公式計算SA,SES_A, S_E, 計算完了之後除以自由度然後相除得到FF值, 然後比較FFFα(n1,nr)F_\alpha(n-1, n-r)的大小, 當F>Fα(n1,nr)F>F_\alpha(n-1, n-r), 拒絕原假設, 否則接受原假設。 一定要注意這個FF值和PP值的比較標準是不同的。 因爲這是兩種假設檢驗的方法, P值比較的這種是基於P值法, 而F的那種是臨界值法。

上面的例子我們還可以進行那種單因素方差表的顯示格式:
首先改一下數據的格式

values = A1.copy()
groups = []
for i in range(1, len(data)):
    values.extend(data[i])

for i, j in zip(range(4), data):
    groups.extend(np.repeat('A'+str(i+1), len(j)).tolist())

df = pd.DataFrame({'values': values, 'groups': groups})
df

數據長這個樣子了,也是我們一般見到的pandas的形式:
在這裏插入圖片描述
通過下面的方式做單因素方差分析:

anova_res = anova_lm(ols('values~C(groups)', df).fit())
anova_res.columns = ['自由度', '平方和', '均方', 'F值', 'P值']
anova_res.index = ['因素A', '誤差']
anova_res        # 這種情況下看p值  >0.05 所以接受H0

結果如下:
在這裏插入圖片描述
這樣就會得到單因素方差分析表的格式。 當然, 爲了考慮的全面些, 我們應該評估檢驗的假設條件, 就是看看每個數據是不是真的服從正態。這裏就使用上一篇文章中學習到的判斷數據是不是服從正態的方法了Shapiro-Wilk test(小樣本情況下, 常用的正態檢驗方法):

# 數據格式張這樣
A1 = [1.6, 1.61, 1.65, 1.68, 1.7, 1.7, 1.78]
A2 = [1.5, 1.64, 1.4, 1.7, 1.75]
A3 = [1.6, 1.55, 1.6, 1.62, 1.64, 1.60, 1.74, 1.8]
A4 = [1.51, 1.52, 1.53, 1.57, 1.64, 1.6]

data = [A1, A2, A3, A4]

from scipy.stats import shapiro

def normal_judge(data):
	stat, p = shapiro(data)
	if p > 0.05:
		return 'stat={:.3f}, p = {:.3f}, probably gaussian'.format(stat,p)
	else:
		return 'stat={:.3f}, p = {:.3f}, probably not gaussian'.format(stat,p)

for d in data:
    print(normal_judge(d))

結果如下:

stat=0.942, p = 0.660, probably gaussian
stat=0.938, p = 0.655, probably gaussian
stat=0.850, p = 0.096, probably gaussian
stat=0.918, p = 0.489, probably gaussian

4. 雙因素方差分析

在很多中情況下, 只考慮一個指標對觀察值的影響顯然是不夠的, 這時就會用到多因素方差分析。 雙因素方差分析和多因素方差分析原理上一致, 所以下面就以雙因素方差分析爲例來看後面的原理(這個和單因素方差分析也有很多類似的地方), 文檔中給出的那種形式是假設兩個因素之間無交互的一種形式, 爲了使得知識全面, 下面給出一種兩個因素之間有交互的一種形式寫法作爲補充。

所謂雙因素方差分析, 就是有兩個因素A,BA, B作用於試驗的指標, 因素AArr個水平A1,A2,...ArA_1, A_2, ...A_r, 因素BBss個水平B1,B2...BsB_1, B_2...B_s. 現對因素A,BA,B的水平的每對組合(Ai,Bj)(A_i, B_j)都作tt次試驗,也會得到一個表:
在這裏插入圖片描述
並設
XijkN(μij,σ2),i=1,2,,r;j=1,2,,s;k=1,2,,tX_{i j k} \sim N\left(\mu_{i j}, \sigma^{2}\right), i=1,2, \cdots, r ; j=1,2, \cdots, s ; k=1,2, \cdots, t
這裏的XijkX_{ijk}獨立, 類比着單因素方差分析那裏, 我們就會先有下面的數學模型:
Xijk=μij+εijkεijkN(0,σ2), 各 εijk 獨立 i=1,2,,r;j=1,2,,sk=1,2,,t\begin{array}{l} X_{i j k}=\mu_{i j}+\varepsilon_{i j k} \\ \varepsilon_{i j k} \sim N\left(0, \sigma^{2}\right), \text { 各 } \varepsilon_{i j k} \text { 獨立 } \\ i=1,2, \cdots, r ; j=1,2, \cdots, s \\ k=1,2, \cdots, t \end{array}
這裏的XijkX_{ijk}表示的是第ii個A因素第jj個B因素下的第kk個觀測值。μij\mu_{ij}是組合(i,j)(i, j)下的所有觀測值的平均數(平均效應)。εijk\varepsilon_{i j k}是隨機誤差, 這個其實和單因素那裏的理解是一個意思, 上面的單因素的那個表格放在雙因素這裏就相當於這裏的其中一個小格子了。

那麼就開始引入一些新的公式, 因爲既然每個格子裏面有平均, 那麼每一行的格子和每一列的格子也會有平均, 整體上也會有平均, 所以下面就定義三個公式:
μ=1rsi=1rj=1sμijμi=1sj=1sμij,i=1,2,,rμj=1ri=1rμij,j=1,2,,s\begin{aligned} & \mu= \frac{1}{r s} \sum_{i=1}^{r} \sum_{j=1}^{s} \mu_{i j} \\ \mu_{i} &=\frac{1}{s} \sum_{j=1}^{s} \mu_{i j}, \quad i=1,2, \cdots, r \\ \mu_{ j} &=\frac{1}{r} \sum_{i=1}^{r} \mu_{i j}, \quad j=1,2, \cdots, s \end{aligned}

我們稱這裏的μ\mu爲總的平均。 再定義兩個公式:
αi=μiμ,i=1,2,,rβj=μjμ,j=1,2,,s\begin{array}{ll} \alpha_{i}=\mu_{i }-\mu, & i=1,2, \cdots, r \\ \beta_{j}=\mu_{ j}-\mu, & j=1,2, \cdots, s \end{array}
我們稱αi\alpha_i爲水平AiA_i上的效應, 稱βj\beta_j爲水平BjB_j的效應。下面嘗試理解一下上面的這些公式, 因爲符號有些多了, 對於雙因素水平, 我們會發現A因素的某個ii水平,B因素的某個jj水平下的第kk個觀測值XijkX_{ijk}其實會和Ai,BjA_i, B_j各個分水平效應有關, 也會和兩者的組合效應有關,也會和一切水平的總組合效應有關,再加上殘差項的影響。所以上面的uu的引入是爲了去衡量總的組合效應, αi\alpha_i的引入是爲了衡量因素A的水平ii帶來的影響, βj\beta_j衡量因素B水平jj帶來的影響。 很顯然,
i=1rαi=0,j=1sβj=0\sum_{i=1}^{r} \alpha_{i}=0, \quad \sum_{j=1}^{s} \beta_{j}=0
這兩個等式就會說明某些水平ii或者jj上的效應會高於總水平的平均效應, 也會低於總水平的平均效應。加和之後, 高的那部分和低的那部分就會抵消掉, 因爲總水平的平均效應是一個基準, 單個因素的各個水平上或許會高於或者低於總平均效應, 但是綜合起來還是回到那個基準。

那麼影響XijkX_{ijk}的還有一個AiA_i和上的效應會高於總的BjB_j的組合效應, 也就是兩者搭配起來聯合起作用, 我們看看這個是個啥東西, 由:
μij=μ+αi+βj+(μijμiμj+μ)\mu_{i j}=\mu+\alpha_{i}+\beta_{j}+\left(\mu_{i j}-\mu_{i \cdot}-\mu_{\cdot j}+\mu\right)
這是個恆成立等式, 我們會發現後面括號裏面那部分其實就是兩者的組合效應, 我們令其等於γij\gamma_{ij}, 此時上面的模型就可以化簡成最終的結果:
Xijk=μ+αi+βj+γij+εijkεijkN(0,σ2), 各 εijk 獨立 i=1,2,,r;j=1,2,,s;k=1,2,,ti=1rαi=0,j=1sβj=0,i=1rγij=0,j=1sγij=0}\left.\begin{array}{l} X_{i j k}=\mu+\alpha_{i}+\beta_{j}+\gamma_{i j}+\varepsilon_{i j k} \\ \varepsilon_{i j k} \sim N\left(0, \sigma^{2}\right), \text { 各 } \varepsilon_{i j k} \text { 獨立 } \\ i=1,2, \cdots, r ; j=1,2, \cdots, s ; k=1,2, \cdots, t \\ \sum_{i=1}^{r} \alpha_{i}=0, \sum_{j=1}^{s} \beta_{j}=0, \sum_{i=1}^{r} \gamma_{i j}=0, \sum_{j=1}^{s} \gamma_{i j}=0 \end{array}\right\}
這個就是雙因素試驗方差分析的數學模型。對於這個模型, 我們就會有三個假設檢驗的問題了:

  1. 因素A對於試驗結果是否帶來了顯著影響
    {H01:α1=α2==αr=0H11:α1,α2,,αr 不全爲0 \left\{\begin{array}{ll} H_{01}: & \alpha_{1}=\alpha_{2}=\cdots=\alpha_{r}=0 \\ H_{11}: & \alpha_{1}, \alpha_{2}, \cdots, \alpha_{r} \text { 不全爲0 } \end{array}\right.
  2. 因素B對於試驗結果是否帶來了顯著影響
    {H02:β1=β2==βs=0H12:β1,β2,,βs 不全爲0 \left\{\begin{array}{ll} H_{02}: & \beta_{1}=\beta_{2}=\cdots=\beta_{s}=0 \\ H_{12}: & \beta_{1}, \beta_{2}, \cdots, \beta_{s} \text { 不全爲0 } \end{array}\right.
  3. 兩者的組合對於試驗結果是否帶來了顯著影響
    {H03:γ11=γ12==γn=0H13:γ11,γ12,,γn 不全爲0 \left\{\begin{array}{ll} H_{03}: & \gamma_{11}=\gamma_{12}=\cdots=\gamma_{n}=0 \\ H_{13}: & \gamma_{11}, \gamma_{12}, \cdots, \gamma_{n} \text { 不全爲0 } \end{array}\right.

與單因素的情況類似, 我們依然是採用平方和分解的方式進行驗證。 首先我們得先計算四個平均值:

  • 因素A的ii水平因素B的jj水平的平均值:Xˉij=1tk=1tXijk\bar{X}_{i j}=\frac{1}{t} \sum_{k=1}^{t} X_{i j k}
  • 因素A的ii水平上的平均值:Xˉi=1stj=1sk=1tXijk\bar{X}_{i }=\frac{1}{s t} \sum_{j=1}^{s} \sum_{k=1}^{t} X_{i j k}
  • 因素B的jj水平平均值:Xˉj=1rti=1rk=1tXijk\bar{X}_{j}=\frac{1}{r t} \sum_{i=1}^{r} \sum_{k=1}^{t} X_{i j k}
  • 總平均值:Xˉ=1rsti=1rj=1sk=1tXijk\bar{X}=\frac{1}{r s t} \sum_{i=1}^{r} \sum_{j=1}^{s} \sum_{k=1}^{t} X_{i j k}

有了上面的平均值, 我們就可以得到偏差平方和了, 總偏差平方和如下:
在這裏插入圖片描述
就得到了
ST=SE+SA+SB+SA×BS_T=S_E+S_A+S_B+S_{A\times B}
其中SES_E稱爲誤差平方和SA,SBS_A, S_B分爲稱爲因素A和B的效應平方和SA×BS_{A\times B}成爲A和B的組合效應平方和

這裏也給出每個平方和的自由度, STS_T的自由度rst1rst-1SES_E自由度是rs(t1)rs(t-1)SAS_A自由度是r1r-1SBS_B自由度s1s-1SA×BS_{A\times B}自由度是(r1)(s1)(r-1)(s-1)。 那麼和單因素水平分析那樣, 我們可以得到每個假設下面的拒絕域形式:

  1. H01:α1=α2==αr=0H_{01}: \alpha_{1}=\alpha_{2}=\cdots=\alpha_{r}=0爲真的時候, FA=SA/(r1)SE/(rs(t1))F(r1,rs(t1))F_{A}=\frac{S_{A} /(r-1)}{S_{E} /(r s(t-1))} \sim F(r-1, r s(t-1)), 這時候取顯著水平爲α\alpha, 就會得到H01H_{01}的拒絕域:
    FA=SA/(r1)SE/(rs(t1))Fa(r1,rs(t1))F_{A}=\frac{S_{A} /(r-1)}{S_{E} /(r s(t-1))} \geqslant F_{a}(r-1, r s(t-1))
  2. H02H_{02}的拒絕域形式:
    FB=SB/(s1)SE/(rs(t1))Fa(s1,rs(t1))F_{B}=\frac{S_{B} /(s-1)}{S_{E} /(r s(t-1))} \geqslant F_{a}(s-1, r s(t-1))
  3. H03H_{03}的拒絕域形式:
    FA×B=SA×B/((r1)(s1))SE/(rs(t1))Fa((r1)(s1),rs(t1)\begin{aligned} F_{A \times B} &=\frac{S_{A \times B} /((r-1)(s-1))}{S_{E} /(r s(t-1))} & \geqslant F_{a}((r-1)(s-1), r s(t-1) \end{aligned}

依然會有個方差分析表:
在這裏插入圖片描述
和單因素方差分析那裏的思路是一樣的, 碰到具體問題的時候, 我們一般不會採用手算的形式, 如果手算的話, 思路和上面一樣, 就是先根據公式求四個平均值, 然後根據平均值求那四個平方和的東西, 求完了之後算三個F, 看看是不是落在了拒絕域裏面。 當然手算, 單因素方差分析還能算算, 雙因素這裏就很麻煩了, 並且實際應用裏面還可能是多因素方差分析,總不能全靠手算吧, 所以掌握軟件的方式進行方差分析就很有必要了,哈哈。下面依然是給出兩個實際應用中的例子:(一個無交互作用的, 一個有交互作用的), 當然有沒有交互作用, 要事先進行分析。

導入這次用到的包(依然是單因素分析時的olsanova_lm

import pandas as pd
import numpy as np

from scipy import stats
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm

# 這三個交互效果的可視化畫圖
from statsmodels.graphics.api import interaction_plot
import matplotlib.pyplot as plt
from pylab import mpl      # 顯示中文

# 這個看某個因素各個水平之間的差異
from statsmodels.stats.multicomp import pairwise_tukeyhsd
  1. 無交互作用的情況
    由於不考慮交互作用的影響,對每一個因素組合 (Ai,Bj)( A_i , B_j )只需進行一次獨立試驗,稱爲無重複試驗
    數據:考慮三種不同形式的廣告和五種不同的價格對某種商品銷量的影響。選取某市15家大超市,每家超市選用其中的一個組合,統計出一個月的銷量如下(設顯著性水平爲0.05):
    在這裏插入圖片描述
    下面進行雙因素方差分析, 簡要流程是,先用pandas庫的DataFrame數據結構來構造輸入數據格式。然後用statsmodels庫中的ols函數得到最小二乘線性迴歸模型。最後用statsmodels庫中的anova_lm函數進行方差分析。

    dic_t2=[{'廣告':'A1','價格':'B1','銷量':276},{'廣告':'A1','價格':'B2','銷量':352},
           {'廣告':'A1','價格':'B3','銷量':178},{'廣告':'A1','價格':'B4','銷量':295},
           {'廣告':'A1','價格':'B5','銷量':273},{'廣告':'A2','價格':'B1','銷量':114},
           {'廣告':'A2','價格':'B2','銷量':176},{'廣告':'A2','價格':'B3','銷量':102},
           {'廣告':'A2','價格':'B4','銷量':155},{'廣告':'A2','價格':'B5','銷量':128},
           {'廣告':'A3','價格':'B1','銷量':364},{'廣告':'A3','價格':'B2','銷量':547},
           {'廣告':'A3','價格':'B3','銷量':288},{'廣告':'A3','價格':'B4','銷量':392},
           {'廣告':'A3','價格':'B5','銷量':378}]
    df_t2=pd.DataFrame(dic_t2,columns=['廣告','價格','銷量'])
    df_t2
    

    數據長這樣:
    在這裏插入圖片描述

    # 方差分析
    price_lm = ols('銷量~C(廣告)+C(價格)', data=df_t2).fit()
    table = sm.stats.anova_lm(price_lm, typ=2)
    table
    

    結果如下:
    在這裏插入圖片描述
    可以發現這裏的p值都是小於0.05的, 所以我們要拒絕掉原假設, 即可認爲不同的廣告形式, 不同的價格均造成商品銷量的顯著差異。

    下面還可以看一下交互影響效果:

    fig = interaction_plot(df_t2['廣告'],df_t2['價格'], df_t2['銷量'],
                            ylabel='銷量', xlabel='廣告')
    

    結果如下:
    在這裏插入圖片描述
    再來分析一下單因素各個水平之間的顯著差異:

    # 廣告與銷量的影響  注意這個的顯著水平是0.01
    print(pairwise_tukeyhsd(df_t2['銷量'], df_t2['廣告'], alpha=0.01))         # 第一個必須是銷量, 也就是我們的指標 
    

    結果如下:
    在這裏插入圖片描述
    這個可以得到的結論是在顯著水平0.01的時候, A2和A3的p值小於0.01, reject=True, 即認爲A2和A3有顯著性差異。

  2. 有交互作用的情況
    由於因素有交互作用,需要對每一個因素組合 (Ai,Bj)( A_i , B_j ) 分別進行 tt(t2)( t ≥ 2 ) 重複試驗,稱這種試驗爲等重複試驗
    數據:概率論課本上的那個例子, 火箭的射程與燃料的種類和推進器的型號有關,現對四種不同的燃料與三種不同型號的推進器進行試驗,每種組合各發射火箭兩次,測得火箭的射程結果如下(設顯著性水平爲0.01):
    在這裏插入圖片描述
    第一步依然是先構造數據,

    dic_t3=[{'燃料':'A1','推進器':'B1','射程':58.2},{'燃料':'A1','推進器':'B1','射程':52.6},
           {'燃料':'A1','推進器':'B2','射程':56.2},{'燃料':'A1','推進器':'B2','射程':41.2},
           {'燃料':'A1','推進器':'B3','射程':65.3},{'燃料':'A1','推進器':'B3','射程':60.8},
           {'燃料':'A2','推進器':'B1','射程':49.1},{'燃料':'A2','推進器':'B1','射程':42.8},
           {'燃料':'A2','推進器':'B2','射程':54.1},{'燃料':'A2','推進器':'B2','射程':50.5},
           {'燃料':'A2','推進器':'B3','射程':51.6},{'燃料':'A2','推進器':'B3','射程':48.4},
           {'燃料':'A3','推進器':'B1','射程':60.1},{'燃料':'A3','推進器':'B1','射程':58.3},
           {'燃料':'A3','推進器':'B2','射程':70.9},{'燃料':'A3','推進器':'B2','射程':73.2},
           {'燃料':'A3','推進器':'B3','射程':39.2},{'燃料':'A3','推進器':'B3','射程':40.7},
           {'燃料':'A4','推進器':'B1','射程':75.8},{'燃料':'A4','推進器':'B1','射程':71.5},
           {'燃料':'A4','推進器':'B2','射程':58.2},{'燃料':'A4','推進器':'B2','射程':51.0},
           {'燃料':'A4','推進器':'B3','射程':48.7},{'燃料':'A4','推進器':'B3','射程':41.4},]
    df_t3=pd.DataFrame(dic_t3,columns=['燃料','推進器','射程'])
    df_t3.head()
    

    結果張這樣:
    在這裏插入圖片描述

    下面是方差分析:

    moore_lm = ols('射程~燃料+推進器+燃料:推進器', data=df_t3).fit()
    table = sm.stats.anova_lm(moore_lm, typ=1)
    table
    

    結果如下:
    在這裏插入圖片描述
    這裏得到的結論就是燃料的P值是大於0.01的, 而推進器和兩者組合的p值都小於0.01, 並且兩者的組合非常小, 這就說明燃料對於火箭的射程沒有顯著影響, 而後兩者都有顯著影響,兩者的交互作用更是高度顯著。

    下面是交互效應效果:

    fig = interaction_plot(df_t3['燃料'],df_t3['推進器'], df_t3['射程'],
                            ylabel='射程', xlabel='燃料') 
    

    結果如下:
    在這裏插入圖片描述
    從這個圖裏面可以看出, (A4, B1)和(A3, B2)組合的進程最好。 黃金搭檔。單因素差異性分析:

    print(pairwise_tukeyhsd(df_t3['射程'], df_t3['燃料']))
    

    結果:
    在這裏插入圖片描述
    都是False, 說明A因素各個水平之間無顯著差異。

兩個實驗到這裏就結束了, 這裏再補充兩點別的知識:

  1. ols函數裏面公式的寫法

    • '射程~C(燃料)+C(推進器)+C(燃料):C(推進器)' : 相當於射程是y(指標), 燃料和推進器是x(影響因素), 三項加和的前兩項表示兩個主效應, 第三項表示考慮兩者的交互效應, 不加C也可。
    • '射程~C(燃料, Sum)*C(推進器, Sum)'和上面效果是一致的, 星號在這裏表示既考慮主效應也考慮交互效應
      *'銷量~C(廣告)+C(價格)': 這個表示不考慮交互相應

    但是要注意, 考慮交互相應和不考慮交互相應導致的Se(殘差項)會不同, 所以會影響最終的結果。

  2. stats.anova_lm(moore_lm, typ=1)這裏面的typ參數, 這個參數我嘗試還沒有完全搞明白到底是什麼意思, 這個參數有1,2,3 三個可選項, 分別代表着不同的偏差平方和的計算方法, 我在第二個實驗中嘗試過改這個參數,改成1的時候發現就加了一列mean_sq, 然後其他的沒變。
    在這裏插入圖片描述
    改成3的時候發現加一行Intercept, 並且此時燃料和推進器的數據都發生了變化。
    在這裏插入圖片描述
    然後查資料也沒弄明白這三個的具體區別, 具體資料Anova – Type I/II/III SS explained, 大意就是1類型不適合樣本不均衡數據, 2不適合交互效應的數據, 如果沒有交互效果就選2, 否則就選3。這裏貼出結論:
    在這裏插入圖片描述
    但是根據上面的實驗,感覺和這個說的對不起來。 如果有看明白的,也歡迎指點一下!

5. 總結

方差分析這塊到這裏就結束了, 隨着這篇文章的結束也意味着概率統計的知識串聯也到了尾聲, 簡單的回顧一下本篇的內容, 這篇文章主要是在實踐的角度進行的分析, 方差分析在統計中還是很常用的, 比較適合類別因素對於數值指標的影響程度, 首先從單因素方差分析入手, 這個只考慮了一個因素對於指標的影響, 先分析了原理,然後基於python進行了實現。 實際應用中,一般是會點原理,然後使用工具實現方差分析,會看結果,這樣就算入門了。 然後就是進行雙因素方差的分析, 重點補充了帶有交互效應的形式原理和python實現, 這樣與文檔形成一種互補。 最後是帶有交互和不帶交互的雙因素方差的實驗。

實際應用中, 或許可以通過這種方法去分析類別特徵的重要性或者關聯性,以及類別和類別特徵之間的交互作用等。 這個由於邏輯很清晰就不用思維導圖了。

簡單梳理一下這四篇文章的一個邏輯關係,用了大約10天的時間跟着Datawhale的組隊學習完成了這四篇文章, 基本上能夠把概率統計的知識串一遍, 從概率統計基礎(一): 隨機變量與隨機事件的故事開始, 這篇文章是有關概率論的基本內容和基礎, 包括統計的一些基本概念, 一些變量分佈的初識, 第二篇文章概率統計基礎(二): 數理統計與描述性統計這個是整理的數理統計的一些內容, 主要是從實際應用的角度出發, 忽略掉了一些底層原理, 這兩者的關係是前者是從總體出發,知分佈然後探究性質。 而後者是從樣本出發, 根據統計性質去猜總體的分佈和規律。 第三篇文章概率統計基礎(三):常見分佈與假設檢驗類似於在前兩篇裏面挑出了很重要的某個點進行的詳述, 常見分佈是概率論的內容, 而這些分佈對於數據分析來講非常的關鍵。 假設檢驗是統計的內容, 也是統計核心之一。 最後一篇的方差分析, 是從實用的角度出發去進行數理統計的實戰。

概率統計的複習到這裏估計就先告一段落了, 後面如果再遇到新的知識,繼續在這四篇文章中進行補充, 再次感謝Datawhale的組隊學習,這次又收穫了不少哈哈。

你看, 天上太陽正晴, 不如我們一起吧 😉

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章