Улучшение полиномиальной логистической регрессии с помощью деревьев решений, случайных лесов и настройки гиперпараметров

Полный код можно найти здесь: Github Link

Этот проект, являющийся решением конкурса Kaggle Рекрутинг Walmart — классификация типов поездок, демонстрирует, как Walmart объединяет искусство и науку для повышения уровня понимания клиентов и качества обслуживания. Сегментация посещений магазинов по различным типам поездок улучшает впечатления от покупок, используя знания (искусство) и историю покупок (наука). Проект направлен на улучшение процесса сегментации Walmart путем уточнения классификации типов поездок с использованием данных о транзакционных покупках. Подробности конкурса можно найти здесь: Kaggle Competition

Общие действия по решению проблемы машинного обучения

  • Понимать бизнес-требования и характер доступных данных.
  • Классифицируйте проблему как контролируемую/неконтролируемую и регрессию/классификацию.
  • Скачивайте, очищайте и исследуйте данные и создавайте новые функции, которые могут улучшить модели.
  • Создайте наборы для обучения, тестирования и проверки и подготовьте данные для обучения моделей машинного обучения.
  • Создайте быструю и простую базовую модель для оценки и сравнения будущих моделей.
  • Выберите стратегию моделирования, обучите модель и настройте гиперпараметры для достижения оптимального соответствия.
  • Экспериментируйте и комбинируйте результаты нескольких стратегий, чтобы получить лучший результат.
  • Интерпретируйте модели, изучайте отдельные прогнозы и представляйте результаты.

Понимание бизнес-требований и характера данных

Точно классифицируя различные типы поездок, Walmart может улучшить свои маркетинговые стратегии, оптимизировать планировку магазинов, улучшить управление запасами и обеспечить персонализированный опыт покупок. Конкретные бизнес-требования для этого проекта включают классификацию поездок Walmart на основе моделей покупок, получение аналитической информации на основе данных, оптимизировать маркетинг, оптимизировать планировку магазина, обеспечить персонализированный опыт покупок, обеспечение управления запасами и т. д.

Даны два набора данных: обучающий и тестовый, с «TripType» в качестве целевого столбца и другими в качестве входных функций.

  • TripType классифицирует покупательское поведение.
  • VisitNumber идентифицирует поездки клиентов.
  • День недели отмечает день покупок.
  • UPC — это идентификатор продукта.
  • ScanCount записывает покупки/возвраты товаров.
  • DepartmentDescription классифицирует элементы.
  • FinelineNumber уточняет категории.

Классификация проблемы

Задача «Walmart Recruiting — Классификация типов поездок» включает контролируемое обучение и классификацию.

Обучение с учителем. Набор данных содержит помеченные поездки за покупками, что позволяет прогнозировать типы поездок на основе особенностей.

Классификация Задача состоит в том, чтобы отнести поездки к заранее определенным категориям с использованием шаблонов обучения модели для будущих прогнозов.

Очистка данных, EDA и создание новых функций

Удаление шума:

# Drop duplicates if present
def drop_duplicates(df):
  df_de_duplicated = df.drop_duplicates()
  return df_de_duplicated

print("Original shape of the training dataset: ", walmart_train.shape)
print("Original shape of the test dataset: ", walmart_test.shape)
print("Total duplicates in the training dataset: ", len(walmart_train[walmart_train.duplicated()]))
print("Total duplicates in the test dataset: ", len(walmart_test[walmart_test.duplicated()]))
walmart_train = drop_duplicates(walmart_train)
walmart_test = drop_duplicates(walmart_test)
print("Shape of the training dataset after dropping duplicates: ", walmart_train.shape)
print("Shape of the test dataset after dropping duplicates: ", walmart_test.shape)

Категория TripType_999 — это специальная категория, используемая для представления поездок, которые не относятся ни к какому конкретному типу и считаются «прочими». Это может негативно повлиять на производительность нашей модели, добавив неоднозначность и шум.

# drop 999 triptype to reduce noise in dataset
def remove_999_triptype(df):
    triptypes_train = df.groupby('TripType')['VisitNumber'].nunique().sort_values(ascending=False).head(10)
    print(triptypes_train)
    # Remove rows with TripType 999
    df = df[df['TripType'] != 999]
    print("Shape of the training dataset after dropping TripType 999: ", df.shape)
    return df

