Comment effectuer une régression logistique en utilisant vowpal wabbit sur un ensemble de données très déséquilibré
j'essaie d'utiliser vowpal wabbit pour la régression logistique. Je ne suis pas sûr si c'est la bonne syntaxe pour le faire
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
Voici un extrait de mon train de données
-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
Voici un extrait de mes données de test
-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
cependant, si je regarde les résultats, les prédictions sont toutes -1 et les scores bruts sont tous 0s. J'ai environ 200 000 exemples, dont 100 sont +1 et les autres -1. Pour gérer cette données déséquilibrées, j'ai donné le positif exemples poids de 200 000 / 100 et le poids d'exemple négatif de 200 000 / (200000-100). Est-ce parce que mes données sont comme très déséquilibrées même si j'ajuste les poids que cela se produit?
Je m'attendais à la sortie de (P(y|x)) dans le fichier de score brut. Mais je reçois tous les zéros. J'ai juste besoin des sorties de probabilité. Toutes les suggestions de ce qu'il se passe, les gars?
2 réponses
il est important de savoir quelle est la fonction de coût final (perte) prévue: Perte logistique, 0/1 perte (c.-à-d. précision), score F1, surface sous la courbe RO, autre chose?
voici un code Bash pour une partie de la réponse d'arielf. Notez que nous devrions d'abord supprimer les tentatives étranges de pondération de l'importance du train.txt (je veux dire le ": 1.00038" et ":2601.25" dans le question.)
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
une question semblable a été affichée sur la liste de diffusion vw. Je vais essayer de résumer les principaux points dans toutes les réponses ici, pour le bénéfice des futurs utilisateurs.
formation déséquilibrée ensembles de pratiques exemplaires:
votre ensemble d'entraînement est très déséquilibré (200 000 à 100). Cela signifie que seulement 0.0005 (0.05%) des exemples ont une étiquette de 1
. En prédisant toujours -1
, le classificateur atteint d'une précision remarquable, de 99.95%. Dans d'autres termes, si le coût d'un faux-positifs est égal au coût d'un faux négatif, c'est effectivement une excellente classificateur. Si vous cherchez un résultat à pondération égale, vous devez faire deux choses:
- Pesez vos exemples de sorte que le petit groupe aurait un poids égal à la plus grande
- réorganiser/mélanger les exemples de façon à ce que les éléments positifs et négatifs soient mélangés.
le deuxième point est particulièrement important dans l'apprentissage en ligne où l'apprentissage de taux décroît avec le temps. Il s'ensuit que l'ordre idéal, en supposant que vous êtes autorisé à réordonner librement (par exemple, pas de dépendance temporelle entre les exemples), pour l'apprentissage en ligne est un mélange tout à fait uniforme (1, -1, 1, -1, ...)
notez aussi que la syntaxe pour l'exemple-poids (en supposant un rapport de prévalence de 2000:1) doit être quelque chose comme ceci:
1 2000 optional-tag| features ...
-1 1 optional-tag| features ...
Et comme mentionné ci-dessus, la décomposition de l' 2000
pondéré exemple n'avoir qu'un poids 1
tout en le répétant 2000 fois et en l'entrelaçant avec les 2000 exemples communs (ceux avec le -1
étiquette) à la place:
1 | ...
-1 | ...
1 | ... # repeated, very rare, example
-1 | ...
1 | ... # repeated, very rare, example
devrait conduire à des résultats encore meilleurs en termes de convergence plus douce et de perte de formation plus faible. * Mise en garde: en règle générale, le fait de répéter un exemple trop souvent, comme dans le cas d'un ratio de 1:2000, est très probablement pour conduire à un ajustement excessif de la classe répétée. Vous pourriez vouloir contrer cela en apprenant plus lentement (en utilisant --learning_rate ...
) et / ou rééchantillonnage aléatoire: (en utilisant --bootstrap ...
)
envisagez de réduire l'échantillon de la classe dominante
pour éviter l'ajustement excessif: plutôt que de surcharger la classe rare d'ici 2000x, envisager d'aller dans le sens opposé et "poids insuffisant" la classe plus commune en rejetant la plupart de ses exemples. Bien que cela puisse sembler surprenant (comment jeter des données parfaitement bonnes peut-il être bénéfique?) il évitera l'ajustement excessif de la classe répétée comme décrit ci-dessus, et peut effectivement conduire à une meilleure généralisation. Selon le cas, et les coûts d'une fausse classification, le facteur d'échantillonnage optimal peut varier (il n'est pas nécessairement 1/2000 dans ce cas, mais peut être n'importe où entre 1 et 1/2000). Une autre approche nécessitant une certaine programmation est d'utiliser l'apprentissage actif: former sur une très petite partie des données, puis continuer à prédire la classe sans apprendre (-t
ou zéro poids); si la classe est la prévalence de la classe et en ligne le classificateur est très certain du résultat (la valeur prédite est extrême, ou très proche de -1
lors de l'utilisation de --link glf1
), jetez l'exemple redondant. OIE: concentrez votre formation sur les cas limites seulement.
--binary
(dépend de votre besoin)
--binary
sorties le signe de la prédiction (et calcule la perte progressive en conséquence). Si vous voulez probabilités, ne utiliser --binary
et pipe vw
sortie de prédiction en utl/logistic
(dans l'arbre). utl/logistic
va cartographier la prédiction brute en probabilités signées dans la gamme [-1, +1]
.
Un effet de --binary
est une perte trompeuse (optimiste). Clamper les prédictions à {-1, +1}, peut considérablement augmenter le apparent précision car chaque prédiction correcte a une perte de 0,0. Cela pourrait être trompeur que tout en ajoutant --binary
souvent donne l'impression que le modèle est beaucoup plus précis (parfois parfaitement précis) que sans --binary
.
Mise À Jour (Septembre 2014): une nouvelle option a été récemment ajoutée à vw
:--link logistic
qui met en oeuvre [0,1]
cartographie, tout en prédisant, à l'intérieur de vw
. De même, --link glf1
met en oeuvre le plus souvent nécessaire [-1, 1]
cartographie. mnémotechnique:glf1
signifie " fonction logistique généralisée avec un [-1, 1]
gamme"
Aller simple --l1
et --l2
C'est une erreur courante d'utiliser la haute --l1
et/ou --l2
valeurs. Les valeurs sont utilisées directement par exemple, plutôt que de dire, par rapport à 1.0
. Plus précisément: dans vw
:l1
et l2
s'appliquent directement à la somme des gradients (ou la "norme") dans chaque exemple. Essayez d'utiliser des valeurs beaucoup plus basses, comme --l1 1e-8
. utl/vw-hypersearch
peut vous aider à trouver les valeurs optimales des différents hyper-paramètres.
attention avec plusieurs passes
C'est une erreur commune à utiliser --passes 20
afin de minimiser les erreurs de formation. Rappelez-vous que l'objectif est de minimiser l'erreur de généralisation, plutôt que la formation d'erreur. Même avec l'ajout cool de holdout
(merci à Zhen Qin) où vw
automatiquement en début termine quand l'erreur s'arrête de descendre sur automatiquement tenu des données (par défaut, tous les 10 exemple est tenue de sortie), les laissez-passer multiples finiront par commencer à SUR-ajuster les données tenues à jour (le principe "pas de repas gratuit").