Python实现两因素独立设计方差分析,简单效应分析

# Python实现两因素独立设计方差分析

1. 背景

1. 有研究者探讨了在不同企业文化下,管理者的不同语言风格所产生的影响

有的企业注重员工的独立性,强调个人努力和内部竞争;有的企业注重员工的整体性,强调团队合作和团队绩效。

管理者的语言风格有斩钉截铁型和优柔寡断型。

据此,研究者制作了 4 种录音材料,分别提供不同企业文化背景下管理者不同语言风格的对话内容, 12名被试被分成4组参与了实验,每组分别听不同的录音。最后要求被试用 7 点量表评估管理者的能力。

结果如下:

实验目的:探究不同企业文化下不同语言风格对管理能力得分的影响。

实验设计:2*2 两因素独立方差分析

变量:

自变量1: 企业文化(个人努力VS团队合作),自变量2: 语言风格(优柔寡断VS斩钉截铁)

因变量:管理能力得分

PS:此处为了减少数据转换操作,故直接采用长数据格式。

2. Python代码

import pandas as pd
from statsmodels.stats.multicomp import pairwise_tukeyhsd
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
from scipy import stats


def general_data():
    # 为了减少转换这里直接给了长数据,指定第0列(表中第1列)为索引列
    df_two_way = pd.read_excel('./excel/不同企业文化下不同语言风格对管理的影响.xlsx', index_col=0)
    print("df_two_way=
", df_two_way)
    # 制定各列的变量名,如不指定则直接用表头
    # df_two_way.columns = ['企业文化', '语言风格', '管理能力得分']
    return df_two_way


def two_way_anova(df_two_way):
    # 包括两个主效应和一个交互效应
    formula = '管理能力得分  ~  C(企业文化)  +  C(语言风格)  +  C(企业文化) : C(语言风格)'
    model_two_way = ols(formula, df_two_way).fit()
    anova_table = anova_lm(model_two_way)
    print("=======输出方差分析表=======")
    # print(anova_table)

    for i in range(3):  # 将科学计数法转换为小数并只保留3位小数,和SPSS输出结果一致
        anova_table["PR(>F)"][i] = format(anova_table["PR(>F)"][i], ".3f")
    print(anova_table)

    # 读取交互效应行,如果显著,进行下一步,简单效应分析
    int_p = anova_table["PR(>F)"]["C(企业文化):C(语言风格)"]
    print("交互作用p值=", int_p)
    if float(int_p) < 0.05:
        print("p值小于0.05,交互效应显著,要进行简单效应分析")
        return True


# 由于没有找到现成的方案,所以考虑对表格进行拆分,如果交互作用显著,
# 则读取表格中的某一变量的某个水平下的所有数据,然后进行t校验
# 这是自己写的一个简单的算法,如有更好的方法欢迎赐教
def simple_effect_analysis(check, melt_data):
    dependent = "管理能力得分"
    # 交互效应存在,进行简单效应分析,否则跳过
    if check:
        # 简单效应分析需要分别
        # 检测企业文化为"个人努力"下的不同语言风格差异,
        # 以及企业文化为"团队合作"下的不同语言风格差异,
        # 分别对两种情况进行t检验即可
        groups = melt_data.groupby(melt_data.企业文化)
        for company_culture in ["个人努力", "团队合作"]:
            melt_data = groups.get_group(company_culture)
            # print(melt_data)
            # 分别比较在不同企业文化下,不同语言风格对管理能力得分影响的差异
            print("
=======%s企业文化下不同语言风格t检验分析结果=========" % company_culture)
            t_test(melt_data)


def t_test(melt_data):
    melt_data = melt_data[['语言风格', '管理能力得分']]
    # print("melt_data=
", melt_data)
    groups = melt_data.groupby(melt_data.语言风格)
    a_group = groups.get_group("优柔寡断")
    # print("a_group=
", a_group)
    b_group = groups.get_group("斩钉截铁")
    # print("b_group=
", b_group)
    t_value, p_value = stats.ttest_ind(a=a_group['管理能力得分'], b=b_group['管理能力得分'])
    # T = (样本均值 - 总体均值或另一样本均值) / (标准误差)
    print(f"T值:{t_value:.3f}, p值:{p_value:.3f}")


data = general_data()
simple_effect_analysis(two_way_anova(data), data)

3. 结果

3.1 运行以上代码,会出现如下结果

3.1.1 两因素独立方差分析输出结果

由于它这里对得不是很齐,所以我把p值圈了出来,可以看到有两个主效应的p值和一个交互效应的p值,其中企业文化主效应不显著,其他两个显著。

我的代码检测到交互作用p值小于0.05,就自动进入简单效应分析。

可以和SPSS的输出结果对比下:

中文版:

英文版:

3.1.2 简单效应分析结果

由于没有找到现成的方案来做简单效应分析,所以考虑对表格进行拆分,如果交互作用显著,则读取表格中的某一变量的某个水平下的所有数据,然后进行t检验。
代码中呈现的是自己写的简单算法,如有错误或更好的方法欢迎赐教。

补充,T值的公式为:

T = (样本均值 - 总体均值或另一样本均值) / (标准误差)

SPSS中的输出:

这里SPSS是采用了语法编辑器中的COMPARE语句,因为没有直接的成对比较方法。

可以看出,在不同企业文化下,不同语言风格的管理能力得分均存在显著差异。

4. 详细分析

4.1 方差分析

4.1.1 python代码

def general_data():
    # 为了减少转换这里直接给了长数据,指定第0列(表中第1列)为索引列
    df_two_way = pd.read_excel('./excel/不同企业文化下不同语言风格对管理的影响.xlsx', index_col=0)
    print("df_two_way=
", df_two_way)
    # 制定各列的变量名,如不指定则直接用表头
    # df_two_way.columns = ['企业文化', '语言风格', '管理能力得分']
    return df_two_way


def two_way_anova(df_two_way):
    # 包括两个主效应和一个交互效应
    formula = '管理能力得分  ~  C(企业文化)  +  C(语言风格)  +  C(企业文化) : C(语言风格)'
    model_two_way = ols(formula, df_two_way).fit()
    anova_table = anova_lm(model_two_way)
    print("=======输出方差分析表=======")
    # print(anova_table)

    for i in range(3):  # 将科学计数法转换为小数并只保留3位小数,和SPSS输出结果一致
        anova_table["PR(>F)"][i] = format(anova_table["PR(>F)"][i], ".3f")
    print(anova_table)

    # 读取交互效应行,如果显著,进行下一步,简单效应分析
    int_p = anova_table["PR(>F)"]["C(企业文化):C(语言风格)"]
    print("交互作用p值=", int_p)
    if float(int_p) < 0.05:
        print("p值小于0.05,交互效应显著,要进行简单效应分析")
        return True

代码中都有详细注释,不再重复,这里补充一下SPSS操作

4.1.2 SPSS操作

把自变量和因变量放入对应位置,点击确认即可

同样描述统计和齐性检验那些可以在选项里面选择,这里不选择,输出可以纯粹一点,结果见开头,不再重复贴出。

4.2 简单效应分析

4.2.1 Python代码

# 由于没有找到现成的方案,所以考虑对表格进行拆分,如果交互作用显著,
# 则读取表格中的某一变量的某个水平下的所有数据,然后进行t校验
# 这是自己写的一个简单的算法,如有更好的方法欢迎赐教
def simple_effect_analysis(check, melt_data):
    dependent = "管理能力得分"
    # 交互效应存在,进行简单效应分析,否则跳过
    if check:
        # 简单效应分析需要分别
        # 检测企业文化为"个人努力"下的不同语言风格差异,
        # 以及企业文化为"团队合作"下的不同语言风格差异,
        # 分别对两种情况进行t检验即可
        groups = melt_data.groupby(melt_data.企业文化)
        for company_culture in ["个人努力", "团队合作"]:
            melt_data = groups.get_group(company_culture)
            # print(melt_data)
            # 分别比较在不同企业文化下,不同语言风格对管理能力得分影响的差异
            print("
=======%s企业文化下不同语言风格t检验分析结果=========" % company_culture)
            t_test(melt_data)


def t_test(melt_data):
    melt_data = melt_data[['语言风格', '管理能力得分']]
    # print("melt_data=
", melt_data)
    groups = melt_data.groupby(melt_data.语言风格)
    a_group = groups.get_group("优柔寡断")
    # print("a_group=
", a_group)
    b_group = groups.get_group("斩钉截铁")
    # print("b_group=
", b_group)
    t_value, p_value = stats.ttest_ind(a=a_group['管理能力得分'], b=b_group['管理能力得分'])
    # T = (样本均值 - 总体均值或另一样本均值) / (标准误差)
    print(f"T值:{t_value:.3f}, p值:{p_value:.3f}")
simple_effect_analysis()函数中,有两步关键的数据拆分,详细说明如下,
"""
df_two_way=
     企业文化  语言风格  管理能力得分
被试                    
1   个人努力  优柔寡断     3.1
2   个人努力  优柔寡断     3.0
3   个人努力  优柔寡断     3.2
4   个人努力  斩钉截铁     4.7
5   个人努力  斩钉截铁     4.6
6   个人努力  斩钉截铁     4.8
7   团队合作  优柔寡断     4.5
8   团队合作  优柔寡断     4.4
9   团队合作  优柔寡断     4.6
10  团队合作  斩钉截铁     3.5
11  团队合作  斩钉截铁     3.4
12  团队合作  斩钉截铁     3.6
"""
# 将该数据按企业文化分组,然后按照对应的值,拆分为两个df格式的数据
def split_data(df_two_way):
    groups = df_two_way.groupby(df_two_way.企业文化)
    person_df = groups.get_group("个人努力")
    team_df = groups.get_group("团队合作")
    print(person_df)
    print(team_df)
# 即可得到
"""
    企业文化  语言风格  管理能力得分
被试                    
1   个人努力  优柔寡断     3.1
2   个人努力  优柔寡断     3.0
3   个人努力  优柔寡断     3.2
4   个人努力  斩钉截铁     4.7
5   个人努力  斩钉截铁     4.6
6   个人努力  斩钉截铁     4.8
"""
# 以及
"""
    企业文化  语言风格  管理能力得分
被试                    
7   团队合作  优柔寡断     4.5
8   团队合作  优柔寡断     4.4
9   团队合作  优柔寡断     4.6
10  团队合作  斩钉截铁     3.5
11  团队合作  斩钉截铁     3.4
12  团队合作  斩钉截铁     3.6
"""

然后t_test也用了相同的方式处理。

4.2.2 SPSS中的简单效应分析

据我所知,SPSS中没有直接的点击操作可以进行简单效应分析,所以这部分要进入语法编辑器中进行操作。

在之前的方差分析页面中,点击Paste

即可进入语法编辑器窗口

  1. UNIANOVA 管理能力得分 BY 企业文化 语言风格:这部分表示要进行单因素方差分析(UNIANOVA),因变量是“管理能力得分”,自变量是“企业文化”和“语言风格”。
  2. /METHOD=SSTYPE(3):指定使用Type III SS(类型III平方和),这是计算F统计量所用的平方和类型。
  3. /INTERCEPT=INCLUDE:表示在模型中包含截距项。
  4. /CRITERIA=ALPHA(0.05):设置显著性水平为0.05。
  5. /DESIGN=企业文化 语言风格 企业文化*语言风格:指定用于设计的自变量,即“企业文化”、“语言风格”和它们的交互项“企业文化*语言风格”。

然后我们在中间加一句:/EMMEANS=TABLES(企业文化*语言风格) COMPARE(语言风格)ADJ(LSD)

DATASET ACTIVATE DataSet1.
UNIANOVA 管理能力得分 BY 企业文化 语言风格
  /METHOD=SSTYPE(3)
  /INTERCEPT=INCLUDE
  /EMMEANS=TABLES(企业文化*语言风格) COMPARE(语言风格)ADJ(LSD)
  /CRITERIA=ALPHA(0.05)
  /DESIGN=企业文化 语言风格 企业文化*语言风格.
  1. /EMMEANS=TABLES(企业文化*语言风格) COMPARE(语言风格)ADJ(LSD):这部分是关于估计边际平均数(EMMEANS)的命令,用于生成交叉表,比较不同组之间的平均数,并使用LSD(最小显著差异)方法进行多重比较。

点击顶部的绿色三角即可运行,注意光标要放在代码块中。

输出结果如下:

中文版:

英文版:

END