walmart_train= remove_999_triptype(walmart_train)

Обработка пропущенных значений:

В столбцах 'UPC', 'FinelineNumber' и 'DepartmentDescription' отсутствуют значения. Для FinelineNumber использование вменения режима подходит из-за его специфической природы продукта. Замените пропущенные значения режимом в соответствующем отделе или соответствующей комбинацией функций.

def impute_missing_values(df_train, df_test):
    # Impute 'DepartmentDescription'
    df_train['DepartmentDescription'].fillna(df_train['DepartmentDescription'].mode()[0], inplace=True)
    df_test['DepartmentDescription'].fillna(df_test['DepartmentDescription'].mode()[0], inplace=True)
    # Impute 'Upc'
    df_train['Upc'].fillna(df_train['Upc'].mode()[0], inplace=True)
    df_test['Upc'].fillna(df_test['Upc'].mode()[0], inplace=True)
    # Impute missing 'FinelineNumber' values with the mode of the corresponding department
    df_train['FinelineNumber'] = df_train.groupby('DepartmentDescription')['FinelineNumber'].transform(lambda x: x.fillna(x.mode()[0]))
    df_test['FinelineNumber'] = df_test.groupby('DepartmentDescription')['FinelineNumber'].transform(lambda x: x.fillna(x.mode()[0]))
    return df_train, df_test

walmart_train, walmart_test = impute_missing_values(walmart_train, walmart_test)
print("Our training dataset contains no null values:\n", walmart_train.isnull().sum().sort_values(ascending=False))
print("Our test dataset contains no null values:\n", walmart_test.isnull().sum().sort_values(ascending=False))

Кодирование категориальных столбцов:

ЗакодируйтеДень недели, используя порядковую кодировку для упорядоченных дней. Закодируйте «DepartmentDescription» с помощью частотной кодировки, отражающей появление категории. Поскольку у нас есть 68 уникальных значений «DepartmentDescription», мы столкнемся с «проклятием размерности», если будем использовать одно горячее кодирование, которое напрямую повлияет на производительность нашей модели.

def encode_features(df_train, df_test):
    # Frequency Encoding for 'DepartmentDescription' in Training and Test
    frequency_encoding = df_train['DepartmentDescription'].value_counts(normalize=True)
    df_train['Department_Encoded'] = df_train['DepartmentDescription'].map(frequency_encoding)

    frequency_encoding = df_test['DepartmentDescription'].value_counts(normalize=True)
    df_test['Department_Encoded'] = df_test['DepartmentDescription'].map(frequency_encoding)

    # Weekday Encoding
    weekday_mapping = {'Monday': 1, 'Tuesday': 2, 'Wednesday': 3, 'Thursday': 4, 'Friday': 5, 'Saturday': 6, 'Sunday': 7}
    df_train['Weekday_Encoded'] = df_train['Weekday'].map(weekday_mapping)

    weekday_mapping = {'Monday': 1, 'Tuesday': 2, 'Wednesday': 3, 'Thursday': 4, 'Friday': 5, 'Saturday': 6, 'Sunday': 7}
    df_test['Weekday_Encoded'] = df_test['Weekday'].map(weekday_mapping)
    return df_train, df_test

walmart_train, walmart_test = encode_features(walmart_train, walmart_test)
print("Encoded Walmart Test: \n", walmart_test.head())
print("Encoded Walmart Training: \n", walmart_train.head())

Разработка функций:

  • TotalItems. Вычисляет общее количество товаров, купленных во время каждой поездки, путем суммирования значений ScanCount.
  • ReturnItems Подсчитывает количество возвращенных товаров во время каждой поездки путем суммирования отрицательных значений ScanCount.
  • UniqueItems. Определяет количество уникальных товаров, купленных во время каждой поездки, с учетом отдельных значений UPC.
  • AverageScanCount: рассчитывает среднее число ScanCount на элемент для каждой поездки путем деления суммы ScanCount на общее количество элементов.
  • DepartmentCount: подсчитывает количество различных отделов, посещенных во время каждой поездки, путем подсчета отдельных значений DepartmentDescription.
  • PopularDepartment: Определяет наиболее часто посещаемый отдел во время каждой поездки, определяя режим DepartmentDescription.
  • DepartmentFrequency Вычисляет частоту посещений каждого отдела путем группировки данных по параметрам VisitNumber и DepartmentDescription и подсчета посещений.
  • WeekdayEncoded: кодирует столбец «День недели» в числовые значения для целей моделирования. Например, назначьте понедельнику значение 1, вторнику — значение 2 и т. д.
