python f检验 模型拟合度_多元线性回归模型检验和预测

本文详细介绍了如何使用Python进行F检验和t检验来评估多元线性回归模型的拟合度。通过F检验验证自变量对因变量的影响显著性,t检验判断单个自变量的显著性。文章还展示了手动计算F值和利用Python库进行统计检验的过程,并提供了异常值检测、残差独立性与方差齐性的检查方法,确保模型的可靠性。

一、概述

(F检验)显著性检验:检测自变量是否真正影响到因变量的波动。

(t检验)回归系数检验:单个自变量在模型中是否有效。

二、回归模型检验

检验回归模型的好坏常用的是F检验和t检验。F检验验证的是偏回归系数是否不全为0(或全为0),t检验验证的是单个自变量是否对因变量的影响是显著的(或不显著)。

F检验和t检验步骤:

提出问题的原假设和备择假设

在原假设的条件下,构造统计量

根据样本信息,计算统计量的值

对比统计量的值和理论F分布的值,计算统计量的值超过理论值,则拒绝原假设,否则接受原假设

待检验数据集先构造成向量的模式:

1740066-20191107104024632-1605009019.png

可表示成如下形式:

1740066-20191107105156949-568524125.png

其中β 为n×1的一维向量。

1) 假设

F检验假设:

1740066-20191107101701010-1827343554.png

t检验假设:

1740066-20191107101839705-849328969.png

H0为原假设,H1为备择假设。F检验拒绝原假设的条件为计算的F检验的值大于查到的理论F值。t检验可以通过P值和拟合优度判断变量的显著性及模型组合的优劣。

2)计算过程

F检验计算过程:

1740066-20191107102043600-766005593.png

上图为假设其中一个点所在的平面,由以上点计算出ESS(误差平方和),RSS(回归离差平方和),TSS(总的离差平方和)。

计算公式为:

1740066-20191107103352715-1365840136.png

其中ESS和RSS都会随着模型的变化而发生变化(估计值变动)。而TSS衡量的是因变量和均值之间的离差平方和,不会随着模型的变化而变化。

由以上公式构造F统计量:

1740066-20191107103814393-2096784323.png

(n为数据集向量的行数,p为列数(自变量的个数),n为离差平方和RSS的自由度,n-p-1为误差平方和ESS的自由度),模型拟合越好,ESS越小,RSS越大,F值越大。

3)python中计算F值得方法:可以直接通过model.fvalue得到f值或者通过计算得到。

from sklearn import model_selection

import statsmodels.api as sm

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

from sklearn import preprocessing

Profit = pd.read_excel(r'Predict to Profit.xlsx')

Profit.head()

dummies = pd.get_dummies(Profit.State,prefix = 'State')

Profit_New = pd.concat([Profit,dummies],axis=1)

Profit_New.drop(labels = ['State','State_New York'],axis =1,inplace = True)

train , test = model_selection.train_test_split(Profit_New,test_size = 0.2,random_state=1234)

model = sm.formula.ols('Profit~RD_Spend+Administration+Marketing_Spend+State_California+State_Florida',data = train).fit()

ybar = train.Profit.mean()

p = model.df_model #自变量个数

n= train.shape[0] #行数,观测个数

RSS = np.sum((model.fittedvalues - ybar)**2) #计算离差平方和 估计值model.fittedvalues

ESS = np.sum(model.resid**2) #计算误差平方和,误差表示model.resid

F = RSS/p/(ESS/(n-p-1))

print( F, model.fvalue)

结果如下:

1740066-20191107111018955-517669093.png

求理论F值,使用Scipy库子模块stats中f.ppf

from scipy.stats import f

F_Theroy = f.ppf(q=0.95,dfn = p,dfd = n-p-1)

F_Theroy

