Python中是否有用于均方根误差(RMSE)的库函数?

264

我知道我可以像这样实现一个均方根误差函数:

def rmse(predictions, targets):
    return np.sqrt(((predictions - targets) ** 2).mean())

如果这个RMSE函数已经在某个库中实现了,比如说scipy或者scikit-learn,我是希望能够找到它的。


7
你在那里写了这个函数。如果函数写起来很简单,很可能不会出现在库中。你最好创建一个名为“modules”的目录,将有用的函数放入其中,并将其添加到您的路径中。 - Ryan Saxe
27
我不同意@RyanSaxe的观点。与其自己重新实现一个函数,我更愿意调用库函数。比如说,我原本想用.mean(),但写成了.sum()。此外,我认为这个函数被使用得如此频繁,没有理由不将其作为库函数供人使用。 - siamii
3
我理解100%。我只是在推测为什么这种函数可能不在scipy中。如果有的话,我似乎找不到它。 - Ryan Saxe
1
对于那些尝试过但没有成功的人:如果predictionstargets的类型例如为int16,则平方可能会溢出(产生负数)。因此,在使用平方之前,您可能需要使用.astype('int').astype('double'),例如np.sqrt(((predictions - targets).astype('double') ** 2).mean()) - John
1
在sklearn中拥有这个的另一个优点是,sklearn的实现具有大量额外的样板代码,以确保数组具有相同的形状,并包括权重参数,还处理多维数组和不同的“类似数组”。做所有这些将使问题变得更加复杂。 - David Waterworth
显示剩余2条评论
14个回答

0

如果你正在处理复数,那么你可能想要添加绝对值np.abs

import numpy as np
rms = np.sqrt(np.mean(np.abs(x-y)**2))

请注意,如果您使用np.linalg.norm,它已经处理了复数。
import numpy as np
rms = np.linalg.norm(x-y)/np.sqrt(len(x))

0
这是一个计算两个多边形文件格式 PLY 之间 RMSE 的示例代码。它同时使用了 ml_metrics 库和 np.linalg.norm 函数:
import sys
import SimpleITK as sitk
from pyntcloud import PyntCloud as pc
import numpy as np
from ml_metrics import rmse

if len(sys.argv) < 3 or sys.argv[1] == "-h" or sys.argv[1] == "--help":
    print("Usage: compute-rmse.py <input1.ply> <input2.ply>")
    sys.exit(1)

def verify_rmse(a, b):
    n = len(a)
    return np.linalg.norm(np.array(b) - np.array(a)) / np.sqrt(n)

def compare(a, b):
    m = pc.from_file(a).points
    n = pc.from_file(b).points
    m = [ tuple(m.x), tuple(m.y), tuple(m.z) ]; m = m[0]
    n = [ tuple(n.x), tuple(n.y), tuple(n.z) ]; n = n[0]
    v1, v2 = verify_rmse(m, n), rmse(m,n)
    print(v1, v2)

compare(sys.argv[1], sys.argv[2])

0

基准测试

对于特定的使用情况,如果您不需要开销处理程序并且总是期望numpy数组输入,则最快的方法是在numpy中手动编写函数。更重要的是,如果您经常调用它,可以使用numba来加速。

import numpy as np
from numba import jit
from sklearn.metrics import mean_squared_error

%%timeit
mean_squared_error(y[i],y[j], squared=False)

445 µs ± 90.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

def euclidian_distance(y1, y2):
    """
    RMS Euclidean method
    """
    return np.sqrt(((y1-y2)**2).mean())

%%timeit
euclidian_distance(y[i],y[j])

28.8 µs ± 2.54 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

@jit(nopython=True)
def jit_euclidian_distance(y1, y2):
    """
    RMS Euclidean method
    """
    return np.sqrt(((y1-y2)**2).mean())

%%timeit
jit_euclidian_distance(y[i],y[j])

2.1 µs ± 234 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

@jit(nopython=True)
def jit2_euclidian_distance(y1, y2):
    """
    RMS Euclidean method
    """
    return np.linalg.norm(y1-y2)/np.sqrt(y1.shape[0])

%%timeit
jit2_euclidian_distance(y[i],y[j])

2.67 µs ± 60.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

额外说明:在我的使用情况中,numbanp.sqrt(((y1-y2)**2).mean()) 上给出了略微不同但可以忽略的结果,而没有 numba,结果将等于 scipy 的结果。你可以自己试试。


0
不,有一个用于机器学习的Scikit Learn库,可以通过使用Python语言轻松地应用它。它具有一个用于均方误差的函数,我在下面分享链接:

https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html

  • 该函数被命名为mean_squared_error,如下所示,其中y_true是数据元组的真实类值,y_pred是机器学习算法预测的值:
  • mean_squared_error(y_true, y_pred)

  • 您需要修改它以获得RMSE(使用Python中的sqrt函数)。此过程在以下链接中描述: https://www.codeastar.com/regression-model-rmsd/
  • 因此,最终代码将类似于:

    from sklearn.metrics import mean_squared_error
    from math import sqrt
    
    RMSD = sqrt(mean_squared_error(testing_y, prediction))
    
    print(RMSD)
    

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