%%time
def encode_additional_features(df):
    # Calculate and encode additional features
    df['TotalItems'] = df.groupby('VisitNumber')['ScanCount'].transform('sum')
    df['ReturnItems'] = df.groupby('VisitNumber')['ScanCount'].transform('sum')
    df['UniqueItems'] = df.groupby('VisitNumber')['Upc'].transform('nunique')
    df['DepartmentCount'] = df.groupby('VisitNumber')['DepartmentDescription'].transform('nunique')
    df['PopularDepartment'] = df.groupby('VisitNumber')['DepartmentDescription'].transform(lambda x: x.mode()[0])
    df['DepartmentFrequency'] = df.groupby(['VisitNumber', 'DepartmentDescription'])['VisitNumber'].transform('count')
    return df

# Call the function with your 'walmart_train' dataset
walmart_train = encode_additional_features(walmart_train)
print("Encoded Walmart Training: \n", walmart_train.head())

# Call the function with your 'walmart_test' dataset
walmart_test = encode_additional_features(walmart_test)
print("Encoded Walmart Test: \n", walmart_test.head())

Исследовательский анализ данных:

В проведенном нами EDA, который включает в себя такие визуализации, как диаграммы рассеяния, корреляционные матрицы и гистограммы, раскрывается информация о покупательском поведении в зависимости от типов поездок. Эти результаты способствуют лучшему пониманию моделей покупок и типов поездок клиентов.

Создание базовой модели с использованием полиномиальной логистической регрессии

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

Как отмечалось выше, наша базовая модель показала низкую производительность: точность проверки составила всего 27,72 %.

Чтобы повысить точность, давайте изучим деревья решений и случайные леса.

Обучение с использованием деревьев решений

Алгоритм дерева решений начинается с изучения объектов в наборе данных и выбора того, который лучше всего разбивает данные на разные классы (типы поездок). «Наилучшее разделение» определяется на основе такого критерия, как примесь Джини или энтропия.

Цель состоит в том, чтобы найти функцию, которая обеспечивает максимальную информационную выгоду или максимально снижает неопределенность в отношении целевой переменной (типа поездки). После выбора лучшего объекта набор данных разбивается на подмножества в зависимости от значений этого объекта. Каждое подмножество представляет собой ветвь дерева решений.

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

%%time
from sklearn.tree import DecisionTreeClassifier

# Train-validation split
x_train_split, x_val, y_train_split, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=42)

# Create a Decision Tree Classifier
decision_tree_model = DecisionTreeClassifier(random_state=42)

# Training the model on the training data
decision_tree_model.fit(x_train_split, y_train_split)

# Making predictions on the training data
y_train_pred = decision_tree_model.predict(x_train_split)

# Making predictions on the validation data
y_val_pred = decision_tree_model.predict(x_val)

# Accuracy of the model on the validation data
accuracy_train = accuracy_score(y_train_split, y_train_pred)
accuracy_val = accuracy_score(y_val, y_val_pred)

# Calculate precision, recall, and F1-Score
precision_val = precision_score(y_val, y_val_pred, average='weighted')
recall_val = recall_score(y_val, y_val_pred, average='weighted')
f1_val = f1_score(y_val, y_val_pred, average='weighted')

print(f"Decision Tree Model Accuracy in Training df: {accuracy_train*100:.2f}%")
print(f"Decision Tree Model Accuracy in Validation df: {accuracy_val*100:.7f}%")
print(f"Decision Tree Model Precision in Validation df: {precision_val:.7f}")
print(f"Decision Tree Model Recall in Validation df: {recall_val:.7f}")
print(f"Decision Tree Model F1-Score in Validation df: {f1_val:.7f}")

Точность обучающих данных 100,00 % означает, что модель прекрасно усвоила обучающие данные, включая как закономерности, так и шум в данных. Это явный признак переобучения. Модель, по сути, запомнила обучающие данные, поэтому она работает с ними так хорошо.

