Регрессия OLS: Scikit против Statsmodels?

Короткая версия: я использовал scikit LinearRegression на некоторых данных, но я привык к p-значениям, поэтому помещаю данные в OLS statsmodels, и хотя R ^ 2 примерно одинаков, переменные коэффициенты все различаются в больших количествах, Это касается меня, поскольку наиболее вероятная проблема заключается в том, что я где-то допустил ошибку, и теперь я не чувствую уверенности ни в одном из результатов (поскольку, вероятно, я сделал одну модель неправильно, но не знаю, какая).

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

У меня сложилось впечатление, что scikit LR и statsmodels OLS должны выполнять OLS, и, насколько я знаю, OLS - это OLS, поэтому результаты должны быть одинаковыми.

Для scikit LR результаты (статистически) одинаковы независимо от того, установлен ли я normalize = True или = False, что я нахожу несколько странным.

Для statsmodels OLS я нормализую данные, используя StandardScaler из sklearn. Я добавляю столбец единиц, чтобы он включал перехват (поскольку вывод scikit включает в себя перехват). Подробнее об этом здесь: http://statsmodels.sourceforge.net/devel/examples/generated/example_ols.html (Добавление этого столбца не изменило переменные коэффициенты в какой-либо заметной степени, а перехват был очень близок к нулю.) StandardScaler не понравилось, что мои целые числа не были плавающими, поэтому я попробовал это: https://github.com/scikit-learn/scikit-learn/issues/1709 Это убирает предупреждение, но результаты точно такие же.

Конечно, я использую 5-кратное cv для подхода sklearn (R ^ 2 согласуются как для тестовых, так и для тренировочных данных каждый раз), а для statsmodels я просто выкидываю все эти данные.

R ^ 2 составляет около 0,41 для sklearn и statsmodels (это хорошо для социальных наук). Это может быть хорошим знаком или просто совпадением.

Данные - это наблюдения аватаров в WoW (из http://mmnet.iis.sinica.edu.tw/dl/wowah/), которые я собирался сделать еженедельными с некоторыми другими функциями. Первоначально это был классный проект для класса данных науки.

Независимые переменные включают количество наблюдений за неделю (int), уровень персонажа (int), если в гильдии (Boolean), когда они видны (Booleans в день недели, канун дня недели, поздний день недели и те же три для выходных), фиктивный для класса символов (на момент сбора данных в WoW было только 8 классов, поэтому есть 7 фиктивных переменных, а исходная строковая категориальная переменная отброшена) и другие.

Зависимая переменная - это количество уровней, которое каждый персонаж получил за эту неделю (int).

Интересно, что некоторый относительный порядок внутри одинаковых переменных поддерживается в statsmodels и sklearn. Таким образом, порядок ранжирования "когда видно" одинаков, хотя нагрузки очень разные, и порядок рангов для манекенов класса персонажей одинаков, хотя опять же нагрузки очень разные.

Я думаю, что этот вопрос похож на этот: Различия в Python statsmodels OLS и R & # 39; s lm

Я достаточно хорош в Python и его статистике, но не настолько хорош, чтобы понять что-то подобное. Я пытался читать документы sklearn и statsmodels, но если ответ был там, глядя мне в лицо, я не понимал этого.

Я хотел бы знать:

  1. Какой вывод может быть точным? (Конечно, они оба могут быть, если я пропустил kwarg.)
  2. Если я допустил ошибку, что это такое и как это исправить?
  3. Мог ли я понять это, не спрашивая здесь, и если да, то как?

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

(Я даже попробовал некоторые другие вызовы OLS для триангуляции, один дал намного более низкое R ^ 2, один зациклился на пять минут, и я убил его, а один потерпел крах.)

Спасибо!

Ответы

Ответ 1

Похоже, вы не подаете одну и ту же матрицу регрессоров X на обе процедуры (но см. ниже). Вот пример, чтобы показать вам, какие опции вам нужно использовать для sklearn и statsmodels для получения идентичных результатов.

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

# Generate artificial data (2 regressors + constant)
nobs = 100 
X = np.random.random((nobs, 2)) 
X = sm.add_constant(X)
beta = [1, .1, .5] 
e = np.random.random(nobs)
y = np.dot(X, beta) + e 

# Fit regression model
sm.OLS(y, X).fit().params
>> array([ 1.4507724 ,  0.08612654,  0.60129898])

LinearRegression(fit_intercept=False).fit(X, y).coef_
>> array([ 1.4507724 ,  0.08612654,  0.60129898])

Как предположил комментатор, даже если вы даете обеим программам одинаковый X, X может не иметь полного ранга столбца, и они могут выполнять разные действия для выполнения OLS-вычислений. через (то есть, отбрасывая разные столбцы).

Я рекомендую использовать pandas и patsy, чтобы позаботиться об этом:

import pandas as pd
from patsy import dmatrices

dat = pd.read_csv('wow.csv')
y, X = dmatrices('levels ~ week + character + guild', data=dat)

Или, альтернативно, интерфейс формулы statsmodels:

import statsmodels.formula.api as smf
dat = pd.read_csv('wow.csv')
mod = smf.ols('levels ~ week + character + guild', data=dat).fit()

Изменение: этот пример может быть полезен: http://statsmodels.sourceforge.net/devel/example_formulas.html

Ответ 2

я просто хотел добавить здесь, что с точки зрения sklearn, он не использует метод OLS для линейной регрессии под капотом. Поскольку sklearn происходит из области интеллектуального анализа данных/машинного обучения, им нравится использовать алгоритм градиента крутого спуска. Это численный метод, который чувствителен к начальным условиям и т.д., В то время как OLS - это аналитический подход в замкнутой форме, поэтому следует ожидать различий. Таким образом, statsmodels происходит из классической области статистики, поэтому они будут использовать технику OLS. Таким образом, есть различия между двумя линейными регрессиями из двух разных библиотек

Ответ 3

Если вы используете statsmodels, я настоятельно рекомендую использовать вместо этого интерфейс формулы statsmodels. Вы получите тот же старый результат из OLS, используя интерфейс формулы statsmodels, как и из sklearn.linear_model.LinearRegression, или R, или SAS, или Excel.

smod = smf.ols(formula ='y~ x', data=df)
result = smod.fit()
print(result.summary())

Если у вас есть сомнения, пожалуйста,

  1. попробуйте прочитать исходный код
  2. попробуйте другой язык для сравнения или
  3. попробуйте OLS с нуля, который является основной линейной алгеброй.