使用curve_fit获取R平方值

37
我是一个初学者,对Python及其库都不熟悉。但我已经成功地编写了一个小程序,它按预期工作。该程序接受一个字符串,计算不同字母的出现次数并在图表中绘制它们,然后应用一个方程及其曲线。 现在我想得到拟合的R平方值。
总体思路是比较来自不同水平文章的不同文本,并查看整体模式的强度。
这只是一个练习,我是新手,因此易于理解的答案会很棒。
代码如下:
import numpy as np
import math
import matplotlib.pyplot as plt
from matplotlib.pylab import figure, show
from scipy.optimize import curve_fit

s="""det, og deres undersøgelse af hvor meget det bliver brugt viser, at der kun er seks plugins, som benyttes af mere end 5 % af Chrome-brugere.
Problemet med teknologien er, at den ivivuilv rduyd iytf ouyf ouy yg oyuf yd iyt erzypu zhrpyh dfgopaehr poargi ah pargoh ertao gehorg aeophgrpaoghraprbpaenbtibaeriber en af hovedårsagerne til sikkerhedshuller, ustabilitet og deciderede nedbrud af browseren.
Der vil ikke bve lukket for API'et  ivivuilv rduyd iytf ouyf ouy yg oyuf yd iyt erzypu zhrpyh dfgopaehr poargi ah pargoh ertao gehorg aeophgrpaoghraprbpaenbtibaeriber en af hovedårsagerne til sikkerhedshuller, ustabilitet og deciderede nedbrud af browseren.
Der vil ikke blive lukket for API'et på én gang, men det vil blive udfaset i løbet af et års tid. De mest populære plugins får lov at fungere i udfasningsperioden; Det drejer sig om: Silverlight (anvendt af 15 % af Chrome-brugere sidste måned), Unity (9,1 %), Google Earth (9,1 %), Java (8,9%), Google Talk (8,7 %) og Facebook Video (6,0 %).
Det er muligt at hvidliste andre plugins, men i slutningen af 2014 forventer udviklerne helt at lukke for brugen af dem."""
fordel=[]
alf=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','æ','ø','å']
i=1
p=0
fig = figure()
ax1 = fig.add_subplot(1,2,0)
for i in range(len(alf)):
    fordel.append(s.count(alf[i]))
    i=i+1   
fordel=sorted(fordel,key=int,reverse=True)
yFit=fordel
xFit=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28]
def func(x, a, b):
    return a * (b ** x)
popt, pcov = curve_fit(func, xFit, yFit)
t = np.arange(0.0, 30.0, 0.1)
a=popt[0]
b=popt[1]
s = (a*b**t)
ax1.plot(t,s)
print(popt)
yMax=math.ceil(fordel[0]+5)
ax1.axis([0,30,0,yMax])
for i in range(0,int(len(alf))*2,2):
    fordel.insert(i,p)
    p=p+1
for i in range(0,int(len(fordel)/2)):
    ax1.scatter(fordel[0],fordel[1])
    fordel.pop(0)
    fordel.pop(0)
plt.show()
show()
3个回答

97

计算r_squared值:

r_squared 值可以通过使用均值(mean)、总平方和 (ss_tot) 和残差平方和(ss_res) 来计算,它们的定义如下:

mean

SStot

SSres

rsquared

f_i 代表 x_i 点的函数值。引自 维基百科

scipy.optimize.curve_fit() 中取得以下信息:

  • 通过 curve_fit() 可以获得参数 (popt),使用方法为

    popt, pcov = curve_fit(f, xdata, ydata)

  • 可以通过以下方式得出残差平方和 (ss_res)

    • residuals = ydata- f(xdata, *popt)
    • ss_res = numpy.sum(residuals**2)
  • 可以通过以下方式得出总离差平方和 (ss_tot)

    ss_tot = numpy.sum((ydata-numpy.mean(ydata))**2)

  • 最后,r_squared 值可通过以下方式得出

    r_squared = 1 - (ss_res / ss_tot)


2
当然!太棒了的答案。出于某种原因,我没有考虑过自己计算它,尽管它似乎非常简单。谢谢。 - Mathias
9
两个问题:1. 在残差方程中,popt不应该被替换为*popt吗?2. 为什么不使用pcov? - Foad S. Farimani
9
这段话的意思是:这个方法和回答“拿起笔和纸,打开维基百科,自己编程”一样有用!对于scipy中的线性拟合,我们可以得到标准输出;对于任何求解器,输出结果都是一个整洁的包含t统计量、p值、对数似然等信息的表格。但是对于 curve_fit,最好的回答却是:“自己动手编程”。 - Intelligent-Infrastructure

8

关于R2scipy中似乎没有直接实现的一些背景

您可以使用sklearn.metrics.r2_score

从您的示例中:

from sklearn.metrics import r2_score
popt, pcov = curve_fit(func, xFit, yFit)
y_pred = func(xFit, *popt)
r2_score(yFit, y_pred)

0
我认为这种方法是解决最小化问题的更简单的方法:
res = minimize(func)  # your optimize function
cof = np.reshape(np.array(res.x),(-1,1))
r_square = 1.0 - (np.var(ydata-xdata.dot(cof)) / np.var(ydata))

# or 
# r_square = 1 - np.square(ydata-xdata.dot(cof)).sum() / (np.var(ydata) * len(ydata))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接