当您像以前那样拟合线性模型时,您正在估计每个类别的平均值,它不是斜率和截距拟合所有数据点,例如:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm
import numpy as np
import statsmodels.formula.api as smf
df = pd.DataFrame({'Y':np.random.normal(np.repeat([0,1.5,2.5],20),1,60),
'X':np.repeat(['x1','x2','x3'],20)})
df['X'] = pd.Categorical(df['X'],categories=['x1','x2','x3'])
res = smf.ols(formula= "Y ~ X",data=df).fit()
res.summary()
coef std err t P>|t| [0.025 0.975]
Intercept -0.0418 0.233 -0.180 0.858 -0.508 0.424
X[T.x2] 1.3507 0.329 4.102 0.000 0.691 2.010
X[T.x3] 2.5947 0.329 7.880 0.000 1.935 3.254
要绘制这些结果,您可以:
fig, ax = plt.subplots()
sns.scatterplot(data=df,x = "X",y = "Y",ax=ax)
ncat = len(res.params)
ax.scatter(x = np.arange(ncat)+0.1,y = res.params , color = "#FE9898")
ax.vlines(x = np.arange(ncat)+0.1,
ymin = res.conf_int().iloc[:,0],
ymax = res.conf_int().iloc[:,1],
color = "#FE9898")
如果你真的必须强制一条线,请记住这不是来自你刚刚展示的回归:
sns.regplot(x = df['X'].cat.codes,y = df['Y'],ax=ax,scatter=False,color="#628395")
fig