218

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

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

如果这个 rmse 函数是在某个库中实现的,我在寻找什么,也许在 scipy 或 scikit-learn 中?

4

14 回答 14

313

sklearn >= 0.22.0

sklearn.metrics有一个mean_squared_error带有squaredkwarg 的函数(默认为True)。设置squaredFalse将返回 RMSE。

from sklearn.metrics import mean_squared_error

rms = mean_squared_error(y_actual, y_predicted, squared=False)

sklearn < 0.22.0

sklearn.metrics有一个mean_squared_error功能。RMSE 只是它返回的任何东西的平方根。

from sklearn.metrics import mean_squared_error
from math import sqrt

rms = sqrt(mean_squared_error(y_actual, y_predicted))
于 2013-09-04T20:56:57.047 回答
158

什么是 RMSE?也称为 MSE、RMD 或 RMS。它解决了什么问题?

如果您了解 RMSE:(均方根误差)、MSE:(均方误差)RMD(均方根偏差)和 RMS:(均方根),那么请一个库为您计算这个是不必要的过度工程. 所有这些指标都是一行最多 2 英寸长的 Python 代码。这三个度量 rmse、mse、rmd 和 rms 在其核心概念上是相同的。

RMSE 回答了这个问题:“平均而言,与 的数字有多相似list1list2”。这两个列表的大小必须相同。我想“消除任何两个给定元素之间的噪音,消除所收集数据的大小,并获得一个随时间变化的单一数字感觉”。

RMSE 的直觉和 ELI5:

想象一下,你正在学习向飞镖板投掷飞镖。每天练习一小时。你想弄清楚你是变得更好还是变得更糟。因此,您每天进行 10 次投掷并测量靶心和飞镖击中位置之间的距离。

你列出这些数字list1list2使用第 1 天的距离与包含全零的距离之间的均方根误差。在第 2 天和第 n 天做同样的事情。你会得到一个单一的数字,希望随着时间的推移而减少。当您的 RMSE 数为零时,您每次都击中靶心。如果 rmse 值上升,你会变得更糟。

在python中计算均方根误差的示例:

import numpy as np
d = [0.000, 0.166, 0.333]   #ideal target distances, these can be all zeros.
p = [0.000, 0.254, 0.998]   #your performance goes here

print("d is: " + str(["%.8f" % elem for elem in d]))
print("p is: " + str(["%.8f" % elem for elem in p]))

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

rmse_val = rmse(np.array(d), np.array(p))
print("rms error is: " + str(rmse_val))

哪个打印:

d is: ['0.00000000', '0.16600000', '0.33300000']
p is: ['0.00000000', '0.25400000', '0.99800000']
rms error between lists d and p is: 0.387284994115

数学符号:

均方根偏差解释

字形图例: n是一个表示投掷次数的正整数。 i表示枚举总和的整个正整数计数器. d代表理想距离,list2在上面的例子中包含全零。 p代表性能,list1在上面的例子中。上标 2 代表数字平方。 d i是 的第 i 个索引dp i是 的第 i 个索引p

rmse 以小步骤完成,因此可以理解:

def rmse(predictions, targets):

    differences = predictions - targets                       #the DIFFERENCEs.

    differences_squared = differences ** 2                    #the SQUAREs of ^

    mean_of_differences_squared = differences_squared.mean()  #the MEAN of ^

    rmse_val = np.sqrt(mean_of_differences_squared)           #ROOT of ^

    return rmse_val                                           #get the ^

RMSE 的每一步是如何工作的:

从另一个数字中减去一个数字可以得出它们之间的距离。

8 - 5 = 3         #absolute distance between 8 and 5 is +3
-20 - 10 = -30    #absolute distance between -20 and 10 is +30

如果将任何数字乘以自身,结果总是正数,因为负数乘以负数是正数:

3*3     = 9   = positive
-30*-30 = 900 = positive

将它们全部加起来,但是等等,一个包含许多元素的数组会比一个小数组有更大的误差,所以用元素的数量来平均它们。

但是等等,我们早先将它们全部平方以迫使它们积极。用平方根消除损坏!

这给您留下了一个数字,平均而言,它表示 list1 的每个值与其对应的 list2 元素值之间的距离。

如果 RMSE 值随着时间的推移而下降,我们会很高兴,因为方差正在减少。“缩小方差”是一种机器学习算法。

RMSE 不是最准确的线拟合策略,总最小二乘为:

均方根误差测量点和线之间的垂直距离,因此,如果您的数据形状像香蕉,底部附近平坦,顶部附近陡峭,则 RMSE 将报告到高点的距离更大,但距离短实际上距离相等时点低。这会导致线更靠近高点而不是低点的倾斜。

如果这是一个问题,总最小二乘法可以解决这个问题: https ://mubaris.com/posts/linear-regression

