Подтвердить что ты не робот

Несколько деталей реализации для машины поддержки-вектора (SVM)

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

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

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

  • В моих учебных примерах есть 3 класса. Таким образом, каждый пример обучения помещается в один из этих трех классов. Я хочу функциональность класса "Неизвестный". Все, что не соответствует этим 3 классам, должно быть помечено как "неизвестное". Но я не могу рассматривать "Unknown" как новый класс и приводить примеры для этого тоже.

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

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

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

Например, если у вас есть атрибут, называемый "цвет", который имеет минимальное значение 4 и максимальное значение 123, вы можете добавить их в свой обучающий набор

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

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

Ответ 3

  • Существуют алгоритмы для постепенного обучения SVM, но я не думаю, что libSVM реализует это. Я думаю, вам стоит подумать, нужна ли вам эта функция. Я не вижу проблем с вашим текущим подходом, если процесс обучения не слишком медленный. Если да, можете ли вы переучиваться партиями (т.е. После каждых 100 новых примеров)?
  • Вы можете получить libSVM для создания вероятностей членства в классе. Я думаю, что это можно сделать для классификации многоклассов, но я не совсем уверен в этом. Вам нужно будет решить какой-то порог, при котором классификация недостаточно достоверна, а затем вывести "Неизвестно". Я полагаю, что что-то вроде установки порога на разницу между наиболее вероятным и вторым, наиболее вероятным классом, достигнет этого.
  • Я думаю, что libSVM масштабируется до любого количества новых классов. Однако точность вашей модели может страдать, добавляя новые классы.

Ответ 4

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

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

  • Добавление "Неизвестно" в качестве класса - не очень хорошая идея. В зависимости от использования, причины разные.

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

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

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

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