Создайте два новых признака:

  • bad_grade_num — число негативных оценок (1, 2) в численных признаках;
  • bad_grade_str — число негативных оценок ('плохо') в строковых признаках. Для этого:
  1. Создайте список с наименованиями строковых признаков.
  2. Создайте признак bad_grade_str.

Заодно изучите важность признаков: оказались ли новые признаки полезными.

# импортируем библиотеки и объявляем константы
import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import RandomizedSearchCV

RANDOM_STATE = 42

# считываем данные из CSV-файла
df_full = pd.read_csv('railway_full.csv')

# создаём список численных признаков для создания нового
columns_grades_num = [
    'Оценка комфортности места',
    'Оценка качества уборки',
    'Оценка качества обслуживания в пути'
]

# создайте список строковых признаков для создания нового
columns_grades_str = ['Оценка комфортности покупки билета онлайн',
                      'Оценка качества питания',
                      'Оценка качества wifi',
                      'Оценка комфортности времени отправления/прибытия'
                     ]

# создайте новые признаки, которые содержат число негативных оценок 
df_full['bad_grade_num'] = df_full[columns_grades_num].isin([1, 2]).sum(axis=1)
df_full['bad_grades_str'] = df_full[columns_grades_str].isin(['плохо']).sum(axis=1)

# делим данные на входные и целевые
X = df_full.drop(['Общая оценка качества предоставленной услуги'], axis=1)
y = df_full['Общая оценка качества предоставленной услуги']

# подготавливаем данные заранее созданной функцией
X_train, X_test, y_train, y_test = prepare_data(X, y)

# инициализируем модель дерева решений
model = DecisionTreeClassifier(random_state=RANDOM_STATE)

# создаём словарь с гиперпараметрами
parameters = {
    'min_samples_split': range(2, 11),
    'min_samples_leaf': range(1, 11),
    'max_depth': range(2, 11),
}

# создаём экземпляр объекта для случайного поиска гиперпараметров
rs = RandomizedSearchCV(
    model,
    parameters,
    n_jobs=-1,
    scoring='roc_auc_ovo',
    random_state=RANDOM_STATE
)

# запускаем поиск гиперпараметров
rs.fit(X_train, y_train)

# выводим лучшую метрику и гиперпараметры
print(f'Best score: {rs.best_score_}, best params: {rs.best_params_}')

# формируем таблицу важности признаков
feature_importances = pd.DataFrame(
    {
        'Feature': X_train.columns,
        'Importance': rs.best_estimator_.feature_importances_
    })

# выводим важность признаков на экран
print(feature_importances.sort_values('Importance', ascending=False))

Результат
Best score: 0.9088671152103602, best params: {'min_samples_split': 4, 'min_samples_leaf': 7, 'max_depth': 8}
                                             Feature  Importance
6                               Оценка качества wifi    0.411362
9                                     bad_grades_str    0.207893
8                                      bad_grade_num    0.185228
12                        Путешествует по работе_нет    0.072611
14                                            Тип_св    0.023703
2                          Оценка комфортности места    0.022824
1                                         Расстояние    0.021970
0                                            Возраст    0.015116
5          Оценка комфортности покупки билета онлайн    0.012709
4                Оценка качества обслуживания в пути    0.011124
7   Оценка комфортности времени отправления/прибытия    0.004835
11                         Путешествует с детьми_нет    0.004373
3                             Оценка качества уборки    0.001969
15                 Оценка качества питания_нормально    0.001644
17                     Оценка качества питания_плохо    0.001237
10                                           Пол_муж    0.001090
18                    Оценка качества питания_хорошо    0.000312
13                                      Тип_плацкарт    0.000000
16               Оценка качества питания_отсутствует    0.000000