Вопрос или проблема
Этот вопрос относится в целом ко всем автоматизированным методам выбора признаков. В моем конкретном случае у нас есть Python-пакет под названием tsfresh и задача многоклассовой классификации.
Что было сделано до сих пор? Я извлек признаки, используя tsfresh.extract_features, без фильтрации каких-либо признаков. Все эти признаки подаются модели RF, и модель оставляется, чтобы сама решила, какие признаки являются важными. Эффективность модели оценивается по усреднению кросс-валидации с 5-кратным разбиением, а не с использованием одного единого распределения на обучающую и тестовую выборки.
Что я хочу достичь? Следуя официальной документации tsfresh по многоклассовому выбору, разумным было бы разделить данные перед тем, как проводить какой-либо выбор признаков, используя tsfresh.select_features. Поскольку выбор признаков зачастую является довольно трудоемкой задачей, а у меня много моделей, использование кросс-валидации с 5-кратным разбиением значительно увеличивает время вычислений. Если я проведу выбор признаков с использованием tsfresh без какого-либо разбиения, я, вероятно, утечу данные?
Есть ли у вас какие-либо альтернативные решения для обработки этого сценария или мне придется смириться с этими большими временами вычислений, связанными с кросс-валидацией? Вы считаете это необходимым, если у меня есть модель RF (из-за внутреннего выбора признаков)?
Вам в целом нужно выполнять временную кросс-валидацию, если вы хотите избежать утечки времени.
Вопросы о том, действительно ли вам нужна временная кросс-валидация, оправданы ли затраты времени на вычисления и нужно ли выполнять выбор признаков перед RF, являются совершенно разными вопросами, на которые нет тривиальных ответов. Мой общий ответ был бы: да, да, нет, но есть много специфических подслучаев, где ответ был бы другим. Если ваше время вычислений является узким местом, постарайтесь проводить ваши вычисления за ночь.
Посмотрите на этот общий пример и посмотрите, подходит ли он вам.
from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Загружаем датасет о жилье в Бостоне в качестве примера
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]
reg = RandomForestRegressor()
reg.fit(X, Y)
print("Признаки, отсортированные по их значимости:")
print(sorted(zip(map(lambda x: round(x, 4), reg.feature_importances_), names),
reverse=True))
boston_pd = pd.DataFrame(boston.data)
print(boston_pd.head())
boston_pd.columns = boston.feature_names
print(boston_pd.head())
# корреляции
features = boston.feature_names
importances = reg.feature_importances_
indices = np.argsort(importances)
plt.title('Значимость признаков')
plt.barh(range(len(indices)), importances[indices], color="#8f63f4", align='center')
plt.yticks(range(len(indices)), features[indices])
plt.xlabel('Относительная важность')
plt.show()
Ответ или решение
Автоматизированный отбор признаков является важным этапом в процессе машинного обучения, однако он также может привести к утечке данных, если не следовать правильным практикам. Вот рекомендации, которые помогут избежать утечки данных при использовании пакета tsfresh и обеспечат корректное выполнение автоматизированного отбора признаков.
1. Разделение данных:
Первым и самым важным шагом является разделение данных на тренировочную и тестовую выборки до процесса извлечения признаков и их отбора. Это предотвратит утечку, так как модель не будет иметь доступа к информации из тестовой выборки.
from sklearn.model_selection import train_test_split
# Предположим, что у вас есть массив данных X (признаки) и Y (целевая переменная)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
2. Извлечение признаков на тренировочной выборке:
Следующим шагом является извлечение признаков только из тренировочной выборки. Используйте функцию tsfresh.extract_features()
только на X_train
и y_train
.
from tsfresh import extract_features
X_train_tsfresh = extract_features(X_train, y_train, column_id='id', column_sort='time')
3. Отбор признаков:
После извлечения признаков, выполните отбор признаков также только на тренировочных данных. Использование функции tsfresh.select_features()
должно происходить на тренировочной выборке:
from tsfresh import select_features
X_train_selected = select_features(X_train_tsfresh, y_train)
4. Оценка модели:
Теперь вы можете обучить свою модель на отобранных признаках з тренировки и протестировать её на тестовом наборе данных.
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X_train_selected, y_train)
X_test_tsfresh = extract_features(X_test, test_column_id='id', test_column_sort='time')
X_test_selected = X_test_tsfresh[X_train_selected.columns] # Убедитесь, что отбор соответствует
predictions = model.predict(X_test_selected)
5. Кросс-валидация:
Если вы хотите использовать кросс-валидацию, важно помнить, что кросс-валидация должна проводиться с учетом временных рядов при наличии временной зависимости в данных. В этом случае рассмотрите использование TimeSeriesSplit
из библиотеки scikit-learn.
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)
for train_index, test_index in tscv.split(X):
# ваш код для обучения и тестирования
...
Важно помнить:
-
Избыточные вычисления: Некоторые модели, такие как случайные леса (RF), действительно обеспечивают внутренний отбор признаков, что может снизить необходимость в предварительном выборе признаков. Тем не менее, в зависимости от природы ваших данных, возможно, стоит предварительно отбирать признаки, чтобы ускорить обучение.
-
Оптимизация времени вычислений: Если время вычислений становится критичным, рассмотрите возможность выполнения расчетов в период, когда вы не работаете, например, ночью, или используйте методы параллелизации для ускорения процессов.
Следуя этим рекомендациям, вы сможете эффективно управлять автоматизированным отбором признаков, минимизируя риск утечки данных и обеспечивая корректное функционирование моделей.