2014-01-29 2 views
3

У меня есть модели большого размера SVC (~ 50Mb cPickles) для классификации текста, и я использую различные способы использования их в производственной среде. Классификация партий документов работает очень хорошо (около 1 тыс. Документов в минуту с использованием как predict, так и predict_proba). Однако прогноз на одном документе, другая история, как описано в комментарии к this question:Улучшение производительности предсказания SVC на отдельных образцах

Вы делаете прогнозы в пакетном режиме? Метод SVC.predict, к сожалению, несет много накладных расходов, потому что он должен восстановить структуру данных LibSVM, аналогичную той, которую подготовил алгоритм обучения, мелкой копии в векторах поддержки и преобразовать тестовые образцы в формат LibSVM, который может отличаться от форматов NumPy/SciPy. Поэтому прогнозирование на одном образце должно быть медленным. - larsmans

Я уже обслуживаю модель SVC как Flask веб-приложения, так что часть накладных расходов исчезла (unpickling), но времена предсказания для одиночных документов все еще находятся на высокой стороне (0.25s). Я просмотрел код в методах predict, но не могу понять, есть ли способ «предварительно разогревать» их, заранее перестраивая структуру данных LibSVM при запуске сервера ... любые идеи?

def predict(self, X): 
    """Perform classification on samples in X. 

    For an one-class model, +1 or -1 is returned. 

    Parameters 
    ---------- 
    X : {array-like, sparse matrix}, shape = [n_samples, n_features] 

    Returns 
    ------- 
    y_pred : array, shape = [n_samples] 
     Class labels for samples in X. 
    """ 
    y = super(BaseSVC, self).predict(X) 
    return self.classes_.take(y.astype(np.int)) 
+1

Не используйте 'SVC' для классификации текста, это не стоит. –

+0

Привет, я понимаю, что вы имеете в виду, но я должен был указать, что это многоклассовая классификация чувств (очень разные размеры классов). Пока я пытаюсь достичь максимальной точности. До сих пор SVC с ядрами RBF превосходил каждый другой классификатор, хотя и с небольшим отрывом (например, SVC 0.898, PassiveAggressiveClassifier 0.868, MultinomialNB 0.837). Однако SVC в значительной степени превосходит конкуренцию с наименьшими классами (например, F1 SVC 0.84, PAC 0.76, MNB 0.68). Если бы SVC был немного быстрее с одним документом, я бы не видел причин не использовать его с моими текущими данными. – emiguevara

ответ

3

Я вижу три возможных решения.

Пользовательский сервер

Это не вопрос «потепления» ничего вверх. Просто - libSVM - это библиотека C, и вам нужно упаковать/распаковать данные в правильный формат. Этот процесс более эффективен для всех матриц, чем для каждой строки отдельно. Единственный способ преодолеть это - написать более эффективную оболочку между вашим производством env и libSVM (вы можете написать сервер на основе libsvm, который будет использовать какую-то общую память с вашей службой). К сожалению, это проблема, которая может быть разрешена существующими реализациями.

Порции

Наивный подход как буферные запросов вариант (если это система «высокая производительность» с тысячами запросов, вы можете просто хранить их в N-элементных партий, и направить их на libSVM в таких пакеты).

Собственная классификация

Наконец - классификация с использованием SVM действительно простая задача. Вам не нужно libSVM для выполнения классификации. Только обучение - сложная проблема.После того, как вы получите все векторы поддержки (SV_i), ядро ​​(K), lagragian мультипликаторов (alpha_i) и свободный член (б), вы классифицируете с помощью:

cl(x) = sgn(SUM_i y_i alpha_i K(SV_i, x) + b) 

Вы можете закодировать эту операцию непосредственно в приложении , без необходимости актуальной упаковки/распаковать/отправить что-нибудь в libsvm. Это может ускорить процесс на порядок. Очевидно, что вероятность более сложна для извлечения, поскольку она требует скейлинга Платта, но это все еще возможно.

+0

Очень полезно, спасибо. Я думаю, что партии будут решением на данный момент, но я попробую классифицировать, как только я получу время :-) – emiguevara

1

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

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

+0

Конечно, вы не можете избежать обработки одного документа, который вы получите по запросу. Однако разница в производительности в зависимости от количества образцов настолько велика, что мне все еще интересно, можно ли что-то сделать заранее. Например, вызов как '' predict' и predict_proba' каждого документа: 100 докторов 5.6157s, 10 докторов 0.9705s, 2 документы 0.4969s, 1 DOC 0.4551s – emiguevara

+0

пеленального классификатор не является частью вопроса. – emiguevara

+0

'LinearSVC' - это просто оптимизированная версия' SVC', поэтому вы не меняете классификатор. http://stackoverflow.com/questions/11508788/whats-the-difference-between-libsvm-and-liblinear – mbatchkarov

Смежные вопросы