Модель дерева решений дает точность 73,42% в наборе проверочных данных, что больше, чем то, что мы наблюдали в нашей простой базовой модели, и значительно ниже точности обучения. Это указывает на то, что, хотя модель сравнительно хорошо обобщает новые, невидимые данные (данные проверки), мы все же можем повысить точность проверки за счет настройки гиперпараметров с помощью GridSearchCV.

На графике выше показаны функции с самым высоким рейтингом и их оценки важности. Например, TotalItems лидирует с показателем важности 0,214, за ним следует VisitNumber с показателем 0,206. Это дает представление о важнейших функциях, управляющих процессом дерева решений, помогая в выборе функций, интерпретации модели и усилиях по оптимизации.

Оптимизация деревьев решений посредством уточнения гиперпараметров

Гиперпараметры — это параметры модели машинного обучения, которые изучаются во время обучения, заранее определяются пользователем или специалистом по обработке данных и влияют на поведение алгоритма обучения. В приведенной выше модели дерева решений необходимо настроить следующие гиперпараметры: max_eeps, min_samples_leaf, max_features, min_samples_split, критерий.

Давайте проверим вручную влияние этих гиперпараметров на точность проверки.

%%time
def test_params_dt(**params):
    # Train-validation split
    x_train_split, x_val, y_train_split, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=42)
    decision_tree_model = DecisionTreeClassifier(random_state=42, **params).fit(x_train_split, y_train_split)
    y_train_pred = decision_tree_model.predict(x_train_split)
    y_val_pred = decision_tree_model.predict(x_val)
    return accuracy_score(y_train_split, y_train_pred), accuracy_score(y_val, y_val_pred)

print("Parameter max_depth = 100 gives accuracy:", test_params_dt(max_depth=100)) # correct, 0.7342343064056142
print("Parameter criterion = 'entropy' gives accuracy:", test_params_dt(criterion='entropy')) # correct, 0.773768705739097
print("Parameter min_samples_split = 2 gives accuracy:", test_params_dt(min_samples_split=2)) # correct, 0.7342343064056142
print("Parameter min_samples_leaf = 2 gives accuracy:", test_params_dt(min_samples_leaf=2)) # correct, 0.7082305252026789
print("Parameter max_features = None gives accuracy:", test_params_dt(max_features=None)) # correct, 0.7342343064056142
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
print("Final Tuned accuracy for decision tree:", test_params_dt(max_depth=100, criterion='entropy', min_samples_split=2, min_samples_leaf=2, max_features=None)) #

Методом проб и ошибок мы заметили, что точность увеличивается при изменении критерия на «энтропию». Для остальных параметров точность проверки остается прежней. Общая настроенная точность составила 74,87%, что больше предварительно настроенной точности (73,42%).

GridSearchCV и RandomizedSearchCV — это мощные методы настройки гиперпараметров в моделях машинного обучения. Они помогают нам систематически перебирать различные комбинации гиперпараметров, чтобы найти лучший набор, который оптимизирует производительность модели.

Давайте посмотрим, сможем ли мы еще больше повысить точность проверки, используя эти методы.

GridSearchCV и RandomizedSearchCV

# Function to tune hyperparameters using GridSearchCV and RandomizedSearchCV
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV

