Source code for lerot.environment.CascadeUserModel

# This file is part of Lerot.
#
# Lerot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Lerot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Lerot.  If not, see <http://www.gnu.org/licenses/>.

# KH 07/10/2012

import argparse
import re

from random import random
from numpy import zeros

from .AbstractUserModel import AbstractUserModel
from ..utils import split_arg_str


[docs]class CascadeUserModel(AbstractUserModel): """Defines a cascade user model, simulating a user that inspects results starting from the top of a result list.""" def __init__(self, arg_str): parser = argparse.ArgumentParser(description="Initialize a cascade " "user model with click and stop probabilities.", prog="CascadeUserModel") parser.add_argument("-c", "--p_click", nargs="+") parser.add_argument("-s", "--p_stop", nargs="+") args = vars(parser.parse_args(split_arg_str(arg_str))) # allow arbitrary hash maps to map relevance labels to click and stop # probabilities p_click_str = "".join(args["p_click"]).strip("\"") self.p_click = {} for entry in re.split("\s*,\s*", p_click_str): (key, value) = re.split("\s*:\s*", entry) self.p_click[int(key)] = float(value) self.p_stop = {} p_stop_str = "".join(args["p_stop"]).strip("\"") for entry in re.split("\s*,\s*", p_stop_str): (key, value) = re.split("\s*:\s*", entry) self.p_stop[int(key)] = float(value)
[docs] def get_clicks(self, result_list, labels, **kwargs): """simulate clicks on list l""" c = zeros(len(result_list), dtype='int') for pos, d in enumerate(result_list): label = labels[d.get_id()] if label not in self.p_click: raise Exception("Cardinality of labels does not match the user" " model.") # generate a random number between 0 and 1 rand = random() if rand < self.p_click[label]: c[pos] = 1 # click at rank r # if there was a click, determine whether to stop rand = random() if rand < self.p_stop[label]: break return c