Как выполнить логистическую регрессию с использованием vowpal wabbit на очень несбалансированном наборе данных

Я пытаюсь использовать vowpal wabbit для логистической регрессии. Я не уверен, что это правильный синтаксис для этого.

For training, I do

 ./vw -d ~/Desktop/new_data.txt --passes 20 --binary --cache_file cache.txt -f lr.vw --loss_function logistic --l1 0.05

For testing I do 
./vw -d ~/libsvm-3.18_test/matlab/new_data_test.txt --binary -t -i lr.vw -p predictions.txt -r raw_score.txt

Вот фрагмент из моих данных поезда

-1:1.00038 | 110:0.30103 262:0.90309 689:1.20412 1103:0.477121 1286:1.5563 2663:0.30103 2667:0.30103 2715:4.63112 3012:0.30103 3113:8.38411 3119:4.62325 3382:1.07918 3666:1.20412 3728:5.14959 4029:0.30103 4596:0.30103

1:2601.25 | 32:2.03342 135:3.77379 146:3.19535 284:2.5563 408:0.30103 542:3.80618 669:1.07918 689:2.25527 880:0.30103 915:1.98227 1169:5.35371 1270:0.90309 1425:0.30103 1621:0.30103 1682:0.30103 1736:3.98227 1770:0.60206 1861:4.34341 1900:3.43136 1905:7.54141 1991:5.33791 2437:0.954243 2532:2.68664 3370:2.90309 3497:0.30103 3546:0.30103 3733:0.30103 3963:0.90309 4152:3.23754 4205:1.68124 4228:0.90309 4257:1.07918 4456:0.954243 4483:0.30103 4766:0.30103

Вот фрагмент из моих тестовых данных

-1 | 110:0.90309 146:1.64345 543:0.30103 689:0.30103 1103:0.477121 1203:0.30103 1286:2.82737 1892:0.30103 2271:0.30103 2715:4.30449 3012:0.30103 3113:7.99039 3119:4.08814 3382:1.68124 3666:0.60206 3728:5.154 3960:0.778151 4309:0.30103 4596:0.30103 4648:0.477121

Однако, если я посмотрю на результаты, прогнозы будут равны -1, а сырые оценки - все 0. У меня около 200 000 примеров, из которых 100 составляют +1, а остальные -1. Чтобы справиться с этими несбалансированными данными, я дал вес положительных примеров 200 000/100 и отрицательный вес примера 200 000/(200000-100). Это потому, что мои данные похожи на действительно сильно неуравновешенные, хотя я настраиваю весы, которые это происходит?

Я ожидал выход (P (y | x)) в исходном файле оценки. Но я получаю все нули. Мне просто нужны вероятностные выходы. Любые предложения о том, что происходит с парнями?

Ответы

Ответ 1

Подводя итог подробному ответу arielf.

  • Важно знать, какова предполагаемая конечная стоимость (потеря): Потеря логистики, потеря 0/1 (то есть точность), оценка F1, Area Under RO Curve, что-то еще?

  • Вот код Bash для части ответа arielf. Обратите внимание, что мы должны сначала удалить странные попытки взвешивания важности из train.txt(я имею в виду ": 1.00038" и ": 2601.25" в вопросе).

    A. Prepare the training data
    grep '^-1' train.txt | shuf > neg.txt
    grep '^1' train.txt | shuf > p.txt
    for i in `seq 2000`; do cat p.txt; done > pos.txt
    paste -d '\n' neg.txt pos.txt > newtrain.txt
    
    B. Train model.vw
    # Note that passes=1 is the default.
    # With one pass, holdout_off is the default.
    `vw -d newtrain.txt --loss_function=logistic -f model.vw`
    #average loss = 0.0953586
    
    C. Compute test loss using vw
    `vw -d test.txt -t -i model.vw --loss_function=logistic -r   
    raw_predictions.txt`
    #average loss = 0.0649306
    
    D. Compute AUROC using http://osmot.cs.cornell.edu/kddcup/software.html
    cut -d ' ' -f 1 test.txt | sed -e 's/^-1/0/' > gold.txt
    $VW_HOME/utl/logistic -0 raw_predictions.txt > probabilities.txt
    perf -ROC -files gold.txt probabilities.txt 
    #ROC    0.83484
    perf -ROC -plot roc -files gold.txt probabilities.txt | head -n -2 > graph
    echo 'plot "graph"' | gnuplot -persist
    

Ответ 2

Аналогичный вопрос был отправлен в списке рассылки vw. Я попытаюсь обобщить основные моменты во всех ответах здесь для будущих пользователей.

Неуравновешенный тренинг устанавливает лучшие практики:

