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

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

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


当前回答

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

from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_true, y_pred , squared=False)

其他回答

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

from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_true, y_pred , squared=False)

下面是一个示例代码,计算两种多边形文件格式PLY之间的RMSE。它同时使用ml_metrics库和np. linalgg .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])

Kaggle内核中有一个ml_metrics库,无需预安装即可使用,非常轻量级,可以通过pypi访问(使用pip install ml_metrics即可轻松快速安装):

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

它有一些其他有趣的指标,这些指标在sklearn中是不可用的,比如mapk。

引用:

https://pypi.org/project/ml_metrics/ https://github.com/benhamner/Metrics/tree/master/Python

基准

对于不需要开销处理程序并且总是期望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结果。你自己试试。

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

from sklearn.metrics import mean_squared_error
mean_squared_error(y_actual, y_predicted, squared=False)