其中,??為第?R行第?C列的期望頻數,??為第?R行的總數,??為第?C列的總數,??E為總樣本量
計算卡方統計量
卡方統計量計算公式:
其中,??O為第??i行第??j列的觀測頻數,??E為第?i行第?i列的期望頻數
確定自由度
自由度計算公式:
其中,??為行數,??為列數
確定?K值
根據卡方統計量和自由度,查卡方分布表或使用統計軟件計算 值
結論
如果 值小于顯著性水平(例如 ),拒絕原假設,認為兩個分類變量之間存在顯著關聯
使用場景
用于檢驗兩個分類變量是否獨立(案例:性別-男性和女性,是否影響一個人是否吸煙-吸煙或不吸煙,驗證性別和吸煙習慣之間是否存在關聯)
注意事項
代碼實現
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import chi2_contingency
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 生成數據
np.random.seed(0)
products = np.random.choice(['Electronics', 'Clothing', 'Home Decor'], size=100)
regions = np.random.choice(['North', 'South', 'East', 'West'], size=100)
# 創建一個新的數據集
data = {'Product_Category': products, 'Sales_Region': regions}
df = pd.DataFrame(data)
# 創建交叉表
contingency_table = pd.crosstab(df['Product_Category'], df['Sales_Region'])
# 進行卡方獨立性檢驗
chi2, p, dof, expected = chi2_contingency(contingency_table)
print("Chi2 Statistic:", chi2)
print("p-value:", p)
print("Degrees of Freedom:", dof)
# 可視化實際頻數的交叉表
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.heatmap(contingency_table, annot=True, fmt='d', cmap='YlGnBu')
plt.title('實際頻數的交叉表')
# 可視化期望頻數的交叉表
plt.subplot(1, 2, 2)
sns.heatmap(expected, annot=True, fmt='.2f', cmap='YlGnBu')
plt.title('期望頻數的交叉表')
plt.tight_layout()
plt.show()
在這里我們生成數據來分析不同產品類別在不同銷售區域的分布情況,并通過卡方檢驗來判斷產品類別和銷售區域之間是否存在顯著關聯,這里??在顯著性水平0.05下,我們無法拒絕原假設,說明根據現有數據,沒有足夠的證據表明產品類別和銷售區域之間存在顯著的關聯性
實現步驟
提出假設原假設??:觀測數據與理論分布一致
備擇假設 :觀察數據與理論分布不一致
收集數據
收集觀測數據和相應的理論頻數
計算期望頻數
根據理論分布計算期望頻數
計算卡方統計量
其中, 為第 類觀測頻數, 為第 類的期望頻數
確定自由度
其中,??k為分類數
確定p?值
根據卡方統計量和自由度,查卡方分布表或使用統計軟件計算 值
結論
如果?p值小于顯著性水平(例如a=0.05??),拒絕原假設,認為觀測數據與理論分布不一致
代碼實現
from scipy.stats import chisquare
# 觀察到的頻數
observed = np.array([16, 18, 16, 14, 12, 14])
# 期望頻數(假設是公平的骰子)
expected = np.array([15, 15, 15, 15, 15, 15])
# 卡方適合度檢驗
chi2, p = chisquare(observed, f_exp=expected)
# 輸出結果
print(f"Chi2 Statistic: {chi2}")
print(f"P-value: {p}")
# 創建DataFrame用于可視化
df = pd.DataFrame({
'Side': ['1', '2', '3', '4', '5', '6'],
'Observed': observed,
'Expected': expected
})
# 可視化實際頻數和期望頻數
fig, ax = plt.subplots(figsize=(10, 6))
# 觀察到的頻數柱狀圖
sns.barplot(x='Side', y='Observed', data=df, color='blue', label='觀察到的', ax=ax)
# 期望頻數柱狀圖
sns.barplot(x='Side', y='Expected', data=df, color='orange', label='期望的', ax=ax, alpha=0.5)
ax.set_title('觀察到的 vs 期望的頻數')
ax.legend()
plt.show()
假設我們在一個實驗中投擲了一個六面骰子100次,然后統計了每個面出現的次數,在理想情況下,如果骰子是公平的,每個面應該均勻地出現約15次,這里的代碼模擬了這樣的情景,并進行了卡方適合度檢驗,來驗證觀察到的頻數是否與期望的頻數(即公平骰子的預期結果)相符,根據這個卡方適合度檢驗的結果P=0.916884在顯著性水平0.05下,可以得出結論:在這個實驗中,投擲的六面骰子的觀察結果與預期的公平骰子模型一致,沒有足夠的證據表明骰子不是公平的