Skip to content

Customers request models

A request model emulates customers interest on booking flight tickets. defined by a set of parameters that define the rate of requests per day as the departure date approaches and the amount of seats for each request.

BaseRequestModel dataclass

Bases: CustomersModel

Base dataclass for request models.

Source code in src/rmlab/data/parametric/customers_request.py
14
15
16
17
18
@dataclass
class BaseRequestModel(CustomersModel):
    """Base dataclass for request models."""

    pass

ExponentialPoisson dataclass

Bases: BaseRequestModel

A particular kind of request model, characterized by an exponential curve that for a given day before departure (d onwards, from 0 departure day to +D on-sale day) returns the cumulative booking requests for that day

\[ CumulativeRequestsOn(d) = scale · \exp(-d/ \beta) \]

On a given day before departure d, the average booking requests is given by

\[ \lambda_{requests}(d) = CumulativeRequestsOn(d) - CumulativeRequestsOn(d+1). \]

Note that \(d+1\) is the day before \(d\).

From \(\lambda_{requests}\) we sample the number of booking requests on day before departure \(d\) as:

\[ \# booking\,requests(d) \sim Poisson(\lambda_{requests}(d)) \]

For each booking request, we also sample the requested seats from a zero-truncated Poisson

\[ \# seats\,per\,request \sim Poisson_{ZT}(\lambda_{seats}) \]

Parameters:

NameTypeDescriptionDefault
class_namestr

Customers class

required
betafloat
\[\beta\]
required
scalefloat
\[scale\]
required
lambda_seatsfloat
\[\lambda_{seats}\]
required

Examples:

bus_req_model = ExponentialPoisson(class_name="business", beta=30, scale=300, lambda_seats=1.5)

JSON representation:

{
  "business": {"type": "poisson", "beta": 30.0, "scale": 400, "lambda_seats": 1.5},
}

Source code in src/rmlab/data/parametric/customers_request.py
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
@dataclass
class ExponentialPoisson(BaseRequestModel):
    """A particular kind of request model, characterized by an exponential curve that
    for a given day before departure (*d* onwards, from 0 *departure day* to +D *on-sale day*) returns the cumulative booking requests for that day

    $$
    CumulativeRequestsOn(d) = scale · \exp(-d/ \\beta)
    $$

    On a given day before departure *d*, the average booking requests is given by

    $$
    \lambda_{requests}(d) = CumulativeRequestsOn(d) - CumulativeRequestsOn(d+1).
    $$

    Note that $d+1$ is the day *before* $d$.

    From $\lambda_{requests}$ we sample the number of booking requests on day before departure $d$ as:

    $$
    \# booking\,requests(d) \sim Poisson(\lambda_{requests}(d))
    $$

    For each booking request, we also sample the requested seats from a zero-truncated Poisson

    $$
    \# seats\,per\,request \sim Poisson_{ZT}(\lambda_{seats})
    $$

    Args:
      class_name (str): Customers class
      beta (float): $$\\beta$$
      scale (float): $$scale$$
      lambda_seats (float): $$\lambda_{seats}$$

    Examples:
    ```py
    bus_req_model = ExponentialPoisson(class_name="business", beta=30, scale=300, lambda_seats=1.5)
    ```

    JSON representation:
    ```json
    {
      "business": {"type": "poisson", "beta": 30.0, "scale": 400, "lambda_seats": 1.5},
    }
    ```
    """

    class_name: str
    beta: float
    scale: float
    lambda_seats: float

MultipleRequestModels dataclass

Bases: BaseRequestModel

An aggregation of request models for different customer classes.

Example:

bus_req_model = ExponentialPoisson(class_name="business", beta=30, scale=300, lambda_seats=1.5)
lei_req_model = ExponentialPoisson(class_name="leisure", beta=10, scale=400, lambda_seats=3)

mul_req_model = MultipleRequestModels(bus_req_model, lei_req_model)

JSON representation:

{
  "business": {"type": "poisson", "beta": 30.0, "scale": 400, "lambda_seats": 1.5},
  "leisure": {"type": "poisson", "beta": 10.0, "scale": 300, "lambda_seats": 3}
}

Source code in src/rmlab/data/parametric/customers_request.py
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
@dataclass
class MultipleRequestModels(BaseRequestModel):
    """An aggregation of request models for different customer classes.

    Example:
    ```py
    bus_req_model = ExponentialPoisson(class_name="business", beta=30, scale=300, lambda_seats=1.5)
    lei_req_model = ExponentialPoisson(class_name="leisure", beta=10, scale=400, lambda_seats=3)

    mul_req_model = MultipleRequestModels(bus_req_model, lei_req_model)
    ```

    JSON representation:
    ```json
    {
      "business": {"type": "poisson", "beta": 30.0, "scale": 400, "lambda_seats": 1.5},
      "leisure": {"type": "poisson", "beta": 10.0, "scale": 300, "lambda_seats": 3}
    }
    ```
    """

    models: List[BaseRequestModel]

make_customers_request_model_from_json(filename_or_dict)

Make a request model instance from a json representation (from file or dict).

Parameters:

NameTypeDescriptionDefault
filename_or_dictUnion[str, dict]

JSON filename or dictionary in json format

required

Raises:

TypeDescription
ValueError

If JSON is not a dict

ValueError

If model type is invalid

ValueError

If JSON content is empty

Returns:

TypeDescription
BaseRequestModel

A customers request model instance

Example from dict:

my_dict = dict()
my_dict["business"] = {"type": "poisson", "beta": 30.0, "scale": 400, "lambda_seats": 1.5}
my_dict["leisure"] = {"type": "poisson", "beta": 10.0, "scale": 300, "lambda_seats": 3}

my_req_model = make_from_json(my_dict)

Example from file: my_req_model.json

{
  "business": {"type": "poisson", "beta": 30.0, "scale": 400, "lambda_seats": 1.5},
  "leisure": {"type": "poisson", "beta": 10.0, "scale": 300, "lambda_seats": 3}
}
my_req_model = make_customers_request_model_from_json("my_req_model.json")

Source code in src/rmlab/data/parametric/customers_request.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
def make_customers_request_model_from_json(
    filename_or_dict: Union[str, dict]
) -> BaseRequestModel:
    """Make a request model instance from a json representation (from file or dict).


    Args:
        filename_or_dict (Union[str, dict]): JSON filename or dictionary in json format

    Raises:
        ValueError: If JSON is not a dict
        ValueError: If model type is invalid
        ValueError: If JSON content is empty

    Returns:
        A customers request model instance

    Example from dict:
    ```py
    my_dict = dict()
    my_dict["business"] = {"type": "poisson", "beta": 30.0, "scale": 400, "lambda_seats": 1.5}
    my_dict["leisure"] = {"type": "poisson", "beta": 10.0, "scale": 300, "lambda_seats": 3}

    my_req_model = make_from_json(my_dict)
    ```

    Example from file:
    `my_req_model.json`
    ```json
    {
      "business": {"type": "poisson", "beta": 30.0, "scale": 400, "lambda_seats": 1.5},
      "leisure": {"type": "poisson", "beta": 10.0, "scale": 300, "lambda_seats": 3}
    }
    ```
    ```py
    my_req_model = make_customers_request_model_from_json("my_req_model.json")
    ```
    """

    model_id, filename, md5hash, content = parse_data_from_json(filename_or_dict)

    if not isinstance(content, dict):
        raise ValueError(f"Expected dict format in {filename_or_dict}")

    content: dict

    if len(content) > 0:
        models = list()
        for class_name, fields in content.items():
            if fields["type"] == "poisson":
                models.append(
                    ExponentialPoisson(
                        id=model_id,
                        filename=filename,
                        cnt=json.dumps(content),
                        hash=md5hash,
                        kind=CustomersModelKind.REQUEST,
                        extension=FileExtensions.JSON,
                        class_name=class_name,
                        beta=fields["beta"],
                        scale=fields["scale"],
                        lambda_seats=fields["lambda_seats"],
                    )
                )
            else:
                raise ValueError(f'Unknown request model type {fields["type"]}')

        if len(models) > 1:
            return MultipleRequestModels(
                id=model_id,
                filename=filename,
                cnt=json.dumps(content),
                hash=md5hash,
                kind=CustomersModelKind.REQUEST,
                extension=FileExtensions.JSON,
                models=models,
            )
        else:
            return models[0]

    else:
        raise ValueError(f"Empty content")