Optimizer

Rank locations by sampling priority from their state variables, using multiple-criteria decision-making.

Optimizer decides where the next sampling campaign matters most. It takes the state of each location, one row per loc_id and one column per criterion, as returned by calling a State (see trufl.callbacks). get_rank normalizes the criteria, weighs them and scores each location with the functions in trufl.mcdm. Rank 1 is the location that most needs more samples. rank_to_sample in trufl.sampler turns these ranks into a number of samples per location.


source

Optimizer

def Optimizer(
    state:pandas.DataFrame, # One row per `loc_id` and one column per criterion, as returned by calling a `State`
):

Rank locations by sampling priority from their state variables.


source

Optimizer.get_rank

def get_rank(
    is_benefit_x:list, # One flag per criterion: `True` if a high value raises sampling priority (benefit), `False` if a low value does (cost)
    w_vector:list=None, # Weight of each criterion, summing to 1, or `None` to compute weights with `w_method`
    n_method:str=None, # Normalization method: `LINEAR1`, `LINEAR2`, `LINEAR3`, `VECTOR`, or `None` for values already in [0, 1]
    c_method:str=None, # Correlation method for `CRITIC` and `VIC` weighting: `PEARSON`, `ABSPEARSON` or `DCOR`
    w_method:str=None, # Weighting method used when `w_vector` is `None`: `MW`, `EM`, `SD`, `CRITIC` or `VIC`
    s_method:str=None, # Scoring method: `CP` or `TOPSIS`. Required
)->pandas.DataFrame: # A `rank` column indexed by `loc_id`, sorted from highest priority (rank 1) to lowest

Rank each location in state by sampling priority.

The examples below use three locations and two criteria. Max is the highest value measured at a location, and Count is how many measurements it has. Location 2 has no measurements yet, so its Max is missing:

state = pd.DataFrame({'Max': [0.8, 0.3, np.nan], 'Count': [4, 2, 0]},
                     index=pd.Index([0, 1, 2], name='loc_id'))
opt = Optimizer(state)

Max is a benefit criterion, because a high value raises priority. Count is a cost criterion, because a high value lowers priority. Both criteria get the same weight here. CP (compromise programming) scores each location by its distance to an ideal location that has the best value of every criterion:

ranks = opt.get_rank(is_benefit_x=[True, False], w_vector=[0.5, 0.5], n_method='LINEAR2', s_method='CP')
test_eq(ranks['rank'].to_dict(), {2: 1, 0: 2, 1: 3})
ranks
rank
loc_id
2 1
0 2
1 3

A missing value counts as the highest priority for its criterion. Location 2 ranks first because it has no measurements. Location 0 ranks above location 1 because its Max is higher.

Leave out w_vector to compute the weights from the data with w_method. MW (mean weights) gives every criterion the same weight, and it reproduces the ranking above:

test_eq(opt.get_rank(is_benefit_x=[True, False], n_method='LINEAR2', w_method='MW', s_method='CP'), ranks)