# 置換檢驗
> 原文:[https://www.textbook.ds100.org/ch/18/hyp_introduction_part2.html](https://www.textbook.ds100.org/ch/18/hyp_introduction_part2.html)
```
# HIDDEN
# Clear previously defined variables
%reset -f
# Set directory for data loading to work properly
import os
os.chdir(os.path.expanduser('~/notebooks/18'))
```
```
# HIDDEN
import warnings
# Ignore numpy dtype warnings. These warnings are caused by an interaction
# between numpy and Cython and can be safely ignored.
# Reference: https://stackoverflow.com/a/40846742
warnings.filterwarnings("ignore", message="numpy.dtype size changed")
warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
%matplotlib inline
import ipywidgets as widgets
from ipywidgets import interact, interactive, fixed, interact_manual
import nbinteract as nbi
sns.set()
sns.set_context('talk')
np.set_printoptions(threshold=20, precision=2, suppress=True)
pd.options.display.max_rows = 7
pd.options.display.max_columns = 8
pd.set_option('precision', 2)
# This option stops scientific notation for pandas
# pd.set_option('display.float_format', '{:.2f}'.format)
```
在一些情況下,我們希望執行一個置換測試,以測試一個假設并了解更多關于世界的信息。置換測試是一種非常有用的非參數測試類型,它允許我們在不進行低于傳統參數測試的統計假設的情況下進行推論。
排列推理的一個有見地的例子是通過無聊、奧托博尼和斯塔克(2016)對學生對教學(集合)數據的評估進行復查。在這個實驗中,47 名學生被隨機分配到四個部分中的一個。有兩個助教分別教兩個部分;一個助教是男性,另一個是女性。在其中兩個部分中,教學助理是用他們的實際姓名介紹的。在其他兩個部分中,助手們交換了名字。
```
#HIDDEN
from IPython.display import Image
display(Image('student_setup.png'))
```

學生們從未面對面見到過助教。相反,他們通過在線論壇與學生互動。家庭作業的返回是協調的,這樣所有學生都能同時收到分數/反饋。這兩個助教的經驗水平也相當。在課程結束時,學生們會評估作業的及時性。作者想調查性別認知是否對集合評估/評分有任何影響。
### 實驗裝置
我們使用 0.05 的 p 值截止值進行假設檢驗。
在我們的**模型**中,每個助教有兩個可能的評分,每個學生一個針對每個感知到的性別。每個學生被分配到任何一對(性別,感知性別)的機會均等。最后,學生們相互獨立地評估他們的助教。
本實驗的**無效假設**是感知性別對集合沒有影響,任何觀察到的評分差異都是偶然的。換言之,無論是男性還是女性,對每個助教的評估都應保持不變。這意味著每個助教實際上只有一個可能的評分來自每個學生。
另一種假設是感知性別對集合有影響。
**檢驗統計**是每個 TA 的感知男性和感知女性評分的平均值差異。直觀地說,如果性別對收視率沒有影響,我們預計這將接近 0。我們可以正式寫下:
$$\mu \文本感知女性-\mu \文本感知男性$$
哪里:
$$ \begin{aligned} \mu_{\text{perceived female}} &= \frac {\sum_{j=1}^{n_1} x_{1j} + \sum_{j=1}^{n_3} x_{3j}}{{n_1} + {n_3}} \\ \mu_{\text{perceived male}} &= \frac {\sum_{j=1}^{n_2} x_{2j} + \sum_{j=1}^{n_4} x_{4j}}{{n_2} + {n_4}} \end{aligned} $$
其中,$n i$是$i$th 組的學生人數,$x ij 是第 i 組的第 j 個學生的評分。
為了確定性別對集合評分是否有影響,我們進行了置換測試,以在無效假設下生成檢驗統計量的經驗分布。我們遵循以下步驟:
1. 為同一助教下的學生排列感知的性別標簽。請注意,在上圖中,我們在左右兩半部分進行了調整。
2. 計算確定的女性和確定的男性群體的平均得分差異。
3. 重復多次,為兩組的平均分數差創建一個近似的抽樣分布。
4. 使用近似分布來估計看到測試統計數據比觀察到的更極端的可能性。
理解置換測試在這種情況下的合理性是很重要的。在空模型下,每個學生都會給他們的助教相同的分數,而不管他們的性別。簡單的隨機分配意味著,對于一個給定的助教,無論他們被視為男性還是女性,他們的所有評分都有平等的機會出現。因此,如果無效假設為真,那么排列性別標簽對評分應該沒有影響。
### 數據[?](#The-Data)
我們從下面的學生和性別數據開始。這些數據是美國一所大學的 47 名參加在線課程的學生的人口普查。
```
#HIDDEN
student_eval = (
pd.read_csv('StudentRatingsData.csv')
.loc[:, ["tagender", "taidgender", "prompt"]]
.dropna()
.rename(columns={'tagender': 'actual', 'taidgender': 'perceived'})
)
student_eval[['actual', 'perceived']] = (
student_eval[['actual', 'perceived']]
.replace([0, 1], ['female', 'male'])
)
student_eval
```
| | 實際的 | 感知 | 促使 |
| --- | --- | --- | --- |
| 零 | 女性的 | 男性的 | 四 |
| --- | --- | --- | --- |
| 1 個 | female | male | 五 |
| --- | --- | --- | --- |
| 二 | female | male | 5.0 |
| --- | --- | --- | --- |
| …… | …… | ... | ... |
| --- | --- | --- | --- |
| 四十三 | male | female | 4.0 |
| --- | --- | --- | --- |
| 四十四 | male | female | 二 |
| --- | --- | --- | --- |
| 45 歲 | male | female | 4.0 |
| --- | --- | --- | --- |
43 行×3 列
這些列具有以下含義:
**實際**——助教的真實性別
**感知**——呈現給學生的性別
**提示**——HW 的及時性等級從 1 到 5
在分析和繪制了下面實驗的評分數據后,兩組學生之間似乎存在差異,感知到的女性評分低于男性評分;然而,我們需要一個更正式的假設測試,以確定這種差異是否僅僅是由于隨機性導致的。m 學生作業。
```
# HIDDEN
avg_ratings = (student_eval
.loc[:, ['actual', 'perceived', 'prompt']]
.groupby(['actual', 'perceived'])
.mean()
.rename(columns={'prompt': 'mean prompt'})
)
avg_ratings
```
| | | 平均提示 |
| --- | --- | --- |
| actual | perceived | |
| --- | --- | --- |
| 女性的 | 女性的 | 3.75 條 |
| --- | --- | --- |
| 男性的 | 四點三三 |
| --- | --- |
| 男性的 | female | 三點四二 |
| --- | --- | --- |
| male | 四點三六 |
| --- | --- |
```
# HIDDEN
fig, ax = plt.subplots(figsize=(12, 7))
ind = np.arange(4)
plt.bar(ind, avg_ratings["mean prompt"])
ax.set_xticks(ind)
ax.set_xticklabels(['Female (Percieved Female)', 'Female (Percieved Male)', 'Male (Percieved Female)', "Male (Percieved Male)"])
ax.set_ylabel('Average Promptness Rating')
ax.set_xlabel('Actual/Percieved Gender')
ax.set_title('Average Rating Per Actual/Percieved Gender')
plt.show()
```

### 進行實驗
我們將計算確定的男性和確定的女性群體的平均評分之間觀察到的差異:
```
def stat(evals):
'''Computes the test statistic on the evals DataFrame'''
avgs = evals.groupby('perceived').mean()
return avgs.loc['female', 'prompt'] - avgs.loc['male', 'prompt']
```
```
observed_difference = stat(student_eval)
observed_difference
```
```
-0.79782608695652169
```
我們發現差異是-0.8-在這種情況下,女性的平均評分從 1 分到 5 分低了近 1 分。考慮到評級的規模,這種差異似乎相當大。通過執行排列測試,我們將能夠發現在空模型下觀察到如此大差異的機會。
現在,我們可以為每個 TA 排列感知的性別標簽,并計算 1000 次測試統計:
```
def shuffle_column(df, col):
'''Returns a new copy of df with col shuffled'''
result = df.copy()
result[col] = np.random.choice(df[col], size=len(df[col]))
return result
```
```
repetitions = 1000
gender_differences = np.array([
stat(shuffle_column(student_eval, 'perceived'))
for _ in range(repetitions)
])
```
我們使用下面的排列圖繪制得分差異的近似抽樣分布,用紅色虛線顯示觀察值。
```
# HIDDEN
differences_df = pd.DataFrame()
differences_df["gender_differences"] = gender_differences
gender_hist = differences_df.loc[:, "gender_differences"].hist(normed=True)
gender_hist.set_xlabel("Average Gender Difference (Test Statistic)")
gender_hist.set_ylabel("Percent per Unit")
gender_hist.set_title("Distribution of Gender Differences")
plt.axvline(observed_difference, c='r', linestyle='--');
```
```
<matplotlib.lines.Line2D at 0x1a1b34e3c8>
```

```
# HIDDEN
differences_df = pd.DataFrame()
differences_df["gender_differences"] = gender_differences
gender_hist = differences_df.loc[:, "gender_differences"].hist(normed=True)
gender_hist.set_xlabel("Average Gender Difference (Test Statistic)")
gender_hist.set_ylabel("Percent per Unit")
gender_hist.set_title("Distribution of Gender Differences")
plt.axvline(observed_difference, c='r', linestyle='--')
```
```
<matplotlib.lines.Line2D at 0x1a1b256ef0>
```

根據下面的計算,在 1000 個模擬中,只有 18 個的差異至少與觀察到的差異一樣大。因此,我們的 p 值小于 0.05 閾值,我們拒絕了零假設,而贊成替代。
```
#Sample Distribution Parameters
sample_sd = np.std(gender_differences)
sample_mean = np.mean(gender_differences)
#Computing right-hand extreme value
num_sd_away = (sample_mean - observed_difference)/sample_sd
right_extreme_val = sample_mean + (num_sd_away*sample_sd)
#Calculate P-value
num_extreme_left = np.count_nonzero(gender_differences <= observed_difference)
num_extreme_right = np.count_nonzero(gender_differences >= right_extreme_val)
empirical_P = (num_extreme_left + num_extreme_right) / repetitions
empirical_P
```
```
0.018
```
### 結論[?](#Conclusion)
通過這一排列測試,我們發現集合對女教師的偏見是一個數額大,統計意義重大。
還有其他一些研究也在教學評估中測試了偏差。根據 Dring,Ottoboni&Stark 2016,進行了其他幾個參數測試,假設男女教師的評級是來自具有相同方差的正態分布人群的獨立隨機樣本;這種類型的實驗設計與提出了零假設,導致 p 值可能產生誤導。
相比之下,無聊的 Ottoboni&Stark 2016 使用了基于隨機分配學生到班級的排列測試。回想一下,在排列測試期間,我們沒有對數據的分布做任何基本假設。在這個實驗中,我們沒有假設學生、集合分數、成績或任何其他變量包含任何群體的隨機樣本,更不用說具有正態分布的群體。
在檢驗假設時,仔細選擇實驗設計和無效假設是非常重要的,以獲得可靠的結果。
- 一、數據科學的生命周期
- 二、數據生成
- 三、處理表格數據
- 四、數據清理
- 五、探索性數據分析
- 六、數據可視化
- Web 技術
- 超文本傳輸協議
- 處理文本
- python 字符串方法
- 正則表達式
- regex 和 python
- 關系數據庫和 SQL
- 關系模型
- SQL
- SQL 連接
- 建模與估計
- 模型
- 損失函數
- 絕對損失和 Huber 損失
- 梯度下降與數值優化
- 使用程序最小化損失
- 梯度下降
- 凸性
- 隨機梯度下降法
- 概率與泛化
- 隨機變量
- 期望和方差
- 風險
- 線性模型
- 預測小費金額
- 用梯度下降擬合線性模型
- 多元線性回歸
- 最小二乘-幾何透視
- 線性回歸案例研究
- 特征工程
- 沃爾瑪數據集
- 預測冰淇淋評級
- 偏方差權衡
- 風險和損失最小化
- 模型偏差和方差
- 交叉驗證
- 正規化
- 正則化直覺
- L2 正則化:嶺回歸
- L1 正則化:LASSO 回歸
- 分類
- 概率回歸
- Logistic 模型
- Logistic 模型的損失函數
- 使用邏輯回歸
- 經驗概率分布的近似
- 擬合 Logistic 模型
- 評估 Logistic 模型
- 多類分類
- 統計推斷
- 假設檢驗和置信區間
- 置換檢驗
- 線性回歸的自舉(真系數的推斷)
- 學生化自舉
- P-HACKING
- 向量空間回顧
- 參考表
- Pandas
- Seaborn
- Matplotlib
- Scikit Learn