为什么拟合优度不是判断模型优劣的好标准
发布网友
发布时间:2023-05-11 02:47
我来回答
共1个回答
热心网友
时间:2023-10-12 17:10
建立完回归模型后,还需要验证咱们建立的模型是否合适,换句话说,就是咱们建立的模型是否真的能代表现有的因变量与自变量关系,这个验证标准一般就选用拟合优度。
拟合优度是指回归方程对观测值的拟合程度。度量拟合优度的统计量是判定系数R2。R2的取值范围是[0,1]。R2的值越接近1,说明回归方程对观测值的拟合程度越好;反之,R2的值越接近0,说明回归方程对观测值的拟合程度越差。
拟合优度问题目前还没有找到统一的标准说大于多少就代表模型准确,一般默认大于0.8即可
拟合优度的公式:R^2 = 1 - RSS/TSS
注: RSS 离差平方和 ; TSS 总体平方和
理解拟合优度的公式前,需要先了解清楚几个概念:总体平方和、离差平方和、回归平方和。
一、总体平方和、离差平方和、回归平方和
回归平方和 ESS,残差平方和 RSS,总体平方和 TSS
TSS(Total Sum of Squares)表示实际值与期望值的离差平方和,代表变量的总变动程度
ESS(Explained Sum of Squares)表示预测值与期望值的离差平方和,代表预测模型拥有的变量变动程度
RSS(Resial Sum of Squares)表示实际值与预测值的离差平方和,代表变量的未知变动程度
各个平方和的计算公式如下:
在这里插入图片描述
二、拟合优度
接上一节内容可知,我们拿实际值与期望值的离差平方和作为整体变量的总变动程度,这个变动程度就是我们建模型的目的,我们建立模型就是为了模拟这个变动程度。
建立模型后,整体变量的总变动程度(TSS)可以划分为两部分:模型模拟的变动程度(ESS)和未知的变动程度(RSS)
通常来说,预测模型拥有的变量变动程度在总变动程度中的占比越高,代表模型越准确,当RSS=0时,表示模型能完全模拟变量的总变动。
回到文章开头的拟合优度公式:R^2 = 1 - RSS/TSS 。是不是很好理解了!
假设R^2 = 0.8,意味着咱们建立的模型拥有的变动程度能模拟80%的总变动程度,剩下20%为未知变动
三、例子
对于学生而言,现在要探索一下学生的学习成绩与单一的学习时间是否有关系,给出两组数据如下:
‘学习时间’:[0.50,0.75,1.00,1.25,1.50,1.75,1.75, 2.00,2.25,2.50,2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
‘分数’:[10,22,13,43,20,22,33,50,62,48,55,75,62,73,81,76,64,82,90,93]
常识理解,学习时间越长,分数一般都会越高,两者是正比关系,因为就一个自变量,直接用sklearn,算出截距和斜率即可
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas import DataFrame,Series
from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LinearRegression
#创建数据集
examDict = {'学习时间':[0.50,0.75,1.00,1.25,1.50,1.75,1.75,
2.00,2.25,2.50,2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
'分数':[10,22,13,43,20,22,33,50,62,
48,55,75,62,73,81,76,64,82,90,93]}
#转换为DataFrame的数据格式
examDf = DataFrame(examDict)
#examDf
#绘制散点图
plt.scatter(examDf.分数,examDf.学习时间,color = 'b',label = "Exam Data")
#添加图的标签(x轴,y轴)
plt.xlabel("Hours")
plt.ylabel("Score")
#显示图像
plt.show()
#将原数据集拆分训练集和测试集
exam_X = examDf.学习时间
exam_Y = examDf.分数
X_train,X_test,Y_train,Y_test = train_test_split(exam_X,exam_Y,train_size=0.8)
#X_train为训练数据标签,X_test为测试数据标签,exam_X为样本特征,exam_y为样本标签,train_size 训练数据占比
print("原始数据特征:",exam_X.shape,
",训练数据特征:",X_train.shape,
",测试数据特征:",X_test.shape)
print("原始数据标签:",exam_Y.shape,
",训练数据标签:",Y_train.shape,
",测试数据标签:",Y_test.shape)
model = LinearRegression()
#对于模型错误我们需要把我们的训练集进行reshape操作来达到函数所需要的要求
# model.fit(X_train,Y_train)
#reshape如果行数=-1的话可以使我们的数组所改的列数自动按照数组的大小形成新的数组
#因为model需要二维的数组来进行拟合但是这里只有一个特征所以需要reshape来转换为二维数组
X_train = X_train.values.reshape(-1,1)
X_test = X_test.values.reshape(-1,1)
model.fit(X_train,Y_train)
a = model.intercept_#截距
b = model.coef_#回归系数
print("最佳拟合线:截距",a,",回归系数:",b)
接下来算出拟合优度看看 ,拟合优度0.83,符合要求
# 用训练集进行拟合优度,验证回归方程是否合理
def get_lr_stats(x, y, model):
message0 = '一元线性回归方程为: '+'\ty' + '=' + str(model.intercept_)+' + ' +str(model.coef_[0]) + '*x'
from scipy import stats
n = len(x)
y_prd = model.predict(x)
Regression = sum((y_prd - np.mean(y))**2) # 回归平方和
Resial = sum((y - y_prd)**2) # 残差平方和
total = sum((y-np.mean(y))**2) #总体平方和
R_square = 1-Resial / total # 相关性系数R^2
message1 = ('相关系数(R^2): ' + str(R_square) + ';' + '\n'+ '总体平方和(TSS): ' + str(total) + ';' + '\n')
message2 = ('回归平方和(RSS): ' + str(Regression) + ';' + '\n残差平方和(ESS): ' + str(Resial) + ';' + '\n')
return print(message0 +'\n' +message1 + message2 )
get_lr_stats(X_train,Y_train,model)
在这里插入图片描述
如果需要,可以把所有点和回归直线画出来,直观感受一下