COM6005 Statistical Modeling · Module 3b
Tabular Data & Chi-squared Tests
COM6005 · Module 3b · Source: Module3b_Chi-square-L02_complete.pdf (24 slides)
Contents · 7 sections
🎯 本講重點 (Learning outcomes)
- 由 categorical data 整 one-way table(
value_counts)同 two-way contingency table(pd.crosstab);用pd.cut將 numerical 轉 categorical。 - 用 stacked / side-by-side bar chart 視覺化 tabular data。
- Chi-squared test for independence:expected count 、 statistic、、查 chi-square table、
stats.chi2_contingency。 - Chi-squared goodness-of-fit: 由 嘅 distribution 計、、
stats.chisquare。
⭐ 考試必溫 Top-5
- Expected count:;例:Local Math = 300 × 1000/1250 = 240。
- ;例子 → reject independence。
- df:independence = ;goodness-of-fit = 。
- 查表:、 → 5.991 =
chi2.ppf(0.95, 2); → 11.071。 - Goodness-of-fit 朱古力例:,, → do not reject(uniform)。
1. One-way 同 two-way table
Slide 3:
- One-way table:一欄 categorical data,數每個 category 嘅 frequency。
- Two-way (contingency) table:兩欄 categorical data,數每個 category 組合嘅 joint frequency。
Slide 4 數據(10 條 comment):
| Comment | Rating | Number of customers |
|---|---|---|
| 1 | Good | Few |
| 2 | Bad | Few |
| 3 | Good | Many |
| 4 | Average | Many |
| 5 | Average | Many |
| 6 | Bad | Few |
| 7 | Average | Few |
| 8 | Good | Many |
| 9 | Average | Many |
| 10 | Bad | Many |
import pandas as pd
x = ["G","B","G","A","A","B","A","G","A","B"] # Rating
y = ["F","F","M","M","M","F","F","M","M","M"] # Number of customers (Few / Many)
freq = pd.Series(x).value_counts() # one-way table:A 4, G 3, B 3
joint_freq = pd.crosstab(pd.Series(x), pd.Series(y)) # two-way table
得到嘅 two-way table:
| Rating \ Customers | F (Few) | M (Many) | Row total |
|---|---|---|---|
| A (Average) | 1 | 3 | 4 |
| B (Bad) | 2 | 1 | 3 |
| G (Good) | 1 | 2 | 3 |
| Column total | 4 | 6 | 10 |
1.1 Numerical → Categorical:pd.cut(slide 6)
向觀眾展示數據時,用 young / middle / senior 呢類 label 比抽象數字易明。
x = [68, 32, 47, 52, 15, 73, 67, 45, 24, 39]
age_labels = ["young", "middle", "senior"]
age_group = pd.cut(x, bins=[0, 35, 55, float('inf')], labels=age_labels)
# (0,35] → young;(35,55] → middle;(55,inf) → senior
# 結果:senior, young, middle, middle, young, senior, senior, middle, young, middle
pd.Series(age_group).value_counts() # middle 4, young 3, senior 3
pd.cut 預設 bins 係 右閉 (a, b]:35 歲會入 young,唔係 middle。邊界值嘅歸類係常見考點/bug。
COM6001 pandas 嘅 value_counts()、pd.crosstab()、pd.cut()(binning / discretization);COM6004 Chapter 2 Data preprocessing 嘅 discretization 同 binarization 都係同一回事。COM6002 SQL 嘅 GROUP BY rating, customers + COUNT(*) 就係 two-way table。
2. Statistical graphics for tabular data
import matplotlib.pyplot as plt
ft = pd.crosstab(pd.Series(x), pd.Series(y))
ft.index.name = None
ft.columns.name = None
fig, axs = plt.subplots(2, 2, figsize=(10, 8))
ft.T.plot(kind='bar', ax=axs[0, 0], stacked=True, rot=0) # 直立 stacked bar
ft.T.plot(kind='bar', ax=axs[0, 1], stacked=False, rot=0) # 直立 side-by-side bar
ft.T.plot(kind='barh', ax=axs[1, 0], stacked=True, legend=False) # 橫向 stacked
ft.T.plot(kind='barh', ax=axs[1, 1], stacked=False, legend=False) # 橫向 side-by-side
plt.show()
Slide 8 嘅四幅圖(x 軸 F / M,顏色 A / B / G):stacked 版顯示 F 總數 4(A 1、B 2、G 1)、M 總數 6(A 3、B 1、G 2);side-by-side 版就將三個 rating 並排比較。ft.T(transpose)令 customers (F/M) 做 x 軸、rating 做顏色。
Stacked 易睇每組總數同組成比例;side-by-side 易比較同一 category 喺唔同組之間嘅大細。
2.1 由 table 到 test(slide 9)
| Table | 問題 | Test | |
|---|---|---|---|
| One-way | Categorical data 有冇某個 distribution pattern(例如所有 categories equally likely)? | Chi-square goodness-of-fit | :符合指定 distribution;:唔符合 |
| Two-way | 兩個 categorical variables 有冇關係? | Chi-square test for independence | :independent;:dependent |
3. Chi-squared test for independence
Slides 10–11:本地生同外地生揀主修科目嘅偏好有冇分別?
- Situation:兩欄 categorical data。
- X = origin(Local / Foreign);Y = first subject choice(Math / Computer / Literature)。
- Question:Is it evident that X and Y are related?
- :independent;:related / dependent。
3.1 Observed 同 expected counts(slide 12)
| Local | Foreign | Subtotals | |
|---|---|---|---|
| Math | 250 | 50 | |
| Computer | 400 | 50 | |
| Literature | 350 | 150 | |
| Subtotals |
Idea:如果冇 dependence,揀 Math 嘅 300 個學生應該按 Local : Foreign = 1000 : 250 嘅比例分配。Local 比例 = 1000/1250,所以 Expected Local Math = 300 × 1000/1250 = 240。
(slide 13)如果冇 dependence, 應該接近 。 大過 critical value → dependence 證據強。Critical value 喺 chi-square table 查;建議用 p-value:p-value < → reject “:The two columns are independent”。
- Hypotheses::origin 同 subject choice independent;:dependent。
- 。
- Expected counts:
(檢查:每行、每欄 expected 總和 = observed 總和。)E Local Foreign Math 300×1000/1250 = 240 300×250/1250 = 60 Computer 450×1000/1250 = 360 450×250/1250 = 90 Literature 500×1000/1250 = 400 500×250/1250 = 100 - Test statistic:
Cell O E Math, Local 250 240 100/240 = 0.417 Math, Foreign 50 60 100/60 = 1.667 Computer, Local 400 360 1600/360 = 4.444 Computer, Foreign 50 90 1600/90 = 17.778 Literature, Local 350 400 2500/400 = 6.25 Literature, Foreign 150 100 2500/100 = 25 55.56 - Critical value:; → 5.991。
- Decision:55.56 > 5.991()→ reject 。結論:學生來源同主修科目選擇有關——外地生較多揀 Literature(150 vs 預期 100)、較少揀 Computer(50 vs 預期 90)。
每格 係「意外程度」:差距越大、相對 expected 越大,貢獻越多。Foreign × Literature(25)同 Foreign × Computer(17.78)貢獻最大,即係 dependence 主要嚟自外地生嘅選科模式。
3.2 查 chi-square table(slides 14–15)
Slide 14 嘅 chi-square table:column = Upper Tail Areas (),row = Degrees of Freedom;圖中右尾陰影面積 = ,左邊 。圈住嘅值:、 → 5.991。
- Degree of freedom (independence test)= 。
- :5%(較低標準 reject )或 1%(較高標準)。
- 例:、 → df = 2; → critical value = 5.991 =
scipy.stats.chi2.ppf(0.95, 2)(chi-square distribution 嘅 95% quantile)。
| df | ||||
|---|---|---|---|---|
| 1 | 2.706 | 3.841 | 5.024 | 6.635 |
| 2 | 4.605 | 5.991 | 7.378 | 9.210 |
| 3 | 6.251 | 7.815 | 9.348 | 11.345 |
| 4 | 7.779 | 9.488 | 11.143 | 13.277 |
| 5 | 9.236 | 11.071 | 12.833 | 15.086 |
| 6 | 10.645 | 12.592 | 14.449 | 16.812 |
- Chi-square test 永遠係 right-tailed(,越大越唔似 ),唔需要 。
- df 唔係 ,係 ;r、c 唔計 subtotal 行/欄。
- 一定要用 counts(次數),唔可以用 percentage 代入公式。
- (補充)每格 expected count 最好 ,否則 chi-square approximation 唔可靠——slide 4 嘅 10 筆 rating 數據 expected 只有 1.2–2.4,只適合示範 code。
3.3 Python(slides 16–18)
import numpy as np
from scipy import stats
# 方法 1:直接入兩欄 raw data → 先 crosstab
contingency_table = pd.crosstab(pd.Series(x), pd.Series(y))
chi2, p, dof, expected = stats.chi2_contingency(contingency_table)
# 方法 2:直接入 joint frequency table
Ft = np.array([[250, 50], [400, 50], [350, 150]])
chi2, p, dof, expected = stats.chi2_contingency(Ft)
# Chi2ContingencyResult(statistic=55.5555, pvalue=8.635e-13, dof=2,
# expected_freq=array([[240., 60.], [360., 90.], [400., 100.]]))
chi2 > chi2.ppf(0.95, 2) # statistic 大過 critical value
chi2.cdf(chi2, 2) > 0.95 # cumulative prob 大過 95%
1 - chi2.cdf(chi2, 2) < 0.05 # p-value 細過 α
1 - chi2.cdf(chi2, 2) 就係 p-value。Python 嘅 scipy.stats.chi2_contingency() 一次過做晒。
Slide 16 寫 “In chisq.test()…”——chisq.test() 係 R 嘅函數名;Python 對應係 stats.chi2_contingency()。另外 2×2 table 時 scipy 預設做 Yates' continuity correction(correction=True),所以結果會同手計少少唔同。
4. Chi-squared goodness-of-fit
Slide 20:
- Situation:一欄 categorical data。
- Example:雜錦朱古力嘅顏色係咪均勻分佈(evenly distributed)?
- Question:Is it evident that the distribution of (yellow, red, orange, brown, blue, green) is not even?
- :The distribution is even,即 (1/6, 1/6, 1/6, 1/6, 1/6, 1/6)。:The distribution is not even (uniformly distributed)。
- Experiment:買一包嚟數。
| Yellow | Red | Orange | Brown | Blue | Green | Total |
|---|---|---|---|---|---|---|
| 20 () | 13 () | 12 () | 12 () | 18 () | 25 () | 100 |
- Hypotheses::6 種顏色各佔 1/6;:唔係均勻。
- 。
- Expected:uniform → 每色 。
- Test statistic:
Colour O E Yellow 20 16.67 0.667 Red 13 16.67 0.807 Orange 12 16.67 1.307 Brown 12 16.67 1.307 Blue 18 16.67 0.107 Green 25 16.67 4.167 8.36 - Critical value:; → 11.071(slide 22 圈住)。
- Decision:8.36 < 11.071(p-value = 0.1374 > 0.05)→ is not rejected。結論(slide 23):We cannot statistically reject the null hypothesis that the distribution is uniform。
from scipy import stats
obs = [20, 13, 12, 12, 18, 25]
stats.chisquare(obs) # 預設 expected = 平均分配
# Power_divergenceResult(statistic=8.36, pvalue=0.1374)
stats.chisquare(obs, f_exp=[100/6]*6) # 明確指定 expected
stats.chi2.ppf(0.95, 5) # 11.071
1 - stats.chi2.cdf(8.36, 5) # p-value 0.1374
Slide 24:同樣三個等價 rule():chi2 > chi2.ppf(0.95, 5) ⇔ chi2.cdf(chi2, 5) > 0.95 ⇔ 1 - chi2.cdf(chi2, 5) < 0.05;Python 用 stats.chisquare()。
- Goodness-of-fit (類別數 − 1),唔係 。
- 唔一定係 uniform:例如 可以係 (0.3, 0.2, 0.2, 0.1, 0.1, 0.1),咁 ,要用
f_exp=指定。 - “Not rejected” ≠ 「證明係 uniform」,只係冇足夠證據話唔係。
5. Independence vs Goodness-of-fit 比較
| Test for independence | Goodness-of-fit | |
|---|---|---|
| 數據 | 兩欄 categorical(two-way table) | 一欄 categorical(one-way table) |
| 兩個 variables independent | 數據符合指定 distribution(例如 uniform) | |
| Expected | ||
| Statistic | ||
| df | ||
| Python | stats.chi2_contingency(table) | stats.chisquare(obs, f_exp) |
| Slide 例子 | Origin × Subject:,,crit 5.991 → reject | 朱古力顏色:,,crit 11.071 → not reject |
COM6004 Classification 做 feature selection 時,可以用 chi-square test 揀同 class label 最有關(dependent)嘅 categorical attributes(例如 scikit-learn SelectKBest(chi2));COM6004 Chapter 2 嘅 correlation analysis for nominal data 亦係用 。
Slide 10 係「本地生 vs 外地生」嘅示意圖頁,冇額外文字;slides 2、19 係分節標題頁。
自我測驗 Self-test
Q1. 2×2 table:男 吸煙 30、不吸煙 70;女 吸煙 20、不吸煙 80。求所有 expected counts。
Row totals:男 100、女 100;column totals:吸煙 50、不吸煙 150;。E(男, 吸煙) = 100 × 50/200 = 25;E(男, 不吸煙) = 75;E(女, 吸煙) = 25;E(女, 不吸煙) = 75。
Q2. 繼續 Q1:計 (不用 continuity correction),df = ?, 結論?
;;;;。,critical 3.841。2.667 < 3.841 → do not reject:冇足夠證據顯示性別同吸煙有關。
Q3. 一個 4×3 contingency table 嘅 df 係幾多? critical value?
; → 16.812。
Q4. 骰子擲 60 次:1–6 點分別出現 8, 9, 12, 11, 6, 14 次。用 檢驗骰子是否公平。
。。,critical 11.071。4.2 < 11.071 → do not reject:冇證據顯示骰子唔公平。
Q5. 某品牌聲稱顏色比例係 Red 40%、Blue 30%、Green 30%。抽 200 粒:Red 95、Blue 50、Green 55。寫 expected 同 。
。。,critical 5.991 → do not reject。Python:stats.chisquare([95,50,55], f_exp=[80,60,60])。
Q6. 寫出三個等價嘅 decision rule(df = 2,)。
chi2 > chi2.ppf(0.95, 2);chi2.cdf(chi2, 2) > 0.95;1 - chi2.cdf(chi2, 2) < 0.05。
Q7. pd.cut([35, 55, 56], bins=[0, 35, 55, float('inf')], labels=["young","middle","senior"]) 結果係咩?
young, middle, senior(bins 右閉:,,)。
Q8. 點解 chi-square test 唔分 one-tailed / two-tailed?
係平方和,永遠 ;任何方向嘅偏離( 或 )都會令 變大,所以 rejection region 只喺右尾。
一頁總結 Cheat sheet
- One-way table:
pd.Series(x).value_counts();two-way:pd.crosstab(x, y);binning:pd.cut(x, bins, labels)(右閉)。 - Plot:
ft.T.plot(kind='bar'/'barh', stacked=True/False)。 - Independence: independent;;;
chi2_contingency。 - Goodness-of-fit: 指定 distribution;;;
chisquare。 - ;永遠 right-tailed;用 counts。
- Critical:df 1 → 3.841|df 2 → 5.991|df 5 → 11.071();
chi2.ppf(0.95, df)。 - p-value =
1 - chi2.cdf(stat, df); → reject。 - 例 1:Local/Foreign × Math/Computer/Lit:; → reject(dependent)。
- 例 2:朱古力 6 色:;、 → not reject(uniform)。