Подгонка регрессора ансамбля в цикле генерирует повторяющиеся значения

Я пытаюсь использовать ансамблевый регрессор для прогнозирования производства на основе нескольких измерений материала. Мои данные ежегодные, начиная с 1965 года. (Некоторые детали удалены и используются случайные данные, потому что это для рабочего проекта с использованием конфиденциальных данных.)

Я сократил свой код до минимума, и я все еще вижу проблему:

import pandas as pd
import numpy as np

from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor
from xgboost.sklearn import XGBRegressor

X_past = pd.DataFrame(index = range(1965, 2020), data = dict(
    A = np.random.randint(4170, 19091, size = 55),
    B = np.random.randint(74, 337, size = 55)
))

X_future = pd.DataFrame(index = range(2020, 2023), data = dict(
    A = np.random.randint(4170, 19091, size = 3),
    B = np.random.randint(74, 337, size = 3)
))

y_past = pd.DataFrame(index = range(1965, 2020), data = dict(
    C = np.random.randint(12163, 42580, size = 55)
))

predictions = None
predictions = pd.DataFrame()

i = 0

while i < 10:
    i += 1
    
    reg = None
    y_pred = None
    
    X = X_past.values
    y = y_past.values.ravel()

    #reg = RandomForestRegressor(n_estimators = 300)
    reg = GradientBoostingRegressor(n_estimators = 300)
    #reg = XGBRegressor(n_estimators = 640, silent = True)

    reg.fit(X, y)

    y_pred = reg.predict(np.array(X_future))
    predictions = predictions.append(pd.Series(y_pred), ignore_index = True,)
    

predictions.columns = [2020, 2021, 2022]
predictions['Row-wise Duplicates'] = (predictions[2021] == predictions[2022])

predictions

Это дает такие результаты, как:

2020 2021 2022 Дубликаты по строкам 13211.008045 29624.483861 34110.523735 ЛОЖЬ 13211.008045 29624.483861 33462.196606 ЛОЖЬ 13211.008045 29624.483861 33867.781932 ЛОЖЬ 13211.008045 29624.483861 33999.203849 ЛОЖЬ 13211.008045 29624.483861 33947.950436 ЛОЖЬ 13211.008045 29624.483861 33550.338744 ЛОЖЬ 13211.008045 29624.483861 34079.297200 ЛОЖЬ 13211.008045 29624.483861 33924.349324 ЛОЖЬ 13211.008045 29624.483861 33195.847833 ЛОЖЬ 13211.008045 29624.483861 33922.391200 ЛОЖЬ

Как видите, несмотря на то, что на каждой итерации я подгоняю заново, я вижу много повторяющихся значений.

Я также иногда вижу дублирование значений по годам (обычно 2021 год совпадает с 2022 годом, поэтому я рассчитываю столбец дубликатов по строкам):

2020 2021 2022 Дубликаты по строкам 40819.929316 40819.929316 40819.929316 Истинный 41516.312213 41516.312213 41516.312213 Истинный 41516.312213 41516.312213 41516.312213 Истинный 40901.743937 40901.743937 40901.743937 Истинный 41191.025907 41191.025907 41191.025907 Истинный 41109.211286 41109.211286 41109.211286 Истинный 40910.834451 40910.834451 40910.834451 Истинный 41799.581630 41799.581630 41799.581630 Истинный 42512.531092 42512.531092 42512.531092 Истинный 41018.306151 41018.306151 41018.306151 Истинный

Что я делаю не так? Почему я вижу такие дубликаты? И как я могу это исправить?

Вы должны хотя бы указать, откуда вы импортируете GradientBoostingRegressor (я думаю, scikit-learn, но я должен догадываться? :))

Itamar Katz 09.12.2020 18:36

О, упс... Да, склерн. XGBoostingRegressor происходит от xgboost.

Bob 09.12.2020 18:40

Вы даете алгоритму одни и те же обучающие входные данные и одни и те же тестовые входные данные на каждой итерации, почему вы ожидаете другой результат?

Itamar Katz 09.12.2020 18:50
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Алгоритм, который вы используете, с параметрами, которые вы используете, не имеет случайного внутреннего элемента. Таким образом, предоставление ему одного и того же обучающего набора и одного и того же набора тестов (как вы делаете в своем коде) приведет к тем же результатам.

Вы можете использовать параметр subsample со значением меньше, чем 1, чтобы он использовал другую случайную подвыборку для обучения каждого базового ученика (см. документацию https://scikit-learn.org/stable/modules/generated/sklearn.ensemble .GradientBoostingRegressor.html)

Итак, если вы замените свою строку на эту:

reg = GradientBoostingRegressor(n_estimators = 300, subsample = 0.9)

Алгоритм будет использовать случайное подмножество 90% ваших данных для обучения каждого ученика, и вы будете получать разные результаты при каждом вызове. Вы все еще можете сделать результаты воспроизводимыми, если объедините его с параметром random_state.

Это имеет смысл, но тогда почему иногда это отличается от ряда к ряду? Кроме того, почему иногда дублируются результаты для столбцов 2021 и 2022 годов? Их следует предсказывать по трем различным массивам признаков.

Bob 09.12.2020 19:10

Я не знаю, при вводе вашего вопроса он выдает идентичные строки. Но я запускаю его всего несколько раз.

Itamar Katz 09.12.2020 19:12

Вы уверены, что разные строки не создаются, когда вы просто запускаете скрипт несколько раз (в отличие от итерации с i по j)? Потому что это вызвано случайным вводом, который вы создаете... извините, если это тривиально, но иногда простые вещи трудно увидеть :)

Itamar Katz 09.12.2020 19:14

Другие вопросы по теме