Skip to content

Commit

Permalink
Bugfixes in examples and tree params (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
bkleyn authored Mar 28, 2022
1 parent 329125d commit 646a398
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 23 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
MABWiser CHANGELOG
=====================

March, 28, 2022 2.4.1
-------------------------------------------------------------------------------
minor:
- Bug fixes in examples
- Validate tree parameters of TreeBandit to be compatible with sklearn.tree.DecisionTreeRegressor

March, 17, 2022 2.4.0
-------------------------------------------------------------------------------
major:
Expand Down
2 changes: 1 addition & 1 deletion examples/context_free_mab.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@

# Results
print("Randomized Popularity: ", prediction, " ", expectations)
assert(prediction == 2)
assert(prediction == 1)

###################################
# Softmax Learning Policy
Expand Down
2 changes: 1 addition & 1 deletion examples/customized_mab.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def predict(self, contexts: np.ndarray=None):
class LinUCBColdStart(_Linear):
def __init__(self, rng, arms, n_jobs, backend, l2_lambda=1.0, alpha=1.0, features=None):
# initialize the parent class as is
super().__init__(rng, arms, n_jobs, backend, l2_lambda, alpha, 'ucb')
super().__init__(rng, arms, n_jobs, backend, alpha, 0.0, l2_lambda, 'ucb', False)

# save the feature vectors
self.features = features
Expand Down
13 changes: 1 addition & 12 deletions examples/parallel_mab.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,13 @@
rewards_train, rewards_test = train_test_split(rewards, test_size=0.3, random_state=seed)
decisions_train, decisions_test = train_test_split(decisions, test_size=0.3, random_state=seed)

# Fit standard scaler for each arm
arm_to_scaler = {}
for arm in arms:
# Get indices for arm
indices = np.where(decisions_train == arm)

# Fit standard scaler
scaler = StandardScaler()
scaler.fit(contexts[indices])
arm_to_scaler[arm] = scaler

########################################################
# LinUCB Learning Policy
########################################################

# LinUCB learning policy with alpha 1.25 and n_jobs = -1 (maximum available cores)
linucb = MAB(arms=arms,
learning_policy=LearningPolicy.LinUCB(alpha=1.25, arm_to_scaler=arm_to_scaler),
learning_policy=LearningPolicy.LinUCB(alpha=1.25, scale=True),
n_jobs=-1)

# Learn from playlists shown and observed click rewards for each arm
Expand Down
2 changes: 1 addition & 1 deletion mabwiser/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

__author__ = "FMR LLC"
__email__ = "[email protected]"
__version__ = "2.4.0"
__version__ = "2.4.1"
__copyright__ = "Copyright (C), FMR LLC"
10 changes: 5 additions & 5 deletions mabwiser/mab.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import numpy as np
import pandas as pd
from sklearn.cluster import MiniBatchKMeans
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import DecisionTreeRegressor

from mabwiser._version import __author__, __email__, __version__, __copyright__
from mabwiser.approximate import _LSHNearest
Expand Down Expand Up @@ -633,9 +633,9 @@ class TreeBandit(NamedTuple):
----------
tree_parameters: Dict, **kwarg
Parameters of the decision tree.
The keys must match the parameters of sklearn.tree.DecisionTreeClassifier.
The keys must match the parameters of sklearn.tree.DecisionTreeRegressor.
When a parameter is not given, the default parameters from
sklearn.tree.DecisionTreeClassifier will be chosen.
sklearn.tree.DecisionTreeRegressor will be chosen.
Default value is an empty dictionary.
Example
Expand All @@ -655,10 +655,10 @@ class TreeBandit(NamedTuple):

def _validate(self):
check_true(isinstance(self.tree_parameters, dict), TypeError("tree_parameters must be a dictionary."))
tree = DecisionTreeClassifier()
tree = DecisionTreeRegressor()
for key in self.tree_parameters.keys():
check_true(key in tree.__dict__.keys(),
ValueError("sklearn.tree.DecisionTreeClassifier doesn't have a parameter " + str(key) + "."))
ValueError("sklearn.tree.DecisionTreeRegressor doesn't have a parameter " + str(key) + "."))

def _is_compatible(self, learning_policy: LearningPolicy):
# TreeBandit is compatible with these learning policies
Expand Down
6 changes: 3 additions & 3 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ def predict(arms: List[Arm],
return expectations[0] if num_run == 1 else expectations, mab

@staticmethod
def is_compatible(lp, np):
def is_compatible(learning_policy, neighborhood_policy):

# Special case for TreeBandit lp/np compatibility
if isinstance(np, NeighborhoodPolicy.TreeBandit):
return np._is_compatible(lp)
if isinstance(neighborhood_policy, NeighborhoodPolicy.TreeBandit):
return neighborhood_policy._is_compatible(learning_policy)

return True

Expand Down

0 comments on commit 646a398

Please sign in to comment.