def tune_hyperparameters(model, param_grid_gs, param_grid_rs, x_train, y_train, cv_gs, cv_rs, n_iter):
    # Train-validation split
    x_train_split, x_val, y_train_split, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=42)

    # GridSearchCV
    grid_search = GridSearchCV(model, param_grid_gs, cv=cv_gs, scoring='accuracy', n_jobs=-1)
    grid_search.fit(x_train_split, y_train_split)

    # Best hyperparameters
    best_params_grid = grid_search.best_params_
    best_model_grid = grid_search.best_estimator_
    val_accuracy_grid = best_model_grid.score(x_val, y_val)

    # RandomizedSearchCV
    random_search = RandomizedSearchCV(model, param_grid_rs, n_iter=n_iter, cv=cv_rs, scoring='accuracy', n_jobs=-1, random_state=42)
    random_search.fit(x_train_split, y_train_split)

    # Best hyperparameters
    best_params_random = random_search.best_params_
    best_model_random = random_search.best_estimator_
    val_accuracy_random = best_model_random.score(x_val, y_val)

    # Making predictions on the validation data using the best grid search model
    y_val_pred_grid = best_model_grid.predict(x_val)

    # Making predictions on the validation data using the best randomized search model
    y_val_pred_random = best_model_random.predict(x_val)

    # Calculate precision, recall, and F1-Score for the grid search model
    precision_val_grid = precision_score(y_val, y_val_pred_grid, average='weighted')
    recall_val_grid = recall_score(y_val, y_val_pred_grid, average='weighted')
    f1_val_grid = f1_score(y_val, y_val_pred_grid, average='weighted')

    # Calculate precision, recall, and F1-Score for the randomized search model
    precision_val_random = precision_score(y_val, y_val_pred_random, average='weighted')
    recall_val_random = recall_score(y_val, y_val_pred_random, average='weighted')
    f1_val_random = f1_score(y_val, y_val_pred_random, average='weighted')

    return (
        best_params_grid, val_accuracy_grid,
        best_params_random, val_accuracy_random,
        precision_val_grid, recall_val_grid, f1_val_grid,
        precision_val_random, recall_val_random, f1_val_random
    )

Приведенная выше функция принимает модель и сетку параметров в качестве входных данных, а затем выполняет настройку гиперпараметров с помощью GridSearchCV и RandomizedSearchCV на основе предоставленных значений сетки параметров и данных обучения. Это помогает найти лучшие гиперпараметры для данной модели, потенциально улучшая ее производительность. Это систематический способ поиска по различным гиперпараметрам для оптимизации производительности модели, не полагаясь исключительно на метод проб и ошибок вручную.

Использование GridSearchCV и RandomizedSearchCV для деревьев решений

%%time
# Define the model
decision_tree_model = DecisionTreeClassifier(random_state=42)

# GridSearchCV Parameters
param_grid_gs = {
    'max_depth': [100, 500],
    'min_samples_leaf': [2, 3, 4],
    'max_features': [None],
    'min_samples_split': [2, 3, 4],
    'criterion': ['entropy']
}

# RandomizedSearchCV Parameters
param_grid_rs = {
  "criterion": ['entropy'],
  "max_depth": [100, 200, 500],
  'min_samples_leaf': [2, 3, 4],
  'max_features': [None],
  'min_samples_split': [2, 3, 4],
  "splitter": ["best", "random"]
  }

# Call the function with the defined model and hyperparameter grid
best_params_grid, val_accuracy_grid, best_params_random, val_accuracy_random, precision_val_grid, recall_val_grid, f1_val_grid, precision_val_random, recall_val_random, f1_val_random = tune_hyperparameters(decision_tree_model, param_grid_gs, param_grid_rs, x_train, y_train, cv_gs = 5, cv_rs = 2, n_iter = 2)

# Print the results
print("GridSearchCV - Best hyperparameters:", best_params_grid)
print("GridSearchCV - Validation accuracy:", val_accuracy_grid)
print("RandomizedSearchCV - Best hyperparameters:", best_params_random)
print("RandomizedSearchCV - Validation accuracy:", val_accuracy_random)
print(f"Decision Tree Model Precision in Validation df (Grid Search): {precision_val_grid:.7f}")
print(f"Decision Tree Model Recall in Validation df (Grid Search): {recall_val_grid:.7f}")
print(f"Decision Tree Model F1-Score in Validation df (Grid Search): {f1_val_grid:.7f}")
print(f"Decision Tree Model Precision in Validation df (Random Search): {precision_val_random:.7f}")
print(f"Decision Tree Model Recall in Validation df (Random Search): {recall_val_random:.7f}")
print(f"Decision Tree Model F1-Score in Validation df (Random Search): {f1_val_random:.7f}")

Наблюдение:

  • Исходная точность проверки: 73,42%
  • GridSearchCV — точность проверки: 74,87%
  • RandomizedSearchCV — точность проверки: 75,63%

GridSearchCV и RandomizedSearchCV повысили точность модели по сравнению с оригиналом. Это подчеркивает влияние настройки гиперпараметра на обнаружение закономерностей и улучшение прогнозов в наборе проверки. Примечательно, что RandomizedSearchCV обеспечивает немного лучшую точность проверки, чем GridSearchCV, что указывает на эффективную случайную выборку гиперпараметров для оптимальной производительности набора данных.

