VowpalWabbit / vowpal_wabbit

Vowpal Wabbit is a machine learning system which pushes the frontier of machine learning with techniques such as online, hashing, allreduce, reductions, learning2search, active, and interactive learning.
https://vowpalwabbit.org
Other
8.49k stars 1.93k forks source link

--invert_hash for cb_explore_adf with interactions displays as --readable_model output #2674

Closed r-angi closed 3 years ago

r-angi commented 3 years ago

Problem Description

I have trained an online contextual bandit using --save_resume. I was attempting to debug interaction coefficients, and unfortunately --invert_hash for cb_explore_adf with interactions displays as the --readable_model output and does not include the string names for features. I've looked through the source code, but could not determine if this is intentional or a bug. If it is intentional, the documentation on --invert_hash might need to be updated.

It may be due to the --save_resume argument, but I have no evidence to back this up.

To Reproduce

train.dat (a 2 example training set)

shared |F browser=a time=evening
|A one two three
0:1:0.5 |A two three four
|A four five six

shared |F browser=a time=morning
|A one two three
|A two three four
0:1:0.5 |A four five six

Running this command provides me with a binary model output:

vw -d train.dat --cb_adf --cb_explore_adf --cb_type dr --epsilon 0.1 --interactions AF --save_resume -f model.binary

Expected behavior

Running the following command should produce a model output with feature names as shown in the --invert_hash documentation.

vw -d train.dat -i model.binary --invert_hash model.humanreadable --save_resume -k

The same thing happens with -k present or not, vw also mentions using no cache in output. The same thing happens with -t present or not.

Observed Behavior

Output in model.humanreadable is the same as if I replaced --invert_hash with --readable_model:

Version 8.8.1
Id 
Min label:0
Max label:2
bits:18
lda:0
0 ngram:
0 skip:
options: --cb_adf --cb_explore_adf --cb_type dr --csoaa_ldf multiline --csoaa_rank --epsilon 0.100000001490116 --interactions AF
Checksum: 2638192375
event_sum 0
action_sum 0
:1
initial_t 0
norm normalizer 108
t 4
sum_loss 2.53333
sum_loss_since_last_dump 0
dump_interval 4
min_label 0
max_label 2
weighted_labeled_examples 2
weighted_labels 0
weighted_unlabeled_examples 0
example_number 2
total_features 30
total_weight 9
sd::oec.weighted_labeled_examples 2
current_pass 1
4430:0.0965485 16 1
4431:0.0761336 8 1
49576:0.0953729 16.06 1
49577:0.0761336 8 1
69842:0.147383 24.6787 1
69843:0.112858 11.8694 1
89726:-0.019228 0.0600146 1
99504:0.0709793 8.64246 1
99505:0.0643199 3.86938 1
103886:0.0905473 8.58244 1
... (cut off the rest for brevity)

Additional Context

One thing I did notice is if I use the -a audit parameter. I do get unhashed string names back. In most places in the code where I saw all.hash_inv I saw it in conjunction with the all.audit boolean which makes me wonder why audit would work correctly but invert hash does not.

Here is the terminal output using the -a parameter

vw -d train.dat -i model.binary --invert_hash model.humanreadable --save_resume -a
creating features for following interactions: AF
Num weight bits = 18
learning rate = 0.5
initial_t = 0
power_t = 0.5
using no cache
Reading datafile = train.dat
num sources = 1
average  since         example        example  current  current  current
loss     last          counter         weight    label  predict features
0
    A^one:112163:1:0@0  A^two:258513:1:0@0  A^three:137909:1:0@0    Constant:232121:1:0@0   F^browser=a:230627:1:0@0    F^time=evening:113471:1:0@0 A^one*F^browser=a:144229:1:0@0  A^one*F^time=evening:3257:1:0@0 A^two*F^browser=a:142995:1:0@0  A^two*F^time=evening:4431:1:0@0 A^three*F^browser=a:232895:1:0@0    A^three*F^time=evening:111203:1:0@0
0
    A^two:258513:1:0@0  A^three:137909:1:0@0    A^four:69843:1:0@0  Constant:232121:1:0@0   F^browser=a:230627:1:0@0    F^time=evening:113471:1:0@0 A^two*F^browser=a:142995:1:0@0  A^two*F^time=evening:4431:1:0@0 A^three*F^browser=a:232895:1:0@0    A^three*F^time=evening:111203:1:0@0 A^four*F^browser=a:196213:1:0@0 A^four*F^time=evening:49577:1:0@0
0.456802
    A^four:69843:1:0.0761336@8  Constant:232121:1:0.0761336@8   F^browser=a:230627:1:0.0761336@8    F^time=evening:113471:1:0.0761336@8 A^four*F^browser=a:196213:1:0.0761336@8 A^four*F^time=evening:49577:1:0.0761336@8   A^five:249281:1:0@0 A^six:260519:1:0@0  A^five*F^browser=a:221603:1:0@0 A^five*F^time=evening:89727:1:0@0   A^six*F^browser=a:99505:1:0@0   A^six*F^time=evening:244589:1:0@0
0
    A^one:112162:1:0@0  A^two:258512:1:0@0  A^three:137908:1:0@0    Constant:232120:1:0@0   F^browser=a:230626:1:0@0    F^time=evening:113470:1:0@0 A^one*F^browser=a:144228:1:0@0  A^one*F^time=evening:3256:1:0@0 A^two*F^browser=a:142994:1:0@0  A^two*F^time=evening:4430:1:0@0 A^three*F^browser=a:232894:1:0@0    A^three*F^time=evening:111202:1:0@0
0
... (cut for brevity)

finished run
number of examples = 2
weighted example sum = 2.000000
weighted label sum = 0.000000
average loss = 1.266667
total feature number = 30

Environment

VW version 8.8.1 on OSX using cmd line interface.

ataymano commented 3 years ago

Yes, it is caused by --save_resume.

Other way to reproduce: vw --cb_adf -d train.dat --invert_hash model.readable -f model.bin => model.readable has feature names vw --cb_adf -d train.dat --invert_hash model.readable -f model.bin --save_resume => model.readable is without feature names.

Have to be investigated.

r-angi commented 3 years ago

I'm not an expert on this code base, but I tried to take a stab at figuring out some link between save_resume and invert_hash. My initial thought is there could be something here on L115 that is causing the size of this feature space to be 0? I could be completely off though if the readable model isn't actually created from this audit_regressor.cc file and the inverting of the hash values to strings isn't added to the strings in audit_regressor_interaction().

features& fs = ec.feature_space[(size_t)*i]

https://github.com/VowpalWabbit/vowpal_wabbit/blob/master/vowpalwabbit/audit_regressor.cc#L115-L126