scikit-learn & statsmodels - какой R-квадрат правильный? - PullRequest
0 голосов
/ 10 февраля 2019

Я бы хотел выбрать лучший алгоритм на будущее.Я нашел некоторые решения, но я не понял, какое значение R-Squared является правильным.

Для этого я разделил свои данные на две части в качестве теста и обучения и напечатал два разных значения R в квадрате ниже.

import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

lineer = LinearRegression()
lineer.fit(x_train,y_train)
lineerPredict = lineer.predict(x_test)

scoreLineer = r2_score(y_test, lineerPredict)  # First R-Squared

model = sm.OLS(lineerPredict, y_test)
print(model.fit().summary()) # Second R-Squared

Первый результат R-квадрата равен -4,28.
Второй результат R-квадрата равен 0,84

Но я не понял, какое значение является правильным.

Ответы [ 3 ]

0 голосов
/ 10 февраля 2019

Вы, похоже, используете sklearn.metrics_r2_score .В документации утверждается, что «наилучшая возможная оценка равна 1,0, и она может быть отрицательной (поскольку модель может быть произвольно хуже»)

В статье Википедии , к которой приводит документация, указывается, что "Значения R2 вне диапазона от 0 до 1 могут возникать, когда модель соответствует данным, которые хуже горизонтальной гиперплоскости. Это может произойти, если выбрана неправильная модель или если по ошибке применены бессмысленные ограничения ».По этой причине тот факт, что у вас был такой отрицательный показатель r2_score, вероятно, гораздо более важен, чем сравнительно хорошая (но не очень) статистика R ^ 2, вычисленная другим способом.Если первая оценка указывает на то, что ваш выбор модели плох, то вторая статистика, скорее всего, будет просто артефактом переоснащения.

В конечном счете, это скорее вопрос методологии, чем вопрос программирования.Возможно, вы захотите опубликовать следующий вопрос на Перекрестная проверка о том, как интерпретировать модель, в которой две версии R ^ 2 так сильно отличаются.Если вы зададите такой вопрос, обязательно дайте немного больше информации о том, что вы моделируете.

0 голосов
/ 10 февраля 2019

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

Хотя LinearRegression() (т. Е. Ваш 1-й квадрат R) Scikit-learn по умолчанию установлен на fit_intercept=True ( документы ), это не случай со статсмоделями 'OLS (ваш 2-й R-квадрат);цитирование из документов :

Перехват не включен по умолчанию и должен быть добавлен пользователем.См. statsmodels.tools.add_constant.

Имея в виду эту важную деталь, давайте проведем несколько простых экспериментов с фиктивными данными:

import numpy as np
import statsmodels.api as sm
from sklearn.metrics import r2_score
from sklearn.linear_model import LinearRegression

# dummy data:
y = np.array([1,3,4,5,2,3,4])
X = np.array(range(1,8)).reshape(-1,1) # reshape to column

# scikit-learn:
lr = LinearRegression()
lr.fit(X,y)
# LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
#     normalize=False)

lr.score(X,y)
# 0.16118421052631582

y_pred=lr.predict(X)
r2_score(y, y_pred)
# 0.16118421052631582


# statsmodels
# first artificially add intercept to X, as advised in the docs:
X_ = sm.add_constant(X)

model = sm.OLS(y,X_) # X_ here
results = model.fit()
results.rsquared
# 0.16118421052631593

Для всех практических целей эти два значения R-Квадрат, полученный с помощью scikit-learn и statsmodels, идентичен .

Давайте сделаем еще один шаг и попробуем модель scikit-learn без перехвата, но где мы используем искусственно «перехваченные» данные X_ мы уже построили для использования со statsmodels:

lr2 = LinearRegression(fit_intercept=False)
lr2.fit(X_,y) # X_ here
# LinearRegression(copy_X=True, fit_intercept=False, n_jobs=None,
#         normalize=False)

lr2.score(X_, y)
# 0.16118421052631593

y_pred2 = lr2.predict(X_)
r2_score(y, y_pred2)
# 0.16118421052631593

Опять R-квадрат идентичен с предыдущими значениями.

Итак, что происходит, когдамы «случайно» забываем учесть тот факт, что statsmodels OLS устанавливается без перехвата?Давайте посмотрим:

