File size: 1,523 Bytes
36131f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import numpy as np
from artwork_bandit.bandit.linucb import LinUCBArm, LinUCBBandit
from artwork_bandit.bandit.thompson import ThompsonBandit

def test_linucb_score_and_update():
    d=10
    arm = LinUCBArm(d=d, alpha=0.5)
    ctx = np.ones(d)
    s = arm.score(ctx)
    assert isinstance(s, float)
    A0 = arm.A.copy()
    b0 = arm.b.copy()
    arm.update(ctx, 1.0)
    assert not np.allclose(arm.A, A0)
    assert not np.allclose(arm.b, b0)

def test_linucb_bandit_select():
    arms = ['a','b','c']
    d=5
    bandit = LinUCBBandit(arms, d=d, alpha=1.0)
    contexts = {a: np.ones(d) * i for i,a in enumerate(arms, start=1)}
    chosen = bandit.select(contexts)
    assert chosen in arms

def test_linucb_exploit_after_updates():
    arms = ['a','b','c']
    d=5
    bandit = LinUCBBandit(arms, d=d, alpha=0.1)
    ctx = np.ones(d)
    # reward arm 'b' heavily
    for _ in range(100):
        bandit.update('b', ctx, 1.0)
    counts = {a:0 for a in arms}
    for _ in range(100):
        chosen = bandit.select({a:ctx for a in arms})
        counts[chosen]+=1
    assert counts['b'] > 80

def test_thompson_select():
    arms = [f'a{i}' for i in range(4)]
    t = ThompsonBandit(arms)
    chosen = t.select(arms)
    assert chosen in arms

def test_linucb_serialization_roundtrip():
    d=3
    arm = LinUCBArm(d=d, alpha=1.0)
    arm.update(np.ones(d), 1.0)
    data = arm.to_dict()
    arm2 = LinUCBArm.from_dict('x', d, data, alpha=1.0)
    assert np.allclose(arm.A, arm2.A)
    assert np.allclose(arm.b, arm2.b)