Обучение с использованием случайных лесов

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

%%time
from sklearn.ensemble import RandomForestClassifier

# Create the RandomForestClassifier model
random_forest_model = RandomForestClassifier(random_state=42)

# Train-validation split
x_train_split, x_val, y_train_split, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=42)

# # Reshaping the target variables to 1-dimensional arrays
# y_train_split = y_train_split.ravel()
# y_val = y_val.ravel()

# Training the model on the training data
random_forest_model.fit(x_train_split, y_train_split)

# Making predictions on the training data
y_train_pred = random_forest_model.predict(x_train_split)

# Making predictions on the validation data
y_val_pred = random_forest_model.predict(x_val)

# Accuracy of the model on the validation data
accuracy_train = accuracy_score(y_train_split, y_train_pred)
accuracy_val = accuracy_score(y_val, y_val_pred)

# Calculate precision, recall, and F1-Score
precision_val = precision_score(y_val, y_val_pred, average='weighted')
recall_val = recall_score(y_val, y_val_pred, average='weighted')
f1_val = f1_score(y_val, y_val_pred, average='weighted')

print(f"Random forest Model Accuracy in Training df: {accuracy_train*100:.2f}%")
print(f"Random forest Model Accuracy in Validation df: {accuracy_val*100:.7f}%")
print(f"Random forest Model Precision in Validation df: {precision_val:.7f}")
print(f"Random forest Model Recall in Validation df: {recall_val:.7f}")
print(f"Random forest Model F1-Score in Validation df: {f1_val:.7f}")

Случайные леса достигают точности проверки 77,57 %, превосходя деревья решений. Это улучшение предполагает, что ансамблевая природа уменьшает переобучение, фиксирует разнообразные закономерности и повышает надежность. Хотя интерпретируемость может быть поставлена ​​под угрозу, компромисс между точностью и интерпретируемостью благоприятствует случайным лесам.

Давайте попробуем повысить точность проверки случайных лесов, используя настройку гиперпараметров.

Оптимизация случайных лесов посредством уточнения гиперпараметров

Давайте выполним поиск по различным гиперпараметрам, чтобы оптимизировать производительность модели случайного леса, используя метод проб и ошибок вручную, а затем настроим ее с помощью GridSearchCV и RandomizedSearchCV.

%%time
from sklearn.ensemble import RandomForestClassifier

def test_params_dt(**params):
    # Train-validation split
    x_train_split, x_val, y_train_split, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=42)
    random_forest_model = RandomForestClassifier(random_state=42, **params).fit(x_train_split, y_train_split)
    y_train_pred = random_forest_model.predict(x_train_split)
    y_val_pred = random_forest_model.predict(x_val)
    return accuracy_score(y_train_split, y_train_pred), accuracy_score(y_val, y_val_pred)

print("Parameter max_depth = 100 gives accuracy:", test_params_dt(max_depth=100)) # 0.7756673182298843
print("Parameter criterion = 'entropy' gives accuracy:", test_params_dt(criterion='entropy')) # 0.8039302079661614
print("Parameter min_samples_split = 2 gives accuracy:", test_params_dt(min_samples_split=2)) # 0.7756673182298843
print("Parameter min_samples_leaf = 2 gives accuracy:", test_params_dt(min_samples_leaf=2)) # 0.7525234722978819
print("Parameter max_features = None gives accuracy:", test_params_dt(max_features=None)) # 0.7898067741211907
print("Parameter n_estimators = 50 gives accuracy:", test_params_dt(n_estimators=100)) # 0.7756673182298843
print("Parameter bootstrap = True gives accuracy:", test_params_dt(bootstrap = True)) # 0.7756673182298843
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
print("Final Tuned accuracy for random forest tree:", test_params_dt(max_depth=100, criterion='entropy', min_samples_split=2, min_samples_leaf=2, max_features=None, bootstrap = True, n_estimators = 50, n_jobs=-1)) # 0.8056605889704233

