Машинное обучение с помощью Python в научных вычислениях: от теории к коду

Раздел: Анализ данных -> Научные вычисления

Основы машинного обучения с Python: реализация и выбор алгоритмов

Какое решение является наиболее эффективным для старта задачи классификации с табличными данными?

В большинстве случаев рекомендуется использовать ансамблевый алгоритм RandomForestClassifier из библиотеки scikit-learn. Он устойчив к переобучению, работает с пропусками (при соответствующей настройке) и не требует сложной предобработки. Ниже приведён типовой пайплайн.


from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report, confusion_matrix
import pandas as pd

# Загрузка данных (например, Iris)
data = pd.read_csv('iris.csv')
X = data.drop('species', axis=1)
y = data['species']

# Разделение на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Стандартизация (для RandomForest не обязательна, но полезна для некоторых метрик)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Обучение модели
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
model.fit(X_train_scaled, y_train)

# Оценка
y_pred = model.predict(X_test_scaled)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))
  

машинное обучение с помощью python (машинное обучение)

Какие проблемы могут возникнуть при использовании RandomForest?

  • Переобучение при слишком глубоких деревьях. Решение: ограничить max_depth или min_samples_leaf.
  • Дисбаланс классов. Решение: установить class_weight='balanced' или использовать SMOTE перед обучением.
  • Долгое обучение на больших наборах данных. Решение: уменьшить n_estimators или использовать n_jobs=-1 для параллелизации.

Какой алгоритм выбрать для бинарной классификации с линейно разделимыми данными?

Логистическая регрессия (LogisticRegression) - простой и интерпретируемый метод. Он хорошо работает, когда признаки независимы и нет сложных взаимодействий.


from sklearn.linear_model import LogisticRegression

model_log = LogisticRegression(max_iter=1000, penalty='l2', C=1.0)
model_log.fit(X_train_scaled, y_train)
print('Accuracy:', model_log.score(X_test_scaled, y_test))
  

модуль numpy в python (модуль numpy в python)

Почему логистическая регрессия может давать низкое качество?

  • Мультиколлинеарность признаков. Решение: применить регуляризацию (L1 или L2) или удалить коррелированные признаки.
  • Несбалансированные классы. Решение: использовать class_weight='balanced'.

Как обработать нелинейные зависимости в данных?

Метод опорных векторов (SVC) с ядром RBF способен строить нелинейные границы. Перед использованием обязательно выполняется стандартизация.


from sklearn.svm import SVC

model_svm = SVC(kernel='rbf', C=1.0, gamma='scale', probability=True)
model_svm.fit(X_train_scaled, y_train)
print('Accuracy:', model_svm.score(X_test_scaled, y_test))
  

Какие типичные ошибки встречаются при работе с SVM?

  • Неправильное масштабирование признаков. Решение: всегда применять StandardScaler или MinMaxScaler.
  • Выбор гиперпараметров C и gamma наугад. Решение: использовать GridSearchCV с перекрёстной проверкой.

Как классифицировать данные, когда границы классов имеют сложную форму?

Метод k-ближайших соседей (KNeighborsClassifier) не делает предположений о распределении данных, но чувствителен к масштабу и выбросам.


from sklearn.neighbors import KNeighborsClassifier

model_knn = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
model_knn.fit(X_train_scaled, y_train)
print('Accuracy:', model_knn.score(X_test_scaled, y_test))
  

Почему KNN может работать плохо?

  • Разные масштабы признаков. Решение: применить стандартизацию.
  • Неверно выбранное число соседей k. Решение: подобрать через перекрёстную проверку.
  • Высокая размерность (проклятие размерности). Решение: использовать методы понижения размерности (PCA, t-SNE).

Расширенные примеры: настройка и оценка моделей

Пример 1. Подбор гиперпараметров с помощью GridSearchCV

Пример

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier

param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [None, 10, 20],
    'min_samples_split': [2, 5, 10]
}

grid = GridSearchCV(RandomForestClassifier(random_state=42), param_grid, cv=5, scoring='accuracy')
grid.fit(X_train, y_train)

print('Лучшие параметры:', grid.best_params_)
print('Точность на тесте:', grid.score(X_test, y_test))
Лучшие параметры: {'max_depth': 10, 'min_samples_split': 5, 'n_estimators': 100}
Точность на тесте: 0.9667

Пояснение: GridSearchCV перебирает все комбинации параметров и выбирает лучшую по средней точности на 5-кратной кросс-валидации.

Пример 2. Работа с категориальными признаками с помощью ColumnTransformer

Пример

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
import pandas as pd

# Предположим, что в данных есть категориальный признак 'color' и числовые 'height', 'weight'
df = pd.DataFrame({
    'color': ['red', 'blue', 'green', 'red'],
    'height': [150, 160, 155, 170],
    'weight': [50, 60, 55, 65],
    'target': [0, 1, 0, 1]
})
X = df.drop('target', axis=1)
y = df['target']

preprocessor = ColumnTransformer(
    transformers=[
        ('num', StandardScaler(), ['height', 'weight']),
        ('cat', OneHotEncoder(drop='first'), ['color'])
    ]
)

pipeline = Pipeline([
    ('prep', preprocessor),
    ('clf', LogisticRegression(max_iter=1000))
])

pipeline.fit(X, y)
print('Коэффициенты модели:', pipeline.named_steps['clf'].coef_)
Коэффициенты модели: [[0.234 -0.567 1.234]]

Пояснение: ColumnTransformer позволяет применять разные преобразования к разным столбцам. Это удобно при работе со смешанными типами данных.

Пример 3. Визуализация кривых обучения

Пример

import matplotlib.pyplot as plt
from sklearn.model_selection import learning_curve

train_sizes, train_scores, test_scores = learning_curve(
    RandomForestClassifier(n_estimators=50, random_state=42),
    X_train, y_train,
    cv=5,
    train_sizes=np.linspace(0.1, 1.0, 5),
    scoring='accuracy'
)

train_mean = np.mean(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)

plt.plot(train_sizes, train_mean, 'o-', label='Обучение')
plt.plot(train_sizes, test_mean, 's-', label='Валидация')
plt.xlabel('Размер обучающей выборки')
plt.ylabel('Точность')
plt.legend(loc='best')
plt.title('Кривые обучения')
plt.show()
[График: две кривые, сходящиеся на уровне 0.95]

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

Пример 4. Балансировка классов с помощью SMOTE

Пример

from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

X_train_bal, y_train_bal = SMOTE(random_state=42).fit_resample(X_train, y_train)

model = RandomForestClassifier(random_state=42)
model.fit(X_train_bal, y_train_bal)
print('Точность после SMOTE:', model.score(X_test, y_test))
Точность после SMOTE: 0.95

Пояснение: SMOTE создаёт синтетические примеры миноритарного класса, что улучшает качество на несбалансированных данных. Установка imbalanced-learn обязательна.

Машинное обучение - comments

En
машинное обучение с помощью python (python)