Я использую набор данных 1,88 миллиона лесных пожаров в США и использую KNeighborsRegressor от SciKit Learn для регрессии по «FIRE_SIZE». Я получаю следующий вывод и немного смущен тем, почему точность моего обучения снижается, а точность тестов увеличивается. Ищу здесь некоторое представление о том, что может происходить за кулисами.
Test RMSE: 7495.765269614677
Train Accuracy: 0.9995951877448755
Test Accuracy: 0.04561166544992734
--x--
3-Nearest Neighbor(s) Results:
Test RMSE: 5798.419599886992
Train Accuracy: 0.5157901853607345
Test Accuracy: 0.4288996249038137
--x--
5-Nearest Neighbor(s) Results:
Test RMSE: 4370.705370544834
Train Accuracy: 0.3818744943896586
Test Accuracy: 0.6755138015850977
--x--
7-Nearest Neighbor(s) Results:
Test RMSE: 5234.077626536805
Train Accuracy: 0.32715455088444
Test Accuracy: 0.5346566791409124
--x--
9-Nearest Neighbor(s) Results:
Test RMSE: 4833.210891971975
Train Accuracy: 0.2925369697746403
Test Accuracy: 0.603206401422826
--x--
11-Nearest Neighbor(s) Results:
Test RMSE: 4662.668487875189
Train Accuracy: 0.27812301457721345
Test Accuracy: 0.6307145104081042
--x--
13-Nearest Neighbor(s) Results:
Test RMSE: 4475.217632469529
Train Accuracy: 0.2623128334766227
Test Accuracy: 0.659810044524328
--x--
def k_nearest_neighbors(X, y, n):
# Get training and testing splits.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.01, random_state=42)
# Initialize a LinearRegr model and return scores/results in a dictionary.
classifier = KNeighborsRegressor(n_neighbors=n, n_jobs=-1)
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)
mse_test = mean_squared_error(y_test, y_pred) # Mean-squared error, test
test_predictions = classifier.predict(X_test) # prediction accuracy, test
test_score = r2_score(y_test, test_predictions)
train_predictions = classifier.predict(X_train) # prediction accuracy, train
train_score = r2_score(y_train, train_predictions)
return {'rmse': sqrt(mse_test), 'train': train_score, 'test': test_score}
for i in range(1, 15, 2):
print(f'{i}-Nearest Neighbor(s) Results:\n')
X, y = get_prediction_df(conn, cols_with_log, 'FIRE_SIZE', 700000, geohash_precision=2)
result = k_nearest_neighbors(X, y, i)
print('Test RMSE: ', result['rmse'])
print('Train Accuracy: ', result['train'])
print('Test Accuracy: ', result['test'], '\n')
print('--x--\n')
Похоже, что ваша модель переоснащена — по мере того, как вы включаете в модель больше соседей, вы даете ей возможность изучить все более и более сложную функцию, но когда вы проверяете модель на своем тестовом наборе, она не работает. не так хорошо. Это связано с тем, что ваша модель начала изучать отношения, которых нет в данных, с которыми она не обучалась (и, вероятно, отношения, которых не существует). Судя по вашим результатам, кажется, что между версиями с 3 соседями и 5 соседями начинает происходить переоснащение. Возможно, попробуйте версию с 4 соседями и посмотрите, обеспечивает ли она наилучшую точность теста в целом?
=====
Редактировать: основываясь на разговоре в комментариях, мне интересно, происходит ли здесь что-то большее, чем просто переобучение. По совету по этому ответу
Я думаю, что первым шагом является проверка того, действительно ли отчеты о тренировках и тестах верны.
В подобных ситуациях я рассмотрю пару примеров, когда прогнозы были классифицированы как точные, и чаще всего пойму, что допустил ошибку в своем оценочном коде, из-за которой точные результаты выглядели неточными, и наоборот.
Когда происходит переобучение, не увеличивается ли точность обучения и снижается точность теста? Это означает, что модель теперь слишком многому учится на тренировочном наборе и работает очень хорошо, но не может обобщать на тестовом наборе?
Вы поднимаете очень хорошие вопросы, спасибо за понимание! Вот результаты 4 соседей. 4-Nearest Neighbor(s) Results: Test RMSE: 4524.328935384681 Train Accuracy: 0.42028669564300813 Test Accuracy: 0.6523025460837525
Не могли бы вы объяснить, почему, если модель изучила отношения к переобучению, то есть отношения, которые не существуют, она так хорошо работает с новыми данными, то есть с точностью теста?
оформить заказ - stats.stackexchange.com/questions/59630/…
Выполните 10-кратную перекрестную проверку и снова проверьте свои результаты.
@sharathnatraj не очень хорошо знаком с CV, так что бы вы порекомендовали? Должен ли я использовать ванильный cross_val_score из sklearn или что-то еще в той же библиотеке?
Кроме того, вы делаете здесь 99% поезд и 1% тест? Рекомендуется разделение 90-10 или 80-20 и т.д. Есть ли конкретная причина делать 99:1?
Хорошая мысль stackoverflow.com/users/13628883/sharathnatraj относительно обратного ожидаемого результата. Я обновлю свой ответ, чтобы включить нашу неопределенность в этот ответ.
Я собрал свои мысли в виде нового ответа, в который я также включил ссылку для резюме - @AbdulSohu
@sharathnatraj Я повторял модель по разным разбиениям тестовых поездов и получил результаты, которые показали снижение точности тестирования более чем на 1%, например: The train-test split: 99.0%-1.0% Test Accuracy: 0.10377409618872824 --x-- The train-test split: 97.0%-3.0% Test Accuracy: 0.07242578496681529 --x-- The train-test split: 95.0%-5.0% Test Accuracy: 0.06685114199694864 --x-- The train-test split: 93.0%-6.999999999999999% Test Accuracy: 0.06976801027832258 --x-- The train-test split: 91.0%-8.999999999999998% Test Accuracy: 0.05168511650970986
В идеале для хорошей модели вы почти всегда должны видеть точность теста лишь немного меньше, чем точность поезда. Только тогда можно доверять модели.
Взгляните на изображение ниже (взято из здесь):
Это общее представление компромисса смещения и дисперсии в машинном обучении. Нижняя из двух кривых представляет вашу ошибку обучения, а верхняя кривая представляет ошибку тестирования (или проверки).
Когда ваша модель имеет низкую сложность, например, небольшое количество предикторов, обе ошибки высоки, но по мере добавления данных они обе начинают уменьшаться, но до определенного момента. Ошибка обучения будет продолжать уменьшаться по мере усложнения модели и может продолжаться бесконечно. Проще говоря, когда вы добавляете в модель много данных, алгоритм теперь может еще лучше «запоминать» все обучающие данные и точно предсказывать их.
Но в то же время ошибка проверки начинает увеличиваться из-за переобучения — теперь ваша модель очень хорошо «запоминает» обучающие данные, но это ухудшает ее способность делать прогнозы на новых данных.
Обычно лучшая модель — это когда кривая ошибки тестирования находится на минимуме, точка, в которой у вас достаточно данных, чтобы объяснить большую часть дисперсии, но не настолько, чтобы смещение было высоким.
Это подробно обсуждается в теме ниже, https://stats.stackexchange.com/questions/59630/test-accuracy-higher-than-training-how-to-interpret
В вашем случае разделение на поезд-тест составляет 99: 1, что не рекомендуется, и это может быть одной из причин странных результатов. Перейдите на разделение 90-10 или 80-20 и используйте перекрестную проверку K-кратности (с K 10 или 20), а затем снова оцените свои результаты.
Выполнение перекрестной проверки хорошо объясняется здесь: https://towardsdatascience.com/building-a-k-nearest-neighbours-k-nn-model-with-scikit-learn-51209555453a
Я сделал перекрестную складку, где cv = 10, и еще одну, где cv = 6, и получил массив оценок с отрицательными значениями с плавающей запятой. Статья, на которую вы мне указали, показывает на самом деле лучшие (положительные) оценки прогноза для модели. Есть идеи, что вызывает мои отрицательные значения?
Итак, вы пробовали CV = 10, для какого значения «K»? Каково было среднее значение массива для CV-10 для обучения и тестирования?
Отрицательные значения для точности? @АбдулСоху
Проблема ОП - это проблема регрессии, где, конечно, понятие точности бессмысленно; то, что здесь называют «точностью», на самом деле является показателем R^2.
О, верно. Отрицательный R2 указывает на то, что подгонка модели довольно плохая. Пожалуйста, дважды проверьте подгонку модели @AbdulSohu
@sharathnatraj Я полагаю, что единственный способ проверить соответствие модели - это вызвать model.predict(), и результаты этого находятся под вопросом. Я могу ошибаться здесь, и если да, дайте мне знать, как еще мы можем проверить соответствие модели ..?
Я не имею в виду вызов model.predict(). Проверьте, есть ли у вас правильные черты, правильно ли выполнено масштабирование и т. д. и т. д., все девять ярдов. Похоже, вы напрямую подключаете входные данные без какой-либо предварительной обработки? Ознакомьтесь с шагами предварительной обработки ML, на которые уходит 80% тяжелой работы.
Я голосую за то, чтобы закрыть этот вопрос, потому что речь идет не о программировании, как это определено в справочном центре , а о теории и/или методологии машинного обучения — см. вступление и ПРИМЕЧАНИЕ в информации тега
machine-learning
.