Есть ли библиотечная функция для среднеквадратической ошибки (RMSE) в python?


158

Я знаю, что мог бы реализовать функцию среднеквадратичной ошибки следующим образом:

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

Что я ищу, если эта функция rmse реализована где-то в библиотеке, возможно, в scipy или scikit-learn?


5
Вы написали функцию прямо там. Скорее всего, если функцию так просто написать, ее не будет в библиотеке. вам лучше создать директора под названием модули и просто добавить в него полезные функции и добавить его на свой путь
Райан Сакс

14
@RyanSaxe Я не согласен. Я бы посчитал гораздо более обнадеживающим вызывать библиотечную функцию, чем переопределять ее сам. Например, я написал .sum()вместо .mean()первого по ошибке. Кроме того, я полагаю, что эта функция используется так часто, что я не вижу причин, почему она не должна быть доступна как библиотечная функция.
Сиамия

1
@siamii: Я понимаю, что 100%, я просто размышлял о причине, по которой такого рода функции могут быть не в порядке. Если это так, я не могу найти его
Райан Сакс

1
Людям, которые попробовали это, и это не сработало: если predictionsи targets, например, типа, int16квадрат может переполниться (давая отрицательные числа). Таким образом, вам может понадобиться .astype('int')или .astype('double')перед использованием квадрата, как np.sqrt(((predictions - targets).astype('double') ** 2).mean()).
Джон

Еще одним преимуществом использования этого в sklearn является то, что реализации sklearn имеют множество дополнительных кодов котельной пластины, чтобы гарантировать, что массивы имеют одинаковую форму, и включают в себя весовые параметры, а также обрабатывают многомерные массивы и различные «массивы». Делать все это превращает это в гораздо более сложную проблему
Дэвид

Ответы:


214

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))

3
mean_squared_errorin sklearn.metricsтеперь поддерживает дополнительный параметр: squared- «Если True возвращает значение MSE, если False возвращает значение RMSE».
Daddy32

132

Что такое RMSE? Также известный как MSE, RMD или RMS. Какую проблему это решает?

Если вы понимаете RMSE: (среднеквадратическая ошибка), MSE: (среднеквадратичная ошибка) RMD (среднеквадратическое отклонение) и RMS: (среднеквадратичное отклонение), тогда запрос библиотеки для вычисления этого значения для вас не требуется. , Все эти метрики представляют собой одну строку кода Python длиной не более 2 дюймов. Три метрики rmse, mse, rmd и rms по своей сути концептуально идентичны.

RMSE отвечает на вопрос: «Насколько в среднем похожи цифры list1наlist2 ?». Два списка должны быть одинакового размера. Я хочу "стереть шум между любыми двумя данными элементами, вымыть размер собранных данных и почувствовать, как со временем меняется одно число".

Интуиция и ELI5 для RMSE:

Представьте, что вы учитесь бросать дротики в дартс. Каждый день вы тренируетесь в течение одного часа. Вы хотите выяснить, становится ли вам лучше или хуже. Поэтому каждый день вы делаете 10 бросков и измеряете расстояние между яблочком и местом удара дротика.

Вы делаете список этих чисел list1. Используйте среднеквадратичную ошибку между расстояниями в день 1 и a, list2содержащую все нули. Сделайте то же самое на 2-й и 9-й день. То, что вы получите, это одно число, которое, мы надеемся, со временем уменьшается. Когда ваш 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 -й индекс d. р я - это -й индекс 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 - не самая точная стратегия подгонки линии, наименьшее число квадратов:

Среднеквадратическая ошибка измеряет вертикальное расстояние между точкой и линией, поэтому, если ваши данные имеют форму банана, плоские у дна и крутые у вершины, то среднеквадратическое отклонение будет сообщать о больших расстояниях до высоких точек, но о коротких расстояниях до указывает низко, когда на самом деле расстояния эквивалентны. Это вызывает перекос, когда линия предпочитает быть ближе к точкам выше, чем ниже.

Если это проблема, метод общих наименьших квадратов исправляет это: https://mubaris.com/posts/linear-regression

Поправки, которые могут нарушить эту функцию RMSE:

