查找最高的R^2值

1 投票
1 回答
1145 浏览
提问于 2025-04-30 18:47

我刚开始学Python,遇到一个问题。我有一组数据:

import numpy as np

x=np.arange(1,5)
y=np.arange(5,9)

我的问题是想找到一个数字n(不一定是整数),这个数字能让我在绘制y^n和x的图时,R^2值达到最高。我在想可以这样生成n:

n=np.linspace(1,9,100)

但我不知道怎么实现这个想法。另一种方法是用暴力法生成n,然后把y的值提高到每个n的次方。得到这个值后(假设叫y1),我就可以绘制y1和x的图(这意味着我需要生成100个图)。但是我不知道怎么计算某个图的R^2值(用于线性拟合)。

我想做的是得到一个R^2值的列表(或数组):

R2= np.array() #a set containing the R^2 values calculated from the plots

然后找出这个数组中的最大值,接着找到对应这个R^2值的图,这样我就能找到一个特定的n。我不知道该怎么做。

暂无标签

1 个回答

0

如果你会使用pandas这个库,那么这个问题就很简单了:

import pandas
import numpy as np

x = pandas.Series(np.arange(1,5))
y = pandas.Series(np.arange(5,9))
exponents = exponents = np.linspace(1, 9, 100)

r2s = {n:pandas.ols(x=x, y=y**n).r2 for n in exponents}
max(r2s.iteritems(), key=lambda x: x[1])
#>>> (1.0, 1.0)

我们来分解一下:

  1. pandas.Series对象就像是一列有索引的数据。它类似于numpy数组,但功能更多。在这里,我们之所以关心它,是因为我们可以把它传给pandas.ols
  2. pandas.ols是最小二乘回归的基本实现。你也可以直接用numpy里的numpy.linalg.lstsq来做这个,但它不会直接给你R平方值。如果你想用纯粹的numpy来做,就需要从numpy的lstsq中得到平方残差的总和,然后手动计算R平方。你可以为自己写一个函数(这可能是个不错的练习)。
  3. {..}里面的东西是一个dict推导式。它会遍历你想要的指数,对每个指数执行ols函数,并报告.r2属性(R平方统计量存储的地方),并根据用来获取它的指数编号进行索引。
  4. 最后一步是对r2s中的键值对序列调用maxkey告诉max要根据第二个元素(R平方)来比较这些元素。

这里有一个示例函数,只用np.linalg.lstsq来实现这个功能(这是一个关于如何在numpy中计算R2的好解释):

def r2(x, y):
    x_with_intercept = np.vstack([x, np.ones(len(x))]).T
    coeffs, resid = np.linalg.lstsq(x_with_intercept, y)[:2]
    return 1 - resid / (y.size * y.var())[0]

然后在纯numpy中,上面的做法是:

import numpy as np

x = np.arange(1,5)
y = np.arange(5,9)
exponents = np.linspace(1, 9, 100)

r2s = {n:r2(x=x, y=y**n) for n in exponents}
max(r2s.iteritems(), key=lambda x: x[1])
#>>> (1.0, 1.0)

最后提一下,还有一种更高级的方式来指定从某个东西中获取第一个位置的项。你可以使用内置库operator和可调用的itemgetter

max(..., key=operator.itemgetter(1))

表达式itemgetter(1)会生成一个可调用的对象——当它在参数r上被调用时,会触发__getitem__协议,从而得到r[1]

撰写回答