Несколько подробностей реализации машины опорных векторов (SVM) - PullRequest
26 голосов
/ 10 августа 2010

В конкретном приложении я нуждался в машинном обучении (я знаю, что я изучал в моем курсе бакалавриата).Я использовал машины опорных векторов и решил проблему.Работает нормально.

Теперь мне нужно улучшить систему.Проблемы здесь:

  1. Я получаю дополнительные примеры тренировок каждую неделю.Прямо сейчас система начинает обучение заново с обновленными примерами (старые примеры + новые примеры).Я хочу сделать это инкрементным обучением.Использование предыдущих знаний (вместо предыдущих примеров) с новыми примерами для получения новой модели (знания)

  2. Правильно, мои учебные примеры состоят из 3 классов.Итак, каждый пример обучения вписывается в один из этих 3 классов.Я хочу функционал класса "Неизвестно".Все, что не соответствует этим 3 классам, должно быть помечено как «неизвестное».Но я не могу трактовать «Неизвестный» как новый класс и приводить примеры для этого тоже.

  3. Предполагается, что «неизвестный» класс реализован.Когда класс «неизвестен», пользователь приложения вводит то, что, по его мнению, может быть классом.Теперь мне нужно включить пользовательский ввод в обучение.Я понятия не имею, как это сделать.Будет ли какая-то разница, если пользователь введет новый класс (т. Е. Класс, которого еще нет в обучающем наборе)?

Нужно ли выбирать новый алгоритм или вектор поддержки?Машины могут сделать это?

PS: я использую реализацию libsvm для SVM.

Ответы [ 4 ]

8 голосов
/ 10 августа 2010

Я только что написал свой ответ, используя ту же организацию, что и ваш вопрос (1., 2., 3).

  1. Могут ли SVM сделать это, т.е. инкрементное обучение? Многослойные персептроны, конечно, могут - потому что последующие обучающие экземпляры не влияют на базовую сетевую архитектуру, они просто вызовут корректировку значений весовых матриц. Но SVMs? Мне кажется, что (теоретически) один дополнительный обучающий экземпляр может изменить выбор векторов поддержки. Но опять же, я не знаю.

  2. Я думаю, что вы можете решить эту проблему довольно легко, настроив LIBSVM как один против многих, т. Е. Как одноклассный классификатор . SVM являются одноклассными классификаторами; Применение SVM для мультикласса означает, что он был закодирован для выполнения нескольких пошаговых классификаций «один против многих», но опять-таки алгоритм обучается (и тестируется) по одному классу за раз. Если вы сделаете это, то, что останется после пошагового выполнения для набора тестов, будет «неизвестно» - другими словами, какие бы данные не классифицировались после выполнения нескольких последовательных классификаций одного класса, по определению это «неизвестно». ' учебный класс.

  3. Почему бы не сделать так, чтобы пользователь угадал особенность (т.е. просто другую зависимую переменную)? Единственный другой вариант - сделать его меткой класса, а вы этого не хотите. Так, например, вы бы добавили столбец к своей матрице данных «угадывание пользовательского класса» и просто заполнили его некоторым значением, которое, скорее всего, не окажет влияния на те точки данных, которые не входят в категорию «неизвестно» и, следовательно, для которых пользователь не будет предлагать предположение - это значение может быть «0» или «1», но на самом деле это зависит от того, как ваши данные масштабируются и нормализуются).

5 голосов
/ 11 августа 2010

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

Несколько месяцев назад я также исследовал онлайн или инкрементные алгоритмы SVM. К сожалению, текущее состояние реализаций довольно скудное. Все, что я нашел, это пример Matlab , OnlineSVR (дипломный проект, реализующий только поддержку регрессии) и SVMHeavy (только поддержка двоичного класса).

Я не использовал ни одного из них лично. Все они, кажется, находятся на стадии «исследовательской игрушки». Я даже не смог заставить SVMHeavy скомпилировать.

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

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

Например, если у вас есть атрибут с именем «color», который имеет минимальное значение 4 и максимальное значение 123, вы можете добавить их в свой тренировочный набор

[({'color':3},'unknown'),({'color':125},'unknown')]

, чтобы дать вашему SVM представление о том, что означает "неизвестный" цвет.