Если в любом из входных списков есть нули или бесконечность, то выходное значение rmse не будет иметь смысла. Есть три стратегии, чтобы иметь дело с нулями / отсутствующими значениями / бесконечностями в любом списке: игнорировать этот компонент, обнулять его или добавлять наилучшее предположение или равномерный случайный шум для всех временных шагов. Каждое лекарство имеет свои плюсы и минусы в зависимости от того, что означают ваши данные. В общем случае предпочтительным является игнорирование любого компонента с отсутствующим значением, но это смещает среднеквадратичное отклонение к нулю, заставляя думать, что производительность улучшилась, хотя на самом деле это не так. Добавление случайного шума по наилучшему предположению может быть предпочтительным, если имеется много пропущенных значений.

Чтобы гарантировать относительную правильность выходных данных RMSE, вы должны исключить все нули / бесконечности из входных данных.

RMSE имеет нулевой допуск для посторонних точек данных, которые не принадлежат

Среднеквадратичные квадраты ошибок основаны на правильности всех данных, и все они считаются равными. Это означает, что одна случайная точка в левом поле полностью испортит весь расчет. Чтобы обработать точки данных выбросов и отклонить их огромное влияние после определенного порога, см. Надежные оценки, которые строят порог для отклонения выбросов.


3
Да, простая функция. Но если вам это нужно изо дня в день, используйте его, чтобы просто иметь где-то правильное решение, чтобы вам не приходилось каждый раз переопределять его; )
логично x 2

@ eric-leschinski, я был бы признателен, если бы вы могли взглянуть на это: stackoverflow.com/questions/45173451/…
Desta Haileselassie Hagos

1
Это определенно признак того поколения, о котором люди просят и указывают на библиотеки размером в несколько гигабайт; требуется от 3 до 20 минут загрузки по сети, затем установка полного наклона ЦП, когда все, что вам действительно нужно, это примерно 3 строки кода, которые умещаются в 400 байт. Если вы запрашиваете библиотеку для задания, которое можно сжать в 1 строку кода шириной около 90 символов, то вы даете лицензию на то, что люди будут злоупотреблять вами с помощью 3, 10 и вскоре 50-гигабайтных установок размером 99,9999. % раздувать. Это не ракетная операция. Ваш калькулятор на солнечной батарее, изготовленный в 1978 году с процессором 740 Гц, может работать как RMSE.
Эрик Лещинский

22

Это наверное быстрее?

n = len(predictions)
rmse = np.linalg.norm(predictions - targets) / np.sqrt(n)

18

В 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)

2
Это новая функция, и было бы лучше, если бы мы ее использовали.
Рави Г

9

На всякий случай, если кто-то найдет этот поток в 2019 году, есть библиотека, ml_metricsкоторая доступна без предварительной установки в ядрах Kaggle, довольно легковесна и доступна через pypi(ее можно легко и быстро установить pip install ml_metrics):

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

У него есть несколько других интересных метрик, которые не доступны sklearn, например mapk.

Ссылки:


4

На самом деле, я написал несколько из них в качестве служебных функций для statsmodels

http://statsmodels.sourceforge.net/devel/tools.html#measure-for-fit-performance-eval-measures

и http://statsmodels.sourceforge.net/devel/generated/statsmodels.tools.eval_measures.rmse.html#statsmodels.tools.eval_measures.rmse

В основном один или два лайнера и не очень много проверок ввода, и в основном они предназначены для простого получения статистики при сравнении массивов. Но у них есть модульные тесты для аргументов оси, потому что именно здесь я иногда делаю небрежные ошибки.


3

Или просто используя только функции NumPy:

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

Куда:

  • у моя цель
  • y_pred - мой прогноз

Обратите внимание, что rmse(y, y_pred)==rmse(y_pred, y)из-за функции квадрата.


3

Вы не можете найти функцию RMSE непосредственно в SKLearn. Но вместо того, чтобы вручную выполнять sqrt, есть другой стандартный способ использования sklearn. По-видимому, сам Sklearn mean_squared_error содержит параметр, называемый «квадрат» со значением по умолчанию, равным true. Если мы установим его в значение false, та же функция вернет RMSE вместо MSE.

# code changes implemented by Esha Prakash
from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_true, y_pred , squared=False)

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])

-1
  1. Нет, есть библиотека Scikit Learn для машинного обучения, и ее легко можно использовать с помощью языка Python. У него есть функция для Mean Squared Error, которой я делюсь по ссылке ниже:

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 (используя функцию sqrt с использованием Python). Этот процесс описан по этой ссылке: https://www.codeastar.com/regression-model-rmsd/

Итак, окончательный код будет выглядеть примерно так:

из sklearn.metrics import mean_squared_error из математического импорта sqrt

RMSD = sqrt (mean_squared_error (testing_y, прогноз))

печать (СКО)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.