Код оценивает различные гиперпараметры для RandomForestClassifier, указывая на то, что очень высокая точность обучения предполагает риски переобучения. Критерий «Энтропия» и меньшие значения min_samples_split и min_samples_leaf повышают точность проверки. Окончательно настроенная модель достигает точности обучения около 98,28 % и точности проверки 80,47 %, что подчеркивает компромисс между переоснащением и обобщением.

Использование GridSearchCV и RandomizedSearchCV для случайных лесов

%%time
from sklearn.ensemble import RandomForestClassifier

# Define the model
random_forest_model = RandomForestClassifier(random_state=42)

# GridSearchCV Parameters
param_grid_gs = {
    'max_depth': [100],
    'min_samples_leaf': [2],
    'max_features': [None],
    'min_samples_split': [2],
    'criterion': ['entropy']
}

# RandomizedSearchCV Parameters
param_grid_rs = {
    "criterion": ['entropy'],
    "max_depth": [100],
    'min_samples_leaf': [2],
    'max_features': [None],
    'min_samples_split': [2],
    "n_estimators": [50],
    "bootstrap": [True]
}

# Call the function with the defined model and hyperparameter grid
best_params_grid, val_accuracy_grid, best_params_random, val_accuracy_random, precision_val_grid, recall_val_grid, f1_val_grid, precision_val_random, recall_val_random, f1_val_random = tune_hyperparameters(random_forest_model, param_grid_gs, param_grid_rs, x_train, y_train, cv_gs = 2, cv_rs = 2, n_iter = 2)

# Print the results
print("GridSearchCV - Best hyperparameters:", best_params_grid)
print("GridSearchCV - Validation accuracy:", val_accuracy_grid)
print("RandomizedSearchCV - Best hyperparameters:", best_params_random)
print("RandomizedSearchCV - Validation accuracy:", val_accuracy_random)
print(f"Random Forest Tree Model Precision in Validation df (Grid Search): {precision_val_grid:.7f}")
print(f"Random Forest Model Recall in Validation df (Grid Search): {recall_val_grid:.7f}")
print(f"Random Forest Model F1-Score in Validation df (Grid Search): {f1_val_grid:.7f}")
print(f"Random Forest Model Precision in Validation df (Random Search): {precision_val_random:.7f}")
print(f"Random Forest Model Recall in Validation df (Random Search): {recall_val_random:.7f}")
print(f"Random Forest Model F1-Score in Validation df (Random Search): {f1_val_random:.7f}")

Наблюдения:

  • Точность исходной проверки: 77,56%
  • GridSearchCV — Точность проверки: 80,56%
  • RandomizedSearchCV — точность проверки: 80,46 %.

Как отмечалось выше, GridSearchCV и RandomizedSearchCV работают значительно лучше, чем то, что мы наблюдали до настройки случайных лесов.

Окончательные результаты

  • Ручная настройка привела к заметному повышению точности обеих моделей, что позволяет предположить, что ручной выбор конкретных гиперпараметров на основе знаний предметной области или экспериментов может иметь положительный эффект.
  • Настройка GridSearchCV не привела к значительному повышению точности по сравнению с ручной настройкой, что, возможно, указывает на то, что первоначальная ручная настройка была эффективной.
  • Настройка RandomizedSearchCV показала некоторое постепенное улучшение по сравнению с ручной настройкой, демонстрируя потенциал исследования более широкого пространства гиперпараметров.
  • Случайные леса неизменно превосходят деревья решений при всех подходах к настройке, что подтверждает мнение о том, что ансамблевые методы часто приводят к более высокой производительности прогнозирования.
  • Достижение точности более 80 % с использованием модели случайного леса является многообещающим, но дальнейшее изучение проектирования функций, предварительной обработки данных и потенциально более продвинутых моделей может привести к еще более высокой производительности.

Будущие работы

  • Использование моделей градиентного повышения, таких как XGBoost или LightGBM и SVM. Эти модели известны своей высокой производительностью и часто превосходят традиционные алгоритмы.
  • Продолжайте экспериментировать с разработкой функций, создавая более значимые функции из существующих.
  • Проведите анализ ошибок, чтобы понять неправильные классификации и выявить закономерности в прогнозах. Этот анализ может способствовать дальнейшему совершенствованию моделей.
  • Улучшить настройку гиперпараметров.
  • А ещё пересмотрите «Клинику».

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