数据科学4月13日上机作业
——made by njtech_计2104 Melody
3.1 卡方检验
3.1.1 基本原理与过程。
卡方检验(Chi-square test)是一种统计分析方法,用于检验分类变量之间的独立性或观察频率与预期频率之间的差异。它主要应用于观察数据中的计数和频率,而不是连续数据。卡方检验的基本原理和过程如下:
-
原假设与备择假设:首先,建立一个原假设( H 0 \mathrm{H}_0 H0),即两个分类变量之间是独立的,不存在关联。相应地,备择假设( H 1 \mathrm{H}_1 H1)表示这两个分类变量之间存在关联。
-
构建列联表:根据观察到的数据,构建一个列联表(contingency table),用于显示不同分类变量组合的观察频数。
-
计算期望频数:假设原假设成立,即分类变量之间独立,根据列联表的行、列边际总数,计算每个单元格的期望频数。
-
计算卡方统计量:使用观察频数和期望频数计算卡方统计量( X 2 \mathrm{X}^2 X2 )。公式如下:
X 2 = ∑ [ ( O i j − E i j ) 2 E i j ] X^2=\sum\left[ \frac{(\mathrm{O_{ij}}-\mathrm{E_{ij}})^2}{\mathrm{E_{ij}}} \right] X2=∑[Eij(Oij−Eij)2]
其中, O i j \mathrm{O}_{ij} Oij 表示第 i i i 行第 j j j 列的观察频数,$\mathrm{E}_{ij} $ 表示第 i i i 行第 $j $ 列的期望频数. -
自由度与卡方分布:计算卡方检验的自由度(df)。对于列联表,自由度通常为 (行数-1)×(列数-1)。接下来,根据自由度和显著性水平(通常为0.05),查找卡方分布表,得到卡方临界值。
-
结果判断:将计算得到的卡方统计量与卡方临界值进行比较。如果卡方统计量大于临界值,拒绝原假设,接受备选假设;反之,无法拒绝原假设。这意味着如果卡方统计量大于临界值,我们认为观察到的差异是显著的,分类变量之间存在关联;否则,不能认为分类变量之间有显著关联。
3.1.2 数据样本
假设一次学科竞赛A、B两所学校各有300人参加,工作人员随机取样了两所学校若干同学的成绩情况,如文件夹中scores文件所示。
3.1.3 数据转化
将数据转化为四格表形式
# 读取Excel文件
file_name = "scores.xlsx"
data = pd.read_excel(file_name)
# 创建一个四格表(列联表)
contingency_table = pd.crosstab(data['所属学校'], data['成绩是否合格'])
print(contingency_table)
# 将列联表保存为新的Excel文件
output_file_name = "contingency_table.xlsx"
contingency_table.to_excel(output_file_name)
3.1.4 原假设与备择假设
在这个例子中,我们关心的是成绩是否合格(合格或不合格)与所属学校(A学校或B学校)之间的关系。因此,我们可以建立以下原假设( H 0 \mathrm{H}_0 H0)与备择假设( H 1 \mathrm{H}_1 H1 ):
-
原假设( H 0 \mathrm{H}_0 H0):成绩是否合格与所属学校之间是独立的,不存在关联。
-
备择假设( H 1 \mathrm{H}_1 H1 ):成绩是否合格与所属学校之间存在关联。
3.1.5 数据分析
选择适当的假设检验方法,编程进行数据分析。输出自由度、卡方值、p值和最终检验结果(保留四位小数)。
import pandas as pd
import numpy as np
# 读取Excel文件
file_name = "scores.xlsx"
data = pd.read_excel(file_name)
print(data)
# 创建一个四格表(列联表)
contingency_table = pd.crosstab(data['所属学校'], data['成绩是否合格'])
print(contingency_table)
# 将列联表保存为新的Excel文件
output_file_name = "contingency_table.xlsx"
contingency_table.to_excel(output_file_name)
from scipy.stats import chi2
# 自定义卡方检验公式
def my_chi2_contingency(contingency_table):
# 计算行、列边际总数和表格总数
row_totals = contingency_table.sum(axis=1)
col_totals = contingency_table.sum(axis=0)
total = contingency_table.sum().sum()
# 计算期望频数
expected = np.outer(row_totals, col_totals) / total
# 计算卡方值
chi2_value = ((contingency_table - expected) ** 2 / expected).sum().sum()
# 计算自由度
df = (contingency_table.shape[0] - 1) * (contingency_table.shape[1] - 1)
# 计算p值
p_value = 1 - chi2.cdf(chi2_value, df)
return chi2_value, p_value, df
# 使用自定义函数进行卡方检验
chi2, p_value, df = my_chi2_contingency(contingency_table)
# 输出自由度、卡方值、p值和最终检验结果(保留四位小数)
print(f"自由度: {df}")
print(f"卡方值: {chi2:.4f}")
print(f"p值: {p_value:.4f}")
# 判断检验结果
alpha = 0.05
if p_value < alpha:
print("拒绝原假设,成绩是否合格与所属学校之间存在关联。")
else:
print("无法拒绝原假设,成绩是否合格与所属学校之间没有显著关联。")
计算结果:
自由度: 1
卡方值: 0.6031
p值: 0.4374
无法拒绝原假设,成绩是否合格与所属学校之间没有显著关联。
3.1.6 Yates连续性校正(optional)
在查找资料的时候,发现有个矫正可以专门针对 2x2 列联表进行优化。
Yates连续性校正(Yates’ continuity correction)是一种针对2x2列联表卡方检验的校正方法。它旨在解决在小样本量和/或观测值与期望值接近的情况下,卡方检验可能出现的过高显著性(高卡方值和低p值)的问题。Yates校正通过在卡方统计量的计算中引入一个修正项(0.5)来实现。
X
2
=
Σ
[
(
∣
O
−
E
∣
−
0.5
)
2
E
]
X^2=\Sigma\left[\frac{(|O-E|-0.5)^2}{E} \right]
X2=Σ[E(∣O−E∣−0.5)2]
def my_chi2_contingency(contingency_table, correction=True):
# 计算行、列边际总数和表格总数
row_totals = contingency_table.sum(axis=1)
col_totals = contingency_table.sum(axis=0)
total = contingency_table.sum().sum()
# 计算期望频数
expected = np.outer(row_totals, col_totals) / total
# 计算卡方值(应用Yates连续性校正)
if correction and contingency_table.shape == (2, 2):
chi2_value = (np.abs(contingency_table - expected) - 0.5) ** 2 / expected
else:
chi2_value = (contingency_table - expected) ** 2 / expected
chi2_value = chi2_value.sum().sum()
# 计算自由度
df = (contingency_table.shape[0] - 1) * (contingency_table.shape[1] - 1)
# 计算p值
p_value = 1 - chi2.cdf(chi2_value, df)
return chi2_value, p_value, df
计算结果:
自由度: 1
卡方值: 0.4066
p值: 0.5237
无法拒绝原假设,成绩是否合格与所属学校之间没有显著关联。
PS:scipy.satas
库中默认使用Yates连续性矫正
chi2, p_value, df, _ = chi2_contingency(contingency_table)
3.2 T检验
3.2.1 基本原理与过程
T检验(t-test)是一种用于检验两组数据之间是否存在显著差异的统计方法。它是基于t分布的假设检验,通常用于比较两个独立或相关样本的平均值。T检验的基本原理是通过比较样本统计量(如样本均值)与其对应的总体参数(如总体均值)来确定两组数据之间是否存在显著差异。
T检验的过程如下:
- 建立假设:
- 原假设(H0):两组数据之间没有显著差异,即总体均值相等。
- 备择假设(H1):两组数据之间存在显著差异,即总体均值不相等。
- 选择适当的t检验类型:
- 独立样本t检验(independent samples t-test):用于比较两个独立样本的平均值。
- 配对样本t检验(paired samples t-test):用于比较两个相关或配对样本的平均值。
- 单样本t检验(one-sample t-test):用于比较一个样本的平均值与已知或假设的总体平均值。
- 计算t统计量:
- 根据所选t检验类型的公式,使用样本数据计算t统计量。
- 确定显著性水平和自由度:
- 显著性水平(α)通常设定为0.05,表示我们愿意接受5%的错误拒绝原假设的风险。
- 自由度(df)根据样本大小和检验类型计算。对于独立样本t检验,自由度通常为两个样本大小之和减2(n1 + n2 - 2);对于配对样本t检验和单样本t检验,自由度为样本大小减1(n - 1)。
- 计算p值:
- 根据计算得到的t统计量和自由度,查找相应的t分布表或使用统计软件计算p值。
- 做出决策:
- 如果p值小于显著性水平(p < α),则拒绝原假设,认为两组数据之间存在显著差异。
- 如果p值大于等于显著性水平(p ≥ α),则无法拒绝原假设,认为两组数据之间没有显著差异。
3.2.2 问题解决
设某工厂生产的一批灯泡服从正态分布,该批灯泡设计寿命为2000小时。现从该批灯泡中随机抽取11只进行测试,得到的最终寿命如下:1789, 1867, 2012, 2134, 1952, 1997, 1840, 1567, 2230, 2403,1777。请问,在显著水平为0.05下,能否认为本批灯泡合格?列出计算方法并编程验证。
为了判断本批灯泡是否合格,我们可以进行单样本t检验。原假设是本批灯泡的平均寿命等于设计寿命2000小时。备择假设是本批灯泡的平均寿命不等于2000小时。
计算方法:
- 计算样本平均值和样本标准差。
- 计算t统计量。
- 根据t统计量和自由度(n-1)计算p值。
- 如果p值小于显著性水平(0.05),则拒绝原假设,认为灯泡不合格。否则,无法拒绝原假设,认为灯泡合格。
import numpy as np
from scipy import stats
# 灯泡寿命数据
lifetimes = np.array([1789, 1867, 2012, 2134, 1952, 1997, 1840, 1567, 2230, 2403, 1777])
# 设计寿命
design_lifetime = 2000
# 计算样本平均值和样本标准差
sample_mean = np.mean(lifetimes)
sample_std = np.std(lifetimes, ddof=1) # 使用无偏标准差(n-1)
# 计算t统计量
t_statistic = (sample_mean - design_lifetime) / (sample_std / np.sqrt(len(lifetimes)))
# 计算自由度
df = len(lifetimes) - 1
# 计算双侧p值
p_value = stats.t.sf(np.abs(t_statistic), df) * 2
# 输出t统计量和p值
print(f"t统计量: {t_statistic:.4f}")
print(f"p值: {p_value:.4f}")
# 判断检验结果
alpha = 0.05
if p_value < alpha:
print("拒绝原假设,本批灯泡不合格。")
else:
print("无法拒绝原假设,本批灯泡合格。")
计算结果:
t统计量: -0.5586
p值: 0.5887
无法拒绝原假设,本批灯泡合格。
3.3 方差检验
3.3.1 基本原理与过程
方差分析(ANOVA,Analysis of Variance)是一种统计方法,用于比较三个或更多组之间的平均值差异。方差分析的目的是确定不同组之间是否存在显著差异。根据不同的应用场景和数据类型,方差分析可以分为以下几种:
- 单因素方差分析(One-way ANOVA):用于比较一个因素的不同水平之间的平均值差异。单因素方差分析仅考虑一个分类变量。
- 双因素方差分析(Two-way ANOVA):用于比较两个因素的不同水平组合之间的平均值差异。双因素方差分析可以分析两个分类变量以及它们之间的交互作用。
- 多因素方差分析(Multifactor ANOVA):用于比较多个因素的不同水平组合之间的平均值差异。多因素方差分析可以处理多个分类变量及其相互作用。
方差分析的基本原理是通过比较组内方差(Within-group Variance)和组间方差(Between-group Variance)来确定不同组之间是否存在显著差异。如果组间方差显著大于组内方差,我们可以认为不同组之间存在显著差异。
方差分析的流程如下:
- 建立假设:
- 原假设(H0):所有组的总体均值相等。
- 备择假设(H1):至少有一个组的总体均值与其他组不同。
- 计算组间平方和(SSB)、组内平方和(SSW)以及它们对应的自由度。
- 计算组间均方(MSB)和组内均方(MSW):
- MSB = SSB / df_between
- MSW = SSW / df_within
- 计算F统计量:
- F = MSB / MSW
- 计算p值:
- 根据F统计量和自由度,查找相应的F分布表或使用统计软件计算p值。
- 做出决策:
- 如果p值小于显著性水平(如0.05),则拒绝原假设,认为不同组之间存在显著差异。
- 如果p值大于等于显著性水平,无法拒绝原假设,认为不同组之间没有显著差异。
3.3.2 问题解决
某灯泡制造厂有3条不同的生产线,分别为国产A、德国产B和美国产C,有四班组生产工人,分别为甲、乙、丙、丁班组。经理希望研究不同生产线以及不同生产班组对产量的影响,因此安排生产计划,让甲、乙、丙、丁四班工人操作生产线A、B、C各生产3天,其灯泡产量如下表格所示:
A B C 甲 56 , 55 , 59 62 , 61 , 66 52 , 50 , 47 乙 47 , 45 , 49 54 , 50 , 55 42 , 45 , 48 闪 47 , 49 , 44 56 , 52 , 54 44 , 49 , 48 丁 53 , 57 , 54 54 , 61 , 60 48 , 51 , 64 \begin{array}{|l|l|l|l|} \hline & A & B & C \\ \hline \text { 甲 } & 56,55,59 & 62,61,66 & 52,50,47 \\ \hline \text { 乙 } & 47,45,49 & 54,50,55 & 42,45,48 \\ \hline \text { 闪 } & 47,49,44 & 56,52,54 & 44,49,48 \\ \hline \text { 丁 } & 53,57,54 & 54,61,60 & 48,51,64 \\ \hline \end{array} 甲 乙 闪 丁 A56,55,5947,45,4947,49,4453,57,54B62,61,6654,50,5556,52,5454,61,60C52,50,4742,45,4844,49,4848,51,64
请选用适合的方差分析方法,分析班组与生产线对灯泡产量是否有显著影响,并说明理由。然后编程验证分析,并得出结论。
我们需要考虑两个因素:生产线(A、B、C)和班组(甲、乙、丙、丁)。因此,应使用双因素方差分析(Two-way ANOVA)来研究这两个因素对灯泡产量的影响。
原假设和备择假设如下:
- 生产线对产量的影响:
- 原假设(H0):不同生产线的灯泡产量总体均值相等。
- 备择假设(H1):至少有一个生产线的灯泡产量总体均值与其他生产线不同。
- 班组对产量的影响:
- 原假设(H0):不同班组的灯泡产量总体均值相等。
- 备择假设(H1):至少有一个班组的灯泡产量总体均值与其他班组不同。
import numpy as np
import pandas as pd
from scipy.stats import f_oneway
import statsmodels.api as sm
from statsmodels.formula.api import ols
# 灯泡产量数据
data = pd.DataFrame({
'Line': ['A']*12 + ['B']*12 + ['C']*12,
'Group': ['甲', '甲', '甲', '乙', '乙', '乙', '丙', '丙', '丙', '丁', '丁', '丁'] * 3,
'Output': [56, 55, 59, 47, 45, 49, 47, 49, 44, 53, 57, 54,
62, 61, 66, 54, 50, 55, 56, 52, 54, 54, 61, 60,
52, 50, 47, 42, 45, 48, 44, 49, 48, 48, 51, 64]
})
# 使用双因素方差分析
model = ols('Output ~ C(Line) * C(Group)', data=data).fit()
anova_table = sm.stats.anova_lm(model, typ=2)
# 输出结果
print(anova_table)
计算结果:
sum_sq df F PR(>F)
C(Line) 417.722222 2.0 17.166667 0.000024
C(Group) 489.555556 3.0 13.412481 0.000024
C(Line):C(Group) 85.611111 6.0 1.172755 0.353370
Residual 292.000000 24.0 NaN NaN
结论:
-
生产线对产量的影响:p值(0.000024)小于显著性水平0.05,拒绝原假设,认为存在显著差异。这意味着不同生产线对灯泡产量有显著影响。
-
班组对产量的影响:p值(0.000024)小于显著性水平0.05,拒绝原假设,认为不同班组之间的灯泡产量总体均值存在显著差异。这意味着班组对灯泡产量有显著影响。
-
生产线和班组的交互作用:p值(0.353370)大于显著性水平0.05,无法拒绝原假设,认为生产线和班组之间的交互作用对灯泡产量没有显著影响。
综上所述,双因素方差分析的结果表明,生产线和班组都对灯泡产量有显著影响,同时生产线和班组之间的交互作用对灯泡产量没有显著影响。