可以破坏此 RMSE 函数的陷阱:

如果任一输入列表中有空值或无穷大,则输出 rmse 值将没有意义。有三种策略来处理任一列表中的空值/缺失值/无穷大:忽略该分量,将其归零或向所有时间步添加最佳猜测或均匀随机噪声。每种补救措施都有其优缺点,具体取决于您的数据的含义。一般来说,忽略任何具有缺失值的组件是首选,但这会使 RMSE 偏向零,使您认为性能已经提高,而实际上并没有提高。如果有很多缺失值,最好在最佳猜测上添加随机噪声。

为了保证 RMSE 输出的相对正确性,您必须从输入中消除所有空值/无限值。

RMSE 对不属于的异常数据点具有零容忍度

均方根误差平方依赖于所有数据都是正确的,并且所有数据都被视为相等。这意味着在左侧字段中的一个偏离点将完全破坏整个计算。要处理异常数据点并在某个阈值后消除它们的巨大影响,请参阅建立阈值的稳健估计器,将异常值视为不需要控制的极端罕见事件:如流氓波:https://youtu .be/8Zpi9V0_5tw?t=5

于 2016-06-16T14:17:14.580 回答
38

在 scikit-learn 0.22.0 中,您可以传递mean_squared_error()参数squared=False以返回 RMSE。

from sklearn.metrics import mean_squared_error
mean_squared_error(y_actual, y_predicted, squared=False)
于 2020-01-26T16:38:42.903 回答
27

这可能更快?:

n = len(predictions)
rmse = np.linalg.norm(predictions - targets) / np.sqrt(n)
于 2013-06-20T19:08:39.450 回答
18

sklearnmean_squared_error本身包含一个参数squared,默认值为True. 如果我们将其设置为False,相同的函数将返回 RMSE 而不是 MSE。

from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_true, y_pred , squared=False)
于 2020-03-03T12:50:58.333 回答
11

ml_metrics在 Kaggle 的内核中有一个无需预先安装即可使用的库,非常轻量级并且可以通过以下方式访问pypi(它可以通过 轻松快速地安装pip install ml_metrics):

from ml_metrics import rmse
rmse(actual=[0, 1, 2], predicted=[1, 10, 5])
# 5.507570547286102

它几乎没有其他有趣的指标,这些指标sklearnmapk.

参考:

于 2019-04-22T19:59:27.727 回答
7

或者仅使用 NumPy 函数:

def rmse(y, y_pred):
    return np.sqrt(np.mean(np.square(y - y_pred)))

在哪里:

  • y是我的目标
  • y_pred 是我的预测

请注意,rmse(y, y_pred)==rmse(y_pred, y)由于平方函数。

于 2019-05-18T08:26:44.457 回答
2
from sklearn import metrics              
import numpy as np
print(np.sqrt(metrics.mean_squared_error(y_test,y_predict)))
于 2020-08-29T07:07:19.637 回答
1

是的,它是由 SKLearn 提供的,我们只需要squared = False在参数中提及

from sklearn.metrics import mean_squared_error

mean_squared_error(y_true, y_pred, squared=False)
于 2022-01-11T10:36:37.217 回答
1
from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_actual, y_predicted, squared=False)

or 

import math
from sklearn.metrics import mean_squared_error
rmse = math.sqrt(mean_squared_error(y_actual, y_predicted))
于 2021-01-01T19:29:48.733 回答
0

这是计算两种多边形文件格式之间的 RMSE 的示例代码PLY。它同时使用ml_metricslib 和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])
于 2019-04-30T08:27:48.277 回答
0
  1. 不,有一个用于机器学习的库 Scikit Learn,它可以通过使用 Python 语言轻松使用。它具有均方误差的功能,我在下面分享链接:

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

  1. 该函数名为 mean_squared_error ,如下所示,其中 y_true 是数据元组的真实类值,y_pred 是预测值,由您使用的机器学习算法预测:

mean_squared_error(y_true, y_pred)

  1. 您必须对其进行修改以获得 RMSE(通过使用 Python 使用 sqrt 函数)。此链接中描述了此过程: https ://www.codeastar.com/regression-model-rmsd/

因此,最终代码将类似于:

从 sklearn.metrics 导入 mean_squared_error 从数学导入 sqrt

RMSD = sqrt(mean_squared_error(testing_y,预测))

打印(RMSD)

于 2019-08-05T03:35:03.820 回答
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)

额外说明:在我的用例中,在numba上给出略有不同但可以忽略不计的结果np.sqrt(((y1-y2)**2).mean()),如果没有numba,结果将等于scipy结果。自己试试。

于 2021-12-29T14:44:58.770 回答
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))
于 2021-12-16T11:35:32.893 回答