|
| 1 | +.. _sessionization: |
| 2 | + |
| 3 | +.. |SessionEncoder| replace:: :class:`~skrub.SessionEncoder` |
| 4 | +.. |BaseEstimator| replace:: :class:`~sklearn.base.BaseEstimator` |
| 5 | +.. |TransformerMixin| replace:: :class:`~sklearn.base.TransformerMixin` |
| 6 | + |
| 7 | + |
| 8 | +Detecting sessions in timestamped data with the SessionEncoder |
| 9 | +---------------------------------------------------------------- |
| 10 | + |
| 11 | +When dealing with timestamped data (data that includes at least a timestamp column), |
| 12 | +it may be beneficial to try and identify groups of events as |
| 13 | +`"sessions" <https://en.wikipedia.org/wiki/Session_(web_analytics)>`__, |
| 14 | +through **sessionization**. |
| 15 | + |
| 16 | +Sessionization is the process of grouping a sequence of events (like user |
| 17 | +interactions) into meaningful sessions. |
| 18 | +For example, in an online retail context you might define a new session whenever |
| 19 | +more than 30 minutes pass with no activity from the user. On a website, a session may |
| 20 | +define a sequence of requests made by a single end-user within a certain time duration. |
| 21 | + |
| 22 | +While definitions may vary depending on the specific use case, being able to detect |
| 23 | +such "bursts" of activity by a user can often help with building features that have |
| 24 | +greater predictive power than raw individual events, such as number of sessions or |
| 25 | +average session duration. |
| 26 | + |
| 27 | +The |SessionEncoder| addresses this problem by detecting sessions based on |
| 28 | +a timestamp column, other session-related columns (e.g., user and device) that should be |
| 29 | +used to distinguish between sessions, and a ``session_gap``. Session-related columns |
| 30 | +-- identified by the ``split_by`` parameter -- allow to split sessions based on |
| 31 | +the provided parameters, for example to group user actions only if they were conducted |
| 32 | +on the same device. |
| 33 | + |
| 34 | +A session is then defined as a sequence of events that share the same value in the |
| 35 | +``split_by`` columns, and whose events are closer to each other than the |
| 36 | +``session_gap``. |
| 37 | + |
| 38 | +>>> from skrub import SessionEncoder |
| 39 | +>>> from skrub.datasets import make_retail_events |
| 40 | +>>> events = make_retail_events(n_events=100, random_state=0) |
| 41 | +>>> X, y = events.X, events.y |
| 42 | + |
| 43 | +Once the necessary features are provided, the |SessionEncoder| |
| 44 | +returns a dataframe that includes a ``timestamp_session_id`` column, which is |
| 45 | +composed of a distinct integer ID for each session: |
| 46 | + |
| 47 | +>>> se = SessionEncoder(timestamp_col="timestamp", split_by="user_id", session_gap=30 * 60) |
| 48 | +>>> res = se.fit_transform(X) |
| 49 | +>>> res.head(5) # doctest: +SKIP |
| 50 | + user_id timestamp device_type page_category event_type time_on_page price_viewed timestamp_session_id |
| 51 | +0 user_0164 2024-01-01 03:29:07.708922+00:00 mobile fashion page_view 134.1 309.80 59 |
| 52 | +1 user_0164 2024-01-01 03:29:42.185048+00:00 tablet books search 103.4 11.00 59 |
| 53 | +2 user_0164 2024-01-01 03:32:38.352703+00:00 desktop home wishlist 180.3 4.80 59 |
| 54 | +3 user_0008 2024-01-02 10:49:56.974375+00:00 mobile books page_view 7.0 33.94 2 |
| 55 | +4 user_0149 2024-01-04 10:00:15.882835+00:00 desktop electronics page_view 108.5 4.44 49 |
| 56 | + |
| 57 | +With the session ID, it becomes possible to compute aggregations on |
| 58 | +each session, for example to find the duration or number of sessions |
| 59 | +by a user. |
| 60 | + |
| 61 | +.. warning:: |
| 62 | + |
| 63 | +Caution! Aggregation can introduce data leakage. Records should only be aggregated from |
| 64 | +within the training set at training time, and the test set at predict time. To |
| 65 | +ensure this is the case, any code that performs aggregation can be wrapped in a |
| 66 | +scikit-learn |BaseEstimator| (as shown in the |
| 67 | +:ref:`SessionEncoder example <sphx_glr_auto_examples_0110_session_encoder.py>`), |
| 68 | +otherwise the pipeline should use the skrub :ref:`Data Ops framework<user_guide_data_ops_plan>`. |
| 69 | + |
| 70 | +The |SessionEncoder| includes the ``suffix`` parameter (by default |
| 71 | +``suffix="session_id"``) to specify what the name of the new column should be. |
| 72 | +This can help with creating multiple session IDs based on the same timestamp. |
| 73 | +For example, we might want to create sessions based on users, and based on users |
| 74 | +and their device: |
| 75 | + |
| 76 | +>>> se = SessionEncoder(timestamp_col="timestamp", |
| 77 | +... split_by="user_id", |
| 78 | +... session_gap=30 * 60, |
| 79 | +... suffix="user" |
| 80 | +... ) |
| 81 | +>>> res = se.fit_transform(X) |
| 82 | +>>> res.head(5) # doctest: +SKIP |
| 83 | + user_id timestamp ... price_viewed timestamp_user |
| 84 | +0 user_0164 2024-01-01 03:29:07.708922+00:00 ... 309.80 59 |
| 85 | +1 user_0164 2024-01-01 03:29:42.185048+00:00 ... 11.00 59 |
| 86 | +2 user_0164 2024-01-01 03:32:38.352703+00:00 ... 4.80 59 |
| 87 | +3 user_0008 2024-01-02 10:49:56.974375+00:00 ... 33.94 2 |
| 88 | +4 user_0149 2024-01-04 10:00:15.882835+00:00 ... 4.44 49 |
| 89 | + |
| 90 | +>>> se = SessionEncoder(timestamp_col="timestamp", |
| 91 | +... split_by=["user_id", "device_type"], |
| 92 | +... session_gap=30 * 60, |
| 93 | +... suffix="user_device" |
| 94 | +... ) |
| 95 | +>>> res = se.fit_transform(X) |
| 96 | +>>> res.head(5) # doctest: +SKIP |
| 97 | + user_id timestamp ... price_viewed timestamp_user_device |
| 98 | +0 user_0164 2024-01-01 03:29:07.708922+00:00 ... 309.80 75 |
| 99 | +1 user_0164 2024-01-01 03:29:42.185048+00:00 ... 11.00 76 |
| 100 | +2 user_0164 2024-01-01 03:32:38.352703+00:00 ... 4.80 74 |
| 101 | +3 user_0008 2024-01-02 10:49:56.974375+00:00 ... 33.94 2 |
| 102 | +4 user_0149 2024-01-04 10:00:15.882835+00:00 ... 4.44 59 |
| 103 | + |
| 104 | +The |SessionEncoder| has additional features that are detailed in the relevant docstring. |
| 105 | +You can also find a working :ref:`example <sphx_glr_auto_examples_0110_session_encoder.py>` |
| 106 | +in the gallery. |
0 commit comments