首页 > 解决方案 > Statsmodel:从方差分析中检索系数并传递二次函数

问题描述

一段时间以来,我一直在尝试对我的一些数据进行方差分析。在这种情况下,我试图拟合几个模型,看看哪一个最适合我的实验数据。我在 statsmodel 中使用 OLS 方法来拟合线性、线性交互和二次公式。该数据集由一个表组成,该表具有三个测试变量(速度、压力和间距)和测量的厚度(这是我试图拟合模型的变量)。每个变量有 3 个实验点。每个实验进行 4 次。数据看起来或多或少是这样的:

ID       Pressure Speed Spacing  Thickness
0        20       10     110     24
1        20       25     120     23
2        20       25     100     26
3        20       40     110     27
4        26       10     120     33
5        26       10     100     37

我正在使用的代码如下:

import statsmodels.api as sm
import statsmodels.formula.api as smf
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl

data = pd.read_csv('ANOVA Data.csv') # Load data from .csv file
# data[['Pressure','Speed','Spacing']] = data[['Pressure','Speed','Spacing']].astype(str) # Tried to convert variables into strings to not confuse statsmodels, doesn't work with quadratics

model_t_lin = smf.ols(formula="Thickness ~C(Pressure) + C(Speed) + C(Spacing)",data = data).fit() # Linear OLS
model_t_int = smf.ols(formula="Thickness ~ C(Pressure) + C(Speed) + C(Spacing) + C(Pressure*Speed) + C(Pressure*Spacing) + C(Spacing*Speed)",data = data).fit() # Interactions OLS
model_t_qd = smf.ols(formula="Thickness ~ C(Pressure) + C(Speed) + C(Spacing) + C(Pressure*Speed) + C(Pressure*Spacing) + C(Spacing*Speed) + C(Pressure**2) + C(Spacing**2) + C(Speed**2)",data = data).fit() # Quadratic OLS

models = [model_t_lin,model_t_int,model_t_qd] # Assemble vector for ease of use

modelnoms = ['t_linear','t_interactions','t_quadratic'] # Model names

A_type = 3 # Set Anova Type

for i in range(0,len(models)):
    print(' ')
    print(modelnoms[i]+':')
    print(models[i].summary())
    print(' ')
    print(sm.stats.anova_lm(models[i],typ=A_type))
    
# Determine and normalize coefficients of models
a_t_lin = model_t_lin.params/model_t_lin.params[0]
a_t_int = model_t_int.params/model_t_int.params[0]
a_t_qd = model_t_qd.params/model_t_qd.params[0]

coeff = [a_t_lin,a_t_int,a_t_qd] # Coefficients vector for plotting

fullnoms = ['Thickness - linear','Thickness - interactions','Thickness - quadratic']

mpl.rc('font',family='Verdana')
mpl.rcParams.update({'figure.autolayout': True})

for i in range(0,len(models)):
    plt.figure()
    plt.title(fullnoms[i])
    coeff[i].plot.bar()
    plt.show()

考虑到我的变量都是数字,我试图将它们作为字符串传递,这不适用于二次项,或者作为没有错误的类别传递。前者似乎最适合方差分析。然而,当我试图确定我的模型的系数时,我从 stats.summary 中得到了两个系数,而只期望一个。

第二个问题似乎是我的二次项在方差分析中被忽略了。我想这在某种程度上是有道理的,因为我使用的是 anova_lm,据我所知,它只处理线性模型。但是,我不明白为什么它与也是非线性的交互公式没有问题,除非它提供了错误的结果。

有没有人有使用这个包的经验,或者有没有更好的方法来执行这个分析?

标签: pythonstatsmodelsanova

解决方案


这个问题中获得灵感,您可以尝试将二次项包装成I(...),如下所示:

 model_t_qd = smf.ols(
    formula="Thickness ~ Pressure + Speed + Spacing + Pressure*Speed + Pressure*Spacing + Spacing*Speed + I(Pressure*Pressure) + I(Spacing*Spacing) + I(Speed*Speed)",
    data=data).fit() # Quadratic OLS

我还将您的其他因素写为连续的,而不是分类的,这对我来说似乎更有意义。

我只是用一个示例数据集尝试了它,对我来说它有效。我用商业软件交叉检查了结果,它们是 100% 相同的。

使用 anova_lm 时这有意义吗?好吧,不幸的是,我对统计数据了解得不够多,无法对此说些聪明的话。


推荐阅读