Как правила соседства могут повредить вашим прогнозам.
Случайный лес - популярная модель машинного обучения, которая обычно используется для задач классификации, что можно увидеть во многих научных статьях, конкурсах Kaggle и сообщениях в блогах. В дополнение к классификации случайные леса также могут использоваться для задач регрессии. Нелинейная природа случайного леса может дать ему преимущество перед линейными алгоритмами, что делает его отличным вариантом. Однако важно знать свои данные и помнить, что случайный лес не может быть экстраполирован. Он может только сделать прогноз, который является средним из ранее наблюдаемых меток. В этом смысле он очень похож на KNN. Другими словами, в задаче регрессии диапазон прогнозов, которые может сделать случайный лес, ограничен наивысшей и самой низкой метками в обучающих данных. Такое поведение становится проблематичным в ситуациях, когда входные данные для обучения и прогнозирования различаются по диапазону и / или распределению. Это называется ковариативный сдвиг, и с ним трудно справиться для большинства моделей, но особенно для случайного леса, поскольку он не может быть экстраполирован.
Например, предположим, что вы работаете с данными, в основе которых лежит тенденция с течением времени, такими как цены на акции, стоимость домов или продажи. Если в данных тренировки отсутствуют какие-либо периоды времени, ваша модель случайного леса будет занижать или переоценивать, в зависимости от тенденции, примеры за пределами временных рамок в данных тренировки. Это будет очень заметно, если вы сопоставите прогнозы своей модели с их истинными значениями. Давайте посмотрим на это, создав некоторые данные.
import numpy as np import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression from sklearn.ensemble import RandomForestRegressor %matplotlib inline #make fake data with a time trend X = np.random.rand(1000,10) #add time feature simulating years 2000-2010 time = np.random.randint(2000,2011,size=1000) #add time to X X = np.hstack((X,time.reshape(-1,1))) #create target via a linear relationship to X weights = np.random.rand(11) y = X.dot(weights) #create test data that includes years #not in training data 2000 - 2019 X_test = np.random.rand(1000,10) time_test = np.random.randint(2000,2020,size=1000) X_test = np.hstack((X_test,time_test.reshape(-1,1))) y_test = X_test.dot(weights)
Давайте посмотрим, насколько хорошо случайный лес может предсказать тестовые данные.
#fit and score the data using RF RF = RandomForestRegressor(n_estimators=100) RF.fit(X,y) RF.score(X_test,y_test) >>0.5872576516824577
Это не очень хорошо. Давайте сопоставим наши прогнозы с их известными значениями, чтобы увидеть, что происходит.
#plot RF as trees increase #set starting point for subplots index = 1 #set the size of the subplot to something large plt.figure(figsize=(20,20)) #iterate through number of trees in model #and plot predictions v actual for i in [1,5,10,100]: plt.subplot(2, 2, index) RF_plot = RandomForestRegressor(n_estimators=i) RF_plot.fit(X,y) #split data btw vals RF can interploate vs. data #it needs to exptrapolate interpolate_index = X_test[:,10]<=2010 extrapolate_index = X_test[:,10]>2010 X_interpolate = X_test[interpolate_index] X_extrapolate = X_test[extrapolate_index] y_interpolate = y_test[interpolate_index] y_extrapolate = y_test[extrapolate_index] #plot predictions vs. actual plt.scatter(RFplot.predict(X_interpolate), y_interpolate, color="g",label="interpolate") plt.scatter(RFplot.predict(X_extrapolate), y_extrapolate, color="b",label="extrapolate") plt.xlabel('Predicted') plt.ylabel('Actual') plt.title('Random Forest with {} trees'.format(i)) plt.subplots_adjust(wspace=.4, hspace=.4) plt.legend(loc="best") index += 1
Этот график показывает, что максимальное значение, которое модель может предсказать, составляет около 961, в то время как основной тренд в данных подталкивает более свежие значения к 966. К сожалению, случайный лес не может экстраполировать линейный тренд и точно предсказать новые примеры которые имеют значение времени выше, чем в данных обучения (2000–2010 гг.). Даже регулировка количества деревьев не решает проблемы. В этой ситуации, поскольку мы установили идеально линейную зависимость для данных, модель, такая как линейная регрессия, будет лучшим выбором, и у нее не будет проблем с обнаружением тенденции в данных и выполнением точных прогнозов для данных за пределами временных диапазонов в обучении. данные.
#fit the data using Linear Regression LR = LinearRegression() LR.fit(X,y) LR.score(X_test,y_test) >>1.0 #plot predictions of Linear Regression against actual plt.figure(figsize=(7,7)) plt.xlabel('Predicted') plt.ylabel('Actual') plt.title('Linear Regression - Test Data') _ = plt.scatter(LR.predict(X_interpolate),y_interpolate, color="g",label="interpolate") _ = plt.scatter(LR.predict(X_extrapolate),y_extrapolate, color="b",label="extrapolate") plt.legend(loc="best")
Хотя случайный лес часто является отличным выбором модели, все же важно знать, как он работает, и могут ли у него быть какие-либо ограничения с учетом ваших данных. В этом случае, поскольку это модель, основанная на соседстве, она не позволяет нам делать точные прогнозы для временных рамок за пределами наших обучающих данных. Если вы окажетесь в такой ситуации, лучше всего протестировать другие модели, такие как линейная регрессия или кубизм, и / или рассмотреть возможность использования случайного леса в ансамбле моделей. Удачного предсказания!