model3 = sm.OLS(y,X) # X here, i.e. no intercept
results3 = model2.fit()
results3.rsquared
# 0.8058035714285714

Ну, R-квадрат 0,80 действительно очень далек от значения 0,16, возвращаемого моделью с перехватом, и, возможно, это именно то, что имеетслучилось в вашем случае.

Пока все хорошо, и я мог бы легко закончить ответ здесь;но действительно существует момент, когда этот гармоничный мир рушится: давайте посмотрим, что произойдет, когда мы подгоним обе модели без перехвата и с исходными данными X, где мы не добавили искусственно никакого перехвата.Мы уже установили модель OLS выше и получили R-квадрат 0,80;а как насчет аналогичной модели от scikit-learn?

# scikit-learn
lr3 = LinearRegression(fit_intercept=False)
lr3.fit(X,y) # X here
lr3.score(X,y)
# -0.4309210526315792

y_pred3 = lr3.predict(X)
r2_score(y, y_pred3)
# -0.4309210526315792

Упс ...!Какого черта ??

Кажется, что scikit-earn, когда вычисляет r2_score, всегда предполагает перехват, либо явно в модели (fit_intercept=True), либо неявно вданные (то, как мы создали X_ из X выше, используя statsmodels 'add_constant);Если немного покопаться в интернете, то вы увидите ветку Github (закрыта без исправления), где подтверждается, что ситуация действительно такая.

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


Итак, почему scikit-learn не только терпит неудачу в таком (по общему признанию edge ) случае, но даже когда факт возникает в проблеме Github, он фактически обрабатывается с равнодушным ?(Заметьте также, что разработчик ядра scikit-learn, отвечающий в вышеупомянутой ветке, случайно признает, что « Я не очень знаком со статистикой » ...).

Ответ идетнемного больше, чем проблемы кодирования, такие как те, о которых в основном говорит SO, но, возможно, здесь стоит немного остановиться.

Возможно, причина в том, что вся концепция R-квадрата на самом деле происходит непосредственно из мирастатистика, где акцент делается на интерпретативных моделях, и он мало используется в контексте машинного обучения, где акцент явно делается на прогнозирующих моделях;по крайней мере AFAIK, и помимо некоторых очень вводных курсов, я никогда (я имею в виду никогда ...) не видел проблемы прогнозирующего моделирования, где R-квадрат используется для любого вида оценки производительности;Также не случайно, что популярные машинные курсы , такие как Машинное обучение Эндрю Нг в Coursera, даже не удосужились об этом упомянуть.И, как отмечалось в ветке Github выше (выделение добавлено):

В частности, при использовании набора test мне немного неясно, что означает R ^ 2.

, с которым я, безусловно, согласен.

Что касается крайнего случая, рассмотренного выше (включать или не включать термин перехвата?), Я подозреваю, что это будет звучать действительно неуместно для современных практиков глубокого обучения, где эквивалентпересечение (параметры смещения) всегда включается по умолчанию в модели нейронной сети ...

См. принятый (и высоко оцененный) ответ в перекрестном утверждении вопроса Разница между statsmodel OLS и линейной регрессией scikit для более подробного обсуждения в этих последних строках ...

0 голосов
/ 10 февраля 2019

Как вы заметили, и, как отмечает статья Википедии , существует несколько определений "r в квадрате" или "R в квадрате".Тем не менее, все обычные имеют свойство варьироваться от 0 до 1.Как правило, они положительны, как это видно из «квадратной» части названия.(Исключения из этого общего правила см. В статье Википедии.)

Ваш «Первый результат R-квадрата» равен -4.28, который не находится между 0 и 1 и даже не является положительным.Таким образом, это на самом деле не «R квадрат» вообще.Поэтому используйте «Второй результат R-квадрата», который находится в правильном диапазоне.

Вы не говорите, какую библиотеку вы используете, поэтому я не могу сказать, каков на самом деле ваш так называемый «Первый результат R-квадрата».является.С этого момента, когда вы задаете вопрос, пожалуйста, покажите полный фрагмент кода, который мы можем скопировать и вставить и выполнить - не забудьте включить все операторы import.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...