Приближение полиномиального ядра с использованием Scikit - Learn

Beginner

This tutorial is from open-source community. Access the source code

Введение

В этом практическом занятии будет показано, как использовать приближение полиномиального ядра в scikit-learn для эффективного генерации приближений пространства признаков с полиномиальным ядром. Это используется для обучения линейных классификаторов, которые приближают точность классификаторов с ядром. Будем использовать датасет Covtype, который содержит 581 012 образцов по 54 признака каждому, распределенных по 6 классам. Цель этого датасета - предсказать тип лесного покрова только по картографическим переменным (без данных, полученных с помощью дистанционного зондирования). После загрузки мы преобразуем его в задачу бинарной классификации, чтобы соответствовать версии датасета на веб-странице LIBSVM, которая использовалась в оригинальной статье.

Советы по использованию ВМ

После запуска ВМ кликните в верхнем левом углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.

Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook загрузится. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.

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

Загрузка и подготовка данных

Сначала мы загрузим датасет Covtype и преобразуем его в задачу бинарной классификации, выбрав только один класс. Затем мы разделим данные на обучающий и тестовый наборы и нормализуем признаки.

from sklearn.datasets import fetch_covtype
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, Normalizer

## Загрузка датасета Covtype, выбор только одного класса
X, y = fetch_covtype(return_X_y=True)
y[y!= 2] = 0
y[y == 2] = 1

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

## Нормализация признаков
mm = make_pipeline(MinMaxScaler(), Normalizer())
X_train = mm.fit_transform(X_train)
X_test = mm.transform(X_test)

Создание базовой модели

Мы обучим линейный SVM на исходных признаках, чтобы создать базовую модель, и выведем ее точность.

from sklearn.svm import LinearSVC

## Обучаем линейный SVM на исходных признаках
lsvm = LinearSVC(dual="auto")
lsvm.fit(X_train, y_train)
lsvm_score = 100 * lsvm.score(X_test, y_test)

## Выводим точность базовой модели
print(f"Linear SVM score on raw features: {lsvm_score:.2f}%")

Создание модели приближения ядра

Теперь мы обучим линейные SVM на признаках, сгенерированных с использованием PolynomialCountSketch с разными значениями n_components. Мы будем использовать цикл для перебора различных значений n_components и выводить точность каждой модели.

from sklearn.kernel_approximation import PolynomialCountSketch

n_runs = 1
N_COMPONENTS = [250, 500, 1000, 2000]

for n_components in N_COMPONENTS:
    ps_lsvm_score = 0
    for _ in range(n_runs):
        ## Обучаем линейный SVM на признаках, сгенерированных с использованием PolynomialCountSketch
        pipeline = make_pipeline(
            PolynomialCountSketch(n_components=n_components, degree=4),
            LinearSVC(dual="auto"),
        )
        pipeline.fit(X_train, y_train)
        ps_lsvm_score += 100 * pipeline.score(X_test, y_test)

    ps_lsvm_score /= n_runs

    ## Выводим точность модели
    print(f"Linear SVM score on {n_components} PolynomialCountSketch features: {ps_lsvm_score:.2f}%")

Создание модели SVM с ядром

Мы обучим SVM с ядром, чтобы увидеть, насколько хорошо PolynomialCountSketch приближает производительность ядра.

from sklearn.svm import SVC

## Обучаем SVM с ядром
ksvm = SVC(C=500.0, kernel="poly", degree=4, coef0=0, gamma=1.0)
ksvm.fit(X_train, y_train)
ksvm_score = 100 * ksvm.score(X_test, y_test)

## Выводим точность SVM с ядром
print(f"Kernel-SVM score on raw features: {ksvm_score:.2f}%")

Сравнение результатов

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

import matplotlib.pyplot as plt

## Построение графиков результатов различных методов
fig, ax = plt.subplots(figsize=(7, 7))
ax.scatter(
    [
        lsvm_time,
    ],
    [
        lsvm_score,
    ],
    label="Linear SVM",
    c="green",
    marker="^",
)

for n_components in N_COMPONENTS:
    ax.scatter(
        [
            results[f"LSVM + PS({n_components})"]["time"],
        ],
        [
            results[f"LSVM + PS({n_components})"]["score"],
        ],
        c="blue",
    )
    ax.annotate(
        f"n_comp.={n_components}",
        (
            results[f"LSVM + PS({n_components})"]["time"],
            results[f"LSVM + PS({n_components})"]["score"],
        ),
        xytext=(-30, 10),
        textcoords="offset pixels",
    )

ax.scatter(
    [
        ksvm_time,
    ],
    [
        ksvm_score,
    ],
    label="Kernel SVM",
    c="red",
    marker="x",
)

ax.set_xlabel("Training time (s)")
ax.set_ylabel("Accuracy (%)")
ax.legend()
plt.show()

Резюме

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