3 голосов
/ 10 августа 2010
  1. Существуют алгоритмы для постепенного обучения SVM, но я не думаю, что libSVM реализует это. Я думаю, вы должны подумать, действительно ли вам нужна эта функция. Я не вижу проблем с вашим текущим подходом, если процесс обучения не слишком медленный. Если это так, можете ли вы переучиваться партиями (т.е. после каждых 100 новых примеров)?
  2. Вы можете получить libSVM для получения вероятностей членства в классе. Я думаю, что это можно сделать для мультиклассовой классификации, но я не совсем уверен в этом. Вам нужно будет определить какой-то порог, при котором классификация будет недостаточно точной, и затем вывести «Неизвестно». Я полагаю, что что-то вроде установки порога разницы между наиболее вероятным и вторым наиболее вероятным классом позволит достичь этого.
  3. Я думаю, что libSVM масштабируется до любого количества новых классов. Однако точность вашей модели может пострадать от добавления новых классов.
2 голосов
/ 06 февраля 2013

Несмотря на то, что этот вопрос, вероятно, устарел, я чувствую себя обязанным поделиться некоторыми дополнительными мыслями.

  1. Поскольку на ваш первый вопрос ответили другие (готовых к производству продуктов нет)SVM, который реализует пошаговое обучение, хотя это и возможно), я его пропущу.;)

  2. Добавление 'Unknown' в качестве класса не очень хорошая идея.В зависимости от его использования, причины разные.

    • Если вы используете класс «Неизвестно» в качестве тега для «этот экземпляр не был классифицирован, но принадлежит к одному из известных классов», то у вашего SVM большие проблемы,Причина в том, что libsvm создает несколько двоичных классификаторов и объединяет их.Поэтому, если у вас есть три класса - скажем, A, B и C - SVM создает первый двоичный классификатор, разбивая обучающие примеры на «классифицированные как A» и «любой другой класс».Последний, очевидно, будет содержать все примеры из класса «Неизвестно».При попытке построить гиперплоскость примеры в «Неизвестно» (которые действительно принадлежат классу «А»), вероятно, приведут к тому, что SVM создаст гиперплоскость с очень небольшим запасом, и плохо распознают будущие экземпляры А, т.е. это производительность обобщениябудет уменьшаться.Это связано с тем, что SVM будет пытаться построить гиперплоскость, которая разделяет большинство экземпляров A (официально обозначенных как «A») на одной стороне гиперплоскости, а некоторые экземпляры (официально обозначенные как «Неизвестно») - надругая сторона.

    • Другая проблема возникает, если вы используете класс «Неизвестно» для хранения всех примеров, класс которых еще не известен SVM.Например, SVM знает классы A, B и C, но вы недавно получили пример данных для двух новых классов D и E. Поскольку эти примеры не классифицированы, а новые классы не известны SVM, вы можете временно сохранитьих в «Неизвестном».В этом случае класс «Неизвестно» может вызвать проблемы, так как он может содержать примеры с огромным разбросом значений его функций.Это очень затруднит создание хороших разделяющих гиперплоскостей, и, следовательно, полученный классификатор будет плохо распознавать новые экземпляры D или E как «Неизвестные».Возможно, будет затруднена классификация новых экземпляров, принадлежащих A, B или C.

    Подводя итог: Введение класса «Неизвестно», который содержит примеры известных классов или примерынесколько новых классов приведут к плохому классификатору.Я думаю, что лучше всего игнорировать все несекретные примеры при обучении классификатора.

  3. Я бы порекомендовал вам решить эту проблему вне алгоритма классификации.Меня попросили об этой функции и я реализовал одну веб-страницу, которая показывает изображение рассматриваемого объекта и кнопку для каждого известного класса.Если рассматриваемый объект принадлежит классу, который еще не известен, пользователь может заполнить другую форму, чтобы добавить новый класс.Если он вернется на страницу классификации, волшебным образом появится еще одна кнопка для этого класса.После классификации экземпляров их можно использовать для обучения классификатора.(Я использовал базу данных для хранения известных классов и ссылки, какой пример принадлежит какому классу. Я реализовал функцию экспорта для обеспечения готовности данных к SVM.)

...