例子:
代码部分
# lec05
# 计量实验3-代码部分-02 多重共线性的诊断与处理
# 导入库文件
import pandas as pd
import statsmodels.api as sm
from statsmodels.stats.outliers_influence import variance_inflation_factor
import ssl
# 禁用SSL证书校验
ssl._create_default_https_context = ssl._create_unverified_context# 导入在线数据
# 导入在线数据
df = pd.read_excel(r"https://cdn.seit2019.xyz/data/econometrics/table10.8.xlsx")
# 展示数据
print("原始数据展示如下:")
print(df, "\n")
# 简要的描述性统计
print("原始数据的主要统计指标:")
print(df.describe(), "\n")
# 多元线性回归
# 主回归模型
y = df.Y
x = df.iloc[:, 2:8]
X = sm.add_constant(x) # 添加常数项
OLS_model = sm.OLS(y, X).fit() # OLS回归
print(OLS_model.summary(), "\n") # 显示OLS回归结果
R2 = OLS_model.rsquared # 获取回归R平方
dfc = pd.DataFrame(OLS_model.params).round(4) # 获取回归参数,保留小数点后4位
dfc = dfc.astype("string") # 转换格式为字符串
beta0 = dfc.iloc[0, 0] # 定义beta0
beta1 = dfc.iloc[1, 0] # 定义beta1
beta2 = dfc.iloc[2, 0] # 定义beta2
beta3 = dfc.iloc[3, 0] # 定义beta3
beta4 = dfc.iloc[4, 0] # 定义beta4
beta5 = dfc.iloc[5, 0] # 定义beta5
beta6 = dfc.iloc[6, 0] # 定义beta6
OLS_equation = "Y=" + beta0 + beta1 + "*X1" + beta2 + "*X2" + beta3 + "*X3"+ beta4 + "*X4" + "+" + beta5 + "*X5" + "+" + beta6 + "*X6" # 定义回归方程,格式:字符串
print("估计的回归方程为:")
print(OLS_equation, "\n")
# 多重共线性诊断原则1
print("多重共线性诊断原则1:高的R平方,低的t值", "\n")
print("结论:上述回归结果中R平方(0.995512)很高,但是部分变量(X1,X2,X5)系数不显著,可能存在多重共线性", "\n")
# 相关系数矩阵
x_corr = x.corr()
print(x_corr, "\n")
# 相关系数筛选
df_x_corr =pd.DataFrame(x_corr)
corr1 = []
corr2 = []
for i in df_x_corr.index:
for j in df_x_corr.columns:
if i != j:
if df_x_corr.loc[i, j] >= 0.9:
corr1.append([i])
corr1.append([j])
elif df_x_corr.loc[i, j] > 0.6:
corr2.append([i])
corr2.append([j])
df_corr1 = pd.DataFrame(corr1)
df_corr2 = pd.DataFrame(corr2)
fd1 = pd.unique(df_corr1[0])
fd2 = pd.unique(df_corr2[0])
print("存在高度相关(r>0.9)的解释变量有:")
for x in fd1:
print(x)
print("存在较高相关(r>0.6)的解释变量有:")
for x in fd2:
print(x)
# 多重共线性诊断原则2
print("多重共线性诊断原则2:解释变量之间高度相关性。")
print("结论:根据上述解释变量的相关系数矩阵,解释变量X1、X2、X5、X6之间存在很高的相关性(相关系数大于0.9),X3、X5、X6之间存在较高的相关性(相关系数大于0.6),这表明上述解释变量之间可能存在多重共线性。", "\n")
# 辅助回归
# 辅助回归模型1
y = df.X1
x = df[["X2", "X3", "X4", "X5", "X6"]]
X = sm.add_constant(x) # 添加常数项
AUX_model1 = sm.OLS(y, X).fit() # OLS回归
print(AUX_model1.summary(), "\n") # 显示OLS回归结果
R2_AUX1 = AUX_model1.rsquared # 获取R平方
# 辅助回归模型2
y = df.X2
x = df[["X1", "X3", "X4", "X5", "X6"]]
X = sm.add_constant(x) # 添加常数项
AUX_model2 = sm.OLS(y, X).fit() # OLS回归
print(AUX_model2.summary(), "\n") # 显示OLS回归结果
R2_AUX2 = AUX_model2.rsquared # 获取R平方
# 辅助回归模型3
y = df.X3
x = df[["X1", "X2", "X4", "X5", "X6"]]
X = sm.add_constant(x) # 添加常数项
AUX_model3 = sm.OLS(y, X).fit() # OLS回归
print(AUX_model3.summary(), "\n") # 显示OLS回归结果
R2_AUX3 = AUX_model3.rsquared # 获取R平方
# 辅助回归模型4
y = df.X4
x = df[["X1", "X2", "X3", "X5", "X6"]]
X = sm.add_constant(x) # 添加常数项
AUX_model4 = sm.OLS(y, X).fit() # OLS回归
print(AUX_model4.summary(), "\n") # 显示OLS回归结果
R2_AUX4 = AUX_model4.rsquared # 获取R平方
# 辅助回归模型5
y = df.X5
x = df[["X1", "X2", "X3", "X4", "X6"]]
X = sm.add_constant(x) # 添加常数项
AUX_model5 = sm.OLS(y, X).fit() # OLS回归
print(AUX_model5.summary(), "\n") # 显示OLS回归结果
R2_AUX5 = AUX_model5.rsquared # 获取R平方
# 辅助回归模型6
y = df.X6
x = df[["X1", "X2", "X3", "X4", "X5"]]
X = sm.add_constant(x) # 添加常数项
AUX_model6 = sm.OLS(y, X).fit() # OLS回归
print(AUX_model6.summary(), "\n") # 显示OLS回归结果
R2_AUX6 = AUX_model6.rsquared # 获取R平方
df_aux = pd.DataFrame(columns=["辅助回归", "被解释变量", "辅助回归R平方", "VIF值", "TOL值"])
data = {"辅助回归": ["1", "2", "3", "4", "5", "6"], "被解释变量": ["X1", "X2", "X3", "X4", "X5", "X6"]}
df_aux = pd.DataFrame(data)
df_aux["辅助回归R平方"] = pd.DataFrame([R2_AUX1, R2_AUX2, R2_AUX3, R2_AUX4, R2_AUX5, R2_AUX6]).round(4)
df_aux = df_aux.set_index("辅助回归")
print("辅助回归的R平方为:")
print(df_aux, "\n")
# 辅助回归R平方与主回归R平方比较
xvar = []
for i in range(6):
if df_aux.iloc[i, 1] > R2:
xvar.append(["X" + str(i+1)])
df_xvar = pd.DataFrame(xvar)
print("辅助回归R平方大于主回归的R平方的解释变量有:")
for x in df_xvar[0]:
print(x)
# 多重共线性诊断原则3
print("多重共线性诊断原则3:解释变量之间的辅助回归R平方大于主回归的R平方。")
print("结论:从上述辅助回归结果来看,解释变量X2、X5、X6对应的辅助回归R平方大于主回归的R平方,这表明:解释变量X2、X5、X6可能引发的多重共线性", "\n")
# VIF和TOL值
# 定义变量
y = df.Y
x = df.iloc[:, 2:8]
# 添加常数项
X = sm.add_constant(x)
# 计算VIF值
print("辅助回归的R平方,TOL值和VIF值:")
vif_value = []
tol_value = []
for i in range(6):
i += 1
vif = variance_inflation_factor(X.values, i)
tol = 1/vif
vif_value.append(vif.round(2))
tol_value.append(tol.round(4))
df_aux["VIF值"] = vif_value
df_aux["TOL值"] = tol_value
print(df_aux, "\n")
# 判断VIF值是否大于10
vif_var = []
for i in range(6):
if df_aux.iloc[i, 2] > 10:
vif_var.append(["X" + str(i+1)])
df_vif_var = pd.DataFrame(vif_var)
print("VIF值大于10的解释变量有:")
for x in df_vif_var[0]:
print(x)
# 多重共线性诊断原则4
print("多重共线性诊断原则4:VIF值大于10时,该解释变量存在高度多重共线性。")
print("结论:从上述辅助回归的TOL和VIF值来看,解释变量X1、X2、X3、X5、X6之间存在高度的多重共线性", "\n\n")
# 处理多重共线性
# 简单删除法
# 定义变量
y = df.Y
X1 = df["X1"]
X2 = df["X2"]
df["X2_X1"] = X2/X1
x = df[["X2_X1", "X4", "X5"]]
# 添加常数项
X = sm.add_constant(x)
# 展示回归结果
OLS_model = sm.OLS(y, X).fit()
print("经过简单删除后,最终的回归结果为:")
print(OLS_model.summary(), "\n")
# 逐步删除法
# 方法:后向逐步回归(所有变量导入,逐步删除不显著的变量)
# 定义变量
y = df.Y
x = df.iloc[:, 2:8]
# 添加常数项
X = sm.add_constant(x)
# 展示所有解释变量
print("全部的解释变量为:")
print(X, "\n")
# 展示初始回归结果
OLS_model = sm.OLS(y, X).fit()
print("初始的回归结果为:")
print(OLS_model.summary(), "\n")
p_values = OLS_model.pvalues
p_max = p_values.max()
# 判断P值-剔除解释变量-重新回归
while p_max > 0.05: # 循环开始的判断条件,参数P值是否大于0.05
X_num = p_values.argmax() # 获取最大P值对应的行索引号
X_name = p_values.index[X_num] # 获取最大P值的索引值,比如:X5
X = X.drop([X_name], axis=1) # 剔除最大P值对应的X数据列,比如X5列
print("剔除解释变量:" + X_name) # 提示剔除变量
OLS_model = sm.OLS(y, X).fit() # 重新回归
p_values = OLS_model.pvalues # 获取新回归的参数P值
p_max = p_values.max() # 获取最大的参数P值
else:
print("所有解释变量对应的P值均小于0.05,后向逐步回归结束。", "\n")
print("最终的回归结果为:")
print(OLS_model.summary(), "\n")