Линейная регрессия: хорошие результаты для тренировочных данных, ужасные для тестовых данных - PullRequest
0 голосов
/ 11 июня 2018

Я работаю с набором данных размером около 400 000 x 250. У меня проблема с моделью, которая дает очень хороший показатель R ^ 2 при тестировании ее на тренировочном наборе, но крайне плохо при использовании на тестовом наборе.Первоначально это звучит как переоснащение.Но данные разбиты на произвольно обучающие / тестовые наборы и набор данных у меня довольно большой, поэтому я чувствую, что должно быть что-то еще.Любые предложения?

Разделение набора данных на тренировочный набор и тестовый набор

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df.drop(['SalePrice'], 
axis=1), df.SalePrice, test_size = 0.3)

Оценка линейной регрессии Склеарна

from sklearn import linear_model
linReg = linear_model.LinearRegression()    # Create linear regression object
linReg.fit(X_train, y_train)                # Train the model using the training sets

# Predict from training set
y_train_linreg = linReg.predict(X_train)

# Predict from test set
y_pred_linreg = linReg.predict(X_test)

Метрический расчет

from sklearn import metrics
metrics.r2_score(y_train, y_train_linreg)
metrics.r2_score(y_test, y_pred_linreg)

Оценка R ^ 2 при тестировании на тренировочном наборе: 0,64

Оценка R ^ 2 при тестировании на испытательном наборе: -10 ^ 23 (приблизительно)

1 Ответ

0 голосов
/ 11 июня 2018

Хотя я согласен с Михаем, что ваша проблема определенно выглядит как переоснащение, я не обязательно согласен с его ответом, что нейронная сеть решит вашу проблему;по крайней мере, не из коробки.Сами по себе нейронные сети превосходят больше , не меньше, чем линейные модели.Вам нужно как-то заботиться о ваших данных, вряд ли любая модель сможет сделать это за вас.Несколько вариантов, которые вы могли бы рассмотреть (извините, я не могу быть более точным, не глядя на набор данных):

  • Самый простой способ - использовать регуляризацию.400 тысяч строк - это много, но с 250 размерами вы можете уместить почти все, что захотите.Поэтому попробуйте заменить LinearRegression на Ridge или Lasso (или Elastic Net или что-то еще).См. http://scikit -learn.org / stable / modules / linear_model.html (у Лассо есть преимущество в отбрасывании функций для вас, см. Следующий пункт)
  • Особенно, если вы хотите выйти на улицулинейных моделей (и вам, вероятно, следует), желательно сначала уменьшить масштаб проблемы, как я уже сказал, 250 - это много.Попробуйте использовать некоторые из техник выбора функций здесь: http://scikit -learn.org / stable / modules / feature_selection.html
  • Вероятно, наиболее важно, чем что-либо еще, вам следует подумать об адаптации вашего вводаданные.Самое первое, что я попробую, это предположить, что вы действительно пытаетесь предсказать цену в соответствии с вашим кодом, чтобы заменить ее логарифмом или log (1 + x).В противном случае линейная регрессия будет изо всех сил стараться соответствовать тому единственному объекту, который был продан за 1 миллион долларов, игнорируя все, что ниже 1 тысячи долларов.Не менее важно проверить, есть ли у вас какие-либо нечисловые (категориальные) столбцы, и сохраняйте их только при необходимости, в случае их сокращения до макрокатегорий: категориальный столбец с 1000 возможными значениями увеличит размер проблемы на 1000, делаяэто уверенный наряд.Один столбец с уникальными категориальными данными для каждого ввода (например, имя покупателя) приведет вас к идеальному переоснащению.
  • После всего этого (очистка данных, уменьшение размера с помощью одного из указанных выше методов или просто регрессия Лассо)до тех пор, пока вы не достигнете, конечно, меньше чем dim 100, возможно, меньше 20 - и помните, что это включает в себя любые категориальные данные!), вы должны рассмотреть нелинейные методы для дальнейшего улучшения ваших результатов - но это бесполезно, пока ваша линейная модель не предоставит вам по крайней меренекоторое слегка положительное значение R ^ 2 по данным испытаний.Склеарн предоставляет множество из них: http://scikit -learn.org / stable / modules / kernel_ridge.html является самым простым в использовании из коробки (также выполняет регуляризацию), но это может бытьслишком медленный, чтобы использовать его в вашем случае (сначала вы должны попробовать это и любое из следующего на подмножестве ваших данных, скажем 1000 строк, как только вы выбрали только 10 или 20 объектов, и посмотрите, насколько это медленно).http://scikit -learn.org / stable / modules / svm.html # regression имеет много разных разновидностей, но я думаю, что все, кроме линейного, будут слишком медленными.Придерживаясь линейных вещей, http://scikit -learn.org / stable / modules / sgd.html # regression , вероятно, является самым быстрым, и именно так я бы обучил линейную модель на этом множестве выборок.Если исходить из линейности, то самые простые методы, вероятно, будут включать в себя какие-то деревья, либо напрямую http://scikit -learn.org / stable / modules / tree.html # regression (но это почти определенное превышение) или, лучше, с использованием некоторой техники ансамбля (случайные леса http://scikit -learn.org / stable / modules / ensemble.html # trees-of-randomized-trees являются типичным алгоритмом перехода, градиентboost http://scikit -learn.org / stable / modules / ensemble.html # добавление градиента-дерева иногда работает лучше).Наконец, современные результаты действительно обычно получают с помощью нейронных сетей, см., Например, http://scikit -learn.org / stable / modules / neural_networks_supervised.html , но для этих методов sklearn обычно неправильный ответ, и вам следует взглянуть на специальные среды (TensorFlow, Caffe, PyTorch и т. д.) ... однако, если вы не знакомы с ними, это, безусловно, не стоит проблем!
...