Jua*_*oto 4 python numpy scikit-learn goodness-of-fit
为什么r2_scorescikit-learn中的函数与维基百科中描述的确定系数公式之间存在显着差异?哪个是正确的?
我正在使用Python 3.5来预测线性和二次模型,而我正在尝试的适合度的衡量标准之一是.但是,在测试时,维基百科中提供的r2_score指标scikit-learn与计算之间存在显着差异.
我在这里提供我的代码作为参考,它计算上面链接的维基百科页面中的示例.
from sklearn.metrics import r2_score import numpy y = [1, 2, 3, 4, 5] f = [1.9, 3.7, 5.8, 8.0, 9.6] # Convert to numpy array and ensure double precision to avoid single precision errors observed = numpy.array(y, dtype=numpy.float64) predicted = numpy.array(f, dtype=numpy.float64) scipy_value = r2_score(observed, predicted) >>> scipy_value:
很明显,scipy计算值是-3.8699999999999992维基百科中的参考值0.998.
谢谢!
更新:这与关于如何在scikit-learn中计算R ^ 2的问题不同,我正在努力理解并澄清两种结果之间的差异.这个问题表明scikit中使用的公式与维基百科的公式相同,不应该导致不同的值.
更新#2:事实证明我在阅读维基百科文章的例子时犯了一个错误.下面的答案和评论提到我提供的示例是针对示例中(x,y)值的线性,最小二乘拟合.为此,维基百科的文章中的答案是正确的.为此,提供的R ^ 2 calue为0.998.对于两个向量之间的R ^ 2,scikit的答案也是正确的.非常感谢你的帮助!
引用的问题是正确的 - 如果您通过计算剩余的平方和和总平方和,则得到与sklearn相同的值:
In [85]: import numpy as np
In [86]: y = [1,2,3,4,5]
In [87]: f = [1.9, 3.7, 5.8, 8.0, 9.6]
In [88]: SSres = sum(map(lambda x: (x[0]-x[1])**2, zip(y, f)))
In [89]: SStot = sum([(x-np.mean(y))**2 for x in y])
In [90]: SSres, SStot
Out[90]: (48.699999999999996, 10.0)
In [91]: 1-(SSres/SStot)
Out[91]: -3.8699999999999992
Run Code Online (Sandbox Code Playgroud)
负值背后的想法是,如果你每次只预测平均值(这对应于r2 = 0),你就更接近实际值.
我认为您误解了维基百科。维基百科上的示例未声明:
y=[1,2,3,4,5]
f=[1.9, 3.7, 5.8, 8.0, 9.6]
R^2 = 0.998
Run Code Online (Sandbox Code Playgroud)
相反,它表示R^2用于线性最小二乘法的拟合数据:
x=[1,2,3,4,5]
y=[1.9, 3.7, 5.8, 8.0, 9.6]
Run Code Online (Sandbox Code Playgroud)
等于 0.998
考虑一下此脚本,该脚本首先用于np.linalg.lstsq查找最小二乘拟合,然后使用这两种方法为这两种方法找到一个R^20.998的值:
import numpy as np
from sklearn.metrics import r2_score
x=np.arange(1,6,1)
y=np.array([1.9, 3.7, 5.8, 8.0, 9.6])
A=np.vstack([x, np.ones(len(x))]).T
# Use numpy's least squares function
m, c = np.linalg.lstsq(A, y)[0]
print m,c
# 1.97 -0.11
# Define the values of our least squares fit
f=m*x+c
print f
# [ 1.86 3.83 5.8 7.77 9.74]
# Calculate R^2 explicitly
yminusf2=(y-f)**2
sserr=sum(yminusf2)
mean=float(sum(y))/float(len(y))
yminusmean2=(y-mean)**2
sstot=sum(yminusmean2)
R2=1.-(sserr/sstot)
print R2
# 0.99766066838
# Use scikit
print r2_score(y,f)
# 0.99766066838
r2_score(y,f) == R2
# True
Run Code Online (Sandbox Code Playgroud)
两种方法都使用相同的公式来计算 R 方。查看下面的代码:
# Data
X=np.array([1.9, 3.7, 5.8, 8.0, 9.6]).reshape(-1, 1)
y=[1,2,3,4,5]
# Import module
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
reg = LinearRegression().fit(X, y)
# Predict the target variable
y_pred=reg.predict(X)
# R-Square fitness
print('R-Square(metrics):', r2_score(y, y_pred))
# R-Square using score method
print('R-Sqaure(Score):',reg.score(X, y))
Run Code Online (Sandbox Code Playgroud)
输出: R 方(指标):0.9976606683804627 R 方(分数):0.9976606683804627
| 归档时间: |
|
| 查看次数: |
9417 次 |
| 最近记录: |