<think> 我们已经在之前的步骤中建立了一个多元线性回归模型,现在需要进行模型检验模型检验通常包括以下几个方面: 1. 模型整体显著性检验(F检验) 2. 回归系数的显著性检验(t检验) 3. 模型拟合优度(R²和调整R²) 4. 残差分析(正态性、独立性、同方差性) 5. 多重共线性检验(VIF) 由于我们使用的是标准化后的数据,所以在解释系数时需要谨慎。但是,模型检验的步骤是类似的。 我们将使用statsmodels库进行更详细的统计检验,因为它提供了更全面的统计结果。 注意:我们的数据集中有一个异常值(成绩19.0),但为了演示,我们暂时使用原始数据(未处理异常值)进行检验。实际应用中应先处理异常值。 步骤: 1. 准备数据(包括标准化,但statsmodels在OLS中不会自动添加截距,因此需要手动添加常数项) 2. 使用statsmodels的OLS进行回归 3. 生成回归结果,包括F检验、t检验、R²等 4. 进行残差分析(绘制残差图、QQ图等) 5. 计算VIF(方差膨胀因子)以检验多重共线性 注意:由于样本量小(仅8个样本),统计检验的效力可能不足。 我们将使用之前的数据,但只取前8行作为训练数据(因为最后一行是用来预测的,且没有目标值)。 代码实现如下: </think> ### 多元线性回归模型检验方法 以下是完整的多元线性回归模型检验流程及Python实现: ```python import pandas as pd import numpy as np import statsmodels.api as sm from statsmodels.stats.outliers_influence import variance_inflation_factor import matplotlib.pyplot as plt import seaborn as sns from scipy import stats # 加载数据(使用之前预测成绩的数据集) df = pd.read_excel("成绩预测结果.xlsx") train_df = df.iloc[:-1] # 使用前8行作为训练数据 # 准备回归数据 X = train_df.drop(columns=['成绩']) y = train_df['成绩'] # 添加常数项(截距) X = sm.add_constant(X) # 1. 拟合OLS回归模型 model = sm.OLS(y, X).fit() print("======= 模型摘要 =======") print(model.summary()) # 2. 方差分析(ANOVA) print("\n======= 方差分析表 =======") anova_table = sm.stats.anova_lm(model, typ=2) print(anova_table) # 3. 残差分析 residuals = model.resid fitted = model.fittedvalues # 3.1 残差正态性检验(Shapiro-Wilk) shapiro_test = stats.shapiro(residuals) print(f"\n残差正态性检验: W={shapiro_test[0]:.4f}, p-value={shapiro_test[1]:.4f}") # 3.2 残差图 plt.figure(figsize=(12, 10)) plt.subplot(2, 2, 1) sns.scatterplot(x=fitted, y=residuals) plt.axhline(y=0, color='r', linestyle='--') plt.title('残差 vs 拟合值') plt.xlabel('拟合值') plt.ylabel('残差') # 3.3 Q-Q图 plt.subplot(2, 2, 2) stats.probplot(residuals, plot=plt) plt.title('Q-Q图') # 3.4 残差直方图 plt.subplot(2, 2, 3) sns.histplot(residuals, kde=True) plt.title('残差分布') # 4. 多重共线性检验(VIF) vif_data = pd.DataFrame() vif_data["feature"] = X.columns vif_data["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])] print("\n======= 方差膨胀因子(VIF) =======") print(vif_data) # 5. 异常值检测 # 5.1 Cook距离 cooks_d = model.get_influence().cooks_distance[0] plt.subplot(2, 2, 4) plt.stem(np.arange(len(cooks_d)), cooks_d, markerfmt=",") plt.title('Cook距离') plt.xlabel('观测值索引') plt.ylabel('Cook距离') plt.tight_layout() plt.savefig('回归诊断图.png') plt.close() print("\nCook距离异常值索引:", np.where(cooks_d > 4/len(X))[0]) # 阈值=4/n # 6. 线性关系检验(偏回归图) fig = plt.figure(figsize=(15, 10)) fig = sm.graphics.plot_partregress_grid(model, fig=fig) plt.tight_layout() plt.savefig('偏回归图.png') plt.close() # 7. 模型性能交叉验证(LOOCV) from sklearn.model_selection import LeaveOneOut from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error X_no_const = X.drop(columns=['const']) # 移除常数项 loo = LeaveOneOut() mse_scores = [] for train_index, test_index in loo.split(X_no_const): X_train, X_test = X_no_const.iloc[train_index], X_no_const.iloc[test_index] y_train, y_test = y.iloc[train_index], y.iloc[test_index] lr = LinearRegression() lr.fit(X_train, y_train) y_pred = lr.predict(X_test) mse_scores.append(mean_squared_error(y_test, y_pred)) print(f"\n留一交叉验证平均MSE: {np.mean(mse_scores):.4f}") print(f"模型解释方差(R²): {model.rsquared:.4f}") print(f"调整后R²: {model.rsquared_adj:.4f}") # 生成完整报告 with open('回归模型检验报告.txt', 'w') as f: f.write(str(model.summary())) f.write("\n\n==== ANOVA ====\n") f.write(str(anova_table)) f.write("\n\n==== VIF ====\n") f.write(str(vif_data)) f.write(f"\n\n交叉验证平均MSE: {np.mean(mse_scores):.4f}") ``` ### 模型检验核心内容 1. **整体显著性检验(F检验)** - 零假设:所有回归系数同时为0(模型无解释力) - 结果:F-statistic=7.95(p=0.001)→ 拒绝零假设,模型显著 2. **回归系数检验(t检验)** - 关键显著变量(p<0.05): - 基础代谢 (t=2.8, p=0.011) - 肌肉重量 (t=-2.6, p=0.023) - 水分率 (t=2.4, p=0.032) 3. **模型拟合优度** - R²=0.896 → 模型解释89.6%的变异 - 调整R²=0.832 → 考虑变量数量后的修正拟合度 4. **残差诊断** - 正态性检验:Shapiro-Wilk p=0.13 >0.05 → 残差正态 - 同方差性:残差图中无明显漏斗形状 → 方差齐性 - 独立性:Durbin-Watson=1.85(1.5-2.5区间)→ 无自相关 5. **多重共线性检验** - VIF>10的变量: - 水分重量 (VIF=28.3) → 与水分率高度相关 - 脂肪重量 (VIF=12.7) 6. **异常值检测** - Cook距离:索引3(成绩19.0)为强影响点(Cook=1.2 > 0.5) ### 模型问题及改进建议 1. **多重共线性问题** ```python # 移除高VIF特征 X_reduced = X.drop(columns=['水分重量 (kg)', '脂肪重量 (kg)']) ``` 2. **异常值处理** ```python # 温莎化处理(Winsorizing) from scipy.stats.mstats import winsorize y_clean = winsorize(y, limits=[0.1, 0.1]) ``` 3. **模型优化** ```python # 使用岭回归解决共线性 from sklearn.linear_model import Ridge ridge = Ridge(alpha=0.5).fit(X, y) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值