python一元线性回归

#问题:python一元线性回归模型的检验

我用python做了output value和receivables两组数据之间的线性回归分析,其中自变量是receivables,因变量是output value。
下面是我的代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import seaborn as sns
import statsmodels.api as sm
import statsmodels.formula.api as smf
from scipy import stats
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.graphics.gofplots import ProbPlot

# 加载数据
data = pd.read_excel('output value&receivables.xlsx')

# 设置字体为微软雅黑
my_font = fm.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')

# 1. 绘制散点图进行定性检验
plt.figure(figsize=(8, 6))
sns.scatterplot(data=data, x="receivables", y="output value")
plt.title('散点图', fontproperties=my_font)
plt.xlabel('receivables', fontproperties=my_font)
plt.ylabel('output value', fontproperties=my_font)
plt.show()

# 2. 计算相关系数进行定量检验
correlation = data[['receivables', 'output value']].corr()
print('相关系数:', correlation.loc['receivables', 'output value'])

# 3. 建立模型,得到回归系数
model = smf.ols("Q('output value') ~ Q('receivables')", data=data).fit()
print('回归系数:', model.params)

# 4. 进行假设检验,包括对回归系数的显著性检验和对模型整体显著性的F检验
print(model.summary())

# 5. 计算R^2
print('R^2:', model.rsquared)

# 6. 进行残差分析,包括残差的正态性、独立性和同方差性等
residuals = model.resid
fig = sm.qqplot(residuals, fit=True, line='45')
plt.title('Q-Q Plot', fontproperties=my_font)
plt.show()

# 残差的独立性
dw = sm.stats.durbin_watson(residuals)
print('Durbin-Watson:', dw)

# 残差的同方差性
plt.scatter(model.predict(), residuals)
plt.title('Residuals vs Predicted', fontproperties=my_font)
plt.xlabel('Predicted', fontproperties=my_font)
plt.ylabel('Residuals', fontproperties=my_font)
plt.show()

# 7. 若模型通过上述检验,绘制散点图和回归线,并给出回归方程
sns.regplot(x="receivables", y="output value", data=data)
plt.title('散点图和回归线', fontproperties=my_font)
plt.xlabel('receivables', fontproperties=my_font)
plt.ylabel('output value', fontproperties=my_font)
plt.show()
print('回归方程: output value = {:.3f} + {:.3f}*receivables'.format(model.params[0], model.params[1]))

下面是计算结果以及散点图:

img

img

计算结果显示两组数据强相关,相关系数: 0.987。且决定系数R^2为0.976,非常高。F-statistic: 2335.,Prob (F-statistic): 1.49e-48:F统计量的p值,小于0.05,所以模型整体是显著的。P>|t|:t统计量的p值,小于0.05,说明回归系数显著。
但是对于残差的分析,计算的值和相关的图形好像不太符合。
Q-Q图如下:

img

残差图如下:

img


我认为QQ图和残差图似乎说明残差呈正态分布,但是计算的数据却显示:
Prob(Omnibus): 0.000:Omnibus检验的p值,小于0.05,说明残差不符合正态分布。
rob(JB): 1.67e-102:Jarque-Bera检验的p值,小于0.05,说明残差不符合正态分布。
Kurtosis: 15.838:峰度,衡量数据分布的尖锐程度,大于3说明数据分布比正态分布更尖锐。
总的来说,模型整体上是显著的,但是模型的残差不符合正态分布,可能存在一些问题。

想解决的问题:
1.该模型是否显著,能否用于预测
2.残差是否需要进一步分析

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    根据问题描述,可以得知你的模型可能存在问题。残差不符合正态分布可能会导致模型的预测能力下降,因此需要对问题进行进一步的分析。

    针对该问题,你可以采取以下步骤:

    1. 首先,我们需要确认模型是否显著。可以通过计算t值和p值来判断统计学上是否显著。具体做法是计算自变量的系数标准误差,然后计算t值,并计算p值来检验t值是否显著,常用的显著性水平是0.05。如果t值显著,则表明模型显著。

    代码示例:

    import statsmodels.api as sm
    import numpy as np
    
    # 假设你的数据存储在receivables和output_value两个变量中
    X = sm.add_constant(receivables)
    model = sm.OLS(output_value, X).fit()
    print(model.summary())
    
    # 查看系数的标准误差
    print(model.bse)
    
    # 计算t值和p值
    t_value = model.params[1] / model.bse[1]
    p_value = 2 * (1 - stats.t.cdf(abs(t_value), len(X)-2))
    if p_value < 0.05:
      print("该模型显著")
    else:
      print("该模型不显著")
    
    1. 如果模型显著,则可以继续分析残差不符合正态分布的问题。可以采用多种方法进行检验,比如偏度和峰度的检验、Shapiro-Wilk检验等。如果残差不符合正态分布,则可以考虑进行变换或使用其他模型。

    代码示例:

    from scipy import stats
    
    # 残差
    residuals = model.resid
    
    # 偏度和峰度检验
    skewtest_result = stats.skewtest(residuals)
    kurtosistest_result = stats.kurtosistest(residuals)
    print("偏度检验结果:", skewtest_result)
    print("峰度检验结果:", kurtosistest_result)
    
    # Shapiro-Wilk检验
    shapiro_result = stats.shapiro(residuals)
    print("Shapiro-Wilk检验结果:", shapiro_result)
    
    # 以上检验均使用显著水平0.05
    
    1. 如果残差不符合正态分布,则可以考虑进行变换。常用的方法包括对数变换、平方根变换、Box-Cox变换等。可以对残差进行变换后再进行检验,以便找到一个更好的模型。

    代码示例:

    # 对数变换
    log_residuals = np.log(residuals)
    shapiro_result = stats.shapiro(log_residuals)
    print("对数变换后残差的Shapiro-Wilk检验结果:", shapiro_result)
    
    # 平方根变换
    sqrt_residuals = np.sqrt(residuals)
    shapiro_result = stats.shapiro(sqrt_residuals)
    print("平方根变换后残差的Shapiro-Wilk检验结果:", shapiro_result)
    
    # Box-Cox变换
    bc_result, bc_lambda = stats.boxcox(residuals)
    shapiro_result = stats.shapiro(bc_result)
    print("Box-Cox变换后残差的Shapiro-Wilk检验结果:", shapiro_result)
    

    最后,需要说明的是,对于其他模型,也需要进行类似的分析过程,以确保模型的可靠性和准确性。如果模型存在问题,需要及时进行改进和优化。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^