R 与 scikit-learn 中用于线性回归 R2 的交叉验证

Posted

技术标签:

【中文标题】R 与 scikit-learn 中用于线性回归 R2 的交叉验证【英文标题】:Cross validation in R vs scikit-learn for linear regression R2 【发布时间】:2020-04-06 12:26:07 【问题描述】:

我有一个简单的线性回归模型:

Y = 平均能量,X = A + B

我的数据集仅包含 23 行。

因此,为了得到模型的训练R2,我做了5折交叉验证(cv)。

Python 中使用的模型是 scikit 的 LinearRegression,R 中是 lm。

为了在 Python 中做 cv,我在 scikit-learn 中使用了 cross_validate 函数,cross_validate(model, X, Y, cv=5, scoring='r2')

要在 R 中执行 cv,我使用了插入符号包 model <- train(Y ~ A + B ,data = df, method = "lm", trControl = train.control)trControl=trainControl(method = "cv", number = 5)。然后使用model$resample查看简历R2。

与 Python 相比,R 中的 cv R2 波动很大。请参阅下面的结果。知道为什么吗?谢谢。

注意下面的R2不是测试分数,是模型的训练R2。

在 R 中训练 cv R2:

Fold 1 = 0.6686680
Fold 2 = 0.3571826
Fold 3 = 0.8858084
Fold 4 = 0.7081766
Fold 5 = 0.3101449

用 Python 训练 cv R2:

Fold 1 = 0.29353287
Fold 2 = 0.24257606
Fold 3 = 0.38664367
Fold 4 = 0.26943862
Fold 5 = 0.24531835

仅供参考,对于 R 交叉验证,我指的是 https://quantdev.s-s-ri.psu.edu/tutorials/cross-validation-tutorial

数据集:https://drive.google.com/file/d/1rLeJ9_myCboM4jzX0wZ9rSZ3s9aRpLTo/view?usp=sharing

Y, A, B
12.48, 0.22, 0.33
5.32, 0.11, 0.22
13.71, 0.33, 0.44
27.48, 0.56, 0.44
3.87, 0.22, 0.56
3.88, 0.33, 0.11
37.90, 0.56, 0.11
10.62, 0.44, 0.22
41.71, 0.44, 0.44
1.96, 0.11, 0.33
25.14, 0.22, 0.33
2.25, 0.33, 0.33
9.73, 0.11, 0.22
8.67, 0.44, 0.33
3.80, 0.56, 0.33
35.90, 0.44, 0.33
3.43, 0.33, 0.11
6.68, 0.11, 0.56
13.54, 0.44, 0.44
8.04, 0.33, 0.22
6.41, 0.56, 0.11
31.67, 0.11, 0.67
70.59, 0.33, 0.56

【问题讨论】:

有趣的问题。您能否发布一个指向您的 csv 的链接,或者只是将要读取的数据硬编码到数据框中,以便我们可以重现它? @MaxPower 我添加了 csv 链接 python的型号是什么? @PV8 scikit 线性回归。我会在帖子里说清楚 【参考方案1】:

我不知道这是否有帮助,但python分数是正确的:

import pandas as pd
d = 'Y': [12.48, 5.32, 13.71, 27.48, 3.87, 3.88, 37.90, 10.62, 41.71, 1.96, 25.14, 2.25, 9.73, 8.67, 3.80, 35.90, 3.43, 6.68, 13.54, 8.04, 6.41, 31.67, 70.59],
     'A': [0.22, 0.11,0.33,0.56,0.22, 0.33, 0.56, 0.44, 0.44, 0.11, 0.22, 0.33, 0.11, 0.44, 0.56, 0.44, 0.33, 0.11, 0.44, 0.33, 0.56, 0.11, 0.33],
     'B': [0.33, 0.22, 0.44, 0.44, 0.56, 0.11, 0.11, 0.22, 0.44, 0.33, 0.33, 0.33, 0.22, 0.33, 0.33, 0.33, 0.11, 0.56, 0.44, 0.22, 0.11, 0.67, 0.56]
df = pd.DataFrame(data=d)
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_validate
model = LinearRegression()
X = df[['A', 'B']]
Y = df[['Y']]
cross_validate(model, X, Y, cv=5, scoring='r2')

输出:

'fit_time': array([0.        , 0.        , 0.        , 0.        , 0.01559973]),
 'score_time': array([0.01559997, 0.        , 0.        , 0.        , 0.        ]),
 'test_score': array([-1.31785296,  0.02722109, -4.055718  , -0.07446545, -0.39258268]),
 'train_score': array([0.29353287, 0.24257606, 0.38664367, 0.26943862, 0.24531835])

如果你看到测试分数,输出甚至更差。

我不知道 R 在做什么,但如果你看到 correlation:df.corr():

这也不好,如果你问我,R 正在做一些过度拟合,你会看到火车分数吗?

【讨论】:

是的,我正在查看模型的训练 R2。我认为这可能与 R2 的插入符号包进行随机 k 折拆分的方式有关。 @PV8

以上是关于R 与 scikit-learn 中用于线性回归 R2 的交叉验证的主要内容,如果未能解决你的问题,请参考以下文章

机器学习系列6 使用Scikit-learn构建回归模型:简单线性回归多项式回归与多元线性回归

[机器学习与scikit-learn-20]:算法-逻辑回归-线性逻辑回归linear_model.LogisticRegression与代码实现

[机器学习与scikit-learn-29]:算法-回归-普通线性回归LinearRegression拟合线性分布数据的代码示例

[机器学习与scikit-learn-27]:算法-回归-多元线性回归的几何原理线性代数原理本质(去掉激活函数的神经元)

[机器学习与scikit-learn-21]:算法-逻辑回归-多项式非线性回归PolynomialFeatures与代码实现

[机器学习与scikit-learn-31]:算法-回归-线性模拟拟合拟合非线性数据-概述