Посібник зі створення кастомних трансформерів у scikit-learn для надійних конвеєрів машинного навчання. Покращуйте попередню обробку даних та інженерію ознак.
Конвеєр машинного навчання: Розробка кастомних трансформерів у Scikit-learn
Конвеєри машинного навчання є важливими для створення надійних та підтримуваних моделей машинного навчання. Scikit-learn (sklearn) надає потужний фреймворк для створення таких конвеєрів. Ключовим компонентом будь-якого хорошого конвеєра є здатність виконувати власні перетворення даних. Ця стаття розглядає розробку кастомних трансформерів у scikit-learn, надаючи вичерпний посібник для науковців з даних та інженерів машинного навчання по всьому світу.
Що таке конвеєр машинного навчання?
Конвеєр машинного навчання — це послідовність компонентів обробки даних, які з'єднані в ланцюжок. Ці компоненти зазвичай включають:
- Очищення даних: Обробка пропущених значень, викидів та невідповідностей.
- Інженерія ознак: Створення нових ознак з наявних для покращення продуктивності моделі.
- Відбір ознак: Вибір найбільш релевантних ознак для моделі.
- Навчання моделі: Навчання моделі машинного навчання на підготовлених даних.
- Оцінка моделі: Оцінювання продуктивності навченої моделі.
Використання конвеєра має кілька переваг, зокрема:
- Відтворюваність: Гарантія того, що ті самі кроки обробки даних застосовуються послідовно.
- Модульність: Розбиття робочого процесу обробки даних на компоненти для повторного використання.
- Підтримуваність: Спрощення оновлення та підтримки робочого процесу обробки даних.
- Спрощене розгортання: Оптимізація процесу розгортання моделей машинного навчання.
Навіщо потрібні кастомні трансформери?
Scikit-learn пропонує широкий спектр вбудованих трансформерів для поширених завдань обробки даних. Однак у багатьох реальних сценаріях вам доведеться виконувати власні перетворення даних, специфічні для ваших даних і задачі. Саме тут у нагоді стають кастомні трансформери. Вони дозволяють інкапсулювати вашу власну логіку обробки даних у компоненти для повторного використання, які можна безперешкодно інтегрувати в конвеєр scikit-learn.
Наприклад, уявіть, що ви працюєте з даними клієнтів глобальної платформи електронної комерції. Вам може знадобитися створити кастомний трансформер, який конвертує валюти транзакцій у спільну валюту (наприклад, долар США) на основі історичних обмінних курсів. Або розгляньте сценарій із даними сенсорів з IoT-пристроїв у різних країнах; ви могли б створити кастомний трансформер для нормалізації даних на основі місцевих часових поясів та одиниць вимірювання.
Створення кастомного трансформера
Щоб створити кастомний трансформер у scikit-learn, вам потрібно створити клас, який успадковує від sklearn.base.BaseEstimator та sklearn.base.TransformerMixin. Ваш клас повинен реалізувати два методи:
fit(self, X, y=None): Цей метод вивчає будь-які параметри, необхідні для перетворення. У багатьох випадках цей метод просто повертаєself.transform(self, X): Цей метод застосовує перетворення до даних.
Ось базовий приклад кастомного трансформера, який додає постійне значення до кожної ознаки:
from sklearn.base import BaseEstimator, TransformerMixin
import numpy as np
class AddConstantTransformer(BaseEstimator, TransformerMixin):
def __init__(self, constant=1):
self.constant = constant
def fit(self, X, y=None):
return self
def transform(self, X):
return X + self.constant
Розглянемо цей приклад детальніше:
- Імпорт необхідних бібліотек:
BaseEstimator,TransformerMixinзsklearn.baseтаnumpyдля числових операцій. - Визначення класу:
AddConstantTransformerуспадковує відBaseEstimatorтаTransformerMixin. - Конструктор (
__init__): Цей метод ініціалізує трансформер зі значеннямconstant(за замовчуванням 1). - Метод
fit: Цей метод просто повертаєself, оскільки цьому трансформеру не потрібно вивчати жодних параметрів з даних. - Метод
transform: Цей метод додає значенняconstantдо кожного елемента у вхідних данихX.
Приклад використання
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
X = np.array([[1, 2], [3, 4], [5, 6]])
pipeline = Pipeline([
('scaler', StandardScaler()),
('add_constant', AddConstantTransformer(constant=2))
])
X_transformed = pipeline.fit_transform(X)
print(X_transformed)
Цей приклад демонструє, як використовувати AddConstantTransformer у конвеєрі. Спочатку дані масштабуються за допомогою StandardScaler, а потім додається константа за допомогою нашого кастомного трансформера.
Просунута розробка кастомних трансформерів
Тепер розглянемо деякі більш просунуті сценарії та техніки для створення кастомних трансформерів.
Обробка категоріальних ознак
Категоріальні ознаки є поширеним типом даних у машинному навчанні. Ви можете створювати кастомні трансформери для виконання різноманітних операцій з категоріальними ознаками, таких як one-hot кодування, кодування міток або хешування ознак.
Ось приклад кастомного трансформера, який виконує one-hot кодування для вказаних стовпців:
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
class CategoricalEncoder(BaseEstimator, TransformerMixin):
def __init__(self, categorical_features=None):
self.categorical_features = categorical_features
self.encoder = None
def fit(self, X, y=None):
if self.categorical_features is None:
self.categorical_features = X.select_dtypes(include=['object']).columns
self.encoder = OneHotEncoder(handle_unknown='ignore', sparse_output=False)
self.encoder.fit(X[self.categorical_features])
return self
def transform(self, X):
X_encoded = self.encoder.transform(X[self.categorical_features])
X_encoded = pd.DataFrame(X_encoded, index=X.index, columns=self.encoder.get_feature_names_out(self.categorical_features))
X = X.drop(columns=self.categorical_features)
X = pd.concat([X, X_encoded], axis=1)
return X
У цьому прикладі:
- Трансформер автоматично визначає категоріальні стовпці (якщо вони не вказані).
- Він використовує
OneHotEncoderзі scikit-learn для виконання кодування. - Він обробляє невідомі категорії за допомогою
handle_unknown='ignore'. - Закодовані ознаки об'єднуються з вихідним датафреймом.
Обробка пропущених значень
Пропущені значення — ще одна поширена проблема в наборах даних для машинного навчання. Ви можете створювати кастомні трансформери для заповнення пропущених значень за допомогою різних стратегій, таких як заповнення середнім, медіаною або модою.
Ось приклад кастомного трансформера, який заповнює пропущені значення за допомогою медіани:
from sklearn.impute import SimpleImputer
class MissingValueImputer(BaseEstimator, TransformerMixin):
def __init__(self, strategy='median', missing_values=np.nan):
self.strategy = strategy
self.missing_values = missing_values
self.imputer = None
def fit(self, X, y=None):
self.imputer = SimpleImputer(strategy=self.strategy, missing_values=self.missing_values)
self.imputer.fit(X)
return self
def transform(self, X):
return self.imputer.transform(X)
Цей трансформер використовує SimpleImputer зі scikit-learn для виконання заповнення. Він дозволяє вам вказати стратегію заповнення та значення, яке використовується для позначення пропущених значень.
Масштабування та нормалізація ознак
Масштабування та нормалізація ознак — це важливі кроки попередньої обробки для багатьох алгоритмів машинного навчання. Ви можете створювати кастомні трансформери для реалізації різних технік масштабування та нормалізації.
Хоча scikit-learn надає такі трансформери, як StandardScaler та MinMaxScaler, вам може знадобитися кастомний скейлер для специфічних розподілів даних. Наприклад, якщо у вас є дані з дуже асиметричним розподілом, PowerTransformer (також доступний у scikit-learn) може бути більш доречним. Однак ви можете інкапсулювати його у власний трансформер, щоб керувати його параметрами та безперешкодно інтегрувати у ваш конвеєр.
from sklearn.preprocessing import PowerTransformer
class SkewedDataTransformer(BaseEstimator, TransformerMixin):
def __init__(self, method='yeo-johnson'):
self.method = method
self.transformer = None
def fit(self, X, y=None):
self.transformer = PowerTransformer(method=self.method)
self.transformer.fit(X)
return self
def transform(self, X):
return self.transformer.transform(X)
Поєднання кількох перетворень
Іноді вам може знадобитися застосувати кілька перетворень до одних і тих самих даних. Ви можете створити кастомний трансформер, який поєднує кілька перетворень в один крок. Це може допомогти спростити ваш конвеєр і зробити його більш читабельним.
Ось приклад кастомного трансформера, який поєднує one-hot кодування та заповнення пропущених значень:
class CombinedTransformer(BaseEstimator, TransformerMixin):
def __init__(self, categorical_features=None, missing_value_strategy='median'):
self.categorical_features = categorical_features
self.missing_value_strategy = missing_value_strategy
self.categorical_encoder = None
self.missing_value_imputer = None
def fit(self, X, y=None):
self.categorical_encoder = CategoricalEncoder(categorical_features=self.categorical_features)
self.missing_value_imputer = MissingValueImputer(strategy=self.missing_value_strategy)
self.categorical_encoder.fit(X)
self.missing_value_imputer.fit(X)
return self
def transform(self, X):
X = self.categorical_encoder.transform(X)
X = self.missing_value_imputer.transform(X)
return X
Цей трансформер використовує CategoricalEncoder та MissingValueImputer з попередніх прикладів для виконання як one-hot кодування, так і заповнення пропущених значень за один крок.
Найкращі практики для розробки кастомних трансформерів
Ось кілька найкращих практик, яких варто дотримуватися при розробці кастомних трансформерів:
- Будьте простими: Кожен трансформер повинен виконувати одне, чітко визначене завдання.
- Робіть його багаторазовим: Проєктуйте ваші трансформери якомога більш загальними, щоб їх можна було повторно використовувати в різних конвеєрах.
- Обробляйте крайні випадки: Враховуйте, як ваш трансформер буде обробляти крайні випадки, такі як пропущені значення, викиди та неочікувані типи даних.
- Пишіть юніт-тести: Пишіть юніт-тести, щоб переконатися, що ваш трансформер працює коректно.
- Документуйте свій код: Чітко документуйте свій код, щоб інші могли зрозуміти, як використовувати ваш трансформер.
Приклади з реального світу
Розглянемо ще кілька прикладів кастомних трансформерів з реального світу.
Інженерія ознак з дат
При роботі з часовими рядами часто буває корисно витягувати ознаки з дат, такі як день тижня, місяць року або квартал року. Ви можете створити кастомний трансформер для виконання цього завдання.
class DateFeatureExtractor(BaseEstimator, TransformerMixin):
def __init__(self, date_columns=None):
self.date_columns = date_columns
def fit(self, X, y=None):
return self
def transform(self, X):
for col in self.date_columns:
X[col + '_dayofweek'] = X[col].dt.dayofweek
X[col + '_month'] = X[col].dt.month
X[col + '_quarter'] = X[col].dt.quarter
return X
Цей трансформер витягує день тижня, місяць та квартал із вказаних стовпців з датами.
Інженерія текстових ознак
При роботі з текстовими даними часто буває корисно виконувати інженерію ознак за допомогою таких технік, як TF-IDF або векторні представлення слів (word embeddings). Ви можете створювати кастомні трансформери для виконання цих завдань. Наприклад, розглянемо відгуки клієнтів кількома мовами. Вам може знадобитися кастомний трансформер, який перекладає відгуки англійською мовою перед застосуванням векторизації TF-IDF.
Примітка: Сервіси перекладу часто вимагають ключів API і можуть бути платними. Цей приклад зосереджений на структурі кастомного трансформера.
# Note: This example requires a translation service (e.g., Google Translate API) and API key
# from googletrans import Translator # Example library (install with pip install googletrans==4.0.0-rc1)
class TextFeatureExtractor(BaseEstimator, TransformerMixin):
def __init__(self, text_column, language='en'):
self.text_column = text_column
self.language = language
# self.translator = Translator() # Instantiate translator (requires setup)
def fit(self, X, y=None):
return self
def transform(self, X):
# Example: Translate to English (replace with actual translation logic)
# X[self.text_column + '_translated'] = X[self.text_column].apply(lambda text: self.translator.translate(text, dest=self.language).text)
# Dummy translation for demonstration purposes
X[self.text_column + '_translated'] = X[self.text_column].apply(lambda text: "Translated: " + text)
# Apply TF-IDF or other text vectorization techniques here
return X
Інженерія геопросторових ознак
При роботі з геопросторовими даними ви можете створювати кастомні трансформери для вилучення таких ознак, як відстань до найближчого міста, щільність населення або тип землекористування. Наприклад, уявіть аналіз цін на нерухомість у всьому світі. Ви могли б створити кастомний трансформер, який отримує середній рівень доходу для певного місця за допомогою зовнішніх API на основі широти та довготи.
Інтеграція з наявними бібліотеками
Кастомні трансформери можна використовувати для обгортання функціональності з інших бібліотек Python у конвеєр scikit-learn. Це дозволяє вам використовувати потужність інших бібліотек, водночас користуючись перевагами структури та організації конвеєра.
Наприклад, ви могли б використовувати кастомний трансформер для інтеграції бібліотеки для виявлення аномалій, прогнозування часових рядів або обробки зображень у ваш конвеєр машинного навчання.
Висновок
Кастомні трансформери — це потужний інструмент для створення надійних та підтримуваних конвеєрів машинного навчання в scikit-learn. Інкапсулюючи вашу власну логіку обробки даних у компоненти для повторного використання, ви можете створювати конвеєри, які легше розуміти, оновлювати та розгортати. Не забувайте дотримуватися найкращих практик, писати юніт-тести та документувати свій код, щоб ваші кастомні трансформери були надійними та підтримуваними. У міру розвитку ваших навичок у машинному навчанні, оволодіння розробкою кастомних трансформерів стане неоціненним у вирішенні складних і різноманітних реальних проблем по всьому світу. Від обробки конвертації валют для міжнародної електронної комерції до обробки даних сенсорів з IoT-пристроїв по всьому світу, кастомні трансформери дають вам змогу адаптувати ваші конвеєри до конкретних потреб ваших даних та застосунків.