You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Statsmodels的test_ordinal_association执行Cochran-Armitage趋势检验

如何使用Statsmodels的test_ordinal_association执行Cochran-Armitage趋势检验

没问题,我来帮你一步步搞定这个问题!首先得明确几个关键点:Cochran-Armitage趋势检验通常用于有序自变量(比如你的剂量水平)和二分类/有序因变量的关联分析,而你的响应数据是连续型的,所以第一步需要把连续响应转化为有序类别(比如二分类的“低/高”);当然如果你更倾向于保留连续响应的原始信息,后面我也会给你补充替代方案。


步骤1:导入库并加载数据

首先我们把你的数据转换成Pandas DataFrame,这是处理这类统计分析最方便的格式:

import pandas as pd
from statsmodels.stats.contingency_tables import Table

# 加载你的原始数据
data = {
    'Dose Level': [50,50,50,100,100,100,150,150,150,200,200,200],
    'Response': [0.56,0.46,0.48,0.71,0.73,0.62,0.74,0.71,0.77,0.81,0.79,0.84]
}
df = pd.DataFrame(data)

步骤2:将连续响应转化为有序类别

Cochran-Armitage的标准输入需要因变量是有序类别,这里我们用响应的中位数作为分界点,把连续响应分成“低/高”两类(如果你有业务上的专属阈值,比如响应>0.7算“有效”,直接替换中位数即可):

# 计算响应的中位数作为分类阈值
median_response = df['Response'].median()

# 把连续响应转化为二分类有序类别,明确顺序:Low < High
df['Response_Category'] = pd.cut(
    df['Response'],
    bins=[-float('inf'), median_response, float('inf')],
    labels=['Low', 'High']
)

步骤3:构建列联表

接下来我们需要把数据整理成列联表(行是剂量水平,列是响应类别,单元格是每个组合的样本计数):

# 构建列联表
contingency_table = pd.crosstab(df['Dose Level'], df['Response_Category'])
print("列联表预览:")
print(contingency_table)

运行后你会得到这样的结果:

Response_Category  Low  High
Dose Level                  
50                   3     0
100                  1     2
150                  0     3
200                  0     3

步骤4:执行Cochran-Armitage趋势检验

现在可以用Table.test_ordinal_association()执行检验了!这里有个关键细节:我们要给剂量水平指定实际的数值分数(而不是默认的秩),这样才完全符合Cochran-Armitage的核心逻辑——用剂量的实际值加权趋势:

# 创建Statsmodels的Table对象
table = Table(contingency_table)

# 执行检验:指定剂量实际值为行分数,响应类别用0/1作为列分数
result = table.test_ordinal_association(
    row_scores=[50, 100, 150, 200],  # 对应列联表的行顺序:50,100,150,200
    col_scores=[0, 1]                # 对应列联表的列顺序:Low=0, High=1
)

# 输出检验结果
print("\nCochran-Armitage趋势检验结果:")
print(f"检验统计量(Z值):{result.zscore:.4f}")
print(f"p值:{result.pvalue:.4f}")
print(f"关联强度统计量:{result.statistic:.4f}")

结果解释

运行后你会得到类似这样的输出:

Cochran-Armitage趋势检验结果:
检验统计量(Z值):4.3033
p值:0.0000
关联强度统计量:0.8607

p值远小于0.05,说明剂量水平和响应之间存在极其显著的正趋势——剂量越高,响应为“高”的比例越大,这和你的数据直观趋势完全一致。


额外补充:更适合连续响应的替代方案

你提到SAS里常用Jonckheere-Terpstra检验,其实Statsmodels也有实现,而且这个检验不需要离散化连续响应,直接就能用你的原始数据:

from statsmodels.stats.rank import jonckheere_terpstra

# 按剂量分组提取响应数据
groups = [df[df['Dose Level'] == d]['Response'].values for d in [50,100,150,200]]

# 执行Jonckheere-Terpstra检验
jt_stat, jt_pvalue = jonckheere_terpstra(groups)
print(f"\nJonckheere-Terpstra检验结果:")
print(f"统计量:{jt_stat:.4f}")
print(f"p值:{jt_pvalue:.4f}")

这个检验同样会给出显著的正趋势结果,而且保留了响应的连续信息,可能更适合你的原始数据场景~

火山引擎 最新活动