cleverly.datasets.make_sequential_pricing#

cleverly.datasets.make_sequential_pricing(n: int, *, seed: int | Generator | None = None, backend: Literal['pandas', 'polars'] | str | None = None) → tuple[Any, dict[str, float]][source]#

Draw three monthly renewal prices and the renewal, with the exact truth of the plans.

A subscription retailer’s pricing engine sets a renewal price in each of three months. The outcome renewed is the renewal at the third price, and revenue is renewed times that price. The frame has one wide row per customer and no missing value.

Parameters:
nint

Number of customers.

seedint, Generator, or None

Seed or NumPy random generator.

backend{“pandas”, “polars”, “pyarrow”} or None, default=None

Dataframe backend. None uses pandas when installed, then the first available backend.

Returns:
framedataframe

A wide frame with columns usage, engaged_1, price_1, engaged_2, price_2, engaged_3, price_3, renewed, and revenue.

truthdict of str to float

The result of pricing_truth().

See also

cleverly.datasets.pricing_truth

The exact truth this function returns.

cleverly.datasets.pricing_protocol

The protocol of the question the frame answers.

cleverly.datasets.PRICE_PLANS

The plans of the tutorial.

Notes

The law, for months \(t = 1, 2, 3\), with \(W\) the usage, \(L_t\) the engagement, \(A_t\) the price, \(c_t = 6 + 2 L_t\) the month’s centre, and \(g_t = A_t - c_t\) the price gap. The start is \(A_0 = c_0 = 6\) and \(L_0 = 0\).

variable

law

usage \(W\)

\(N(0, 1)\) truncated to \([-2.5, 2.5]\)

engaged_t \(L_t\)

Bernoulli, logit \(0.3 + 0.6 W - 0.35\,g_{t-1} + 0.8 L_{t-1}\)

price_t \(A_t\)

\(N(c_t + 0.3\,g_{t-1} + 0.3 W,\ 1.5^2)\) truncated to \([4 + 2 L_t,\ 8 + 2 L_t]\)

renewed \(Y\)

Bernoulli, logit \(0.5 - 0.45\,g_3 + 0.9 L_3 + 0.3 W - 0.1 (g_1 + g_2)\)

revenue

\(Y A_3\), with the declared support \([0, 10]\)

A price above the centre lowers the next engagement, and an engaged customer takes a higher price. The engine carries 0.3 of each price gap into the next price. The generator does not round a price. A rounded price could leave a plan’s price one unit in the last place outside the band that the design declares. Each column equals the same column of the law of the registered study mtp-pricing at three nodes, row for row. There is no censoring: every customer has every column.

Examples

>>> from cleverly.datasets import make_sequential_pricing
>>> frame, truth = make_sequential_pricing(200, seed=0)
>>> list(frame.columns)[:3]
['usage', 'engaged_1', 'price_1']
>>> frame.shape
(200, 9)
>>> round(truth["ate_regimen[price_up vs natural_prices]"], 4)
-0.1003