увеличить скорость для SVM с полиномиальным ядром - PullRequest
0 голосов
/ 02 апреля 2019

Я новичок в машинном обучении.
Я использую машины опорных векторов (SVM) с «полиномиальным» ядром для многоклассовой классификации.Размер моего набора данных (56010395, 4) в форме (без образцов, без функций).Тем не менее, моя машина бесконечно тренировалась с прошлой недели, и тренировка еще не закончена.Мой код действительно прост, поэтому я не понимаю, в чем проблема в моем коде.Я не могу отобрать свой набор данных.Объем моей оперативной памяти составляет 15 ГБ, и я использую процессор Intel i7.

Я уже пробовал SVM с линейным классификатором, и обучение завершилось за 3 часа с точностью до 75%. Также данные масштабируются с использованием MinMaxscaler.

from sklearn.svm import SVC
X_train, X_test, y_train, y_test = train_test_split(X_data, y_labels, test_size=0.3, random_state=0)

print('start training')
start = time. time()
svm_model_linear = SVC(kernel='poly', degree=3, C=1.0, gamma = 'auto').fit(X_train, y_train)
print('training_finished')
end = time. time()
print('time: ', end - start)
svm_predictions = svm_model_linear.predict(X_test)

1 Ответ

0 голосов
/ 06 апреля 2019

У SVM есть время тренировки, которое масштабируется квадратично с количеством образцов или хуже. Для O (n ^ 2) время пропорционально c * n ^ 2). Ваша конфигурация модели занимает около 20 секунд с 100 тыс. Функций на моей машине, что дает постоянную величину около c=2e9. Таким образом, ожидаемое время обучения для 56 010 395 образцов составляет 72 дня, вероятно, значительно больше.

Так что либо делайте выборку из своего набора данных, либо используйте другой классификатор. Вы можете использовать небольшой многослойный персептрон, чтобы получить выразительность, аналогичную SVM с полиномиальным ядром. Его можно тренировать с помощью мини-партий с использованием SGD. Использование потери шарнира - это то же, что и потеря SVM.

Кстати, вам всегда нужно оптимизировать гиперпараметр C для SVM. Лучшая практика - провести 5-кратную перекрестную проверку в сеточном поиске. Таким образом, вы должны планировать тренировать как минимум 50 моделей ...


import time

from sklearn.svm import SVC
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
import numpy
import pandas

def time_training(estimator, n_samples):
    X, y = make_moons(n_samples=n_samples, noise=0.1, random_state=1)
    X = numpy.concatenate([X, X], axis=1)
    assert (X.shape[1] == 4), X.shape

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

    start = time. time()
    estimator.fit(X_train, y_train)
    end = time.time()
    t = end-start
    print('took', n_samples, t)
    return t

def main():
    model = SVC(kernel='poly', degree=3, C=1.0, gamma = 'auto')
    sizes = numpy.array((100, 1e3, 1e4, 2e4, 4e4, 6e4, 1e5, 1.1e5, 1.2e5)).astype(int)
    times = [ time_training(model, s) for s in sizes ]

    df = pandas.DataFrame({
        'samples': sizes,
        'time': times,
    })
    df.to_csv('temp/svmtrain.csv')

if __name__ == '__main__':
    main()

[jon@jon-thinkpad ~]$ python3 temp/svm-training-time.py
took 100 0.0006172657012939453
took 1000 0.00444340705871582
took 10000 0.26808977127075195
took 20000 1.1068146228790283
took 40000 3.8822362422943115
took 60000 8.051671743392944
took 100000 20.05191993713379
took 110000 36.83517003059387
took 120000 61.012284994125366
>>> 0.26/(10000**2)
2.6e-09
>>> 20/(100000**2)
2e-09
>>> 2e-9*(56e6**2)/(3600*24)
72.5925925925926
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...