Запуск SVM быстрее в python

Используя приведенный ниже код для svm в python:

from sklearn import datasets from sklearn.multiclass import OneVsRestClassifier from sklearn.svm import SVC iris = datasets.load_iris() X, y = iris.data, iris.target clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto')) clf.fit(X, y) proba = clf.predict_proba(X) 

Но это занимает огромное количество времени.

Фактические размеры данных :

 train-set (1422392,29) test-set (233081,29) 

Как я могу ускорить его (параллельно или по-другому)? Пожалуйста помоги. Я уже попробовал PCA и понизил дискретизацию.

У меня 6 классов. Изменить: найдено http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDClassifier.html, но я желаю оценки вероятности, и, похоже, это не так для svm.

Редактировать:

 from sklearn import datasets from sklearn.multiclass import OneVsRestClassifier from sklearn.svm import SVC,LinearSVC from sklearn.linear_model import SGDClassifier import joblib import numpy as np from sklearn import grid_search import multiprocessing import numpy as np import math def new_func(a): #converts array(x) elements to (1/(1 + e(-x))) a=1/(1 + math.exp(-a)) return a if __name__ == '__main__': iris = datasets.load_iris() cores=multiprocessing.cpu_count()-2 X, y = iris.data, iris.target #loading dataset C_range = 10.0 ** np.arange(-4, 4); #c value range param_grid = dict(estimator__C=C_range.tolist()) svr = OneVsRestClassifier(LinearSVC(class_weight='auto'),n_jobs=cores) ################LinearSVC Code faster #svr = OneVsRestClassifier(SVC(kernel='linear', probability=True, ##################SVC code slow # class_weight='auto'),n_jobs=cores) clf = grid_search.GridSearchCV(svr, param_grid,n_jobs=cores,verbose=2) #grid search clf.fit(X, y) #training svm model decisions=clf.decision_function(X) #outputs decision functions #prob=clf.predict_proba(X) #only for SVC outputs probablilites print decisions[:5,:] vecfunc = np.vectorize(new_func) prob=vecfunc(decisions) #converts deicision to (1/(1 + e(-x))) print prob[:5,:] 

Редактировать 2: ответ пользователя3914041 дает очень плохие оценки вероятности.

  • Подготовка данных и выбор функций для Именованного объекта с использованием SVM
  • SKLearn, как получить вероятностные решения для классификатора LinearSVC
  • Прогнозирование с использованием ядра chi для многослойных изображений с использованием sklearn
  • import check_arrays от sklearn
  • Выбор из другой функции стоимости и функции активации нейронной сети
  • Получение предупреждения об устаревании в Sklearn над массивом 1d, несмотря на отсутствие массива 1D
  • Есть ли способ использовать рекурсивный выбор функций с нелинейными моделями с scikit-learn?
  • как настроить параметры пользовательской функции ядра с помощью конвейера в scikit-learn
  • 4 Solutions collect form web for “Запуск SVM быстрее в python”

    Если вы хотите как можно больше придерживаться SVC и тренироваться по полному набору данных, вы можете использовать ансамбли SVC, которые обучаются на подмножествах данных, чтобы уменьшить количество записей в классификаторе (что, по-видимому, оказывает квадратичное влияние на сложность). Scikit поддерживает это с BaggingClassifier обертки BaggingClassifier . Это должно дать вам аналогичную (если не лучшую) точность по сравнению с одним классификатором с гораздо меньшим временем обучения. Обучение отдельных классификаторов также можно запускать параллельно, используя параметр n_jobs .

    В качестве альтернативы, я бы также рассмотрел использование классификатора Random Forest – он поддерживает классификацию нескольких классов изначально, он быстрый и дает довольно хорошие оценки вероятности, когда min_samples_leaf устанавливается соответствующим образом.

    Я провел быстрые тесты по набору данных диафрагмы, взорванному 100 раз с помощью ансамбля из 10 SVC, каждый из которых тренировался на 10% данных. Это более чем в 10 раз быстрее, чем один классификатор. Это номера, которые я получил на своем ноутбуке:

    Одноместный SVC: 45 секунд

    Ансамбль SVC: 3s

    Случайный лесной классификатор: 0.5s

    Ниже приведен код, который я использовал для создания чисел:

     import time import numpy as np from sklearn.ensemble import BaggingClassifier, RandomForestClassifier from sklearn import datasets from sklearn.multiclass import OneVsRestClassifier from sklearn.svm import SVC iris = datasets.load_iris() X, y = iris.data, iris.target X = np.repeat(X, 100, axis=0) y = np.repeat(y, 100, axis=0) start = time.time() clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto')) clf.fit(X, y) end = time.time() print "Single SVC", end - start, clf.score(X,y) proba = clf.predict_proba(X) n_estimators = 10 start = time.time() clf = OneVsRestClassifier(BaggingClassifier(SVC(kernel='linear', probability=True, class_weight='auto'), max_samples=1.0 / n_estimators, n_estimators=n_estimators)) clf.fit(X, y) end = time.time() print "Bagging SVC", end - start, clf.score(X,y) proba = clf.predict_proba(X) start = time.time() clf = RandomForestClassifier(min_samples_leaf=20) clf.fit(X, y) end = time.time() print "Random Forest", end - start, clf.score(X,y) proba = clf.predict_proba(X) 

    Если вы хотите, чтобы каждая запись использовалась только один раз для обучения в BaggingClassifier , вы можете установить для параметра bootstrap значение False.

    Классификаторы SVM не масштабируются так легко. Из документов, о сложности sklearn.svm.SVC .

    Сложная временная сложность более чем квадратична с количеством выборок, что затрудняет масштабирование до набора данных с более чем несколькими 10000 образцами.

    В scikit-learn у вас есть svm.linearSVC который может масштабироваться лучше. По-видимому, он сможет обрабатывать ваши данные.

    В качестве альтернативы вы можете просто пойти с другим классификатором. Если вы хотите оценки вероятности, я бы предложил логистическую регрессию. Логистическая регрессия также имеет то преимущество, что не нужна калибровка вероятности для вывода «правильных» вероятностей.

    Редактировать:

    Я не знал о сложности linearSVC , наконец, нашел информацию в руководстве пользователя :

    Также обратите внимание, что для линейного случая алгоритм, используемый в LinearSVC с помощью liblinear-реализации, намного эффективнее, чем его SVC-совместимость на основе libsvm и может масштабироваться почти линейно до миллионов образцов и / или функций.

    Чтобы получить вероятность из linearSVC проверьте эту ссылку . Это всего лишь пара ссылок от руководства по калибровке вероятности I, связанного выше, и содержит способ оценки вероятностей. А именно:

      prob_pos = clf.decision_function(X_test) prob_pos = (prob_pos - prob_pos.min()) / (prob_pos.max() - prob_pos.min()) 

    Обратите внимание, что оценки, вероятно, будут плохими без калибровки, как показано в ссылке.

    Он был кратко упомянут в верхнем ответе; вот код: Самый быстрый способ сделать это – через параметр n_jobs : заменить строку

     clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto')) 

    с

     clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto'), n_jobs=-1) 

    Это будет использовать все доступные процессоры на вашем компьютере, при этом все еще выполняйте те же вычисления, что и раньше.

    Вы можете использовать модуль kernel_approximation для масштабирования SVM до большого количества таких образцов.

    Python - лучший язык программирования в мире.