Ваш тренировочный комплект очень неуравновешен (от 200 000 до 100). Это означает, что только 0,0005 (0,05%) примеров имеют метку 1. Всегда прогнозируя -1, классификатор достигает замечательной точности 99,95%. Другими словами, если стоимость ложноположительного равна стоимости ложноотрицательного, это на самом деле отличный классификатор. Если вы ищете равноценный результат, вам нужно сделать две вещи:

  • Повторите свои примеры, чтобы меньшая группа имела равный вес для большего.
  • Переупорядочить/перетасовать примеры, чтобы помехи и негативы были перемешаны.

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

Также обратите внимание, что синтаксис для примера-весов (при условии коэффициента распространенности 2000: 1) должен быть примерно следующим:

    1   2000  optional-tag| features ...
    -1  1     optional-tag| features ...

И, как упоминалось выше, разбив один взвешенный пример 2000, чтобы иметь только вес 1, повторяя его 2000 раз и чередуя его с общими примерами 2000 (тегами с меткой -1):

   1  | ...
   -1 | ...
   1  | ...  # repeated, very rare, example
   -1 | ...
   1  | ...  # repeated, very rare, example

Должно привести к еще большему результату с точки зрения более плавной конвергенции и снижения потерь при тренировках. * Предостережение: как правило, повторение любого примера слишком сильно, как в случае отношения 1: 2000, очень вероятно, чтобы привести к переопределению повторяющегося класса. Возможно, вам захочется противопоставить это медленным обучением (используя --learning_rate ...) и/или рандомизированную передискретизацию: (используя --bootstrap ...)

Рассмотрим понижающую дискретизацию преобладающего класса

Чтобы избежать чрезмерной установки: вместо того, чтобы перегружать редкий класс 2000x, рассмотрите обратный путь и "недостаточный вес" более общий класс, исключив большинство его примеров. Хотя это может показаться удивительным (как можно отбросить отличные данные, полезно?), Это позволит избежать переопределения повторяющегося класса, как описано выше, и может фактически привести к лучшему обобщению. В зависимости от случая и стоимости ложной классификации оптимальный коэффициент выборки может варьироваться (это не обязательно 1/2000 в этом случае, но может быть где-то между 1 и 1/2000). Другой подход, требующий некоторого программирования, - использовать активное обучение: тренироваться на очень небольшой части данных, а затем продолжать прогнозировать класс без обучения (-t или нулевой вес); если класс является преобладающим классом, и онлайновый классификатор очень уверен в результатах (предсказанное значение является экстремальным или очень близко к -1 при использовании --link glf1), отбросьте избыточный пример. IOW: сосредоточьте свое обучение только на граничных случаях.


Использование --binary (зависит от ваших потребностей)

--binary выводит знак прогноза (и соответственно вычисляет прогрессивные потери). Если вам нужны вероятности, не используйте вывод --binary и pipe vw для прогнозирования в utl/logistic (в исходном дереве). utl/logistic отобразит необработанное предсказание в подписанные вероятности в диапазоне [-1, +1].

Один эффект --binary - вводить в заблуждение (оптимистичную) потерю. Предположения о зажимах {-1, +1} могут значительно увеличить кажущуюся точность, поскольку каждое правильное предсказание имеет потерю 0,0. Это может ввести в заблуждение, так как просто добавление --binary часто заставляет его выглядеть так, как если бы модель была намного более точной (иногда совершенно точной), чем без --binary.

Обновление (сентябрь 2014 г.): недавно добавлена ​​новая опция vw: --link logistic, которая реализует отображение [0,1] при прогнозировании внутри vw. Аналогично, --link glf1 реализует наиболее часто используемое отображение [-1, 1]. Мнемоника: glf1 означает "обобщенная логистическая функция с диапазоном [-1, 1]"

Легко переходите к --l1 и --l2

Общепринятой ошибкой является использование высоких значений --l1 и/или --l2. Значения используются непосредственно для примера, а не, скажем, относительно 1.0. Точнее: в vw: l1 и l2 применимы непосредственно к сумме градиентов (или "нормы" ) в каждом примере. Попытайтесь использовать гораздо более низкие значения, например --l1 1e-8. utl/vw-hypersearch может помочь вам найти оптимальные значения различных гиперпараметров.

Будьте осторожны с несколькими проходами

Общепринятой ошибкой является использование --passes 20, чтобы свести к минимуму ошибку обучения. Помните, что целью является минимизация ошибки обобщения, а не ошибки обучения. Даже при прохладном добавлении holdout (благодаря Zhen Qin), где vw автоматически рано заканчивается, когда ошибка перестает падать на автоматически выставляемые данные (по умолчанию каждый 10-й пример выставляется), многократные проходы будут в конечном итоге начинают переполнять запатентованные данные (принцип "без бесплатного обеда" ).