From d87d54f92a9df369c402d7554365e0d8feb19e03 Mon Sep 17 00:00:00 2001 From: rezarayev Date: Sat, 10 Dec 2022 23:54:19 +0300 Subject: [PATCH 01/12] [half hw_4] --- ...0\275\320\270\320\265 \342\204\2264.ipynb" | 5276 +++++++++++++++++ 1 file changed, 5276 insertions(+) create mode 100644 "notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" diff --git "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" new file mode 100644 index 00000000..80e446b6 --- /dev/null +++ "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" @@ -0,0 +1,5276 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "7780d9a2", + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e42a5585", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "from implicit.als import AlternatingLeastSquares\n", + "\n", + "from rectools.metrics import Precision, Recall, MAP, calc_metrics\n", + "from rectools.models import PopularModel, RandomModel, ImplicitALSWrapperModel\n", + "from rectools import Columns\n", + "from rectools.dataset import Dataset\n", + "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "\n", + "import matplotlib.pyplot as plt\n", + "from pathlib import Path\n", + "import typing as tp\n", + "from tqdm import tqdm\n", + "\n", + "from lightfm import LightFM\n", + "\n", + "from implicit.bpr import BayesianPersonalizedRanking\n", + "\n", + "from implicit.lmf import LogisticMatrixFactorization\n", + "\n", + "import optuna" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "8cd36e1a", + "metadata": {}, + "outputs": [], + "source": [ + "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4cb722c3", + "metadata": {}, + "outputs": [], + "source": [ + "DATA_PATH = Path(\"../data\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "8195e56b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.71 s, sys: 627 ms, total: 3.34 s\n", + "Wall time: 3.69 s\n" + ] + } + ], + "source": [ + "%%time\n", + "users = pd.read_csv(DATA_PATH / 'users.csv')\n", + "items = pd.read_csv(DATA_PATH / 'items.csv')\n", + "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "01c2bdef", + "metadata": {}, + "outputs": [], + "source": [ + "Columns.Datetime = 'last_watch_dt'" + ] + }, + { + "cell_type": "markdown", + "id": "00b5584e", + "metadata": {}, + "source": [ + "# Preprocess Interactions" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "0a3b4b12", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
..................
5476246648596122252021-08-13760.0
547624754686296732021-04-13230849.0
5476248697262152972021-08-201830763.0
5476249384202161972021-04-196203100.0
547625031970944362021-08-15392145.0
\n", + "

5476251 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct\n", + "0 176549 9506 2021-05-11 4250 72.0\n", + "1 699317 1659 2021-05-29 8317 100.0\n", + "2 656683 7107 2021-05-09 10 0.0\n", + "3 864613 7638 2021-07-05 14483 100.0\n", + "4 964868 9506 2021-04-30 6725 100.0\n", + "... ... ... ... ... ...\n", + "5476246 648596 12225 2021-08-13 76 0.0\n", + "5476247 546862 9673 2021-04-13 2308 49.0\n", + "5476248 697262 15297 2021-08-20 18307 63.0\n", + "5476249 384202 16197 2021-04-19 6203 100.0\n", + "5476250 319709 4436 2021-08-15 3921 45.0\n", + "\n", + "[5476251 rows x 5 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "260b1c48", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id int64\n", + "item_id int64\n", + "last_watch_dt object\n", + "total_dur int64\n", + "watched_pct float64\n", + "dtype: object" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "fe2dbc06", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id 0\n", + "item_id 0\n", + "last_watch_dt 0\n", + "total_dur 0\n", + "watched_pct 828\n", + "dtype: int64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "71f61e81", + "metadata": {}, + "outputs": [], + "source": [ + "interactions[Columns.Datetime] = pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "39646cb5", + "metadata": {}, + "outputs": [], + "source": [ + "interactions.dropna(inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f98ae95d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "interactions['watched_pct'].hist(bins=20);" + ] + }, + { + "cell_type": "markdown", + "id": "1a0ad9f8", + "metadata": {}, + "source": [ + "Делю график просмотра на 5 категорий, где: \n", + "от 0% до 20% = 1, \n", + "от 21% до 40% = 2, \n", + "... , \n", + "от 80% до 100% = 5" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "1424e744", + "metadata": {}, + "outputs": [], + "source": [ + "interactions[Columns.Weight] = np.where((interactions['watched_pct'] > 20), 2, 1)\n", + "interactions[Columns.Weight].mask(interactions['watched_pct'] > 40, 3, inplace=True)\n", + "interactions[Columns.Weight].mask(interactions['watched_pct'] > 60, 4, inplace=True)\n", + "interactions[Columns.Weight].mask(interactions['watched_pct'] > 80, 5, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "052d2fb0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "interactions[Columns.Datetime].hist(bins=20)" + ] + }, + { + "cell_type": "markdown", + "id": "5adb80ee", + "metadata": {}, + "source": [ + "Вообще, видно, что кол-во пользователей растет" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "0fbd2bbc", + "metadata": {}, + "outputs": [], + "source": [ + "cold_users = interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts() == 1].index" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "150e1593", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'].hist(bins=20)" + ] + }, + { + "cell_type": "markdown", + "id": "b5fa83eb", + "metadata": {}, + "source": [ + "Для холодных пользователей, я бы рекомендовал айтемы с самый высоким просмотром в среднем по холодным пользователям" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "cca06e3f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n", + "

355162 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "10 791466 8199 2021-07-27 713 9.0 1\n", + "26 181144 10440 2021-08-08 27408 40.0 2\n", + "37 161176 10440 2021-07-29 22 0.0 1\n", + "38 21723 1819 2021-04-11 8535 100.0 5\n", + "60 77216 8143 2021-05-08 660 11.0 1\n", + "... ... ... ... ... ... ...\n", + "5476222 1007900 9728 2021-08-12 416 6.0 1\n", + "5476225 882138 4716 2021-05-21 1594 2.0 1\n", + "5476238 805174 13125 2021-06-27 1 0.0 1\n", + "5476246 648596 12225 2021-08-13 76 0.0 1\n", + "5476248 697262 15297 2021-08-20 18307 63.0 4\n", + "\n", + "[355162 rows x 6 columns]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users = interactions[interactions[Columns.User].isin(cold_users)]\n", + "hot_users = interactions[~interactions[Columns.User].isin(cold_users)]\n", + "cold_users" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "a691676f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n", + "

5475423 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "0 176549 9506 2021-05-11 4250 72.0 4\n", + "1 699317 1659 2021-05-29 8317 100.0 5\n", + "2 656683 7107 2021-05-09 10 0.0 1\n", + "3 864613 7638 2021-07-05 14483 100.0 5\n", + "4 964868 9506 2021-04-30 6725 100.0 5\n", + "... ... ... ... ... ... ...\n", + "5476246 648596 12225 2021-08-13 76 0.0 1\n", + "5476247 546862 9673 2021-04-13 2308 49.0 3\n", + "5476248 697262 15297 2021-08-20 18307 63.0 4\n", + "5476249 384202 16197 2021-04-19 6203 100.0 5\n", + "5476250 319709 4436 2021-08-15 3921 45.0 3\n", + "\n", + "[5475423 rows x 6 columns]" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hot_users" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "a64701c2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n", + "

6440 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " item_id\n", + "10440 45695\n", + "15297 39309\n", + "2657 20474\n", + "9728 15140\n", + "4740 11455\n", + "... ...\n", + "1946 1\n", + "13886 1\n", + "14090 1\n", + "5730 1\n", + "13125 1\n", + "\n", + "[6440 rows x 1 columns]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users['item_id'].value_counts().to_frame()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "cef9cfa6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users[['item_id', 'total_dur']].groupby('item_id').mean().sort_values(by='total_dur', ascending=False).head(10).index" + ] + }, + { + "cell_type": "markdown", + "id": "a52f311b", + "metadata": {}, + "source": [ + "# Делим на train и test" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "bd68d3fe", + "metadata": {}, + "outputs": [], + "source": [ + "max_date = hot_users[Columns.Datetime].max()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "3092fe4b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: (4984443, 6)\n", + "test: (490980, 6)\n" + ] + } + ], + "source": [ + "train = interactions[interactions[Columns.Datetime] < max_date - pd.Timedelta(days=7)].copy()\n", + "test = interactions[interactions[Columns.Datetime] >= max_date - pd.Timedelta(days=7)].copy()\n", + "\n", + "print(f\"train: {train.shape}\")\n", + "print(f\"test: {test.shape}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "ec286bdc", + "metadata": {}, + "outputs": [], + "source": [ + "train.drop(train.query(\"total_dur < 300\").index, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "c32fcaae", + "metadata": {}, + "outputs": [], + "source": [ + "drop_user = set(test[Columns.User]) - set(train[Columns.User])" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "7183cb6f", + "metadata": {}, + "outputs": [], + "source": [ + "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "1ff85593", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
9203219135822021-08-226975100.05
5420019793352021-08-16832.01
6473446144882021-08-196011100.05
84100105122021-08-15140.01
94890735142002021-08-16117928.02
.....................
54761695895899832021-08-21240343.03
547618859089286182021-08-21133523.02
5476191857162123602021-08-16110.01
5476201273558106052021-08-2134030100.05
547625031970944362021-08-15392145.03
\n", + "

333022 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "9 203219 13582 2021-08-22 6975 100.0 5\n", + "54 200197 9335 2021-08-16 83 2.0 1\n", + "64 73446 14488 2021-08-19 6011 100.0 5\n", + "84 10010 512 2021-08-15 14 0.0 1\n", + "94 890735 14200 2021-08-16 1179 28.0 2\n", + "... ... ... ... ... ... ...\n", + "5476169 589589 983 2021-08-21 2403 43.0 3\n", + "5476188 590892 8618 2021-08-21 1335 23.0 2\n", + "5476191 857162 12360 2021-08-16 11 0.0 1\n", + "5476201 273558 10605 2021-08-21 34030 100.0 5\n", + "5476250 319709 4436 2021-08-15 3921 45.0 3\n", + "\n", + "[333022 rows x 6 columns]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test" + ] + }, + { + "cell_type": "markdown", + "id": "b5eec6da", + "metadata": {}, + "source": [ + "# User preprocess" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "c57e2b2f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n", + "

840197 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " user_id age income sex kids_flg\n", + "0 973171 age_25_34 income_60_90 М 1\n", + "1 962099 age_18_24 income_20_40 М 0\n", + "2 1047345 age_45_54 income_40_60 Ж 0\n", + "3 721985 age_45_54 income_20_40 Ж 0\n", + "4 704055 age_35_44 income_60_90 Ж 0\n", + "... ... ... ... ... ...\n", + "840192 339025 age_65_inf income_0_20 Ж 0\n", + "840193 983617 age_18_24 income_20_40 Ж 1\n", + "840194 251008 NaN NaN NaN 0\n", + "840195 590706 NaN NaN Ж 0\n", + "840196 166555 age_65_inf income_20_40 Ж 0\n", + "\n", + "[840197 rows x 5 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "63996e92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id 0.000000\n", + "age 0.016776\n", + "income 0.017586\n", + "sex 0.016462\n", + "kids_flg 0.000000\n", + "dtype: float64" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users.isnull().sum()/840197" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "24cc138a", + "metadata": {}, + "outputs": [], + "source": [ + "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" + ] + }, + { + "cell_type": "markdown", + "id": "c7f9a6e7", + "metadata": {}, + "source": [ + "Заменяю Nan'ы на Unknown" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "1286eb60", + "metadata": {}, + "outputs": [], + "source": [ + "users.fillna('Unknown', inplace=True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "1ccccf0f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 973171 М sex\n", + "1 962099 М sex\n", + "3 721985 Ж sex\n", + "4 704055 Ж sex\n", + "5 1037719 М sex" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_features_frames = []\n", + "for feature in [\"sex\", \"age\", \"income\"]:\n", + " feature_frame = users.reindex(columns=[Columns.User, feature])\n", + " feature_frame.columns = [\"id\", \"value\"]\n", + " feature_frame[\"feature\"] = feature\n", + " user_features_frames.append(feature_frame)\n", + "user_features = pd.concat(user_features_frames)\n", + "user_features.head()" + ] + }, + { + "cell_type": "markdown", + "id": "b9220b0b", + "metadata": {}, + "source": [ + "# Item preprocess" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "8bbe9ee4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
.............................................
159586443seriesПолярный кругArctic Circle2018.0драмы, триллеры, криминалФинляндия, ГерманияNaN16.0NaNХанну СалоненИина Куустонен, Максимилиан Брюкнер, Пихла Вии...Во время погони за браконьерами по лесу, сотру...убийство, вирус, расследование преступления, н...
159592367seriesНадеждаNaN2020.0драмы, боевикиРоссия0.018.0NaNЕлена ХазановаВиктория Исакова, Александр Кузьмин, Алексей М...Оригинальный киносериал от создателей «Бывших»...Надежда, 2020, Россия
1596010632seriesСговорHassel2017.0драмы, триллеры, криминалРоссия0.018.0NaNЭшреф Рейбрук, Амир Камдин, Эрик ЭгерОла Рапас, Алиетт Офейм, Уильма Лиден, Шанти Р...Криминальная драма по мотивам романов о шведск...Сговор, 2017, Россия
159614538seriesСреди камнейDarklands2019.0драмы, спорт, криминалРоссия0.018.0NaNМарк О’Коннор, Конор МакМахонДэйн Уайт О’Хара, Томас Кэйн-Бирн, Джудит Родд...Семнадцатилетний Дэмиен мечтает вырваться за п...Среди, камней, 2019, Россия
159623206seriesГошаNaN2019.0комедииРоссия0.016.0NaNМихаил МироновМкртыч Арзуманян, Виктория РунцоваДобродушный Гоша не может выйти из дома, чтобы...Гоша, 2019, Россия
\n", + "

15963 rows × 14 columns

\n", + "
" + ], + "text/plain": [ + " item_id content_type title title_orig \\\n", + "0 10711 film Поговори с ней Hable con ella \n", + "1 2508 film Голые перцы Search Party \n", + "2 10716 film Тактическая сила Tactical Force \n", + "3 7868 film 45 лет 45 Years \n", + "4 16268 film Все решает мгновение NaN \n", + "... ... ... ... ... \n", + "15958 6443 series Полярный круг Arctic Circle \n", + "15959 2367 series Надежда NaN \n", + "15960 10632 series Сговор Hassel \n", + "15961 4538 series Среди камней Darklands \n", + "15962 3206 series Гоша NaN \n", + "\n", + " release_year genres \\\n", + "0 2002.0 драмы, зарубежные, детективы, мелодрамы \n", + "1 2014.0 зарубежные, приключения, комедии \n", + "2 2011.0 криминал, зарубежные, триллеры, боевики, комедии \n", + "3 2015.0 драмы, зарубежные, мелодрамы \n", + "4 1978.0 драмы, спорт, советские, мелодрамы \n", + "... ... ... \n", + "15958 2018.0 драмы, триллеры, криминал \n", + "15959 2020.0 драмы, боевики \n", + "15960 2017.0 драмы, триллеры, криминал \n", + "15961 2019.0 драмы, спорт, криминал \n", + "15962 2019.0 комедии \n", + "\n", + " countries for_kids age_rating studios \\\n", + "0 Испания NaN 16.0 NaN \n", + "1 США NaN 16.0 NaN \n", + "2 Канада NaN 16.0 NaN \n", + "3 Великобритания NaN 16.0 NaN \n", + "4 СССР NaN 12.0 Ленфильм \n", + "... ... ... ... ... \n", + "15958 Финляндия, Германия NaN 16.0 NaN \n", + "15959 Россия 0.0 18.0 NaN \n", + "15960 Россия 0.0 18.0 NaN \n", + "15961 Россия 0.0 18.0 NaN \n", + "15962 Россия 0.0 16.0 NaN \n", + "\n", + " directors \\\n", + "0 Педро Альмодовар \n", + "1 Скот Армстронг \n", + "2 Адам П. Калтраро \n", + "3 Эндрю Хэй \n", + "4 Виктор Садовский \n", + "... ... \n", + "15958 Ханну Салонен \n", + "15959 Елена Хазанова \n", + "15960 Эшреф Рейбрук, Амир Камдин, Эрик Эгер \n", + "15961 Марк О’Коннор, Конор МакМахон \n", + "15962 Михаил Миронов \n", + "\n", + " actors \\\n", + "0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n", + "1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n", + "2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n", + "3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n", + "4 Александр Абдулов, Александр Демьяненко, Алекс... \n", + "... ... \n", + "15958 Иина Куустонен, Максимилиан Брюкнер, Пихла Вии... \n", + "15959 Виктория Исакова, Александр Кузьмин, Алексей М... \n", + "15960 Ола Рапас, Алиетт Офейм, Уильма Лиден, Шанти Р... \n", + "15961 Дэйн Уайт О’Хара, Томас Кэйн-Бирн, Джудит Родд... \n", + "15962 Мкртыч Арзуманян, Виктория Рунцова \n", + "\n", + " description \\\n", + "0 Мелодрама легендарного Педро Альмодовара «Пого... \n", + "1 Уморительная современная комедия на популярную... \n", + "2 Профессиональный рестлер Стив Остин («Все или ... \n", + "3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n", + "4 Расчетливая чаровница из советского кинохита «... \n", + "... ... \n", + "15958 Во время погони за браконьерами по лесу, сотру... \n", + "15959 Оригинальный киносериал от создателей «Бывших»... \n", + "15960 Криминальная драма по мотивам романов о шведск... \n", + "15961 Семнадцатилетний Дэмиен мечтает вырваться за п... \n", + "15962 Добродушный Гоша не может выйти из дома, чтобы... \n", + "\n", + " keywords \n", + "0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n", + "1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n", + "2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n", + "3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n", + "4 Все, решает, мгновение, 1978, СССР, сильные, ж... \n", + "... ... \n", + "15958 убийство, вирус, расследование преступления, н... \n", + "15959 Надежда, 2020, Россия \n", + "15960 Сговор, 2017, Россия \n", + "15961 Среди, камней, 2019, Россия \n", + "15962 Гоша, 2019, Россия \n", + "\n", + "[15963 rows x 14 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "72fa86a0", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "item_id 0\n", + "content_type 0\n", + "title 0\n", + "title_orig 4745\n", + "release_year 98\n", + "genres 0\n", + "countries 37\n", + "for_kids 15397\n", + "age_rating 2\n", + "studios 14898\n", + "directors 1509\n", + "actors 2619\n", + "description 2\n", + "keywords 423\n", + "dtype: int64" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "50f0611f", + "metadata": {}, + "outputs": [], + "source": [ + "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "280cf47d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "item_id 0\n", + "content_type 0\n", + "title 0\n", + "title_orig 3775\n", + "release_year 31\n", + "genres 0\n", + "countries 14\n", + "for_kids 13415\n", + "age_rating 1\n", + "studios 13047\n", + "directors 939\n", + "actors 1858\n", + "description 0\n", + "keywords 388\n", + "dtype: int64" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "markdown", + "id": "eddd93b5", + "metadata": {}, + "source": [ + "# Genre" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "bf6da75c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Explode genres to flatten table\n", + "items[\"genre\"] = items[\"genres\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "genre_feature = items[[\"item_id\", \"genre\"]].explode(\"genre\")\n", + "genre_feature.columns = [\"id\", \"value\"]\n", + "genre_feature[\"feature\"] = \"genre\"\n", + "genre_feature.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "913b9c27", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n", + "

36128 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre\n", + "... ... ... ...\n", + "15960 10632 криминал genre\n", + "15961 4538 драмы genre\n", + "15961 4538 спорт genre\n", + "15961 4538 криминал genre\n", + "15962 3206 комедии genre\n", + "\n", + "[36128 rows x 3 columns]" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "genre_feature" + ] + }, + { + "cell_type": "markdown", + "id": "478bf1e3", + "metadata": {}, + "source": [ + "# Content" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "65f8b5d9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
............
159586443seriescontent_type
159592367seriescontent_type
1596010632seriescontent_type
159614538seriescontent_type
159623206seriescontent_type
\n", + "

13963 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 film content_type\n", + "1 2508 film content_type\n", + "2 10716 film content_type\n", + "3 7868 film content_type\n", + "4 16268 film content_type\n", + "... ... ... ...\n", + "15958 6443 series content_type\n", + "15959 2367 series content_type\n", + "15960 10632 series content_type\n", + "15961 4538 series content_type\n", + "15962 3206 series content_type\n", + "\n", + "[13963 rows x 3 columns]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", + "content_feature.columns = [\"id\", \"value\"]\n", + "content_feature[\"feature\"] = \"content_type\"\n", + "content_feature" + ] + }, + { + "cell_type": "markdown", + "id": "a62ebee4", + "metadata": {}, + "source": [ + "# Actors" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "fdc43660", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
............
159614538джудит роддиactors
159614538марк о’халлоранactors
159614538джимми смоллхорнactors
159623206мкртыч арзуманянactors
159623206виктория рунцоваactors
\n", + "

128926 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 адольфо фернандес actors\n", + "0 10711 ана фернандес actors\n", + "0 10711 дарио грандинетти actors\n", + "0 10711 джеральдин чаплин actors\n", + "0 10711 елена анайя actors\n", + "... ... ... ...\n", + "15961 4538 джудит родди actors\n", + "15961 4538 марк о’халлоран actors\n", + "15961 4538 джимми смоллхорн actors\n", + "15962 3206 мкртыч арзуманян actors\n", + "15962 3206 виктория рунцова actors\n", + "\n", + "[128926 rows x 3 columns]" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items[\"actors\"] = items[\"actors\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "actors_feature = items[[\"item_id\", \"actors\"]].explode(\"actors\")\n", + "actors_feature.columns = [\"id\", \"value\"]\n", + "actors_feature[\"feature\"] = \"actors\"\n", + "actors_feature" + ] + }, + { + "cell_type": "markdown", + "id": "73801647", + "metadata": {}, + "source": [ + "# Keywords" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "594abe5c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
............
1596145382019keywords
159614538россияkeywords
159623206гошаkeywords
1596232062019keywords
159623206россияkeywords
\n", + "

341629 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 поговори keywords\n", + "0 10711 ней keywords\n", + "0 10711 2002 keywords\n", + "0 10711 испания keywords\n", + "0 10711 друзья keywords\n", + "... ... ... ...\n", + "15961 4538 2019 keywords\n", + "15961 4538 россия keywords\n", + "15962 3206 гоша keywords\n", + "15962 3206 2019 keywords\n", + "15962 3206 россия keywords\n", + "\n", + "[341629 rows x 3 columns]" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items[\"keywords\"] = items[\"keywords\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "keywords_feature = items[[\"item_id\", \"keywords\"]].explode(\"keywords\")\n", + "keywords_feature.columns = [\"id\", \"value\"]\n", + "keywords_feature[\"feature\"] = \"keywords\"\n", + "keywords_feature" + ] + }, + { + "cell_type": "markdown", + "id": "d3eb0a37", + "metadata": {}, + "source": [ + "# Countries\t" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "8eb8a621", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
............
159586443Финляндия, Германияcountries
159592367Россияcountries
1596010632Россияcountries
159614538Россияcountries
159623206Россияcountries
\n", + "

13963 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 Испания countries\n", + "1 2508 США countries\n", + "2 10716 Канада countries\n", + "3 7868 Великобритания countries\n", + "4 16268 СССР countries\n", + "... ... ... ...\n", + "15958 6443 Финляндия, Германия countries\n", + "15959 2367 Россия countries\n", + "15960 10632 Россия countries\n", + "15961 4538 Россия countries\n", + "15962 3206 Россия countries\n", + "\n", + "[13963 rows x 3 columns]" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "country_feature = items.reindex(columns=[Columns.Item, \"countries\"])\n", + "country_feature.columns = [\"id\", \"value\"]\n", + "country_feature[\"feature\"] = \"countries\"\n", + "country_feature" + ] + }, + { + "cell_type": "markdown", + "id": "5e477ee1", + "metadata": {}, + "source": [ + "# Age Rating" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "0894154a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
............
15958644316.0age_feature
15959236718.0age_feature
159601063218.0age_feature
15961453818.0age_feature
15962320616.0age_feature
\n", + "

13963 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 16.0 age_feature\n", + "1 2508 16.0 age_feature\n", + "2 10716 16.0 age_feature\n", + "3 7868 16.0 age_feature\n", + "4 16268 12.0 age_feature\n", + "... ... ... ...\n", + "15958 6443 16.0 age_feature\n", + "15959 2367 18.0 age_feature\n", + "15960 10632 18.0 age_feature\n", + "15961 4538 18.0 age_feature\n", + "15962 3206 16.0 age_feature\n", + "\n", + "[13963 rows x 3 columns]" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", + "age_feature.columns = [\"id\", \"value\"]\n", + "age_feature[\"feature\"] = \"age_feature\"\n", + "age_feature" + ] + }, + { + "cell_type": "markdown", + "id": "c09df1ec", + "metadata": {}, + "source": [ + "# Studios" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "ff937b4f", + "metadata": {}, + "outputs": [], + "source": [ + "items.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "cee42708", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711Unknownstudios
12508Unknownstudios
210716Unknownstudios
37868Unknownstudios
416268Ленфильмstudios
............
159586443Unknownstudios
159592367Unknownstudios
1596010632Unknownstudios
159614538Unknownstudios
159623206Unknownstudios
\n", + "

13963 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 Unknown studios\n", + "1 2508 Unknown studios\n", + "2 10716 Unknown studios\n", + "3 7868 Unknown studios\n", + "4 16268 Ленфильм studios\n", + "... ... ... ...\n", + "15958 6443 Unknown studios\n", + "15959 2367 Unknown studios\n", + "15960 10632 Unknown studios\n", + "15961 4538 Unknown studios\n", + "15962 3206 Unknown studios\n", + "\n", + "[13963 rows x 3 columns]" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", + "studios_feature.columns = [\"id\", \"value\"]\n", + "studios_feature[\"feature\"] = \"studios\"\n", + "studios_feature" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "6158b0bd", + "metadata": {}, + "outputs": [], + "source": [ + "item_features = pd.concat((genre_feature, content_feature, studios_feature, age_feature, country_feature))" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "ea1feadd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
159586443Финляндия, Германияcountries
159592367Россияcountries
1596010632Россияcountries
159614538Россияcountries
159623206Россияcountries
\n", + "

91980 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre\n", + "... ... ... ...\n", + "15958 6443 Финляндия, Германия countries\n", + "15959 2367 Россия countries\n", + "15960 10632 Россия countries\n", + "15961 4538 Россия countries\n", + "15962 3206 Россия countries\n", + "\n", + "[91980 rows x 3 columns]" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "item_features" + ] + }, + { + "cell_type": "markdown", + "id": "09b8d756", + "metadata": {}, + "source": [ + "# Metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "b082e667", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Precision@1': Precision(k=1),\n", + " 'Precision@2': Precision(k=2),\n", + " 'Precision@3': Precision(k=3),\n", + " 'Precision@4': Precision(k=4),\n", + " 'Precision@5': Precision(k=5),\n", + " 'Precision@6': Precision(k=6),\n", + " 'Precision@7': Precision(k=7),\n", + " 'Precision@8': Precision(k=8),\n", + " 'Precision@9': Precision(k=9),\n", + " 'Precision@10': Precision(k=10),\n", + " 'Recall@1': Recall(k=1),\n", + " 'Recall@2': Recall(k=2),\n", + " 'Recall@3': Recall(k=3),\n", + " 'Recall@4': Recall(k=4),\n", + " 'Recall@5': Recall(k=5),\n", + " 'Recall@6': Recall(k=6),\n", + " 'Recall@7': Recall(k=7),\n", + " 'Recall@8': Recall(k=8),\n", + " 'Recall@9': Recall(k=9),\n", + " 'Recall@10': Recall(k=10),\n", + " 'MAP@1': MAP(k=1, divide_by_k=False),\n", + " 'MAP@2': MAP(k=2, divide_by_k=False),\n", + " 'MAP@3': MAP(k=3, divide_by_k=False),\n", + " 'MAP@4': MAP(k=4, divide_by_k=False),\n", + " 'MAP@5': MAP(k=5, divide_by_k=False),\n", + " 'MAP@6': MAP(k=6, divide_by_k=False),\n", + " 'MAP@7': MAP(k=7, divide_by_k=False),\n", + " 'MAP@8': MAP(k=8, divide_by_k=False),\n", + " 'MAP@9': MAP(k=9, divide_by_k=False),\n", + " 'MAP@10': MAP(k=10, divide_by_k=False)}" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metrics_name = {\n", + " 'Precision': Precision,\n", + " 'Recall': Recall,\n", + " 'MAP': MAP,\n", + "}\n", + "\n", + "metrics = {}\n", + "for metric_name, metric in metrics_name.items():\n", + " for k in range(1, 11):\n", + " metrics[f'{metric_name}@{k}'] = metric(k=k)\n", + "metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "864a7990", + "metadata": {}, + "outputs": [], + "source": [ + "K_RECOS = 10\n", + "RANDOM_STATE = 42\n", + "NUM_THREADS = 8\n", + "N_FACTORS = (32,)\n", + "N_EPOCHS = 1 # Lightfm\n", + "USER_ALPHA = 0 # Lightfm\n", + "ITEM_ALPHA = 0 # Lightfm\n", + "LEARNING_RATE = 0.05 # Lightfm" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "12662152", + "metadata": {}, + "outputs": [], + "source": [ + "models = {}\n", + "implicit_models = {\n", + " 'ALS': AlternatingLeastSquares,\n", + "}\n", + "for implicit_name, implicit_model in implicit_models.items():\n", + " for is_fitting_features in (True, False):\n", + " for n_factors in N_FACTORS:\n", + " models[f\"{implicit_name}_{n_factors}_{is_fitting_features}\"] = (\n", + " ImplicitALSWrapperModel(\n", + " model=implicit_model(\n", + " factors=n_factors, \n", + " random_state=RANDOM_STATE, \n", + " num_threads=NUM_THREADS,\n", + " ),\n", + " fit_features_together=is_fitting_features,\n", + " )\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "6f9ef4f0", + "metadata": {}, + "outputs": [], + "source": [ + "lightfm_losses = ('logistic', 'bpr', 'warp')\n", + "\n", + "for loss in lightfm_losses:\n", + " for n_factors in N_FACTORS:\n", + " models[f\"LightFM_{loss}_{n_factors}\"] = LightFMWrapperModel(\n", + " LightFM(\n", + " no_components=n_factors, \n", + " loss=loss, \n", + " random_state=RANDOM_STATE,\n", + " learning_rate=LEARNING_RATE,\n", + " user_alpha=USER_ALPHA,\n", + " item_alpha=ITEM_ALPHA,\n", + " ),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "21773201", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'ALS_32_True': ,\n", + " 'ALS_32_False': ,\n", + " 'LightFM_logistic_32': ,\n", + " 'LightFM_bpr_32': ,\n", + " 'LightFM_warp_32': }" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "models" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "125de2fc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'content_type', 'genre'}" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "set(item_features.feature)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "6288eea7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 1.35 s, sys: 79.5 ms, total: 1.43 s\n", + "Wall time: 1.43 s\n" + ] + } + ], + "source": [ + "%%time\n", + "dataset = Dataset.construct(\n", + " interactions_df=train,\n", + " user_features_df=user_features,\n", + " cat_user_features=[\"sex\", \"age\", \"income\"],\n", + " item_features_df=item_features,\n", + " cat_item_features=['content_type', 'genre'])" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "d027f149", + "metadata": {}, + "outputs": [], + "source": [ + "TEST_USERS = test[Columns.User].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70bc6f59", + "metadata": {}, + "outputs": [], + "source": [ + " model = LightFMWrapperModel(LightFM(k=5,\n", + " learning_rate=learning_rate,\n", + " loss=loss), \n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "c99924ca", + "metadata": {}, + "outputs": [], + "source": [ + "model = LightFMWrapperModel(\n", + " LightFM(\n", + " k=5,\n", + " no_components=32, \n", + " loss='warp', \n", + " random_state=RANDOM_STATE,\n", + " learning_rate=0.08165160206425184,\n", + " user_alpha=USER_ALPHA,\n", + " item_alpha=ITEM_ALPHA),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS) " + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "d3907c1d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.fit(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "b2050a6e", + "metadata": {}, + "outputs": [], + "source": [ + "recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "8c7da423", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idscorerank
0203219104404.9805491
1203219152974.9678702
220321941514.4776473
3203219138654.4307254
420321997284.3544635
...............
1129735857162373414.4367456
112973685716214214.1344087
1129737857162488014.0818358
1129738857162265714.0243259
1129739857162680913.95767710
\n", + "

1129740 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id score rank\n", + "0 203219 10440 4.980549 1\n", + "1 203219 15297 4.967870 2\n", + "2 203219 4151 4.477647 3\n", + "3 203219 13865 4.430725 4\n", + "4 203219 9728 4.354463 5\n", + "... ... ... ... ...\n", + "1129735 857162 3734 14.436745 6\n", + "1129736 857162 142 14.134408 7\n", + "1129737 857162 4880 14.081835 8\n", + "1129738 857162 2657 14.024325 9\n", + "1129739 857162 6809 13.957677 10\n", + "\n", + "[1129740 rows x 4 columns]" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recos" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "6bbe3ff3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.07682068366774675" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "calc_metrics(metrics, recos, test, train)['MAP@10']" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "51b77a4b", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'model_quality' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_23602/1194377468.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mmetric_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcalc_metrics\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmetrics\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrecos\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrain\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmodel_quality\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmetric_values\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'model_quality' is not defined" + ] + } + ], + "source": [ + "metric_values = calc_metrics(metrics, recos, test, train)\n", + "model_quality.update(metric_values)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b6345c1", + "metadata": {}, + "outputs": [], + "source": [ + "recos" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "2d847fd3", + "metadata": {}, + "outputs": [], + "source": [ + "recos['rank'] = recos.groupby('user_id')['user_id'].rank(method='first')" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "9d12a9b6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idscorerank
0203219104404.9805491.0
1203219152974.9678702.0
220321941514.4776473.0
3203219138654.4307254.0
420321997284.3544635.0
...............
1129735857162373414.4367456.0
112973685716214214.1344087.0
1129737857162488014.0818358.0
1129738857162265714.0243259.0
1129739857162680913.95767710.0
\n", + "

1129740 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id score rank\n", + "0 203219 10440 4.980549 1.0\n", + "1 203219 15297 4.967870 2.0\n", + "2 203219 4151 4.477647 3.0\n", + "3 203219 13865 4.430725 4.0\n", + "4 203219 9728 4.354463 5.0\n", + "... ... ... ... ...\n", + "1129735 857162 3734 14.436745 6.0\n", + "1129736 857162 142 14.134408 7.0\n", + "1129737 857162 4880 14.081835 8.0\n", + "1129738 857162 2657 14.024325 9.0\n", + "1129739 857162 6809 13.957677 10.0\n", + "\n", + "[1129740 rows x 4 columns]" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recos" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "d3eead34", + "metadata": {}, + "outputs": [], + "source": [ + "recos = recos[['user_id', 'item_id']]\n", + "recos.to_csv('LightFM_after_optuna.csv.gz', index=False, compression='gzip')" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "ab782bd2", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Precision@1': 0.07723901074583532,\n", + " 'Recall@1': 0.039945025203155064,\n", + " 'Precision@2': 0.06777223077876325,\n", + " 'Recall@2': 0.06826845228559537,\n", + " 'Precision@3': 0.060972731188874404,\n", + " 'Recall@3': 0.09049343777050076,\n", + " 'Precision@4': 0.05550613415476127,\n", + " 'Recall@4': 0.10871933417276143,\n", + " 'Precision@5': 0.050597482606595634,\n", + " 'Recall@5': 0.12251909647186383,\n", + " 'Precision@6': 0.0459235458306068,\n", + " 'Recall@6': 0.1321820062289563,\n", + " 'Precision@7': 0.041941382214374844,\n", + " 'Recall@7': 0.1398538669008927,\n", + " 'Precision@8': 0.038631676314904315,\n", + " 'Recall@8': 0.14618067736019413,\n", + " 'Precision@9': 0.03598468084103889,\n", + " 'Recall@9': 0.15248904141482145,\n", + " 'Precision@10': 0.03387593605606706,\n", + " 'Recall@10': 0.1588631307179617,\n", + " 'MAP@1': 0.039945025203155064,\n", + " 'MAP@2': 0.05480355385012115,\n", + " 'MAP@3': 0.06281691802625049,\n", + " 'MAP@4': 0.0678842944950224,\n", + " 'MAP@5': 0.07103949043829605,\n", + " 'MAP@6': 0.07292909703284091,\n", + " 'MAP@7': 0.07424621516323489,\n", + " 'MAP@8': 0.0752068879380646,\n", + " 'MAP@9': 0.076042345201511,\n", + " 'MAP@10': 0.07682068366774675}" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metric_values" + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "id": "b44853f7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Precision@1': 0.08459468550285906,\n", + " 'Recall@1': 0.043103367696718034,\n", + " 'Precision@2': 0.07092782410112061,\n", + " 'Recall@2': 0.07046014541694683,\n", + " 'Precision@3': 0.06248635379230436,\n", + " 'Recall@3': 0.0921280723507131,\n", + " 'Precision@4': 0.05624966806521855,\n", + " 'Recall@4': 0.10932894551338254,\n", + " 'Precision@5': 0.05087719298243397,\n", + " 'Recall@5': 0.12237920952417945,\n", + " 'Precision@6': 0.04632924389682875,\n", + " 'Recall@6': 0.1323848629683412,\n", + " 'Precision@7': 0.04247753591851333,\n", + " 'Recall@7': 0.1404981921258083,\n", + " 'Precision@8': 0.03938074247171915,\n", + " 'Recall@8': 0.14793166723537798,\n", + " 'Precision@9': 0.036883609404740884,\n", + " 'Recall@9': 0.15500874146216406,\n", + " 'Precision@10': 0.03488855842935579,\n", + " 'Recall@10': 0.16230490106911452,\n", + " 'MAP@1': 0.043103367696718034,\n", + " 'MAP@2': 0.05749557914551633,\n", + " 'MAP@3': 0.0653294074408595,\n", + " 'MAP@4': 0.07012030221603167,\n", + " 'MAP@5': 0.07311471593152033,\n", + " 'MAP@6': 0.07509192714707785,\n", + " 'MAP@7': 0.07646356744900325,\n", + " 'MAP@8': 0.07757984846454224,\n", + " 'MAP@9': 0.07852432437618763,\n", + " 'MAP@10': 0.07940775755218821}" + ] + }, + "execution_count": 168, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metric_values" + ] + }, + { + "cell_type": "code", + "execution_count": 161, + "id": "0d5edb2b", + "metadata": { + "collapsed": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting model ALS_32_True...\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, dataset, *args, **kwargs)\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \"\"\"\n\u001b[0;32m---> 55\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 56\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_fitted\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36m_fit\u001b[0;34m(self, dataset)\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit_features_together\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 71\u001b[0;31m user_factors, item_factors = fit_als_with_features_together(\n\u001b[0m\u001b[1;32m 72\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36mfit_als_with_features_together\u001b[0;34m(model, ui_csr, user_features, item_features, verbose)\u001b[0m\n\u001b[1;32m 315\u001b[0m )\n\u001b[1;32m 316\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 317\u001b[0;31m _fit_combined_factors_on_cpu_inplace(\n\u001b[0m\u001b[1;32m 318\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 319\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36m_fit_combined_factors_on_cpu_inplace\u001b[0;34m(model, ui_csr, user_factors, item_factors, n_user_explicit_factors, n_item_explicit_factors, verbose)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miterations\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mverbose\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m model.solver(\n\u001b[0m\u001b[1;32m 346\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[0muser_factors\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "%%time\n", + "results = []\n", + "for model_name, model in models.items():\n", + " print(f\"Fitting model {model_name}...\")\n", + " model_quality = {'model': model_name}\n", + "\n", + " model.fit(dataset)\n", + " recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True,\n", + " )\n", + " metric_values = calc_metrics(metrics, recos, test, train)\n", + " model_quality.update(metric_values)\n", + " results.append(model_quality)" + ] + }, + { + "cell_type": "markdown", + "id": "2c603783", + "metadata": {}, + "source": [ + "# Optuna" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "a17b8b66", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-09 17:13:21,142]\u001b[0m A new study created in memory with name: no-name-44cee810-24ee-4f4d-af33-ba725d146103\u001b[0m\n", + "\u001b[32m[I 2022-12-09 17:15:14,403]\u001b[0m Trial 0 finished with value: 0.025636581479650006 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.023009046673404, 'k': 7, 'loss': 'bpr', 'no_components': 57}. Best is trial 0 with value: 0.025636581479650006.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.025636581479650006\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-09 17:17:17,369]\u001b[0m Trial 1 finished with value: 1.7682698542896463e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.9292650108371142, 'k': 5, 'loss': 'bpr', 'no_components': 54}. Best is trial 0 with value: 0.025636581479650006.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 1.7682698542896463e-06\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-09 17:19:24,650]\u001b[0m Trial 2 finished with value: 5.655503042200033e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8504703081672879, 'k': 9, 'loss': 'bpr', 'no_components': 48}. Best is trial 0 with value: 0.025636581479650006.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 5.655503042200033e-07\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[33m[W 2022-12-09 17:21:00,280]\u001b[0m Trial 3 failed because of the following error: KeyboardInterrupt()\u001b[0m\n", + "Traceback (most recent call last):\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", + " value_or_values = func(trial)\n", + " File \"/tmp/ipykernel_24970/801119696.py\", line 34, in objective\n", + " model.fit(dataset)\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\", line 55, in fit\n", + " self._fit(dataset, *args, **kwargs)\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\", line 71, in _fit\n", + " user_factors, item_factors = fit_als_with_features_together(\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\", line 317, in fit_als_with_features_together\n", + " _fit_combined_factors_on_cpu_inplace(\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\", line 345, in _fit_combined_factors_on_cpu_inplace\n", + " model.solver(\n", + "KeyboardInterrupt\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_24970/801119696.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 43\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[0mstudy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptuna\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_study\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdirection\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'maximize'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 45\u001b[0;31m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobjective\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_trials\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 417\u001b[0m \"\"\"\n\u001b[1;32m 418\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 419\u001b[0;31m _optimize(\n\u001b[0m\u001b[1;32m 420\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 421\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize\u001b[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 65\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn_jobs\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 66\u001b[0;31m _optimize_sequential(\n\u001b[0m\u001b[1;32m 67\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize_sequential\u001b[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 160\u001b[0;31m \u001b[0mfrozen_trial\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_run_trial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 161\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[0;31m# The following line mitigates memory problems that can be occurred in some\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 232\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc_err\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 233\u001b[0m ):\n\u001b[0;32m--> 234\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mfunc_err\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 235\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfrozen_trial\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 236\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 194\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mget_heartbeat_thread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_trial_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_storage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 195\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 196\u001b[0;31m \u001b[0mvalue_or_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 197\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTrialPruned\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[0;31m# TODO(mamu): Handle multi-objective cases.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_24970/801119696.py\u001b[0m in \u001b[0;36mobjective\u001b[0;34m(trial)\u001b[0m\n\u001b[1;32m 32\u001b[0m ),\n\u001b[1;32m 33\u001b[0m fit_features_together=True)\n\u001b[0;32m---> 34\u001b[0;31m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 35\u001b[0m recos = model.recommend(\n\u001b[1;32m 36\u001b[0m \u001b[0musers\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTEST_USERS\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, dataset, *args, **kwargs)\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \"\"\"\n\u001b[0;32m---> 55\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 56\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_fitted\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36m_fit\u001b[0;34m(self, dataset)\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit_features_together\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 71\u001b[0;31m user_factors, item_factors = fit_als_with_features_together(\n\u001b[0m\u001b[1;32m 72\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36mfit_als_with_features_together\u001b[0;34m(model, ui_csr, user_features, item_features, verbose)\u001b[0m\n\u001b[1;32m 315\u001b[0m )\n\u001b[1;32m 316\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 317\u001b[0;31m _fit_combined_factors_on_cpu_inplace(\n\u001b[0m\u001b[1;32m 318\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 319\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36m_fit_combined_factors_on_cpu_inplace\u001b[0;34m(model, ui_csr, user_factors, item_factors, n_user_explicit_factors, n_item_explicit_factors, verbose)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miterations\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mverbose\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m model.solver(\n\u001b[0m\u001b[1;32m 346\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[0muser_factors\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "dataset = Dataset.construct(\n", + " interactions_df=train,\n", + " user_features_df=user_features,\n", + " cat_user_features=[\"sex\", \"age\", \"income\"],\n", + " item_features_df=item_features,\n", + " cat_item_features=[ 'content_type','genre','studios', 'age_feature', 'countries'])\n", + "TEST_USERS = test[Columns.User].unique()\n", + "\n", + "def objective(trial):\n", + "\n", + " model_name = trial.suggest_categorical('recomender', ['LightFM', 'ALS'])\n", + " if model_name == 'LightFM':\n", + " learning_rate = trial.suggest_float('learning_rate', 1e-10, 1)\n", + " k = trial.suggest_int('k', 2, 10)\n", + " loss = trial.suggest_categorical('loss',['logistic', 'bpr', 'warp'])\n", + " no_components = trial.suggest_int('no_components', 32, 64)\n", + " model = LightFMWrapperModel(LightFM(k=k,\n", + " learning_rate=learning_rate,\n", + " loss=loss,\n", + " no_components = no_components), \n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS)\n", + " else:\n", + " factors = trial.suggest_int('factors',32, 64)\n", + " regularization = trial.suggest_float('regularization', 1e-4, 1e-2)\n", + " model = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=factors, \n", + " random_state=RANDOM_STATE, \n", + " num_threads=NUM_THREADS,\n", + " regularization=regularization\n", + " ),\n", + " fit_features_together=True)\n", + " model.fit(dataset)\n", + " recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True)\n", + " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", + " print(\"MAP@10\", metric)\n", + " return metric\n", + "\n", + "study = optuna.create_study(direction = 'maximize')\n", + "study.optimize(objective, n_trials = 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "99aae61e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'recomender': 'LightFM',\n", + " 'learning_rate': 0.08165160206425184,\n", + " 'k': 5,\n", + " 'loss': 'warp'}" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "study.best_params" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "1d149ce9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([203219, 505244, 200197, ..., 226430, 857162, 697262])" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "TEST_USERS" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "0c778c15", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dataset(user_id_map=IdMap(external_ids=array([176549, 699317, 656683, ..., 882138, 805174, 648596])), item_id_map=IdMap(external_ids=array([ 9506, 1659, 7107, ..., 13516, 13019, 10542])), interactions=Interactions(df= user_id item_id weight last_watch_dt\n", + "0 0 0 4.0 2021-05-11\n", + "1 1 1 5.0 2021-05-29\n", + "2 2 2 1.0 2021-05-09\n", + "3 3 3 5.0 2021-07-05\n", + "4 4 0 5.0 2021-04-30\n", + "... ... ... ... ...\n", + "5476244 69618 219 5.0 2021-08-02\n", + "5476245 40050 132 1.0 2021-05-12\n", + "5476246 896762 318 1.0 2021-08-13\n", + "5476247 206582 2546 3.0 2021-04-13\n", + "5476249 7236 1609 5.0 2021-04-19\n", + "\n", + "[4984443 rows x 4 columns]), user_features=SparseFeatures(values=<896763x17 sparse matrix of type ''\n", + "\twith 2091336 stored elements in Compressed Sparse Row format>, names=(('sex', 'М'), ('sex', 'Ж'), ('sex', 'Unknown'), ('age', 'age_25_34'), ('age', 'age_18_24'), ('age', 'age_45_54'), ('age', 'age_35_44'), ('age', 'age_55_64'), ('age', 'age_65_inf'), ('age', 'Unknown'), ('income', 'income_60_90'), ('income', 'income_20_40'), ('income', 'income_40_60'), ('income', 'income_90_150'), ('income', 'income_0_20'), ('income', 'Unknown'), ('income', 'income_150_inf'))), item_features=SparseFeatures(values=<15464x96 sparse matrix of type ''\n", + "\twith 54961 stored elements in Compressed Sparse Row format>, names=(('content_type', 'film'), ('content_type', 'series'), ('genre', 'драмы'), ('genre', 'зарубежные'), ('genre', 'детективы'), ('genre', 'мелодрамы'), ('genre', 'приключения'), ('genre', 'комедии'), ('genre', 'криминал'), ('genre', 'триллеры'), ('genre', 'боевики'), ('genre', 'спорт'), ('genre', 'советские'), ('genre', 'фильмы'), ('genre', 'сказки'), ('genre', 'семейное'), ('genre', 'фэнтези'), ('genre', 'для детей'), ('genre', 'полнометражные'), ('genre', 'западные мультфильмы'), ('genre', 'русские'), ('genre', 'биография'), ('genre', 'экранизации'), ('genre', 'исторические'), ('genre', 'военные'), ('genre', 'ужасы'), ('genre', 'мистика'), ('genre', 'фильмы-спектакли'), ('genre', 'мюзиклы'), ('genre', 'короткометражные'), ('genre', 'детские'), ('genre', 'вестерн'), ('genre', 'мультфильмы'), ('genre', 'для взрослых'), ('genre', 'мультфильм'), ('genre', 'фантастика'), ('genre', 'документальное'), ('genre', 'историческое'), ('genre', 'концерт'), ('genre', 'познавательные'), ('genre', 'сериалы'), ('genre', 'про животных'), ('genre', 'музыка'), ('genre', 'реалити-шоу'), ('genre', 'фитнес'), ('genre', 'телешоу'), ('genre', 'научно-популярные'), ('genre', 'ток-шоу'), ('genre', 'молодежные'), ('genre', 'стендап'), ('genre', 'хочу всё знать'), ('genre', 'русские мультфильмы'), ('genre', 'развитие'), ('genre', 'детские песни'), ('genre', 'аниме'), ('genre', 'музыкальные'), ('genre', 'мультсериалы'), ('genre', 'для самых маленьких'), ('genre', 'no_genre'), ('genre', 'развлекательные'), ('genre', 'караоке'), ('genre', 'фильмы hbo'), ('genre', 'катастрофы'), ('genre', 'медицинские'), ('genre', 'передачи'), ('genre', 'мировая классика'), ('genre', 'артхаус'), ('genre', 'дорамы'), ('genre', 'воспитание детей'), ('genre', 'короткий метр'), ('genre', 'интервью'), ('genre', 'по комиксам'), ('genre', 'увлечения'), ('genre', 'охота и рыбалка'), ('genre', 'популярное'), ('genre', 'реалити'), ('genre', 'футбол'), ('genre', 'романтика'), ('genre', 'фильм-нуар'), ('genre', 'тележурналы'), ('genre', 'живая природа'), ('genre', 'немое кино'), ('genre', 'единоборства'), ('genre', 'шоу'), ('genre', 'юмор'), ('genre', 'вокруг света'), ('genre', 'анимация'), ('genre', 'кулинария'), ('genre', 'индийское кино'), ('genre', 'о знаменитостях'), ('genre', '18+'), ('genre', 'токшоу'), ('genre', 'комиксы'), ('genre', 'красота и здоровье'), ('genre', 'образование'), ('genre', 'рекомендуем'))))" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "cc9c030d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
547624443858578292021-08-026804100.05
547624578673248802021-05-127530.01
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476249384202161972021-04-196203100.05
\n", + "

4984443 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "0 176549 9506 2021-05-11 4250 72.0 4\n", + "1 699317 1659 2021-05-29 8317 100.0 5\n", + "2 656683 7107 2021-05-09 10 0.0 1\n", + "3 864613 7638 2021-07-05 14483 100.0 5\n", + "4 964868 9506 2021-04-30 6725 100.0 5\n", + "... ... ... ... ... ... ...\n", + "5476244 438585 7829 2021-08-02 6804 100.0 5\n", + "5476245 786732 4880 2021-05-12 753 0.0 1\n", + "5476246 648596 12225 2021-08-13 76 0.0 1\n", + "5476247 546862 9673 2021-04-13 2308 49.0 3\n", + "5476249 384202 16197 2021-04-19 6203 100.0 5\n", + "\n", + "[4984443 rows x 6 columns]" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "id": "5e5009e5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywordsgenre
41644filmОчень женские историиUnknown2020.0мелодрамы, русские, комедииРоссияUnknown18.0UnknownАнна Саруханова, Антон Бильжо, Лика Ятковская,...[анастасия пронина, анна михалкова, анна слю, ...Киноальманах из пяти короткометражных фильмов,...[очень, женские, истории, 2020, россия, друзья...[мелодрамы, русские, комедии]
\n", + "
" + ], + "text/plain": [ + " item_id content_type title title_orig release_year \\\n", + "4164 4 film Очень женские истории Unknown 2020.0 \n", + "\n", + " genres countries for_kids age_rating studios \\\n", + "4164 мелодрамы, русские, комедии Россия Unknown 18.0 Unknown \n", + "\n", + " directors \\\n", + "4164 Анна Саруханова, Антон Бильжо, Лика Ятковская,... \n", + "\n", + " actors \\\n", + "4164 [анастасия пронина, анна михалкова, анна слю, ... \n", + "\n", + " description \\\n", + "4164 Киноальманах из пяти короткометражных фильмов,... \n", + "\n", + " keywords \\\n", + "4164 [очень, женские, истории, 2020, россия, друзья... \n", + "\n", + " genre \n", + "4164 [мелодрамы, русские, комедии] " + ] + }, + "execution_count": 120, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items[items['item_id'] == 4]" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "id": "a30929c1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idageincomesexkids_flg
1496621age_25_34income_20_40Ж1
\n", + "
" + ], + "text/plain": [ + " user_id age income sex kids_flg\n", + "149662 1 age_25_34 income_20_40 Ж 1" + ] + }, + "execution_count": 125, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users[users['user_id'] == 1]" + ] + }, + { + "cell_type": "markdown", + "id": "43411998", + "metadata": {}, + "source": [ + " ## Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. " + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "62bf8c5b", + "metadata": { + "collapsed": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: nmslib in /home/rezarayev/anaconda3/lib/python3.8/site-packages (2.1.1)\n", + "Collecting pybind11<2.6.2\n", + " Using cached pybind11-2.6.1-py2.py3-none-any.whl (188 kB)\n", + "Requirement already satisfied: psutil in /home/rezarayev/anaconda3/lib/python3.8/site-packages (from nmslib) (5.8.0)\n", + "Requirement already satisfied: numpy>=1.10.0 in /home/rezarayev/anaconda3/lib/python3.8/site-packages (from nmslib) (1.22.2)\n", + "\u001b[33mWARNING: Error parsing requirements for pybind11: [Errno 2] Нет такого файла или каталога: '/home/rezarayev/anaconda3/lib/python3.8/site-packages/pybind11-2.9.2.dist-info/METADATA'\u001b[0m\n", + "Installing collected packages: pybind11\n", + " Attempting uninstall: pybind11\n", + " Found existing installation: pybind11 2.9.2\n", + "\u001b[31mERROR: Could not install packages due to an OSError: [Errno 2] Нет такого файла или каталога: '/home/rezarayev/anaconda3/lib/python3.8/site-packages/pybind11-2.9.2.dist-info/RECORD'\n", + "\u001b[0m\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install nmslib" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "2aa5abcf", + "metadata": {}, + "outputs": [], + "source": [ + "import nmslib\n", + "import time" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "id": "62d4c831", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Dataset(user_id_map=IdMap(external_ids=array([ 176549, 699317, 864613, ..., 92876, 1007900, 882138])), item_id_map=IdMap(external_ids=array([ 9506, 1659, 7638, ..., 14064, 11002, 10542])), interactions=Interactions(df= user_id item_id weight last_watch_dt\n", + "0 0 0 4.0 2021-05-11\n", + "1 1 1 5.0 2021-05-29\n", + "3 2 2 5.0 2021-07-05\n", + "4 3 0 5.0 2021-04-30\n", + "5 4 3 5.0 2021-05-13\n", + "... ... ... ... ...\n", + "5476242 233253 46 5.0 2021-04-21\n", + "5476244 54444 166 5.0 2021-08-02\n", + "5476245 173668 100 1.0 2021-05-12\n", + "5476247 165648 2141 3.0 2021-04-13\n", + "5476249 115506 1328 5.0 2021-04-19\n", + "\n", + "[3832259 rows x 4 columns]), user_features=SparseFeatures(values=<756545x17 sparse matrix of type ''\n", + "\twith 1759959 stored elements in Compressed Sparse Row format>, names=(('sex', 'М'), ('sex', 'Ж'), ('sex', 'Unknown'), ('age', 'age_25_34'), ('age', 'age_18_24'), ('age', 'age_45_54'), ('age', 'age_35_44'), ('age', 'age_55_64'), ('age', 'age_65_inf'), ('age', 'Unknown'), ('income', 'income_60_90'), ('income', 'income_20_40'), ('income', 'income_40_60'), ('income', 'income_90_150'), ('income', 'income_0_20'), ('income', 'Unknown'), ('income', 'income_150_inf'))), item_features=SparseFeatures(values=<13963x809 sparse matrix of type ''\n", + "\twith 91980 stored elements in Compressed Sparse Row format>, names=(('content_type', 'film'), ('content_type', 'series'), ('genre', 'драмы'), ('genre', 'зарубежные'), ('genre', 'детективы'), ('genre', 'мелодрамы'), ('genre', 'приключения'), ('genre', 'комедии'), ('genre', 'криминал'), ('genre', 'триллеры'), ('genre', 'боевики'), ('genre', 'спорт'), ('genre', 'советские'), ('genre', 'фильмы'), ('genre', 'сказки'), ('genre', 'семейное'), ('genre', 'фэнтези'), ('genre', 'для детей'), ('genre', 'полнометражные'), ('genre', 'западные мультфильмы'), ('genre', 'русские'), ('genre', 'биография'), ('genre', 'экранизации'), ('genre', 'исторические'), ('genre', 'военные'), ('genre', 'ужасы'), ('genre', 'мистика'), ('genre', 'фильмы-спектакли'), ('genre', 'мюзиклы'), ('genre', 'короткометражные'), ('genre', 'детские'), ('genre', 'вестерн'), ('genre', 'мультфильмы'), ('genre', 'для взрослых'), ('genre', 'мультфильм'), ('genre', 'фантастика'), ('genre', 'документальное'), ('genre', 'историческое'), ('genre', 'концерт'), ('genre', 'познавательные'), ('genre', 'музыка'), ('genre', 'реалити-шоу'), ('genre', 'фитнес'), ('genre', 'телешоу'), ('genre', 'научно-популярные'), ('genre', 'ток-шоу'), ('genre', 'молодежные'), ('genre', 'стендап'), ('genre', 'хочу всё знать'), ('genre', 'про животных'), ('genre', 'русские мультфильмы'), ('genre', 'развитие'), ('genre', 'аниме'), ('genre', 'музыкальные'), ('genre', 'сериалы'), ('genre', 'детские песни'), ('genre', 'мультсериалы'), ('genre', 'для самых маленьких'), ('genre', 'no_genre'), ('genre', 'развлекательные'), ('genre', 'караоке'), ('genre', 'фильмы hbo'), ('genre', 'катастрофы'), ('genre', 'медицинские'), ('genre', 'передачи'), ('genre', 'мировая классика'), ('genre', 'артхаус'), ('genre', 'дорамы'), ('genre', 'воспитание детей'), ('genre', 'короткий метр'), ('genre', 'интервью'), ('genre', 'по комиксам'), ('genre', 'увлечения'), ('genre', 'охота и рыбалка'), ('genre', 'популярное'), ('genre', 'реалити'), ('genre', 'футбол'), ('genre', 'романтика'), ('genre', 'фильм-нуар'), ('genre', 'тележурналы'), ('genre', 'живая природа'), ('genre', 'немое кино'), ('genre', 'единоборства'), ('genre', 'шоу'), ('genre', 'юмор'), ('genre', 'вокруг света'), ('genre', 'анимация'), ('genre', 'кулинария'), ('genre', 'о знаменитостях'), ('genre', 'индийское кино'), ('genre', '18+'), ('genre', 'токшоу'), ('genre', 'комиксы'), ('genre', 'красота и здоровье'), ('genre', 'образование'), ('genre', 'рекомендуем'), ('studios', 'Unknown'), ('studios', 'Ленфильм'), ('studios', 'Sony Pictures'), ('studios', 'Starz'), ('studios', 'BBC'), ('studios', 'Ленфильм, рентв'), ('studios', 'HBO'), ('studios', 'Paramount'), ('studios', 'Universal'), ('studios', 'Sky'), ('studios', 'Cinemax'), ('studios', 'CBS'), ('studios', 'Sony Plus, рентв'), ('studios', 'FX'), ('studios', 'Sky, Fremantle'), ('studios', 'DAZN'), ('studios', 'Warner Bros'), ('studios', 'Fremantle'), ('studios', 'Sony Pictures, рентв'), ('studios', 'Fox'), ('studios', 'HBO, BBC'), ('studios', 'Мосфильм'), ('studios', 'Showtime'), ('studios', 'Endemol'), ('studios', 'Sony Pictures Television'), ('studios', 'CBS All Access'), ('studios', 'ABC'), ('studios', 'Universal, рентв'), ('studios', 'Amediateka'), ('studios', 'Рок фильм'), ('studios', 'Disney'), ('studios', 'HBO Max'), ('studios', 'Warner Bros. Television'), ('studios', 'MGM'), ('studios', 'Legendary'), ('studios', 'рентв'), ('studios', 'Channel 4'), ('studios', 'New Regency Productions'), ('studios', 'Sony Plus'), ('age_feature', 16.0), ('age_feature', 12.0), ('age_feature', 6.0), ('age_feature', 18.0), ('age_feature', 0.0), ('age_feature', 21.0), ('age_feature', nan), ('countries', 'Испания'), ('countries', 'США'), ('countries', 'Канада'), ('countries', 'Великобритания'), ('countries', 'СССР'), ('countries', 'Россия'), ('countries', 'Германия'), ('countries', 'Италия'), ('countries', 'Аргентина'), ('countries', 'Франция'), ('countries', 'Украина'), ('countries', 'США, Германия, Япония, Великобритания'), ('countries', 'Швеция'), ('countries', 'Норвегия'), ('countries', 'Германия, Канада'), ('countries', 'Россия, Италия, Швеция'), ('countries', 'Чехия'), ('countries', 'Китай, Япония, Тайвань, Республика Корея'), ('countries', 'Израиль'), ('countries', 'Великобритания, Франция'), ('countries', 'Дания, Швеция, США, Великобритания, Аргентина, Германия, Исландия, Испания'), ('countries', 'Бельгия'), ('countries', 'США, Канада'), ('countries', 'Франция, Бельгия'), ('countries', 'Республика Корея'), ('countries', 'Новая Зеландия'), ('countries', 'Австралия'), ('countries', 'Мексика'), ('countries', 'Великобритания, США'), ('countries', 'Швеция, Испания, США'), ('countries', 'США, Великобритания'), ('countries', 'Нидерланды, Великобритания'), ('countries', 'США, Германия'), ('countries', 'Япония'), ('countries', 'Китай'), ('countries', 'Великобритания, Швеция, Германия'), ('countries', 'США, Китай, Германия, Япония'), ('countries', 'Великобритания, США, Китай'), ('countries', 'Кипр'), ('countries', 'Маврикий'), ('countries', 'Казахстан'), ('countries', 'США, Гонконг'), ('countries', 'США, Китай, Япония'), ('countries', 'Ирландия'), ('countries', 'Германия, Норвегия'), ('countries', 'Болгария, Великобритания'), ('countries', 'Россия, Беларусь'), ('countries', 'Италия, СССР'), ('countries', 'США, Румыния'), ('countries', 'Франция, США'), ('countries', 'Россия, США'), ('countries', 'США, Китай'), ('countries', 'США, Мальта'), ('countries', 'США, Великобритания, Австралия'), ('countries', 'Великобритания, США, Канада'), ('countries', 'США, Болгария'), ('countries', 'Нидерланды'), ('countries', 'Чили'), ('countries', 'Армения'), ('countries', 'Германия, Франция'), ('countries', 'Канада, Франция'), ('countries', 'США, Мексика, Австралия, Канада'), ('countries', 'США, Мексика'), ('countries', 'США, Индия'), ('countries', 'Таиланд'), ('countries', 'Канада, США'), ('countries', 'Великобритания, Франция, США, Китай, Венгрия'), ('countries', 'Франция, Сенегал'), ('countries', 'Бразилия, Канада'), ('countries', 'США, Великобритания, Япония, Германия'), ('countries', 'Ирландия, Великобритания'), ('countries', 'США, Германия, Япония'), ('countries', 'США, Великобритания, Канада, Китай'), ('countries', 'США, Япония'), ('countries', 'Италия, Франция'), ('countries', 'Гонконг'), ('countries', 'Беларусь'), ('countries', 'Польша'), ('countries', 'Испания, США'), ('countries', 'Германия, Франция, Италия'), ('countries', 'Австралия, США'), ('countries', 'Нидерланды, Чехия'), ('countries', 'Германия, Бельгия, Люксембург, Ирландия, США'), ('countries', 'Франция, Великобритания, Чехия'), ('countries', 'США, Ирландия'), ('countries', 'Китай, Гонконг'), ('countries', 'Норвегия, Великобритания'), ('countries', 'Россия, Украина'), ('countries', 'Россия, Украина, Беларусь'), ('countries', 'Дания'), ('countries', 'Великобритания, Австралия, США'), ('countries', 'США, Испания'), ('countries', 'Турция'), ('countries', 'ЮАР'), ('countries', 'Швейцария'), ('countries', 'США, Великобритания, Германия'), ('countries', 'США, Франция, Великобритания'), ('countries', 'Швейцария, Великобритания, США'), ('countries', 'Ирландия, Великобритания, Германия, Швеция'), ('countries', 'Дания, Швеция, Нидерланды'), ('countries', 'Македония'), ('countries', 'Великобритания, Канада'), ('countries', 'Индия'), ('countries', 'Финляндия'), ('countries', 'Франция, Республика Корея, Япония'), ('countries', 'Узбекистан'), ('countries', 'Малайзия'), ('countries', 'США, ОАЭ, Чехия'), ('countries', 'США, Австралия'), ('countries', 'Австралия, Россия'), ('countries', 'США, Франция'), ('countries', 'Испания, Мальта, Болгария'), ('countries', 'Португалия, Германия, Дания, США, Франция'), ('countries', 'Испания, Болгария'), ('countries', 'Бразилия'), ('countries', 'Дания, Швеция, Франция, Германия'), ('countries', 'Франция, Германия, США'), ('countries', 'Великобритания, США, Франция'), ('countries', 'Франция, Австралия'), ('countries', 'Канада, США, Индия, Великобритания'), ('countries', 'Германия, США'), ('countries', 'США, Канада, Новая Зеландия'), ('countries', 'Испания, Германия'), ('countries', 'Великобритания, Франция, Германия, США'), ('countries', 'США, Великобритания, Япония'), ('countries', 'Венгрия'), ('countries', 'США, Швеция, ЮАР'), ('countries', 'Казахстан, Россия, Франция'), ('countries', 'Франция, Канада'), ('countries', 'США, Швейцария, Великобритания'), ('countries', 'США, Республика Корея'), ('countries', 'Бельгия, Франция'), ('countries', 'Франция, Бельгия, Германия'), ('countries', 'Польша, Великобритания, Франция'), ('countries', 'США, Франция, Япония'), ('countries', 'Россия, Испания'), ('countries', 'Филиппины'), ('countries', 'Великобритания, Австралия'), ('countries', 'США, Бразилия'), ('countries', 'Пуэрто-Рико, Великобритания, США'), ('countries', 'Испания, Канада'), ('countries', 'Великобритания, Канада, Ирландия'), ('countries', 'Португалия'), ('countries', 'Германия, Бельгия, Великобритания, Дания'), ('countries', 'Чехия, Великобритания, Германия, США'), ('countries', 'Франция, Германия, ЮАР'), ('countries', 'Канада, Ирландия, Великобритания, США'), ('countries', 'Италия, Германия'), ('countries', 'Перу'), ('countries', 'Франция, Канада, США'), ('countries', 'Австралия, Бельгия'), ('countries', 'Латвия'), ('countries', 'Австрия, Германия'), ('countries', 'Киргизия'), ('countries', 'Великобритания, Швеция, Дания, Ирландия'), ('countries', 'Швеция, Норвегия, Германия'), ('countries', 'Алжир, США'), ('countries', 'Дания, Чехия'), ('countries', 'Великобритания, Нидерланды'), ('countries', 'Дания, Швеция, Франция, Нидерланды, Италия, Испания'), ('countries', 'Австралия, Канада'), ('countries', nan), ('countries', 'Великобритания, Франция, Германия'), ('countries', 'Франция, Великобритания, Венгрия'), ('countries', 'Дания, Швеция, Франция, Нидерланды, Норвегия, Исландия, Испания'), ('countries', 'США, ЮАР, Великобритания'), ('countries', 'Великобритания, Румыния'), ('countries', 'Великобритания, Дания'), ('countries', 'Колумбия'), ('countries', 'Румыния'), ('countries', 'Гонконг, Китай'), ('countries', 'США, Финляндия'), ('countries', 'Ирландия, Бельгия, Дания, Канада'), ('countries', 'Австралия, Франция'), ('countries', 'США, Франция, Италия'), ('countries', 'Испания, Япония'), ('countries', 'США, Гонконг, Исландия'), ('countries', 'Франция, Германия, США, Великобритания'), ('countries', 'Австрия'), ('countries', 'Венесуэла'), ('countries', 'США, Великобритания, Италия'), ('countries', 'США, Великобритания, Канада'), ('countries', 'Аргентина, Уругвай, Россия, Германия, Франция, Нидерланды'), ('countries', 'Мексика, США'), ('countries', 'Россия, Беларусь, Польша'), ('countries', 'Германия, Франция, Великобритания, Канада, США, Япония'), ('countries', 'Индонезия, США'), ('countries', 'США, Германия, Канада'), ('countries', 'Китай, США'), ('countries', 'Ирландия, Бельгия'), ('countries', 'Германия, Великобритания, США'), ('countries', 'Дания, Канада, Швеция, США, Франция'), ('countries', 'США, Великобритания, Франция'), ('countries', 'США, Франция, Бельгия, Нидерланды, Латвия'), ('countries', 'Хорватия'), ('countries', 'США, Франция, Великобритания, Италия'), ('countries', 'Австралия, Новая Зеландия'), ('countries', 'Ирландия, Испания'), ('countries', 'Канада, США, Великобритания'), ('countries', 'Новая Зеландия, США'), ('countries', 'США, Великобритания, Франция, Венгрия, Германия'), ('countries', 'Индия, Великобритания, Китай, Канада, Япония, Республика Корея, США'), ('countries', 'Швеция, Дания'), ('countries', 'Великобритания, США, Индия, Канада, Франция, Бельгия'), ('countries', 'Япония, Сингапур'), ('countries', 'Великобритания, Испания, Германия, США'), ('countries', 'Аргентина, Испания, Бразилия, Германия'), ('countries', 'США, Аргентина, Гонконг, Канада'), ('countries', 'Индонезия'), ('countries', 'США, Италия, Румыния, Великобритания'), ('countries', 'Великобритания, Франция, Китай, Камбоджа, США, Германия'), ('countries', 'Дания, Норвегия, Венгрия, Чехия'), ('countries', 'Япония, США'), ('countries', 'США, Канада, Гонконг'), ('countries', 'Германия, Великобритания, США, Канада'), ('countries', 'США, Чехия'), ('countries', 'Италия, Испания'), ('countries', 'Франция, Италия'), ('countries', 'Парагвай'), ('countries', 'Россия, Франция'), ('countries', 'Великобритания, Франция, США'), ('countries', 'Великобритания, Китай, Япония, США'), ('countries', 'Франция, Бельгия, Люксембург'), ('countries', 'США, Бельгия'), ('countries', 'Сербия, СССР'), ('countries', 'США, Нидерланды, Аргентина, Франция'), ('countries', 'Швеция, США'), ('countries', 'Великобритания, Швеция, Франция, Бельгия'), ('countries', 'Россия, Сербия'), ('countries', 'США, Великобритания, Чехия, Канада'), ('countries', 'Россия, Германия, Франция'), ('countries', 'Франция, Польша, Бельгия'), ('countries', 'Франция, Великобритания'), ('countries', 'Испания, Аргентина'), ('countries', 'Германия, Индия, США'), ('countries', 'Великобритания, Германия, США'), ('countries', 'США, Канада, Франция'), ('countries', 'Франция, Япония'), ('countries', 'Австралия, Китай, Германия, США'), ('countries', 'Великобритания, США, Индия'), ('countries', 'Дания, Норвегия, Германия'), ('countries', 'Великобритания, Нидерланды, Франция, Италия, Япония'), ('countries', 'Молдова'), ('countries', 'Германия, Китай'), ('countries', 'Дания, США'), ('countries', 'Великобритания, Испания'), ('countries', 'Швеция, Дания, США'), ('countries', 'Австралия, Германия'), ('countries', 'Великобритания, Франция, США, Канада'), ('countries', 'Исландия, Дания, Швеция'), ('countries', 'США, Великобритания, Франция, Германия, Япония'), ('countries', 'Эстония'), ('countries', 'США, Армения'), ('countries', 'Франция, Польша'), ('countries', 'Нидерланды, Люксембург, Великобритания'), ('countries', 'Россия, Люксембург'), ('countries', 'США, Канада, Индия'), ('countries', 'США, Германия, Франция'), ('countries', 'США, Франция, Бельгия, Чехия'), ('countries', 'Албания'), ('countries', 'Бельгия, Великобритания, Германия'), ('countries', 'Болгария'), ('countries', 'Испания, Португалия, Франция'), ('countries', 'Канада, Республика Корея, США'), ('countries', 'Великобритания, Италия'), ('countries', 'США, Чили, Израиль'), ('countries', 'Мексика, Франция'), ('countries', 'Великобритания, Ирландия, Франция, США'), ('countries', 'Великобритания, Новая Зеландия'), ('countries', 'Бельгия, Люксембург, Франция'), ('countries', 'Аргентина, Испания'), ('countries', 'США, Гонконг, Канада, Китай'), ('countries', 'США, Китай, Канада, Австралия'), ('countries', 'Швеция, СССР, Норвегия'), ('countries', 'Австралия, Великобритания'), ('countries', 'США, Канада, Австралия'), ('countries', 'Канада, Китай, США'), ('countries', 'Россия, Великобритания, Австрия'), ('countries', 'США, Австралия, Мексика'), ('countries', 'США, Япония, Испания, Великобритания'), ('countries', 'США, Россия'), ('countries', 'США, ОАЭ'), ('countries', 'Великобритания, США, Китай, Швеция, Япония'), ('countries', 'Франция, Испания, Румыния, Бельгия, США'), ('countries', 'Гонконг, США'), ('countries', 'Великобритания, Китай, США'), ('countries', 'Нидерланды, Великобритания, Польша, Украина, США'), ('countries', 'Дания, Германия, Франция, Бельгия'), ('countries', 'США, Новая Зеландия'), ('countries', 'Великобритания, Германия, Испания, США'), ('countries', 'Испания, Франция'), ('countries', 'Исландия'), ('countries', 'США, Германия, Великобритания, Нидерланды, Италия'), ('countries', 'Индия, Сингапур, США'), ('countries', 'США, Канада, Великобритания'), ('countries', 'Ирландия, Швеция, США'), ('countries', 'Швейцария, Германия, Португалия'), ('countries', 'Германия, Австрия, Италия'), ('countries', 'Великобритания, Франция, Германия, Ирландия, США'), ('countries', 'США, Великобритания, Япония, Венгрия'), ('countries', 'Великобритания, Канада, США'), ('countries', 'Сингапур'), ('countries', 'Франция, США, Бразилия'), ('countries', 'Китай, Канада, США'), ('countries', 'Россия, Турция'), ('countries', 'Хорватия, Люксембург, Норвегия, Чехия, Словакия, Словения'), ('countries', 'Германия, Австралия'), ('countries', 'Австралия, Колумбия'), ('countries', 'Россия, Казахстан'), ('countries', 'Австрия, Россия'), ('countries', 'Эквадор, Испания, Перу'), ('countries', 'Франция, Великобритания, США'), ('countries', 'Сербия'), ('countries', 'Швеция, Германия, Норвегия, Дания, Исландия, Бельгия, Великобритания'), ('countries', 'Великобритания, Ирландия, Канада, США, Индия'), ('countries', 'США, ЮАР'), ('countries', 'Тайвань'), ('countries', 'Мальта'), ('countries', 'Бельгия, Люксембург'), ('countries', 'Франция, Китай'), ('countries', 'США, Канада, Франция, Великобритания, Индия'), ('countries', 'Армения, Грузия, США'), ('countries', 'Канада, Испания, Япония'), ('countries', 'Канада, Республика Корея'), ('countries', 'Испания, Болгария, США'), ('countries', 'Испания, США, Франция'), ('countries', 'США, Норвегия'), ('countries', 'Великобритания, Германия'), ('countries', 'США, Франция, Канада, Испания'), ('countries', 'США, Камбоджа'), ('countries', 'США, Великобритания, Мальта, Марокко'), ('countries', 'Аргентина, Мексика'), ('countries', 'Франция, Люксембург, Бельгия'), ('countries', 'Великобритания, США, Германия'), ('countries', 'Великобритания, Германия, США, Испания'), ('countries', 'США, Германия, Польша'), ('countries', 'США, Великобритания, Ирландия'), ('countries', 'Индия, США'), ('countries', 'Канада, Бельгия'), ('countries', 'Норвегия, США, Великобритания'), ('countries', 'Россия, Украина, Великобритания'), ('countries', 'Италия, Бельгия'), ('countries', 'Иран'), ('countries', 'Германия, Япония, США, Великобритания'), ('countries', 'США, Германия, Чехия'), ('countries', 'Великобритания, Ирландия'), ('countries', 'Россия, Тунис'), ('countries', 'Великобритания, Финляндия, Германия, США, Франция'), ('countries', 'США, Германия, Китай, Канада'), ('countries', 'Польша, СССР'), ('countries', 'США, Нидерланды'), ('countries', 'Ирландия, США'), ('countries', 'Бельгия, Великобритания, Ирландия, США'), ('countries', 'США, Швеция, Венгрия'), ('countries', 'Великобритания, Мексика, США'), ('countries', 'США, Канада, Австралия, Тайвань'), ('countries', 'США, Греция'), ('countries', 'Германия, Канада, США'), ('countries', 'США, Бельгия, Дания, Великобритания, Швеция, Китай'), ('countries', 'Бельгия, Германия'), ('countries', 'Германия, Франция, Испания, США'), ('countries', 'Германия, Россия'), ('countries', 'Ирландия, Франция'), ('countries', 'Германия, Дания, Франция, Швеция'), ('countries', 'Франция, США, Германия'), ('countries', 'США, Китай, Великобритания'), ('countries', 'США, Филиппины, Пуэрто-Рико'), ('countries', 'США, Германия, Гонконг, Сингапур'), ('countries', 'Великобритания, Люксембург'), ('countries', 'Швейцария, Франция'), ('countries', 'Великобритания, Германия, Франция'), ('countries', 'Франция, США, Испания'), ('countries', 'Швеция, Канада'), ('countries', 'Россия, Латвия, Великобритания, Австрия'), ('countries', 'Новая Зеландия, США, Германия'), ('countries', 'Германия, США, Мексика'), ('countries', 'Ирландия, Канада'), ('countries', 'Швеция, Великобритания, Франция, Испания, Россия'), ('countries', 'Чехия, Великобритания'), ('countries', 'Словения'), ('countries', 'США, Канада, Китай'), ('countries', 'США, Новая Зеландия, Германия'), ('countries', 'Россия, Канада, Грузия, Греция'), ('countries', 'Индия, Китай'), ('countries', 'Дания, Норвегия, Чехия'), ('countries', 'Канада, Венгрия'), ('countries', 'Дания, Латвия, Россия, США'), ('countries', 'Ирландия, Франция, Исландия, США, Мексика, Бельгия, Великобритания, Гонконг'), ('countries', 'Иран, Ливан'), ('countries', 'Франция, Испания'), ('countries', 'Франция, СССР'), ('countries', 'Германия, Италия'), ('countries', 'Куба, Испания'), ('countries', 'Великобритания, США, Испания'), ('countries', 'Уругвай, Аргентина, Германия, Испания, Нидерланды'), ('countries', 'Италия, Люксембург, Бельгия'), ('countries', 'США, Индия, Великобритания, Франция, Канада, Германия'), ('countries', 'Болгария, США'), ('countries', 'Испания, США, Италия'), ('countries', 'США, Великобритания, Китай'), ('countries', 'Россия, Грузия'), ('countries', 'США, Германия, Великобритания, Франция'), ('countries', 'Азербайджан'), ('countries', 'Великобритания, Австралия, США, Новая Зеландия'), ('countries', 'США, Индия, Канада'), ('countries', 'Германия, Франция, Бельгия, ЮАР, Италия, Великобритания, Люксембург'), ('countries', 'США, Германия, Великобритания'), ('countries', 'Франция, Германия'), ('countries', 'Великобритания, Чехия, Германия, США'), ('countries', 'Финляндия, Латвия'), ('countries', 'Германия, Бельгия, Франция'), ('countries', 'США, Испания, Франция, Великобритания'), ('countries', 'США, Великобритания, Германия, Нидерланды, Франция, Италия, Марокко, Таиланд'), ('countries', 'Великобритания, ЮАР'), ('countries', 'Аргентина, США'), ('countries', 'Великобритания, Румыния, США'), ('countries', 'Франция, Польша, Великобритания'), ('countries', 'Мексика, Тайвань, Великобритания, США, Япония, Италия'), ('countries', 'Австралия, США, Канада, Великобритания'), ('countries', 'Великобритания, Канада, Норвегия, США'), ('countries', 'Великобритания, США, Германия, Дания, Бельгия, Япония'), ('countries', 'Франция, Италия, Тунис'), ('countries', 'Бельгия, Великобритания'), ('countries', 'Канада, Великобритания'), ('countries', 'Франция, Бельгия, США'), ('countries', 'Китай, США, Канада'), ('countries', 'Россия, Франция, Германия, Бельгия'), ('countries', 'Иордания'), ('countries', 'Германия, Франция, ЮАР'), ('countries', 'Бразилия, Германия'), ('countries', 'Германия, Франция, США, Канада, Великобритания'), ('countries', 'США, Канада, Италия'), ('countries', 'Болгария, Великобритания, США'), ('countries', 'США, Мексика, Испания'), ('countries', 'Грузия, Украина'), ('countries', 'Турция, США'), ('countries', 'Армения, Россия'), ('countries', 'Беларусь, Украина'), ('countries', 'Великобритания, США, Австралия'), ('countries', 'США, Венгрия'), ('countries', 'Япония, США, Франция'), ('countries', 'Великобритания, США, Япония'), ('countries', 'Япония, Канада'), ('countries', 'Дания, Швеция, Франция, Италия, Германия, Исландия'), ('countries', 'Португалия, Великобритания'), ('countries', 'США, Канада, Венгрия'), ('countries', 'США, Япония, Мексика, Канада'), ('countries', 'Россия, Беларусь, Чехия, Франция, Польша, Израиль'), ('countries', 'Колумбия, США'), ('countries', 'Швеция, Дания, Финляндия'), ('countries', 'Германия, Бельгия'), ('countries', 'Италия, Франция, Великобритания, Швейцария'), ('countries', 'Великобритания, Германия, Люксембург'), ('countries', 'США, Тайвань, Великобритания, Канада'), ('countries', 'Россия, Армения'), ('countries', 'США, Швейцария'), ('countries', 'США, Аргентина, Мексика'), ('countries', 'Норвегия, США'), ('countries', 'Германия, Великобритания'), ('countries', 'Китай, Франция'), ('countries', 'США, Германия, Канада, Великобритания'), ('countries', 'Бельгия, Германия, Швеция'), ('countries', 'Германия, СССР'), ('countries', 'Бразилия, Франция'), ('countries', 'США, Великобритания, Австралия, Канада'), ('countries', 'Испания, Великобритания, Франция, США'), ('countries', 'Германия, Канада, США, Франция, Великобритания'), ('countries', 'США, Китай, Канада'), ('countries', 'ЮАР, Япония, США'), ('countries', 'США, ЮАР, Замбия, Германия'), ('countries', 'Китай, США, Индия'), ('countries', 'Нидерланды, Перу'), ('countries', 'Великобритания, США, Франция, Испания, Италия'), ('countries', 'Испания, Франция, Италия'), ('countries', 'Великобритания, Польша'), ('countries', 'Италия, Испания, Великобритания'), ('countries', 'Япония, Россия'), ('countries', 'США, Малайзия, Португалия'), ('countries', 'США, Ливан'), ('countries', 'Греция'), ('countries', 'США, Япония, Великобритания'), ('countries', 'Канада, Финляндия'), ('countries', 'Индия, Мексика'), ('countries', 'США, Польша'), ('countries', 'Великобритания, США, Румыния'), ('countries', 'Германия, Норвегия, Швеция'), ('countries', 'Япония, Китай'), ('countries', 'Дания, Швеция'), ('countries', 'Япония, СССР'), ('countries', 'Великобритания, СССР'), ('countries', 'США, Великобритания, Канада, Бельгия'), ('countries', 'ЮАР, США'), ('countries', 'Франция, Бельгия, Китай'), ('countries', 'Уругвай, Аргентина, Испания'), ('countries', 'Финляндия, Россия'), ('countries', 'Франция, Израиль, Германия'), ('countries', 'Франция, Россия'), ('countries', 'США, Канада, Люксембург'), ('countries', 'Великобритания, США, Швеция'), ('countries', 'США, Великобритания, Германия, Чехия'), ('countries', 'США, Италия'), ('countries', 'США, Франция, Чехия'), ('countries', 'США, Германия, Франция, Испания'), ('countries', 'Дания, Швеция, Франция, Германия, Швейцария, Испания'), ('countries', 'США, Германия, Венгрия'), ('countries', 'Германия, Испания'), ('countries', 'Казахстан, Турция'), ('countries', 'США, Россия, Венгрия'), ('countries', 'Ирландия, Великобритания, Германия'), ('countries', 'Германия, Люксембург'), ('countries', 'Тунис, Швейцария, Франция'), ('countries', 'Великобритания, Ирландия, Канада, США'), ('countries', 'Бельгия, Великобритания, Ирландия'), ('countries', 'Канада, Великобритания, США'), ('countries', 'Ирландия, Великобритания, США'), ('countries', 'СССР, Франция'), ('countries', 'Швеция, Бельгия'), ('countries', 'Россия, Азербайджан'), ('countries', 'Дания, Швеция, Чехия'), ('countries', 'Великобритания, Франция, Канада, Бельгия, США'), ('countries', 'Бельгия, Франция, Великобритания'), ('countries', 'Великобритания, Венгрия, США'), ('countries', 'Россия, Китай'), ('countries', 'Россия, Германия, Казахстан, Франция'), ('countries', 'Чехия, Германия, Сингапур, США'), ('countries', 'Бразилия, Уругвай, Дания, Норвегия'), ('countries', 'Эстония, Россия'), ('countries', 'Германия, Австрия'), ('countries', 'Германия, Бельгия, США'), ('countries', 'Австрия, Венгрия'), ('countries', 'США, Германия, Бельгия'), ('countries', 'Франция, Бельгия, Италия'), ('countries', 'США, Исландия, Великобритания'), ('countries', 'Украина, Беларусь'), ('countries', 'США, Великобритания, Индия, Испания, Канада'), ('countries', 'Швеция, Германия, Франция, Дания, США'), ('countries', 'Великобритания, Сербия'), ('countries', 'Франция, Чехия'), ('countries', 'США, Польша, Словения, Чехия'), ('countries', 'Испания, Канада, Франция'), ('countries', 'Россия, Франция, Германия'), ('countries', 'Канада, Китай'), ('countries', 'Франция, Чили'), ('countries', 'Великобритания, США, Франция, Венгрия, Нидерланды'), ('countries', 'Германия, Канада, Великобритания'), ('countries', 'Дания, Франция, Швеция, Германия, Бельгия, Тунис'), ('countries', 'Россия, Норвегия'), ('countries', 'Индия, Канада'), ('countries', 'Германия, Великобритания, Италия, Испания'), ('countries', 'Италия, Люксембург, Франция, Бельгия'), ('countries', 'США, Канада, Филиппины, Великобритания, Республика Корея, Франция'), ('countries', 'Канада, США, Великобритания, Австралия'), ('countries', 'Ирландия, США, Великобритания, Швеция, Бельгия'), ('countries', 'Бельгия, Нидерланды'), ('countries', 'Германия, Испания, Тайвань'), ('countries', 'Россия, Великобритания'), ('countries', 'США, Канада, Китай, Япония'), ('countries', 'Великобритания, Испания, США'), ('countries', 'Великобритания, Чехия, США, Германия'), ('countries', 'США, Нидерланды, Великобритания'), ('countries', 'США, Канада, Япония'), ('countries', 'Россия, Латвия'), ('countries', 'Великобритания, Франция, Германия, Мексика, США'), ('countries', 'Вьетнам'), ('countries', 'Германия, Франция, Бельгия'), ('countries', 'Италия, США'), ('countries', 'Германия, Швеция, США, Венгрия'), ('countries', 'Франция, Норвегия'), ('countries', 'Дания, Нидерланды, Швеция, Германия, Великобритания, Франция, Финляндия, Норвегия, Италия'), ('countries', 'Чехия, Словакия, Хорватия'), ('countries', 'США, Таиланд'), ('countries', 'Чили, Аргентина, Бразилия'), ('countries', 'Нидерланды, Великобритания, Франция, Люксембург, Австрия'), ('countries', 'Чили, США'), ('countries', 'Дания, Швейцария'), ('countries', 'Чехия, Великобритания, США'), ('countries', 'Мексика, США, Канада'), ('countries', 'США, Китай, Гонконг, Австралия, Канада'), ('countries', 'США, Канада, Япония, Франция'), ('countries', 'Великобритания, Пуэрто-Рико'), ('countries', 'США, Япония, Колумбия'), ('countries', 'Испания, Великобритания, Нидерланды'), ('countries', 'Германия, США, Франция, Австралия, Великобритания'), ('countries', 'Япония, Китай, Республика Корея'), ('countries', 'Люксембург'), ('countries', 'США, Германия, Мексика'), ('countries', 'Республика Корея, Канада'), ('countries', 'Франция, США, Мексика'), ('countries', 'Великобритания, Германия, Дания, США'), ('countries', 'Аргентина, США, Чили, Перу, Бразилия, Великобритания, Германия, Франция'), ('countries', 'Великобритания, Бельгия'), ('countries', 'США, Германия, Италия'), ('countries', 'Чехия, Словакия'), ('countries', 'Гонконг, Канада, США'), ('countries', 'Россия, Нидерланды'), ('countries', 'Дания, Великобритания'), ('countries', 'Канада, Мексика, Германия'), ('countries', 'Германия, Ирландия, США'), ('countries', 'Великобритания, Норвегия'), ('countries', 'Великобритания, Чехия, Франция, Италия, США'), ('countries', 'Великобритания, Испания, Германия'), ('countries', 'Дания, Швеция, Италия, Франция, Германия'), ('countries', 'США, Германия, Великобритания, Венгрия'), ('countries', 'Китай, Тайвань, Гонконг'), ('countries', 'Коста-Рика'), ('countries', 'Россия, Болгария'), ('countries', 'Дания, Франция, США, Швеция, Бельгия'), ('countries', 'Мексика, Индия, США'), ('countries', 'США, Китай, Бразилия'), ('countries', 'США, Германия, Великобритания, Испания'), ('countries', 'Дания, Швеция, Нидерланды, Франция, Германия, Великобритания, Италия, США'), ('countries', 'Грузия'), ('countries', 'Португалия, США'), ('countries', 'Швеция, Дания, Германия, Финляндия, Франция, Великобритания, Италия'), ('countries', 'Великобритания, США, Венгрия'), ('countries', 'США, Великобритания, Венгрия'), ('countries', 'Дания, Норвегия, Чехия, Исландия, Швеция'), ('countries', 'США, Великобритания, Испания'), ('countries', 'Великобритания, Россия'), ('countries', 'Италия, Испания, Германия'), ('countries', 'Кения, Индия, США'), ('countries', 'Франция, Испания, США'), ('countries', 'США, Франция, Китай, Великобритания'), ('countries', 'Дания, Норвегия, Швеция, Исландия'), ('countries', 'Швеция, СССР'), ('countries', 'Бельгия, Франция, Ирландия'), ('countries', 'США, Германия, Ирландия, Великобритания'), ('countries', 'США, Индия, Франция'), ('countries', 'Сербия, Великобритания, США, Аргентина'), ('countries', 'Великобритания, Япония'), ('countries', 'Великобритания, Франция, Испания, США'), ('countries', 'США, ЮАР, Индия'), ('countries', 'Бельгия, США, Франция, Италия'), ('countries', 'Республика Корея, Чехия'), ('countries', 'Ирландия, Бельгия, США'), ('countries', 'Венгрия, Великобритания, Франция, Австралия, США, Новая Зеландия'), ('countries', 'Республика Корея, Китай'), ('countries', 'Австралия, Швеция'), ('countries', 'Россия, Украина, Германия, Великобритания, Чехия'), ('countries', 'Норвегия, Швеция, Дания'), ('countries', 'Германия, Индия, Австралия'), ('countries', 'Иран, Франция, Германия, Швейцария'), ('countries', 'Испания, Франция, Швеция, Аргентина'), ('countries', 'Франция, Республика Корея, Испания'), ('countries', 'Венгрия, Дания, Норвегия, Чехия'), ('countries', 'Россия, Япония, Эстония'), ('countries', 'ОАЭ'), ('countries', 'Франция, Иран'), ('countries', 'Чехия, СССР'), ('countries', 'Германия, Люксембург, Дания'), ('countries', 'Испания, Бельгия'), ('countries', 'США, Чехия, Великобритания'), ('countries', 'Япония, Великобритания'), ('countries', 'Ирландия, Великобритания, Греция, Франция, Нидерланды'), ('countries', 'Великобритания, Австрия'), ('countries', 'Норвегия, Швеция, Дания, Германия'), ('countries', 'Россия, Литва, Ирландия'), ('countries', 'Бельгия, Канада'), ('countries', 'Италия, Франция, Великобритания'), ('countries', 'Германия, Франция, Польша'), ('countries', 'Канада, США, Франция, Германия, Великобритания'), ('countries', 'Великобритания, Франция, Австралия'), ('countries', 'США, Германия, Чехия, Великобритания'), ('countries', 'Германия, США, Нидерланды'), ('countries', 'США, Франция, Канада'), ('countries', 'Испания, США, Чехия'), ('countries', 'Финляндия, Германия'))))" + ] + }, + "execution_count": 126, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "e0dfa8e8", + "metadata": {}, + "outputs": [], + "source": [ + "user_embeddings, item_embeddings = model.get_vectors(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "91a20b08", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((756545, 34), (13963, 34))" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings.shape, item_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "3634fd78", + "metadata": {}, + "outputs": [], + "source": [ + "def augment_inner_product(factors):\n", + " normed_factors = np.linalg.norm(factors, axis=1)\n", + " max_norm = normed_factors.max()\n", + " \n", + " extra_dim = np.sqrt(max_norm ** 2 - normed_factors ** 2).reshape(-1, 1)\n", + " augmented_factors = np.append(factors, extra_dim, axis=1)\n", + " return max_norm, augmented_factors" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "c2668a0d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pre shape: (13963, 34)\n" + ] + }, + { + "data": { + "text/plain": [ + "(13963, 35)" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print('pre shape: ', item_embeddings.shape)\n", + "max_norm, augmented_item_embeddings = augment_inner_product(item_embeddings)\n", + "augmented_item_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "16fb4a95", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(756545, 35)" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "extra_zero = np.zeros((user_embeddings.shape[0], 1))\n", + "augmented_user_embeddings = np.append(user_embeddings, extra_zero, axis=1)\n", + "augmented_user_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "8d3d96d3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-3.57730194e+02, 1.00000000e+00, -2.26793036e-01, -3.82283032e-02,\n", + " -2.24665195e-01, 2.79386699e-01, 4.53218251e-01, 7.11198449e-01,\n", + " -3.75804901e-01, -1.72303200e-01, 2.92628944e-01, -1.33832023e-01,\n", + " -2.28909120e-01, -3.57735574e-01, -3.30191135e-01, 1.64654672e-01,\n", + " 9.00539607e-02, -4.77109384e-03, -3.73476028e-01, -3.36808801e-01,\n", + " -2.85889745e-01, 3.30380827e-01, 5.07512987e-02, -1.93970263e-01,\n", + " 5.27234077e-02, -1.03786469e-01, 2.36950964e-02, -3.96105945e-01,\n", + " -2.38289386e-01, -4.49349046e-01, 4.56677824e-01, 1.46467835e-01,\n", + " -2.78142452e-01, -4.42725003e-01])" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_id = 30\n", + "user_embeddings[user_id]" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "a3abdc5a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-3.57730194e+02, 1.00000000e+00, -2.26793036e-01, -3.82283032e-02,\n", + " -2.24665195e-01, 2.79386699e-01, 4.53218251e-01, 7.11198449e-01,\n", + " -3.75804901e-01, -1.72303200e-01, 2.92628944e-01, -1.33832023e-01,\n", + " -2.28909120e-01, -3.57735574e-01, -3.30191135e-01, 1.64654672e-01,\n", + " 9.00539607e-02, -4.77109384e-03, -3.73476028e-01, -3.36808801e-01,\n", + " -2.85889745e-01, 3.30380827e-01, 5.07512987e-02, -1.93970263e-01,\n", + " 5.27234077e-02, -1.03786469e-01, 2.36950964e-02, -3.96105945e-01,\n", + " -2.38289386e-01, -4.49349046e-01, 4.56677824e-01, 1.46467835e-01,\n", + " -2.78142452e-01, -4.42725003e-01, 0.00000000e+00])" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "augmented_user_embeddings[user_id]" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "b4d804fe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1. , 3.20644975, -0.28407601, 0.04007996, -1.09869027,\n", + " 1.66705382, 1.70660424, 2.58876157, -1.66243601, -1.03955173,\n", + " 1.49190485, -0.31513208, -0.32752386, -2.05019426, -0.32129809,\n", + " 2.38546944, 2.56410718, 0.10934736, -2.01597881, -1.75085366,\n", + " -2.90048265, 2.37181401, -1.49925196, -1.98518109, 1.68892503,\n", + " 0.41754866, 0.90933883, -2.91862941, -2.08309627, -2.04692388,\n", + " 3.48958254, 1.95236182, -2.21343875, -2.94543052])" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "item_id = 0\n", + "item_embeddings[item_id]" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "2e0030f1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1. , 3.20644975, -0.28407601, 0.04007996, -1.09869027,\n", + " 1.66705382, 1.70660424, 2.58876157, -1.66243601, -1.03955173,\n", + " 1.49190485, -0.31513208, -0.32752386, -2.05019426, -0.32129809,\n", + " 2.38546944, 2.56410718, 0.10934736, -2.01597881, -1.75085366,\n", + " -2.90048265, 2.37181401, -1.49925196, -1.98518109, 1.68892503,\n", + " 0.41754866, 0.90933883, -2.91862941, -2.08309627, -2.04692388,\n", + " 3.48958254, 1.95236182, -2.21343875, -2.94543052, 7.11584563])" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "augmented_item_embeddings[item_id]" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "id": "19104d9a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index-time parameters {'M': 48, 'indexThreadQty': 4, 'efConstruction': 100, 'post': 0}\n" + ] + } + ], + "source": [ + "M = 48\n", + "efC = 100\n", + "\n", + "num_threads = 4\n", + "index_time_params = {'M': M, 'indexThreadQty': num_threads, 'efConstruction': efC, 'post' : 0}\n", + "print('Index-time parameters', index_time_params)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "3634ebbb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13963" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "K=10\n", + "space_name='negdotprod'\n", + "index = nmslib.init(method='hnsw', space=space_name, data_type=nmslib.DataType.DENSE_VECTOR) \n", + "index.addDataPointBatch(augmented_item_embeddings) " + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "6d423d8d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index-time parameters {'M': 48, 'indexThreadQty': 4, 'efConstruction': 100}\n", + "Indexing time = 0.282692\n" + ] + } + ], + "source": [ + "start = time.time()\n", + "index_time_params = {'M': M, 'indexThreadQty': num_threads, 'efConstruction': efC}\n", + "index.createIndex(index_time_params) \n", + "end = time.time() \n", + "print('Index-time parameters', index_time_params)\n", + "print('Indexing time = %f' % (end-start))" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "9dc1529f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setting query-time parameters {'efSearch': 100}\n" + ] + } + ], + "source": [ + "efS = 100\n", + "query_time_params = {'efSearch': efS}\n", + "print('Setting query-time parameters', query_time_params)\n", + "index.setQueryTimeParams(query_time_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "0fff67a2", + "metadata": {}, + "outputs": [], + "source": [ + "query_matrix = augmented_user_embeddings[:1000, :]" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "1cdffc65", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "kNN time total=0.023291 (sec), per query=0.000023 (sec), per query adjusted for thread number=0.000093 (sec)\n" + ] + } + ], + "source": [ + "query_qty = query_matrix.shape[0]\n", + "start = time.time() \n", + "nbrs = index.knnQueryBatch(query_matrix, k = K, num_threads = num_threads)\n", + "end = time.time() \n", + "print('kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' % \n", + " (end-start, float(end-start)/query_qty, num_threads*float(end-start)/query_qty)) \n" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "d94de743", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 43, 32, 19, 62, 31, 112, 305, 188, 268, 948], dtype=int32),\n", + " array([304.80273, 304.95447, 305.16202, 305.32443, 305.47067, 305.5135 ,\n", + " 305.6464 , 305.6903 , 305.73453, 305.78738], dtype=float32))" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nbrs[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "5be5c93c", + "metadata": {}, + "outputs": [], + "source": [ + "def recommend_all(query_factors, index_factors, topn=10):\n", + " output = query_factors.dot(index_factors.T)\n", + " argpartition_indices = np.argpartition(output, -topn)[:, -topn:]\n", + "\n", + " x_indices = np.repeat(np.arange(output.shape[0]), topn)\n", + " y_indices = argpartition_indices.flatten()\n", + " top_value = output[x_indices, y_indices].reshape(output.shape[0], topn)\n", + " top_indices = np.argsort(top_value)[:, ::-1]\n", + "\n", + " y_indices = top_indices.flatten()\n", + " top_indices = argpartition_indices[x_indices, y_indices]\n", + " labels = top_indices.reshape(-1, topn)\n", + " distances = output[x_indices, top_indices].reshape(-1, topn)\n", + " return labels, distances\n" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "id": "e9988091", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 19, 31, 121, 32, 43, 268, 120, 62, 103, 173]])" + ] + }, + "execution_count": 108, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labels,_ = recommend_all(user_embeddings[[], :], item_embeddings)\n", + "labels" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "id": "3c722149", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([], shape=(0, 34), dtype=float64)" + ] + }, + "execution_count": 112, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings[[], :]" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "id": "d300a815", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-3.24551971e+02, 1.00000000e+00, 8.73963833e-02, ...,\n", + " -1.30321786e-01, 1.82629615e-01, -3.07083875e-01],\n", + " [-3.24792297e+02, 1.00000000e+00, 3.87268960e-01, ...,\n", + " -4.32303697e-02, -4.72983688e-01, -1.79986209e-01],\n", + " [-3.01102661e+02, 1.00000000e+00, -1.63965374e-01, ...,\n", + " -1.01540364e-01, 1.10484377e-01, -2.40944147e-01],\n", + " ...,\n", + " [-3.58453766e+02, 1.00000000e+00, -1.08767882e-01, ...,\n", + " 2.43232936e-01, -1.24036551e-01, -4.88389194e-01],\n", + " [-2.99490662e+02, 1.00000000e+00, -3.04439873e-01, ...,\n", + " -2.42081508e-02, -3.93126070e-01, -2.91359007e-01],\n", + " [-3.10774689e+02, 1.00000000e+00, -2.57401466e-01, ...,\n", + " -3.03505287e-02, -4.26894128e-01, -3.11958164e-01]])" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15d49fe7", + "metadata": {}, + "outputs": [], + "source": [ + "labels" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "d6c68dd7", + "metadata": {}, + "outputs": [], + "source": [ + "query_matrix_not_augmented = user_embeddings[:1000, :]" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "id": "b7d9dd1f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "207 ms ± 6.37 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "labels,_ = recommend_all(query_matrix_not_augmented, item_embeddings)\n", + "print(labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "id": "904846a6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((1000, 34), (756545, 34))" + ] + }, + "execution_count": 92, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "item_embeddings[:1000, :].shape, user_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "d6027ae4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7.88 ms ± 368 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "index.knnQueryBatch(query_matrix, k = K, num_threads = num_threads)" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "id": "901b82c3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting hnswlib\n", + " Downloading hnswlib-0.6.2.tar.gz (31 kB)\n", + " Installing build dependencies ... \u001b[?25ldone\n", + "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", + "\u001b[?25h Preparing wheel metadata ... \u001b[?25ldone\n", + "\u001b[?25hRequirement already satisfied: numpy in /home/rezarayev/anaconda3/lib/python3.8/site-packages (from hnswlib) (1.22.2)\n", + "Building wheels for collected packages: hnswlib\n", + " Building wheel for hnswlib (PEP 517) ... \u001b[?25ldone\n", + "\u001b[?25h Created wheel for hnswlib: filename=hnswlib-0.6.2-cp38-cp38-linux_x86_64.whl size=2038858 sha256=51c4c2849d71105958f418c5961215d8cac3027e3f96cab05899827043a3d43d\n", + " Stored in directory: /home/rezarayev/.cache/pip/wheels/74/3b/89/4bd924865709f24ac2df457bcca4c0b55a3eb89c5a94ce3ce8\n", + "Successfully built hnswlib\n", + "\u001b[33mWARNING: Error parsing requirements for pybind11: [Errno 2] Нет такого файла или каталога: '/home/rezarayev/anaconda3/lib/python3.8/site-packages/pybind11-2.9.2.dist-info/METADATA'\u001b[0m\n", + "Installing collected packages: hnswlib\n", + "Successfully installed hnswlib-0.6.2\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install hnswlib" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "id": "e6b0be91", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[-304.80272148 -304.95450166 -305.1620535 ... -305.69031591\n", + " -305.73454442 -305.7874324 ]\n", + " [-311.19933349 -311.44323422 -311.45526998 ... -312.0948194\n", + " -312.21820321 -312.23901463]\n", + " [-284.3956498 -284.45770448 -284.96237912 ... -285.29546382\n", + " -285.36598349 -285.41208658]\n", + " ...\n", + " [-332.37278335 -332.85525963 -332.98405066 ... -333.36833688\n", + " -333.44008879 -333.48889785]\n", + " [-302.10402324 -302.13324433 -302.3124104 ... -302.86405908\n", + " -302.88296188 -303.00234271]\n", + " [ 14.88806505 14.41715752 14.1114468 ... 13.71272978\n", + " 13.68271151 13.6242354 ]]\n" + ] + } + ], + "source": [ + "labels, distances = recommend_all(user_embeddings[:1000, :], item_embeddings)\n", + "print(labels)\n", + "print(distances)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77fedf20", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ee9ae0adce14a1a7fbe8a7dd657da44af92843a2 Mon Sep 17 00:00:00 2001 From: Shakirov Renat Date: Sun, 11 Dec 2022 17:50:19 +0300 Subject: [PATCH 02/12] add first version notebooks with lightFM --- notebooks/ALS_LightFM_MF.ipynb | 3904 ++++++++++++ notebooks/online_LightFm.ipynb | 877 +++ ...0\275\320\270\320\265 \342\204\2264.ipynb" | 5276 ----------------- poetry.lock | 770 ++- pyproject.toml | 5 + 5 files changed, 5548 insertions(+), 5284 deletions(-) create mode 100644 notebooks/ALS_LightFM_MF.ipynb create mode 100644 notebooks/online_LightFm.ipynb delete mode 100644 "notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" diff --git a/notebooks/ALS_LightFM_MF.ipynb b/notebooks/ALS_LightFM_MF.ipynb new file mode 100644 index 00000000..c1e10c42 --- /dev/null +++ b/notebooks/ALS_LightFM_MF.ipynb @@ -0,0 +1,3904 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7322c9ec", + "metadata": {}, + "source": [ + "# Домашнее задание\n", + "\n", + "Домашнее задание состоит из нескольких блоков.\n", + "\n", + "\n", + "## Эксперименты в ipynb ноутбуках (15 баллов)\n", + "- Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", + " - Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)\n", + "- Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", + " - Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д\n", + "- Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**\n", + "- Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", + "\n", + "Примечание: за невоспроизводимый код в ноутбуках (например, нарушен порядок выполнения ячеек, вызываются переменные, которые нигде не были объявлены ранее и.т.п) будут штрафы на усмотрение проверяющего.\n", + "\n", + "\n", + "## Реализация итоговой модели в сервисе (10 баллов)\n", + "- Пробитие бейзлайна $MAP@10 \\geq 0.074921$ **(6 баллов)**\n", + "- Код сервиса соответствует критериям читаемости и воспроизводимости **(4 балла)**" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "7780d9a2", + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6e60b1cf", + "metadata": {}, + "outputs": [], + "source": [ + "# import sys\n", + "# !{sys.executable} -m pip install rectools=0.3.0" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e42a5585", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import time\n", + "from pathlib import Path\n", + "\n", + "import numpy as np\n", + "import optuna\n", + "import pandas as pd\n", + "\n", + "# import nmslib\n", + "from implicit.als import AlternatingLeastSquares\n", + "from lightfm import LightFM\n", + "from rectools import Columns\n", + "from rectools.dataset import Dataset\n", + "from rectools.metrics import MAP, Precision, Recall, calc_metrics\n", + "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "46bfbe38", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'item_id'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Columns.Item" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "8cd36e1a", + "metadata": {}, + "outputs": [], + "source": [ + "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"\n", + "Columns.Datetime = 'last_watch_dt'\n", + "DATA_PATH = Path(\"../data/kion_train/\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8195e56b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.23 s, sys: 464 ms, total: 2.69 s\n", + "Wall time: 2.9 s\n" + ] + } + ], + "source": [ + "%%time\n", + "users = pd.read_csv(DATA_PATH / 'users.csv')\n", + "items = pd.read_csv(DATA_PATH / 'items.csv')\n", + "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" + ] + }, + { + "cell_type": "markdown", + "id": "00b5584e", + "metadata": {}, + "source": [ + "# Preprocess Interactions" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "0a3b4b12", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct\n", + "0 176549 9506 2021-05-11 4250 72.0\n", + "1 699317 1659 2021-05-29 8317 100.0\n", + "2 656683 7107 2021-05-09 10 0.0\n", + "3 864613 7638 2021-07-05 14483 100.0\n", + "4 964868 9506 2021-04-30 6725 100.0" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.head(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "260b1c48", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id int64\n", + "item_id int64\n", + "last_watch_dt object\n", + "total_dur int64\n", + "watched_pct float64\n", + "dtype: object" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "fe2dbc06", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id 0\n", + "item_id 0\n", + "last_watch_dt 0\n", + "total_dur 0\n", + "watched_pct 828\n", + "dtype: int64" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Количество пустых значений в каждой колонке\n", + "interactions.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "71f61e81", + "metadata": {}, + "outputs": [], + "source": [ + "interactions[Columns.Datetime] = pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')\n", + "interactions.dropna(inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f98ae95d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "interactions['watched_pct'].hist(bins=20);" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "aa7af6a8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
..................
5476246648596122252021-08-13760.0
547624754686296732021-04-13230849.0
5476248697262152972021-08-201830763.0
5476249384202161972021-04-196203100.0
547625031970944362021-08-15392145.0
\n", + "

5475423 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct\n", + "0 176549 9506 2021-05-11 4250 72.0\n", + "1 699317 1659 2021-05-29 8317 100.0\n", + "2 656683 7107 2021-05-09 10 0.0\n", + "3 864613 7638 2021-07-05 14483 100.0\n", + "4 964868 9506 2021-04-30 6725 100.0\n", + "... ... ... ... ... ...\n", + "5476246 648596 12225 2021-08-13 76 0.0\n", + "5476247 546862 9673 2021-04-13 2308 49.0\n", + "5476248 697262 15297 2021-08-20 18307 63.0\n", + "5476249 384202 16197 2021-04-19 6203 100.0\n", + "5476250 319709 4436 2021-08-15 3921 45.0\n", + "\n", + "[5475423 rows x 5 columns]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions" + ] + }, + { + "cell_type": "markdown", + "id": "1a0ad9f8", + "metadata": {}, + "source": [ + "Разбиваем длительность просмотра на 5 частей, где:\n", + " - от 0% до 20% = 1,\n", + " - от 21% до 40% = 2,\n", + " - ... ,\n", + " - от 80% до 100% = 5" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "1424e744", + "metadata": {}, + "outputs": [], + "source": [ + "interactions[Columns.Weight] = pd.cut(\n", + " x=interactions['watched_pct'],\n", + " bins=5,\n", + " labels=[1, 2, 3, 4, 5]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "052d2fb0", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "interactions[Columns.Datetime].hist(bins=20);" + ] + }, + { + "cell_type": "markdown", + "id": "5adb80ee", + "metadata": {}, + "source": [ + "Видно, что кол-во пользователей растет" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "0fbd2bbc", + "metadata": {}, + "outputs": [], + "source": [ + "cold_users = interactions[Columns.User].value_counts()\n", + "cold_users = cold_users[cold_users < 3].index" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "150e1593", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'].hist(bins=20);" + ] + }, + { + "cell_type": "markdown", + "id": "b5fa83eb", + "metadata": {}, + "source": [ + "Для холодных пользователей, мы бы рекомендовали айтемы с самый высоким просмотром в среднем по холодным пользователям" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "cca06e3f", + "metadata": {}, + "outputs": [], + "source": [ + "cold_users_interactions = interactions[interactions[Columns.User].isin(cold_users)]\n", + "hot_users_interactions = interactions[~interactions[Columns.User].isin(cold_users)]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "422d0455", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "shape cold_users_interactions - 650696\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
16646903162282021-07-235737546.03
22505244152972021-08-151599163.04
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "10 791466 8199 2021-07-27 713 9.0 1\n", + "16 646903 16228 2021-07-23 57375 46.0 3\n", + "22 505244 15297 2021-08-15 15991 63.0 4\n", + "26 181144 10440 2021-08-08 27408 40.0 2\n", + "37 161176 10440 2021-07-29 22 0.0 1" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print('shape cold_users_interactions -', cold_users_interactions.shape[0])\n", + "cold_users_interactions.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "a691676f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "shape hot_users_interactions - 4824727\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "0 176549 9506 2021-05-11 4250 72.0 4\n", + "1 699317 1659 2021-05-29 8317 100.0 5\n", + "2 656683 7107 2021-05-09 10 0.0 1\n", + "3 864613 7638 2021-07-05 14483 100.0 5\n", + "4 964868 9506 2021-04-30 6725 100.0 5" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print('shape hot_users_interactions -', hot_users_interactions.shape[0])\n", + "hot_users_interactions.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "a64701c2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_id
1044069181
1529764307
972828294
265725592
1386522653
\n", + "
" + ], + "text/plain": [ + " item_id\n", + "10440 69181\n", + "15297 64307\n", + "9728 28294\n", + "2657 25592\n", + "13865 22653" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users_interactions['item_id'].value_counts().to_frame().head()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "cef9cfa6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([609, 3825, 4895, 5069, 2271, 11566, 13390, 9954, 5733, 7434], dtype='int64', name='item_id')" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " cold_users_interactions[['item_id', 'total_dur']]\n", + " .groupby('item_id')\n", + " .mean()\n", + " .sort_values(by='total_dur', ascending=False)\n", + " .head(10)\n", + " .index\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a52f311b", + "metadata": {}, + "source": [ + "# Делим на train и test" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "bd68d3fe", + "metadata": {}, + "outputs": [], + "source": [ + "max_date = hot_users_interactions[Columns.Datetime].max()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "3092fe4b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: (4984443, 6)\n", + "test: (490980, 6)\n" + ] + } + ], + "source": [ + "train = interactions[interactions[Columns.Datetime] < max_date - pd.Timedelta(days=7)].copy()\n", + "test = interactions[interactions[Columns.Datetime] >= max_date - pd.Timedelta(days=7)].copy()\n", + "\n", + "print(f\"train: {train.shape}\")\n", + "print(f\"test: {test.shape}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "ec286bdc", + "metadata": {}, + "outputs": [], + "source": [ + "train.drop(train.query(\"total_dur < 300\").index, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "c32fcaae", + "metadata": {}, + "outputs": [], + "source": [ + "drop_user = set(test[Columns.User]) - set(train[Columns.User])" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "7183cb6f", + "metadata": {}, + "outputs": [], + "source": [ + "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "1ff85593", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
9203219135822021-08-226975100.05
5420019793352021-08-16832.01
6473446144882021-08-196011100.05
84100105122021-08-15140.01
94890735142002021-08-16117928.02
.....................
54761695895899832021-08-21240343.03
547618859089286182021-08-21133523.02
5476191857162123602021-08-16110.01
5476201273558106052021-08-2134030100.05
547625031970944362021-08-15392145.03
\n", + "

333022 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "9 203219 13582 2021-08-22 6975 100.0 5\n", + "54 200197 9335 2021-08-16 83 2.0 1\n", + "64 73446 14488 2021-08-19 6011 100.0 5\n", + "84 10010 512 2021-08-15 14 0.0 1\n", + "94 890735 14200 2021-08-16 1179 28.0 2\n", + "... ... ... ... ... ... ...\n", + "5476169 589589 983 2021-08-21 2403 43.0 3\n", + "5476188 590892 8618 2021-08-21 1335 23.0 2\n", + "5476191 857162 12360 2021-08-16 11 0.0 1\n", + "5476201 273558 10605 2021-08-21 34030 100.0 5\n", + "5476250 319709 4436 2021-08-15 3921 45.0 3\n", + "\n", + "[333022 rows x 6 columns]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test" + ] + }, + { + "cell_type": "markdown", + "id": "b5eec6da", + "metadata": {}, + "source": [ + "# User preprocess" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "c57e2b2f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
\n", + "
" + ], + "text/plain": [ + " user_id age income sex kids_flg\n", + "0 973171 age_25_34 income_60_90 М 1\n", + "1 962099 age_18_24 income_20_40 М 0\n", + "2 1047345 age_45_54 income_40_60 Ж 0\n", + "3 721985 age_45_54 income_20_40 Ж 0\n", + "4 704055 age_35_44 income_60_90 Ж 0" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "63996e92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id 0.000000\n", + "age 0.016776\n", + "income 0.017586\n", + "sex 0.016462\n", + "kids_flg 0.000000\n", + "dtype: float64" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users.isnull().sum()/840197" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "24cc138a", + "metadata": {}, + "outputs": [], + "source": [ + "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "b2283c6d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
\n", + "
" + ], + "text/plain": [ + " user_id age income sex kids_flg\n", + "0 973171 age_25_34 income_60_90 М 1\n", + "1 962099 age_18_24 income_20_40 М 0\n", + "3 721985 age_45_54 income_20_40 Ж 0\n", + "4 704055 age_35_44 income_60_90 Ж 0\n", + "5 1037719 age_45_54 income_60_90 М 0" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users.head()" + ] + }, + { + "cell_type": "markdown", + "id": "c7f9a6e7", + "metadata": {}, + "source": [ + "Заменяем Nan'ы на Unknown" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "1286eb60", + "metadata": {}, + "outputs": [], + "source": [ + "users.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "1ccccf0f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 973171 М sex\n", + "1 962099 М sex\n", + "3 721985 Ж sex\n", + "4 704055 Ж sex\n", + "5 1037719 М sex" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_features_frames = []\n", + "for feature in [\"sex\", \"age\", \"income\"]:\n", + " feature_frame = users.reindex(columns=[Columns.User, feature])\n", + " feature_frame.columns = [\"id\", \"value\"]\n", + " feature_frame[\"feature\"] = feature\n", + " user_features_frames.append(feature_frame)\n", + "user_features = pd.concat(user_features_frames)\n", + "user_features.head()" + ] + }, + { + "cell_type": "markdown", + "id": "b9220b0b", + "metadata": {}, + "source": [ + "# Item preprocess" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "8bbe9ee4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
6657602filmЧем заняться дома?Chem zanyat'sya doma?2020.0мультфильм, комедииКипрNaN0.0NaNНаумов АртемСаранцева ВаряЧем заняться ребёнку, если никуда не получаетс...2020, кипр, чем, заняться, дома
1231315798filmВ мире динозавровNaN2005.0русские, для детей, хочу всё знать, русские му...РоссияNaN0.0NaNРоберт СаакянцNaNПознавательный мультфильм для детей, рассказыв...мире, динозавров, 2005, Россия, динозавры, пут...
842810616filmРождение нацииThe Birth of a Nation2016.0драмы, биография, историческоеСША, КанадаNaN18.0NaNНэйт ПаркерНэйт Паркер, Арми Хаммер, Пенелопа Энн Миллер,...Историко-драматический байопик о чернокожем ра...южные сша, рабство, биография, основанная на р...
\n", + "
" + ], + "text/plain": [ + " item_id content_type title title_orig \\\n", + "6657 602 film Чем заняться дома? Chem zanyat'sya doma? \n", + "12313 15798 film В мире динозавров NaN \n", + "8428 10616 film Рождение нации The Birth of a Nation \n", + "\n", + " release_year genres \\\n", + "6657 2020.0 мультфильм, комедии \n", + "12313 2005.0 русские, для детей, хочу всё знать, русские му... \n", + "8428 2016.0 драмы, биография, историческое \n", + "\n", + " countries for_kids age_rating studios directors \\\n", + "6657 Кипр NaN 0.0 NaN Наумов Артем \n", + "12313 Россия NaN 0.0 NaN Роберт Саакянц \n", + "8428 США, Канада NaN 18.0 NaN Нэйт Паркер \n", + "\n", + " actors \\\n", + "6657 Саранцева Варя \n", + "12313 NaN \n", + "8428 Нэйт Паркер, Арми Хаммер, Пенелопа Энн Миллер,... \n", + "\n", + " description \\\n", + "6657 Чем заняться ребёнку, если никуда не получаетс... \n", + "12313 Познавательный мультфильм для детей, рассказыв... \n", + "8428 Историко-драматический байопик о чернокожем ра... \n", + "\n", + " keywords \n", + "6657 2020, кипр, чем, заняться, дома \n", + "12313 мире, динозавров, 2005, Россия, динозавры, пут... \n", + "8428 южные сша, рабство, биография, основанная на р... " + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.sample(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "72fa86a0", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "item_id 0\n", + "content_type 0\n", + "title 0\n", + "title_orig 4745\n", + "release_year 98\n", + "genres 0\n", + "countries 37\n", + "for_kids 15397\n", + "age_rating 2\n", + "studios 14898\n", + "directors 1509\n", + "actors 2619\n", + "description 2\n", + "keywords 423\n", + "dtype: int64" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "50f0611f", + "metadata": {}, + "outputs": [], + "source": [ + "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "280cf47d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "item_id 0\n", + "content_type 0\n", + "title 0\n", + "title_orig 3775\n", + "release_year 31\n", + "genres 0\n", + "countries 14\n", + "for_kids 13415\n", + "age_rating 1\n", + "studios 13047\n", + "directors 939\n", + "actors 1858\n", + "description 0\n", + "keywords 388\n", + "dtype: int64" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "markdown", + "id": "eddd93b5", + "metadata": {}, + "source": [ + "# Genre" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "bf6da75c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Explode genres to flatten table\n", + "items[\"genre\"] = items[\"genres\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "genre_feature = items[[\"item_id\", \"genre\"]].explode(\"genre\")\n", + "genre_feature.columns = [\"id\", \"value\"]\n", + "genre_feature[\"feature\"] = \"genre\"\n", + "genre_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "478bf1e3", + "metadata": {}, + "source": [ + "# Content" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "65f8b5d9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 film content_type\n", + "1 2508 film content_type\n", + "2 10716 film content_type\n", + "3 7868 film content_type\n", + "4 16268 film content_type" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", + "content_feature.columns = [\"id\", \"value\"]\n", + "content_feature[\"feature\"] = \"content_type\"\n", + "content_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "a62ebee4", + "metadata": {}, + "source": [ + "# Actors" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "fdc43660", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 адольфо фернандес actors\n", + "0 10711 ана фернандес actors\n", + "0 10711 дарио грандинетти actors\n", + "0 10711 джеральдин чаплин actors\n", + "0 10711 елена анайя actors" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items[\"actors\"] = items[\"actors\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "actors_feature = items[[\"item_id\", \"actors\"]].explode(\"actors\")\n", + "actors_feature.columns = [\"id\", \"value\"]\n", + "actors_feature[\"feature\"] = \"actors\"\n", + "actors_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "73801647", + "metadata": {}, + "source": [ + "# Keywords" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "594abe5c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 поговори keywords\n", + "0 10711 ней keywords\n", + "0 10711 2002 keywords\n", + "0 10711 испания keywords\n", + "0 10711 друзья keywords" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items[\"keywords\"] = items[\"keywords\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "keywords_feature = items[[\"item_id\", \"keywords\"]].explode(\"keywords\")\n", + "keywords_feature.columns = [\"id\", \"value\"]\n", + "keywords_feature[\"feature\"] = \"keywords\"\n", + "keywords_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "d3eb0a37", + "metadata": {}, + "source": [ + "# Countries" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "8eb8a621", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 Испания countries\n", + "1 2508 США countries\n", + "2 10716 Канада countries\n", + "3 7868 Великобритания countries\n", + "4 16268 СССР countries" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "country_feature = items.reindex(columns=[Columns.Item, \"countries\"])\n", + "country_feature.columns = [\"id\", \"value\"]\n", + "country_feature[\"feature\"] = \"countries\"\n", + "country_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "5e477ee1", + "metadata": {}, + "source": [ + "# Age Rating" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "0894154a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 16.0 age_feature\n", + "1 2508 16.0 age_feature\n", + "2 10716 16.0 age_feature\n", + "3 7868 16.0 age_feature\n", + "4 16268 12.0 age_feature" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", + "age_feature.columns = [\"id\", \"value\"]\n", + "age_feature[\"feature\"] = \"age_feature\"\n", + "age_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "c09df1ec", + "metadata": {}, + "source": [ + "# Studios" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "ff937b4f", + "metadata": {}, + "outputs": [], + "source": [ + "items.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "cee42708", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711Unknownstudios
12508Unknownstudios
210716Unknownstudios
37868Unknownstudios
416268Ленфильмstudios
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 Unknown studios\n", + "1 2508 Unknown studios\n", + "2 10716 Unknown studios\n", + "3 7868 Unknown studios\n", + "4 16268 Ленфильм studios" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", + "studios_feature.columns = [\"id\", \"value\"]\n", + "studios_feature[\"feature\"] = \"studios\"\n", + "studios_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "82558d41", + "metadata": {}, + "source": [ + "### Конкатим все доп фичи в один датасет" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "6158b0bd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
27556781Unknownstudios
18859843Unknownstudios
7472690912.0age_feature
339510751для детейgenre
39159872триллерыgenre
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "2755 6781 Unknown studios\n", + "1885 9843 Unknown studios\n", + "7472 6909 12.0 age_feature\n", + "3395 10751 для детей genre\n", + "3915 9872 триллеры genre" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "item_features = pd.concat((genre_feature, content_feature, studios_feature, age_feature, country_feature))\n", + "item_features.sample(5)" + ] + }, + { + "cell_type": "markdown", + "id": "09b8d756", + "metadata": {}, + "source": [ + "# Metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "b082e667", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Precision@1': Precision(k=1),\n", + " 'Precision@2': Precision(k=2),\n", + " 'Precision@3': Precision(k=3),\n", + " 'Precision@4': Precision(k=4),\n", + " 'Precision@5': Precision(k=5),\n", + " 'Precision@6': Precision(k=6),\n", + " 'Precision@7': Precision(k=7),\n", + " 'Precision@8': Precision(k=8),\n", + " 'Precision@9': Precision(k=9),\n", + " 'Precision@10': Precision(k=10),\n", + " 'Recall@1': Recall(k=1),\n", + " 'Recall@2': Recall(k=2),\n", + " 'Recall@3': Recall(k=3),\n", + " 'Recall@4': Recall(k=4),\n", + " 'Recall@5': Recall(k=5),\n", + " 'Recall@6': Recall(k=6),\n", + " 'Recall@7': Recall(k=7),\n", + " 'Recall@8': Recall(k=8),\n", + " 'Recall@9': Recall(k=9),\n", + " 'Recall@10': Recall(k=10),\n", + " 'MAP@1': MAP(k=1, divide_by_k=False),\n", + " 'MAP@2': MAP(k=2, divide_by_k=False),\n", + " 'MAP@3': MAP(k=3, divide_by_k=False),\n", + " 'MAP@4': MAP(k=4, divide_by_k=False),\n", + " 'MAP@5': MAP(k=5, divide_by_k=False),\n", + " 'MAP@6': MAP(k=6, divide_by_k=False),\n", + " 'MAP@7': MAP(k=7, divide_by_k=False),\n", + " 'MAP@8': MAP(k=8, divide_by_k=False),\n", + " 'MAP@9': MAP(k=9, divide_by_k=False),\n", + " 'MAP@10': MAP(k=10, divide_by_k=False)}" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metrics_name = {\n", + " 'Precision': Precision,\n", + " 'Recall': Recall,\n", + " 'MAP': MAP,\n", + "}\n", + "\n", + "metrics = {}\n", + "for metric_name, metric in metrics_name.items():\n", + " for k in range(1, 11):\n", + " metrics[f'{metric_name}@{k}'] = metric(k=k)\n", + "metrics" + ] + }, + { + "cell_type": "markdown", + "id": "0bce189f", + "metadata": {}, + "source": [ + "# Обучение моделей" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "864a7990", + "metadata": {}, + "outputs": [], + "source": [ + "K_RECOS = 10\n", + "RANDOM_STATE = 42\n", + "NUM_THREADS = 8\n", + "N_FACTORS = (32,)\n", + "N_EPOCHS = 1 # Lightfm\n", + "USER_ALPHA = 0 # Lightfm\n", + "ITEM_ALPHA = 0 # Lightfm\n", + "LEARNING_RATE = 0.05 # Lightfm" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "89c1cedb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "user_features - {'income', 'age', 'sex'}\n", + "item_features - {'age_feature', 'countries', 'studios', 'genre', 'content_type'}\n" + ] + } + ], + "source": [ + "print('user_features -', set(user_features.feature))\n", + "print('item_features -', set(item_features.feature))" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "6288eea7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 663 ms, sys: 165 ms, total: 828 ms\n", + "Wall time: 900 ms\n" + ] + } + ], + "source": [ + "%%time\n", + "dataset = Dataset.construct(\n", + " interactions_df=train,\n", + " user_features_df=user_features,\n", + " item_features_df=item_features,\n", + " cat_user_features=[\"sex\", \"age\", \"income\"],\n", + " cat_item_features=['age_feature', 'content_type', 'countries', 'genre', 'studios']\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "d027f149", + "metadata": {}, + "outputs": [], + "source": [ + "TEST_USERS = test[Columns.User].unique()" + ] + }, + { + "cell_type": "markdown", + "id": "b73393d0", + "metadata": {}, + "source": [ + "## Baseline LightFM" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "c99924ca", + "metadata": {}, + "outputs": [], + "source": [ + "model = LightFMWrapperModel(\n", + " LightFM(\n", + " k=5,\n", + " no_components=32,\n", + " loss='warp',\n", + " random_state=RANDOM_STATE,\n", + " learning_rate=0.081651,\n", + " user_alpha=USER_ALPHA,\n", + " item_alpha=ITEM_ALPHA\n", + " ),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "d3907c1d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.fit(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "id": "b2050a6e", + "metadata": {}, + "outputs": [], + "source": [ + "recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "8c7da423", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idscorerank
0203219104406.9803371
1203219152976.9500362
2203219138656.4135013
320321997286.3615484
420321941516.2872445
\n", + "
" + ], + "text/plain": [ + " user_id item_id score rank\n", + "0 203219 10440 6.980337 1\n", + "1 203219 15297 6.950036 2\n", + "2 203219 13865 6.413501 3\n", + "3 203219 9728 6.361548 4\n", + "4 203219 4151 6.287244 5" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recos.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "6bbe3ff3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Precision@1': 0.07467204843592332,\n", + " 'Recall@1': 0.03845573009300656,\n", + " 'Precision@2': 0.0649131658611716,\n", + " 'Recall@2': 0.06533320917725449,\n", + " 'Precision@3': 0.05858575129380801,\n", + " 'Recall@3': 0.08732125781565075,\n", + " 'Precision@4': 0.053242338945244036,\n", + " 'Recall@4': 0.10450467843880465,\n", + " 'Precision@5': 0.04813673942677076,\n", + " 'Recall@5': 0.11660090113349054,\n", + " 'Precision@6': 0.04386112438850237,\n", + " 'Recall@6': 0.12606432618063965,\n", + " 'Precision@7': 0.04029751472525916,\n", + " 'Recall@7': 0.13385118540696275,\n", + " 'Precision@8': 0.037416795014782164,\n", + " 'Recall@8': 0.14120255388899725,\n", + " 'Precision@9': 0.03498445069957099,\n", + " 'Recall@9': 0.14776157788428726,\n", + " 'Precision@10': 0.03296510701577354,\n", + " 'Recall@10': 0.15403037510704012,\n", + " 'MAP@1': 0.03845573009300656,\n", + " 'MAP@2': 0.05246902559206522,\n", + " 'MAP@3': 0.06034291707347781,\n", + " 'MAP@4': 0.06511711937144428,\n", + " 'MAP@5': 0.06788409272317658,\n", + " 'MAP@6': 0.06973275065780024,\n", + " 'MAP@7': 0.071056944551092,\n", + " 'MAP@8': 0.07213601259055538,\n", + " 'MAP@9': 0.0730308574271295,\n", + " 'MAP@10': 0.07379233810864445}" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metric_values = calc_metrics(metrics, recos, test, train)\n", + "metric_values" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "d3eead34", + "metadata": {}, + "outputs": [], + "source": [ + "recos = recos[['user_id', 'item_id']]\n", + "recos.to_csv('../data/base_LightFM.csv.gz', index=False, compression='gzip')" + ] + }, + { + "cell_type": "markdown", + "id": "bb0b92d4", + "metadata": {}, + "source": [ + "## Grid Search ALS and LightFM" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1740223a", + "metadata": {}, + "outputs": [], + "source": [ + "models = {}\n", + "implicit_models = {\n", + " 'ALS': AlternatingLeastSquares,\n", + "}\n", + "for implicit_name, implicit_model in implicit_models.items():\n", + " for is_fitting_features in (True, False):\n", + " for n_factors in N_FACTORS:\n", + " models[f\"{implicit_name}_{n_factors}_{is_fitting_features}\"] = (\n", + " ImplicitALSWrapperModel(\n", + " model=implicit_model(\n", + " factors=n_factors,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " ),\n", + " fit_features_together=is_fitting_features,\n", + " )\n", + " )\n", + "\n", + "for loss in ('logistic', 'bpr', 'warp'): # lightfm losses\n", + " for n_factors in N_FACTORS:\n", + " models[f\"LightFM_{loss}_{n_factors}\"] = LightFMWrapperModel(\n", + " LightFM(\n", + " no_components=n_factors,\n", + " loss=loss,\n", + " random_state=RANDOM_STATE,\n", + " learning_rate=LEARNING_RATE,\n", + " user_alpha=USER_ALPHA,\n", + " item_alpha=ITEM_ALPHA,\n", + " ),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS,\n", + " )\n", + "\n", + "print(models)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "0d5edb2b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting model ALS_32_True...\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", + "File \u001B[0;32m:6\u001B[0m\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/base.py:55\u001B[0m, in \u001B[0;36mModelBase.fit\u001B[0;34m(self, dataset, *args, **kwargs)\u001B[0m\n\u001B[1;32m 42\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mfit\u001B[39m(\u001B[38;5;28mself\u001B[39m: T, dataset: Dataset, \u001B[38;5;241m*\u001B[39margs: tp\u001B[38;5;241m.\u001B[39mAny, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: tp\u001B[38;5;241m.\u001B[39mAny) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m T:\n\u001B[1;32m 43\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 44\u001B[0m \u001B[38;5;124;03m Fit model.\u001B[39;00m\n\u001B[1;32m 45\u001B[0m \n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 53\u001B[0m \u001B[38;5;124;03m self\u001B[39;00m\n\u001B[1;32m 54\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m---> 55\u001B[0m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_fit\u001B[49m\u001B[43m(\u001B[49m\u001B[43mdataset\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43margs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 56\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mis_fitted \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m 57\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:71\u001B[0m, in \u001B[0;36mImplicitALSWrapperModel._fit\u001B[0;34m(self, dataset)\u001B[0m\n\u001B[1;32m 68\u001B[0m ui_csr \u001B[38;5;241m=\u001B[39m dataset\u001B[38;5;241m.\u001B[39mget_user_item_matrix(include_weights\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[1;32m 70\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfit_features_together:\n\u001B[0;32m---> 71\u001B[0m user_factors, item_factors \u001B[38;5;241m=\u001B[39m \u001B[43mfit_als_with_features_together\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 72\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 73\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 74\u001B[0m \u001B[43m \u001B[49m\u001B[43mdataset\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43muser_features\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 75\u001B[0m \u001B[43m \u001B[49m\u001B[43mdataset\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mitem_features\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 76\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mverbose\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 77\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 78\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 79\u001B[0m user_factors, item_factors \u001B[38;5;241m=\u001B[39m fit_als_with_features_separately(\n\u001B[1;32m 80\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmodel,\n\u001B[1;32m 81\u001B[0m ui_csr,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 84\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mverbose,\n\u001B[1;32m 85\u001B[0m )\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:317\u001B[0m, in \u001B[0;36mfit_als_with_features_together\u001B[0;34m(model, ui_csr, user_features, item_features, verbose)\u001B[0m\n\u001B[1;32m 307\u001B[0m _fit_combined_factors_on_gpu_inplace(\n\u001B[1;32m 308\u001B[0m model,\n\u001B[1;32m 309\u001B[0m ui_csr,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 314\u001B[0m verbose,\n\u001B[1;32m 315\u001B[0m )\n\u001B[1;32m 316\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m--> 317\u001B[0m \u001B[43m_fit_combined_factors_on_cpu_inplace\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 318\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 319\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 320\u001B[0m \u001B[43m \u001B[49m\u001B[43muser_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 321\u001B[0m \u001B[43m \u001B[49m\u001B[43mitem_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 322\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_user_explicit_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 323\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_item_explicit_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 324\u001B[0m \u001B[43m \u001B[49m\u001B[43mverbose\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 325\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 327\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m user_factors, item_factors\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:345\u001B[0m, in \u001B[0;36m_fit_combined_factors_on_cpu_inplace\u001B[0;34m(model, ui_csr, user_factors, item_factors, n_user_explicit_factors, n_item_explicit_factors, verbose)\u001B[0m\n\u001B[1;32m 342\u001B[0m iu_csr \u001B[38;5;241m=\u001B[39m ui_csr\u001B[38;5;241m.\u001B[39mT\u001B[38;5;241m.\u001B[39mtocsr(copy\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m)\n\u001B[1;32m 344\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m _ \u001B[38;5;129;01min\u001B[39;00m tqdm(\u001B[38;5;28mrange\u001B[39m(model\u001B[38;5;241m.\u001B[39miterations), disable\u001B[38;5;241m=\u001B[39mverbose \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m0\u001B[39m):\n\u001B[0;32m--> 345\u001B[0m \u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43msolver\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 346\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 347\u001B[0m \u001B[43m \u001B[49m\u001B[43muser_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 348\u001B[0m \u001B[43m \u001B[49m\u001B[43mitem_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 349\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mregularization\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 350\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mnum_threads\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 351\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 352\u001B[0m user_factors[:, :n_user_explicit_factors] \u001B[38;5;241m=\u001B[39m user_explicit_factors\n\u001B[1;32m 354\u001B[0m model\u001B[38;5;241m.\u001B[39msolver(\n\u001B[1;32m 355\u001B[0m iu_csr,\n\u001B[1;32m 356\u001B[0m item_factors,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 359\u001B[0m model\u001B[38;5;241m.\u001B[39mnum_threads,\n\u001B[1;32m 360\u001B[0m )\n", + "\u001B[0;31mKeyboardInterrupt\u001B[0m: " + ] + } + ], + "source": [ + "%%time\n", + "results = []\n", + "for model_name, model in models.items():\n", + " print(f\"Fitting model {model_name}...\")\n", + " model_quality = {'model': model_name}\n", + "\n", + " model.fit(dataset)\n", + " recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True,\n", + " )\n", + " metric_values = calc_metrics(metrics, recos, test, train)\n", + " model_quality.update(metric_values)\n", + " results.append(model_quality)\n", + "\n", + "df_quality_grid_search = pd.DataFrame(results).T\n", + "df_quality_grid_search.columns = df_quality_grid_search.iloc[0]\n", + "df_quality_grid_search.drop('model', inplace=True)\n", + "\n", + "df_quality_grid_search.style.highlight_max(color='lightgreen', axis=1)" + ] + }, + { + "cell_type": "markdown", + "id": "2c603783", + "metadata": {}, + "source": [ + "# Optuna" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "a17b8b66", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-11 01:16:32,212]\u001B[0m A new study created in memory with name: no-name-db609323-c8c4-4475-8bcf-6d559813862c\u001B[0m\n", + "\u001B[32m[I 2022-12-11 01:17:37,725]\u001B[0m Trial 0 finished with value: 3.6209115294627156e-05 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.5486709126434274, 'k': 3, 'loss': 'warp', 'no_components': 57}. Best is trial 0 with value: 3.6209115294627156e-05.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 3.6209115294627156e-05\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[33m[W 2022-12-11 01:36:33,239]\u001B[0m Trial 1 failed because of the following error: KeyboardInterrupt()\u001B[0m\n", + "Traceback (most recent call last):\n", + " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", + " value_or_values = func(trial)\n", + " File \"/var/folders/f8/ytvrd_xj4gvd76trh8sqryh80000gn/T/ipykernel_2736/210213320.py\", line 38, in objective\n", + " model.fit(dataset)\n", + " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/base.py\", line 55, in fit\n", + " self._fit(dataset, *args, **kwargs)\n", + " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py\", line 71, in _fit\n", + " user_factors, item_factors = fit_als_with_features_together(\n", + " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py\", line 317, in fit_als_with_features_together\n", + " _fit_combined_factors_on_cpu_inplace(\n", + " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py\", line 345, in _fit_combined_factors_on_cpu_inplace\n", + " model.solver(\n", + "KeyboardInterrupt\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[77], line 51\u001B[0m\n\u001B[1;32m 48\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m metric\n\u001B[1;32m 50\u001B[0m study \u001B[38;5;241m=\u001B[39m optuna\u001B[38;5;241m.\u001B[39mcreate_study(direction \u001B[38;5;241m=\u001B[39m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mmaximize\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[0;32m---> 51\u001B[0m \u001B[43mstudy\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43moptimize\u001B[49m\u001B[43m(\u001B[49m\u001B[43mobjective\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mn_trials\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m \u001B[49m\u001B[38;5;241;43m10\u001B[39;49m\u001B[43m)\u001B[49m\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/study.py:419\u001B[0m, in \u001B[0;36mStudy.optimize\u001B[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 315\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21moptimize\u001B[39m(\n\u001B[1;32m 316\u001B[0m \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m 317\u001B[0m func: ObjectiveFuncType,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 324\u001B[0m show_progress_bar: \u001B[38;5;28mbool\u001B[39m \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m 325\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m 326\u001B[0m \u001B[38;5;124;03m\"\"\"Optimize an objective function.\u001B[39;00m\n\u001B[1;32m 327\u001B[0m \n\u001B[1;32m 328\u001B[0m \u001B[38;5;124;03m Optimization is done by choosing a suitable set of hyperparameter values from a given\u001B[39;00m\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 416\u001B[0m \u001B[38;5;124;03m If nested invocation of this method occurs.\u001B[39;00m\n\u001B[1;32m 417\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m--> 419\u001B[0m \u001B[43m_optimize\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 420\u001B[0m \u001B[43m \u001B[49m\u001B[43mstudy\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[1;32m 421\u001B[0m \u001B[43m \u001B[49m\u001B[43mfunc\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mfunc\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 422\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_trials\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mn_trials\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 423\u001B[0m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 424\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_jobs\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mn_jobs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 425\u001B[0m \u001B[43m \u001B[49m\u001B[43mcatch\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mcatch\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 426\u001B[0m \u001B[43m \u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mcallbacks\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 427\u001B[0m \u001B[43m \u001B[49m\u001B[43mgc_after_trial\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mgc_after_trial\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 428\u001B[0m \u001B[43m \u001B[49m\u001B[43mshow_progress_bar\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mshow_progress_bar\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 429\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py:66\u001B[0m, in \u001B[0;36m_optimize\u001B[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 64\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m 65\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m n_jobs \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m1\u001B[39m:\n\u001B[0;32m---> 66\u001B[0m \u001B[43m_optimize_sequential\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 67\u001B[0m \u001B[43m \u001B[49m\u001B[43mstudy\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 68\u001B[0m \u001B[43m \u001B[49m\u001B[43mfunc\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 69\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_trials\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 70\u001B[0m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 71\u001B[0m \u001B[43m \u001B[49m\u001B[43mcatch\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 72\u001B[0m \u001B[43m \u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 73\u001B[0m \u001B[43m \u001B[49m\u001B[43mgc_after_trial\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 74\u001B[0m \u001B[43m \u001B[49m\u001B[43mreseed_sampler_rng\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[1;32m 75\u001B[0m \u001B[43m \u001B[49m\u001B[43mtime_start\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mNone\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[1;32m 76\u001B[0m \u001B[43m \u001B[49m\u001B[43mprogress_bar\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mprogress_bar\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 77\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 78\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 79\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m n_jobs \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m1\u001B[39m:\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py:160\u001B[0m, in \u001B[0;36m_optimize_sequential\u001B[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001B[0m\n\u001B[1;32m 157\u001B[0m \u001B[38;5;28;01mbreak\u001B[39;00m\n\u001B[1;32m 159\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 160\u001B[0m frozen_trial \u001B[38;5;241m=\u001B[39m \u001B[43m_run_trial\u001B[49m\u001B[43m(\u001B[49m\u001B[43mstudy\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mfunc\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcatch\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 161\u001B[0m \u001B[38;5;28;01mfinally\u001B[39;00m:\n\u001B[1;32m 162\u001B[0m \u001B[38;5;66;03m# The following line mitigates memory problems that can be occurred in some\u001B[39;00m\n\u001B[1;32m 163\u001B[0m \u001B[38;5;66;03m# environments (e.g., services that use computing containers such as CircleCI).\u001B[39;00m\n\u001B[1;32m 164\u001B[0m \u001B[38;5;66;03m# Please refer to the following PR for further details:\u001B[39;00m\n\u001B[1;32m 165\u001B[0m \u001B[38;5;66;03m# https://github.com/optuna/optuna/pull/325.\u001B[39;00m\n\u001B[1;32m 166\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m gc_after_trial:\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py:234\u001B[0m, in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 227\u001B[0m \u001B[38;5;28;01massert\u001B[39;00m \u001B[38;5;28;01mFalse\u001B[39;00m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mShould not reach.\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 229\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m (\n\u001B[1;32m 230\u001B[0m frozen_trial\u001B[38;5;241m.\u001B[39mstate \u001B[38;5;241m==\u001B[39m TrialState\u001B[38;5;241m.\u001B[39mFAIL\n\u001B[1;32m 231\u001B[0m \u001B[38;5;129;01mand\u001B[39;00m func_err \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(func_err, catch)\n\u001B[1;32m 233\u001B[0m ):\n\u001B[0;32m--> 234\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m func_err\n\u001B[1;32m 235\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m frozen_trial\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py:196\u001B[0m, in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 194\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m get_heartbeat_thread(trial\u001B[38;5;241m.\u001B[39m_trial_id, study\u001B[38;5;241m.\u001B[39m_storage):\n\u001B[1;32m 195\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 196\u001B[0m value_or_values \u001B[38;5;241m=\u001B[39m \u001B[43mfunc\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtrial\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 197\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m exceptions\u001B[38;5;241m.\u001B[39mTrialPruned \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m 198\u001B[0m \u001B[38;5;66;03m# TODO(mamu): Handle multi-objective cases.\u001B[39;00m\n\u001B[1;32m 199\u001B[0m state \u001B[38;5;241m=\u001B[39m TrialState\u001B[38;5;241m.\u001B[39mPRUNED\n", + "Cell \u001B[0;32mIn[77], line 38\u001B[0m, in \u001B[0;36mobjective\u001B[0;34m(trial)\u001B[0m\n\u001B[1;32m 28\u001B[0m model \u001B[38;5;241m=\u001B[39m ImplicitALSWrapperModel(\n\u001B[1;32m 29\u001B[0m model\u001B[38;5;241m=\u001B[39mAlternatingLeastSquares(\n\u001B[1;32m 30\u001B[0m factors\u001B[38;5;241m=\u001B[39mfactors,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 35\u001B[0m fit_features_together\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m 36\u001B[0m )\n\u001B[1;32m 37\u001B[0m \u001B[38;5;66;03m# Обучение модели и предикт для подсчета метрик\u001B[39;00m\n\u001B[0;32m---> 38\u001B[0m \u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mfit\u001B[49m\u001B[43m(\u001B[49m\u001B[43mdataset\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 40\u001B[0m recos \u001B[38;5;241m=\u001B[39m model\u001B[38;5;241m.\u001B[39mrecommend(\n\u001B[1;32m 41\u001B[0m users\u001B[38;5;241m=\u001B[39mTEST_USERS,\n\u001B[1;32m 42\u001B[0m dataset\u001B[38;5;241m=\u001B[39mdataset,\n\u001B[1;32m 43\u001B[0m k\u001B[38;5;241m=\u001B[39mK_RECOS,\n\u001B[1;32m 44\u001B[0m filter_viewed\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m 45\u001B[0m )\n\u001B[1;32m 46\u001B[0m metric \u001B[38;5;241m=\u001B[39m calc_metrics(metrics, recos, test, train)[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mMAP@10\u001B[39m\u001B[38;5;124m'\u001B[39m]\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/base.py:55\u001B[0m, in \u001B[0;36mModelBase.fit\u001B[0;34m(self, dataset, *args, **kwargs)\u001B[0m\n\u001B[1;32m 42\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mfit\u001B[39m(\u001B[38;5;28mself\u001B[39m: T, dataset: Dataset, \u001B[38;5;241m*\u001B[39margs: tp\u001B[38;5;241m.\u001B[39mAny, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: tp\u001B[38;5;241m.\u001B[39mAny) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m T:\n\u001B[1;32m 43\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 44\u001B[0m \u001B[38;5;124;03m Fit model.\u001B[39;00m\n\u001B[1;32m 45\u001B[0m \n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 53\u001B[0m \u001B[38;5;124;03m self\u001B[39;00m\n\u001B[1;32m 54\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m---> 55\u001B[0m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_fit\u001B[49m\u001B[43m(\u001B[49m\u001B[43mdataset\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43margs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 56\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mis_fitted \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m 57\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:71\u001B[0m, in \u001B[0;36mImplicitALSWrapperModel._fit\u001B[0;34m(self, dataset)\u001B[0m\n\u001B[1;32m 68\u001B[0m ui_csr \u001B[38;5;241m=\u001B[39m dataset\u001B[38;5;241m.\u001B[39mget_user_item_matrix(include_weights\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[1;32m 70\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfit_features_together:\n\u001B[0;32m---> 71\u001B[0m user_factors, item_factors \u001B[38;5;241m=\u001B[39m \u001B[43mfit_als_with_features_together\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 72\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 73\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 74\u001B[0m \u001B[43m \u001B[49m\u001B[43mdataset\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43muser_features\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 75\u001B[0m \u001B[43m \u001B[49m\u001B[43mdataset\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mitem_features\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 76\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mverbose\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 77\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 78\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 79\u001B[0m user_factors, item_factors \u001B[38;5;241m=\u001B[39m fit_als_with_features_separately(\n\u001B[1;32m 80\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmodel,\n\u001B[1;32m 81\u001B[0m ui_csr,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 84\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mverbose,\n\u001B[1;32m 85\u001B[0m )\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:317\u001B[0m, in \u001B[0;36mfit_als_with_features_together\u001B[0;34m(model, ui_csr, user_features, item_features, verbose)\u001B[0m\n\u001B[1;32m 307\u001B[0m _fit_combined_factors_on_gpu_inplace(\n\u001B[1;32m 308\u001B[0m model,\n\u001B[1;32m 309\u001B[0m ui_csr,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 314\u001B[0m verbose,\n\u001B[1;32m 315\u001B[0m )\n\u001B[1;32m 316\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m--> 317\u001B[0m \u001B[43m_fit_combined_factors_on_cpu_inplace\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 318\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 319\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 320\u001B[0m \u001B[43m \u001B[49m\u001B[43muser_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 321\u001B[0m \u001B[43m \u001B[49m\u001B[43mitem_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 322\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_user_explicit_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 323\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_item_explicit_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 324\u001B[0m \u001B[43m \u001B[49m\u001B[43mverbose\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 325\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 327\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m user_factors, item_factors\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:345\u001B[0m, in \u001B[0;36m_fit_combined_factors_on_cpu_inplace\u001B[0;34m(model, ui_csr, user_factors, item_factors, n_user_explicit_factors, n_item_explicit_factors, verbose)\u001B[0m\n\u001B[1;32m 342\u001B[0m iu_csr \u001B[38;5;241m=\u001B[39m ui_csr\u001B[38;5;241m.\u001B[39mT\u001B[38;5;241m.\u001B[39mtocsr(copy\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m)\n\u001B[1;32m 344\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m _ \u001B[38;5;129;01min\u001B[39;00m tqdm(\u001B[38;5;28mrange\u001B[39m(model\u001B[38;5;241m.\u001B[39miterations), disable\u001B[38;5;241m=\u001B[39mverbose \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m0\u001B[39m):\n\u001B[0;32m--> 345\u001B[0m \u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43msolver\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 346\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 347\u001B[0m \u001B[43m \u001B[49m\u001B[43muser_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 348\u001B[0m \u001B[43m \u001B[49m\u001B[43mitem_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 349\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mregularization\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 350\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mnum_threads\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 351\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 352\u001B[0m user_factors[:, :n_user_explicit_factors] \u001B[38;5;241m=\u001B[39m user_explicit_factors\n\u001B[1;32m 354\u001B[0m model\u001B[38;5;241m.\u001B[39msolver(\n\u001B[1;32m 355\u001B[0m iu_csr,\n\u001B[1;32m 356\u001B[0m item_factors,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 359\u001B[0m model\u001B[38;5;241m.\u001B[39mnum_threads,\n\u001B[1;32m 360\u001B[0m )\n", + "\u001B[0;31mKeyboardInterrupt\u001B[0m: " + ] + } + ], + "source": [ + "def objective(trial):\n", + " # параметры для подбора типа модели\n", + " model_name = trial.suggest_categorical('recomender', ['LightFM', 'ALS'])\n", + "\n", + " if model_name == 'LightFM':\n", + " # параметры для подбора модели LightFM\n", + " learning_rate = trial.suggest_float('learning_rate', 0.001, 0.1)\n", + " k = trial.suggest_int('k', 2, 10)\n", + " loss = trial.suggest_categorical('loss',['logistic', 'bpr', 'warp'])\n", + " no_components = trial.suggest_int('no_components', 5, 64)\n", + "\n", + " # Создание инстанса модели\n", + " model = LightFMWrapperModel(\n", + " LightFM(\n", + " no_components=no_components,\n", + " k=k,\n", + " learning_rate=learning_rate,\n", + " loss=loss,\n", + " ),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS\n", + " )\n", + " else:\n", + " # параметры для подбора модели ALS\n", + " factors = trial.suggest_int('factors', 32, 128)\n", + " regularization = trial.suggest_float('regularization', 0.001, 0.1)\n", + "\n", + " # Создание инстанса модели\n", + " model = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=factors,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=regularization\n", + " ),\n", + " fit_features_together=True\n", + " )\n", + " # Обучение модели и предикт для подсчета метрик\n", + " model.fit(dataset)\n", + "\n", + " recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True\n", + " )\n", + " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", + " print(\"MAP@10\", metric)\n", + " return metric\n", + "\n", + "study = optuna.create_study(direction = 'maximize')\n", + "study.optimize(objective, n_trials = 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "99aae61e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "best params from optuna - {'recomender': 'LightFM', 'learning_rate': 0.5486709126434274, 'k': 3, 'loss': 'warp', 'no_components': 57}\n" + ] + } + ], + "source": [ + "print('best params from optuna -', study.best_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "8428c4c7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Precision@1': 3.540637668844159e-05,\n", + " 'Recall@1': 1.4548389395699396e-05,\n", + " 'Precision@2': 3.098057960238639e-05,\n", + " 'Recall@2': 1.9395690966140803e-05,\n", + " 'Precision@3': 2.3604251125627725e-05,\n", + " 'Recall@3': 2.824728513825121e-05,\n", + " 'Precision@4': 2.8767681059358792e-05,\n", + " 'Recall@4': 3.996894166313679e-05,\n", + " 'Precision@5': 2.4784463681909114e-05,\n", + " 'Recall@5': 4.144420735848852e-05,\n", + " 'Precision@6': 2.0653719734924258e-05,\n", + " 'Recall@6': 4.144420735848852e-05,\n", + " 'Precision@7': 1.896770179737942e-05,\n", + " 'Recall@7': 4.1526932537667124e-05,\n", + " 'Precision@8': 1.8809637615734594e-05,\n", + " 'Recall@8': 4.7427995319074045e-05,\n", + " 'Precision@9': 1.868669880778862e-05,\n", + " 'Recall@9': 4.834627294577257e-05,\n", + " 'Precision@10': 1.8588347761431833e-05,\n", + " 'Recall@10': 5.295271481085044e-05,\n", + " 'MAP@1': 1.4548389395699396e-05,\n", + " 'MAP@2': 1.69720401809201e-05,\n", + " 'MAP@3': 1.9922571571623564e-05,\n", + " 'MAP@4': 2.2852985702844963e-05,\n", + " 'MAP@5': 2.3148038841915313e-05,\n", + " 'MAP@6': 2.3148038841915313e-05,\n", + " 'MAP@7': 2.3159856724655112e-05,\n", + " 'MAP@8': 2.3897489572330977e-05,\n", + " 'MAP@9': 2.3999520419741923e-05,\n", + " 'MAP@10': 2.4460164606249712e-05}" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "if study.best_params['recomender'] == 'LightFM':\n", + " # Создание инстанса модели\n", + " model = LightFMWrapperModel(\n", + " LightFM(\n", + " k=study.best_params['k'],\n", + " learning_rate=study.best_params['learning_rate'],\n", + " loss=study.best_params['loss'],\n", + " no_components=study.best_params['no_components']\n", + " ),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS\n", + " )\n", + "else:\n", + " # Создание инстанса модели\n", + " model = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=study.best_params['factors'],\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=study.best_params['regularization']\n", + " ),\n", + " fit_features_together=True\n", + " )\n", + "# Обучение модели и предикт для подсчета метрик\n", + "model.fit(dataset)\n", + "\n", + "recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True\n", + ")\n", + "metric = calc_metrics(metrics, recos, test, train)\n", + "metric" + ] + }, + { + "cell_type": "markdown", + "id": "43411998", + "metadata": {}, + "source": [ + " ## Метод приближенного поиска соседей." + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "id": "e0dfa8e8", + "metadata": {}, + "outputs": [], + "source": [ + "user_embeddings, item_embeddings = model.get_vectors(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "id": "91a20b08", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((756545, 59), (13963, 59))" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings.shape, item_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "3634fd78", + "metadata": {}, + "outputs": [], + "source": [ + "def augment_inner_product(factors):\n", + " normed_factors = np.linalg.norm(factors, axis=1)\n", + " max_norm = normed_factors.max()\n", + "\n", + " extra_dim = np.sqrt(max_norm ** 2 - normed_factors ** 2).reshape(-1, 1)\n", + " augmented_factors = np.append(factors, extra_dim, axis=1)\n", + " return max_norm, augmented_factors" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "id": "c2668a0d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pre shape: (13963, 59)\n" + ] + }, + { + "data": { + "text/plain": [ + "(13963, 60)" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print('pre shape: ', item_embeddings.shape)\n", + "max_norm, augmented_item_embeddings = augment_inner_product(item_embeddings)\n", + "augmented_item_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "16fb4a95", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(756545, 60)" + ] + }, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "extra_zero = np.zeros((user_embeddings.shape[0], 1))\n", + "augmented_user_embeddings = np.append(user_embeddings, extra_zero, axis=1)\n", + "augmented_user_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "id": "8d3d96d3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-3.68946387e+03, 1.00000000e+00, 5.00279766e+04, 8.85783906e+04,\n", + " -1.05108094e+05, -3.06310918e+04, 1.96517285e+04, 6.73730078e+04,\n", + " 2.04599453e+05, 6.12343242e+04, 6.41995352e+04, -5.77218633e+04,\n", + " -7.05726250e+04, -1.61670656e+05, -5.52132148e+04, -1.30570914e+05,\n", + " -7.23810078e+04, 2.07963969e+05, 1.65819863e+04, -9.76921953e+04,\n", + " -3.12005684e+04, -7.85079531e+04, 5.45297734e+04, 1.34828297e+05,\n", + " 1.17192398e+05, 7.57457812e+04, -1.89341052e+03, 1.23631297e+05,\n", + " -1.10485789e+05, 2.78173301e+04, 1.66516035e+04, -6.22929336e+04,\n", + " 9.86834219e+04, -1.32930908e+04, 3.14460527e+04, 6.04318125e+04,\n", + " -8.20018047e+04, 6.20642812e+04, 4.66973711e+04, -1.44485000e+05,\n", + " 1.34138750e+05, 1.11652305e+05, -1.54659141e+05, -1.48082953e+05,\n", + " 3.26356621e+04, -2.69916387e+04, -1.60023016e+05, -7.10024922e+04,\n", + " -4.93529492e+04, -3.54507500e+04, 8.54245703e+04, -2.75770918e+04,\n", + " -1.25765594e+05, -1.01873039e+05, -3.04939473e+04, 9.42476641e+04,\n", + " 2.47347930e+04, 1.37679953e+05, 5.63563555e+04])" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_id = 30\n", + "user_embeddings[user_id]" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "id": "a3abdc5a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-3.68946387e+03, 1.00000000e+00, 5.00279766e+04, 8.85783906e+04,\n", + " -1.05108094e+05, -3.06310918e+04, 1.96517285e+04, 6.73730078e+04,\n", + " 2.04599453e+05, 6.12343242e+04, 6.41995352e+04, -5.77218633e+04,\n", + " -7.05726250e+04, -1.61670656e+05, -5.52132148e+04, -1.30570914e+05,\n", + " -7.23810078e+04, 2.07963969e+05, 1.65819863e+04, -9.76921953e+04,\n", + " -3.12005684e+04, -7.85079531e+04, 5.45297734e+04, 1.34828297e+05,\n", + " 1.17192398e+05, 7.57457812e+04, -1.89341052e+03, 1.23631297e+05,\n", + " -1.10485789e+05, 2.78173301e+04, 1.66516035e+04, -6.22929336e+04,\n", + " 9.86834219e+04, -1.32930908e+04, 3.14460527e+04, 6.04318125e+04,\n", + " -8.20018047e+04, 6.20642812e+04, 4.66973711e+04, -1.44485000e+05,\n", + " 1.34138750e+05, 1.11652305e+05, -1.54659141e+05, -1.48082953e+05,\n", + " 3.26356621e+04, -2.69916387e+04, -1.60023016e+05, -7.10024922e+04,\n", + " -4.93529492e+04, -3.54507500e+04, 8.54245703e+04, -2.75770918e+04,\n", + " -1.25765594e+05, -1.01873039e+05, -3.04939473e+04, 9.42476641e+04,\n", + " 2.47347930e+04, 1.37679953e+05, 5.63563555e+04, 0.00000000e+00])" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "augmented_user_embeddings[user_id]" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "id": "b4d804fe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1.00000000e+00, 3.71805847e+02, 3.05234741e+03, 1.01628503e+03,\n", + " -2.01937231e+03, -7.06286914e+03, 2.08036670e+03, 1.44198691e+04,\n", + " 1.04459076e+02, 2.91055640e+03, 4.90286133e+03, -8.00846631e+03,\n", + " -3.74290078e+04, -5.34835303e+03, -5.73522314e+03, -1.32270422e+03,\n", + " -4.57180566e+03, 5.20245544e+02, 2.12270190e+03, -2.74671069e+03,\n", + " -3.97734521e+03, -5.76298193e+03, -9.74685645e+03, 1.00388757e+03,\n", + " 1.41514294e+03, 2.31493750e+04, 8.51632129e+03, 9.64525818e+02,\n", + " -1.17795410e+04, 5.20026611e+03, -1.86291174e+03, -3.32180225e+03,\n", + " 2.35795312e+03, -2.74500562e+03, 7.57092236e+03, 8.45529199e+03,\n", + " -4.04447168e+03, 3.18093457e+03, 1.06870723e+04, -1.86842322e+03,\n", + " 1.92173401e+03, 2.00068164e+03, -2.32481689e+03, -1.20484082e+03,\n", + " 8.42075134e+02, -2.14867944e+03, -8.79860291e+02, -7.14862646e+03,\n", + " -2.94369702e+03, -2.65627759e+03, 1.50566143e+04, -2.40812646e+03,\n", + " -8.63793823e+02, -1.57019958e+03, -2.04618115e+03, 1.11798945e+04,\n", + " 1.65814307e+03, 6.58971863e+02, 7.54287207e+03])" + ] + }, + "execution_count": 92, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "item_id = 0\n", + "item_embeddings[item_id]" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "2e0030f1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1.00000000e+00, 3.71805847e+02, 3.05234741e+03, 1.01628503e+03,\n", + " -2.01937231e+03, -7.06286914e+03, 2.08036670e+03, 1.44198691e+04,\n", + " 1.04459076e+02, 2.91055640e+03, 4.90286133e+03, -8.00846631e+03,\n", + " -3.74290078e+04, -5.34835303e+03, -5.73522314e+03, -1.32270422e+03,\n", + " -4.57180566e+03, 5.20245544e+02, 2.12270190e+03, -2.74671069e+03,\n", + " -3.97734521e+03, -5.76298193e+03, -9.74685645e+03, 1.00388757e+03,\n", + " 1.41514294e+03, 2.31493750e+04, 8.51632129e+03, 9.64525818e+02,\n", + " -1.17795410e+04, 5.20026611e+03, -1.86291174e+03, -3.32180225e+03,\n", + " 2.35795312e+03, -2.74500562e+03, 7.57092236e+03, 8.45529199e+03,\n", + " -4.04447168e+03, 3.18093457e+03, 1.06870723e+04, -1.86842322e+03,\n", + " 1.92173401e+03, 2.00068164e+03, -2.32481689e+03, -1.20484082e+03,\n", + " 8.42075134e+02, -2.14867944e+03, -8.79860291e+02, -7.14862646e+03,\n", + " -2.94369702e+03, -2.65627759e+03, 1.50566143e+04, -2.40812646e+03,\n", + " -8.63793823e+02, -1.57019958e+03, -2.04618115e+03, 1.11798945e+04,\n", + " 1.65814307e+03, 6.58971863e+02, 7.54287207e+03, 3.94554062e+09])" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "augmented_item_embeddings[item_id]" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "id": "19104d9a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index-time parameters {'M': 48, 'indexThreadQty': 4, 'efConstruction': 100, 'post': 0}\n" + ] + } + ], + "source": [ + "M = 48\n", + "efC = 100\n", + "\n", + "num_threads = 4\n", + "index_time_params = {'M': M, 'indexThreadQty': num_threads, 'efConstruction': efC, 'post' : 0}\n", + "print('Index-time parameters', index_time_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "id": "3634ebbb", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'nmslib' is not defined", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[95], line 3\u001B[0m\n\u001B[1;32m 1\u001B[0m K\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m10\u001B[39m\n\u001B[1;32m 2\u001B[0m space_name\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mnegdotprod\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[0;32m----> 3\u001B[0m index \u001B[38;5;241m=\u001B[39m \u001B[43mnmslib\u001B[49m\u001B[38;5;241m.\u001B[39minit(method\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mhnsw\u001B[39m\u001B[38;5;124m'\u001B[39m, space\u001B[38;5;241m=\u001B[39mspace_name, data_type\u001B[38;5;241m=\u001B[39mnmslib\u001B[38;5;241m.\u001B[39mDataType\u001B[38;5;241m.\u001B[39mDENSE_VECTOR)\n\u001B[1;32m 4\u001B[0m index\u001B[38;5;241m.\u001B[39maddDataPointBatch(augmented_item_embeddings)\n", + "\u001B[0;31mNameError\u001B[0m: name 'nmslib' is not defined" + ] + } + ], + "source": [ + "K=10\n", + "space_name='negdotprod'\n", + "index = nmslib.init(method='hnsw', space=space_name, data_type=nmslib.DataType.DENSE_VECTOR)\n", + "index.addDataPointBatch(augmented_item_embeddings)" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "6d423d8d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index-time parameters {'M': 48, 'indexThreadQty': 4, 'efConstruction': 100}\n", + "Indexing time = 0.282692\n" + ] + } + ], + "source": [ + "start = time.time()\n", + "index_time_params = {'M': M, 'indexThreadQty': num_threads, 'efConstruction': efC}\n", + "index.createIndex(index_time_params)\n", + "end = time.time()\n", + "print('Index-time parameters', index_time_params)\n", + "print('Indexing time = %f' % (end-start))" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "9dc1529f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setting query-time parameters {'efSearch': 100}\n" + ] + } + ], + "source": [ + "efS = 100\n", + "query_time_params = {'efSearch': efS}\n", + "print('Setting query-time parameters', query_time_params)\n", + "index.setQueryTimeParams(query_time_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "0fff67a2", + "metadata": {}, + "outputs": [], + "source": [ + "query_matrix = augmented_user_embeddings[:1000, :]" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "1cdffc65", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "kNN time total=0.023291 (sec), per query=0.000023 (sec), per query adjusted for thread number=0.000093 (sec)\n" + ] + } + ], + "source": [ + "query_qty = query_matrix.shape[0]\n", + "start = time.time()\n", + "nbrs = index.knnQueryBatch(query_matrix, k = K, num_threads = num_threads)\n", + "end = time.time()\n", + "print(\n", + " 'kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' %\n", + " (end-start, float(end-start)/query_qty, num_threads*float(end-start)/query_qty)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "d94de743", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 43, 32, 19, 62, 31, 112, 305, 188, 268, 948], dtype=int32),\n", + " array([304.80273, 304.95447, 305.16202, 305.32443, 305.47067, 305.5135 ,\n", + " 305.6464 , 305.6903 , 305.73453, 305.78738], dtype=float32))" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nbrs[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "5be5c93c", + "metadata": {}, + "outputs": [], + "source": [ + "def recommend_all(query_factors, index_factors, topn=10):\n", + " output = query_factors.dot(index_factors.T)\n", + " argpartition_indices = np.argpartition(output, -topn)[:, -topn:]\n", + "\n", + " x_indices = np.repeat(np.arange(output.shape[0]), topn)\n", + " y_indices = argpartition_indices.flatten()\n", + " top_value = output[x_indices, y_indices].reshape(output.shape[0], topn)\n", + " top_indices = np.argsort(top_value)[:, ::-1]\n", + "\n", + " y_indices = top_indices.flatten()\n", + " top_indices = argpartition_indices[x_indices, y_indices]\n", + " labels = top_indices.reshape(-1, topn)\n", + " distances = output[x_indices, top_indices].reshape(-1, topn)\n", + " return labels, distances\n" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "id": "e9988091", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 19, 31, 121, 32, 43, 268, 120, 62, 103, 173]])" + ] + }, + "execution_count": 108, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labels,_ = recommend_all(user_embeddings[[], :], item_embeddings)\n", + "labels" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "id": "3c722149", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([], shape=(0, 34), dtype=float64)" + ] + }, + "execution_count": 112, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings[[], :]" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "id": "d300a815", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-3.24551971e+02, 1.00000000e+00, 8.73963833e-02, ...,\n", + " -1.30321786e-01, 1.82629615e-01, -3.07083875e-01],\n", + " [-3.24792297e+02, 1.00000000e+00, 3.87268960e-01, ...,\n", + " -4.32303697e-02, -4.72983688e-01, -1.79986209e-01],\n", + " [-3.01102661e+02, 1.00000000e+00, -1.63965374e-01, ...,\n", + " -1.01540364e-01, 1.10484377e-01, -2.40944147e-01],\n", + " ...,\n", + " [-3.58453766e+02, 1.00000000e+00, -1.08767882e-01, ...,\n", + " 2.43232936e-01, -1.24036551e-01, -4.88389194e-01],\n", + " [-2.99490662e+02, 1.00000000e+00, -3.04439873e-01, ...,\n", + " -2.42081508e-02, -3.93126070e-01, -2.91359007e-01],\n", + " [-3.10774689e+02, 1.00000000e+00, -2.57401466e-01, ...,\n", + " -3.03505287e-02, -4.26894128e-01, -3.11958164e-01]])" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15d49fe7", + "metadata": {}, + "outputs": [], + "source": [ + "labels" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "d6c68dd7", + "metadata": {}, + "outputs": [], + "source": [ + "query_matrix_not_augmented = user_embeddings[:1000, :]" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "id": "b7d9dd1f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "207 ms ± 6.37 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "labels,_ = recommend_all(query_matrix_not_augmented, item_embeddings)\n", + "print(labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "id": "904846a6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((1000, 34), (756545, 34))" + ] + }, + "execution_count": 92, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "item_embeddings[:1000, :].shape, user_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "d6027ae4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7.88 ms ± 368 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "index.knnQueryBatch(query_matrix, k = K, num_threads = num_threads)" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "id": "e6b0be91", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 43 32 19 ... 188 268 948]\n", + " [ 31 19 62 ... 450 49 268]\n", + " [ 19 31 121 ... 62 103 173]\n", + " ...\n", + " [ 31 62 358 ... 8 884 43]\n", + " [ 43 19 32 ... 8 121 164]\n", + " [3117 5859 776 ... 43 62 1132]]\n", + "[[-304.80272148 -304.95450166 -305.1620535 ... -305.69031591\n", + " -305.73454442 -305.7874324 ]\n", + " [-311.19933349 -311.44323422 -311.45526998 ... -312.0948194\n", + " -312.21820321 -312.23901463]\n", + " [-284.3956498 -284.45770448 -284.96237912 ... -285.29546382\n", + " -285.36598349 -285.41208658]\n", + " ...\n", + " [-332.37278335 -332.85525963 -332.98405066 ... -333.36833688\n", + " -333.44008879 -333.48889785]\n", + " [-302.10402324 -302.13324433 -302.3124104 ... -302.86405908\n", + " -302.88296188 -303.00234271]\n", + " [ 14.88806505 14.41715752 14.1114468 ... 13.71272978\n", + " 13.68271151 13.6242354 ]]\n" + ] + } + ], + "source": [ + "labels, distances = recommend_all(user_embeddings[:1000, :], item_embeddings)\n", + "print(labels)\n", + "print(distances)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77fedf20", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/online_LightFm.ipynb b/notebooks/online_LightFm.ipynb new file mode 100644 index 00000000..a953cc50 --- /dev/null +++ b/notebooks/online_LightFm.ipynb @@ -0,0 +1,877 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 292, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import scipy as sp\n", + "from typing import Optional\n", + "\n", + "import os\n", + "import time\n", + "from functools import reduce\n", + "from tqdm import tqdm\n", + "from pathlib import Path\n", + "\n", + "from lightfm import LightFM\n", + "import pandas as pd\n", + "from collections import defaultdict\n", + "from scipy.sparse import csr_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"\n", + "datetime_col = 'last_watch_dt'\n", + "DATA_PATH = Path(\"../data/kion_train/\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.2 s, sys: 325 ms, total: 2.53 s\n", + "Wall time: 2.55 s\n" + ] + } + ], + "source": [ + "%%time\n", + "users = pd.read_csv(DATA_PATH / 'users.csv')\n", + "items = pd.read_csv(DATA_PATH / 'items.csv')\n", + "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "interactions[datetime_col] = pd.to_datetime(interactions[datetime_col], format='%Y-%m-%d')\n", + "interactions.dropna(inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "interactions['watched'] = pd.cut(\n", + " x=interactions['watched_pct'],\n", + " bins=5,\n", + " labels=[1, 2, 3, 4, 5]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 197, + "metadata": {}, + "outputs": [], + "source": [ + "items.fillna('Unknown', inplace=True)\n", + "\n", + "items[\"genre\"] = items[\"genres\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "items[\"actors\"] = items[\"actors\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "\n", + "genre_feature = items[[\"item_id\", \"genre\"]].explode(\"genre\")\n", + "genre_feature.columns = [\"id\", \"value\"]\n", + "genre_feature[\"feature\"] = \"genre\"\n", + "\n", + "actors_feature = items[[\"item_id\", \"actors\"]].explode(\"actors\")\n", + "actors_feature.columns = [\"id\", \"value\"]\n", + "actors_feature[\"feature\"] = \"actors\"\n", + "\n", + "\n", + "content_feature = items.reindex(columns=['item_id', \"content_type\"])\n", + "content_feature.columns = [\"id\", \"value\"]\n", + "content_feature[\"feature\"] = \"content_type\"\n", + "\n", + "country_feature = items.reindex(columns=['item_id', \"countries\"])\n", + "country_feature.columns = [\"id\", \"value\"]\n", + "country_feature[\"feature\"] = \"countries\"\n", + "\n", + "age_feature = items.reindex(columns=['item_id', \"age_rating\"])\n", + "age_feature.columns = [\"id\", \"value\"]\n", + "age_feature[\"feature\"] = \"age_feature\"\n", + "\n", + "studios_feature = items.reindex(columns=['item_id', \"studios\"])\n", + "studios_feature.columns = [\"id\", \"value\"]\n", + "studios_feature[\"feature\"] = \"studios\"\n", + "\n", + "\n", + "genre_feature_bin = pd.get_dummies(genre_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + "content_feature_bin = pd.get_dummies(content_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + "studios_feature_bin = pd.get_dummies(studios_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + "age_feature_bin = pd.get_dummies(age_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + "country_feature_bin = pd.get_dummies(country_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + "\n", + "dfs = [genre_feature_bin, content_feature_bin, studios_feature_bin, age_feature_bin, country_feature_bin]\n", + "item_final_features = reduce(lambda left,right: pd.merge(left,right,on='id'), dfs)\n", + "\n", + "# item_final_features.id = item_final_features.id.map(model.mapping['items_mapping'])\n", + "# item_final_features = item_final_features.sort_values('id').drop('id', axis=1)\n", + "# item_final_features_matrix_sparse = csr_matrix(item_final_features.values)" + ] + }, + { + "cell_type": "code", + "execution_count": 332, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
value_18+value_no_genrevalue_анимацияvalue_анимеvalue_артхаусvalue_биографияvalue_блогерvalue_боевикиvalue_вестернvalue_военные...value_Японияvalue_Япония, Великобританияvalue_Япония, Канадаvalue_Япония, Китайvalue_Япония, Китай, Республика Кореяvalue_Япония, Россияvalue_Япония, СССРvalue_Япония, СШАvalue_Япония, США, Францияvalue_Япония, Сингапур
103290000000000...0000000000
24200000000000...0000000000
103340000000100...0000000000
75990000000000...0000000000
157140000000000...0000000000
..................................................................
62150000000000...0000000000
22850000000100...0000000000
102560000000000...0000000000
43780000000000...0000000000
30900000000000...0000000000
\n", + "

15963 rows × 831 columns

\n", + "
" + ], + "text/plain": [ + " value_18+ value_no_genre value_анимация value_аниме value_артхаус \\\n", + "10329 0 0 0 0 0 \n", + "2420 0 0 0 0 0 \n", + "10334 0 0 0 0 0 \n", + "7599 0 0 0 0 0 \n", + "15714 0 0 0 0 0 \n", + "... ... ... ... ... ... \n", + "6215 0 0 0 0 0 \n", + "2285 0 0 0 0 0 \n", + "10256 0 0 0 0 0 \n", + "4378 0 0 0 0 0 \n", + "3090 0 0 0 0 0 \n", + "\n", + " value_биография value_блогер value_боевики value_вестерн \\\n", + "10329 0 0 0 0 \n", + "2420 0 0 0 0 \n", + "10334 0 0 1 0 \n", + "7599 0 0 0 0 \n", + "15714 0 0 0 0 \n", + "... ... ... ... ... \n", + "6215 0 0 0 0 \n", + "2285 0 0 1 0 \n", + "10256 0 0 0 0 \n", + "4378 0 0 0 0 \n", + "3090 0 0 0 0 \n", + "\n", + " value_военные ... value_Япония value_Япония, Великобритания \\\n", + "10329 0 ... 0 0 \n", + "2420 0 ... 0 0 \n", + "10334 0 ... 0 0 \n", + "7599 0 ... 0 0 \n", + "15714 0 ... 0 0 \n", + "... ... ... ... ... \n", + "6215 0 ... 0 0 \n", + "2285 0 ... 0 0 \n", + "10256 0 ... 0 0 \n", + "4378 0 ... 0 0 \n", + "3090 0 ... 0 0 \n", + "\n", + " value_Япония, Канада value_Япония, Китай \\\n", + "10329 0 0 \n", + "2420 0 0 \n", + "10334 0 0 \n", + "7599 0 0 \n", + "15714 0 0 \n", + "... ... ... \n", + "6215 0 0 \n", + "2285 0 0 \n", + "10256 0 0 \n", + "4378 0 0 \n", + "3090 0 0 \n", + "\n", + " value_Япония, Китай, Республика Корея value_Япония, Россия \\\n", + "10329 0 0 \n", + "2420 0 0 \n", + "10334 0 0 \n", + "7599 0 0 \n", + "15714 0 0 \n", + "... ... ... \n", + "6215 0 0 \n", + "2285 0 0 \n", + "10256 0 0 \n", + "4378 0 0 \n", + "3090 0 0 \n", + "\n", + " value_Япония, СССР value_Япония, США value_Япония, США, Франция \\\n", + "10329 0 0 0 \n", + "2420 0 0 0 \n", + "10334 0 0 0 \n", + "7599 0 0 0 \n", + "15714 0 0 0 \n", + "... ... ... ... \n", + "6215 0 0 0 \n", + "2285 0 0 0 \n", + "10256 0 0 0 \n", + "4378 0 0 0 \n", + "3090 0 0 0 \n", + "\n", + " value_Япония, Сингапур \n", + "10329 0 \n", + "2420 0 \n", + "10334 0 \n", + "7599 0 \n", + "15714 0 \n", + "... ... \n", + "6215 0 \n", + "2285 0 \n", + "10256 0 \n", + "4378 0 \n", + "3090 0 \n", + "\n", + "[15963 rows x 831 columns]" + ] + }, + "execution_count": 332, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "item_final_features" + ] + }, + { + "cell_type": "code", + "execution_count": 267, + "metadata": {}, + "outputs": [], + "source": [ + "# Удаляем те юзеры и айтемы, которых нет в основных табличках\n", + "interactions = interactions.merge(users.user_id.drop_duplicates(), on='user_id')\n", + "interactions = interactions.merge(items.item_id.drop_duplicates(), on='item_id')" + ] + }, + { + "cell_type": "code", + "execution_count": 328, + "metadata": {}, + "outputs": [], + "source": [ + "class LightFMWrapper:\n", + " \"\"\"\n", + " Class for fit-perdict LightFM\n", + " \"\"\"\n", + "\n", + " def __init__(\n", + " self,\n", + " random_state: int = 42,\n", + " learning_rate: float = 0.05,\n", + " no_components: int = 10,\n", + " item_alpha: float = 0,\n", + " user_alpha: float = 0,\n", + " loss: str = 'warp',\n", + " num_threads: int = 8,\n", + " epochs: int = 1,\n", + " verbose: int = 1,\n", + " ):\n", + " self.loss=loss\n", + " self.no_components=no_components\n", + " self.user_alpha=user_alpha\n", + " self.item_alpha=item_alpha\n", + " self.epochs=epochs\n", + " self.num_threads=num_threads\n", + "\n", + " self.verbose = verbose\n", + " self.is_fitted = False\n", + "\n", + " self.mapping: Dict[str, Dict[int, int]] = defaultdict(dict)\n", + "\n", + " self.weights_matrix = None\n", + " self.users_watched = None\n", + "\n", + " def get_mappings(self, users, items):\n", + " self.mapping['users_inv_mapping'] = dict(\n", + " enumerate(users['user_id'].unique())\n", + " )\n", + " self.mapping['users_mapping'] = dict({\n", + " v: k for k, v in self.mapping['users_inv_mapping'].items()\n", + " })\n", + "\n", + " self.mapping['items_inv_mapping'] = dict(\n", + " enumerate(items['item_id'].unique())\n", + " )\n", + " self.mapping['items_mapping'] = dict({\n", + " v: k for k, v in self.mapping['items_inv_mapping'].items()\n", + " })\n", + "\n", + " def get_matrix(\n", + " self, df: pd.DataFrame,\n", + " user_col: str = 'user_id',\n", + " item_col: str = 'item_id',\n", + " weight_col: str = None,\n", + " ):\n", + " if weight_col:\n", + " weights = df[weight_col].astype(np.float32)\n", + " else:\n", + " weights = np.ones(len(df), dtype=np.float32)\n", + "\n", + " if hasattr(self.mapping['users_mapping'], 'get') and \\\n", + " hasattr(self.mapping['items_mapping'], 'get'):\n", + " interaction_matrix = sp.sparse.coo_matrix((\n", + " weights,\n", + " (\n", + " df[user_col].map(self.mapping['users_mapping'].get),\n", + " df[item_col].map(self.mapping['items_mapping'].get)\n", + " )\n", + " ))\n", + " else:\n", + " raise AttributeError\n", + "\n", + " self.users_watched = df.groupby(user_col).agg({item_col: list})\n", + " return interaction_matrix\n", + "\n", + " def prepare_additional_features_users(self, features: pd.DataFrame):\n", + " pass\n", + "\n", + " def prepare_additional_features_items(self, features: pd.DataFrame):\n", + " items.fillna('Unknown', inplace=True)\n", + " items[\"genre\"] = items[\"genres\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + " items[\"actors\"] = items[\"actors\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", + "\n", + " genre_feature = items[[\"item_id\", \"genre\"]].explode(\"genre\")\n", + " genre_feature.columns = [\"id\", \"value\"]\n", + " genre_feature[\"feature\"] = \"genre\"\n", + "\n", + " actors_feature = items[[\"item_id\", \"actors\"]].explode(\"actors\")\n", + " actors_feature.columns = [\"id\", \"value\"]\n", + " actors_feature[\"feature\"] = \"actors\"\n", + "\n", + "\n", + " content_feature = items.reindex(columns=['item_id', \"content_type\"])\n", + " content_feature.columns = [\"id\", \"value\"]\n", + " content_feature[\"feature\"] = \"content_type\"\n", + "\n", + " country_feature = items.reindex(columns=['item_id', \"countries\"])\n", + " country_feature.columns = [\"id\", \"value\"]\n", + " country_feature[\"feature\"] = \"countries\"\n", + "\n", + " age_feature = items.reindex(columns=['item_id', \"age_rating\"])\n", + " age_feature.columns = [\"id\", \"value\"]\n", + " age_feature[\"feature\"] = \"age_feature\"\n", + "\n", + " studios_feature = items.reindex(columns=['item_id', \"studios\"])\n", + " studios_feature.columns = [\"id\", \"value\"]\n", + " studios_feature[\"feature\"] = \"studios\"\n", + "\n", + "\n", + " genre_feature_bin = pd.get_dummies(genre_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + " content_feature_bin = pd.get_dummies(content_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + " studios_feature_bin = pd.get_dummies(studios_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + " age_feature_bin = pd.get_dummies(age_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + " country_feature_bin = pd.get_dummies(country_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", + "\n", + " dfs = [genre_feature_bin, content_feature_bin, studios_feature_bin, age_feature_bin, country_feature_bin]\n", + " item_final_features = reduce(lambda left,right: pd.merge(left,right,on='id'), dfs)\n", + "\n", + " item_final_features.id = item_final_features.id.map(model.mapping['items_mapping'])\n", + " item_final_features = item_final_features.sort_values('id').drop('id', axis=1)\n", + " item_final_features_matrix_sparse = csr_matrix(item_final_features.values)\n", + "\n", + " return item_final_features_matrix_sparse\n", + "\n", + " def fit(\n", + " self,\n", + " train: pd.DataFrame,\n", + " user_features: Optional[pd.DataFrame] = None, # если не none, то делаем фичи\n", + " item_features: Optional[pd.DataFrame] = None, # если не none, то делаем фичи\n", + " ):\n", + " if user_features is not None:\n", + " user_features = self.prepare_additional_features_users(user_features)\n", + "\n", + " if item_features is not None:\n", + " item_features = self.prepare_additional_features_items(item_features)\n", + "\n", + "\n", + " self.get_mappings(users, items)\n", + " self.weights_matrix = self.get_matrix(train).tocsr()\n", + "\n", + " self.model = LightFM(\n", + " loss=self.loss,\n", + " no_components=self.no_components,\n", + " user_alpha=self.user_alpha,\n", + " item_alpha=self.item_alpha,\n", + " )\n", + "\n", + " self.model.fit(\n", + " self.weights_matrix,\n", + " epochs=self.epochs,\n", + " user_features=user_features, # csr_matrix of shape [n_users, n_user_features]\n", + " item_features=item_features, # csr_matrix of shape [n_items, n_item_features]\n", + " num_threads=self.num_threads,\n", + " verbose=self.verbose > 0,\n", + " )\n", + "\n", + " self.is_fitted = True\n", + "\n", + "\n", + " def predict(self, user_id: int, n_recs: int = 10):\n", + "\n", + " if not self.is_fitted:\n", + " raise ValueError(\"Fit model before predicting\")\n", + "\n", + " if user_id not in self.mapping['users_mapping'].keys(): return []\n", + " user_id = self.mapping['users_mapping'][user_id]\n", + "\n", + "\n", + " scores = self.model.predict(user_id, np.arange(len(self.mapping['items_mapping']))) # LightFM\n", + " top_items = np.argsort(-scores)[:n_recs]\n", + " recos = [self.mapping['items_inv_mapping'][inv_reco_item] for inv_reco_item in top_items]\n", + "\n", + " return recos" + ] + }, + { + "cell_type": "code", + "execution_count": 329, + "metadata": {}, + "outputs": [], + "source": [ + "model = LightFMWrapper()" + ] + }, + { + "cell_type": "code", + "execution_count": 330, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Epoch: 100%|██████████| 1/1 [00:05<00:00, 5.99s/it]\n" + ] + } + ], + "source": [ + "model.fit(train=interactions, item_features=items)" + ] + }, + { + "cell_type": "code", + "execution_count": 331, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "ename": "ValueError", + "evalue": "The item feature matrix specifies more features than there are estimated feature embeddings: 831 vs 15963.", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mValueError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[331], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mpredict\u001B[49m\u001B[43m(\u001B[49m\u001B[43muser_id\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m176549\u001B[39;49m\u001B[43m)\u001B[49m\n", + "Cell \u001B[0;32mIn[328], line 167\u001B[0m, in \u001B[0;36mLightFMWrapper.predict\u001B[0;34m(self, user_id, n_recs)\u001B[0m\n\u001B[1;32m 163\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m user_id \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmapping[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124musers_mapping\u001B[39m\u001B[38;5;124m'\u001B[39m]\u001B[38;5;241m.\u001B[39mkeys(): \u001B[38;5;28;01mreturn\u001B[39;00m []\n\u001B[1;32m 164\u001B[0m user_id \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmapping[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124musers_mapping\u001B[39m\u001B[38;5;124m'\u001B[39m][user_id]\n\u001B[0;32m--> 167\u001B[0m scores \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mpredict\u001B[49m\u001B[43m(\u001B[49m\u001B[43muser_id\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mnp\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43marange\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mlen\u001B[39;49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmapping\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43mitems_mapping\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m \u001B[38;5;66;03m# LightFM\u001B[39;00m\n\u001B[1;32m 168\u001B[0m top_items \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39margsort(\u001B[38;5;241m-\u001B[39mscores)[:n_recs]\n\u001B[1;32m 169\u001B[0m recos \u001B[38;5;241m=\u001B[39m [\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmapping[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mitems_inv_mapping\u001B[39m\u001B[38;5;124m'\u001B[39m][inv_reco_item] \u001B[38;5;28;01mfor\u001B[39;00m inv_reco_item \u001B[38;5;129;01min\u001B[39;00m top_items]\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/lightfm/lightfm.py:817\u001B[0m, in \u001B[0;36mLightFM.predict\u001B[0;34m(self, user_ids, item_ids, item_features, user_features, num_threads)\u001B[0m\n\u001B[1;32m 814\u001B[0m n_users \u001B[38;5;241m=\u001B[39m user_ids\u001B[38;5;241m.\u001B[39mmax() \u001B[38;5;241m+\u001B[39m \u001B[38;5;241m1\u001B[39m\n\u001B[1;32m 815\u001B[0m n_items \u001B[38;5;241m=\u001B[39m item_ids\u001B[38;5;241m.\u001B[39mmax() \u001B[38;5;241m+\u001B[39m \u001B[38;5;241m1\u001B[39m\n\u001B[0;32m--> 817\u001B[0m (user_features, item_features) \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_construct_feature_matrices\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 818\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_users\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mn_items\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43muser_features\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mitem_features\u001B[49m\n\u001B[1;32m 819\u001B[0m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 821\u001B[0m lightfm_data \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_get_lightfm_data()\n\u001B[1;32m 823\u001B[0m predictions \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39mempty(\u001B[38;5;28mlen\u001B[39m(user_ids), dtype\u001B[38;5;241m=\u001B[39mnp\u001B[38;5;241m.\u001B[39mfloat32)\n", + "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/lightfm/lightfm.py:335\u001B[0m, in \u001B[0;36mLightFM._construct_feature_matrices\u001B[0;34m(self, n_users, n_items, user_features, item_features)\u001B[0m\n\u001B[1;32m 333\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mitem_embeddings \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m 334\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mitem_embeddings\u001B[38;5;241m.\u001B[39mshape[\u001B[38;5;241m0\u001B[39m] \u001B[38;5;241m>\u001B[39m\u001B[38;5;241m=\u001B[39m item_features\u001B[38;5;241m.\u001B[39mshape[\u001B[38;5;241m1\u001B[39m]:\n\u001B[0;32m--> 335\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[1;32m 336\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mThe item feature matrix specifies more \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 337\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mfeatures than there are estimated \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 338\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mfeature embeddings: \u001B[39m\u001B[38;5;132;01m{}\u001B[39;00m\u001B[38;5;124m vs \u001B[39m\u001B[38;5;132;01m{}\u001B[39;00m\u001B[38;5;124m.\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;241m.\u001B[39mformat(\n\u001B[1;32m 339\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mitem_embeddings\u001B[38;5;241m.\u001B[39mshape[\u001B[38;5;241m0\u001B[39m], item_features\u001B[38;5;241m.\u001B[39mshape[\u001B[38;5;241m1\u001B[39m]\n\u001B[1;32m 340\u001B[0m )\n\u001B[1;32m 341\u001B[0m )\n\u001B[1;32m 343\u001B[0m user_features \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_to_cython_dtype(user_features)\n\u001B[1;32m 344\u001B[0m item_features \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_to_cython_dtype(item_features)\n", + "\u001B[0;31mValueError\u001B[0m: The item feature matrix specifies more features than there are estimated feature embeddings: 831 vs 15963." + ] + } + ], + "source": [ + "model.predict(user_id=176549)" + ] + }, + { + "cell_type": "code", + "execution_count": 320, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] + }, + "execution_count": 320, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.arange(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 326, + "metadata": {}, + "outputs": [], + "source": [ + "user_id = model.mapping['users_mapping'][176549]\n", + "\n", + "scores = model.model.predict(user_id, np.arange(10))\n", + "top_items = np.argsort(-scores)[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 327, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([2, 1, 4, 7, 9, 5, 8, 6, 3, 0])" + ] + }, + "execution_count": 327, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "top_items" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" deleted file mode 100644 index 80e446b6..00000000 --- "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" +++ /dev/null @@ -1,5276 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "7780d9a2", - "metadata": {}, - "outputs": [], - "source": [ - "import warnings\n", - "warnings.filterwarnings('ignore')" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "e42a5585", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "import pandas as pd\n", - "import numpy as np\n", - "\n", - "from implicit.als import AlternatingLeastSquares\n", - "\n", - "from rectools.metrics import Precision, Recall, MAP, calc_metrics\n", - "from rectools.models import PopularModel, RandomModel, ImplicitALSWrapperModel\n", - "from rectools import Columns\n", - "from rectools.dataset import Dataset\n", - "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "\n", - "import matplotlib.pyplot as plt\n", - "from pathlib import Path\n", - "import typing as tp\n", - "from tqdm import tqdm\n", - "\n", - "from lightfm import LightFM\n", - "\n", - "from implicit.bpr import BayesianPersonalizedRanking\n", - "\n", - "from implicit.lmf import LogisticMatrixFactorization\n", - "\n", - "import optuna" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "8cd36e1a", - "metadata": {}, - "outputs": [], - "source": [ - "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "4cb722c3", - "metadata": {}, - "outputs": [], - "source": [ - "DATA_PATH = Path(\"../data\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "8195e56b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 2.71 s, sys: 627 ms, total: 3.34 s\n", - "Wall time: 3.69 s\n" - ] - } - ], - "source": [ - "%%time\n", - "users = pd.read_csv(DATA_PATH / 'users.csv')\n", - "items = pd.read_csv(DATA_PATH / 'items.csv')\n", - "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "01c2bdef", - "metadata": {}, - "outputs": [], - "source": [ - "Columns.Datetime = 'last_watch_dt'" - ] - }, - { - "cell_type": "markdown", - "id": "00b5584e", - "metadata": {}, - "source": [ - "# Preprocess Interactions" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "0a3b4b12", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
..................
5476246648596122252021-08-13760.0
547624754686296732021-04-13230849.0
5476248697262152972021-08-201830763.0
5476249384202161972021-04-196203100.0
547625031970944362021-08-15392145.0
\n", - "

5476251 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct\n", - "0 176549 9506 2021-05-11 4250 72.0\n", - "1 699317 1659 2021-05-29 8317 100.0\n", - "2 656683 7107 2021-05-09 10 0.0\n", - "3 864613 7638 2021-07-05 14483 100.0\n", - "4 964868 9506 2021-04-30 6725 100.0\n", - "... ... ... ... ... ...\n", - "5476246 648596 12225 2021-08-13 76 0.0\n", - "5476247 546862 9673 2021-04-13 2308 49.0\n", - "5476248 697262 15297 2021-08-20 18307 63.0\n", - "5476249 384202 16197 2021-04-19 6203 100.0\n", - "5476250 319709 4436 2021-08-15 3921 45.0\n", - "\n", - "[5476251 rows x 5 columns]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "260b1c48", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "user_id int64\n", - "item_id int64\n", - "last_watch_dt object\n", - "total_dur int64\n", - "watched_pct float64\n", - "dtype: object" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions.dtypes" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "fe2dbc06", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "user_id 0\n", - "item_id 0\n", - "last_watch_dt 0\n", - "total_dur 0\n", - "watched_pct 828\n", - "dtype: int64" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions.isna().sum()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "71f61e81", - "metadata": {}, - "outputs": [], - "source": [ - "interactions[Columns.Datetime] = pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "39646cb5", - "metadata": {}, - "outputs": [], - "source": [ - "interactions.dropna(inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "f98ae95d", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "interactions['watched_pct'].hist(bins=20);" - ] - }, - { - "cell_type": "markdown", - "id": "1a0ad9f8", - "metadata": {}, - "source": [ - "Делю график просмотра на 5 категорий, где: \n", - "от 0% до 20% = 1, \n", - "от 21% до 40% = 2, \n", - "... , \n", - "от 80% до 100% = 5" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "1424e744", - "metadata": {}, - "outputs": [], - "source": [ - "interactions[Columns.Weight] = np.where((interactions['watched_pct'] > 20), 2, 1)\n", - "interactions[Columns.Weight].mask(interactions['watched_pct'] > 40, 3, inplace=True)\n", - "interactions[Columns.Weight].mask(interactions['watched_pct'] > 60, 4, inplace=True)\n", - "interactions[Columns.Weight].mask(interactions['watched_pct'] > 80, 5, inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "052d2fb0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "interactions[Columns.Datetime].hist(bins=20)" - ] - }, - { - "cell_type": "markdown", - "id": "5adb80ee", - "metadata": {}, - "source": [ - "Вообще, видно, что кол-во пользователей растет" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "0fbd2bbc", - "metadata": {}, - "outputs": [], - "source": [ - "cold_users = interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts() == 1].index" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "150e1593", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'].hist(bins=20)" - ] - }, - { - "cell_type": "markdown", - "id": "b5fa83eb", - "metadata": {}, - "source": [ - "Для холодных пользователей, я бы рекомендовал айтемы с самый высоким просмотром в среднем по холодным пользователям" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "cca06e3f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n", - "

355162 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "10 791466 8199 2021-07-27 713 9.0 1\n", - "26 181144 10440 2021-08-08 27408 40.0 2\n", - "37 161176 10440 2021-07-29 22 0.0 1\n", - "38 21723 1819 2021-04-11 8535 100.0 5\n", - "60 77216 8143 2021-05-08 660 11.0 1\n", - "... ... ... ... ... ... ...\n", - "5476222 1007900 9728 2021-08-12 416 6.0 1\n", - "5476225 882138 4716 2021-05-21 1594 2.0 1\n", - "5476238 805174 13125 2021-06-27 1 0.0 1\n", - "5476246 648596 12225 2021-08-13 76 0.0 1\n", - "5476248 697262 15297 2021-08-20 18307 63.0 4\n", - "\n", - "[355162 rows x 6 columns]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users = interactions[interactions[Columns.User].isin(cold_users)]\n", - "hot_users = interactions[~interactions[Columns.User].isin(cold_users)]\n", - "cold_users" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "a691676f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n", - "

5475423 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "0 176549 9506 2021-05-11 4250 72.0 4\n", - "1 699317 1659 2021-05-29 8317 100.0 5\n", - "2 656683 7107 2021-05-09 10 0.0 1\n", - "3 864613 7638 2021-07-05 14483 100.0 5\n", - "4 964868 9506 2021-04-30 6725 100.0 5\n", - "... ... ... ... ... ... ...\n", - "5476246 648596 12225 2021-08-13 76 0.0 1\n", - "5476247 546862 9673 2021-04-13 2308 49.0 3\n", - "5476248 697262 15297 2021-08-20 18307 63.0 4\n", - "5476249 384202 16197 2021-04-19 6203 100.0 5\n", - "5476250 319709 4436 2021-08-15 3921 45.0 3\n", - "\n", - "[5475423 rows x 6 columns]" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hot_users" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "a64701c2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n", - "

6440 rows × 1 columns

\n", - "
" - ], - "text/plain": [ - " item_id\n", - "10440 45695\n", - "15297 39309\n", - "2657 20474\n", - "9728 15140\n", - "4740 11455\n", - "... ...\n", - "1946 1\n", - "13886 1\n", - "14090 1\n", - "5730 1\n", - "13125 1\n", - "\n", - "[6440 rows x 1 columns]" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users['item_id'].value_counts().to_frame()" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "cef9cfa6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users[['item_id', 'total_dur']].groupby('item_id').mean().sort_values(by='total_dur', ascending=False).head(10).index" - ] - }, - { - "cell_type": "markdown", - "id": "a52f311b", - "metadata": {}, - "source": [ - "# Делим на train и test" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "bd68d3fe", - "metadata": {}, - "outputs": [], - "source": [ - "max_date = hot_users[Columns.Datetime].max()" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "3092fe4b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: (4984443, 6)\n", - "test: (490980, 6)\n" - ] - } - ], - "source": [ - "train = interactions[interactions[Columns.Datetime] < max_date - pd.Timedelta(days=7)].copy()\n", - "test = interactions[interactions[Columns.Datetime] >= max_date - pd.Timedelta(days=7)].copy()\n", - "\n", - "print(f\"train: {train.shape}\")\n", - "print(f\"test: {test.shape}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "ec286bdc", - "metadata": {}, - "outputs": [], - "source": [ - "train.drop(train.query(\"total_dur < 300\").index, inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "c32fcaae", - "metadata": {}, - "outputs": [], - "source": [ - "drop_user = set(test[Columns.User]) - set(train[Columns.User])" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "7183cb6f", - "metadata": {}, - "outputs": [], - "source": [ - "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "1ff85593", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
9203219135822021-08-226975100.05
5420019793352021-08-16832.01
6473446144882021-08-196011100.05
84100105122021-08-15140.01
94890735142002021-08-16117928.02
.....................
54761695895899832021-08-21240343.03
547618859089286182021-08-21133523.02
5476191857162123602021-08-16110.01
5476201273558106052021-08-2134030100.05
547625031970944362021-08-15392145.03
\n", - "

333022 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "9 203219 13582 2021-08-22 6975 100.0 5\n", - "54 200197 9335 2021-08-16 83 2.0 1\n", - "64 73446 14488 2021-08-19 6011 100.0 5\n", - "84 10010 512 2021-08-15 14 0.0 1\n", - "94 890735 14200 2021-08-16 1179 28.0 2\n", - "... ... ... ... ... ... ...\n", - "5476169 589589 983 2021-08-21 2403 43.0 3\n", - "5476188 590892 8618 2021-08-21 1335 23.0 2\n", - "5476191 857162 12360 2021-08-16 11 0.0 1\n", - "5476201 273558 10605 2021-08-21 34030 100.0 5\n", - "5476250 319709 4436 2021-08-15 3921 45.0 3\n", - "\n", - "[333022 rows x 6 columns]" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "test" - ] - }, - { - "cell_type": "markdown", - "id": "b5eec6da", - "metadata": {}, - "source": [ - "# User preprocess" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "c57e2b2f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n", - "

840197 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " user_id age income sex kids_flg\n", - "0 973171 age_25_34 income_60_90 М 1\n", - "1 962099 age_18_24 income_20_40 М 0\n", - "2 1047345 age_45_54 income_40_60 Ж 0\n", - "3 721985 age_45_54 income_20_40 Ж 0\n", - "4 704055 age_35_44 income_60_90 Ж 0\n", - "... ... ... ... ... ...\n", - "840192 339025 age_65_inf income_0_20 Ж 0\n", - "840193 983617 age_18_24 income_20_40 Ж 1\n", - "840194 251008 NaN NaN NaN 0\n", - "840195 590706 NaN NaN Ж 0\n", - "840196 166555 age_65_inf income_20_40 Ж 0\n", - "\n", - "[840197 rows x 5 columns]" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "users" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "63996e92", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "user_id 0.000000\n", - "age 0.016776\n", - "income 0.017586\n", - "sex 0.016462\n", - "kids_flg 0.000000\n", - "dtype: float64" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "users.isnull().sum()/840197" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "24cc138a", - "metadata": {}, - "outputs": [], - "source": [ - "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" - ] - }, - { - "cell_type": "markdown", - "id": "c7f9a6e7", - "metadata": {}, - "source": [ - "Заменяю Nan'ы на Unknown" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "1286eb60", - "metadata": {}, - "outputs": [], - "source": [ - "users.fillna('Unknown', inplace=True)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "1ccccf0f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 973171 М sex\n", - "1 962099 М sex\n", - "3 721985 Ж sex\n", - "4 704055 Ж sex\n", - "5 1037719 М sex" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_features_frames = []\n", - "for feature in [\"sex\", \"age\", \"income\"]:\n", - " feature_frame = users.reindex(columns=[Columns.User, feature])\n", - " feature_frame.columns = [\"id\", \"value\"]\n", - " feature_frame[\"feature\"] = feature\n", - " user_features_frames.append(feature_frame)\n", - "user_features = pd.concat(user_features_frames)\n", - "user_features.head()" - ] - }, - { - "cell_type": "markdown", - "id": "b9220b0b", - "metadata": {}, - "source": [ - "# Item preprocess" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "8bbe9ee4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
.............................................
159586443seriesПолярный кругArctic Circle2018.0драмы, триллеры, криминалФинляндия, ГерманияNaN16.0NaNХанну СалоненИина Куустонен, Максимилиан Брюкнер, Пихла Вии...Во время погони за браконьерами по лесу, сотру...убийство, вирус, расследование преступления, н...
159592367seriesНадеждаNaN2020.0драмы, боевикиРоссия0.018.0NaNЕлена ХазановаВиктория Исакова, Александр Кузьмин, Алексей М...Оригинальный киносериал от создателей «Бывших»...Надежда, 2020, Россия
1596010632seriesСговорHassel2017.0драмы, триллеры, криминалРоссия0.018.0NaNЭшреф Рейбрук, Амир Камдин, Эрик ЭгерОла Рапас, Алиетт Офейм, Уильма Лиден, Шанти Р...Криминальная драма по мотивам романов о шведск...Сговор, 2017, Россия
159614538seriesСреди камнейDarklands2019.0драмы, спорт, криминалРоссия0.018.0NaNМарк О’Коннор, Конор МакМахонДэйн Уайт О’Хара, Томас Кэйн-Бирн, Джудит Родд...Семнадцатилетний Дэмиен мечтает вырваться за п...Среди, камней, 2019, Россия
159623206seriesГошаNaN2019.0комедииРоссия0.016.0NaNМихаил МироновМкртыч Арзуманян, Виктория РунцоваДобродушный Гоша не может выйти из дома, чтобы...Гоша, 2019, Россия
\n", - "

15963 rows × 14 columns

\n", - "
" - ], - "text/plain": [ - " item_id content_type title title_orig \\\n", - "0 10711 film Поговори с ней Hable con ella \n", - "1 2508 film Голые перцы Search Party \n", - "2 10716 film Тактическая сила Tactical Force \n", - "3 7868 film 45 лет 45 Years \n", - "4 16268 film Все решает мгновение NaN \n", - "... ... ... ... ... \n", - "15958 6443 series Полярный круг Arctic Circle \n", - "15959 2367 series Надежда NaN \n", - "15960 10632 series Сговор Hassel \n", - "15961 4538 series Среди камней Darklands \n", - "15962 3206 series Гоша NaN \n", - "\n", - " release_year genres \\\n", - "0 2002.0 драмы, зарубежные, детективы, мелодрамы \n", - "1 2014.0 зарубежные, приключения, комедии \n", - "2 2011.0 криминал, зарубежные, триллеры, боевики, комедии \n", - "3 2015.0 драмы, зарубежные, мелодрамы \n", - "4 1978.0 драмы, спорт, советские, мелодрамы \n", - "... ... ... \n", - "15958 2018.0 драмы, триллеры, криминал \n", - "15959 2020.0 драмы, боевики \n", - "15960 2017.0 драмы, триллеры, криминал \n", - "15961 2019.0 драмы, спорт, криминал \n", - "15962 2019.0 комедии \n", - "\n", - " countries for_kids age_rating studios \\\n", - "0 Испания NaN 16.0 NaN \n", - "1 США NaN 16.0 NaN \n", - "2 Канада NaN 16.0 NaN \n", - "3 Великобритания NaN 16.0 NaN \n", - "4 СССР NaN 12.0 Ленфильм \n", - "... ... ... ... ... \n", - "15958 Финляндия, Германия NaN 16.0 NaN \n", - "15959 Россия 0.0 18.0 NaN \n", - "15960 Россия 0.0 18.0 NaN \n", - "15961 Россия 0.0 18.0 NaN \n", - "15962 Россия 0.0 16.0 NaN \n", - "\n", - " directors \\\n", - "0 Педро Альмодовар \n", - "1 Скот Армстронг \n", - "2 Адам П. Калтраро \n", - "3 Эндрю Хэй \n", - "4 Виктор Садовский \n", - "... ... \n", - "15958 Ханну Салонен \n", - "15959 Елена Хазанова \n", - "15960 Эшреф Рейбрук, Амир Камдин, Эрик Эгер \n", - "15961 Марк О’Коннор, Конор МакМахон \n", - "15962 Михаил Миронов \n", - "\n", - " actors \\\n", - "0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n", - "1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n", - "2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n", - "3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n", - "4 Александр Абдулов, Александр Демьяненко, Алекс... \n", - "... ... \n", - "15958 Иина Куустонен, Максимилиан Брюкнер, Пихла Вии... \n", - "15959 Виктория Исакова, Александр Кузьмин, Алексей М... \n", - "15960 Ола Рапас, Алиетт Офейм, Уильма Лиден, Шанти Р... \n", - "15961 Дэйн Уайт О’Хара, Томас Кэйн-Бирн, Джудит Родд... \n", - "15962 Мкртыч Арзуманян, Виктория Рунцова \n", - "\n", - " description \\\n", - "0 Мелодрама легендарного Педро Альмодовара «Пого... \n", - "1 Уморительная современная комедия на популярную... \n", - "2 Профессиональный рестлер Стив Остин («Все или ... \n", - "3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n", - "4 Расчетливая чаровница из советского кинохита «... \n", - "... ... \n", - "15958 Во время погони за браконьерами по лесу, сотру... \n", - "15959 Оригинальный киносериал от создателей «Бывших»... \n", - "15960 Криминальная драма по мотивам романов о шведск... \n", - "15961 Семнадцатилетний Дэмиен мечтает вырваться за п... \n", - "15962 Добродушный Гоша не может выйти из дома, чтобы... \n", - "\n", - " keywords \n", - "0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n", - "1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n", - "2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n", - "3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n", - "4 Все, решает, мгновение, 1978, СССР, сильные, ж... \n", - "... ... \n", - "15958 убийство, вирус, расследование преступления, н... \n", - "15959 Надежда, 2020, Россия \n", - "15960 Сговор, 2017, Россия \n", - "15961 Среди, камней, 2019, Россия \n", - "15962 Гоша, 2019, Россия \n", - "\n", - "[15963 rows x 14 columns]" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "72fa86a0", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "item_id 0\n", - "content_type 0\n", - "title 0\n", - "title_orig 4745\n", - "release_year 98\n", - "genres 0\n", - "countries 37\n", - "for_kids 15397\n", - "age_rating 2\n", - "studios 14898\n", - "directors 1509\n", - "actors 2619\n", - "description 2\n", - "keywords 423\n", - "dtype: int64" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items.isna().sum()" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "50f0611f", - "metadata": {}, - "outputs": [], - "source": [ - "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "280cf47d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "item_id 0\n", - "content_type 0\n", - "title 0\n", - "title_orig 3775\n", - "release_year 31\n", - "genres 0\n", - "countries 14\n", - "for_kids 13415\n", - "age_rating 1\n", - "studios 13047\n", - "directors 939\n", - "actors 1858\n", - "description 0\n", - "keywords 388\n", - "dtype: int64" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items.isna().sum()" - ] - }, - { - "cell_type": "markdown", - "id": "eddd93b5", - "metadata": {}, - "source": [ - "# Genre" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "bf6da75c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 драмы genre\n", - "0 10711 зарубежные genre\n", - "0 10711 детективы genre\n", - "0 10711 мелодрамы genre\n", - "1 2508 зарубежные genre" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Explode genres to flatten table\n", - "items[\"genre\"] = items[\"genres\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "genre_feature = items[[\"item_id\", \"genre\"]].explode(\"genre\")\n", - "genre_feature.columns = [\"id\", \"value\"]\n", - "genre_feature[\"feature\"] = \"genre\"\n", - "genre_feature.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "913b9c27", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n", - "

36128 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 драмы genre\n", - "0 10711 зарубежные genre\n", - "0 10711 детективы genre\n", - "0 10711 мелодрамы genre\n", - "1 2508 зарубежные genre\n", - "... ... ... ...\n", - "15960 10632 криминал genre\n", - "15961 4538 драмы genre\n", - "15961 4538 спорт genre\n", - "15961 4538 криминал genre\n", - "15962 3206 комедии genre\n", - "\n", - "[36128 rows x 3 columns]" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "genre_feature" - ] - }, - { - "cell_type": "markdown", - "id": "478bf1e3", - "metadata": {}, - "source": [ - "# Content" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "65f8b5d9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
............
159586443seriescontent_type
159592367seriescontent_type
1596010632seriescontent_type
159614538seriescontent_type
159623206seriescontent_type
\n", - "

13963 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 film content_type\n", - "1 2508 film content_type\n", - "2 10716 film content_type\n", - "3 7868 film content_type\n", - "4 16268 film content_type\n", - "... ... ... ...\n", - "15958 6443 series content_type\n", - "15959 2367 series content_type\n", - "15960 10632 series content_type\n", - "15961 4538 series content_type\n", - "15962 3206 series content_type\n", - "\n", - "[13963 rows x 3 columns]" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", - "content_feature.columns = [\"id\", \"value\"]\n", - "content_feature[\"feature\"] = \"content_type\"\n", - "content_feature" - ] - }, - { - "cell_type": "markdown", - "id": "a62ebee4", - "metadata": {}, - "source": [ - "# Actors" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "fdc43660", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
............
159614538джудит роддиactors
159614538марк о’халлоранactors
159614538джимми смоллхорнactors
159623206мкртыч арзуманянactors
159623206виктория рунцоваactors
\n", - "

128926 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 адольфо фернандес actors\n", - "0 10711 ана фернандес actors\n", - "0 10711 дарио грандинетти actors\n", - "0 10711 джеральдин чаплин actors\n", - "0 10711 елена анайя actors\n", - "... ... ... ...\n", - "15961 4538 джудит родди actors\n", - "15961 4538 марк о’халлоран actors\n", - "15961 4538 джимми смоллхорн actors\n", - "15962 3206 мкртыч арзуманян actors\n", - "15962 3206 виктория рунцова actors\n", - "\n", - "[128926 rows x 3 columns]" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items[\"actors\"] = items[\"actors\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "actors_feature = items[[\"item_id\", \"actors\"]].explode(\"actors\")\n", - "actors_feature.columns = [\"id\", \"value\"]\n", - "actors_feature[\"feature\"] = \"actors\"\n", - "actors_feature" - ] - }, - { - "cell_type": "markdown", - "id": "73801647", - "metadata": {}, - "source": [ - "# Keywords" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "594abe5c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
............
1596145382019keywords
159614538россияkeywords
159623206гошаkeywords
1596232062019keywords
159623206россияkeywords
\n", - "

341629 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 поговори keywords\n", - "0 10711 ней keywords\n", - "0 10711 2002 keywords\n", - "0 10711 испания keywords\n", - "0 10711 друзья keywords\n", - "... ... ... ...\n", - "15961 4538 2019 keywords\n", - "15961 4538 россия keywords\n", - "15962 3206 гоша keywords\n", - "15962 3206 2019 keywords\n", - "15962 3206 россия keywords\n", - "\n", - "[341629 rows x 3 columns]" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items[\"keywords\"] = items[\"keywords\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "keywords_feature = items[[\"item_id\", \"keywords\"]].explode(\"keywords\")\n", - "keywords_feature.columns = [\"id\", \"value\"]\n", - "keywords_feature[\"feature\"] = \"keywords\"\n", - "keywords_feature" - ] - }, - { - "cell_type": "markdown", - "id": "d3eb0a37", - "metadata": {}, - "source": [ - "# Countries\t" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "8eb8a621", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
............
159586443Финляндия, Германияcountries
159592367Россияcountries
1596010632Россияcountries
159614538Россияcountries
159623206Россияcountries
\n", - "

13963 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 Испания countries\n", - "1 2508 США countries\n", - "2 10716 Канада countries\n", - "3 7868 Великобритания countries\n", - "4 16268 СССР countries\n", - "... ... ... ...\n", - "15958 6443 Финляндия, Германия countries\n", - "15959 2367 Россия countries\n", - "15960 10632 Россия countries\n", - "15961 4538 Россия countries\n", - "15962 3206 Россия countries\n", - "\n", - "[13963 rows x 3 columns]" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "country_feature = items.reindex(columns=[Columns.Item, \"countries\"])\n", - "country_feature.columns = [\"id\", \"value\"]\n", - "country_feature[\"feature\"] = \"countries\"\n", - "country_feature" - ] - }, - { - "cell_type": "markdown", - "id": "5e477ee1", - "metadata": {}, - "source": [ - "# Age Rating" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "0894154a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
............
15958644316.0age_feature
15959236718.0age_feature
159601063218.0age_feature
15961453818.0age_feature
15962320616.0age_feature
\n", - "

13963 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 16.0 age_feature\n", - "1 2508 16.0 age_feature\n", - "2 10716 16.0 age_feature\n", - "3 7868 16.0 age_feature\n", - "4 16268 12.0 age_feature\n", - "... ... ... ...\n", - "15958 6443 16.0 age_feature\n", - "15959 2367 18.0 age_feature\n", - "15960 10632 18.0 age_feature\n", - "15961 4538 18.0 age_feature\n", - "15962 3206 16.0 age_feature\n", - "\n", - "[13963 rows x 3 columns]" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", - "age_feature.columns = [\"id\", \"value\"]\n", - "age_feature[\"feature\"] = \"age_feature\"\n", - "age_feature" - ] - }, - { - "cell_type": "markdown", - "id": "c09df1ec", - "metadata": {}, - "source": [ - "# Studios" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "ff937b4f", - "metadata": {}, - "outputs": [], - "source": [ - "items.fillna('Unknown', inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "cee42708", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711Unknownstudios
12508Unknownstudios
210716Unknownstudios
37868Unknownstudios
416268Ленфильмstudios
............
159586443Unknownstudios
159592367Unknownstudios
1596010632Unknownstudios
159614538Unknownstudios
159623206Unknownstudios
\n", - "

13963 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 Unknown studios\n", - "1 2508 Unknown studios\n", - "2 10716 Unknown studios\n", - "3 7868 Unknown studios\n", - "4 16268 Ленфильм studios\n", - "... ... ... ...\n", - "15958 6443 Unknown studios\n", - "15959 2367 Unknown studios\n", - "15960 10632 Unknown studios\n", - "15961 4538 Unknown studios\n", - "15962 3206 Unknown studios\n", - "\n", - "[13963 rows x 3 columns]" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", - "studios_feature.columns = [\"id\", \"value\"]\n", - "studios_feature[\"feature\"] = \"studios\"\n", - "studios_feature" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "6158b0bd", - "metadata": {}, - "outputs": [], - "source": [ - "item_features = pd.concat((genre_feature, content_feature, studios_feature, age_feature, country_feature))" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "ea1feadd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
159586443Финляндия, Германияcountries
159592367Россияcountries
1596010632Россияcountries
159614538Россияcountries
159623206Россияcountries
\n", - "

91980 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 драмы genre\n", - "0 10711 зарубежные genre\n", - "0 10711 детективы genre\n", - "0 10711 мелодрамы genre\n", - "1 2508 зарубежные genre\n", - "... ... ... ...\n", - "15958 6443 Финляндия, Германия countries\n", - "15959 2367 Россия countries\n", - "15960 10632 Россия countries\n", - "15961 4538 Россия countries\n", - "15962 3206 Россия countries\n", - "\n", - "[91980 rows x 3 columns]" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "item_features" - ] - }, - { - "cell_type": "markdown", - "id": "09b8d756", - "metadata": {}, - "source": [ - "# Metrics" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "b082e667", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Precision@1': Precision(k=1),\n", - " 'Precision@2': Precision(k=2),\n", - " 'Precision@3': Precision(k=3),\n", - " 'Precision@4': Precision(k=4),\n", - " 'Precision@5': Precision(k=5),\n", - " 'Precision@6': Precision(k=6),\n", - " 'Precision@7': Precision(k=7),\n", - " 'Precision@8': Precision(k=8),\n", - " 'Precision@9': Precision(k=9),\n", - " 'Precision@10': Precision(k=10),\n", - " 'Recall@1': Recall(k=1),\n", - " 'Recall@2': Recall(k=2),\n", - " 'Recall@3': Recall(k=3),\n", - " 'Recall@4': Recall(k=4),\n", - " 'Recall@5': Recall(k=5),\n", - " 'Recall@6': Recall(k=6),\n", - " 'Recall@7': Recall(k=7),\n", - " 'Recall@8': Recall(k=8),\n", - " 'Recall@9': Recall(k=9),\n", - " 'Recall@10': Recall(k=10),\n", - " 'MAP@1': MAP(k=1, divide_by_k=False),\n", - " 'MAP@2': MAP(k=2, divide_by_k=False),\n", - " 'MAP@3': MAP(k=3, divide_by_k=False),\n", - " 'MAP@4': MAP(k=4, divide_by_k=False),\n", - " 'MAP@5': MAP(k=5, divide_by_k=False),\n", - " 'MAP@6': MAP(k=6, divide_by_k=False),\n", - " 'MAP@7': MAP(k=7, divide_by_k=False),\n", - " 'MAP@8': MAP(k=8, divide_by_k=False),\n", - " 'MAP@9': MAP(k=9, divide_by_k=False),\n", - " 'MAP@10': MAP(k=10, divide_by_k=False)}" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "metrics_name = {\n", - " 'Precision': Precision,\n", - " 'Recall': Recall,\n", - " 'MAP': MAP,\n", - "}\n", - "\n", - "metrics = {}\n", - "for metric_name, metric in metrics_name.items():\n", - " for k in range(1, 11):\n", - " metrics[f'{metric_name}@{k}'] = metric(k=k)\n", - "metrics" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "864a7990", - "metadata": {}, - "outputs": [], - "source": [ - "K_RECOS = 10\n", - "RANDOM_STATE = 42\n", - "NUM_THREADS = 8\n", - "N_FACTORS = (32,)\n", - "N_EPOCHS = 1 # Lightfm\n", - "USER_ALPHA = 0 # Lightfm\n", - "ITEM_ALPHA = 0 # Lightfm\n", - "LEARNING_RATE = 0.05 # Lightfm" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "12662152", - "metadata": {}, - "outputs": [], - "source": [ - "models = {}\n", - "implicit_models = {\n", - " 'ALS': AlternatingLeastSquares,\n", - "}\n", - "for implicit_name, implicit_model in implicit_models.items():\n", - " for is_fitting_features in (True, False):\n", - " for n_factors in N_FACTORS:\n", - " models[f\"{implicit_name}_{n_factors}_{is_fitting_features}\"] = (\n", - " ImplicitALSWrapperModel(\n", - " model=implicit_model(\n", - " factors=n_factors, \n", - " random_state=RANDOM_STATE, \n", - " num_threads=NUM_THREADS,\n", - " ),\n", - " fit_features_together=is_fitting_features,\n", - " )\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "6f9ef4f0", - "metadata": {}, - "outputs": [], - "source": [ - "lightfm_losses = ('logistic', 'bpr', 'warp')\n", - "\n", - "for loss in lightfm_losses:\n", - " for n_factors in N_FACTORS:\n", - " models[f\"LightFM_{loss}_{n_factors}\"] = LightFMWrapperModel(\n", - " LightFM(\n", - " no_components=n_factors, \n", - " loss=loss, \n", - " random_state=RANDOM_STATE,\n", - " learning_rate=LEARNING_RATE,\n", - " user_alpha=USER_ALPHA,\n", - " item_alpha=ITEM_ALPHA,\n", - " ),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS,\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "21773201", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'ALS_32_True': ,\n", - " 'ALS_32_False': ,\n", - " 'LightFM_logistic_32': ,\n", - " 'LightFM_bpr_32': ,\n", - " 'LightFM_warp_32': }" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "models" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "125de2fc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'content_type', 'genre'}" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "set(item_features.feature)" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "6288eea7", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 1.35 s, sys: 79.5 ms, total: 1.43 s\n", - "Wall time: 1.43 s\n" - ] - } - ], - "source": [ - "%%time\n", - "dataset = Dataset.construct(\n", - " interactions_df=train,\n", - " user_features_df=user_features,\n", - " cat_user_features=[\"sex\", \"age\", \"income\"],\n", - " item_features_df=item_features,\n", - " cat_item_features=['content_type', 'genre'])" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "d027f149", - "metadata": {}, - "outputs": [], - "source": [ - "TEST_USERS = test[Columns.User].unique()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "70bc6f59", - "metadata": {}, - "outputs": [], - "source": [ - " model = LightFMWrapperModel(LightFM(k=5,\n", - " learning_rate=learning_rate,\n", - " loss=loss), \n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS)" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "c99924ca", - "metadata": {}, - "outputs": [], - "source": [ - "model = LightFMWrapperModel(\n", - " LightFM(\n", - " k=5,\n", - " no_components=32, \n", - " loss='warp', \n", - " random_state=RANDOM_STATE,\n", - " learning_rate=0.08165160206425184,\n", - " user_alpha=USER_ALPHA,\n", - " item_alpha=ITEM_ALPHA),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS) " - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "d3907c1d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model.fit(dataset)" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "id": "b2050a6e", - "metadata": {}, - "outputs": [], - "source": [ - "recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True,\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "id": "8c7da423", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idscorerank
0203219104404.9805491
1203219152974.9678702
220321941514.4776473
3203219138654.4307254
420321997284.3544635
...............
1129735857162373414.4367456
112973685716214214.1344087
1129737857162488014.0818358
1129738857162265714.0243259
1129739857162680913.95767710
\n", - "

1129740 rows × 4 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id score rank\n", - "0 203219 10440 4.980549 1\n", - "1 203219 15297 4.967870 2\n", - "2 203219 4151 4.477647 3\n", - "3 203219 13865 4.430725 4\n", - "4 203219 9728 4.354463 5\n", - "... ... ... ... ...\n", - "1129735 857162 3734 14.436745 6\n", - "1129736 857162 142 14.134408 7\n", - "1129737 857162 4880 14.081835 8\n", - "1129738 857162 2657 14.024325 9\n", - "1129739 857162 6809 13.957677 10\n", - "\n", - "[1129740 rows x 4 columns]" - ] - }, - "execution_count": 78, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "recos" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "6bbe3ff3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.07682068366774675" - ] - }, - "execution_count": 79, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "calc_metrics(metrics, recos, test, train)['MAP@10']" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "51b77a4b", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'model_quality' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/tmp/ipykernel_23602/1194377468.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mmetric_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcalc_metrics\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmetrics\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrecos\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrain\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmodel_quality\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmetric_values\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mNameError\u001b[0m: name 'model_quality' is not defined" - ] - } - ], - "source": [ - "metric_values = calc_metrics(metrics, recos, test, train)\n", - "model_quality.update(metric_values)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2b6345c1", - "metadata": {}, - "outputs": [], - "source": [ - "recos" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "id": "2d847fd3", - "metadata": {}, - "outputs": [], - "source": [ - "recos['rank'] = recos.groupby('user_id')['user_id'].rank(method='first')" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "id": "9d12a9b6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idscorerank
0203219104404.9805491.0
1203219152974.9678702.0
220321941514.4776473.0
3203219138654.4307254.0
420321997284.3544635.0
...............
1129735857162373414.4367456.0
112973685716214214.1344087.0
1129737857162488014.0818358.0
1129738857162265714.0243259.0
1129739857162680913.95767710.0
\n", - "

1129740 rows × 4 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id score rank\n", - "0 203219 10440 4.980549 1.0\n", - "1 203219 15297 4.967870 2.0\n", - "2 203219 4151 4.477647 3.0\n", - "3 203219 13865 4.430725 4.0\n", - "4 203219 9728 4.354463 5.0\n", - "... ... ... ... ...\n", - "1129735 857162 3734 14.436745 6.0\n", - "1129736 857162 142 14.134408 7.0\n", - "1129737 857162 4880 14.081835 8.0\n", - "1129738 857162 2657 14.024325 9.0\n", - "1129739 857162 6809 13.957677 10.0\n", - "\n", - "[1129740 rows x 4 columns]" - ] - }, - "execution_count": 82, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "recos" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "id": "d3eead34", - "metadata": {}, - "outputs": [], - "source": [ - "recos = recos[['user_id', 'item_id']]\n", - "recos.to_csv('LightFM_after_optuna.csv.gz', index=False, compression='gzip')" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "ab782bd2", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Precision@1': 0.07723901074583532,\n", - " 'Recall@1': 0.039945025203155064,\n", - " 'Precision@2': 0.06777223077876325,\n", - " 'Recall@2': 0.06826845228559537,\n", - " 'Precision@3': 0.060972731188874404,\n", - " 'Recall@3': 0.09049343777050076,\n", - " 'Precision@4': 0.05550613415476127,\n", - " 'Recall@4': 0.10871933417276143,\n", - " 'Precision@5': 0.050597482606595634,\n", - " 'Recall@5': 0.12251909647186383,\n", - " 'Precision@6': 0.0459235458306068,\n", - " 'Recall@6': 0.1321820062289563,\n", - " 'Precision@7': 0.041941382214374844,\n", - " 'Recall@7': 0.1398538669008927,\n", - " 'Precision@8': 0.038631676314904315,\n", - " 'Recall@8': 0.14618067736019413,\n", - " 'Precision@9': 0.03598468084103889,\n", - " 'Recall@9': 0.15248904141482145,\n", - " 'Precision@10': 0.03387593605606706,\n", - " 'Recall@10': 0.1588631307179617,\n", - " 'MAP@1': 0.039945025203155064,\n", - " 'MAP@2': 0.05480355385012115,\n", - " 'MAP@3': 0.06281691802625049,\n", - " 'MAP@4': 0.0678842944950224,\n", - " 'MAP@5': 0.07103949043829605,\n", - " 'MAP@6': 0.07292909703284091,\n", - " 'MAP@7': 0.07424621516323489,\n", - " 'MAP@8': 0.0752068879380646,\n", - " 'MAP@9': 0.076042345201511,\n", - " 'MAP@10': 0.07682068366774675}" - ] - }, - "execution_count": 84, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "metric_values" - ] - }, - { - "cell_type": "code", - "execution_count": 168, - "id": "b44853f7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Precision@1': 0.08459468550285906,\n", - " 'Recall@1': 0.043103367696718034,\n", - " 'Precision@2': 0.07092782410112061,\n", - " 'Recall@2': 0.07046014541694683,\n", - " 'Precision@3': 0.06248635379230436,\n", - " 'Recall@3': 0.0921280723507131,\n", - " 'Precision@4': 0.05624966806521855,\n", - " 'Recall@4': 0.10932894551338254,\n", - " 'Precision@5': 0.05087719298243397,\n", - " 'Recall@5': 0.12237920952417945,\n", - " 'Precision@6': 0.04632924389682875,\n", - " 'Recall@6': 0.1323848629683412,\n", - " 'Precision@7': 0.04247753591851333,\n", - " 'Recall@7': 0.1404981921258083,\n", - " 'Precision@8': 0.03938074247171915,\n", - " 'Recall@8': 0.14793166723537798,\n", - " 'Precision@9': 0.036883609404740884,\n", - " 'Recall@9': 0.15500874146216406,\n", - " 'Precision@10': 0.03488855842935579,\n", - " 'Recall@10': 0.16230490106911452,\n", - " 'MAP@1': 0.043103367696718034,\n", - " 'MAP@2': 0.05749557914551633,\n", - " 'MAP@3': 0.0653294074408595,\n", - " 'MAP@4': 0.07012030221603167,\n", - " 'MAP@5': 0.07311471593152033,\n", - " 'MAP@6': 0.07509192714707785,\n", - " 'MAP@7': 0.07646356744900325,\n", - " 'MAP@8': 0.07757984846454224,\n", - " 'MAP@9': 0.07852432437618763,\n", - " 'MAP@10': 0.07940775755218821}" - ] - }, - "execution_count": 168, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "metric_values" - ] - }, - { - "cell_type": "code", - "execution_count": 161, - "id": "0d5edb2b", - "metadata": { - "collapsed": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitting model ALS_32_True...\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, dataset, *args, **kwargs)\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \"\"\"\n\u001b[0;32m---> 55\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 56\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_fitted\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36m_fit\u001b[0;34m(self, dataset)\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit_features_together\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 71\u001b[0;31m user_factors, item_factors = fit_als_with_features_together(\n\u001b[0m\u001b[1;32m 72\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36mfit_als_with_features_together\u001b[0;34m(model, ui_csr, user_features, item_features, verbose)\u001b[0m\n\u001b[1;32m 315\u001b[0m )\n\u001b[1;32m 316\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 317\u001b[0;31m _fit_combined_factors_on_cpu_inplace(\n\u001b[0m\u001b[1;32m 318\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 319\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36m_fit_combined_factors_on_cpu_inplace\u001b[0;34m(model, ui_csr, user_factors, item_factors, n_user_explicit_factors, n_item_explicit_factors, verbose)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miterations\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mverbose\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m model.solver(\n\u001b[0m\u001b[1;32m 346\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[0muser_factors\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "%%time\n", - "results = []\n", - "for model_name, model in models.items():\n", - " print(f\"Fitting model {model_name}...\")\n", - " model_quality = {'model': model_name}\n", - "\n", - " model.fit(dataset)\n", - " recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True,\n", - " )\n", - " metric_values = calc_metrics(metrics, recos, test, train)\n", - " model_quality.update(metric_values)\n", - " results.append(model_quality)" - ] - }, - { - "cell_type": "markdown", - "id": "2c603783", - "metadata": {}, - "source": [ - "# Optuna" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "a17b8b66", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m[I 2022-12-09 17:13:21,142]\u001b[0m A new study created in memory with name: no-name-44cee810-24ee-4f4d-af33-ba725d146103\u001b[0m\n", - "\u001b[32m[I 2022-12-09 17:15:14,403]\u001b[0m Trial 0 finished with value: 0.025636581479650006 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.023009046673404, 'k': 7, 'loss': 'bpr', 'no_components': 57}. Best is trial 0 with value: 0.025636581479650006.\u001b[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.025636581479650006\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m[I 2022-12-09 17:17:17,369]\u001b[0m Trial 1 finished with value: 1.7682698542896463e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.9292650108371142, 'k': 5, 'loss': 'bpr', 'no_components': 54}. Best is trial 0 with value: 0.025636581479650006.\u001b[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 1.7682698542896463e-06\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m[I 2022-12-09 17:19:24,650]\u001b[0m Trial 2 finished with value: 5.655503042200033e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8504703081672879, 'k': 9, 'loss': 'bpr', 'no_components': 48}. Best is trial 0 with value: 0.025636581479650006.\u001b[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 5.655503042200033e-07\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[33m[W 2022-12-09 17:21:00,280]\u001b[0m Trial 3 failed because of the following error: KeyboardInterrupt()\u001b[0m\n", - "Traceback (most recent call last):\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", - " value_or_values = func(trial)\n", - " File \"/tmp/ipykernel_24970/801119696.py\", line 34, in objective\n", - " model.fit(dataset)\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\", line 55, in fit\n", - " self._fit(dataset, *args, **kwargs)\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\", line 71, in _fit\n", - " user_factors, item_factors = fit_als_with_features_together(\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\", line 317, in fit_als_with_features_together\n", - " _fit_combined_factors_on_cpu_inplace(\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\", line 345, in _fit_combined_factors_on_cpu_inplace\n", - " model.solver(\n", - "KeyboardInterrupt\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/tmp/ipykernel_24970/801119696.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 43\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[0mstudy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptuna\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_study\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdirection\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'maximize'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 45\u001b[0;31m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobjective\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_trials\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 417\u001b[0m \"\"\"\n\u001b[1;32m 418\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 419\u001b[0;31m _optimize(\n\u001b[0m\u001b[1;32m 420\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 421\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize\u001b[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 65\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn_jobs\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 66\u001b[0;31m _optimize_sequential(\n\u001b[0m\u001b[1;32m 67\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize_sequential\u001b[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 160\u001b[0;31m \u001b[0mfrozen_trial\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_run_trial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 161\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[0;31m# The following line mitigates memory problems that can be occurred in some\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 232\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc_err\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 233\u001b[0m ):\n\u001b[0;32m--> 234\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mfunc_err\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 235\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfrozen_trial\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 236\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 194\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mget_heartbeat_thread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_trial_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_storage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 195\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 196\u001b[0;31m \u001b[0mvalue_or_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 197\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTrialPruned\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[0;31m# TODO(mamu): Handle multi-objective cases.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/tmp/ipykernel_24970/801119696.py\u001b[0m in \u001b[0;36mobjective\u001b[0;34m(trial)\u001b[0m\n\u001b[1;32m 32\u001b[0m ),\n\u001b[1;32m 33\u001b[0m fit_features_together=True)\n\u001b[0;32m---> 34\u001b[0;31m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 35\u001b[0m recos = model.recommend(\n\u001b[1;32m 36\u001b[0m \u001b[0musers\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTEST_USERS\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, dataset, *args, **kwargs)\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \"\"\"\n\u001b[0;32m---> 55\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_fit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 56\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_fitted\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36m_fit\u001b[0;34m(self, dataset)\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit_features_together\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 71\u001b[0;31m user_factors, item_factors = fit_als_with_features_together(\n\u001b[0m\u001b[1;32m 72\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36mfit_als_with_features_together\u001b[0;34m(model, ui_csr, user_features, item_features, verbose)\u001b[0m\n\u001b[1;32m 315\u001b[0m )\n\u001b[1;32m 316\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 317\u001b[0;31m _fit_combined_factors_on_cpu_inplace(\n\u001b[0m\u001b[1;32m 318\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 319\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/implicit_als.py\u001b[0m in \u001b[0;36m_fit_combined_factors_on_cpu_inplace\u001b[0;34m(model, ui_csr, user_factors, item_factors, n_user_explicit_factors, n_item_explicit_factors, verbose)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miterations\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mverbose\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m model.solver(\n\u001b[0m\u001b[1;32m 346\u001b[0m \u001b[0mui_csr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[0muser_factors\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "dataset = Dataset.construct(\n", - " interactions_df=train,\n", - " user_features_df=user_features,\n", - " cat_user_features=[\"sex\", \"age\", \"income\"],\n", - " item_features_df=item_features,\n", - " cat_item_features=[ 'content_type','genre','studios', 'age_feature', 'countries'])\n", - "TEST_USERS = test[Columns.User].unique()\n", - "\n", - "def objective(trial):\n", - "\n", - " model_name = trial.suggest_categorical('recomender', ['LightFM', 'ALS'])\n", - " if model_name == 'LightFM':\n", - " learning_rate = trial.suggest_float('learning_rate', 1e-10, 1)\n", - " k = trial.suggest_int('k', 2, 10)\n", - " loss = trial.suggest_categorical('loss',['logistic', 'bpr', 'warp'])\n", - " no_components = trial.suggest_int('no_components', 32, 64)\n", - " model = LightFMWrapperModel(LightFM(k=k,\n", - " learning_rate=learning_rate,\n", - " loss=loss,\n", - " no_components = no_components), \n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS)\n", - " else:\n", - " factors = trial.suggest_int('factors',32, 64)\n", - " regularization = trial.suggest_float('regularization', 1e-4, 1e-2)\n", - " model = ImplicitALSWrapperModel(\n", - " model=AlternatingLeastSquares(\n", - " factors=factors, \n", - " random_state=RANDOM_STATE, \n", - " num_threads=NUM_THREADS,\n", - " regularization=regularization\n", - " ),\n", - " fit_features_together=True)\n", - " model.fit(dataset)\n", - " recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True)\n", - " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", - " print(\"MAP@10\", metric)\n", - " return metric\n", - "\n", - "study = optuna.create_study(direction = 'maximize')\n", - "study.optimize(objective, n_trials = 10)" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "99aae61e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'recomender': 'LightFM',\n", - " 'learning_rate': 0.08165160206425184,\n", - " 'k': 5,\n", - " 'loss': 'warp'}" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "study.best_params" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "1d149ce9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([203219, 505244, 200197, ..., 226430, 857162, 697262])" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "TEST_USERS" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "0c778c15", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Dataset(user_id_map=IdMap(external_ids=array([176549, 699317, 656683, ..., 882138, 805174, 648596])), item_id_map=IdMap(external_ids=array([ 9506, 1659, 7107, ..., 13516, 13019, 10542])), interactions=Interactions(df= user_id item_id weight last_watch_dt\n", - "0 0 0 4.0 2021-05-11\n", - "1 1 1 5.0 2021-05-29\n", - "2 2 2 1.0 2021-05-09\n", - "3 3 3 5.0 2021-07-05\n", - "4 4 0 5.0 2021-04-30\n", - "... ... ... ... ...\n", - "5476244 69618 219 5.0 2021-08-02\n", - "5476245 40050 132 1.0 2021-05-12\n", - "5476246 896762 318 1.0 2021-08-13\n", - "5476247 206582 2546 3.0 2021-04-13\n", - "5476249 7236 1609 5.0 2021-04-19\n", - "\n", - "[4984443 rows x 4 columns]), user_features=SparseFeatures(values=<896763x17 sparse matrix of type ''\n", - "\twith 2091336 stored elements in Compressed Sparse Row format>, names=(('sex', 'М'), ('sex', 'Ж'), ('sex', 'Unknown'), ('age', 'age_25_34'), ('age', 'age_18_24'), ('age', 'age_45_54'), ('age', 'age_35_44'), ('age', 'age_55_64'), ('age', 'age_65_inf'), ('age', 'Unknown'), ('income', 'income_60_90'), ('income', 'income_20_40'), ('income', 'income_40_60'), ('income', 'income_90_150'), ('income', 'income_0_20'), ('income', 'Unknown'), ('income', 'income_150_inf'))), item_features=SparseFeatures(values=<15464x96 sparse matrix of type ''\n", - "\twith 54961 stored elements in Compressed Sparse Row format>, names=(('content_type', 'film'), ('content_type', 'series'), ('genre', 'драмы'), ('genre', 'зарубежные'), ('genre', 'детективы'), ('genre', 'мелодрамы'), ('genre', 'приключения'), ('genre', 'комедии'), ('genre', 'криминал'), ('genre', 'триллеры'), ('genre', 'боевики'), ('genre', 'спорт'), ('genre', 'советские'), ('genre', 'фильмы'), ('genre', 'сказки'), ('genre', 'семейное'), ('genre', 'фэнтези'), ('genre', 'для детей'), ('genre', 'полнометражные'), ('genre', 'западные мультфильмы'), ('genre', 'русские'), ('genre', 'биография'), ('genre', 'экранизации'), ('genre', 'исторические'), ('genre', 'военные'), ('genre', 'ужасы'), ('genre', 'мистика'), ('genre', 'фильмы-спектакли'), ('genre', 'мюзиклы'), ('genre', 'короткометражные'), ('genre', 'детские'), ('genre', 'вестерн'), ('genre', 'мультфильмы'), ('genre', 'для взрослых'), ('genre', 'мультфильм'), ('genre', 'фантастика'), ('genre', 'документальное'), ('genre', 'историческое'), ('genre', 'концерт'), ('genre', 'познавательные'), ('genre', 'сериалы'), ('genre', 'про животных'), ('genre', 'музыка'), ('genre', 'реалити-шоу'), ('genre', 'фитнес'), ('genre', 'телешоу'), ('genre', 'научно-популярные'), ('genre', 'ток-шоу'), ('genre', 'молодежные'), ('genre', 'стендап'), ('genre', 'хочу всё знать'), ('genre', 'русские мультфильмы'), ('genre', 'развитие'), ('genre', 'детские песни'), ('genre', 'аниме'), ('genre', 'музыкальные'), ('genre', 'мультсериалы'), ('genre', 'для самых маленьких'), ('genre', 'no_genre'), ('genre', 'развлекательные'), ('genre', 'караоке'), ('genre', 'фильмы hbo'), ('genre', 'катастрофы'), ('genre', 'медицинские'), ('genre', 'передачи'), ('genre', 'мировая классика'), ('genre', 'артхаус'), ('genre', 'дорамы'), ('genre', 'воспитание детей'), ('genre', 'короткий метр'), ('genre', 'интервью'), ('genre', 'по комиксам'), ('genre', 'увлечения'), ('genre', 'охота и рыбалка'), ('genre', 'популярное'), ('genre', 'реалити'), ('genre', 'футбол'), ('genre', 'романтика'), ('genre', 'фильм-нуар'), ('genre', 'тележурналы'), ('genre', 'живая природа'), ('genre', 'немое кино'), ('genre', 'единоборства'), ('genre', 'шоу'), ('genre', 'юмор'), ('genre', 'вокруг света'), ('genre', 'анимация'), ('genre', 'кулинария'), ('genre', 'индийское кино'), ('genre', 'о знаменитостях'), ('genre', '18+'), ('genre', 'токшоу'), ('genre', 'комиксы'), ('genre', 'красота и здоровье'), ('genre', 'образование'), ('genre', 'рекомендуем'))))" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "cc9c030d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
547624443858578292021-08-026804100.05
547624578673248802021-05-127530.01
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476249384202161972021-04-196203100.05
\n", - "

4984443 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "0 176549 9506 2021-05-11 4250 72.0 4\n", - "1 699317 1659 2021-05-29 8317 100.0 5\n", - "2 656683 7107 2021-05-09 10 0.0 1\n", - "3 864613 7638 2021-07-05 14483 100.0 5\n", - "4 964868 9506 2021-04-30 6725 100.0 5\n", - "... ... ... ... ... ... ...\n", - "5476244 438585 7829 2021-08-02 6804 100.0 5\n", - "5476245 786732 4880 2021-05-12 753 0.0 1\n", - "5476246 648596 12225 2021-08-13 76 0.0 1\n", - "5476247 546862 9673 2021-04-13 2308 49.0 3\n", - "5476249 384202 16197 2021-04-19 6203 100.0 5\n", - "\n", - "[4984443 rows x 6 columns]" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "train" - ] - }, - { - "cell_type": "code", - "execution_count": 120, - "id": "5e5009e5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywordsgenre
41644filmОчень женские историиUnknown2020.0мелодрамы, русские, комедииРоссияUnknown18.0UnknownАнна Саруханова, Антон Бильжо, Лика Ятковская,...[анастасия пронина, анна михалкова, анна слю, ...Киноальманах из пяти короткометражных фильмов,...[очень, женские, истории, 2020, россия, друзья...[мелодрамы, русские, комедии]
\n", - "
" - ], - "text/plain": [ - " item_id content_type title title_orig release_year \\\n", - "4164 4 film Очень женские истории Unknown 2020.0 \n", - "\n", - " genres countries for_kids age_rating studios \\\n", - "4164 мелодрамы, русские, комедии Россия Unknown 18.0 Unknown \n", - "\n", - " directors \\\n", - "4164 Анна Саруханова, Антон Бильжо, Лика Ятковская,... \n", - "\n", - " actors \\\n", - "4164 [анастасия пронина, анна михалкова, анна слю, ... \n", - "\n", - " description \\\n", - "4164 Киноальманах из пяти короткометражных фильмов,... \n", - "\n", - " keywords \\\n", - "4164 [очень, женские, истории, 2020, россия, друзья... \n", - "\n", - " genre \n", - "4164 [мелодрамы, русские, комедии] " - ] - }, - "execution_count": 120, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items[items['item_id'] == 4]" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "id": "a30929c1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_idageincomesexkids_flg
1496621age_25_34income_20_40Ж1
\n", - "
" - ], - "text/plain": [ - " user_id age income sex kids_flg\n", - "149662 1 age_25_34 income_20_40 Ж 1" - ] - }, - "execution_count": 125, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "users[users['user_id'] == 1]" - ] - }, - { - "cell_type": "markdown", - "id": "43411998", - "metadata": {}, - "source": [ - " ## Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. " - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "62bf8c5b", - "metadata": { - "collapsed": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: nmslib in /home/rezarayev/anaconda3/lib/python3.8/site-packages (2.1.1)\n", - "Collecting pybind11<2.6.2\n", - " Using cached pybind11-2.6.1-py2.py3-none-any.whl (188 kB)\n", - "Requirement already satisfied: psutil in /home/rezarayev/anaconda3/lib/python3.8/site-packages (from nmslib) (5.8.0)\n", - "Requirement already satisfied: numpy>=1.10.0 in /home/rezarayev/anaconda3/lib/python3.8/site-packages (from nmslib) (1.22.2)\n", - "\u001b[33mWARNING: Error parsing requirements for pybind11: [Errno 2] Нет такого файла или каталога: '/home/rezarayev/anaconda3/lib/python3.8/site-packages/pybind11-2.9.2.dist-info/METADATA'\u001b[0m\n", - "Installing collected packages: pybind11\n", - " Attempting uninstall: pybind11\n", - " Found existing installation: pybind11 2.9.2\n", - "\u001b[31mERROR: Could not install packages due to an OSError: [Errno 2] Нет такого файла или каталога: '/home/rezarayev/anaconda3/lib/python3.8/site-packages/pybind11-2.9.2.dist-info/RECORD'\n", - "\u001b[0m\n", - "Note: you may need to restart the kernel to use updated packages.\n" - ] - } - ], - "source": [ - "pip install nmslib" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "id": "2aa5abcf", - "metadata": {}, - "outputs": [], - "source": [ - "import nmslib\n", - "import time" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "id": "62d4c831", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Dataset(user_id_map=IdMap(external_ids=array([ 176549, 699317, 864613, ..., 92876, 1007900, 882138])), item_id_map=IdMap(external_ids=array([ 9506, 1659, 7638, ..., 14064, 11002, 10542])), interactions=Interactions(df= user_id item_id weight last_watch_dt\n", - "0 0 0 4.0 2021-05-11\n", - "1 1 1 5.0 2021-05-29\n", - "3 2 2 5.0 2021-07-05\n", - "4 3 0 5.0 2021-04-30\n", - "5 4 3 5.0 2021-05-13\n", - "... ... ... ... ...\n", - "5476242 233253 46 5.0 2021-04-21\n", - "5476244 54444 166 5.0 2021-08-02\n", - "5476245 173668 100 1.0 2021-05-12\n", - "5476247 165648 2141 3.0 2021-04-13\n", - "5476249 115506 1328 5.0 2021-04-19\n", - "\n", - "[3832259 rows x 4 columns]), user_features=SparseFeatures(values=<756545x17 sparse matrix of type ''\n", - "\twith 1759959 stored elements in Compressed Sparse Row format>, names=(('sex', 'М'), ('sex', 'Ж'), ('sex', 'Unknown'), ('age', 'age_25_34'), ('age', 'age_18_24'), ('age', 'age_45_54'), ('age', 'age_35_44'), ('age', 'age_55_64'), ('age', 'age_65_inf'), ('age', 'Unknown'), ('income', 'income_60_90'), ('income', 'income_20_40'), ('income', 'income_40_60'), ('income', 'income_90_150'), ('income', 'income_0_20'), ('income', 'Unknown'), ('income', 'income_150_inf'))), item_features=SparseFeatures(values=<13963x809 sparse matrix of type ''\n", - "\twith 91980 stored elements in Compressed Sparse Row format>, names=(('content_type', 'film'), ('content_type', 'series'), ('genre', 'драмы'), ('genre', 'зарубежные'), ('genre', 'детективы'), ('genre', 'мелодрамы'), ('genre', 'приключения'), ('genre', 'комедии'), ('genre', 'криминал'), ('genre', 'триллеры'), ('genre', 'боевики'), ('genre', 'спорт'), ('genre', 'советские'), ('genre', 'фильмы'), ('genre', 'сказки'), ('genre', 'семейное'), ('genre', 'фэнтези'), ('genre', 'для детей'), ('genre', 'полнометражные'), ('genre', 'западные мультфильмы'), ('genre', 'русские'), ('genre', 'биография'), ('genre', 'экранизации'), ('genre', 'исторические'), ('genre', 'военные'), ('genre', 'ужасы'), ('genre', 'мистика'), ('genre', 'фильмы-спектакли'), ('genre', 'мюзиклы'), ('genre', 'короткометражные'), ('genre', 'детские'), ('genre', 'вестерн'), ('genre', 'мультфильмы'), ('genre', 'для взрослых'), ('genre', 'мультфильм'), ('genre', 'фантастика'), ('genre', 'документальное'), ('genre', 'историческое'), ('genre', 'концерт'), ('genre', 'познавательные'), ('genre', 'музыка'), ('genre', 'реалити-шоу'), ('genre', 'фитнес'), ('genre', 'телешоу'), ('genre', 'научно-популярные'), ('genre', 'ток-шоу'), ('genre', 'молодежные'), ('genre', 'стендап'), ('genre', 'хочу всё знать'), ('genre', 'про животных'), ('genre', 'русские мультфильмы'), ('genre', 'развитие'), ('genre', 'аниме'), ('genre', 'музыкальные'), ('genre', 'сериалы'), ('genre', 'детские песни'), ('genre', 'мультсериалы'), ('genre', 'для самых маленьких'), ('genre', 'no_genre'), ('genre', 'развлекательные'), ('genre', 'караоке'), ('genre', 'фильмы hbo'), ('genre', 'катастрофы'), ('genre', 'медицинские'), ('genre', 'передачи'), ('genre', 'мировая классика'), ('genre', 'артхаус'), ('genre', 'дорамы'), ('genre', 'воспитание детей'), ('genre', 'короткий метр'), ('genre', 'интервью'), ('genre', 'по комиксам'), ('genre', 'увлечения'), ('genre', 'охота и рыбалка'), ('genre', 'популярное'), ('genre', 'реалити'), ('genre', 'футбол'), ('genre', 'романтика'), ('genre', 'фильм-нуар'), ('genre', 'тележурналы'), ('genre', 'живая природа'), ('genre', 'немое кино'), ('genre', 'единоборства'), ('genre', 'шоу'), ('genre', 'юмор'), ('genre', 'вокруг света'), ('genre', 'анимация'), ('genre', 'кулинария'), ('genre', 'о знаменитостях'), ('genre', 'индийское кино'), ('genre', '18+'), ('genre', 'токшоу'), ('genre', 'комиксы'), ('genre', 'красота и здоровье'), ('genre', 'образование'), ('genre', 'рекомендуем'), ('studios', 'Unknown'), ('studios', 'Ленфильм'), ('studios', 'Sony Pictures'), ('studios', 'Starz'), ('studios', 'BBC'), ('studios', 'Ленфильм, рентв'), ('studios', 'HBO'), ('studios', 'Paramount'), ('studios', 'Universal'), ('studios', 'Sky'), ('studios', 'Cinemax'), ('studios', 'CBS'), ('studios', 'Sony Plus, рентв'), ('studios', 'FX'), ('studios', 'Sky, Fremantle'), ('studios', 'DAZN'), ('studios', 'Warner Bros'), ('studios', 'Fremantle'), ('studios', 'Sony Pictures, рентв'), ('studios', 'Fox'), ('studios', 'HBO, BBC'), ('studios', 'Мосфильм'), ('studios', 'Showtime'), ('studios', 'Endemol'), ('studios', 'Sony Pictures Television'), ('studios', 'CBS All Access'), ('studios', 'ABC'), ('studios', 'Universal, рентв'), ('studios', 'Amediateka'), ('studios', 'Рок фильм'), ('studios', 'Disney'), ('studios', 'HBO Max'), ('studios', 'Warner Bros. Television'), ('studios', 'MGM'), ('studios', 'Legendary'), ('studios', 'рентв'), ('studios', 'Channel 4'), ('studios', 'New Regency Productions'), ('studios', 'Sony Plus'), ('age_feature', 16.0), ('age_feature', 12.0), ('age_feature', 6.0), ('age_feature', 18.0), ('age_feature', 0.0), ('age_feature', 21.0), ('age_feature', nan), ('countries', 'Испания'), ('countries', 'США'), ('countries', 'Канада'), ('countries', 'Великобритания'), ('countries', 'СССР'), ('countries', 'Россия'), ('countries', 'Германия'), ('countries', 'Италия'), ('countries', 'Аргентина'), ('countries', 'Франция'), ('countries', 'Украина'), ('countries', 'США, Германия, Япония, Великобритания'), ('countries', 'Швеция'), ('countries', 'Норвегия'), ('countries', 'Германия, Канада'), ('countries', 'Россия, Италия, Швеция'), ('countries', 'Чехия'), ('countries', 'Китай, Япония, Тайвань, Республика Корея'), ('countries', 'Израиль'), ('countries', 'Великобритания, Франция'), ('countries', 'Дания, Швеция, США, Великобритания, Аргентина, Германия, Исландия, Испания'), ('countries', 'Бельгия'), ('countries', 'США, Канада'), ('countries', 'Франция, Бельгия'), ('countries', 'Республика Корея'), ('countries', 'Новая Зеландия'), ('countries', 'Австралия'), ('countries', 'Мексика'), ('countries', 'Великобритания, США'), ('countries', 'Швеция, Испания, США'), ('countries', 'США, Великобритания'), ('countries', 'Нидерланды, Великобритания'), ('countries', 'США, Германия'), ('countries', 'Япония'), ('countries', 'Китай'), ('countries', 'Великобритания, Швеция, Германия'), ('countries', 'США, Китай, Германия, Япония'), ('countries', 'Великобритания, США, Китай'), ('countries', 'Кипр'), ('countries', 'Маврикий'), ('countries', 'Казахстан'), ('countries', 'США, Гонконг'), ('countries', 'США, Китай, Япония'), ('countries', 'Ирландия'), ('countries', 'Германия, Норвегия'), ('countries', 'Болгария, Великобритания'), ('countries', 'Россия, Беларусь'), ('countries', 'Италия, СССР'), ('countries', 'США, Румыния'), ('countries', 'Франция, США'), ('countries', 'Россия, США'), ('countries', 'США, Китай'), ('countries', 'США, Мальта'), ('countries', 'США, Великобритания, Австралия'), ('countries', 'Великобритания, США, Канада'), ('countries', 'США, Болгария'), ('countries', 'Нидерланды'), ('countries', 'Чили'), ('countries', 'Армения'), ('countries', 'Германия, Франция'), ('countries', 'Канада, Франция'), ('countries', 'США, Мексика, Австралия, Канада'), ('countries', 'США, Мексика'), ('countries', 'США, Индия'), ('countries', 'Таиланд'), ('countries', 'Канада, США'), ('countries', 'Великобритания, Франция, США, Китай, Венгрия'), ('countries', 'Франция, Сенегал'), ('countries', 'Бразилия, Канада'), ('countries', 'США, Великобритания, Япония, Германия'), ('countries', 'Ирландия, Великобритания'), ('countries', 'США, Германия, Япония'), ('countries', 'США, Великобритания, Канада, Китай'), ('countries', 'США, Япония'), ('countries', 'Италия, Франция'), ('countries', 'Гонконг'), ('countries', 'Беларусь'), ('countries', 'Польша'), ('countries', 'Испания, США'), ('countries', 'Германия, Франция, Италия'), ('countries', 'Австралия, США'), ('countries', 'Нидерланды, Чехия'), ('countries', 'Германия, Бельгия, Люксембург, Ирландия, США'), ('countries', 'Франция, Великобритания, Чехия'), ('countries', 'США, Ирландия'), ('countries', 'Китай, Гонконг'), ('countries', 'Норвегия, Великобритания'), ('countries', 'Россия, Украина'), ('countries', 'Россия, Украина, Беларусь'), ('countries', 'Дания'), ('countries', 'Великобритания, Австралия, США'), ('countries', 'США, Испания'), ('countries', 'Турция'), ('countries', 'ЮАР'), ('countries', 'Швейцария'), ('countries', 'США, Великобритания, Германия'), ('countries', 'США, Франция, Великобритания'), ('countries', 'Швейцария, Великобритания, США'), ('countries', 'Ирландия, Великобритания, Германия, Швеция'), ('countries', 'Дания, Швеция, Нидерланды'), ('countries', 'Македония'), ('countries', 'Великобритания, Канада'), ('countries', 'Индия'), ('countries', 'Финляндия'), ('countries', 'Франция, Республика Корея, Япония'), ('countries', 'Узбекистан'), ('countries', 'Малайзия'), ('countries', 'США, ОАЭ, Чехия'), ('countries', 'США, Австралия'), ('countries', 'Австралия, Россия'), ('countries', 'США, Франция'), ('countries', 'Испания, Мальта, Болгария'), ('countries', 'Португалия, Германия, Дания, США, Франция'), ('countries', 'Испания, Болгария'), ('countries', 'Бразилия'), ('countries', 'Дания, Швеция, Франция, Германия'), ('countries', 'Франция, Германия, США'), ('countries', 'Великобритания, США, Франция'), ('countries', 'Франция, Австралия'), ('countries', 'Канада, США, Индия, Великобритания'), ('countries', 'Германия, США'), ('countries', 'США, Канада, Новая Зеландия'), ('countries', 'Испания, Германия'), ('countries', 'Великобритания, Франция, Германия, США'), ('countries', 'США, Великобритания, Япония'), ('countries', 'Венгрия'), ('countries', 'США, Швеция, ЮАР'), ('countries', 'Казахстан, Россия, Франция'), ('countries', 'Франция, Канада'), ('countries', 'США, Швейцария, Великобритания'), ('countries', 'США, Республика Корея'), ('countries', 'Бельгия, Франция'), ('countries', 'Франция, Бельгия, Германия'), ('countries', 'Польша, Великобритания, Франция'), ('countries', 'США, Франция, Япония'), ('countries', 'Россия, Испания'), ('countries', 'Филиппины'), ('countries', 'Великобритания, Австралия'), ('countries', 'США, Бразилия'), ('countries', 'Пуэрто-Рико, Великобритания, США'), ('countries', 'Испания, Канада'), ('countries', 'Великобритания, Канада, Ирландия'), ('countries', 'Португалия'), ('countries', 'Германия, Бельгия, Великобритания, Дания'), ('countries', 'Чехия, Великобритания, Германия, США'), ('countries', 'Франция, Германия, ЮАР'), ('countries', 'Канада, Ирландия, Великобритания, США'), ('countries', 'Италия, Германия'), ('countries', 'Перу'), ('countries', 'Франция, Канада, США'), ('countries', 'Австралия, Бельгия'), ('countries', 'Латвия'), ('countries', 'Австрия, Германия'), ('countries', 'Киргизия'), ('countries', 'Великобритания, Швеция, Дания, Ирландия'), ('countries', 'Швеция, Норвегия, Германия'), ('countries', 'Алжир, США'), ('countries', 'Дания, Чехия'), ('countries', 'Великобритания, Нидерланды'), ('countries', 'Дания, Швеция, Франция, Нидерланды, Италия, Испания'), ('countries', 'Австралия, Канада'), ('countries', nan), ('countries', 'Великобритания, Франция, Германия'), ('countries', 'Франция, Великобритания, Венгрия'), ('countries', 'Дания, Швеция, Франция, Нидерланды, Норвегия, Исландия, Испания'), ('countries', 'США, ЮАР, Великобритания'), ('countries', 'Великобритания, Румыния'), ('countries', 'Великобритания, Дания'), ('countries', 'Колумбия'), ('countries', 'Румыния'), ('countries', 'Гонконг, Китай'), ('countries', 'США, Финляндия'), ('countries', 'Ирландия, Бельгия, Дания, Канада'), ('countries', 'Австралия, Франция'), ('countries', 'США, Франция, Италия'), ('countries', 'Испания, Япония'), ('countries', 'США, Гонконг, Исландия'), ('countries', 'Франция, Германия, США, Великобритания'), ('countries', 'Австрия'), ('countries', 'Венесуэла'), ('countries', 'США, Великобритания, Италия'), ('countries', 'США, Великобритания, Канада'), ('countries', 'Аргентина, Уругвай, Россия, Германия, Франция, Нидерланды'), ('countries', 'Мексика, США'), ('countries', 'Россия, Беларусь, Польша'), ('countries', 'Германия, Франция, Великобритания, Канада, США, Япония'), ('countries', 'Индонезия, США'), ('countries', 'США, Германия, Канада'), ('countries', 'Китай, США'), ('countries', 'Ирландия, Бельгия'), ('countries', 'Германия, Великобритания, США'), ('countries', 'Дания, Канада, Швеция, США, Франция'), ('countries', 'США, Великобритания, Франция'), ('countries', 'США, Франция, Бельгия, Нидерланды, Латвия'), ('countries', 'Хорватия'), ('countries', 'США, Франция, Великобритания, Италия'), ('countries', 'Австралия, Новая Зеландия'), ('countries', 'Ирландия, Испания'), ('countries', 'Канада, США, Великобритания'), ('countries', 'Новая Зеландия, США'), ('countries', 'США, Великобритания, Франция, Венгрия, Германия'), ('countries', 'Индия, Великобритания, Китай, Канада, Япония, Республика Корея, США'), ('countries', 'Швеция, Дания'), ('countries', 'Великобритания, США, Индия, Канада, Франция, Бельгия'), ('countries', 'Япония, Сингапур'), ('countries', 'Великобритания, Испания, Германия, США'), ('countries', 'Аргентина, Испания, Бразилия, Германия'), ('countries', 'США, Аргентина, Гонконг, Канада'), ('countries', 'Индонезия'), ('countries', 'США, Италия, Румыния, Великобритания'), ('countries', 'Великобритания, Франция, Китай, Камбоджа, США, Германия'), ('countries', 'Дания, Норвегия, Венгрия, Чехия'), ('countries', 'Япония, США'), ('countries', 'США, Канада, Гонконг'), ('countries', 'Германия, Великобритания, США, Канада'), ('countries', 'США, Чехия'), ('countries', 'Италия, Испания'), ('countries', 'Франция, Италия'), ('countries', 'Парагвай'), ('countries', 'Россия, Франция'), ('countries', 'Великобритания, Франция, США'), ('countries', 'Великобритания, Китай, Япония, США'), ('countries', 'Франция, Бельгия, Люксембург'), ('countries', 'США, Бельгия'), ('countries', 'Сербия, СССР'), ('countries', 'США, Нидерланды, Аргентина, Франция'), ('countries', 'Швеция, США'), ('countries', 'Великобритания, Швеция, Франция, Бельгия'), ('countries', 'Россия, Сербия'), ('countries', 'США, Великобритания, Чехия, Канада'), ('countries', 'Россия, Германия, Франция'), ('countries', 'Франция, Польша, Бельгия'), ('countries', 'Франция, Великобритания'), ('countries', 'Испания, Аргентина'), ('countries', 'Германия, Индия, США'), ('countries', 'Великобритания, Германия, США'), ('countries', 'США, Канада, Франция'), ('countries', 'Франция, Япония'), ('countries', 'Австралия, Китай, Германия, США'), ('countries', 'Великобритания, США, Индия'), ('countries', 'Дания, Норвегия, Германия'), ('countries', 'Великобритания, Нидерланды, Франция, Италия, Япония'), ('countries', 'Молдова'), ('countries', 'Германия, Китай'), ('countries', 'Дания, США'), ('countries', 'Великобритания, Испания'), ('countries', 'Швеция, Дания, США'), ('countries', 'Австралия, Германия'), ('countries', 'Великобритания, Франция, США, Канада'), ('countries', 'Исландия, Дания, Швеция'), ('countries', 'США, Великобритания, Франция, Германия, Япония'), ('countries', 'Эстония'), ('countries', 'США, Армения'), ('countries', 'Франция, Польша'), ('countries', 'Нидерланды, Люксембург, Великобритания'), ('countries', 'Россия, Люксембург'), ('countries', 'США, Канада, Индия'), ('countries', 'США, Германия, Франция'), ('countries', 'США, Франция, Бельгия, Чехия'), ('countries', 'Албания'), ('countries', 'Бельгия, Великобритания, Германия'), ('countries', 'Болгария'), ('countries', 'Испания, Португалия, Франция'), ('countries', 'Канада, Республика Корея, США'), ('countries', 'Великобритания, Италия'), ('countries', 'США, Чили, Израиль'), ('countries', 'Мексика, Франция'), ('countries', 'Великобритания, Ирландия, Франция, США'), ('countries', 'Великобритания, Новая Зеландия'), ('countries', 'Бельгия, Люксембург, Франция'), ('countries', 'Аргентина, Испания'), ('countries', 'США, Гонконг, Канада, Китай'), ('countries', 'США, Китай, Канада, Австралия'), ('countries', 'Швеция, СССР, Норвегия'), ('countries', 'Австралия, Великобритания'), ('countries', 'США, Канада, Австралия'), ('countries', 'Канада, Китай, США'), ('countries', 'Россия, Великобритания, Австрия'), ('countries', 'США, Австралия, Мексика'), ('countries', 'США, Япония, Испания, Великобритания'), ('countries', 'США, Россия'), ('countries', 'США, ОАЭ'), ('countries', 'Великобритания, США, Китай, Швеция, Япония'), ('countries', 'Франция, Испания, Румыния, Бельгия, США'), ('countries', 'Гонконг, США'), ('countries', 'Великобритания, Китай, США'), ('countries', 'Нидерланды, Великобритания, Польша, Украина, США'), ('countries', 'Дания, Германия, Франция, Бельгия'), ('countries', 'США, Новая Зеландия'), ('countries', 'Великобритания, Германия, Испания, США'), ('countries', 'Испания, Франция'), ('countries', 'Исландия'), ('countries', 'США, Германия, Великобритания, Нидерланды, Италия'), ('countries', 'Индия, Сингапур, США'), ('countries', 'США, Канада, Великобритания'), ('countries', 'Ирландия, Швеция, США'), ('countries', 'Швейцария, Германия, Португалия'), ('countries', 'Германия, Австрия, Италия'), ('countries', 'Великобритания, Франция, Германия, Ирландия, США'), ('countries', 'США, Великобритания, Япония, Венгрия'), ('countries', 'Великобритания, Канада, США'), ('countries', 'Сингапур'), ('countries', 'Франция, США, Бразилия'), ('countries', 'Китай, Канада, США'), ('countries', 'Россия, Турция'), ('countries', 'Хорватия, Люксембург, Норвегия, Чехия, Словакия, Словения'), ('countries', 'Германия, Австралия'), ('countries', 'Австралия, Колумбия'), ('countries', 'Россия, Казахстан'), ('countries', 'Австрия, Россия'), ('countries', 'Эквадор, Испания, Перу'), ('countries', 'Франция, Великобритания, США'), ('countries', 'Сербия'), ('countries', 'Швеция, Германия, Норвегия, Дания, Исландия, Бельгия, Великобритания'), ('countries', 'Великобритания, Ирландия, Канада, США, Индия'), ('countries', 'США, ЮАР'), ('countries', 'Тайвань'), ('countries', 'Мальта'), ('countries', 'Бельгия, Люксембург'), ('countries', 'Франция, Китай'), ('countries', 'США, Канада, Франция, Великобритания, Индия'), ('countries', 'Армения, Грузия, США'), ('countries', 'Канада, Испания, Япония'), ('countries', 'Канада, Республика Корея'), ('countries', 'Испания, Болгария, США'), ('countries', 'Испания, США, Франция'), ('countries', 'США, Норвегия'), ('countries', 'Великобритания, Германия'), ('countries', 'США, Франция, Канада, Испания'), ('countries', 'США, Камбоджа'), ('countries', 'США, Великобритания, Мальта, Марокко'), ('countries', 'Аргентина, Мексика'), ('countries', 'Франция, Люксембург, Бельгия'), ('countries', 'Великобритания, США, Германия'), ('countries', 'Великобритания, Германия, США, Испания'), ('countries', 'США, Германия, Польша'), ('countries', 'США, Великобритания, Ирландия'), ('countries', 'Индия, США'), ('countries', 'Канада, Бельгия'), ('countries', 'Норвегия, США, Великобритания'), ('countries', 'Россия, Украина, Великобритания'), ('countries', 'Италия, Бельгия'), ('countries', 'Иран'), ('countries', 'Германия, Япония, США, Великобритания'), ('countries', 'США, Германия, Чехия'), ('countries', 'Великобритания, Ирландия'), ('countries', 'Россия, Тунис'), ('countries', 'Великобритания, Финляндия, Германия, США, Франция'), ('countries', 'США, Германия, Китай, Канада'), ('countries', 'Польша, СССР'), ('countries', 'США, Нидерланды'), ('countries', 'Ирландия, США'), ('countries', 'Бельгия, Великобритания, Ирландия, США'), ('countries', 'США, Швеция, Венгрия'), ('countries', 'Великобритания, Мексика, США'), ('countries', 'США, Канада, Австралия, Тайвань'), ('countries', 'США, Греция'), ('countries', 'Германия, Канада, США'), ('countries', 'США, Бельгия, Дания, Великобритания, Швеция, Китай'), ('countries', 'Бельгия, Германия'), ('countries', 'Германия, Франция, Испания, США'), ('countries', 'Германия, Россия'), ('countries', 'Ирландия, Франция'), ('countries', 'Германия, Дания, Франция, Швеция'), ('countries', 'Франция, США, Германия'), ('countries', 'США, Китай, Великобритания'), ('countries', 'США, Филиппины, Пуэрто-Рико'), ('countries', 'США, Германия, Гонконг, Сингапур'), ('countries', 'Великобритания, Люксембург'), ('countries', 'Швейцария, Франция'), ('countries', 'Великобритания, Германия, Франция'), ('countries', 'Франция, США, Испания'), ('countries', 'Швеция, Канада'), ('countries', 'Россия, Латвия, Великобритания, Австрия'), ('countries', 'Новая Зеландия, США, Германия'), ('countries', 'Германия, США, Мексика'), ('countries', 'Ирландия, Канада'), ('countries', 'Швеция, Великобритания, Франция, Испания, Россия'), ('countries', 'Чехия, Великобритания'), ('countries', 'Словения'), ('countries', 'США, Канада, Китай'), ('countries', 'США, Новая Зеландия, Германия'), ('countries', 'Россия, Канада, Грузия, Греция'), ('countries', 'Индия, Китай'), ('countries', 'Дания, Норвегия, Чехия'), ('countries', 'Канада, Венгрия'), ('countries', 'Дания, Латвия, Россия, США'), ('countries', 'Ирландия, Франция, Исландия, США, Мексика, Бельгия, Великобритания, Гонконг'), ('countries', 'Иран, Ливан'), ('countries', 'Франция, Испания'), ('countries', 'Франция, СССР'), ('countries', 'Германия, Италия'), ('countries', 'Куба, Испания'), ('countries', 'Великобритания, США, Испания'), ('countries', 'Уругвай, Аргентина, Германия, Испания, Нидерланды'), ('countries', 'Италия, Люксембург, Бельгия'), ('countries', 'США, Индия, Великобритания, Франция, Канада, Германия'), ('countries', 'Болгария, США'), ('countries', 'Испания, США, Италия'), ('countries', 'США, Великобритания, Китай'), ('countries', 'Россия, Грузия'), ('countries', 'США, Германия, Великобритания, Франция'), ('countries', 'Азербайджан'), ('countries', 'Великобритания, Австралия, США, Новая Зеландия'), ('countries', 'США, Индия, Канада'), ('countries', 'Германия, Франция, Бельгия, ЮАР, Италия, Великобритания, Люксембург'), ('countries', 'США, Германия, Великобритания'), ('countries', 'Франция, Германия'), ('countries', 'Великобритания, Чехия, Германия, США'), ('countries', 'Финляндия, Латвия'), ('countries', 'Германия, Бельгия, Франция'), ('countries', 'США, Испания, Франция, Великобритания'), ('countries', 'США, Великобритания, Германия, Нидерланды, Франция, Италия, Марокко, Таиланд'), ('countries', 'Великобритания, ЮАР'), ('countries', 'Аргентина, США'), ('countries', 'Великобритания, Румыния, США'), ('countries', 'Франция, Польша, Великобритания'), ('countries', 'Мексика, Тайвань, Великобритания, США, Япония, Италия'), ('countries', 'Австралия, США, Канада, Великобритания'), ('countries', 'Великобритания, Канада, Норвегия, США'), ('countries', 'Великобритания, США, Германия, Дания, Бельгия, Япония'), ('countries', 'Франция, Италия, Тунис'), ('countries', 'Бельгия, Великобритания'), ('countries', 'Канада, Великобритания'), ('countries', 'Франция, Бельгия, США'), ('countries', 'Китай, США, Канада'), ('countries', 'Россия, Франция, Германия, Бельгия'), ('countries', 'Иордания'), ('countries', 'Германия, Франция, ЮАР'), ('countries', 'Бразилия, Германия'), ('countries', 'Германия, Франция, США, Канада, Великобритания'), ('countries', 'США, Канада, Италия'), ('countries', 'Болгария, Великобритания, США'), ('countries', 'США, Мексика, Испания'), ('countries', 'Грузия, Украина'), ('countries', 'Турция, США'), ('countries', 'Армения, Россия'), ('countries', 'Беларусь, Украина'), ('countries', 'Великобритания, США, Австралия'), ('countries', 'США, Венгрия'), ('countries', 'Япония, США, Франция'), ('countries', 'Великобритания, США, Япония'), ('countries', 'Япония, Канада'), ('countries', 'Дания, Швеция, Франция, Италия, Германия, Исландия'), ('countries', 'Португалия, Великобритания'), ('countries', 'США, Канада, Венгрия'), ('countries', 'США, Япония, Мексика, Канада'), ('countries', 'Россия, Беларусь, Чехия, Франция, Польша, Израиль'), ('countries', 'Колумбия, США'), ('countries', 'Швеция, Дания, Финляндия'), ('countries', 'Германия, Бельгия'), ('countries', 'Италия, Франция, Великобритания, Швейцария'), ('countries', 'Великобритания, Германия, Люксембург'), ('countries', 'США, Тайвань, Великобритания, Канада'), ('countries', 'Россия, Армения'), ('countries', 'США, Швейцария'), ('countries', 'США, Аргентина, Мексика'), ('countries', 'Норвегия, США'), ('countries', 'Германия, Великобритания'), ('countries', 'Китай, Франция'), ('countries', 'США, Германия, Канада, Великобритания'), ('countries', 'Бельгия, Германия, Швеция'), ('countries', 'Германия, СССР'), ('countries', 'Бразилия, Франция'), ('countries', 'США, Великобритания, Австралия, Канада'), ('countries', 'Испания, Великобритания, Франция, США'), ('countries', 'Германия, Канада, США, Франция, Великобритания'), ('countries', 'США, Китай, Канада'), ('countries', 'ЮАР, Япония, США'), ('countries', 'США, ЮАР, Замбия, Германия'), ('countries', 'Китай, США, Индия'), ('countries', 'Нидерланды, Перу'), ('countries', 'Великобритания, США, Франция, Испания, Италия'), ('countries', 'Испания, Франция, Италия'), ('countries', 'Великобритания, Польша'), ('countries', 'Италия, Испания, Великобритания'), ('countries', 'Япония, Россия'), ('countries', 'США, Малайзия, Португалия'), ('countries', 'США, Ливан'), ('countries', 'Греция'), ('countries', 'США, Япония, Великобритания'), ('countries', 'Канада, Финляндия'), ('countries', 'Индия, Мексика'), ('countries', 'США, Польша'), ('countries', 'Великобритания, США, Румыния'), ('countries', 'Германия, Норвегия, Швеция'), ('countries', 'Япония, Китай'), ('countries', 'Дания, Швеция'), ('countries', 'Япония, СССР'), ('countries', 'Великобритания, СССР'), ('countries', 'США, Великобритания, Канада, Бельгия'), ('countries', 'ЮАР, США'), ('countries', 'Франция, Бельгия, Китай'), ('countries', 'Уругвай, Аргентина, Испания'), ('countries', 'Финляндия, Россия'), ('countries', 'Франция, Израиль, Германия'), ('countries', 'Франция, Россия'), ('countries', 'США, Канада, Люксембург'), ('countries', 'Великобритания, США, Швеция'), ('countries', 'США, Великобритания, Германия, Чехия'), ('countries', 'США, Италия'), ('countries', 'США, Франция, Чехия'), ('countries', 'США, Германия, Франция, Испания'), ('countries', 'Дания, Швеция, Франция, Германия, Швейцария, Испания'), ('countries', 'США, Германия, Венгрия'), ('countries', 'Германия, Испания'), ('countries', 'Казахстан, Турция'), ('countries', 'США, Россия, Венгрия'), ('countries', 'Ирландия, Великобритания, Германия'), ('countries', 'Германия, Люксембург'), ('countries', 'Тунис, Швейцария, Франция'), ('countries', 'Великобритания, Ирландия, Канада, США'), ('countries', 'Бельгия, Великобритания, Ирландия'), ('countries', 'Канада, Великобритания, США'), ('countries', 'Ирландия, Великобритания, США'), ('countries', 'СССР, Франция'), ('countries', 'Швеция, Бельгия'), ('countries', 'Россия, Азербайджан'), ('countries', 'Дания, Швеция, Чехия'), ('countries', 'Великобритания, Франция, Канада, Бельгия, США'), ('countries', 'Бельгия, Франция, Великобритания'), ('countries', 'Великобритания, Венгрия, США'), ('countries', 'Россия, Китай'), ('countries', 'Россия, Германия, Казахстан, Франция'), ('countries', 'Чехия, Германия, Сингапур, США'), ('countries', 'Бразилия, Уругвай, Дания, Норвегия'), ('countries', 'Эстония, Россия'), ('countries', 'Германия, Австрия'), ('countries', 'Германия, Бельгия, США'), ('countries', 'Австрия, Венгрия'), ('countries', 'США, Германия, Бельгия'), ('countries', 'Франция, Бельгия, Италия'), ('countries', 'США, Исландия, Великобритания'), ('countries', 'Украина, Беларусь'), ('countries', 'США, Великобритания, Индия, Испания, Канада'), ('countries', 'Швеция, Германия, Франция, Дания, США'), ('countries', 'Великобритания, Сербия'), ('countries', 'Франция, Чехия'), ('countries', 'США, Польша, Словения, Чехия'), ('countries', 'Испания, Канада, Франция'), ('countries', 'Россия, Франция, Германия'), ('countries', 'Канада, Китай'), ('countries', 'Франция, Чили'), ('countries', 'Великобритания, США, Франция, Венгрия, Нидерланды'), ('countries', 'Германия, Канада, Великобритания'), ('countries', 'Дания, Франция, Швеция, Германия, Бельгия, Тунис'), ('countries', 'Россия, Норвегия'), ('countries', 'Индия, Канада'), ('countries', 'Германия, Великобритания, Италия, Испания'), ('countries', 'Италия, Люксембург, Франция, Бельгия'), ('countries', 'США, Канада, Филиппины, Великобритания, Республика Корея, Франция'), ('countries', 'Канада, США, Великобритания, Австралия'), ('countries', 'Ирландия, США, Великобритания, Швеция, Бельгия'), ('countries', 'Бельгия, Нидерланды'), ('countries', 'Германия, Испания, Тайвань'), ('countries', 'Россия, Великобритания'), ('countries', 'США, Канада, Китай, Япония'), ('countries', 'Великобритания, Испания, США'), ('countries', 'Великобритания, Чехия, США, Германия'), ('countries', 'США, Нидерланды, Великобритания'), ('countries', 'США, Канада, Япония'), ('countries', 'Россия, Латвия'), ('countries', 'Великобритания, Франция, Германия, Мексика, США'), ('countries', 'Вьетнам'), ('countries', 'Германия, Франция, Бельгия'), ('countries', 'Италия, США'), ('countries', 'Германия, Швеция, США, Венгрия'), ('countries', 'Франция, Норвегия'), ('countries', 'Дания, Нидерланды, Швеция, Германия, Великобритания, Франция, Финляндия, Норвегия, Италия'), ('countries', 'Чехия, Словакия, Хорватия'), ('countries', 'США, Таиланд'), ('countries', 'Чили, Аргентина, Бразилия'), ('countries', 'Нидерланды, Великобритания, Франция, Люксембург, Австрия'), ('countries', 'Чили, США'), ('countries', 'Дания, Швейцария'), ('countries', 'Чехия, Великобритания, США'), ('countries', 'Мексика, США, Канада'), ('countries', 'США, Китай, Гонконг, Австралия, Канада'), ('countries', 'США, Канада, Япония, Франция'), ('countries', 'Великобритания, Пуэрто-Рико'), ('countries', 'США, Япония, Колумбия'), ('countries', 'Испания, Великобритания, Нидерланды'), ('countries', 'Германия, США, Франция, Австралия, Великобритания'), ('countries', 'Япония, Китай, Республика Корея'), ('countries', 'Люксембург'), ('countries', 'США, Германия, Мексика'), ('countries', 'Республика Корея, Канада'), ('countries', 'Франция, США, Мексика'), ('countries', 'Великобритания, Германия, Дания, США'), ('countries', 'Аргентина, США, Чили, Перу, Бразилия, Великобритания, Германия, Франция'), ('countries', 'Великобритания, Бельгия'), ('countries', 'США, Германия, Италия'), ('countries', 'Чехия, Словакия'), ('countries', 'Гонконг, Канада, США'), ('countries', 'Россия, Нидерланды'), ('countries', 'Дания, Великобритания'), ('countries', 'Канада, Мексика, Германия'), ('countries', 'Германия, Ирландия, США'), ('countries', 'Великобритания, Норвегия'), ('countries', 'Великобритания, Чехия, Франция, Италия, США'), ('countries', 'Великобритания, Испания, Германия'), ('countries', 'Дания, Швеция, Италия, Франция, Германия'), ('countries', 'США, Германия, Великобритания, Венгрия'), ('countries', 'Китай, Тайвань, Гонконг'), ('countries', 'Коста-Рика'), ('countries', 'Россия, Болгария'), ('countries', 'Дания, Франция, США, Швеция, Бельгия'), ('countries', 'Мексика, Индия, США'), ('countries', 'США, Китай, Бразилия'), ('countries', 'США, Германия, Великобритания, Испания'), ('countries', 'Дания, Швеция, Нидерланды, Франция, Германия, Великобритания, Италия, США'), ('countries', 'Грузия'), ('countries', 'Португалия, США'), ('countries', 'Швеция, Дания, Германия, Финляндия, Франция, Великобритания, Италия'), ('countries', 'Великобритания, США, Венгрия'), ('countries', 'США, Великобритания, Венгрия'), ('countries', 'Дания, Норвегия, Чехия, Исландия, Швеция'), ('countries', 'США, Великобритания, Испания'), ('countries', 'Великобритания, Россия'), ('countries', 'Италия, Испания, Германия'), ('countries', 'Кения, Индия, США'), ('countries', 'Франция, Испания, США'), ('countries', 'США, Франция, Китай, Великобритания'), ('countries', 'Дания, Норвегия, Швеция, Исландия'), ('countries', 'Швеция, СССР'), ('countries', 'Бельгия, Франция, Ирландия'), ('countries', 'США, Германия, Ирландия, Великобритания'), ('countries', 'США, Индия, Франция'), ('countries', 'Сербия, Великобритания, США, Аргентина'), ('countries', 'Великобритания, Япония'), ('countries', 'Великобритания, Франция, Испания, США'), ('countries', 'США, ЮАР, Индия'), ('countries', 'Бельгия, США, Франция, Италия'), ('countries', 'Республика Корея, Чехия'), ('countries', 'Ирландия, Бельгия, США'), ('countries', 'Венгрия, Великобритания, Франция, Австралия, США, Новая Зеландия'), ('countries', 'Республика Корея, Китай'), ('countries', 'Австралия, Швеция'), ('countries', 'Россия, Украина, Германия, Великобритания, Чехия'), ('countries', 'Норвегия, Швеция, Дания'), ('countries', 'Германия, Индия, Австралия'), ('countries', 'Иран, Франция, Германия, Швейцария'), ('countries', 'Испания, Франция, Швеция, Аргентина'), ('countries', 'Франция, Республика Корея, Испания'), ('countries', 'Венгрия, Дания, Норвегия, Чехия'), ('countries', 'Россия, Япония, Эстония'), ('countries', 'ОАЭ'), ('countries', 'Франция, Иран'), ('countries', 'Чехия, СССР'), ('countries', 'Германия, Люксембург, Дания'), ('countries', 'Испания, Бельгия'), ('countries', 'США, Чехия, Великобритания'), ('countries', 'Япония, Великобритания'), ('countries', 'Ирландия, Великобритания, Греция, Франция, Нидерланды'), ('countries', 'Великобритания, Австрия'), ('countries', 'Норвегия, Швеция, Дания, Германия'), ('countries', 'Россия, Литва, Ирландия'), ('countries', 'Бельгия, Канада'), ('countries', 'Италия, Франция, Великобритания'), ('countries', 'Германия, Франция, Польша'), ('countries', 'Канада, США, Франция, Германия, Великобритания'), ('countries', 'Великобритания, Франция, Австралия'), ('countries', 'США, Германия, Чехия, Великобритания'), ('countries', 'Германия, США, Нидерланды'), ('countries', 'США, Франция, Канада'), ('countries', 'Испания, США, Чехия'), ('countries', 'Финляндия, Германия'))))" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "e0dfa8e8", - "metadata": {}, - "outputs": [], - "source": [ - "user_embeddings, item_embeddings = model.get_vectors(dataset)" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "91a20b08", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((756545, 34), (13963, 34))" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_embeddings.shape, item_embeddings.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "id": "3634fd78", - "metadata": {}, - "outputs": [], - "source": [ - "def augment_inner_product(factors):\n", - " normed_factors = np.linalg.norm(factors, axis=1)\n", - " max_norm = normed_factors.max()\n", - " \n", - " extra_dim = np.sqrt(max_norm ** 2 - normed_factors ** 2).reshape(-1, 1)\n", - " augmented_factors = np.append(factors, extra_dim, axis=1)\n", - " return max_norm, augmented_factors" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "c2668a0d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "pre shape: (13963, 34)\n" - ] - }, - { - "data": { - "text/plain": [ - "(13963, 35)" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print('pre shape: ', item_embeddings.shape)\n", - "max_norm, augmented_item_embeddings = augment_inner_product(item_embeddings)\n", - "augmented_item_embeddings.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "16fb4a95", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(756545, 35)" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "extra_zero = np.zeros((user_embeddings.shape[0], 1))\n", - "augmented_user_embeddings = np.append(user_embeddings, extra_zero, axis=1)\n", - "augmented_user_embeddings.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "8d3d96d3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([-3.57730194e+02, 1.00000000e+00, -2.26793036e-01, -3.82283032e-02,\n", - " -2.24665195e-01, 2.79386699e-01, 4.53218251e-01, 7.11198449e-01,\n", - " -3.75804901e-01, -1.72303200e-01, 2.92628944e-01, -1.33832023e-01,\n", - " -2.28909120e-01, -3.57735574e-01, -3.30191135e-01, 1.64654672e-01,\n", - " 9.00539607e-02, -4.77109384e-03, -3.73476028e-01, -3.36808801e-01,\n", - " -2.85889745e-01, 3.30380827e-01, 5.07512987e-02, -1.93970263e-01,\n", - " 5.27234077e-02, -1.03786469e-01, 2.36950964e-02, -3.96105945e-01,\n", - " -2.38289386e-01, -4.49349046e-01, 4.56677824e-01, 1.46467835e-01,\n", - " -2.78142452e-01, -4.42725003e-01])" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_id = 30\n", - "user_embeddings[user_id]" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "id": "a3abdc5a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([-3.57730194e+02, 1.00000000e+00, -2.26793036e-01, -3.82283032e-02,\n", - " -2.24665195e-01, 2.79386699e-01, 4.53218251e-01, 7.11198449e-01,\n", - " -3.75804901e-01, -1.72303200e-01, 2.92628944e-01, -1.33832023e-01,\n", - " -2.28909120e-01, -3.57735574e-01, -3.30191135e-01, 1.64654672e-01,\n", - " 9.00539607e-02, -4.77109384e-03, -3.73476028e-01, -3.36808801e-01,\n", - " -2.85889745e-01, 3.30380827e-01, 5.07512987e-02, -1.93970263e-01,\n", - " 5.27234077e-02, -1.03786469e-01, 2.36950964e-02, -3.96105945e-01,\n", - " -2.38289386e-01, -4.49349046e-01, 4.56677824e-01, 1.46467835e-01,\n", - " -2.78142452e-01, -4.42725003e-01, 0.00000000e+00])" - ] - }, - "execution_count": 68, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "augmented_user_embeddings[user_id]" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "b4d804fe", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 1. , 3.20644975, -0.28407601, 0.04007996, -1.09869027,\n", - " 1.66705382, 1.70660424, 2.58876157, -1.66243601, -1.03955173,\n", - " 1.49190485, -0.31513208, -0.32752386, -2.05019426, -0.32129809,\n", - " 2.38546944, 2.56410718, 0.10934736, -2.01597881, -1.75085366,\n", - " -2.90048265, 2.37181401, -1.49925196, -1.98518109, 1.68892503,\n", - " 0.41754866, 0.90933883, -2.91862941, -2.08309627, -2.04692388,\n", - " 3.48958254, 1.95236182, -2.21343875, -2.94543052])" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "item_id = 0\n", - "item_embeddings[item_id]" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "2e0030f1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 1. , 3.20644975, -0.28407601, 0.04007996, -1.09869027,\n", - " 1.66705382, 1.70660424, 2.58876157, -1.66243601, -1.03955173,\n", - " 1.49190485, -0.31513208, -0.32752386, -2.05019426, -0.32129809,\n", - " 2.38546944, 2.56410718, 0.10934736, -2.01597881, -1.75085366,\n", - " -2.90048265, 2.37181401, -1.49925196, -1.98518109, 1.68892503,\n", - " 0.41754866, 0.90933883, -2.91862941, -2.08309627, -2.04692388,\n", - " 3.48958254, 1.95236182, -2.21343875, -2.94543052, 7.11584563])" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "augmented_item_embeddings[item_id]" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "id": "19104d9a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index-time parameters {'M': 48, 'indexThreadQty': 4, 'efConstruction': 100, 'post': 0}\n" - ] - } - ], - "source": [ - "M = 48\n", - "efC = 100\n", - "\n", - "num_threads = 4\n", - "index_time_params = {'M': M, 'indexThreadQty': num_threads, 'efConstruction': efC, 'post' : 0}\n", - "print('Index-time parameters', index_time_params)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "id": "3634ebbb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "13963" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "K=10\n", - "space_name='negdotprod'\n", - "index = nmslib.init(method='hnsw', space=space_name, data_type=nmslib.DataType.DENSE_VECTOR) \n", - "index.addDataPointBatch(augmented_item_embeddings) " - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "6d423d8d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index-time parameters {'M': 48, 'indexThreadQty': 4, 'efConstruction': 100}\n", - "Indexing time = 0.282692\n" - ] - } - ], - "source": [ - "start = time.time()\n", - "index_time_params = {'M': M, 'indexThreadQty': num_threads, 'efConstruction': efC}\n", - "index.createIndex(index_time_params) \n", - "end = time.time() \n", - "print('Index-time parameters', index_time_params)\n", - "print('Indexing time = %f' % (end-start))" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "9dc1529f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Setting query-time parameters {'efSearch': 100}\n" - ] - } - ], - "source": [ - "efS = 100\n", - "query_time_params = {'efSearch': efS}\n", - "print('Setting query-time parameters', query_time_params)\n", - "index.setQueryTimeParams(query_time_params)" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "id": "0fff67a2", - "metadata": {}, - "outputs": [], - "source": [ - "query_matrix = augmented_user_embeddings[:1000, :]" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "id": "1cdffc65", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "kNN time total=0.023291 (sec), per query=0.000023 (sec), per query adjusted for thread number=0.000093 (sec)\n" - ] - } - ], - "source": [ - "query_qty = query_matrix.shape[0]\n", - "start = time.time() \n", - "nbrs = index.knnQueryBatch(query_matrix, k = K, num_threads = num_threads)\n", - "end = time.time() \n", - "print('kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' % \n", - " (end-start, float(end-start)/query_qty, num_threads*float(end-start)/query_qty)) \n" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "id": "d94de743", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(array([ 43, 32, 19, 62, 31, 112, 305, 188, 268, 948], dtype=int32),\n", - " array([304.80273, 304.95447, 305.16202, 305.32443, 305.47067, 305.5135 ,\n", - " 305.6464 , 305.6903 , 305.73453, 305.78738], dtype=float32))" - ] - }, - "execution_count": 83, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "nbrs[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 87, - "id": "5be5c93c", - "metadata": {}, - "outputs": [], - "source": [ - "def recommend_all(query_factors, index_factors, topn=10):\n", - " output = query_factors.dot(index_factors.T)\n", - " argpartition_indices = np.argpartition(output, -topn)[:, -topn:]\n", - "\n", - " x_indices = np.repeat(np.arange(output.shape[0]), topn)\n", - " y_indices = argpartition_indices.flatten()\n", - " top_value = output[x_indices, y_indices].reshape(output.shape[0], topn)\n", - " top_indices = np.argsort(top_value)[:, ::-1]\n", - "\n", - " y_indices = top_indices.flatten()\n", - " top_indices = argpartition_indices[x_indices, y_indices]\n", - " labels = top_indices.reshape(-1, topn)\n", - " distances = output[x_indices, top_indices].reshape(-1, topn)\n", - " return labels, distances\n" - ] - }, - { - "cell_type": "code", - "execution_count": 108, - "id": "e9988091", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 19, 31, 121, 32, 43, 268, 120, 62, 103, 173]])" - ] - }, - "execution_count": 108, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "labels,_ = recommend_all(user_embeddings[[], :], item_embeddings)\n", - "labels" - ] - }, - { - "cell_type": "code", - "execution_count": 112, - "id": "3c722149", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([], shape=(0, 34), dtype=float64)" - ] - }, - "execution_count": 112, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_embeddings[[], :]" - ] - }, - { - "cell_type": "code", - "execution_count": 113, - "id": "d300a815", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[-3.24551971e+02, 1.00000000e+00, 8.73963833e-02, ...,\n", - " -1.30321786e-01, 1.82629615e-01, -3.07083875e-01],\n", - " [-3.24792297e+02, 1.00000000e+00, 3.87268960e-01, ...,\n", - " -4.32303697e-02, -4.72983688e-01, -1.79986209e-01],\n", - " [-3.01102661e+02, 1.00000000e+00, -1.63965374e-01, ...,\n", - " -1.01540364e-01, 1.10484377e-01, -2.40944147e-01],\n", - " ...,\n", - " [-3.58453766e+02, 1.00000000e+00, -1.08767882e-01, ...,\n", - " 2.43232936e-01, -1.24036551e-01, -4.88389194e-01],\n", - " [-2.99490662e+02, 1.00000000e+00, -3.04439873e-01, ...,\n", - " -2.42081508e-02, -3.93126070e-01, -2.91359007e-01],\n", - " [-3.10774689e+02, 1.00000000e+00, -2.57401466e-01, ...,\n", - " -3.03505287e-02, -4.26894128e-01, -3.11958164e-01]])" - ] - }, - "execution_count": 113, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_embeddings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "15d49fe7", - "metadata": {}, - "outputs": [], - "source": [ - "labels" - ] - }, - { - "cell_type": "code", - "execution_count": 89, - "id": "d6c68dd7", - "metadata": {}, - "outputs": [], - "source": [ - "query_matrix_not_augmented = user_embeddings[:1000, :]" - ] - }, - { - "cell_type": "code", - "execution_count": 105, - "id": "b7d9dd1f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "207 ms ± 6.37 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "labels,_ = recommend_all(query_matrix_not_augmented, item_embeddings)\n", - "print(labels)" - ] - }, - { - "cell_type": "code", - "execution_count": 92, - "id": "904846a6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((1000, 34), (756545, 34))" - ] - }, - "execution_count": 92, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "item_embeddings[:1000, :].shape, user_embeddings.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 93, - "id": "d6027ae4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "7.88 ms ± 368 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "index.knnQueryBatch(query_matrix, k = K, num_threads = num_threads)" - ] - }, - { - "cell_type": "code", - "execution_count": 96, - "id": "901b82c3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Collecting hnswlib\n", - " Downloading hnswlib-0.6.2.tar.gz (31 kB)\n", - " Installing build dependencies ... \u001b[?25ldone\n", - "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", - "\u001b[?25h Preparing wheel metadata ... \u001b[?25ldone\n", - "\u001b[?25hRequirement already satisfied: numpy in /home/rezarayev/anaconda3/lib/python3.8/site-packages (from hnswlib) (1.22.2)\n", - "Building wheels for collected packages: hnswlib\n", - " Building wheel for hnswlib (PEP 517) ... \u001b[?25ldone\n", - "\u001b[?25h Created wheel for hnswlib: filename=hnswlib-0.6.2-cp38-cp38-linux_x86_64.whl size=2038858 sha256=51c4c2849d71105958f418c5961215d8cac3027e3f96cab05899827043a3d43d\n", - " Stored in directory: /home/rezarayev/.cache/pip/wheels/74/3b/89/4bd924865709f24ac2df457bcca4c0b55a3eb89c5a94ce3ce8\n", - "Successfully built hnswlib\n", - "\u001b[33mWARNING: Error parsing requirements for pybind11: [Errno 2] Нет такого файла или каталога: '/home/rezarayev/anaconda3/lib/python3.8/site-packages/pybind11-2.9.2.dist-info/METADATA'\u001b[0m\n", - "Installing collected packages: hnswlib\n", - "Successfully installed hnswlib-0.6.2\n", - "Note: you may need to restart the kernel to use updated packages.\n" - ] - } - ], - "source": [ - "pip install hnswlib" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "id": "e6b0be91", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[-304.80272148 -304.95450166 -305.1620535 ... -305.69031591\n", - " -305.73454442 -305.7874324 ]\n", - " [-311.19933349 -311.44323422 -311.45526998 ... -312.0948194\n", - " -312.21820321 -312.23901463]\n", - " [-284.3956498 -284.45770448 -284.96237912 ... -285.29546382\n", - " -285.36598349 -285.41208658]\n", - " ...\n", - " [-332.37278335 -332.85525963 -332.98405066 ... -333.36833688\n", - " -333.44008879 -333.48889785]\n", - " [-302.10402324 -302.13324433 -302.3124104 ... -302.86405908\n", - " -302.88296188 -303.00234271]\n", - " [ 14.88806505 14.41715752 14.1114468 ... 13.71272978\n", - " 13.68271151 13.6242354 ]]\n" - ] - } - ], - "source": [ - "labels, distances = recommend_all(user_embeddings[:1000, :], item_embeddings)\n", - "print(labels)\n", - "print(distances)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "77fedf20", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/poetry.lock b/poetry.lock index 7dfc0cc9..8c7cc5ea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -66,7 +66,7 @@ yaml = ["PyYAML"] name = "certifi" version = "2022.9.24" description = "Python package for providing Mozilla's CA Bundle." -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -74,7 +74,7 @@ python-versions = ">=3.6" name = "chardet" version = "4.0.0" description = "Universal encoding detector for Python 2 and 3" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -97,6 +97,32 @@ category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +[[package]] +name = "contourpy" +version = "1.0.6" +description = "Python library for calculating contours of 2D quadrilateral grids" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +numpy = ">=1.16" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["docutils (<0.18)", "sphinx (<=5.2.0)", "sphinx-rtd-theme"] +test = ["Pillow", "flake8", "isort", "matplotlib", "pytest"] +test-minimal = ["pytest"] +test-no-codebase = ["Pillow", "matplotlib", "pytest"] + +[[package]] +name = "cycler" +version = "0.11.0" +description = "Composable style cycles" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "fastapi" version = "0.65.3" @@ -128,6 +154,28 @@ mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.7.0,<2.8.0" pyflakes = ">=2.3.0,<2.4.0" +[[package]] +name = "fonttools" +version = "4.38.0" +description = "Tools to manipulate font files" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=14.0.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "scipy"] +lxml = ["lxml (>=4.0,<5)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=14.0.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + [[package]] name = "gitdb" version = "4.0.9" @@ -175,11 +223,22 @@ category = "main" optional = false python-versions = ">=3.7" +[[package]] +name = "hnswlib" +version = "0.6.2" +description = "hnswlib" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +numpy = "*" + [[package]] name = "idna" version = "2.10" description = "Internationalized Domain Names in Applications (IDNA)" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" @@ -205,6 +264,22 @@ pipfile-deprecated-finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] requirements-deprecated-finder = ["pip-api", "pipreqs"] +[[package]] +name = "joblib" +version = "1.2.0" +description = "Lightweight pipelining with Python functions" +category = "main" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "kiwisolver" +version = "1.4.4" +description = "A fast implementation of the Cassowary constraint solver" +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "lazy-object-proxy" version = "1.8.0" @@ -213,6 +288,40 @@ category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "lightfm" +version = "1.16" +description = "LightFM recommendation model" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +numpy = "*" +requests = "*" +scikit-learn = "*" +scipy = ">=0.17.0" + +[[package]] +name = "matplotlib" +version = "3.6.2" +description = "Python plotting package" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.0.1" +numpy = ">=1.19" +packaging = ">=20.0" +pillow = ">=6.2.0" +pyparsing = ">=2.2.1" +python-dateutil = ">=2.7" +setuptools_scm = ">=7" + [[package]] name = "mccabe" version = "0.6.1" @@ -245,6 +354,27 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "nmslib" +version = "2.1.1" +description = "Non-Metric Space Library (NMSLIB)" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +numpy = {version = ">=1.10.0", markers = "python_version >= \"3.5\""} +psutil = "*" +pybind11 = "<2.6.2" + +[[package]] +name = "numpy" +version = "1.23.5" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" +optional = false +python-versions = ">=3.8" + [[package]] name = "orjson" version = "3.8.1" @@ -257,13 +387,33 @@ python-versions = ">=3.7" name = "packaging" version = "21.3" description = "Core utilities for Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +[[package]] +name = "pandas" +version = "1.5.2" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +numpy = [ + {version = ">=1.20.3", markers = "python_version < \"3.10\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, +] +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] + [[package]] name = "pbr" version = "5.11.0" @@ -272,6 +422,18 @@ category = "dev" optional = false python-versions = ">=2.6" +[[package]] +name = "pillow" +version = "9.3.0" +description = "Python Imaging Library (Fork)" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + [[package]] name = "pluggy" version = "1.0.0" @@ -284,6 +446,17 @@ python-versions = ">=3.6" dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "5.9.4" +description = "Cross-platform lib for process and system monitoring in Python." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + [[package]] name = "py" version = "1.11.0" @@ -292,6 +465,17 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "pybind11" +version = "2.6.1" +description = "Seamless operability between C++11 and Python" +category = "main" +optional = false +python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7" + +[package.extras] +global = ["pybind11-global (==2.6.1)"] + [[package]] name = "pycodestyle" version = "2.7.0" @@ -342,7 +526,7 @@ toml = ">=0.7.1" name = "pyparsing" version = "3.0.9" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "dev" +category = "main" optional = false python-versions = ">=3.6.8" @@ -370,6 +554,25 @@ toml = "*" [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2022.6" +description = "World timezone definitions, modern and historical" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "pyyaml" version = "6.0" @@ -382,7 +585,7 @@ python-versions = ">=3.6" name = "requests" version = "2.25.1" description = "Python HTTP for Humans." -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -396,6 +599,60 @@ urllib3 = ">=1.21.1,<1.27" security = ["cryptography (>=1.3.4)", "pyOpenSSL (>=0.14)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +[[package]] +name = "scikit-learn" +version = "1.2.0" +description = "A set of python modules for machine learning and data mining" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +joblib = ">=1.1.1" +numpy = ">=1.17.3" +scipy = ">=1.3.2" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] +tests = ["black (>=22.3.0)", "flake8 (>=3.8.2)", "matplotlib (>=3.1.3)", "mypy (>=0.961)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=5.3.1)", "pytest-cov (>=2.9.0)", "scikit-image (>=0.16.2)"] + +[[package]] +name = "scipy" +version = "1.9.3" +description = "Fundamental algorithms for scientific computing in Python" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +numpy = ">=1.18.5,<1.26.0" + +[package.extras] +dev = ["flake8", "mypy", "pycodestyle", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-panels (>=0.5.2)", "sphinx-tabs"] +test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "seaborn" +version = "0.12.1" +description = "Statistical data visualization" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +matplotlib = ">=3.1,<3.6.1 || >3.6.1" +numpy = ">=1.17" +pandas = ">=0.25" + +[package.extras] +dev = ["flake8", "mypy", "pandas-stubs", "pre-commit", "pytest", "pytest-cov", "pytest-xdist"] +docs = ["ipykernel", "nbconvert", "numpydoc", "pydata_sphinx_theme (==0.10.0rc2)", "pyyaml", "sphinx-copybutton", "sphinx-design", "sphinx-issues"] +stats = ["scipy (>=1.3)", "statsmodels (>=0.10)"] + [[package]] name = "setuptools" version = "65.5.1" @@ -409,6 +666,32 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "setuptools-scm" +version = "7.0.5" +description = "the blessed package to manage your versions by scm tags" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +packaging = ">=20.0" +setuptools = "*" +tomli = ">=1.0.0" +typing-extensions = "*" + +[package.extras] +test = ["pytest (>=6.2)", "virtualenv (>20)"] +toml = ["setuptools (>=42)"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "smmap" version = "5.0.0" @@ -439,6 +722,14 @@ python-versions = ">=3.8" [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" +[[package]] +name = "threadpoolctl" +version = "3.1.0" +description = "threadpoolctl" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "toml" version = "0.10.2" @@ -447,6 +738,14 @@ category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "typed-ast" version = "1.4.3" @@ -467,7 +766,7 @@ python-versions = ">=3.7" name = "urllib3" version = "1.26.12" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" @@ -516,7 +815,7 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "c01b97e2fda031efbc5277fdfb65da75cef9b2da388aa7ecbfbe6d5a68e8dfdb" +content-hash = "3957c89d954678489df8387dc97b248f3fd78e26a9d5e0455fc5779a33456910" [metadata.files] asgiref = [ @@ -554,6 +853,81 @@ colorama = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +contourpy = [ + {file = "contourpy-1.0.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:613c665529899b5d9fade7e5d1760111a0b011231277a0d36c49f0d3d6914bd6"}, + {file = "contourpy-1.0.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:78ced51807ccb2f45d4ea73aca339756d75d021069604c2fccd05390dc3c28eb"}, + {file = "contourpy-1.0.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3b1bd7577c530eaf9d2bc52d1a93fef50ac516a8b1062c3d1b9bcec9ebe329b"}, + {file = "contourpy-1.0.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8834c14b8c3dd849005e06703469db9bf96ba2d66a3f88ecc539c9a8982e0ee"}, + {file = "contourpy-1.0.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4052a8a4926d4468416fc7d4b2a7b2a3e35f25b39f4061a7e2a3a2748c4fc48"}, + {file = "contourpy-1.0.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c0e1308307a75e07d1f1b5f0f56b5af84538a5e9027109a7bcf6cb47c434e72"}, + {file = "contourpy-1.0.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fc4e7973ed0e1fe689435842a6e6b330eb7ccc696080dda9a97b1a1b78e41db"}, + {file = "contourpy-1.0.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:08e8d09d96219ace6cb596506fb9b64ea5f270b2fb9121158b976d88871fcfd1"}, + {file = "contourpy-1.0.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f33da6b5d19ad1bb5e7ad38bb8ba5c426d2178928bc2b2c44e8823ea0ecb6ff3"}, + {file = "contourpy-1.0.6-cp310-cp310-win32.whl", hash = "sha256:12a7dc8439544ed05c6553bf026d5e8fa7fad48d63958a95d61698df0e00092b"}, + {file = "contourpy-1.0.6-cp310-cp310-win_amd64.whl", hash = "sha256:eadad75bf91897f922e0fb3dca1b322a58b1726a953f98c2e5f0606bd8408621"}, + {file = "contourpy-1.0.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:913bac9d064cff033cf3719e855d4f1db9f1c179e0ecf3ba9fdef21c21c6a16a"}, + {file = "contourpy-1.0.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46deb310a276cc5c1fd27958e358cce68b1e8a515fa5a574c670a504c3a3fe30"}, + {file = "contourpy-1.0.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b64f747e92af7da3b85631a55d68c45a2d728b4036b03cdaba4bd94bcc85bd6f"}, + {file = "contourpy-1.0.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50627bf76abb6ba291ad08db583161939c2c5fab38c38181b7833423ab9c7de3"}, + {file = "contourpy-1.0.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:358f6364e4873f4d73360b35da30066f40387dd3c427a3e5432c6b28dd24a8fa"}, + {file = "contourpy-1.0.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c78bfbc1a7bff053baf7e508449d2765964d67735c909b583204e3240a2aca45"}, + {file = "contourpy-1.0.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e43255a83835a129ef98f75d13d643844d8c646b258bebd11e4a0975203e018f"}, + {file = "contourpy-1.0.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:375d81366afd547b8558c4720337218345148bc2fcffa3a9870cab82b29667f2"}, + {file = "contourpy-1.0.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b98c820608e2dca6442e786817f646d11057c09a23b68d2b3737e6dcb6e4a49b"}, + {file = "contourpy-1.0.6-cp311-cp311-win32.whl", hash = "sha256:0e4854cc02006ad6684ce092bdadab6f0912d131f91c2450ce6dbdea78ee3c0b"}, + {file = "contourpy-1.0.6-cp311-cp311-win_amd64.whl", hash = "sha256:d2eff2af97ea0b61381828b1ad6cd249bbd41d280e53aea5cccd7b2b31b8225c"}, + {file = "contourpy-1.0.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5b117d29433fc8393b18a696d794961464e37afb34a6eeb8b2c37b5f4128a83e"}, + {file = "contourpy-1.0.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:341330ed19074f956cb20877ad8d2ae50e458884bfa6a6df3ae28487cc76c768"}, + {file = "contourpy-1.0.6-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:371f6570a81dfdddbb837ba432293a63b4babb942a9eb7aaa699997adfb53278"}, + {file = "contourpy-1.0.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9447c45df407d3ecb717d837af3b70cfef432138530712263730783b3d016512"}, + {file = "contourpy-1.0.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:730c27978a0003b47b359935478b7d63fd8386dbb2dcd36c1e8de88cbfc1e9de"}, + {file = "contourpy-1.0.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:da1ef35fd79be2926ba80fbb36327463e3656c02526e9b5b4c2b366588b74d9a"}, + {file = "contourpy-1.0.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cd2bc0c8f2e8de7dd89a7f1c10b8844e291bca17d359373203ef2e6100819edd"}, + {file = "contourpy-1.0.6-cp37-cp37m-win32.whl", hash = "sha256:3a1917d3941dd58732c449c810fa7ce46cc305ce9325a11261d740118b85e6f3"}, + {file = "contourpy-1.0.6-cp37-cp37m-win_amd64.whl", hash = "sha256:06ca79e1efbbe2df795822df2fa173d1a2b38b6e0f047a0ec7903fbca1d1847e"}, + {file = "contourpy-1.0.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e626cefff8491bce356221c22af5a3ea528b0b41fbabc719c00ae233819ea0bf"}, + {file = "contourpy-1.0.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dbe6fe7a1166b1ddd7b6d887ea6fa8389d3f28b5ed3f73a8f40ece1fc5a3d340"}, + {file = "contourpy-1.0.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e13b31d1b4b68db60b3b29f8e337908f328c7f05b9add4b1b5c74e0691180109"}, + {file = "contourpy-1.0.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a79d239fc22c3b8d9d3de492aa0c245533f4f4c7608e5749af866949c0f1b1b9"}, + {file = "contourpy-1.0.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e8e686a6db92a46111a1ee0ee6f7fbfae4048f0019de207149f43ac1812cf95"}, + {file = "contourpy-1.0.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2bd02f1a7adff3a1f33e431eb96ab6d7987b039d2946a9b39fe6fb16a1036"}, + {file = "contourpy-1.0.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:03d1b9c6b44a9e30d554654c72be89af94fab7510b4b9f62356c64c81cec8b7d"}, + {file = "contourpy-1.0.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b48d94386f1994db7c70c76b5808c12e23ed7a4ee13693c2fc5ab109d60243c0"}, + {file = "contourpy-1.0.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:208bc904889c910d95aafcf7be9e677726df9ef71e216780170dbb7e37d118fa"}, + {file = "contourpy-1.0.6-cp38-cp38-win32.whl", hash = "sha256:444fb776f58f4906d8d354eb6f6ce59d0a60f7b6a720da6c1ccb839db7c80eb9"}, + {file = "contourpy-1.0.6-cp38-cp38-win_amd64.whl", hash = "sha256:9bc407a6af672da20da74823443707e38ece8b93a04009dca25856c2d9adadb1"}, + {file = "contourpy-1.0.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:aa4674cf3fa2bd9c322982644967f01eed0c91bb890f624e0e0daf7a5c3383e9"}, + {file = "contourpy-1.0.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f56515e7c6fae4529b731f6c117752247bef9cdad2b12fc5ddf8ca6a50965a5"}, + {file = "contourpy-1.0.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:344cb3badf6fc7316ad51835f56ac387bdf86c8e1b670904f18f437d70da4183"}, + {file = "contourpy-1.0.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b1e66346acfb17694d46175a0cea7d9036f12ed0c31dfe86f0f405eedde2bdd"}, + {file = "contourpy-1.0.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8468b40528fa1e15181cccec4198623b55dcd58306f8815a793803f51f6c474a"}, + {file = "contourpy-1.0.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1dedf4c64185a216c35eb488e6f433297c660321275734401760dafaeb0ad5c2"}, + {file = "contourpy-1.0.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:494efed2c761f0f37262815f9e3c4bb9917c5c69806abdee1d1cb6611a7174a0"}, + {file = "contourpy-1.0.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:75a2e638042118118ab39d337da4c7908c1af74a8464cad59f19fbc5bbafec9b"}, + {file = "contourpy-1.0.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a628bba09ba72e472bf7b31018b6281fd4cc903f0888049a3724afba13b6e0b8"}, + {file = "contourpy-1.0.6-cp39-cp39-win32.whl", hash = "sha256:e1739496c2f0108013629aa095cc32a8c6363444361960c07493818d0dea2da4"}, + {file = "contourpy-1.0.6-cp39-cp39-win_amd64.whl", hash = "sha256:a457ee72d9032e86730f62c5eeddf402e732fdf5ca8b13b41772aa8ae13a4563"}, + {file = "contourpy-1.0.6-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d912f0154a20a80ea449daada904a7eb6941c83281a9fab95de50529bfc3a1da"}, + {file = "contourpy-1.0.6-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4081918147fc4c29fad328d5066cfc751da100a1098398742f9f364be63803fc"}, + {file = "contourpy-1.0.6-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0537cc1195245bbe24f2913d1f9211b8f04eb203de9044630abd3664c6cc339c"}, + {file = "contourpy-1.0.6-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcd556c8fc37a342dd636d7eef150b1399f823a4462f8c968e11e1ebeabee769"}, + {file = "contourpy-1.0.6-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:f6ca38dd8d988eca8f07305125dec6f54ac1c518f1aaddcc14d08c01aebb6efc"}, + {file = "contourpy-1.0.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c1baa49ab9fedbf19d40d93163b7d3e735d9cd8d5efe4cce9907902a6dad391f"}, + {file = "contourpy-1.0.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:211dfe2bd43bf5791d23afbe23a7952e8ac8b67591d24be3638cabb648b3a6eb"}, + {file = "contourpy-1.0.6-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c38c6536c2d71ca2f7e418acaf5bca30a3af7f2a2fa106083c7d738337848dbe"}, + {file = "contourpy-1.0.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b1ee48a130da4dd0eb8055bbab34abf3f6262957832fd575e0cab4979a15a41"}, + {file = "contourpy-1.0.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5641927cc5ae66155d0c80195dc35726eae060e7defc18b7ab27600f39dd1fe7"}, + {file = "contourpy-1.0.6-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ee394502026d68652c2824348a40bf50f31351a668977b51437131a90d777ea"}, + {file = "contourpy-1.0.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b97454ed5b1368b66ed414c754cba15b9750ce69938fc6153679787402e4cdf"}, + {file = "contourpy-1.0.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0236875c5a0784215b49d00ebbe80c5b6b5d5244b3655a36dda88105334dea17"}, + {file = "contourpy-1.0.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c593aeff7a0171f639da92cb86d24954bbb61f8a1b530f74eb750a14685832"}, + {file = "contourpy-1.0.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9b0e7fe7f949fb719b206548e5cde2518ffb29936afa4303d8a1c4db43dcb675"}, + {file = "contourpy-1.0.6.tar.gz", hash = "sha256:6e459ebb8bb5ee4c22c19cc000174f8059981971a33ce11e17dddf6aca97a142"}, +] +cycler = [ + {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, + {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, +] fastapi = [ {file = "fastapi-0.65.3-py3-none-any.whl", hash = "sha256:d3e3c0ac35110efb22ee3ed28201cf32f9d11a9a0e52d7dd676cad25f5219523"}, {file = "fastapi-0.65.3.tar.gz", hash = "sha256:6ea2286e439c4ced7cce2b2862c25859601bf327a515c12dd6e431ef5d49d12f"}, @@ -562,6 +936,10 @@ flake8 = [ {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] +fonttools = [ + {file = "fonttools-4.38.0-py3-none-any.whl", hash = "sha256:820466f43c8be8c3009aef8b87e785014133508f0de64ec469e4efb643ae54fb"}, + {file = "fonttools-4.38.0.zip", hash = "sha256:2bb244009f9bf3fa100fc3ead6aeb99febe5985fa20afbfbaa2f8946c2fbdaf1"}, +] gitdb = [ {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, @@ -578,6 +956,9 @@ h11 = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] +hnswlib = [ + {file = "hnswlib-0.6.2.tar.gz", hash = "sha256:b696d13f3678aa6795d054a0e8c33b3a2c8e14908432aaf4ced7ebef8290a10c"}, +] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, @@ -590,6 +971,80 @@ isort = [ {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, ] +joblib = [ + {file = "joblib-1.2.0-py3-none-any.whl", hash = "sha256:091138ed78f800342968c523bdde947e7a305b8594b910a0fea2ab83c3c6d385"}, + {file = "joblib-1.2.0.tar.gz", hash = "sha256:e1cee4a79e4af22881164f218d4311f60074197fb707e082e803b61f6d137018"}, +] +kiwisolver = [ + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, + {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, +] lazy-object-proxy = [ {file = "lazy-object-proxy-1.8.0.tar.gz", hash = "sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156"}, {file = "lazy_object_proxy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe"}, @@ -611,6 +1066,52 @@ lazy-object-proxy = [ {file = "lazy_object_proxy-1.8.0-pp38-pypy38_pp73-any.whl", hash = "sha256:7e1561626c49cb394268edd00501b289053a652ed762c58e1081224c8d881cec"}, {file = "lazy_object_proxy-1.8.0-pp39-pypy39_pp73-any.whl", hash = "sha256:ce58b2b3734c73e68f0e30e4e725264d4d6be95818ec0a0be4bb6bf9a7e79aa8"}, ] +lightfm = [ + {file = "lightfm-1.16.tar.gz", hash = "sha256:41950fd8affde192c10b517148aa7f6d016ae2f75a2ec1187335f1c4d21876ac"}, +] +matplotlib = [ + {file = "matplotlib-3.6.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:8d0068e40837c1d0df6e3abf1cdc9a34a6d2611d90e29610fa1d2455aeb4e2e5"}, + {file = "matplotlib-3.6.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:252957e208c23db72ca9918cb33e160c7833faebf295aaedb43f5b083832a267"}, + {file = "matplotlib-3.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d50e8c1e571ee39b5dfbc295c11ad65988879f68009dd281a6e1edbc2ff6c18c"}, + {file = "matplotlib-3.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d840adcad7354be6f2ec28d0706528b0026e4c3934cc6566b84eac18633eab1b"}, + {file = "matplotlib-3.6.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78ec3c3412cf277e6252764ee4acbdbec6920cc87ad65862272aaa0e24381eee"}, + {file = "matplotlib-3.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9347cc6822f38db2b1d1ce992f375289670e595a2d1c15961aacbe0977407dfc"}, + {file = "matplotlib-3.6.2-cp310-cp310-win32.whl", hash = "sha256:e0bbee6c2a5bf2a0017a9b5e397babb88f230e6f07c3cdff4a4c4bc75ed7c617"}, + {file = "matplotlib-3.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:8a0ae37576ed444fe853709bdceb2be4c7df6f7acae17b8378765bd28e61b3ae"}, + {file = "matplotlib-3.6.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:5ecfc6559132116dedfc482d0ad9df8a89dc5909eebffd22f3deb684132d002f"}, + {file = "matplotlib-3.6.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9f335e5625feb90e323d7e3868ec337f7b9ad88b5d633f876e3b778813021dab"}, + {file = "matplotlib-3.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2604c6450f9dd2c42e223b1f5dca9643a23cfecc9fde4a94bb38e0d2693b136"}, + {file = "matplotlib-3.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5afe0a7ea0e3a7a257907060bee6724a6002b7eec55d0db16fd32409795f3e1"}, + {file = "matplotlib-3.6.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca0e7a658fbafcddcaefaa07ba8dae9384be2343468a8e011061791588d839fa"}, + {file = "matplotlib-3.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32d29c8c26362169c80c5718ce367e8c64f4dd068a424e7110df1dd2ed7bd428"}, + {file = "matplotlib-3.6.2-cp311-cp311-win32.whl", hash = "sha256:5024b8ed83d7f8809982d095d8ab0b179bebc07616a9713f86d30cf4944acb73"}, + {file = "matplotlib-3.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:52c2bdd7cd0bf9d5ccdf9c1816568fd4ccd51a4d82419cc5480f548981b47dd0"}, + {file = "matplotlib-3.6.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:8a8dbe2cb7f33ff54b16bb5c500673502a35f18ac1ed48625e997d40c922f9cc"}, + {file = "matplotlib-3.6.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:380d48c15ec41102a2b70858ab1dedfa33eb77b2c0982cb65a200ae67a48e9cb"}, + {file = "matplotlib-3.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0844523dfaaff566e39dbfa74e6f6dc42e92f7a365ce80929c5030b84caa563a"}, + {file = "matplotlib-3.6.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7f716b6af94dc1b6b97c46401774472f0867e44595990fe80a8ba390f7a0a028"}, + {file = "matplotlib-3.6.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74153008bd24366cf099d1f1e83808d179d618c4e32edb0d489d526523a94d9f"}, + {file = "matplotlib-3.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f41e57ad63d336fe50d3a67bb8eaa26c09f6dda6a59f76777a99b8ccd8e26aec"}, + {file = "matplotlib-3.6.2-cp38-cp38-win32.whl", hash = "sha256:d0e9ac04065a814d4cf2c6791a2ad563f739ae3ae830d716d54245c2b96fead6"}, + {file = "matplotlib-3.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:8a9d899953c722b9afd7e88dbefd8fb276c686c3116a43c577cfabf636180558"}, + {file = "matplotlib-3.6.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:f04f97797df35e442ed09f529ad1235d1f1c0f30878e2fe09a2676b71a8801e0"}, + {file = "matplotlib-3.6.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3964934731fd7a289a91d315919cf757f293969a4244941ab10513d2351b4e83"}, + {file = "matplotlib-3.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:168093410b99f647ba61361b208f7b0d64dde1172b5b1796d765cd243cadb501"}, + {file = "matplotlib-3.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e16dcaecffd55b955aa5e2b8a804379789c15987e8ebd2f32f01398a81e975b"}, + {file = "matplotlib-3.6.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83dc89c5fd728fdb03b76f122f43b4dcee8c61f1489e232d9ad0f58020523e1c"}, + {file = "matplotlib-3.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:795ad83940732b45d39b82571f87af0081c120feff2b12e748d96bb191169e33"}, + {file = "matplotlib-3.6.2-cp39-cp39-win32.whl", hash = "sha256:19d61ee6414c44a04addbe33005ab1f87539d9f395e25afcbe9a3c50ce77c65c"}, + {file = "matplotlib-3.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:5ba73aa3aca35d2981e0b31230d58abb7b5d7ca104e543ae49709208d8ce706a"}, + {file = "matplotlib-3.6.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1836f366272b1557a613f8265db220eb8dd883202bbbabe01bad5a4eadfd0c95"}, + {file = "matplotlib-3.6.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eda9d1b43f265da91fb9ae10d6922b5a986e2234470a524e6b18f14095b20d2"}, + {file = "matplotlib-3.6.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9be0f4826cdb3a3a517509dcc5f87f370251b76362051ab59e42b6b765f8c4"}, + {file = "matplotlib-3.6.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3cef89888a466228fc4e4b2954e740ce8e9afde7c4315fdd18caa1b8de58ca17"}, + {file = "matplotlib-3.6.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:54fa9fe27f5466b86126ff38123261188bed568c1019e4716af01f97a12fe812"}, + {file = "matplotlib-3.6.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e68be81cd8c22b029924b6d0ee814c337c0e706b8d88495a617319e5dd5441c3"}, + {file = "matplotlib-3.6.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0ca2c60d3966dfd6608f5f8c49b8a0fcf76de6654f2eda55fc6ef038d5a6f27"}, + {file = "matplotlib-3.6.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4426c74761790bff46e3d906c14c7aab727543293eed5a924300a952e1a3a3c1"}, + {file = "matplotlib-3.6.2.tar.gz", hash = "sha256:b03fd10a1709d0101c054883b550f7c4c5e974f751e2680318759af005964990"}, +] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, @@ -643,6 +1144,73 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +nmslib = [ + {file = "nmslib-2.1.1-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:495ace1146bb1e89ef585a490fa65de19a87fa0d5bb029f3156402a431fc3558"}, + {file = "nmslib-2.1.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:c0ae48f01e63e70dc1e45b28cb1b1478ca09588a21127f1d4473afb22ff3bbbc"}, + {file = "nmslib-2.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:97b3f1af2c163369a043449dec7f05d681aa23c00f9d77bee09fd8f31ba41815"}, + {file = "nmslib-2.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:2061e94f980666bffff4f2173bf2b58a763062dee9cedab11ec46001e576c6b5"}, + {file = "nmslib-2.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e8b30bab631258b36e751d217180cdba0d2f942d779d4444cbc57a5173ee19ad"}, + {file = "nmslib-2.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:191a23dea20c0ad855e78df41a90273020f76d878c52aa1a80557ca83cf0f392"}, + {file = "nmslib-2.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:eae9a1d640a9e4c52c43272620f54f367f03ce25d8b07218fd90dfc204d5c49d"}, + {file = "nmslib-2.1.1-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:c22ffc3376d41b4b4e63d89ec5db2cf2e2051881827d658c94632800bed87e5b"}, + {file = "nmslib-2.1.1-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:a1ff4aeb143747106994a68dfcc29b097fc4562f632f2709f8f467b93d7181e2"}, + {file = "nmslib-2.1.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:5ce529d4f9b572135cdc5a18f04d3cbe258f1f440f8a06ab7209428a3b4c30d6"}, + {file = "nmslib-2.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:00f5b37305837fd5656ab4a65c4f0c9bc8e44cc9cf77cc9222f4153a72f0c727"}, + {file = "nmslib-2.1.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:08cb77c3fc2a346edc3407bd985b63a05bd0ec0d6d81ff2c6f7d6eb6bfbdbc1d"}, + {file = "nmslib-2.1.1-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:7dcc203450c9d95a551e9564646b9d0179edbde0874373ad63739b7e25a9980c"}, + {file = "nmslib-2.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:db4b817f0896e0bbc836722c67b51bc237dc79477d2d383ced344d755705d409"}, + {file = "nmslib-2.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1b120f7766a52c4016c6b8889b34d97eddbb60a16fd39eb5a81e73ca101baf3e"}, + {file = "nmslib-2.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e5cd5d492bf7290adacac797ee092c863d230f3797d0db6a120a1a05c665be2"}, + {file = "nmslib-2.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:0a80e574c3e6bfb724dbb77cbaec53cf9f4366382c2c0a9a2f5148c69b646afe"}, + {file = "nmslib-2.1.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:7b0d916f219b4044cd31e8f6bda92a7f23d68cb3f34f1c7da81e5852702d6ce0"}, + {file = "nmslib-2.1.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:a2129a7519ab73d3544ab6fa2f6c6c4c54644bf3d1c60d6929dcaac49c9307e6"}, + {file = "nmslib-2.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0f5c1c7e3c398a4ed7eaed65cd91776022b2ca4b8f15e504fa22c89da9333257"}, + {file = "nmslib-2.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c5a644d32ad3b2e24635a839d17d9d53d01a47ca55d1ba0d051f51f49df7e98a"}, + {file = "nmslib-2.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:fc75c7e128fd19c21c8cd73a1681a32d902bf5203699321cdfff8cf98607c82d"}, + {file = "nmslib-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:43118bb64f06e62662a8c7f1fe54ae699a078b438e3f8cb75db547731a5e73f6"}, + {file = "nmslib-2.1.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:1b87f7a5813cabedef47b289337ab1eefa4e62485a05884c2dbe7ba1d9c327a4"}, + {file = "nmslib-2.1.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:ca3d4eb91232078fb96eaa938a4dcbcfb3da48a7800350e1ded70d8d3e6e65a5"}, + {file = "nmslib-2.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:b6ebb53999672abf7811ef35e2ec3d76b2a845fd5dbaa5482e2cc445481d87cf"}, + {file = "nmslib-2.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:26062f5f172c35038c46feabb5c60c104808c167db0c3dfab19d11eb99f18b85"}, + {file = "nmslib-2.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:ed63fda2a5572391a0a540689f00d390040b9255e08012ea43344958cea92f36"}, + {file = "nmslib-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:6a3aa123d85c188fc64cb8957e5cdded9c8c57bea2c6a5866fe06c729e6e6e85"}, + {file = "nmslib-2.1.1-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:3fe5bbf304fdde50f3a55329efcf26d4ba4eb1181885877a1baab1df900dd671"}, + {file = "nmslib-2.1.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:7b5a561a71dce6d56b32ea89a591dbe477b4173fbc3e9a1153d534bc248ae7b5"}, + {file = "nmslib-2.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:82680077a06a817df95ea716260231245cf077a4c08b0f39148d4a58d2eb58f2"}, + {file = "nmslib-2.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:be54644e1a1a6e2539e565fe24415997f18656a5260276c40266cacb70e2a9ab"}, + {file = "nmslib-2.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:3681e3e9160fa9661192c19202402e22151e016cf365621609ae5ca4a4677d21"}, + {file = "nmslib-2.1.1.tar.gz", hash = "sha256:971294a7766f91c697d63c88c8adda4797a944346cc535a217393f4167a19c20"}, +] +numpy = [ + {file = "numpy-1.23.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9c88793f78fca17da0145455f0d7826bcb9f37da4764af27ac945488116efe63"}, + {file = "numpy-1.23.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e9f4c4e51567b616be64e05d517c79a8a22f3606499941d97bb76f2ca59f982d"}, + {file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7903ba8ab592b82014713c491f6c5d3a1cde5b4a3bf116404e08f5b52f6daf43"}, + {file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e05b1c973a9f858c74367553e236f287e749465f773328c8ef31abe18f691e1"}, + {file = "numpy-1.23.5-cp310-cp310-win32.whl", hash = "sha256:522e26bbf6377e4d76403826ed689c295b0b238f46c28a7251ab94716da0b280"}, + {file = "numpy-1.23.5-cp310-cp310-win_amd64.whl", hash = "sha256:dbee87b469018961d1ad79b1a5d50c0ae850000b639bcb1b694e9981083243b6"}, + {file = "numpy-1.23.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ce571367b6dfe60af04e04a1834ca2dc5f46004ac1cc756fb95319f64c095a96"}, + {file = "numpy-1.23.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56e454c7833e94ec9769fa0f86e6ff8e42ee38ce0ce1fa4cbb747ea7e06d56aa"}, + {file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5039f55555e1eab31124a5768898c9e22c25a65c1e0037f4d7c495a45778c9f2"}, + {file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f545efd1108e647604a1b5aa809591ccd2540f468a880bedb97247e72db387"}, + {file = "numpy-1.23.5-cp311-cp311-win32.whl", hash = "sha256:b2a9ab7c279c91974f756c84c365a669a887efa287365a8e2c418f8b3ba73fb0"}, + {file = "numpy-1.23.5-cp311-cp311-win_amd64.whl", hash = "sha256:0cbe9848fad08baf71de1a39e12d1b6310f1d5b2d0ea4de051058e6e1076852d"}, + {file = "numpy-1.23.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f063b69b090c9d918f9df0a12116029e274daf0181df392839661c4c7ec9018a"}, + {file = "numpy-1.23.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0aaee12d8883552fadfc41e96b4c82ee7d794949e2a7c3b3a7201e968c7ecab9"}, + {file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92c8c1e89a1f5028a4c6d9e3ccbe311b6ba53694811269b992c0b224269e2398"}, + {file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d208a0f8729f3fb790ed18a003f3a57895b989b40ea4dce4717e9cf4af62c6bb"}, + {file = "numpy-1.23.5-cp38-cp38-win32.whl", hash = "sha256:06005a2ef6014e9956c09ba07654f9837d9e26696a0470e42beedadb78c11b07"}, + {file = "numpy-1.23.5-cp38-cp38-win_amd64.whl", hash = "sha256:ca51fcfcc5f9354c45f400059e88bc09215fb71a48d3768fb80e357f3b457e1e"}, + {file = "numpy-1.23.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8969bfd28e85c81f3f94eb4a66bc2cf1dbdc5c18efc320af34bffc54d6b1e38f"}, + {file = "numpy-1.23.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7ac231a08bb37f852849bbb387a20a57574a97cfc7b6cabb488a4fc8be176de"}, + {file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf837dc63ba5c06dc8797c398db1e223a466c7ece27a1f7b5232ba3466aafe3d"}, + {file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33161613d2269025873025b33e879825ec7b1d831317e68f4f2f0f84ed14c719"}, + {file = "numpy-1.23.5-cp39-cp39-win32.whl", hash = "sha256:af1da88f6bc3d2338ebbf0e22fe487821ea4d8e89053e25fa59d1d79786e7481"}, + {file = "numpy-1.23.5-cp39-cp39-win_amd64.whl", hash = "sha256:09b7847f7e83ca37c6e627682f145856de331049013853f344f37b0c9690e3df"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:abdde9f795cf292fb9651ed48185503a2ff29be87770c3b8e2a14b0cd7aa16f8"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9a909a8bae284d46bbfdefbdd4a262ba19d3bc9921b1e76126b1d21c3c34135"}, + {file = "numpy-1.23.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:01dd17cbb340bf0fc23981e52e1d18a9d4050792e8fb8363cecbf066a84b827d"}, + {file = "numpy-1.23.5.tar.gz", hash = "sha256:1b1766d6f397c18153d40015ddfc79ddb715cabadc04d2d228d4e5a8bc4ded1a"}, +] orjson = [ {file = "orjson-3.8.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:a70aaa2e56356e58c6e1b49f7b7f069df5b15e55db002a74db3ff3f7af67c7ff"}, {file = "orjson-3.8.1-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:d45db052d01d0ab7579470141d5c3592f4402d43cfacb67f023bc1210a67b7bc"}, @@ -698,18 +1266,130 @@ packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] +pandas = [ + {file = "pandas-1.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e9dbacd22555c2d47f262ef96bb4e30880e5956169741400af8b306bbb24a273"}, + {file = "pandas-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e2b83abd292194f350bb04e188f9379d36b8dfac24dd445d5c87575f3beaf789"}, + {file = "pandas-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2552bffc808641c6eb471e55aa6899fa002ac94e4eebfa9ec058649122db5824"}, + {file = "pandas-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fc87eac0541a7d24648a001d553406f4256e744d92df1df8ebe41829a915028"}, + {file = "pandas-1.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0d8fd58df5d17ddb8c72a5075d87cd80d71b542571b5f78178fb067fa4e9c72"}, + {file = "pandas-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:4aed257c7484d01c9a194d9a94758b37d3d751849c05a0050c087a358c41ad1f"}, + {file = "pandas-1.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:375262829c8c700c3e7cbb336810b94367b9c4889818bbd910d0ecb4e45dc261"}, + {file = "pandas-1.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc3cd122bea268998b79adebbb8343b735a5511ec14efb70a39e7acbc11ccbdc"}, + {file = "pandas-1.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4f5a82afa4f1ff482ab8ded2ae8a453a2cdfde2001567b3ca24a4c5c5ca0db3"}, + {file = "pandas-1.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8092a368d3eb7116e270525329a3e5c15ae796ccdf7ccb17839a73b4f5084a39"}, + {file = "pandas-1.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6257b314fc14958f8122779e5a1557517b0f8e500cfb2bd53fa1f75a8ad0af2"}, + {file = "pandas-1.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:82ae615826da838a8e5d4d630eb70c993ab8636f0eff13cb28aafc4291b632b5"}, + {file = "pandas-1.5.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:457d8c3d42314ff47cc2d6c54f8fc0d23954b47977b2caed09cd9635cb75388b"}, + {file = "pandas-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c009a92e81ce836212ce7aa98b219db7961a8b95999b97af566b8dc8c33e9519"}, + {file = "pandas-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:71f510b0efe1629bf2f7c0eadb1ff0b9cf611e87b73cd017e6b7d6adb40e2b3a"}, + {file = "pandas-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a40dd1e9f22e01e66ed534d6a965eb99546b41d4d52dbdb66565608fde48203f"}, + {file = "pandas-1.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ae7e989f12628f41e804847a8cc2943d362440132919a69429d4dea1f164da0"}, + {file = "pandas-1.5.2-cp38-cp38-win32.whl", hash = "sha256:530948945e7b6c95e6fa7aa4be2be25764af53fba93fe76d912e35d1c9ee46f5"}, + {file = "pandas-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:73f219fdc1777cf3c45fde7f0708732ec6950dfc598afc50588d0d285fddaefc"}, + {file = "pandas-1.5.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9608000a5a45f663be6af5c70c3cbe634fa19243e720eb380c0d378666bc7702"}, + {file = "pandas-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:315e19a3e5c2ab47a67467fc0362cb36c7c60a93b6457f675d7d9615edad2ebe"}, + {file = "pandas-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e18bc3764cbb5e118be139b3b611bc3fbc5d3be42a7e827d1096f46087b395eb"}, + {file = "pandas-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0183cb04a057cc38fde5244909fca9826d5d57c4a5b7390c0cc3fa7acd9fa883"}, + {file = "pandas-1.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:344021ed3e639e017b452aa8f5f6bf38a8806f5852e217a7594417fb9bbfa00e"}, + {file = "pandas-1.5.2-cp39-cp39-win32.whl", hash = "sha256:e7469271497960b6a781eaa930cba8af400dd59b62ec9ca2f4d31a19f2f91090"}, + {file = "pandas-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:c218796d59d5abd8780170c937b812c9637e84c32f8271bbf9845970f8c1351f"}, + {file = "pandas-1.5.2.tar.gz", hash = "sha256:220b98d15cee0b2cd839a6358bd1f273d0356bf964c1a1aeb32d47db0215488b"}, +] pbr = [ {file = "pbr-5.11.0-py2.py3-none-any.whl", hash = "sha256:db2317ff07c84c4c63648c9064a79fe9d9f5c7ce85a9099d4b6258b3db83225a"}, {file = "pbr-5.11.0.tar.gz", hash = "sha256:b97bc6695b2aff02144133c2e7399d5885223d42b7912ffaec2ca3898e673bfe"}, ] +pillow = [ + {file = "Pillow-9.3.0-1-cp37-cp37m-win32.whl", hash = "sha256:e6ea6b856a74d560d9326c0f5895ef8050126acfdc7ca08ad703eb0081e82b74"}, + {file = "Pillow-9.3.0-1-cp37-cp37m-win_amd64.whl", hash = "sha256:32a44128c4bdca7f31de5be641187367fe2a450ad83b833ef78910397db491aa"}, + {file = "Pillow-9.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:0b7257127d646ff8676ec8a15520013a698d1fdc48bc2a79ba4e53df792526f2"}, + {file = "Pillow-9.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b90f7616ea170e92820775ed47e136208e04c967271c9ef615b6fbd08d9af0e3"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68943d632f1f9e3dce98908e873b3a090f6cba1cbb1b892a9e8d97c938871fbe"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be55f8457cd1eac957af0c3f5ece7bc3f033f89b114ef30f710882717670b2a8"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d77adcd56a42d00cc1be30843d3426aa4e660cab4a61021dc84467123f7a00c"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:829f97c8e258593b9daa80638aee3789b7df9da5cf1336035016d76f03b8860c"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:801ec82e4188e935c7f5e22e006d01611d6b41661bba9fe45b60e7ac1a8f84de"}, + {file = "Pillow-9.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:871b72c3643e516db4ecf20efe735deb27fe30ca17800e661d769faab45a18d7"}, + {file = "Pillow-9.3.0-cp310-cp310-win32.whl", hash = "sha256:655a83b0058ba47c7c52e4e2df5ecf484c1b0b0349805896dd350cbc416bdd91"}, + {file = "Pillow-9.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:9f47eabcd2ded7698106b05c2c338672d16a6f2a485e74481f524e2a23c2794b"}, + {file = "Pillow-9.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:57751894f6618fd4308ed8e0c36c333e2f5469744c34729a27532b3db106ee20"}, + {file = "Pillow-9.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7db8b751ad307d7cf238f02101e8e36a128a6cb199326e867d1398067381bff4"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3033fbe1feb1b59394615a1cafaee85e49d01b51d54de0cbf6aa8e64182518a1"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22b012ea2d065fd163ca096f4e37e47cd8b59cf4b0fd47bfca6abb93df70b34c"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a65733d103311331875c1dca05cb4606997fd33d6acfed695b1232ba1df193"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:502526a2cbfa431d9fc2a079bdd9061a2397b842bb6bc4239bb176da00993812"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:90fb88843d3902fe7c9586d439d1e8c05258f41da473952aa8b328d8b907498c"}, + {file = "Pillow-9.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:89dca0ce00a2b49024df6325925555d406b14aa3efc2f752dbb5940c52c56b11"}, + {file = "Pillow-9.3.0-cp311-cp311-win32.whl", hash = "sha256:3168434d303babf495d4ba58fc22d6604f6e2afb97adc6a423e917dab828939c"}, + {file = "Pillow-9.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:18498994b29e1cf86d505edcb7edbe814d133d2232d256db8c7a8ceb34d18cef"}, + {file = "Pillow-9.3.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:772a91fc0e03eaf922c63badeca75e91baa80fe2f5f87bdaed4280662aad25c9"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa4107d1b306cdf8953edde0534562607fe8811b6c4d9a486298ad31de733b2"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4012d06c846dc2b80651b120e2cdd787b013deb39c09f407727ba90015c684f"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77ec3e7be99629898c9a6d24a09de089fa5356ee408cdffffe62d67bb75fdd72"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:6c738585d7a9961d8c2821a1eb3dcb978d14e238be3d70f0a706f7fa9316946b"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:828989c45c245518065a110434246c44a56a8b2b2f6347d1409c787e6e4651ee"}, + {file = "Pillow-9.3.0-cp37-cp37m-win32.whl", hash = "sha256:82409ffe29d70fd733ff3c1025a602abb3e67405d41b9403b00b01debc4c9a29"}, + {file = "Pillow-9.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:41e0051336807468be450d52b8edd12ac60bebaa97fe10c8b660f116e50b30e4"}, + {file = "Pillow-9.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b03ae6f1a1878233ac620c98f3459f79fd77c7e3c2b20d460284e1fb370557d4"}, + {file = "Pillow-9.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4390e9ce199fc1951fcfa65795f239a8a4944117b5935a9317fb320e7767b40f"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40e1ce476a7804b0fb74bcfa80b0a2206ea6a882938eaba917f7a0f004b42502"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0a06a052c5f37b4ed81c613a455a81f9a3a69429b4fd7bb913c3fa98abefc20"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03150abd92771742d4a8cd6f2fa6246d847dcd2e332a18d0c15cc75bf6703040"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:15c42fb9dea42465dfd902fb0ecf584b8848ceb28b41ee2b58f866411be33f07"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:51e0e543a33ed92db9f5ef69a0356e0b1a7a6b6a71b80df99f1d181ae5875636"}, + {file = "Pillow-9.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3dd6caf940756101205dffc5367babf288a30043d35f80936f9bfb37f8355b32"}, + {file = "Pillow-9.3.0-cp38-cp38-win32.whl", hash = "sha256:f1ff2ee69f10f13a9596480335f406dd1f70c3650349e2be67ca3139280cade0"}, + {file = "Pillow-9.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:276a5ca930c913f714e372b2591a22c4bd3b81a418c0f6635ba832daec1cbcfc"}, + {file = "Pillow-9.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:73bd195e43f3fadecfc50c682f5055ec32ee2c933243cafbfdec69ab1aa87cad"}, + {file = "Pillow-9.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c7c8ae3864846fc95f4611c78129301e203aaa2af813b703c55d10cc1628535"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0918e03aa0c72ea56edbb00d4d664294815aa11291a11504a377ea018330d3"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0915e734b33a474d76c28e07292f196cdf2a590a0d25bcc06e64e545f2d146c"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0372acb5d3598f36ec0914deed2a63f6bcdb7b606da04dc19a88d31bf0c05b"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:ad58d27a5b0262c0c19b47d54c5802db9b34d38bbf886665b626aff83c74bacd"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:97aabc5c50312afa5e0a2b07c17d4ac5e865b250986f8afe2b02d772567a380c"}, + {file = "Pillow-9.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9aaa107275d8527e9d6e7670b64aabaaa36e5b6bd71a1015ddd21da0d4e06448"}, + {file = "Pillow-9.3.0-cp39-cp39-win32.whl", hash = "sha256:bac18ab8d2d1e6b4ce25e3424f709aceef668347db8637c2296bcf41acb7cf48"}, + {file = "Pillow-9.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:b472b5ea442148d1c3e2209f20f1e0bb0eb556538690fa70b5e1f79fa0ba8dc2"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ab388aaa3f6ce52ac1cb8e122c4bd46657c15905904b3120a6248b5b8b0bc228"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbb8e7f2abee51cef77673be97760abff1674ed32847ce04b4af90f610144c7b"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca31dd6014cb8b0b2db1e46081b0ca7d936f856da3b39744aef499db5d84d02"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c7025dce65566eb6e89f56c9509d4f628fddcedb131d9465cacd3d8bac337e7e"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ebf2029c1f464c59b8bdbe5143c79fa2045a581ac53679733d3a91d400ff9efb"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b59430236b8e58840a0dfb4099a0e8717ffb779c952426a69ae435ca1f57210c"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12ce4932caf2ddf3e41d17fc9c02d67126935a44b86df6a206cf0d7161548627"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae5331c23ce118c53b172fa64a4c037eb83c9165aba3a7ba9ddd3ec9fa64a699"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0b07fffc13f474264c336298d1b4ce01d9c5a011415b79d4ee5527bb69ae6f65"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:073adb2ae23431d3b9bcbcff3fe698b62ed47211d0716b067385538a1b0f28b8"}, + {file = "Pillow-9.3.0.tar.gz", hash = "sha256:c935a22a557a560108d780f9a0fc426dd7459940dc54faa49d83249c8d3e760f"}, +] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] +psutil = [ + {file = "psutil-5.9.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8"}, + {file = "psutil-5.9.4-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:68908971daf802203f3d37e78d3f8831b6d1014864d7a85937941bb35f09aefe"}, + {file = "psutil-5.9.4-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3ff89f9b835100a825b14c2808a106b6fdcc4b15483141482a12c725e7f78549"}, + {file = "psutil-5.9.4-cp27-cp27m-win32.whl", hash = "sha256:852dd5d9f8a47169fe62fd4a971aa07859476c2ba22c2254d4a1baa4e10b95ad"}, + {file = "psutil-5.9.4-cp27-cp27m-win_amd64.whl", hash = "sha256:9120cd39dca5c5e1c54b59a41d205023d436799b1c8c4d3ff71af18535728e94"}, + {file = "psutil-5.9.4-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6b92c532979bafc2df23ddc785ed116fced1f492ad90a6830cf24f4d1ea27d24"}, + {file = "psutil-5.9.4-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:efeae04f9516907be44904cc7ce08defb6b665128992a56957abc9b61dca94b7"}, + {file = "psutil-5.9.4-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:54d5b184728298f2ca8567bf83c422b706200bcbbfafdc06718264f9393cfeb7"}, + {file = "psutil-5.9.4-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16653106f3b59386ffe10e0bad3bb6299e169d5327d3f187614b1cb8f24cf2e1"}, + {file = "psutil-5.9.4-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54c0d3d8e0078b7666984e11b12b88af2db11d11249a8ac8920dd5ef68a66e08"}, + {file = "psutil-5.9.4-cp36-abi3-win32.whl", hash = "sha256:149555f59a69b33f056ba1c4eb22bb7bf24332ce631c44a319cec09f876aaeff"}, + {file = "psutil-5.9.4-cp36-abi3-win_amd64.whl", hash = "sha256:fd8522436a6ada7b4aad6638662966de0d61d241cb821239b2ae7013d41a43d4"}, + {file = "psutil-5.9.4-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:6001c809253a29599bc0dfd5179d9f8a5779f9dffea1da0f13c53ee568115e1e"}, + {file = "psutil-5.9.4.tar.gz", hash = "sha256:3d7f9739eb435d4b1338944abe23f49584bde5395f27487d2ee25ad9a8774a62"}, +] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] +pybind11 = [ + {file = "pybind11-2.6.1-py2.py3-none-any.whl", hash = "sha256:c3691da74b670a4850dec30c1145a0dad53a50eeca78b7e7cdc855b5c98fd32d"}, + {file = "pybind11-2.6.1.tar.gz", hash = "sha256:ab7e60a520fe6ae25eca939191bb2ac416cd58478ce754740238a8bf1af18934"}, +] pycodestyle = [ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, @@ -768,6 +1448,14 @@ pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, ] +python-dateutil = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] +pytz = [ + {file = "pytz-2022.6-py2.py3-none-any.whl", hash = "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427"}, + {file = "pytz-2022.6.tar.gz", hash = "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2"}, +] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, @@ -814,10 +1502,68 @@ requests = [ {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, ] +scikit-learn = [ + {file = "scikit-learn-1.2.0.tar.gz", hash = "sha256:680b65b3caee469541385d2ca5b03ff70408f6c618c583948312f0d2125df680"}, + {file = "scikit_learn-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1beaa631434d1f17a20b1eef5d842e58c195875d2bc11901a1a70b5fe544745b"}, + {file = "scikit_learn-1.2.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d395730f26d8fc752321f1953ddf72647c892d8bed74fad4d7c816ec9b602dfa"}, + {file = "scikit_learn-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd3480c982b9e616b9f76ad8587804d3f4e91b4e2a6752e7dafb8a2e1f541098"}, + {file = "scikit_learn-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:184a42842a4e698ffa4d849b6019de50a77a0aa24d26afa28fa49c9190bb144b"}, + {file = "scikit_learn-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:867023a044fdfe59e5014a7fec7a3086a8928f10b5dce9382eedf4135f6709a2"}, + {file = "scikit_learn-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5546a8894a0616e92489ef995b39a0715829f3df96e801bb55cbf196be0d9649"}, + {file = "scikit_learn-1.2.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:bc7073e025b62c1067cbfb76e69d08650c6b9d7a0e7afdfa20cb92d4afe516f6"}, + {file = "scikit_learn-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc0a72237f0c56780cf550df87201a702d3bdcbbb23c6ef7d54c19326fa23f19"}, + {file = "scikit_learn-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e1ea0bc1706da45589bcf2490cde6276490a1b88f9af208dbb396fdc3a0babf"}, + {file = "scikit_learn-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:f17420a8e3f40129aeb7e0f5ee35822d6178617007bb8f69521a2cefc20d5f00"}, + {file = "scikit_learn-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25ba705ee1600ffc5df1dccd8fae129d7c6836e44ffcbb52d78536c9eaf8fcf9"}, + {file = "scikit_learn-1.2.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:6b63ca2b0643d30fbf9d25d93017ed3fb8351f31175d82d104bfec60cba7bb87"}, + {file = "scikit_learn-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c772fa8c64776ad769fd764752c8452844307adcf10dee3adcc43988260f21"}, + {file = "scikit_learn-1.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0834e4cec2a2e0d8978f39cb8fe1cad3be6c27a47927e1774bf5737ea65ec228"}, + {file = "scikit_learn-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:da29d2e379c396a63af5ed4b671ad2005cd690ac373a23bee5a0f66504e05272"}, + {file = "scikit_learn-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:23a88883ca60c571a06278e4726b3b51b3709cfa4c93cacbf5568b22ba960899"}, + {file = "scikit_learn-1.2.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:40f3ff68c505cb9d1f3693397c73991875d609da905087e00e7b4477645ec67b"}, + {file = "scikit_learn-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9535e867281ae6987bb80620ba14cf1649e936bfe45f48727b978b7a2dbe835"}, + {file = "scikit_learn-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de897720173b26842e21bed54362f5294e282422116b61cd931d4f5d870b9855"}, + {file = "scikit_learn-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:ceb0008f345188aa236e49c973dc160b9ed504a3abd7b321a0ecabcb669be0bd"}, +] +scipy = [ + {file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0"}, + {file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9"}, + {file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb"}, + {file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc"}, + {file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0"}, + {file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58"}, + {file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027"}, +] +seaborn = [ + {file = "seaborn-0.12.1-py3-none-any.whl", hash = "sha256:a9eb39cba095fcb1e4c89a7fab1c57137d70a715a7f2eefcd41c9913c4d4ed65"}, + {file = "seaborn-0.12.1.tar.gz", hash = "sha256:bb1eb1d51d3097368c187c3ef089c0288ec1fe8aa1c69fb324c68aa1d02df4c1"}, +] setuptools = [ {file = "setuptools-65.5.1-py3-none-any.whl", hash = "sha256:d0b9a8433464d5800cbe05094acf5c6d52a91bfac9b52bcfc4d41382be5d5d31"}, {file = "setuptools-65.5.1.tar.gz", hash = "sha256:e197a19aa8ec9722928f2206f8de752def0e4c9fc6953527360d1c36d94ddb2f"}, ] +setuptools-scm = [ + {file = "setuptools_scm-7.0.5-py3-none-any.whl", hash = "sha256:7930f720905e03ccd1e1d821db521bff7ec2ac9cf0ceb6552dd73d24a45d3b02"}, + {file = "setuptools_scm-7.0.5.tar.gz", hash = "sha256:031e13af771d6f892b941adb6ea04545bbf91ebc5ce68c78aaf3fff6e1fb4844"}, +] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] smmap = [ {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, @@ -830,10 +1576,18 @@ stevedore = [ {file = "stevedore-4.1.1-py3-none-any.whl", hash = "sha256:aa6436565c069b2946fe4ebff07f5041e0c8bf18c7376dd29edf80cf7d524e4e"}, {file = "stevedore-4.1.1.tar.gz", hash = "sha256:7f8aeb6e3f90f96832c301bff21a7eb5eefbe894c88c506483d355565d88cc1a"}, ] +threadpoolctl = [ + {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, + {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, +] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, diff --git a/pyproject.toml b/pyproject.toml index 82c2a0c7..7de1e1d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,11 @@ uvloop = "^0.15.2" uvicorn = "^0.14.0" orjson = "^3.7.7" starlette = "^0.14.2" +seaborn = "^0.12.1" +lightfm = "1.16" +hnswlib = "0.6.2" +pybind11 = "2.6.1" +nmslib = "^2.1.1" [tool.poetry.dev-dependencies] pytest = "^6.2.4" From cfd80061aa934b02437431146d618fd5b00cc013 Mon Sep 17 00:00:00 2001 From: Shakirov Renat Date: Sun, 11 Dec 2022 20:14:39 +0300 Subject: [PATCH 03/12] update lightFM wrapper for online reco --- mypy.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy.ini b/mypy.ini index 3e6252bc..eb9d0f09 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,2 +1,3 @@ [mypy] allow_untyped_calls = true +ignore_missing_imports = True From 3a45f0bba53f1805d8d5b1ff1c3f90e038878df0 Mon Sep 17 00:00:00 2001 From: Shakirov Renat Date: Sun, 11 Dec 2022 20:15:05 +0300 Subject: [PATCH 04/12] update lightFM wrapper for online reco --- notebooks/online_LightFm.ipynb | 764 ++------------------------------- service/api/models_zoo.py | 532 ++++++++++++++++++++++- 2 files changed, 560 insertions(+), 736 deletions(-) diff --git a/notebooks/online_LightFm.ipynb b/notebooks/online_LightFm.ipynb index a953cc50..444b7730 100644 --- a/notebooks/online_LightFm.ipynb +++ b/notebooks/online_LightFm.ipynb @@ -2,29 +2,31 @@ "cells": [ { "cell_type": "code", - "execution_count": 292, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "import numpy as np\n", - "import scipy as sp\n", - "from typing import Optional\n", - "\n", "import os\n", + "import pickle\n", "import time\n", + "from collections import defaultdict\n", "from functools import reduce\n", - "from tqdm import tqdm\n", "from pathlib import Path\n", + "from typing import Optional\n", "\n", - "from lightfm import LightFM\n", + "import numpy as np\n", "import pandas as pd\n", - "from collections import defaultdict\n", - "from scipy.sparse import csr_matrix" + "import scipy as sp\n", + "from lightfm import LightFM\n", + "from scipy.sparse import csr_matrix\n", + "from tqdm import tqdm\n", + "\n", + "from service.api.models_zoo import LightFMWrapper" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -35,15 +37,15 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 2.2 s, sys: 325 ms, total: 2.53 s\n", - "Wall time: 2.55 s\n" + "CPU times: user 2.01 s, sys: 224 ms, total: 2.23 s\n", + "Wall time: 2.24 s\n" ] } ], @@ -56,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -66,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -79,481 +81,7 @@ }, { "cell_type": "code", - "execution_count": 197, - "metadata": {}, - "outputs": [], - "source": [ - "items.fillna('Unknown', inplace=True)\n", - "\n", - "items[\"genre\"] = items[\"genres\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "items[\"actors\"] = items[\"actors\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "\n", - "genre_feature = items[[\"item_id\", \"genre\"]].explode(\"genre\")\n", - "genre_feature.columns = [\"id\", \"value\"]\n", - "genre_feature[\"feature\"] = \"genre\"\n", - "\n", - "actors_feature = items[[\"item_id\", \"actors\"]].explode(\"actors\")\n", - "actors_feature.columns = [\"id\", \"value\"]\n", - "actors_feature[\"feature\"] = \"actors\"\n", - "\n", - "\n", - "content_feature = items.reindex(columns=['item_id', \"content_type\"])\n", - "content_feature.columns = [\"id\", \"value\"]\n", - "content_feature[\"feature\"] = \"content_type\"\n", - "\n", - "country_feature = items.reindex(columns=['item_id', \"countries\"])\n", - "country_feature.columns = [\"id\", \"value\"]\n", - "country_feature[\"feature\"] = \"countries\"\n", - "\n", - "age_feature = items.reindex(columns=['item_id', \"age_rating\"])\n", - "age_feature.columns = [\"id\", \"value\"]\n", - "age_feature[\"feature\"] = \"age_feature\"\n", - "\n", - "studios_feature = items.reindex(columns=['item_id', \"studios\"])\n", - "studios_feature.columns = [\"id\", \"value\"]\n", - "studios_feature[\"feature\"] = \"studios\"\n", - "\n", - "\n", - "genre_feature_bin = pd.get_dummies(genre_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - "content_feature_bin = pd.get_dummies(content_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - "studios_feature_bin = pd.get_dummies(studios_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - "age_feature_bin = pd.get_dummies(age_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - "country_feature_bin = pd.get_dummies(country_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - "\n", - "dfs = [genre_feature_bin, content_feature_bin, studios_feature_bin, age_feature_bin, country_feature_bin]\n", - "item_final_features = reduce(lambda left,right: pd.merge(left,right,on='id'), dfs)\n", - "\n", - "# item_final_features.id = item_final_features.id.map(model.mapping['items_mapping'])\n", - "# item_final_features = item_final_features.sort_values('id').drop('id', axis=1)\n", - "# item_final_features_matrix_sparse = csr_matrix(item_final_features.values)" - ] - }, - { - "cell_type": "code", - "execution_count": 332, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
value_18+value_no_genrevalue_анимацияvalue_анимеvalue_артхаусvalue_биографияvalue_блогерvalue_боевикиvalue_вестернvalue_военные...value_Японияvalue_Япония, Великобританияvalue_Япония, Канадаvalue_Япония, Китайvalue_Япония, Китай, Республика Кореяvalue_Япония, Россияvalue_Япония, СССРvalue_Япония, СШАvalue_Япония, США, Францияvalue_Япония, Сингапур
103290000000000...0000000000
24200000000000...0000000000
103340000000100...0000000000
75990000000000...0000000000
157140000000000...0000000000
..................................................................
62150000000000...0000000000
22850000000100...0000000000
102560000000000...0000000000
43780000000000...0000000000
30900000000000...0000000000
\n", - "

15963 rows × 831 columns

\n", - "
" - ], - "text/plain": [ - " value_18+ value_no_genre value_анимация value_аниме value_артхаус \\\n", - "10329 0 0 0 0 0 \n", - "2420 0 0 0 0 0 \n", - "10334 0 0 0 0 0 \n", - "7599 0 0 0 0 0 \n", - "15714 0 0 0 0 0 \n", - "... ... ... ... ... ... \n", - "6215 0 0 0 0 0 \n", - "2285 0 0 0 0 0 \n", - "10256 0 0 0 0 0 \n", - "4378 0 0 0 0 0 \n", - "3090 0 0 0 0 0 \n", - "\n", - " value_биография value_блогер value_боевики value_вестерн \\\n", - "10329 0 0 0 0 \n", - "2420 0 0 0 0 \n", - "10334 0 0 1 0 \n", - "7599 0 0 0 0 \n", - "15714 0 0 0 0 \n", - "... ... ... ... ... \n", - "6215 0 0 0 0 \n", - "2285 0 0 1 0 \n", - "10256 0 0 0 0 \n", - "4378 0 0 0 0 \n", - "3090 0 0 0 0 \n", - "\n", - " value_военные ... value_Япония value_Япония, Великобритания \\\n", - "10329 0 ... 0 0 \n", - "2420 0 ... 0 0 \n", - "10334 0 ... 0 0 \n", - "7599 0 ... 0 0 \n", - "15714 0 ... 0 0 \n", - "... ... ... ... ... \n", - "6215 0 ... 0 0 \n", - "2285 0 ... 0 0 \n", - "10256 0 ... 0 0 \n", - "4378 0 ... 0 0 \n", - "3090 0 ... 0 0 \n", - "\n", - " value_Япония, Канада value_Япония, Китай \\\n", - "10329 0 0 \n", - "2420 0 0 \n", - "10334 0 0 \n", - "7599 0 0 \n", - "15714 0 0 \n", - "... ... ... \n", - "6215 0 0 \n", - "2285 0 0 \n", - "10256 0 0 \n", - "4378 0 0 \n", - "3090 0 0 \n", - "\n", - " value_Япония, Китай, Республика Корея value_Япония, Россия \\\n", - "10329 0 0 \n", - "2420 0 0 \n", - "10334 0 0 \n", - "7599 0 0 \n", - "15714 0 0 \n", - "... ... ... \n", - "6215 0 0 \n", - "2285 0 0 \n", - "10256 0 0 \n", - "4378 0 0 \n", - "3090 0 0 \n", - "\n", - " value_Япония, СССР value_Япония, США value_Япония, США, Франция \\\n", - "10329 0 0 0 \n", - "2420 0 0 0 \n", - "10334 0 0 0 \n", - "7599 0 0 0 \n", - "15714 0 0 0 \n", - "... ... ... ... \n", - "6215 0 0 0 \n", - "2285 0 0 0 \n", - "10256 0 0 0 \n", - "4378 0 0 0 \n", - "3090 0 0 0 \n", - "\n", - " value_Япония, Сингапур \n", - "10329 0 \n", - "2420 0 \n", - "10334 0 \n", - "7599 0 \n", - "15714 0 \n", - "... ... \n", - "6215 0 \n", - "2285 0 \n", - "10256 0 \n", - "4378 0 \n", - "3090 0 \n", - "\n", - "[15963 rows x 831 columns]" - ] - }, - "execution_count": 332, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "item_final_features" - ] - }, - { - "cell_type": "code", - "execution_count": 267, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -564,293 +92,61 @@ }, { "cell_type": "code", - "execution_count": 328, - "metadata": {}, - "outputs": [], - "source": [ - "class LightFMWrapper:\n", - " \"\"\"\n", - " Class for fit-perdict LightFM\n", - " \"\"\"\n", - "\n", - " def __init__(\n", - " self,\n", - " random_state: int = 42,\n", - " learning_rate: float = 0.05,\n", - " no_components: int = 10,\n", - " item_alpha: float = 0,\n", - " user_alpha: float = 0,\n", - " loss: str = 'warp',\n", - " num_threads: int = 8,\n", - " epochs: int = 1,\n", - " verbose: int = 1,\n", - " ):\n", - " self.loss=loss\n", - " self.no_components=no_components\n", - " self.user_alpha=user_alpha\n", - " self.item_alpha=item_alpha\n", - " self.epochs=epochs\n", - " self.num_threads=num_threads\n", - "\n", - " self.verbose = verbose\n", - " self.is_fitted = False\n", - "\n", - " self.mapping: Dict[str, Dict[int, int]] = defaultdict(dict)\n", - "\n", - " self.weights_matrix = None\n", - " self.users_watched = None\n", - "\n", - " def get_mappings(self, users, items):\n", - " self.mapping['users_inv_mapping'] = dict(\n", - " enumerate(users['user_id'].unique())\n", - " )\n", - " self.mapping['users_mapping'] = dict({\n", - " v: k for k, v in self.mapping['users_inv_mapping'].items()\n", - " })\n", - "\n", - " self.mapping['items_inv_mapping'] = dict(\n", - " enumerate(items['item_id'].unique())\n", - " )\n", - " self.mapping['items_mapping'] = dict({\n", - " v: k for k, v in self.mapping['items_inv_mapping'].items()\n", - " })\n", - "\n", - " def get_matrix(\n", - " self, df: pd.DataFrame,\n", - " user_col: str = 'user_id',\n", - " item_col: str = 'item_id',\n", - " weight_col: str = None,\n", - " ):\n", - " if weight_col:\n", - " weights = df[weight_col].astype(np.float32)\n", - " else:\n", - " weights = np.ones(len(df), dtype=np.float32)\n", - "\n", - " if hasattr(self.mapping['users_mapping'], 'get') and \\\n", - " hasattr(self.mapping['items_mapping'], 'get'):\n", - " interaction_matrix = sp.sparse.coo_matrix((\n", - " weights,\n", - " (\n", - " df[user_col].map(self.mapping['users_mapping'].get),\n", - " df[item_col].map(self.mapping['items_mapping'].get)\n", - " )\n", - " ))\n", - " else:\n", - " raise AttributeError\n", - "\n", - " self.users_watched = df.groupby(user_col).agg({item_col: list})\n", - " return interaction_matrix\n", - "\n", - " def prepare_additional_features_users(self, features: pd.DataFrame):\n", - " pass\n", - "\n", - " def prepare_additional_features_items(self, features: pd.DataFrame):\n", - " items.fillna('Unknown', inplace=True)\n", - " items[\"genre\"] = items[\"genres\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - " items[\"actors\"] = items[\"actors\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "\n", - " genre_feature = items[[\"item_id\", \"genre\"]].explode(\"genre\")\n", - " genre_feature.columns = [\"id\", \"value\"]\n", - " genre_feature[\"feature\"] = \"genre\"\n", - "\n", - " actors_feature = items[[\"item_id\", \"actors\"]].explode(\"actors\")\n", - " actors_feature.columns = [\"id\", \"value\"]\n", - " actors_feature[\"feature\"] = \"actors\"\n", - "\n", - "\n", - " content_feature = items.reindex(columns=['item_id', \"content_type\"])\n", - " content_feature.columns = [\"id\", \"value\"]\n", - " content_feature[\"feature\"] = \"content_type\"\n", - "\n", - " country_feature = items.reindex(columns=['item_id', \"countries\"])\n", - " country_feature.columns = [\"id\", \"value\"]\n", - " country_feature[\"feature\"] = \"countries\"\n", - "\n", - " age_feature = items.reindex(columns=['item_id', \"age_rating\"])\n", - " age_feature.columns = [\"id\", \"value\"]\n", - " age_feature[\"feature\"] = \"age_feature\"\n", - "\n", - " studios_feature = items.reindex(columns=['item_id', \"studios\"])\n", - " studios_feature.columns = [\"id\", \"value\"]\n", - " studios_feature[\"feature\"] = \"studios\"\n", - "\n", - "\n", - " genre_feature_bin = pd.get_dummies(genre_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - " content_feature_bin = pd.get_dummies(content_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - " studios_feature_bin = pd.get_dummies(studios_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - " age_feature_bin = pd.get_dummies(age_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - " country_feature_bin = pd.get_dummies(country_feature[['id', 'value']]).groupby('id', as_index=False).sum()\n", - "\n", - " dfs = [genre_feature_bin, content_feature_bin, studios_feature_bin, age_feature_bin, country_feature_bin]\n", - " item_final_features = reduce(lambda left,right: pd.merge(left,right,on='id'), dfs)\n", - "\n", - " item_final_features.id = item_final_features.id.map(model.mapping['items_mapping'])\n", - " item_final_features = item_final_features.sort_values('id').drop('id', axis=1)\n", - " item_final_features_matrix_sparse = csr_matrix(item_final_features.values)\n", - "\n", - " return item_final_features_matrix_sparse\n", - "\n", - " def fit(\n", - " self,\n", - " train: pd.DataFrame,\n", - " user_features: Optional[pd.DataFrame] = None, # если не none, то делаем фичи\n", - " item_features: Optional[pd.DataFrame] = None, # если не none, то делаем фичи\n", - " ):\n", - " if user_features is not None:\n", - " user_features = self.prepare_additional_features_users(user_features)\n", - "\n", - " if item_features is not None:\n", - " item_features = self.prepare_additional_features_items(item_features)\n", - "\n", - "\n", - " self.get_mappings(users, items)\n", - " self.weights_matrix = self.get_matrix(train).tocsr()\n", - "\n", - " self.model = LightFM(\n", - " loss=self.loss,\n", - " no_components=self.no_components,\n", - " user_alpha=self.user_alpha,\n", - " item_alpha=self.item_alpha,\n", - " )\n", - "\n", - " self.model.fit(\n", - " self.weights_matrix,\n", - " epochs=self.epochs,\n", - " user_features=user_features, # csr_matrix of shape [n_users, n_user_features]\n", - " item_features=item_features, # csr_matrix of shape [n_items, n_item_features]\n", - " num_threads=self.num_threads,\n", - " verbose=self.verbose > 0,\n", - " )\n", - "\n", - " self.is_fitted = True\n", - "\n", - "\n", - " def predict(self, user_id: int, n_recs: int = 10):\n", - "\n", - " if not self.is_fitted:\n", - " raise ValueError(\"Fit model before predicting\")\n", - "\n", - " if user_id not in self.mapping['users_mapping'].keys(): return []\n", - " user_id = self.mapping['users_mapping'][user_id]\n", - "\n", - "\n", - " scores = self.model.predict(user_id, np.arange(len(self.mapping['items_mapping']))) # LightFM\n", - " top_items = np.argsort(-scores)[:n_recs]\n", - " recos = [self.mapping['items_inv_mapping'][inv_reco_item] for inv_reco_item in top_items]\n", - "\n", - " return recos" - ] - }, - { - "cell_type": "code", - "execution_count": 329, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "model = LightFMWrapper()" + "model = LightFMWrapper(epochs=5)" ] }, { "cell_type": "code", - "execution_count": 330, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "Epoch: 100%|██████████| 1/1 [00:05<00:00, 5.99s/it]\n" + "Epoch: 100%|██████████| 5/5 [00:27<00:00, 5.43s/it]\n" ] } ], "source": [ - "model.fit(train=interactions, item_features=items)" + "model.fit(train=interactions, item_features=items, user_features=users)" ] }, { "cell_type": "code", - "execution_count": 331, + "execution_count": 9, "metadata": { "scrolled": true }, - "outputs": [ - { - "ename": "ValueError", - "evalue": "The item feature matrix specifies more features than there are estimated feature embeddings: 831 vs 15963.", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mValueError\u001B[0m Traceback (most recent call last)", - "Cell \u001B[0;32mIn[331], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mpredict\u001B[49m\u001B[43m(\u001B[49m\u001B[43muser_id\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m176549\u001B[39;49m\u001B[43m)\u001B[49m\n", - "Cell \u001B[0;32mIn[328], line 167\u001B[0m, in \u001B[0;36mLightFMWrapper.predict\u001B[0;34m(self, user_id, n_recs)\u001B[0m\n\u001B[1;32m 163\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m user_id \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmapping[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124musers_mapping\u001B[39m\u001B[38;5;124m'\u001B[39m]\u001B[38;5;241m.\u001B[39mkeys(): \u001B[38;5;28;01mreturn\u001B[39;00m []\n\u001B[1;32m 164\u001B[0m user_id \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmapping[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124musers_mapping\u001B[39m\u001B[38;5;124m'\u001B[39m][user_id]\n\u001B[0;32m--> 167\u001B[0m scores \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mpredict\u001B[49m\u001B[43m(\u001B[49m\u001B[43muser_id\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mnp\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43marange\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mlen\u001B[39;49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmapping\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43mitems_mapping\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m \u001B[38;5;66;03m# LightFM\u001B[39;00m\n\u001B[1;32m 168\u001B[0m top_items \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39margsort(\u001B[38;5;241m-\u001B[39mscores)[:n_recs]\n\u001B[1;32m 169\u001B[0m recos \u001B[38;5;241m=\u001B[39m [\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmapping[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mitems_inv_mapping\u001B[39m\u001B[38;5;124m'\u001B[39m][inv_reco_item] \u001B[38;5;28;01mfor\u001B[39;00m inv_reco_item \u001B[38;5;129;01min\u001B[39;00m top_items]\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/lightfm/lightfm.py:817\u001B[0m, in \u001B[0;36mLightFM.predict\u001B[0;34m(self, user_ids, item_ids, item_features, user_features, num_threads)\u001B[0m\n\u001B[1;32m 814\u001B[0m n_users \u001B[38;5;241m=\u001B[39m user_ids\u001B[38;5;241m.\u001B[39mmax() \u001B[38;5;241m+\u001B[39m \u001B[38;5;241m1\u001B[39m\n\u001B[1;32m 815\u001B[0m n_items \u001B[38;5;241m=\u001B[39m item_ids\u001B[38;5;241m.\u001B[39mmax() \u001B[38;5;241m+\u001B[39m \u001B[38;5;241m1\u001B[39m\n\u001B[0;32m--> 817\u001B[0m (user_features, item_features) \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_construct_feature_matrices\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 818\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_users\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mn_items\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43muser_features\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mitem_features\u001B[49m\n\u001B[1;32m 819\u001B[0m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 821\u001B[0m lightfm_data \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_get_lightfm_data()\n\u001B[1;32m 823\u001B[0m predictions \u001B[38;5;241m=\u001B[39m np\u001B[38;5;241m.\u001B[39mempty(\u001B[38;5;28mlen\u001B[39m(user_ids), dtype\u001B[38;5;241m=\u001B[39mnp\u001B[38;5;241m.\u001B[39mfloat32)\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/lightfm/lightfm.py:335\u001B[0m, in \u001B[0;36mLightFM._construct_feature_matrices\u001B[0;34m(self, n_users, n_items, user_features, item_features)\u001B[0m\n\u001B[1;32m 333\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mitem_embeddings \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m 334\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mitem_embeddings\u001B[38;5;241m.\u001B[39mshape[\u001B[38;5;241m0\u001B[39m] \u001B[38;5;241m>\u001B[39m\u001B[38;5;241m=\u001B[39m item_features\u001B[38;5;241m.\u001B[39mshape[\u001B[38;5;241m1\u001B[39m]:\n\u001B[0;32m--> 335\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[1;32m 336\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mThe item feature matrix specifies more \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 337\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mfeatures than there are estimated \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 338\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mfeature embeddings: \u001B[39m\u001B[38;5;132;01m{}\u001B[39;00m\u001B[38;5;124m vs \u001B[39m\u001B[38;5;132;01m{}\u001B[39;00m\u001B[38;5;124m.\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;241m.\u001B[39mformat(\n\u001B[1;32m 339\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mitem_embeddings\u001B[38;5;241m.\u001B[39mshape[\u001B[38;5;241m0\u001B[39m], item_features\u001B[38;5;241m.\u001B[39mshape[\u001B[38;5;241m1\u001B[39m]\n\u001B[1;32m 340\u001B[0m )\n\u001B[1;32m 341\u001B[0m )\n\u001B[1;32m 343\u001B[0m user_features \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_to_cython_dtype(user_features)\n\u001B[1;32m 344\u001B[0m item_features \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_to_cython_dtype(item_features)\n", - "\u001B[0;31mValueError\u001B[0m: The item feature matrix specifies more features than there are estimated feature embeddings: 831 vs 15963." - ] - } - ], - "source": [ - "model.predict(user_id=176549)" - ] - }, - { - "cell_type": "code", - "execution_count": 320, - "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + "[3734, 2657, 11237, 13594, 12248, 11754, 1020, 10242, 142, 1451]" ] }, - "execution_count": 320, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "np.arange(10)" + "model.predict(user_id=176549)" ] }, { "cell_type": "code", - "execution_count": 326, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ - "user_id = model.mapping['users_mapping'][176549]\n", - "\n", - "scores = model.model.predict(user_id, np.arange(10))\n", - "top_items = np.argsort(-scores)[:10]" - ] - }, - { - "cell_type": "code", - "execution_count": 327, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([2, 1, 4, 7, 9, 5, 8, 6, 3, 0])" - ] - }, - "execution_count": 327, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "top_items" + "with open('../data/lightfm.pickle', 'wb') as f:\n", + " pickle.dump(model, f)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/service/api/models_zoo.py b/service/api/models_zoo.py index 32a3c867..eede9a81 100644 --- a/service/api/models_zoo.py +++ b/service/api/models_zoo.py @@ -1,11 +1,28 @@ -from abc import ABC -from typing import List +from abc import ABC, abstractmethod +from collections import defaultdict +from functools import reduce +from typing import Dict, List, Optional, Set, Tuple + +import dill +import numpy as np +import pandas as pd +import scipy as sp +from implicit.nearest_neighbours import ItemItemRecommender +from lightfm import LightFM +from scipy.sparse import csr_matrix class BaseModelZoo(ABC): def __init__(self): pass + @staticmethod + def unique_reco(items: List[int]) -> List[int]: + seen: Set[int] = set() + seen_add = seen.add + return [item for item in items if not (item in seen or seen_add(item))] + + @abstractmethod def reco_predict( self, user_id: int, @@ -33,3 +50,514 @@ def reco_predict( """ reco = list(range(k_recs)) return reco + + +class TopPopularAllCovered(BaseModelZoo): + def __init__( + self, + top_reco: Tuple[int, ...] = tuple([ + 10440, 15297, 9728, 13865, 2657, + 4151, 3734, 6809, 4740, 4880, 7571, + 11237, 8636, 14741 + ]) + ) -> None: + super().__init__() + self.top_reco = top_reco + + def reco_predict( + self, + user_id: int, + k_recs: int + ) -> List[int]: + """ + Main function for recommendation items to users + :param user_id: user identification + :param k_recs: how many recs do you need + :return: list of recommendation ids + """ + reco = list(self.top_reco)[:k_recs] + return reco + + +class Popular(BaseModelZoo): + def __init__( + self, + top_reco: Tuple[int, ...] = tuple([ + 10440, 15297, 9728, 13865, 4151, + 3734, 2657, 4880, 142, 6809 + ]) + ) -> None: + super().__init__() + self.top_reco = top_reco + + def reco_predict( + self, + user_id: int, + k_recs: int + ) -> List[int]: + """ + Main function for recommendation items to users + :param user_id: user identification + :param k_recs: how many recs do you need + :return: list of recommendation ids + """ + reco = list(self.top_reco)[:k_recs] + return reco + + +class KNNModelWithTop(BaseModelZoo): + def __init__( + self, + path_to_reco: str = "data/BlendingKNNWithAddFeatures.csv.gz", + top_reco: Tuple[int, ...] = tuple([ + 10440, 15297, 9728, 13865, 3734, + 12192, 4151, 11863, 7793, 7829 + ]), + ) -> None: + super().__init__() + self.path_to_reco = path_to_reco + if self.path_to_reco.endswith('csv.gz'): + self.data = pd.read_csv(path_to_reco, compression='gzip') + elif self.path_to_reco.endswith('.csv'): + self.data = pd.read_csv(path_to_reco) + self.top_reco = top_reco + + def reco_predict( + self, + user_id: int, + k_recs: int + ) -> List[int]: + """ + Main function for recommendation items to users + :param user_id: user identification + :param k_recs: how many recs do you need + :return: list of recommendation ids + """ + reco = ( + self.data[self.data.user_id == user_id] + .item_id + .tolist() + [:k_recs] + ) + + if len(reco) < k_recs: + reco.extend(self.top_reco) + reco = self.unique_reco(reco)[:k_recs] # Удаляем дубли + + return reco + + +class KNNModelBM25(BaseModelZoo): + def __init__( + self, + path_to_model: str = "data/knn_bm25.pickle", + top_reco: Tuple[int, ...] = tuple([ + 10440, 15297, 9728, 13865, 3734, + 12192, 4151, 11863, 7793, 7829 + ]) + ) -> None: + super().__init__() + + with open(path_to_model, 'rb') as f: + self.model = dill.load(f) + + self.top_reco = top_reco + + def reco_predict( + self, + user_id: int, + k_recs: int + ) -> List[int]: + """ + Main function for recommendation items to users + :param user_id: user identification + :param k_recs: how many recs do you need + :return: list of recommendation ids + """ + try: + reco = self.model.predict(user_id=user_id) + except KeyError: + reco = [] + + if len(reco) < k_recs: + reco.extend(self.top_reco) + reco = self.unique_reco(reco)[:k_recs] # Удаляем дубли + + return reco + + +class UserKNN: + """ + Class for fit-perdict UserKNN model and BM25 + based on ItemKNN model from implicit.nearest_neighbours + """ + + def __init__( + self, + dist_model: ItemItemRecommender, + n_neighbors: int = 50, + verbose: int = 1, + ): + self.n_neighbors = n_neighbors + self.dist_model = dist_model + self.verbose = verbose + self.is_fitted = False + + self.mapping: Dict[str, Dict[int, int]] = defaultdict(dict) + + self.weights_matrix = None + self.users_watched = None + + def get_mappings(self, train): + self.mapping['users_inv_mapping'] = dict( + enumerate(train['user_id'].unique()) + ) + self.mapping['users_mapping'] = { + v: k for k, v in self.mapping['users_inv_mapping'].items() + } + + self.mapping['items_inv_mapping'] = dict( + enumerate(train['item_id'].unique()) + ) + self.mapping['items_mapping'] = { + v: k for k, v in self.mapping['items_inv_mapping'].items() + } + + def get_matrix( + self, df: pd.DataFrame, + user_col: str = 'user_id', + item_col: str = 'item_id', + weight_col: str = None, + ): + if weight_col: + weights = df[weight_col].astype(np.float32) + else: + weights = np.ones(len(df), dtype=np.float32) + + if hasattr(self.mapping['users_mapping'], 'get') and \ + hasattr(self.mapping['items_mapping'], 'get'): + interaction_matrix = sp.sparse.coo_matrix(( + weights, + ( + df[user_col].map(self.mapping['users_mapping'].get), + df[item_col].map(self.mapping['items_mapping'].get) + ) + )) + else: + raise AttributeError + + self.users_watched = df.groupby(user_col).agg({item_col: list}) + return interaction_matrix + + def fit(self, train: pd.DataFrame): + self.get_mappings(train) + self.weights_matrix = self.get_matrix(train).tocsr().T + + self.dist_model.fit( + self.weights_matrix, + show_progress=(self.verbose > 0) + ) + self.is_fitted = True + + @staticmethod + def _generate_recs_mapper( + model: ItemItemRecommender, + user_mapping: Dict[int, int], + user_inv_mapping: Dict[int, int], + n_neighbors: int + ): + def _recs_mapper(user): + user_id = user_mapping[user] + recs = model.similar_items(user_id, N=n_neighbors) + return ( + [user_inv_mapping[user] for user, _ in zip(*recs)], + [sim for _, sim in zip(*recs)] + ) + + return _recs_mapper + + def predict(self, user_id: int, n_recs: int = 10): + + if not self.is_fitted: + raise ValueError("Fit model before predicting") + + mapper = self._generate_recs_mapper( + model=self.dist_model, + user_mapping=self.mapping['users_mapping'], + user_inv_mapping=self.mapping['users_inv_mapping'], + n_neighbors=self.n_neighbors + ) + + recs = pd.DataFrame({'user_id': [user_id]}) + + try: + recs['sim_user_id'], recs['sim'] = zip( + *recs['user_id'].map(mapper) + ) + except AttributeError: + return [] + + recs = recs.set_index('user_id').apply(pd.Series.explode).reset_index() + + recs = ( + recs + .merge( + self.users_watched, + left_on=['sim_user_id'], + right_on=['user_id'], how='left' + ) + .explode('item_id') + .sort_values(['user_id', 'sim'], ascending=False) + .drop_duplicates(['user_id', 'item_id'], keep='first') + ) + + recs['rank'] = recs.groupby('user_id').cumcount() + 1 + + result = recs[recs['rank'] <= n_recs][['user_id', 'item_id', 'rank']] + + return result.item_id.tolist()[:n_recs] + + +class LightFMWrapper: + """ + Class for fit-predict LightFM + """ + def __init__( + self, + random_state: int = 42, + learning_rate: float = 0.05, + no_components: int = 10, + item_alpha: float = 0, + user_alpha: float = 0, + loss: str = 'warp', + ): + + self.is_fitted = False + + self.mapping: Dict[str, Dict[int, int]] = defaultdict(dict) + + self.weights_matrix = None + self.users_watched = None + + self.user_features = None + self.item_features = None + + self.model = LightFM( + loss=loss, + no_components=no_components, + user_alpha=user_alpha, + item_alpha=item_alpha, + random_state=random_state, + learning_rate=learning_rate, + ) + + def get_mappings(self, users, items): + self.mapping['users_inv_mapping'] = dict( + enumerate(users['user_id'].unique()) + ) + self.mapping['users_mapping'] = dict({ + v: k for k, v in self.mapping['users_inv_mapping'].items() + }) + + self.mapping['items_inv_mapping'] = dict( + enumerate(items['item_id'].unique()) + ) + self.mapping['items_mapping'] = dict({ + v: k for k, v in self.mapping['items_inv_mapping'].items() + }) + + def get_matrix( + self, df: pd.DataFrame, + user_col: str = 'user_id', + item_col: str = 'item_id', + weight_col: str = None, + ): + if weight_col: + weights = df[weight_col].astype(np.float32) + else: + weights = np.ones(len(df), dtype=np.float32) + + if hasattr(self.mapping['users_mapping'], 'get') and \ + hasattr(self.mapping['items_mapping'], 'get'): + interaction_matrix = sp.sparse.coo_matrix(( + weights, + ( + df[user_col].map(self.mapping['users_mapping'].get), + df[item_col].map(self.mapping['items_mapping'].get) + ) + )) + else: + raise AttributeError + + self.users_watched = df.groupby(user_col).agg({item_col: list}) + return interaction_matrix + + def prepare_additional_features_users(self, features: pd.DataFrame): + user_features_frames = [] + for feature in ["sex", "age", "income"]: + feature_frame = features.reindex(columns=['user_id', feature]) + feature_frame.columns = ["id", "value"] + feature_frame["feature"] = feature + user_features_frames.append(feature_frame) + user_features = pd.concat(user_features_frames) + + user_final_features = pd.get_dummies( + user_features[['id', 'value']]).groupby('id', as_index=False).sum() + + user_final_features.id = user_final_features.id.map( + self.mapping['items_mapping'] + ) + user_final_features = user_final_features.sort_values('id').drop( + 'id', + axis=1 + ) + user_final_features = csr_matrix(user_final_features.values) + + return user_final_features + + def prepare_additional_features_items(self, features: pd.DataFrame): + features.fillna('Unknown', inplace=True) + features["genre"] = features["genres"].str.lower().str.replace( + ", ", + ",", + regex=False + ).str.split(",") + features["actors"] = features["actors"].str.lower().str.replace( + ", ", + ",", + regex=False + ).str.split(",") + + genre_feature = features[["item_id", "genre"]].explode("genre") + genre_feature.columns = ["id", "value"] + genre_feature["feature"] = "genre" + + actors_feature = features[["item_id", "actors"]].explode("actors") + actors_feature.columns = ["id", "value"] + actors_feature["feature"] = "actors" + + content_feature = features.reindex(columns=['item_id', "content_type"]) + content_feature.columns = ["id", "value"] + content_feature["feature"] = "content_type" + + country_feature = features.reindex(columns=['item_id', "countries"]) + country_feature.columns = ["id", "value"] + country_feature["feature"] = "countries" + + age_feature = features.reindex(columns=['item_id', "age_rating"]) + age_feature.columns = ["id", "value"] + age_feature["feature"] = "age_feature" + + studios_feature = features.reindex(columns=['item_id', "studios"]) + studios_feature.columns = ["id", "value"] + studios_feature["feature"] = "studios" + + genre_feature_bin = ( + pd.get_dummies(genre_feature[['id', 'value']]) + .groupby('id', as_index=False) + .sum() + ) + content_feature_bin = ( + pd.get_dummies(content_feature[['id', 'value']]) + .groupby('id', as_index=False) + .sum() + ) + studios_feature_bin = ( + pd.get_dummies(studios_feature[['id', 'value']]) + .groupby('id', as_index=False) + .sum() + ) + age_feature_bin = ( + pd.get_dummies(age_feature[['id', 'value']]) + .groupby('id', as_index=False) + .sum() + ) + country_feature_bin = ( + pd.get_dummies(country_feature[['id', 'value']]) + .groupby('id', as_index=False) + .sum() + ) + + dfs = [ + genre_feature_bin, + content_feature_bin, + studios_feature_bin, + age_feature_bin, + country_feature_bin + ] + item_final_features = reduce( + lambda left, right: pd.merge(left, right, on='id'), + dfs + ) + + item_final_features.id = item_final_features.id.map( + self.mapping['items_mapping'] + ) + item_final_features = ( + item_final_features + .sort_values('id') + .drop('id', axis=1) + ) + item_final_features_matrix_sparse = csr_matrix( + item_final_features.values) + + return item_final_features_matrix_sparse + + def fit( + self, + train: pd.DataFrame, + user_features: Optional[pd.DataFrame] = None, + # если не none, то делаем фичи + item_features: Optional[pd.DataFrame] = None, + # если не none, то делаем фичи + epochs: int = 1, + num_threads: int = 8, + verbose: int = 1, + + ): + if user_features is not None: + self.user_features = self.prepare_additional_features_users( + user_features) + + if item_features is not None: + self.item_features = self.prepare_additional_features_items( + item_features) + + self.get_mappings(user_features, item_features) + self.weights_matrix = self.get_matrix(train).tocsr() + + self.model.fit( + self.weights_matrix, + epochs=epochs, + user_features=self.user_features, + # csr_matrix of shape [n_users, n_user_features] + item_features=self.item_features, + # csr_matrix of shape [n_items, n_item_features] + num_threads=num_threads, + verbose=verbose > 0, + ) + + self.is_fitted = True + + def predict(self, user_id: int, n_recs: int = 10): + + if not self.is_fitted: + raise ValueError("Fit model before predicting") + + if user_id not in self.mapping['users_mapping'].keys(): + return [] + user_id = self.mapping['users_mapping'][user_id] + + scores = self.model.predict( + user_id, + np.arange(len(self.mapping['items_mapping'])), + item_features=self.item_features, + user_features=self.user_features + ) # LightFM + top_items = np.argsort(-scores)[:n_recs] + reco = [ + self.mapping['items_inv_mapping'][inv_reco_item] + for inv_reco_item in top_items + ] + + return reco From 02eb0bd11ec49ba9b37b2e6ea6a1d7bf38fed060 Mon Sep 17 00:00:00 2001 From: rezarayev Date: Tue, 13 Dec 2022 14:59:05 +0300 Subject: [PATCH 05/12] [first check] --- ...0\275\320\270\320\265 \342\204\2264.ipynb" | 7718 +++++++++++++++++ 1 file changed, 7718 insertions(+) create mode 100644 "notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" diff --git "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" new file mode 100644 index 00000000..6303cdae --- /dev/null +++ "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" @@ -0,0 +1,7718 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "7780d9a2", + "metadata": {}, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e42a5585", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "from implicit.als import AlternatingLeastSquares\n", + "\n", + "from rectools.metrics import Precision, Recall, MAP, calc_metrics\n", + "from rectools.models import PopularModel, RandomModel, ImplicitALSWrapperModel\n", + "from rectools import Columns\n", + "from rectools.dataset import Dataset\n", + "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "\n", + "import matplotlib.pyplot as plt\n", + "from pathlib import Path\n", + "import typing as tp\n", + "from tqdm import tqdm\n", + "\n", + "from lightfm import LightFM\n", + "\n", + "from implicit.bpr import BayesianPersonalizedRanking\n", + "\n", + "from implicit.lmf import LogisticMatrixFactorization\n", + "\n", + "import optuna" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "8cd36e1a", + "metadata": {}, + "outputs": [], + "source": [ + "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4cb722c3", + "metadata": {}, + "outputs": [], + "source": [ + "DATA_PATH = Path(\"../data\")" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "8195e56b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.69 s, sys: 212 ms, total: 2.9 s\n", + "Wall time: 3.2 s\n" + ] + } + ], + "source": [ + "%%time\n", + "users = pd.read_csv(DATA_PATH / 'users.csv')\n", + "items = pd.read_csv(DATA_PATH / 'items.csv')\n", + "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "id": "01c2bdef", + "metadata": {}, + "outputs": [], + "source": [ + "Columns.Datetime = 'last_watch_dt'" + ] + }, + { + "cell_type": "markdown", + "id": "00b5584e", + "metadata": {}, + "source": [ + "# Preprocess Interactions" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "id": "0a3b4b12", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
..................
5476246648596122252021-08-13760.0
547624754686296732021-04-13230849.0
5476248697262152972021-08-201830763.0
5476249384202161972021-04-196203100.0
547625031970944362021-08-15392145.0
\n", + "

5476251 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct\n", + "0 176549 9506 2021-05-11 4250 72.0\n", + "1 699317 1659 2021-05-29 8317 100.0\n", + "2 656683 7107 2021-05-09 10 0.0\n", + "3 864613 7638 2021-07-05 14483 100.0\n", + "4 964868 9506 2021-04-30 6725 100.0\n", + "... ... ... ... ... ...\n", + "5476246 648596 12225 2021-08-13 76 0.0\n", + "5476247 546862 9673 2021-04-13 2308 49.0\n", + "5476248 697262 15297 2021-08-20 18307 63.0\n", + "5476249 384202 16197 2021-04-19 6203 100.0\n", + "5476250 319709 4436 2021-08-15 3921 45.0\n", + "\n", + "[5476251 rows x 5 columns]" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "id": "260b1c48", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id int64\n", + "item_id int64\n", + "last_watch_dt object\n", + "total_dur int64\n", + "watched_pct float64\n", + "dtype: object" + ] + }, + "execution_count": 96, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "id": "fe2dbc06", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id 0\n", + "item_id 0\n", + "last_watch_dt 0\n", + "total_dur 0\n", + "watched_pct 828\n", + "dtype: int64" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "id": "71f61e81", + "metadata": {}, + "outputs": [], + "source": [ + "interactions[Columns.Datetime] = \\\n", + " pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "id": "39646cb5", + "metadata": {}, + "outputs": [], + "source": [ + "interactions.dropna(inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "id": "f98ae95d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "interactions['watched_pct'].hist(bins=20);" + ] + }, + { + "cell_type": "markdown", + "id": "1a0ad9f8", + "metadata": {}, + "source": [ + "Делю график просмотра на 5 категорий, где: \n", + "от 0% до 20% = 1, \n", + "от 21% до 40% = 2, \n", + "... , \n", + "от 80% до 100% = 5" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "id": "1424e744", + "metadata": {}, + "outputs": [], + "source": [ + "interactions[Columns.Weight] = np.where(interactions['watched_pct']\n", + " > 20, 2, 1)\n", + "interactions[Columns.Weight].mask(interactions['watched_pct'] > 40, 3,\n", + " inplace=True)\n", + "interactions[Columns.Weight].mask(interactions['watched_pct'] > 60, 4,\n", + " inplace=True)\n", + "interactions[Columns.Weight].mask(interactions['watched_pct'] > 80, 5,\n", + " inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "id": "052d2fb0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "interactions[Columns.Datetime].hist(bins=20)" + ] + }, + { + "cell_type": "markdown", + "id": "5adb80ee", + "metadata": {}, + "source": [ + "Вообще, видно, что кол-во пользователей растет" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "id": "0fbd2bbc", + "metadata": {}, + "outputs": [], + "source": [ + "cold_users = \\\n", + " interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts()\n", + " == 1].index" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "id": "150e1593", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 104, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'\n", + " ].hist(bins=20)" + ] + }, + { + "cell_type": "markdown", + "id": "b5fa83eb", + "metadata": {}, + "source": [ + "Для холодных пользователей, я бы рекомендовал айтемы с самый высоким просмотром в среднем по холодным пользователям" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "id": "cca06e3f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n", + "

355162 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "10 791466 8199 2021-07-27 713 9.0 1\n", + "26 181144 10440 2021-08-08 27408 40.0 2\n", + "37 161176 10440 2021-07-29 22 0.0 1\n", + "38 21723 1819 2021-04-11 8535 100.0 5\n", + "60 77216 8143 2021-05-08 660 11.0 1\n", + "... ... ... ... ... ... ...\n", + "5476222 1007900 9728 2021-08-12 416 6.0 1\n", + "5476225 882138 4716 2021-05-21 1594 2.0 1\n", + "5476238 805174 13125 2021-06-27 1 0.0 1\n", + "5476246 648596 12225 2021-08-13 76 0.0 1\n", + "5476248 697262 15297 2021-08-20 18307 63.0 4\n", + "\n", + "[355162 rows x 6 columns]" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users = interactions[interactions[Columns.User].isin(cold_users)]\n", + "hot_users = interactions[~interactions[Columns.User].isin(cold_users)]\n", + "cold_users" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "id": "a691676f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n", + "

5475423 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "0 176549 9506 2021-05-11 4250 72.0 4\n", + "1 699317 1659 2021-05-29 8317 100.0 5\n", + "2 656683 7107 2021-05-09 10 0.0 1\n", + "3 864613 7638 2021-07-05 14483 100.0 5\n", + "4 964868 9506 2021-04-30 6725 100.0 5\n", + "... ... ... ... ... ... ...\n", + "5476246 648596 12225 2021-08-13 76 0.0 1\n", + "5476247 546862 9673 2021-04-13 2308 49.0 3\n", + "5476248 697262 15297 2021-08-20 18307 63.0 4\n", + "5476249 384202 16197 2021-04-19 6203 100.0 5\n", + "5476250 319709 4436 2021-08-15 3921 45.0 3\n", + "\n", + "[5475423 rows x 6 columns]" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hot_users" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "id": "a64701c2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n", + "

6440 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " item_id\n", + "10440 45695\n", + "15297 39309\n", + "2657 20474\n", + "9728 15140\n", + "4740 11455\n", + "... ...\n", + "1946 1\n", + "13886 1\n", + "14090 1\n", + "5730 1\n", + "13125 1\n", + "\n", + "[6440 rows x 1 columns]" + ] + }, + "execution_count": 107, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users['item_id'].value_counts().to_frame()" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "id": "cef9cfa6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" + ] + }, + "execution_count": 108, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users[['item_id', 'total_dur']].groupby('item_id').mean().sort_values(by='total_dur', ascending=False).head(10).index" + ] + }, + { + "cell_type": "markdown", + "id": "a52f311b", + "metadata": {}, + "source": [ + "# Делим на train и test" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "id": "bd68d3fe", + "metadata": {}, + "outputs": [], + "source": [ + "max_date = interactions[Columns.Datetime].max()" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "id": "3092fe4b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: (4984443, 6)\n", + "test: (490980, 6)\n" + ] + } + ], + "source": [ + "train = interactions[interactions[Columns.Datetime] < max_date\n", + " - pd.Timedelta(days=7)].copy()\n", + "test = interactions[interactions[Columns.Datetime] >= max_date\n", + " - pd.Timedelta(days=7)].copy()\n", + "\n", + "print(f\"train: {train.shape}\")\n", + "print(f\"test: {test.shape}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "id": "ec286bdc", + "metadata": {}, + "outputs": [], + "source": [ + "train.drop(train.query(\"total_dur < 300\").index, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "id": "52241fed", + "metadata": {}, + "outputs": [], + "source": [ + "drop_user = set(test[Columns.User]) - set(train[Columns.User])\n", + "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" + ] + }, + { + "cell_type": "markdown", + "id": "b5eec6da", + "metadata": {}, + "source": [ + "# User preprocess" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "id": "c57e2b2f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n", + "

840197 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " user_id age income sex kids_flg\n", + "0 973171 age_25_34 income_60_90 М 1\n", + "1 962099 age_18_24 income_20_40 М 0\n", + "2 1047345 age_45_54 income_40_60 Ж 0\n", + "3 721985 age_45_54 income_20_40 Ж 0\n", + "4 704055 age_35_44 income_60_90 Ж 0\n", + "... ... ... ... ... ...\n", + "840192 339025 age_65_inf income_0_20 Ж 0\n", + "840193 983617 age_18_24 income_20_40 Ж 1\n", + "840194 251008 NaN NaN NaN 0\n", + "840195 590706 NaN NaN Ж 0\n", + "840196 166555 age_65_inf income_20_40 Ж 0\n", + "\n", + "[840197 rows x 5 columns]" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "id": "24cc138a", + "metadata": {}, + "outputs": [], + "source": [ + "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "id": "6e5e2d92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
..................
840184529394age_25_34income_40_60Ж0
84018680113age_25_34income_40_60Ж0
840188312839age_65_infincome_60_90Ж0
840189191349age_45_54income_40_60М1
840190393868age_25_34income_20_40М0
\n", + "

586653 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " user_id age income sex kids_flg\n", + "0 973171 age_25_34 income_60_90 М 1\n", + "1 962099 age_18_24 income_20_40 М 0\n", + "3 721985 age_45_54 income_20_40 Ж 0\n", + "4 704055 age_35_44 income_60_90 Ж 0\n", + "5 1037719 age_45_54 income_60_90 М 0\n", + "... ... ... ... .. ...\n", + "840184 529394 age_25_34 income_40_60 Ж 0\n", + "840186 80113 age_25_34 income_40_60 Ж 0\n", + "840188 312839 age_65_inf income_60_90 Ж 0\n", + "840189 191349 age_45_54 income_40_60 М 1\n", + "840190 393868 age_25_34 income_20_40 М 0\n", + "\n", + "[586653 rows x 5 columns]" + ] + }, + "execution_count": 115, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users" + ] + }, + { + "cell_type": "markdown", + "id": "c7f9a6e7", + "metadata": {}, + "source": [ + "Заменяю Nan'ы на Unknown" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "id": "1286eb60", + "metadata": {}, + "outputs": [], + "source": [ + "users.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "id": "1ccccf0f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 973171 М sex\n", + "1 962099 М sex\n", + "3 721985 Ж sex\n", + "4 704055 Ж sex\n", + "5 1037719 М sex" + ] + }, + "execution_count": 117, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_features_frames = []\n", + "for feature in ['sex', 'age', 'income']:\n", + " feature_frame = users.reindex(columns=[Columns.User, feature])\n", + " feature_frame.columns = ['id', 'value']\n", + " feature_frame['feature'] = feature\n", + " user_features_frames.append(feature_frame)\n", + "user_features = pd.concat(user_features_frames)\n", + "user_features.head()" + ] + }, + { + "cell_type": "markdown", + "id": "b9220b0b", + "metadata": {}, + "source": [ + "# Item preprocess" + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "id": "8bbe9ee4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
.............................................
159586443seriesПолярный кругArctic Circle2018.0драмы, триллеры, криминалФинляндия, ГерманияNaN16.0NaNХанну СалоненИина Куустонен, Максимилиан Брюкнер, Пихла Вии...Во время погони за браконьерами по лесу, сотру...убийство, вирус, расследование преступления, н...
159592367seriesНадеждаNaN2020.0драмы, боевикиРоссия0.018.0NaNЕлена ХазановаВиктория Исакова, Александр Кузьмин, Алексей М...Оригинальный киносериал от создателей «Бывших»...Надежда, 2020, Россия
1596010632seriesСговорHassel2017.0драмы, триллеры, криминалРоссия0.018.0NaNЭшреф Рейбрук, Амир Камдин, Эрик ЭгерОла Рапас, Алиетт Офейм, Уильма Лиден, Шанти Р...Криминальная драма по мотивам романов о шведск...Сговор, 2017, Россия
159614538seriesСреди камнейDarklands2019.0драмы, спорт, криминалРоссия0.018.0NaNМарк О’Коннор, Конор МакМахонДэйн Уайт О’Хара, Томас Кэйн-Бирн, Джудит Родд...Семнадцатилетний Дэмиен мечтает вырваться за п...Среди, камней, 2019, Россия
159623206seriesГошаNaN2019.0комедииРоссия0.016.0NaNМихаил МироновМкртыч Арзуманян, Виктория РунцоваДобродушный Гоша не может выйти из дома, чтобы...Гоша, 2019, Россия
\n", + "

15963 rows × 14 columns

\n", + "
" + ], + "text/plain": [ + " item_id content_type title title_orig \\\n", + "0 10711 film Поговори с ней Hable con ella \n", + "1 2508 film Голые перцы Search Party \n", + "2 10716 film Тактическая сила Tactical Force \n", + "3 7868 film 45 лет 45 Years \n", + "4 16268 film Все решает мгновение NaN \n", + "... ... ... ... ... \n", + "15958 6443 series Полярный круг Arctic Circle \n", + "15959 2367 series Надежда NaN \n", + "15960 10632 series Сговор Hassel \n", + "15961 4538 series Среди камней Darklands \n", + "15962 3206 series Гоша NaN \n", + "\n", + " release_year genres \\\n", + "0 2002.0 драмы, зарубежные, детективы, мелодрамы \n", + "1 2014.0 зарубежные, приключения, комедии \n", + "2 2011.0 криминал, зарубежные, триллеры, боевики, комедии \n", + "3 2015.0 драмы, зарубежные, мелодрамы \n", + "4 1978.0 драмы, спорт, советские, мелодрамы \n", + "... ... ... \n", + "15958 2018.0 драмы, триллеры, криминал \n", + "15959 2020.0 драмы, боевики \n", + "15960 2017.0 драмы, триллеры, криминал \n", + "15961 2019.0 драмы, спорт, криминал \n", + "15962 2019.0 комедии \n", + "\n", + " countries for_kids age_rating studios \\\n", + "0 Испания NaN 16.0 NaN \n", + "1 США NaN 16.0 NaN \n", + "2 Канада NaN 16.0 NaN \n", + "3 Великобритания NaN 16.0 NaN \n", + "4 СССР NaN 12.0 Ленфильм \n", + "... ... ... ... ... \n", + "15958 Финляндия, Германия NaN 16.0 NaN \n", + "15959 Россия 0.0 18.0 NaN \n", + "15960 Россия 0.0 18.0 NaN \n", + "15961 Россия 0.0 18.0 NaN \n", + "15962 Россия 0.0 16.0 NaN \n", + "\n", + " directors \\\n", + "0 Педро Альмодовар \n", + "1 Скот Армстронг \n", + "2 Адам П. Калтраро \n", + "3 Эндрю Хэй \n", + "4 Виктор Садовский \n", + "... ... \n", + "15958 Ханну Салонен \n", + "15959 Елена Хазанова \n", + "15960 Эшреф Рейбрук, Амир Камдин, Эрик Эгер \n", + "15961 Марк О’Коннор, Конор МакМахон \n", + "15962 Михаил Миронов \n", + "\n", + " actors \\\n", + "0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n", + "1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n", + "2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n", + "3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n", + "4 Александр Абдулов, Александр Демьяненко, Алекс... \n", + "... ... \n", + "15958 Иина Куустонен, Максимилиан Брюкнер, Пихла Вии... \n", + "15959 Виктория Исакова, Александр Кузьмин, Алексей М... \n", + "15960 Ола Рапас, Алиетт Офейм, Уильма Лиден, Шанти Р... \n", + "15961 Дэйн Уайт О’Хара, Томас Кэйн-Бирн, Джудит Родд... \n", + "15962 Мкртыч Арзуманян, Виктория Рунцова \n", + "\n", + " description \\\n", + "0 Мелодрама легендарного Педро Альмодовара «Пого... \n", + "1 Уморительная современная комедия на популярную... \n", + "2 Профессиональный рестлер Стив Остин («Все или ... \n", + "3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n", + "4 Расчетливая чаровница из советского кинохита «... \n", + "... ... \n", + "15958 Во время погони за браконьерами по лесу, сотру... \n", + "15959 Оригинальный киносериал от создателей «Бывших»... \n", + "15960 Криминальная драма по мотивам романов о шведск... \n", + "15961 Семнадцатилетний Дэмиен мечтает вырваться за п... \n", + "15962 Добродушный Гоша не может выйти из дома, чтобы... \n", + "\n", + " keywords \n", + "0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n", + "1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n", + "2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n", + "3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n", + "4 Все, решает, мгновение, 1978, СССР, сильные, ж... \n", + "... ... \n", + "15958 убийство, вирус, расследование преступления, н... \n", + "15959 Надежда, 2020, Россия \n", + "15960 Сговор, 2017, Россия \n", + "15961 Среди, камней, 2019, Россия \n", + "15962 Гоша, 2019, Россия \n", + "\n", + "[15963 rows x 14 columns]" + ] + }, + "execution_count": 118, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "id": "72fa86a0", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "item_id 0\n", + "content_type 0\n", + "title 0\n", + "title_orig 4745\n", + "release_year 98\n", + "genres 0\n", + "countries 37\n", + "for_kids 15397\n", + "age_rating 2\n", + "studios 14898\n", + "directors 1509\n", + "actors 2619\n", + "description 2\n", + "keywords 423\n", + "dtype: int64" + ] + }, + "execution_count": 119, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "id": "50f0611f", + "metadata": {}, + "outputs": [], + "source": [ + "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "id": "280cf47d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "item_id 0\n", + "content_type 0\n", + "title 0\n", + "title_orig 3775\n", + "release_year 31\n", + "genres 0\n", + "countries 14\n", + "for_kids 13415\n", + "age_rating 1\n", + "studios 13047\n", + "directors 939\n", + "actors 1858\n", + "description 0\n", + "keywords 388\n", + "dtype: int64" + ] + }, + "execution_count": 121, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "markdown", + "id": "eddd93b5", + "metadata": {}, + "source": [ + "# Genre" + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "id": "bf6da75c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre" + ] + }, + "execution_count": 122, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Explode genres to flatten table\n", + "items['genre'] = items['genres'].str.lower().str.replace(', ', ',',\n", + " regex=False).str.split(',')\n", + "genre_feature = items[['item_id', 'genre']].explode('genre')\n", + "genre_feature.columns = ['id', 'value']\n", + "genre_feature['feature'] = 'genre'\n", + "genre_feature.head()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "id": "913b9c27", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n", + "

36128 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre\n", + "... ... ... ...\n", + "15960 10632 криминал genre\n", + "15961 4538 драмы genre\n", + "15961 4538 спорт genre\n", + "15961 4538 криминал genre\n", + "15962 3206 комедии genre\n", + "\n", + "[36128 rows x 3 columns]" + ] + }, + "execution_count": 123, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "genre_feature" + ] + }, + { + "cell_type": "markdown", + "id": "478bf1e3", + "metadata": {}, + "source": [ + "# Content" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "id": "65f8b5d9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
............
159586443seriescontent_type
159592367seriescontent_type
1596010632seriescontent_type
159614538seriescontent_type
159623206seriescontent_type
\n", + "

13963 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 film content_type\n", + "1 2508 film content_type\n", + "2 10716 film content_type\n", + "3 7868 film content_type\n", + "4 16268 film content_type\n", + "... ... ... ...\n", + "15958 6443 series content_type\n", + "15959 2367 series content_type\n", + "15960 10632 series content_type\n", + "15961 4538 series content_type\n", + "15962 3206 series content_type\n", + "\n", + "[13963 rows x 3 columns]" + ] + }, + "execution_count": 124, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", + "content_feature.columns = [\"id\", \"value\"]\n", + "content_feature[\"feature\"] = \"content_type\"\n", + "content_feature" + ] + }, + { + "cell_type": "markdown", + "id": "a62ebee4", + "metadata": {}, + "source": [ + "# Actors" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "id": "fdc43660", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
............
159614538джудит роддиactors
159614538марк о’халлоранactors
159614538джимми смоллхорнactors
159623206мкртыч арзуманянactors
159623206виктория рунцоваactors
\n", + "

128926 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 адольфо фернандес actors\n", + "0 10711 ана фернандес actors\n", + "0 10711 дарио грандинетти actors\n", + "0 10711 джеральдин чаплин actors\n", + "0 10711 елена анайя actors\n", + "... ... ... ...\n", + "15961 4538 джудит родди actors\n", + "15961 4538 марк о’халлоран actors\n", + "15961 4538 джимми смоллхорн actors\n", + "15962 3206 мкртыч арзуманян actors\n", + "15962 3206 виктория рунцова actors\n", + "\n", + "[128926 rows x 3 columns]" + ] + }, + "execution_count": 125, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items['actors'] = items['actors'].str.lower().str.replace(', ', ',',\n", + " regex=False).str.split(',')\n", + "actors_feature = items[['item_id', 'actors']].explode('actors')\n", + "actors_feature.columns = ['id', 'value']\n", + "actors_feature['feature'] = 'actors'\n", + "actors_feature" + ] + }, + { + "cell_type": "markdown", + "id": "73801647", + "metadata": {}, + "source": [ + "# Keywords" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "id": "594abe5c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
............
1596145382019keywords
159614538россияkeywords
159623206гошаkeywords
1596232062019keywords
159623206россияkeywords
\n", + "

341629 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 поговори keywords\n", + "0 10711 ней keywords\n", + "0 10711 2002 keywords\n", + "0 10711 испания keywords\n", + "0 10711 друзья keywords\n", + "... ... ... ...\n", + "15961 4538 2019 keywords\n", + "15961 4538 россия keywords\n", + "15962 3206 гоша keywords\n", + "15962 3206 2019 keywords\n", + "15962 3206 россия keywords\n", + "\n", + "[341629 rows x 3 columns]" + ] + }, + "execution_count": 126, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items['keywords'] = items['keywords'].str.lower().str.replace(', ', ','\n", + " , regex=False).str.split(',')\n", + "keywords_feature = items[['item_id', 'keywords']].explode('keywords')\n", + "keywords_feature.columns = ['id', 'value']\n", + "keywords_feature['feature'] = 'keywords'\n", + "keywords_feature" + ] + }, + { + "cell_type": "markdown", + "id": "d3eb0a37", + "metadata": {}, + "source": [ + "# Countries\t" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "8eb8a621", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
............
159586443Финляндия, Германияcountries
159592367Россияcountries
1596010632Россияcountries
159614538Россияcountries
159623206Россияcountries
\n", + "

13963 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 Испания countries\n", + "1 2508 США countries\n", + "2 10716 Канада countries\n", + "3 7868 Великобритания countries\n", + "4 16268 СССР countries\n", + "... ... ... ...\n", + "15958 6443 Финляндия, Германия countries\n", + "15959 2367 Россия countries\n", + "15960 10632 Россия countries\n", + "15961 4538 Россия countries\n", + "15962 3206 Россия countries\n", + "\n", + "[13963 rows x 3 columns]" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "country_feature = items.reindex(columns=[Columns.Item, 'countries'])\n", + "country_feature.columns = ['id', 'value']\n", + "country_feature['feature'] = 'countries'\n", + "country_feature" + ] + }, + { + "cell_type": "markdown", + "id": "5e477ee1", + "metadata": {}, + "source": [ + "# Age Rating" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "0894154a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
............
15958644316.0age_feature
15959236718.0age_feature
159601063218.0age_feature
15961453818.0age_feature
15962320616.0age_feature
\n", + "

13963 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 16.0 age_feature\n", + "1 2508 16.0 age_feature\n", + "2 10716 16.0 age_feature\n", + "3 7868 16.0 age_feature\n", + "4 16268 12.0 age_feature\n", + "... ... ... ...\n", + "15958 6443 16.0 age_feature\n", + "15959 2367 18.0 age_feature\n", + "15960 10632 18.0 age_feature\n", + "15961 4538 18.0 age_feature\n", + "15962 3206 16.0 age_feature\n", + "\n", + "[13963 rows x 3 columns]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", + "age_feature.columns = [\"id\", \"value\"]\n", + "age_feature[\"feature\"] = \"age_feature\"\n", + "age_feature" + ] + }, + { + "cell_type": "markdown", + "id": "c09df1ec", + "metadata": {}, + "source": [ + "# Studios" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "ff937b4f", + "metadata": {}, + "outputs": [], + "source": [ + "items.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "cee42708", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711Unknownstudios
12508Unknownstudios
210716Unknownstudios
37868Unknownstudios
416268Ленфильмstudios
............
159586443Unknownstudios
159592367Unknownstudios
1596010632Unknownstudios
159614538Unknownstudios
159623206Unknownstudios
\n", + "

13963 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 Unknown studios\n", + "1 2508 Unknown studios\n", + "2 10716 Unknown studios\n", + "3 7868 Unknown studios\n", + "4 16268 Ленфильм studios\n", + "... ... ... ...\n", + "15958 6443 Unknown studios\n", + "15959 2367 Unknown studios\n", + "15960 10632 Unknown studios\n", + "15961 4538 Unknown studios\n", + "15962 3206 Unknown studios\n", + "\n", + "[13963 rows x 3 columns]" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", + "studios_feature.columns = [\"id\", \"value\"]\n", + "studios_feature[\"feature\"] = \"studios\"\n", + "studios_feature" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "id": "7234f13b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
159586443seriescontent_type
159592367seriescontent_type
1596010632seriescontent_type
159614538seriescontent_type
159623206seriescontent_type
\n", + "

50091 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre\n", + "... ... ... ...\n", + "15958 6443 series content_type\n", + "15959 2367 series content_type\n", + "15960 10632 series content_type\n", + "15961 4538 series content_type\n", + "15962 3206 series content_type\n", + "\n", + "[50091 rows x 3 columns]" + ] + }, + "execution_count": 128, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# studios_feature, age_feature, country_feature - фичи которые хотелось бы использовать,\n", + "# но длительность обучения \"OPTUNA\" увеличивается в разы\n", + "item_features = pd.concat((genre_feature, content_feature ))\n", + "item_features" + ] + }, + { + "cell_type": "markdown", + "id": "09b8d756", + "metadata": {}, + "source": [ + "# Metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "id": "b082e667", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Precision@1': Precision(k=1),\n", + " 'Precision@2': Precision(k=2),\n", + " 'Precision@3': Precision(k=3),\n", + " 'Precision@4': Precision(k=4),\n", + " 'Precision@5': Precision(k=5),\n", + " 'Precision@6': Precision(k=6),\n", + " 'Precision@7': Precision(k=7),\n", + " 'Precision@8': Precision(k=8),\n", + " 'Precision@9': Precision(k=9),\n", + " 'Precision@10': Precision(k=10),\n", + " 'Recall@1': Recall(k=1),\n", + " 'Recall@2': Recall(k=2),\n", + " 'Recall@3': Recall(k=3),\n", + " 'Recall@4': Recall(k=4),\n", + " 'Recall@5': Recall(k=5),\n", + " 'Recall@6': Recall(k=6),\n", + " 'Recall@7': Recall(k=7),\n", + " 'Recall@8': Recall(k=8),\n", + " 'Recall@9': Recall(k=9),\n", + " 'Recall@10': Recall(k=10),\n", + " 'MAP@1': MAP(k=1, divide_by_k=False),\n", + " 'MAP@2': MAP(k=2, divide_by_k=False),\n", + " 'MAP@3': MAP(k=3, divide_by_k=False),\n", + " 'MAP@4': MAP(k=4, divide_by_k=False),\n", + " 'MAP@5': MAP(k=5, divide_by_k=False),\n", + " 'MAP@6': MAP(k=6, divide_by_k=False),\n", + " 'MAP@7': MAP(k=7, divide_by_k=False),\n", + " 'MAP@8': MAP(k=8, divide_by_k=False),\n", + " 'MAP@9': MAP(k=9, divide_by_k=False),\n", + " 'MAP@10': MAP(k=10, divide_by_k=False)}" + ] + }, + "execution_count": 129, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metrics_name = {\n", + " 'Precision': Precision,\n", + " 'Recall': Recall,\n", + " 'MAP': MAP,\n", + "}\n", + "\n", + "metrics = {}\n", + "for metric_name, metric in metrics_name.items():\n", + " for k in range(1, 11):\n", + " metrics[f'{metric_name}@{k}'] = metric(k=k)\n", + "metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "id": "d027f149", + "metadata": {}, + "outputs": [], + "source": [ + "TEST_USERS = test[Columns.User].unique()" + ] + }, + { + "cell_type": "markdown", + "id": "2c603783", + "metadata": {}, + "source": [ + "# Optuna" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "id": "fb193c2f", + "metadata": {}, + "outputs": [], + "source": [ + "NUM_THREADS = 8\n", + "RANDOM_STATE = 42\n", + "K = 5\n", + "NO_COMPONENTS = 32\n", + "N_EPOCHS = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "id": "3328645d", + "metadata": {}, + "outputs": [], + "source": [ + "USER_ALPHA = 0 \n", + "ITEM_ALPHA = 0 \n", + "K_RECOS = 10" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "a17b8b66", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:32:01,241]\u001b[0m A new study created in memory with name: no-name-d2c12238-d18d-4c6f-bca4-840e7d3f29b0\u001b[0m\n", + "\u001b[32m[I 2022-12-12 18:41:40,178]\u001b[0m Trial 0 finished with value: 0.07156314077881751 and parameters: {'recomender': 'ALS', 'regularization': 0.0035671951579306937}. Best is trial 0 with value: 0.07156314077881751.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07156314077881751\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:51:48,671]\u001b[0m Trial 1 finished with value: 0.07241639094290958 and parameters: {'recomender': 'ALS', 'regularization': 0.006724126527816994}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07241639094290958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:53:18,697]\u001b[0m Trial 2 finished with value: 1.4050149479540313e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8190152272980945, 'k': 6, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 1.4050149479540313e-07\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:54:36,340]\u001b[0m Trial 3 finished with value: 0.005366068762176463 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.18723291153626603, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.005366068762176463\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:56:21,781]\u001b[0m Trial 4 finished with value: 0.0002205827579874263 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.6560234930178588, 'k': 6, 'loss': 'logistic'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.0002205827579874263\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:05:46,138]\u001b[0m Trial 5 finished with value: 0.07173988822226253 and parameters: {'recomender': 'ALS', 'regularization': 0.009044651486228098}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07173988822226253\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:07:05,748]\u001b[0m Trial 6 finished with value: 3.943062688880311e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.44751878244334975, 'k': 7, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 3.943062688880311e-06\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:08:22,099]\u001b[0m Trial 7 finished with value: 0.06793721324055035 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.10438302844592218, 'k': 3, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.06793721324055035\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:17:32,898]\u001b[0m Trial 8 finished with value: 0.07184311920591484 and parameters: {'recomender': 'ALS', 'regularization': 0.0005806772800434514}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07184311920591484\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:18:59,268]\u001b[0m Trial 9 finished with value: 2.2409988419866796e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.805131840226543, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 2.2409988419866796e-06\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:28:09,202]\u001b[0m Trial 10 finished with value: 0.07180954187357708 and parameters: {'recomender': 'ALS', 'regularization': 0.008190821633209066}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07180954187357708\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:37:15,147]\u001b[0m Trial 11 finished with value: 0.07244222251339615 and parameters: {'recomender': 'ALS', 'regularization': 0.00026970098377155163}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07244222251339615\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:46:24,260]\u001b[0m Trial 12 finished with value: 0.07202031081710311 and parameters: {'recomender': 'ALS', 'regularization': 0.0066363513358619185}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07202031081710311\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:55:34,176]\u001b[0m Trial 13 finished with value: 0.07199398893026046 and parameters: {'recomender': 'ALS', 'regularization': 0.004156107607150058}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07199398893026046\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:04:42,589]\u001b[0m Trial 14 finished with value: 0.07167963259586223 and parameters: {'recomender': 'ALS', 'regularization': 0.0006228566403390988}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167963259586223\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:13:49,348]\u001b[0m Trial 15 finished with value: 0.07202106855494453 and parameters: {'recomender': 'ALS', 'regularization': 0.00598705937836684}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07202106855494453\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:22:57,770]\u001b[0m Trial 16 finished with value: 0.07193963920172777 and parameters: {'recomender': 'ALS', 'regularization': 0.0028834604694796696}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07193963920172777\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:32:04,614]\u001b[0m Trial 17 finished with value: 0.07186249836889418 and parameters: {'recomender': 'ALS', 'regularization': 0.007249626991281137}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07186249836889418\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:41:24,258]\u001b[0m Trial 18 finished with value: 0.07164870366757094 and parameters: {'recomender': 'ALS', 'regularization': 0.005115162467576984}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07164870366757094\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:50:49,059]\u001b[0m Trial 19 finished with value: 0.07179004415938793 and parameters: {'recomender': 'ALS', 'regularization': 0.0018963762834092678}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07179004415938793\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 21:42:16,853]\u001b[0m Trial 20 finished with value: 0.07167129296212232 and parameters: {'recomender': 'ALS', 'regularization': 0.009804091535656343}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167129296212232\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 21:52:20,413]\u001b[0m Trial 21 finished with value: 0.07191839766465505 and parameters: {'recomender': 'ALS', 'regularization': 0.005764203522687446}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07191839766465505\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:02:12,773]\u001b[0m Trial 22 finished with value: 0.07159025974450188 and parameters: {'recomender': 'ALS', 'regularization': 0.006209360331833826}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07159025974450188\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:12:55,936]\u001b[0m Trial 23 finished with value: 0.07167021208897958 and parameters: {'recomender': 'ALS', 'regularization': 0.007825089420401029}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167021208897958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:23:04,762]\u001b[0m Trial 24 finished with value: 0.07191850988173716 and parameters: {'recomender': 'ALS', 'regularization': 0.004979324924695012}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07191850988173716\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:34:38,654]\u001b[0m Trial 25 finished with value: 0.07178449755342503 and parameters: {'recomender': 'ALS', 'regularization': 0.002381286135370409}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07178449755342503\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:45:43,850]\u001b[0m Trial 26 finished with value: 0.07177449403191542 and parameters: {'recomender': 'ALS', 'regularization': 0.004677821831829}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07177449403191542\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:56:45,636]\u001b[0m Trial 27 finished with value: 0.07214439856613958 and parameters: {'recomender': 'ALS', 'regularization': 0.0069504676367203744}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07214439856613958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 23:08:13,361]\u001b[0m Trial 28 finished with value: 0.07237690498752612 and parameters: {'recomender': 'ALS', 'regularization': 0.0074561399301387955}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07237690498752612\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 23:18:05,878]\u001b[0m Trial 29 finished with value: 0.07173589378156864 and parameters: {'recomender': 'ALS', 'regularization': 0.00848249465326267}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07173589378156864\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[33m[W 2022-12-12 23:27:26,180]\u001b[0m Trial 30 failed because of the following error: KeyboardInterrupt()\u001b[0m\n", + "Traceback (most recent call last):\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", + " value_or_values = func(trial)\n", + " File \"/tmp/ipykernel_5286/352742220.py\", line 40, in objective\n", + " recos = model.recommend(\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\", line 132, in recommend\n", + " reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 141, in _recommend_u2i\n", + " scores = scores_calculator.calc(target_id)\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 98, in calc\n", + " scores = self.objects_factors @ subject_factors\n", + "KeyboardInterrupt\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_5286/352742220.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[0mstudy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptuna\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_study\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdirection\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'maximize'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 50\u001b[0;31m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobjective\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_trials\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 417\u001b[0m \"\"\"\n\u001b[1;32m 418\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 419\u001b[0;31m _optimize(\n\u001b[0m\u001b[1;32m 420\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 421\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize\u001b[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 65\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn_jobs\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 66\u001b[0;31m _optimize_sequential(\n\u001b[0m\u001b[1;32m 67\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize_sequential\u001b[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 160\u001b[0;31m \u001b[0mfrozen_trial\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_run_trial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 161\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[0;31m# The following line mitigates memory problems that can be occurred in some\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 232\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc_err\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 233\u001b[0m ):\n\u001b[0;32m--> 234\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mfunc_err\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 235\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfrozen_trial\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 236\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 194\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mget_heartbeat_thread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_trial_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_storage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 195\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 196\u001b[0;31m \u001b[0mvalue_or_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 197\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTrialPruned\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[0;31m# TODO(mamu): Handle multi-objective cases.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_5286/352742220.py\u001b[0m in \u001b[0;36mobjective\u001b[0;34m(trial)\u001b[0m\n\u001b[1;32m 38\u001b[0m fit_features_together=True)\n\u001b[1;32m 39\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m recos = model.recommend(\n\u001b[0m\u001b[1;32m 41\u001b[0m \u001b[0musers\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTEST_USERS\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0mdataset\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001b[0m in \u001b[0;36mrecommend\u001b[0;34m(self, users, dataset, k, filter_viewed, items_to_recommend, add_rank_col)\u001b[0m\n\u001b[1;32m 130\u001b[0m \u001b[0msorted_item_ids_to_recommend\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 131\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 132\u001b[0;31m reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n\u001b[0m\u001b[1;32m 133\u001b[0m \u001b[0muser_ids\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 134\u001b[0m \u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001b[0m in \u001b[0;36m_recommend_u2i\u001b[0;34m(self, user_ids, dataset, k, filter_viewed, sorted_item_ids_to_recommend)\u001b[0m\n\u001b[1;32m 139\u001b[0m \u001b[0mall_scores\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mtp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mList\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mtarget_id\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0muser_ids\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mverbose\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 141\u001b[0;31m \u001b[0mscores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mscores_calculator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcalc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtarget_id\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 142\u001b[0m reco_ids, reco_scores = recommend_from_scores(\n\u001b[1;32m 143\u001b[0m \u001b[0mscores\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mscores\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001b[0m in \u001b[0;36mcalc\u001b[0;34m(self, subject_id)\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0msubject_factors\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubjects_factors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msubject_id\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdistance\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mDistance\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDOT\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 98\u001b[0;31m \u001b[0mscores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobjects_factors\u001b[0m \u001b[0;34m@\u001b[0m \u001b[0msubject_factors\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 99\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdistance\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mDistance\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mEUCLIDEAN\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0msubject_dot\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubjects_dots\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msubject_id\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "dataset = Dataset.construct(interactions_df=train,\n", + " user_features_df=user_features,\n", + " cat_user_features=['sex', 'age', 'income'],\n", + " item_features_df=item_features,\n", + " cat_item_features=['content_type', 'genre'])\n", + "TEST_USERS = test[Columns.User].unique()\n", + "\n", + "\n", + "def objective(trial):\n", + " model_name = trial.suggest_categorical('recomender', ['LightFM',\n", + " 'ALS'])\n", + " if model_name == 'LightFM':\n", + " learning_rate = trial.suggest_float('learning_rate', 1e-10, 1)\n", + " k = trial.suggest_int('k', 2, 10)\n", + " loss = trial.suggest_categorical('loss', ['logistic', 'bpr',\n", + " 'warp'])\n", + " model = LightFMWrapperModel(LightFM(k=k,\n", + " learning_rate=learning_rate,\n", + " loss=loss, no_components=10),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS)\n", + " else:\n", + " regularization = trial.suggest_float('regularization', 1e-4,\n", + " 1e-2)\n", + " model = \\\n", + " ImplicitALSWrapperModel(model=AlternatingLeastSquares(factors=10,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=regularization),\n", + " fit_features_together=True)\n", + " model.fit(dataset)\n", + " recos = model.recommend(users=TEST_USERS, dataset=dataset,\n", + " k=K_RECOS, filter_viewed=True)\n", + " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", + " print ('MAP@10', metric)\n", + " return metric\n", + "\n", + "\n", + "study = optuna.create_study(direction='maximize')\n", + "study.optimize(objective, n_trials=100)" + ] + }, + { + "cell_type": "markdown", + "id": "b16ab957", + "metadata": {}, + "source": [ + "## Пришлось остановить обучение, тк эти 30 эпох обучались 6 часов" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "99aae61e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'recomender': 'ALS', 'regularization': 0.00026970098377155163}" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "study.best_params" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "id": "326e1a8b", + "metadata": {}, + "outputs": [], + "source": [ + "# обучаем best model после optuna\n", + "model = \\\n", + " ImplicitALSWrapperModel(model=AlternatingLeastSquares(factors=32,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=study.best_params['regularization'\n", + " ]), fit_features_together=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d3907c1d", + "metadata": {}, + "outputs": [], + "source": [ + "model.fit(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "b2050a6e", + "metadata": {}, + "outputs": [], + "source": [ + "recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "6bbe3ff3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.07124010116092815" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "calc_metrics(metrics, recos, test, train)['MAP@10']" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "d3eead34", + "metadata": {}, + "outputs": [], + "source": [ + "recos = recos[['user_id', 'item_id']]\n", + "recos.to_csv('ALS_after_optuna.csv.gz', index=False, compression='gzip')" + ] + }, + { + "cell_type": "markdown", + "id": "ab12c89f", + "metadata": {}, + "source": [ + " ## Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. " + ] + }, + { + "cell_type": "code", + "execution_count": 216, + "id": "bcdc650a", + "metadata": {}, + "outputs": [], + "source": [ + "#pip install --no-binary :all: nmslib" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "f6fc49dc", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Your CPU supports instructions that this binary was not compiled to use: SSE3 SSE4.1 SSE4.2 AVX AVX2\n", + "For maximum performance, you can install NMSLIB from sources \n", + "pip install --no-binary :all: nmslib\n" + ] + } + ], + "source": [ + "import nmslib\n", + "import time" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "aea61562", + "metadata": {}, + "outputs": [], + "source": [ + "LEARNING_RATE = 0.08165160206425184\n", + "LOSS = 'warp'" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "8e86a071", + "metadata": {}, + "outputs": [], + "source": [ + "# обучаем LightFM, чтобы достать из нее вектора пользователей и айтемов\n", + "model = LightFMWrapperModel(\n", + " LightFM(\n", + " k=K,\n", + " no_components=NO_COMPONENTS, \n", + " loss= LOSS, \n", + " random_state=RANDOM_STATE,\n", + " learning_rate=LEARNING_RATE,\n", + " user_alpha=USER_ALPHA,\n", + " item_alpha=ITEM_ALPHA),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS) " + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "324039bb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.fit(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "1150ce8e", + "metadata": {}, + "outputs": [], + "source": [ + "user_embeddings, item_embeddings = model.get_vectors(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "fd296cf4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((756545, 34), (13963, 34))" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings.shape, item_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "d75b4570", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-2.48910075e+02, 1.00000000e+00, -3.04745167e-01, 1.30259299e-01,\n", + " -1.25937782e-01, 1.32810516e-01, -3.98682870e-01, 2.12211904e-01,\n", + " 3.15063161e-01, 9.48599975e-03, 1.79876286e-01, -1.15210674e-01,\n", + " 3.13044085e-01, 5.25500635e-02, -8.94866249e-02, 6.32450803e-02,\n", + " 3.30464664e-01, -2.79290127e-01, 7.66675368e-02, 2.69704125e-01,\n", + " -2.02872234e-01, 3.65543869e-02, -2.08750917e-01, -7.48397237e-02,\n", + " 2.09714412e-01, 1.28161004e-01, -2.49842146e-01, 7.57336145e-02,\n", + " 6.74582969e-02, 2.03054725e-01, -4.46441335e-02, 1.00222239e-01,\n", + " 3.09746759e-01, 2.26963989e-01])" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#пользователь со средним значением по каждому признаку\n", + "first_person = user_embeddings.mean(0)\n", + "first_person" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "88198015", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-364.41271973, 1. , -2.19337273, -2.05960441,\n", + " -3.03305483, -2.15237951, -3.10027146, -1.44008625,\n", + " -1.55592728, -1.69499218, -1.87335801, -3.19125104,\n", + " -1.8664068 , -2.62357092, -2.23808742, -1.78050435,\n", + " -1.67308342, -2.70261121, -1.94637215, -2.44766903,\n", + " -2.40233946, -1.93648934, -2.32535124, -2.73280096,\n", + " -2.20278382, -1.93085539, -2.29366779, -1.9847883 ,\n", + " -2.619452 , -1.8447926 , -2.03915739, -1.86472845,\n", + " -1.80441463, -1.98137343])" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#пользователь со минимальным значением по каждому признаку\n", + "second_person = user_embeddings.min(axis=0)\n", + "second_person" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "4e02dec3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0. , 1. , 1.80414879, 2.91568851, 2.57092023,\n", + " 2.49563074, 3.0165813 , 2.02071786, 2.10402703, 1.86775827,\n", + " 1.81193578, 2.3456769 , 2.37611055, 4.0926795 , 1.8776809 ,\n", + " 1.91333187, 2.16625547, 1.76979506, 1.87265527, 2.63360167,\n", + " 1.97114313, 1.88249838, 1.89424872, 2.15507913, 2.38049865,\n", + " 1.99921763, 1.80478072, 1.8311218 , 3.32906055, 2.25318193,\n", + " 2.0245254 , 2.37490654, 2.28989363, 1.97282732])" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#пользователь со максимальным значением по каждому признаку\n", + "third_person = user_embeddings.max(axis=0)\n", + "third_person" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "75a314ac", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(756545, 34)" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "3cb72431", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(756548, 34)" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# добавим векотра 3х новых пользователей\n", + "user_embeddings = np.append(user_embeddings, np.array([first_person,\n", + " second_person, third_person]), axis=0)\n", + "user_embeddings.shape\n" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "db53d401", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150, 'post': 0, 'chunkIndexSize': 10000}\n" + ] + } + ], + "source": [ + "M = 50\n", + "efC = 150\n", + "\n", + "num_threads = 8\n", + "chunkIndexSize = 10000\n", + "\n", + "index_time_params = {\n", + " 'M': M,\n", + " 'indexThreadQty': num_threads,\n", + " 'efConstruction': efC,\n", + " 'post': 0,\n", + " 'chunkIndexSize': chunkIndexSize,\n", + " }\n", + "print ('Index-time parameters', index_time_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "e09782e5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13963" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "K = 10\n", + "space_name = 'negdotprod'\n", + "index = nmslib.init(method='hnsw', space=space_name,\n", + " data_type=nmslib.DataType.DENSE_VECTOR)\n", + "index.addDataPointBatch(item_embeddings)" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "209d778e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150}\n", + "Indexing time = 1.392440\n" + ] + } + ], + "source": [ + "start = time.time()\n", + "index_time_params = {'M': M, 'indexThreadQty': num_threads,\n", + " 'efConstruction': efC}\n", + "index.createIndex(index_time_params)\n", + "end = time.time()\n", + "print ('Index-time parameters', index_time_params)\n", + "print 'Indexing time = %f' % (end - start)" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "998dad8b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setting query-time parameters {'efSearch': 100}\n" + ] + } + ], + "source": [ + "efS = 100\n", + "query_time_params = {'efSearch': efS}\n", + "print('Setting query-time parameters', query_time_params)\n", + "index.setQueryTimeParams(query_time_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "6f5cd03c", + "metadata": {}, + "outputs": [], + "source": [ + "query_matrix = user_embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "77039943", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "kNN time total=3.962551 (sec), per query=0.000005 (sec), per query adjusted for thread number=0.000042 (sec)\n" + ] + } + ], + "source": [ + "query_qty = query_matrix.shape[0]\n", + "start = time.time()\n", + "nbrs = index.knnQueryBatch(query_matrix, k=K, num_threads=num_threads)\n", + "end = time.time()\n", + "print 'kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' \\\n", + " % (end - start, float(end - start) / query_qty, num_threads\n", + " * float(end - start) / query_qty)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "id": "3e24230f", + "metadata": { + "collapsed": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(array([ 32, 19, 43, 62, 449, 279, 305, 31, 36, 69], dtype=int32),\n", + " array([313.13745, 313.2156 , 313.23563, 313.69226, 313.96838, 314.01437,\n", + " 314.05713, 314.0591 , 314.07086, 314.1464 ], dtype=float32)),\n", + " (array([ 31, 262, 62, 149, 8, 450, 19, 32, 121, 735], dtype=int32),\n", + " array([312.03275, 312.2426 , 312.44092, 312.47754, 312.50558, 312.55057,\n", + " 312.5966 , 312.61896, 312.65695, 312.85553], dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 173, 268, 43, 29, 62, 105], dtype=int32),\n", + " array([292.56287, 292.7267 , 293.37714, 293.398 , 293.52377, 293.58594,\n", + " 293.59534, 293.6454 , 293.80536, 293.9107 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 43, 32, 173, 268, 103, 105], dtype=int32),\n", + " array([345.13394, 345.63568, 345.96344, 346.01605, 346.06268, 346.1905 ,\n", + " 346.40475, 346.4218 , 346.5124 , 346.5745 ], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 36, 449, 279, 121, 206], dtype=int32),\n", + " array([-17.293152, -17.268269, -17.04797 , -16.923717, -16.860167,\n", + " -16.833693, -16.554005, -16.493723, -16.479094, -16.403612],\n", + " dtype=float32)),\n", + " (array([ 43, 884, 19, 358, 31, 62, 805, 1120, 458, 176],\n", + " dtype=int32),\n", + " array([308.01877, 308.03784, 308.04642, 308.27057, 308.37463, 308.40018,\n", + " 308.41226, 308.4986 , 308.5467 , 308.54898], dtype=float32)),\n", + " (array([ 19, 62, 173, 43, 86, 31, 32, 121, 100, 279], dtype=int32),\n", + " array([288.27673, 288.5546 , 288.56357, 288.70715, 288.70715, 288.72052,\n", + " 288.77975, 288.93396, 289.05566, 289.07333], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 121, 268, 49, 100, 305], dtype=int32),\n", + " array([320.5494 , 320.60464, 320.6968 , 320.70566, 321.05185, 321.22174,\n", + " 321.37576, 321.45926, 321.46765, 321.53632], dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", + " array([311.83444, 311.98633, 312.07584, 312.1188 , 312.1717 , 312.35593,\n", + " 312.52664, 312.74872, 312.81677, 312.8287 ], dtype=float32)),\n", + " (array([ 262, 1, 718, 369, 8, 153, 149, 1482, 835, 1118],\n", + " dtype=int32),\n", + " array([317.74112, 317.9094 , 317.93765, 317.9422 , 318.0492 , 318.05173,\n", + " 318.19272, 318.27676, 318.28412, 318.2907 ], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 100, 268, 29, 121, 255], dtype=int32),\n", + " array([-20.910645, -20.845661, -20.804134, -20.656986, -20.396063,\n", + " -20.082872, -20.038603, -20.029623, -20.027676, -20.001362],\n", + " dtype=float32)),\n", + " (array([ 32, 43, 62, 31, 19, 121, 49, 100, 29, 305], dtype=int32),\n", + " array([306.48294, 306.60352, 306.69205, 306.74927, 306.93555, 306.99304,\n", + " 307.14734, 307.16812, 307.42227, 307.44482], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 173, 358, 268, 100], dtype=int32),\n", + " array([242.05086, 242.39929, 242.54828, 242.56117, 242.58932, 242.84547,\n", + " 243.04828, 243.12746, 243.22084, 243.24095], dtype=float32)),\n", + " (array([2855, 3209, 3546, 1584, 19, 2430, 2181, 3351, 1171, 2953],\n", + " dtype=int32),\n", + " array([-9.165584 , -8.613427 , -7.7613564, -7.308004 , -7.0333157,\n", + " -6.942323 , -6.783264 , -6.7762623, -6.652196 , -6.534201 ],\n", + " dtype=float32)),\n", + " (array([ 13, 32, 43, 279, 36, 350, 19, 62, 31, 69], dtype=int32),\n", + " array([343.35373, 343.62512, 343.6554 , 343.8275 , 343.93793, 344.03436,\n", + " 344.0428 , 344.10455, 344.14474, 344.1633 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 8, 173, 204, 120], dtype=int32),\n", + " array([345.64352, 345.67572, 345.6923 , 345.88 , 345.98047, 346.0731 ,\n", + " 346.19617, 346.36945, 346.39755, 346.41702], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 86, 268, 305, 487, 121], dtype=int32),\n", + " array([313.79404, 313.84033, 313.8432 , 314.10782, 314.28986, 314.4456 ,\n", + " 314.4678 , 314.48093, 314.526 , 314.55356], dtype=float32)),\n", + " (array([ 32, 43, 19, 305, 31, 62, 121, 49, 16, 528], dtype=int32),\n", + " array([311.67966, 311.6894 , 312.01752, 312.02475, 312.0784 , 312.22818,\n", + " 312.30634, 312.35004, 312.38342, 312.40384], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 121, 62, 100, 29, 173, 105], dtype=int32),\n", + " array([318.74945, 318.89972, 318.94348, 319.02133, 319.2833 , 319.4113 ,\n", + " 319.5563 , 319.66492, 319.7494 , 319.75116], dtype=float32)),\n", + " (array([ 31, 19, 121, 100, 62, 32, 173, 86, 43, 12], dtype=int32),\n", + " array([290.89676, 291.22546, 291.24185, 291.418 , 291.50125, 291.53076,\n", + " 291.66797, 291.8173 , 291.83707, 291.92416], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-5.0916862, -5.0628467, -4.526428 , -4.460362 , -4.4587893,\n", + " -4.283753 , -4.275841 , -4.082758 , -4.0510454, -4.0182204],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 120, 43, 268, 62, 2180, 103, 121],\n", + " dtype=int32),\n", + " array([338.37042, 339.149 , 339.20544, 339.22913, 339.23502, 339.49866,\n", + " 339.5416 , 339.5564 , 339.5816 , 339.58572], dtype=float32)),\n", + " (array([ 31, 103, 19, 61, 62, 268, 40, 121, 12, 164], dtype=int32),\n", + " array([340.85242, 341.49536, 341.90274, 341.90433, 342.1021 , 342.1285 ,\n", + " 342.14203, 342.14774, 342.2698 , 342.28677], dtype=float32)),\n", + " (array([ 31, 19, 62, 164, 121, 103, 173, 268, 43, 32], dtype=int32),\n", + " array([313.59637, 313.59827, 314.18777, 314.25516, 314.29272, 314.47693,\n", + " 314.48468, 314.5138 , 314.5995 , 314.6321 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", + " array([311.75436, 311.90695, 311.9811 , 312.04282, 312.101 , 312.277 ,\n", + " 312.45184, 312.67252, 312.71725, 312.74603], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-4.956269 , -4.929399 , -4.380765 , -4.3234515, -4.3203835,\n", + " -4.1493745, -4.1366277, -3.9477794, -3.9138684, -3.889961 ],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 49, 86], dtype=int32),\n", + " array([308.77475, 308.83475, 308.88083, 308.90268, 309.20108, 309.39276,\n", + " 309.61237, 309.62393, 309.70663, 309.73032], dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 32, 100, 43, 8, 268, 49], dtype=int32),\n", + " array([-13.882435, -13.882223, -13.619325, -13.587515, -13.471606,\n", + " -13.293805, -13.28355 , -13.157932, -13.013595, -12.973706],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 43, 62, 173, 121, 32, 12, 268, 100], dtype=int32),\n", + " array([-12.391222 , -12.185223 , -11.797996 , -11.6746235, -11.539297 ,\n", + " -11.5266075, -11.525804 , -11.367205 , -11.29679 , -11.026756 ],\n", + " dtype=float32)),\n", + " (array([ 43, 31, 32, 610, 19, 62, 36, 86, 279, 121], dtype=int32),\n", + " array([309.64053, 309.86337, 309.9061 , 309.97876, 309.98526, 310.06454,\n", + " 310.1976 , 310.20383, 310.35623, 310.36185], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", + " array([343.35208, 343.41168, 343.44373, 343.44824, 343.66055, 343.91107,\n", + " 344.12186, 344.1866 , 344.2187 , 344.25067], dtype=float32)),\n", + " (array([ 31, 19, 12, 121, 62, 32, 268, 173, 43, 120], dtype=int32),\n", + " array([-8.2037525, -7.8561625, -7.32616 , -7.2407165, -7.217618 ,\n", + " -7.2110157, -7.114374 , -7.101262 , -7.086527 , -6.8286524],\n", + " dtype=float32)),\n", + " (array([ 43, 69, 188, 31, 279, 112, 86, 528, 19, 848], dtype=int32),\n", + " array([274.54037, 274.7362 , 274.78943, 274.95895, 274.97327, 275.00256,\n", + " 275.0414 , 275.06506, 275.1002 , 275.107 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 268, 121, 43, 12, 120, 62, 103], dtype=int32),\n", + " array([214.02432, 214.2606 , 214.53061, 214.61006, 214.63873, 214.67516,\n", + " 214.92061, 214.97589, 215.06847, 215.12253], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-5.0349526, -5.018808 , -4.4812174, -4.4271564, -4.417553 ,\n", + " -4.2393327, -4.2360854, -4.0470505, -4.01184 , -3.9929585],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 43, 21, 32, 121, 62, 164, 12, 268], dtype=int32),\n", + " array([269.79233, 269.91074, 270.33194, 270.33887, 270.49026, 270.51355,\n", + " 270.7281 , 270.7439 , 270.7531 , 270.76456], dtype=float32)),\n", + " (array([ 19, 31, 3408, 241, 2196, 43, 149, 62, 32, 173],\n", + " dtype=int32),\n", + " array([0.024508 , 0.14910242, 0.34831434, 0.37699768, 0.46431854,\n", + " 0.534814 , 0.5353782 , 0.5813904 , 0.60867965, 0.6309118 ],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 305, 29, 268, 111, 186], dtype=int32),\n", + " array([341.07092, 341.19382, 341.26025, 341.45108, 341.7736 , 341.86887,\n", + " 341.95206, 342.01297, 342.01733, 342.02136], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 268, 86, 120, 62, 29, 255], dtype=int32),\n", + " array([312.9404 , 312.94547, 312.96555, 313.21994, 313.44928, 313.46713,\n", + " 313.51907, 313.5326 , 313.5641 , 313.78125], dtype=float32)),\n", + " (array([ 149, 57, 735, 530, 1118, 552, 325, 262, 965, 539],\n", + " dtype=int32),\n", + " array([341.78226, 342.1679 , 342.20877, 342.442 , 342.44888, 342.5751 ,\n", + " 342.66943, 342.71283, 342.72598, 342.86658], dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 62, 121, 166, 49, 204, 255], dtype=int32),\n", + " array([297.6658 , 297.68994, 297.76672, 298.01215, 298.0355 , 298.18173,\n", + " 298.46136, 298.49863, 298.50992, 298.5142 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 43, 100, 62, 29, 12, 105], dtype=int32),\n", + " array([353.61127, 353.68066, 353.8292 , 353.89127, 354.0306 , 354.11322,\n", + " 354.19388, 354.24356, 354.32172, 354.4584 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([238.92976, 239.10492, 239.30301, 239.40337, 239.51256, 239.67253,\n", + " 239.87503, 239.93681, 240.0481 , 240.17143], dtype=float32)),\n", + " (array([ 19, 32, 43, 342, 279, 848, 305, 16, 528, 13], dtype=int32),\n", + " array([324.29257, 324.29764, 324.3113 , 324.7585 , 324.8286 , 324.88263,\n", + " 324.8934 , 324.9032 , 324.94672, 324.95236], dtype=float32)),\n", + " (array([ 262, 149, 8, 961, 450, 153, 369, 0, 718, 1482],\n", + " dtype=int32),\n", + " array([-10.602786, -10.398672, -10.261883, -10.200603, -10.195368,\n", + " -10.174867, -10.102303, -10.084438, -10.054341, -10.048715],\n", + " dtype=float32)),\n", + " (array([ 19, 43, 32, 279, 31, 848, 173, 206, 62, 188], dtype=int32),\n", + " array([348.31458, 348.40448, 348.69327, 348.92053, 348.9937 , 349.0691 ,\n", + " 349.14886, 349.1566 , 349.19763, 349.289 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 121, 255, 173, 100, 268], dtype=int32),\n", + " array([-6.228593 , -6.046022 , -5.878892 , -5.686447 , -5.545691 ,\n", + " -5.4963074, -5.3257055, -5.306989 , -5.234576 , -5.19708 ],\n", + " dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 62, 121, 100, 86, 268, 29], dtype=int32),\n", + " array([155.9606 , 156.14497, 156.1596 , 156.20587, 156.54088, 156.65228,\n", + " 156.86281, 156.89601, 156.99948, 157.02376], dtype=float32)),\n", + " (array([ 31, 19, 32, 62, 43, 121, 100, 173, 164, 268], dtype=int32),\n", + " array([301.5933 , 301.77182, 301.88055, 301.8956 , 301.93088, 302.1367 ,\n", + " 302.32584, 302.5011 , 302.61255, 302.62833], dtype=float32)),\n", + " (array([ 43, 19, 32, 848, 279, 31, 1088, 188, 206, 305],\n", + " dtype=int32),\n", + " array([242.30208, 242.4566 , 242.50288, 242.64774, 242.6903 , 242.70723,\n", + " 242.8998 , 242.94298, 243.01842, 243.10117], dtype=float32)),\n", + " (array([ 32, 43, 19, 8, 262, 149, 31, 62, 965, 153], dtype=int32),\n", + " array([325.99268, 326.01578, 326.10822, 326.13806, 326.19952, 326.33246,\n", + " 326.42374, 326.44608, 326.71274, 326.75964], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 62, 121, 268, 105, 29, 173], dtype=int32),\n", + " array([348.06845, 348.13095, 348.13138, 348.38913, 348.7707 , 348.8059 ,\n", + " 348.90616, 348.93887, 348.97375, 349.02744], dtype=float32)),\n", + " (array([ 43, 31, 32, 19, 62, 305, 384, 121, 86, 49], dtype=int32),\n", + " array([-19.180525, -18.978985, -18.847485, -18.57598 , -18.398008,\n", + " -18.037577, -17.899921, -17.898565, -17.893497, -17.85743 ],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 43, 62, 19, 49, 121, 120, 305, 186], dtype=int32),\n", + " array([316.81924, 316.98322, 317.02298, 317.17685, 317.2592 , 317.46994,\n", + " 317.53558, 317.6029 , 317.62537, 317.70798], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 268, 86, 120, 255], dtype=int32),\n", + " array([234.87148, 235.01166, 235.40932, 235.53763, 235.59041, 235.67786,\n", + " 235.8497 , 235.95566, 235.96455, 236.03766], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 112, 62, 305, 204, 186, 487], dtype=int32),\n", + " array([320.0586 , 320.17426, 320.28238, 320.5273 , 320.5556 , 320.582 ,\n", + " 320.7148 , 320.73547, 320.74487, 320.7662 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.86703, 345.08035, 345.2343 , 345.32755, 345.37546, 345.52267,\n", + " 345.7457 , 345.87714, 345.94556, 346.0212 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 32, 8, 43, 149, 121, 268, 49], dtype=int32),\n", + " array([322.33954, 322.37024, 322.60202, 322.62314, 322.70538, 322.7285 ,\n", + " 322.82034, 322.983 , 323.09814, 323.11078], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 29, 173, 120], dtype=int32),\n", + " array([242.67905, 242.71577, 243.18695, 243.23677, 243.37122, 243.47752,\n", + " 243.55363, 243.79132, 243.79521, 243.812 ], dtype=float32)),\n", + " (array([ 31, 62, 43, 32, 358, 149, 8, 117, 552, 347], dtype=int32),\n", + " array([-22.578669, -22.562916, -22.470627, -22.347956, -22.297577,\n", + " -22.153297, -22.151903, -22.0696 , -22.06733 , -22.051004],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 121, 204, 166, 69, 62, 268], dtype=int32),\n", + " array([328.0418 , 328.0906 , 328.16348, 328.231 , 328.41153, 328.50214,\n", + " 328.59714, 328.67847, 328.70084, 328.85712], dtype=float32)),\n", + " (array([ 31, 121, 32, 62, 19, 43, 49, 100, 8, 268], dtype=int32),\n", + " array([287.95667, 288.24008, 288.26828, 288.27618, 288.4324 , 288.57266,\n", + " 288.66376, 288.74893, 288.77286, 288.8862 ], dtype=float32)),\n", + " (array([ 19, 31, 173, 121, 62, 32, 103, 268, 43, 12], dtype=int32),\n", + " array([-9.673244, -9.537863, -8.806235, -8.794689, -8.630214, -8.552435,\n", + " -8.547477, -8.524884, -8.503831, -8.393221], dtype=float32)),\n", + " (array([ 31, 19, 173, 358, 268, 32, 62, 121, 636, 43], dtype=int32),\n", + " array([345.0455 , 345.10556, 345.55307, 345.6344 , 345.7094 , 345.7181 ,\n", + " 345.7714 , 345.85223, 345.96268, 346.00952], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 29, 305, 255, 105, 121, 164], dtype=int32),\n", + " array([-13.802836, -13.402133, -13.22652 , -13.114232, -12.968248,\n", + " -12.774135, -12.758164, -12.713695, -12.6649 , -12.606666],\n", + " dtype=float32)),\n", + " (array([ 31, 121, 62, 43, 32, 19, 120, 12, 86, 100], dtype=int32),\n", + " array([343.27493, 343.95023, 344.08218, 344.1211 , 344.2443 , 344.2454 ,\n", + " 344.417 , 344.41772, 344.58157, 344.59363], dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 149, 62, 57, 8, 305, 262], dtype=int32),\n", + " array([304.57358, 304.69336, 304.9109 , 305.06064, 305.1308 , 305.14938,\n", + " 305.32532, 305.43835, 305.45303, 305.4926 ], dtype=float32)),\n", + " (array([ 31, 32, 62, 43, 19, 121, 100, 49, 120, 268], dtype=int32),\n", + " array([342.73886, 342.82443, 342.94052, 343.03305, 343.0704 , 343.2753 ,\n", + " 343.43192, 343.43774, 343.53738, 343.54156], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 173, 12, 43, 32, 100, 268], dtype=int32),\n", + " array([346.24307, 346.76843, 347.12042, 347.22662, 347.28696, 347.3403 ,\n", + " 347.37088, 347.489 , 347.49182, 347.57352], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", + " array([343.2749 , 343.3322 , 343.36847, 343.39383, 343.58325, 343.83533,\n", + " 344.04684, 344.1072 , 344.1612 , 344.16885], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 100, 120], dtype=int32),\n", + " array([289.75934, 289.83258, 290.14587, 290.26434, 290.43954, 290.46304,\n", + " 290.6384 , 290.79724, 290.9155 , 290.927 ], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 173, 62, 100, 4049, 8, 4086],\n", + " dtype=int32),\n", + " array([-1.0573236 , -0.84619975, -0.65467846, -0.5441257 , -0.33517003,\n", + " -0.2748596 , -0.26382744, -0.1981795 , -0.10777314, -0.08880416],\n", + " dtype=float32)),\n", + " (array([ 31, 62, 19, 8, 149, 240, 121, 32, 262, 347], dtype=int32),\n", + " array([342.65033, 342.66632, 342.67032, 342.70035, 342.71603, 342.73782,\n", + " 342.94247, 342.99304, 343.08875, 343.09988], dtype=float32)),\n", + " (array([ 31, 43, 62, 32, 121, 19, 149, 49, 69, 100], dtype=int32),\n", + " array([342.75912, 342.7855 , 342.9729 , 343.00104, 343.07062, 343.31467,\n", + " 343.31744, 343.4589 , 343.50546, 343.59317], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 173, 62, 268, 100, 12, 120], dtype=int32),\n", + " array([-5.5847416, -5.46135 , -5.327554 , -5.1129932, -4.891976 ,\n", + " -4.7081285, -4.666163 , -4.5997343, -4.582306 , -4.449086 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 173, 121, 32, 29, 12, 43, 100, 62], dtype=int32),\n", + " array([-1.8461745 , -1.7337073 , -1.0355114 , -0.99675316, -0.84427077,\n", + " -0.8012683 , -0.6919193 , -0.66187763, -0.6253451 , -0.56059986],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 31, 32, 62, 121, 86, 100, 173, 268], dtype=int32),\n", + " array([310.91208, 310.94843, 310.95355, 310.98315, 311.24374, 311.39185,\n", + " 311.6052 , 311.6181 , 311.7201 , 311.77524], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 29, 105, 255, 268, 62], dtype=int32),\n", + " array([266.47375, 266.66608, 266.73834, 266.86328, 267.0835 , 267.21884,\n", + " 267.28024, 267.28027, 267.30478, 267.33682], dtype=float32)),\n", + " (array([ 19, 32, 43, 62, 31, 173, 8, 204, 112, 149], dtype=int32),\n", + " array([343.2632 , 343.45453, 343.62622, 343.878 , 344.12677, 344.13196,\n", + " 344.14893, 344.1754 , 344.30896, 344.357 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", + " array([311.78104, 311.92377, 312.00885, 312.05548, 312.11484, 312.3027 ,\n", + " 312.47028, 312.69635, 312.74988, 312.77103], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 86, 305, 255, 483, 268, 62], dtype=int32),\n", + " array([306.78027, 306.89676, 307.04138, 307.1993 , 307.41788, 307.44092,\n", + " 307.52713, 307.54416, 307.61343, 307.70517], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 121, 100, 268, 49, 120], dtype=int32),\n", + " array([341.15765, 341.25577, 341.25867, 341.33832, 341.56152, 341.84787,\n", + " 342.04324, 342.04425, 342.06607, 342.21762], dtype=float32)),\n", + " (array([ 31, 19, 32, 62, 121, 43, 100, 173, 262, 86], dtype=int32),\n", + " array([267.49988, 267.76523, 267.87183, 267.93344, 268.03348, 268.05356,\n", + " 268.25632, 268.48865, 268.50696, 268.51288], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 268, 62, 49, 100, 255, 121], dtype=int32),\n", + " array([346.49777, 346.51266, 346.7497 , 346.81296, 347.1502 , 347.20084,\n", + " 347.38962, 347.43158, 347.43805, 347.47437], dtype=float32)),\n", + " (array([ 31, 19, 21, 121, 12, 173, 358, 61, 268, 62], dtype=int32),\n", + " array([332.9891 , 333.0644 , 333.0821 , 333.63422, 333.898 , 333.94617,\n", + " 333.95294, 333.98947, 334.0268 , 334.07285], dtype=float32)),\n", + " (array([ 62, 43, 31, 121, 32, 19, 49, 8, 149, 86], dtype=int32),\n", + " array([337.5237 , 337.58023, 337.59036, 337.77313, 337.83856, 337.9132 ,\n", + " 337.95486, 337.96304, 337.9762 , 338.20206], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 255, 62, 120, 268, 121, 173], dtype=int32),\n", + " array([-7.41297 , -7.3131714, -6.996518 , -6.5799 , -6.553384 ,\n", + " -6.4600983, -6.4193177, -6.4142714, -6.391178 , -6.2705107],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 121, 29, 255, 12, 86, 100], dtype=int32),\n", + " array([318.9655 , 319.48196, 319.58127, 319.85565, 319.88397, 319.8869 ,\n", + " 319.91284, 320.0058 , 320.11743, 320.326 ], dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 121, 255, 120, 268, 62, 305], dtype=int32),\n", + " array([342.2747 , 342.81036, 342.8518 , 343.1069 , 343.13345, 343.14868,\n", + " 343.21085, 343.30496, 343.3074 , 343.4081 ], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 86, 36, 166, 279, 69, 8], dtype=int32),\n", + " array([238.89128, 239.07706, 239.37599, 239.43842, 239.66939, 239.72287,\n", + " 239.83084, 239.84314, 239.85434, 239.91563], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 305, 29, 121, 255, 62, 120], dtype=int32),\n", + " array([-13.285771 , -13.1329 , -13.046364 , -12.953725 , -12.392658 ,\n", + " -12.3227825, -12.292379 , -12.193694 , -12.176666 , -12.170973 ],\n", + " dtype=float32)),\n", + " (array([ 19, 43, 358, 31, 32, 173, 121, 62, 974, 258], dtype=int32),\n", + " array([268.67563, 269.15594, 269.2859 , 269.2988 , 269.53354, 269.67276,\n", + " 269.67557, 269.74835, 269.77563, 269.81207], dtype=float32)),\n", + " (array([ 31, 43, 19, 62, 32, 121, 86, 268, 358, 120], dtype=int32),\n", + " array([340.41257, 340.81824, 341.0423 , 341.1104 , 341.1158 , 341.36127,\n", + " 341.5532 , 341.55826, 341.68536, 341.71152], dtype=float32)),\n", + " (array([ 43, 69, 36, 32, 350, 279, 62, 449, 913, 89], dtype=int32),\n", + " array([302.2446 , 302.455 , 302.52432, 302.6092 , 302.65167, 302.70242,\n", + " 302.74884, 302.7768 , 302.83377, 302.92834], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 268, 358, 97, 305, 173, 258], dtype=int32),\n", + " array([291.71432, 292.0191 , 292.13284, 292.35666, 292.4423 , 292.69443,\n", + " 292.7329 , 292.76465, 292.79208, 292.80676], dtype=float32)),\n", + " (array([ 19, 31, 62, 43, 32, 173, 121, 268, 100, 29], dtype=int32),\n", + " array([-11.688484 , -11.125582 , -10.9086075, -10.868964 , -10.853149 ,\n", + " -10.779191 , -10.752395 , -10.378834 , -10.325179 , -10.316356 ],\n", + " dtype=float32)),\n", + " (array([ 19, 43, 32, 62, 86, 31, 262, 100, 279, 121], dtype=int32),\n", + " array([243.38695, 243.4355 , 243.47537, 243.87566, 243.88516, 243.97946,\n", + " 243.985 , 244.00552, 244.01039, 244.02129], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 173, 121, 36, 279, 100], dtype=int32),\n", + " array([346.06186, 346.3155 , 346.4341 , 346.66858, 346.73395, 346.93384,\n", + " 347.01212, 347.13586, 347.1704 , 347.20654], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([322.2912 , 322.39038, 322.63904, 322.75272, 322.93408, 322.99997,\n", + " 323.1657 , 323.34866, 323.4547 , 323.47766], dtype=float32)),\n", + " (array([ 43, 31, 32, 19, 279, 100, 62, 121, 173, 149], dtype=int32),\n", + " array([348.38797, 348.51193, 348.58295, 348.73206, 349.00638, 349.08313,\n", + " 349.1072 , 349.18314, 349.1896 , 349.3602 ], dtype=float32)),\n", + " (array([ 43, 32, 36, 62, 19, 279, 69, 31, 350, 913], dtype=int32),\n", + " array([201.66779, 202.24219, 202.32242, 202.54419, 202.57008, 202.5704 ,\n", + " 202.58543, 202.62018, 202.7129 , 202.7193 ], dtype=float32)),\n", + " (array([ 19, 279, 43, 31, 974, 32, 173, 342, 258, 358], dtype=int32),\n", + " array([-6.737044 , -6.4661856, -6.335514 , -6.1007633, -6.018259 ,\n", + " -5.8393497, -5.7927628, -5.7813506, -5.7542744, -5.7353625],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 19, 62, 43, 121, 49, 186, 268, 100], dtype=int32),\n", + " array([237.638 , 237.65561, 237.74834, 237.90337, 238.15375, 238.16351,\n", + " 238.19691, 238.31027, 238.31354, 238.31615], dtype=float32)),\n", + " (array([ 43, 31, 62, 19, 32, 69, 149, 121, 36, 279], dtype=int32),\n", + " array([313.75217, 313.76544, 313.92413, 314.07645, 314.0797 , 314.1986 ,\n", + " 314.21243, 314.2998 , 314.3333 , 314.35022], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 305, 268, 62, 75, 29, 487], dtype=int32),\n", + " array([306.58862, 306.707 , 306.83008, 306.98032, 307.40878, 307.41513,\n", + " 307.52386, 307.54425, 307.55472, 307.56903], dtype=float32)),\n", + " (array([ 19, 31, 62, 32, 43, 121, 173, 86, 100, 49], dtype=int32),\n", + " array([311.85876, 312.34027, 312.35883, 312.51312, 312.51736, 312.5776 ,\n", + " 312.6214 , 312.71265, 312.812 , 313.06488], dtype=float32)),\n", + " (array([ 32, 43, 31, 62, 19, 347, 121, 120, 8, 149], dtype=int32),\n", + " array([340.20966, 340.24063, 340.39673, 340.58658, 340.69055, 340.91504,\n", + " 340.9395 , 341.01114, 341.0885 , 341.08972], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 32, 173, 43, 100, 61, 268], dtype=int32),\n", + " array([315.38632, 315.81006, 315.8251 , 315.97635, 316.28314, 316.3262 ,\n", + " 316.42813, 316.5111 , 316.52377, 316.53525], dtype=float32)),\n", + " (array([ 31, 19, 103, 121, 32, 268, 43, 62, 105, 164], dtype=int32),\n", + " array([309.3906 , 309.6671 , 310.19968, 310.20175, 310.21674, 310.25854,\n", + " 310.25912, 310.3019 , 310.4493 , 310.50653], dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 173, 43, 358, 268, 62, 100], dtype=int32),\n", + " array([-7.4531083, -7.4069843, -7.1199527, -7.0514636, -6.9424915,\n", + " -6.7885723, -6.786592 , -6.7568116, -6.65103 , -6.6452637],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 173, 358, 268, 62, 121, 43, 97], dtype=int32),\n", + " array([293.18036, 293.28452, 293.64398, 293.79703, 293.80237, 293.8423 ,\n", + " 293.91156, 293.9354 , 293.97946, 294.1902 ], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 268, 121, 62, 103, 164, 120], dtype=int32),\n", + " array([287.96588, 288.04755, 288.34372, 288.45853, 288.68408, 288.6929 ,\n", + " 288.7793 , 288.86368, 288.9352 , 288.94495], dtype=float32)),\n", + " (array([ 19, 31, 43, 121, 32, 62, 173, 86, 268, 100], dtype=int32),\n", + " array([314.06598, 314.1612 , 314.46637, 314.58292, 314.66385, 314.7214 ,\n", + " 314.75793, 314.80377, 315.03503, 315.08655], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", + " array([343.33026, 343.38437, 343.41385, 343.43347, 343.6325 , 343.88467,\n", + " 344.08762, 344.1461 , 344.19424, 344.22925], dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 32, 43, 120, 8, 100, 149], dtype=int32),\n", + " array([312.45236, 312.47968, 312.59567, 312.64728, 312.67422, 312.6901 ,\n", + " 312.93405, 312.9464 , 312.9713 , 313.12497], dtype=float32)),\n", + " (array([ 31, 19, 32, 62, 43, 121, 268, 103, 255, 358], dtype=int32),\n", + " array([282.46292, 283.05493, 283.19315, 283.2847 , 283.39166, 283.46155,\n", + " 283.59256, 283.6934 , 283.7161 , 283.911 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 62, 43, 121, 268, 8, 173, 100], dtype=int32),\n", + " array([345.65524, 345.9262 , 346.16885, 346.1865 , 346.21036, 346.32147,\n", + " 346.58743, 346.62735, 346.72934, 346.7569 ], dtype=float32)),\n", + " (array([552, 241, 149, 31, 19, 43, 835, 965, 62, 32], dtype=int32),\n", + " array([340.22452, 340.23013, 340.35202, 340.40323, 340.5305 , 340.61328,\n", + " 340.63605, 340.76526, 340.7976 , 340.83078], dtype=float32)),\n", + " (array([ 0, 149, 19, 31, 262, 8, 57, 2196, 835, 287],\n", + " dtype=int32),\n", + " array([-6.6349945, -6.434936 , -6.4298882, -6.3276916, -6.2651544,\n", + " -6.2419343, -6.2317705, -6.149833 , -6.084716 , -6.0592847],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([342.9787 , 343.1185 , 343.303 , 343.38464, 343.51157, 343.69272,\n", + " 343.88483, 343.9932 , 344.09888, 344.10062], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-4.967532 , -4.927384 , -4.3966413, -4.338209 , -4.332314 ,\n", + " -4.170254 , -4.155649 , -3.9548771, -3.9246242, -3.8911352],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 268, 29, 62, 43, 173, 100], dtype=int32),\n", + " array([308.04425, 308.07153, 308.2269 , 308.80017, 308.8662 , 308.99945,\n", + " 309.00992, 309.02774, 309.07608, 309.08847], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 173, 164, 268, 358, 103, 86], dtype=int32),\n", + " array([350.3946 , 350.56 , 351.00375, 351.08243, 351.1222 , 351.22012,\n", + " 351.3107 , 351.3321 , 351.3452 , 351.3912 ], dtype=float32)),\n", + " (array([ 31, 12, 19, 62, 86, 121, 255, 43, 32, 173], dtype=int32),\n", + " array([344.86353, 345.49313, 345.5193 , 345.57196, 345.64996, 345.70776,\n", + " 345.77866, 345.78577, 345.85107, 345.93347], dtype=float32)),\n", + " (array([ 43, 32, 62, 19, 31, 305, 121, 49, 29, 100], dtype=int32),\n", + " array([309.69183, 309.72003, 310.1108 , 310.12317, 310.19186, 310.20572,\n", + " 310.25827, 310.38513, 310.44757, 310.48715], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 43, 62, 103, 268, 164, 173], dtype=int32),\n", + " array([346.98663, 347.161 , 347.6466 , 347.66846, 347.7361 , 347.87103,\n", + " 347.9015 , 347.98883, 348.1148 , 348.1953 ], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 255, 121, 268, 120, 173], dtype=int32),\n", + " array([344.63037, 344.96603, 345.0624 , 345.35706, 345.6743 , 345.75803,\n", + " 345.79025, 345.7998 , 345.86005, 345.89853], dtype=float32)),\n", + " (array([ 31, 606, 19, 32, 12, 43, 62, 268, 29, 121], dtype=int32),\n", + " array([296.2893 , 296.70212, 296.86227, 296.93552, 297.2532 , 297.5014 ,\n", + " 297.51282, 297.62958, 297.6524 , 297.6867 ], dtype=float32)),\n", + " (array([ 19, 43, 32, 173, 62, 31, 258, 69, 279, 358], dtype=int32),\n", + " array([345.94232, 346.3208 , 346.47083, 346.536 , 346.57697, 346.5811 ,\n", + " 346.60034, 346.7322 , 346.74197, 346.81818], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 62, 121, 173, 268, 100, 164], dtype=int32),\n", + " array([344.73718, 344.74698, 345.1139 , 345.21097, 345.30167, 345.40225,\n", + " 345.47433, 345.5714 , 345.84488, 345.90356], dtype=float32)),\n", + " (array([ 8, 43, 149, 262, 965, 36, 325, 118, 450, 31], dtype=int32),\n", + " array([339.9371 , 339.94836, 339.9582 , 340.12228, 340.15903, 340.193 ,\n", + " 340.26828, 340.27094, 340.28644, 340.40198], dtype=float32)),\n", + " (array([ 43, 32, 31, 62, 305, 19, 49, 111, 350, 255], dtype=int32),\n", + " array([282.34915, 282.55243, 282.9279 , 283.03018, 283.04544, 283.1338 ,\n", + " 283.19824, 283.21097, 283.3 , 283.31216], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 121, 268, 100, 255, 120], dtype=int32),\n", + " array([345.68124, 345.80133, 345.8418 , 345.94818, 346.2074 , 346.42343,\n", + " 346.56555, 346.5872 , 346.67224, 346.709 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 268, 121, 86, 305, 105], dtype=int32),\n", + " array([312.97928, 313.02115, 313.0263 , 313.12262, 313.30692, 313.51068,\n", + " 313.5661 , 313.8236 , 313.87775, 313.9069 ], dtype=float32)),\n", + " (array([ 43, 19, 31, 32, 86, 121, 62, 166, 374, 279], dtype=int32),\n", + " array([-13.556057 , -13.332751 , -13.110254 , -12.861042 , -12.839451 ,\n", + " -12.7131405, -12.609385 , -12.46355 , -12.367276 , -12.366643 ],\n", + " dtype=float32)),\n", + " (array([1959, 3354, 985, 796, 1120, 458, 2181, 884, 827, 39],\n", + " dtype=int32),\n", + " array([206.00974, 206.01682, 206.33737, 206.3616 , 206.4415 , 206.48859,\n", + " 206.50409, 206.52463, 206.69136, 206.6996 ], dtype=float32)),\n", + " (array([ 31, 32, 62, 19, 121, 268, 43, 100, 173, 120], dtype=int32),\n", + " array([239.53592, 240.14597, 240.1554 , 240.20403, 240.37437, 240.52495,\n", + " 240.60902, 240.6724 , 240.76917, 240.77725], dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 173, 62, 43, 100, 12, 262], dtype=int32),\n", + " array([321.57968, 321.7376 , 322.36234, 322.3648 , 322.4114 , 322.46686,\n", + " 322.46756, 322.56653, 322.83417, 322.897 ], dtype=float32)),\n", + " (array([ 43, 32, 279, 62, 36, 202, 19, 31, 118, 129], dtype=int32),\n", + " array([342.04837, 342.36404, 342.5594 , 342.57648, 342.6203 , 342.7652 ,\n", + " 342.80353, 342.8174 , 342.84668, 342.86243], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([322.29755, 322.40707, 322.6554 , 322.7699 , 322.94193, 323.00052,\n", + " 323.17963, 323.35965, 323.46408, 323.4884 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.94446, 345.15247, 345.30548, 345.39865, 345.44852, 345.61697,\n", + " 345.81113, 345.93576, 346.0243 , 346.10663], dtype=float32)),\n", + " (array([ 31, 19, 62, 32, 43, 121, 173, 268, 100, 49], dtype=int32),\n", + " array([-18.67583 , -18.660309, -18.417833, -18.359253, -18.311916,\n", + " -18.297022, -17.962929, -17.872766, -17.866323, -17.787956],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 173, 86, 268, 100], dtype=int32),\n", + " array([265.35388, 265.51334, 265.8318 , 265.98834, 266.0196 , 266.0399 ,\n", + " 266.3121 , 266.329 , 266.36688, 266.4785 ], dtype=float32)),\n", + " (array([ 19, 31, 62, 43, 32, 121, 49, 164, 487, 268], dtype=int32),\n", + " array([318.11493, 318.2129 , 318.48407, 318.5036 , 318.6542 , 318.85413,\n", + " 319.08267, 319.12872, 319.17377, 319.17834], dtype=float32)),\n", + " (array([ 19, 32, 43, 62, 149, 31, 8, 262, 49, 100], dtype=int32),\n", + " array([311.7225 , 311.72437, 311.865 , 311.92014, 312.01312, 312.05374,\n", + " 312.10504, 312.19315, 312.32663, 312.4075 ], dtype=float32)),\n", + " (array([ 43, 19, 31, 32, 62, 121, 86, 164, 49, 255], dtype=int32),\n", + " array([-19.813524, -19.804207, -19.728668, -19.522465, -19.514381,\n", + " -19.144453, -19.036312, -19.008139, -18.869104, -18.85116 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 173, 86, 268, 100], dtype=int32),\n", + " array([265.12915, 265.2871 , 265.59576, 265.74454, 265.7797 , 265.80145,\n", + " 266.07492, 266.12085, 266.1362 , 266.24216], dtype=float32)),\n", + " (array([1380, 69, 279, 36, 43, 118, 2314, 370, 31, 129],\n", + " dtype=int32),\n", + " array([344.4259 , 345.0539 , 345.24893, 345.3121 , 345.52026, 345.52222,\n", + " 345.54364, 345.6231 , 345.63965, 345.73315], dtype=float32)),\n", + " (array([ 19, 32, 31, 62, 121, 268, 43, 173, 358, 258], dtype=int32),\n", + " array([295.7728 , 296.09378, 296.16385, 296.46597, 296.63776, 296.6984 ,\n", + " 296.7833 , 296.7903 , 297.00592, 297.0654 ], dtype=float32)),\n", + " (array([ 31, 103, 19, 32, 268, 40, 43, 62, 121, 120], dtype=int32),\n", + " array([300.94043, 301.23984, 301.47314, 301.7147 , 301.79453, 301.82016,\n", + " 301.8464 , 301.89368, 301.9198 , 301.93735], dtype=float32)),\n", + " (array([ 31, 43, 32, 358, 62, 19, 121, 441, 149, 268], dtype=int32),\n", + " array([338.95685, 339.508 , 339.67297, 339.73325, 339.74152, 339.75598,\n", + " 340.20038, 340.21057, 340.222 , 340.24942], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 62, 262, 8, 268, 173, 489], dtype=int32),\n", + " array([325.10217, 325.2386 , 325.4241 , 325.49515, 325.5875 , 325.60492,\n", + " 325.66873, 325.72284, 325.73413, 325.74463], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 206, 121, 69, 36, 279], dtype=int32),\n", + " array([320.6978 , 320.7718 , 320.82007, 320.8214 , 321.34268, 321.38998,\n", + " 321.45862, 321.49222, 321.5061 , 321.50754], dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 62, 255, 86, 305, 121, 120], dtype=int32),\n", + " array([307.69656, 307.91446, 308.12283, 308.1325 , 308.37936, 308.39438,\n", + " 308.4579 , 308.5237 , 308.5974 , 308.6452 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 268, 173, 62, 121, 255, 43, 86], dtype=int32),\n", + " array([-5.3790417, -5.09458 , -4.8331766, -4.789051 , -4.7823205,\n", + " -4.7822595, -4.7535043, -4.7527666, -4.6321225, -4.5882025],\n", + " dtype=float32)),\n", + " (array([ 43, 62, 32, 8, 31, 149, 262, 121, 19, 49], dtype=int32),\n", + " array([306.98486, 307.0449 , 307.16565, 307.17218, 307.22464, 307.2487 ,\n", + " 307.5891 , 307.61765, 307.6228 , 307.71387], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 62, 173, 268, 86, 121, 206], dtype=int32),\n", + " array([345.04468, 345.1523 , 345.15298, 345.21475, 345.5471 , 345.63983,\n", + " 345.75662, 345.81226, 345.8635 , 345.89917], dtype=float32)),\n", + " (array([ 32, 19, 43, 305, 31, 62, 848, 528, 206, 111], dtype=int32),\n", + " array([285.80884, 286.03918, 286.08514, 286.37485, 286.55283, 286.5899 ,\n", + " 286.72803, 286.73105, 286.73996, 286.74646], dtype=float32)),\n", + " (array([ 19, 31, 29, 173, 121, 86, 43, 32, 268, 12], dtype=int32),\n", + " array([-4.130883 , -4.03582 , -3.3995347, -3.3950984, -3.363095 ,\n", + " -3.2856205, -3.2271123, -3.1006253, -3.0423734, -3.0390787],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 62, 262, 149, 173, 121, 1801, 552, 32],\n", + " dtype=int32),\n", + " array([321.75845, 321.78885, 322.08078, 322.20398, 322.23715, 322.39954,\n", + " 322.42 , 322.4579 , 322.5363 , 322.5482 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 105, 29], dtype=int32),\n", + " array([265.6478 , 265.7476 , 266.03217, 266.21774, 266.3553 , 266.38412,\n", + " 266.56482, 266.73804, 266.83734, 266.8432 ], dtype=float32)),\n", + " (array([ 19, 31, 173, 121, 29, 32, 100, 268, 62, 43], dtype=int32),\n", + " array([172.11482, 172.73111, 172.8957 , 172.95479, 172.99104, 173.08199,\n", + " 173.39893, 173.47232, 173.52538, 173.52583], dtype=float32)),\n", + " (array([ 32, 19, 31, 121, 62, 43, 149, 8, 268, 120], dtype=int32),\n", + " array([290.4755 , 290.66855, 290.73358, 290.89438, 290.90457, 290.98746,\n", + " 291.13034, 291.1794 , 291.2842 , 291.30426], dtype=float32)),\n", + " (array([ 43, 31, 19, 36, 32, 62, 69, 121, 118, 166], dtype=int32),\n", + " array([-19.948433, -19.865835, -19.767326, -19.715992, -19.686586,\n", + " -19.623251, -19.613674, -19.511026, -19.272453, -19.251122],\n", + " dtype=float32)),\n", + " (array([ 31, 43, 32, 19, 62, 268, 121, 120, 173, 164], dtype=int32),\n", + " array([310.11475, 310.49615, 310.5521 , 310.56354, 310.88065, 310.94458,\n", + " 311.0378 , 311.28223, 311.28406, 311.31076], dtype=float32)),\n", + " (array([ 31, 19, 606, 268, 164, 103, 29, 121, 24, 105], dtype=int32),\n", + " array([317.68994, 317.96915, 318.5397 , 318.62595, 318.64584, 318.66415,\n", + " 318.70285, 318.7048 , 318.7665 , 318.8746 ], dtype=float32)),\n", + " (array([ 31, 62, 121, 19, 268, 43, 120, 164, 214, 32], dtype=int32),\n", + " array([262.13736, 262.50522, 262.60654, 262.91647, 262.9387 , 262.94522,\n", + " 263.01373, 263.01846, 263.05392, 263.10217], dtype=float32)),\n", + " (array([ 43, 19, 62, 31, 32, 112, 148, 1137, 117, 121],\n", + " dtype=int32),\n", + " array([314.6324 , 314.9748 , 315.0158 , 315.05917, 315.0685 , 315.1134 ,\n", + " 315.20398, 315.21063, 315.22266, 315.25092], dtype=float32)),\n", + " (array([ 43, 32, 31, 149, 62, 8, 835, 305, 19, 255], dtype=int32),\n", + " array([317.45267, 317.56024, 317.86456, 317.92487, 318.19208, 318.31525,\n", + " 318.4304 , 318.4578 , 318.47083, 318.60315], dtype=float32)),\n", + " (array([ 32, 43, 31, 19, 121, 305, 62, 120, 86, 166], dtype=int32),\n", + " array([340.92197, 341.07843, 341.2549 , 341.26987, 341.57135, 341.644 ,\n", + " 341.64444, 341.79153, 341.84293, 341.89413], dtype=float32)),\n", + " (array([ 262, 1482, 153, 369, 149, 0, 1118, 2412, 718, 1],\n", + " dtype=int32),\n", + " array([-7.1548753, -6.9324064, -6.911993 , -6.759491 , -6.718952 ,\n", + " -6.7030196, -6.678854 , -6.6310854, -6.593932 , -6.5888405],\n", + " dtype=float32)),\n", + " (array([ 31, 43, 32, 62, 86, 19, 268, 255, 49, 258], dtype=int32),\n", + " array([341.9816 , 342.15033, 342.1702 , 342.173 , 342.22507, 342.36948,\n", + " 342.6958 , 342.78616, 342.80396, 342.80933], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 255, 268, 62, 358, 103, 120], dtype=int32),\n", + " array([288.07123, 288.49142, 288.733 , 288.738 , 289.01697, 289.03793,\n", + " 289.21478, 289.28265, 289.48224, 289.51526], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 186, 305, 121, 86, 29, 112], dtype=int32),\n", + " array([344.77808, 344.9268 , 345.0211 , 345.12537, 345.19983, 345.23236,\n", + " 345.34995, 345.38492, 345.52972, 345.55905], dtype=float32)),\n", + " (array([ 31, 19, 12, 121, 268, 32, 173, 21, 62, 86], dtype=int32),\n", + " array([242.72072, 243.02757, 243.07562, 243.29799, 243.47444, 243.50716,\n", + " 243.51355, 243.53151, 243.63689, 243.65224], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 121, 173, 29, 100, 62, 268], dtype=int32),\n", + " array([-1.7275019 , -1.5240912 , -1.5131664 , -1.302887 , -1.0184895 ,\n", + " -0.9363806 , -0.83797127, -0.7796087 , -0.7261653 , -0.58068794],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 43, 62, 121, 49, 120, 19, 240, 273], dtype=int32),\n", + " array([306.33493, 306.36124, 306.46613, 306.48672, 306.6366 , 306.75226,\n", + " 306.878 , 306.9205 , 306.9364 , 306.98468], dtype=float32)),\n", + " (array([ 43, 19, 32, 62, 31, 255, 86, 49, 121, 305], dtype=int32),\n", + " array([338.62006, 338.6211 , 338.85815, 339.0491 , 339.1276 , 339.22012,\n", + " 339.278 , 339.45724, 339.577 , 339.62994], dtype=float32)),\n", + " (array([ 43, 32, 62, 86, 279, 69, 31, 19, 36, 347], dtype=int32),\n", + " array([310.36154, 310.56738, 310.9095 , 310.92197, 310.9578 , 311.01923,\n", + " 311.08517, 311.0926 , 311.2108 , 311.3261 ], dtype=float32)),\n", + " (array([ 62, 43, 49, 19, 32, 69, 149, 36, 121, 31], dtype=int32),\n", + " array([306.1763 , 306.17786, 306.38458, 306.39423, 306.49142, 306.50192,\n", + " 306.55487, 306.70963, 306.71368, 306.77325], dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 32, 43, 240, 358, 105, 49], dtype=int32),\n", + " array([269.36642, 269.51428, 269.58096, 269.80392, 269.83282, 269.93283,\n", + " 270.1375 , 270.20126, 270.2353 , 270.26593], dtype=float32)),\n", + " (array([ 31, 19, 43, 29, 32, 121, 268, 255, 62, 105], dtype=int32),\n", + " array([258.56244, 258.65323, 259.31674, 259.44766, 259.45993, 259.5162 ,\n", + " 259.66318, 259.68094, 259.77652, 259.77942], dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 29, 268, 255, 12, 121, 62], dtype=int32),\n", + " array([304.15906, 304.51242, 304.56384, 305.05228, 305.09103, 305.18475,\n", + " 305.30072, 305.34534, 305.35364, 305.45563], dtype=float32)),\n", + " (array([ 31, 19, 62, 32, 43, 86, 255, 121, 173, 100], dtype=int32),\n", + " array([344.4151 , 344.68985, 344.75046, 344.78992, 344.79123, 344.85745,\n", + " 344.88364, 345.25653, 345.28488, 345.2936 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 29, 173, 120], dtype=int32),\n", + " array([242.73578, 242.77695, 243.25046, 243.3083 , 243.42842, 243.54744,\n", + " 243.61342, 243.84935, 243.86339, 243.86943], dtype=float32)),\n", + " (array([ 31, 121, 19, 103, 62, 12, 164, 268, 120, 43], dtype=int32),\n", + " array([267.23877, 267.92746, 268.0079 , 268.0668 , 268.13895, 268.27744,\n", + " 268.3579 , 268.37933, 268.37994, 268.40927], dtype=float32)),\n", + " (array([ 19, 32, 31, 121, 62, 49, 43, 392, 100, 186], dtype=int32),\n", + " array([299.38724, 299.5782 , 299.9818 , 299.98248, 300.07025, 300.1459 ,\n", + " 300.22537, 300.25055, 300.27667, 300.31436], dtype=float32)),\n", + " (array([ 43, 32, 62, 31, 19, 86, 36, 112, 69, 305], dtype=int32),\n", + " array([307.471 , 307.6228 , 307.91605, 307.96405, 307.9878 , 308.32446,\n", + " 308.32645, 308.41098, 308.4709 , 308.47647], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 255, 62, 342, 279, 86, 268], dtype=int32),\n", + " array([349.6414 , 349.76047, 349.80942, 349.84158, 350.01733, 350.15176,\n", + " 350.3185 , 350.3313 , 350.3726 , 350.50482], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 86, 100, 173, 268], dtype=int32),\n", + " array([51.6959 , 51.76991 , 52.026886, 52.168182, 52.248154, 52.29082 ,\n", + " 52.56731 , 52.63062 , 52.649 , 52.71079 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-4.979111 , -4.9550138, -4.4053645, -4.362955 , -4.347425 ,\n", + " -4.1834154, -4.1732507, -3.9843915, -3.946623 , -3.9122121],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", + " array([343.29697, 343.36044, 343.3889 , 343.4099 , 343.61017, 343.8627 ,\n", + " 344.0746 , 344.13998, 344.1806 , 344.19122], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", + " array([343.23718, 343.31253, 343.3428 , 343.3581 , 343.56107, 343.81424,\n", + " 344.0172 , 344.06387, 344.123 , 344.16122], dtype=float32)),\n", + " (array([ 19, 43, 2149, 32, 69, 279, 36, 62, 3738, 848],\n", + " dtype=int32),\n", + " array([281.35736, 281.57596, 281.74463, 281.86624, 282.01538, 282.01828,\n", + " 282.16446, 282.21942, 282.25064, 282.26828], dtype=float32)),\n", + " (array([ 31, 43, 19, 62, 32, 121, 173, 358, 268, 100], dtype=int32),\n", + " array([308.28625, 308.80652, 308.92523, 308.9867 , 309.12177, 309.32 ,\n", + " 309.37027, 309.45898, 309.54633, 309.56366], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 12, 268, 120, 121, 173], dtype=int32),\n", + " array([306.65912, 307.02588, 307.1139 , 307.16785, 307.45615, 307.5961 ,\n", + " 307.60892, 307.68198, 307.81 , 307.85135], dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 43, 62, 8, 173, 262, 100], dtype=int32),\n", + " array([-4.9612145, -4.7801676, -4.4426303, -4.362227 , -4.29175 ,\n", + " -4.232999 , -4.1409297, -4.1223755, -4.1110063, -3.9338346],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", + " array([310.42456, 310.54694, 310.79398, 310.86536, 311.01654, 311.1057 ,\n", + " 311.32666, 311.43158, 311.51782, 311.53967], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 268, 62, 120, 255, 164, 121], dtype=int32),\n", + " array([213.3347 , 213.55576, 213.58586, 213.88168, 214.03857, 214.15764,\n", + " 214.29588, 214.30124, 214.33507, 214.33618], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 268, 62, 105, 164, 29], dtype=int32),\n", + " array([289.43854, 289.73373, 289.78995, 289.80457, 289.96722, 290.09177,\n", + " 290.18765, 290.3794 , 290.43402, 290.46213], dtype=float32)),\n", + " (array([ 32, 31, 121, 19, 62, 43, 49, 120, 100, 105], dtype=int32),\n", + " array([259.71948, 259.7744 , 259.9528 , 260.16757, 260.21237, 260.21616,\n", + " 260.2609 , 260.31436, 260.42203, 260.53326], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 268, 62, 29, 120, 121, 100], dtype=int32),\n", + " array([341.1209 , 341.1635 , 341.37372, 341.50504, 341.74292, 341.90494,\n", + " 342.08875, 342.14835, 342.15802, 342.20963], dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 62, 100, 43, 173, 69, 86], dtype=int32),\n", + " array([262.8588 , 262.8746 , 263.1927 , 263.4276 , 263.54294, 263.59656,\n", + " 263.649 , 263.73904, 264.07852, 264.0804 ], dtype=float32)),\n", + " (array([ 69, 118, 36, 610, 370, 2314, 705, 559, 62, 32],\n", + " dtype=int32),\n", + " array([312.58954, 312.62265, 312.6653 , 312.7235 , 312.76132, 312.80417,\n", + " 312.84802, 312.89355, 312.90686, 312.90787], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 49, 120], dtype=int32),\n", + " array([341.39944, 341.51138, 341.5183 , 341.58606, 341.82016, 342.09595,\n", + " 342.28403, 342.29416, 342.31415, 342.46347], dtype=float32)),\n", + " (array([ 31, 8, 32, 43, 121, 19, 12, 62, 268, 21], dtype=int32),\n", + " array([346.1303 , 346.16727, 346.54965, 346.58475, 346.79022, 346.88788,\n", + " 346.984 , 347.08054, 347.128 , 347.177 ], dtype=float32)),\n", + " (array([ 43, 32, 19, 305, 16, 374, 188, 206, 116, 487], dtype=int32),\n", + " array([338.19223, 338.36545, 338.87158, 338.94052, 339.00848, 339.08832,\n", + " 339.11365, 339.114 , 339.13242, 339.13516], dtype=float32)),\n", + " (array([ 8, 31, 149, 262, 19, 62, 32, 450, 43, 121], dtype=int32),\n", + " array([347.69055, 347.8411 , 347.8882 , 348.03934, 348.10352, 348.2643 ,\n", + " 348.31277, 348.50272, 348.50607, 348.59665], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 173, 100, 268, 358], dtype=int32),\n", + " array([-14.646804 , -14.412246 , -14.14266 , -14.138294 , -14.106711 ,\n", + " -13.979977 , -13.71926 , -13.628071 , -13.555971 , -13.4387665],\n", + " dtype=float32)),\n", + " (array([ 21, 2310, 3162, 31, 19, 12, 1342, 121, 29, 32],\n", + " dtype=int32),\n", + " array([238.73308, 240.39923, 240.75497, 240.90102, 241.0412 , 241.18866,\n", + " 241.24402, 241.51207, 241.59366, 241.80627], dtype=float32)),\n", + " (array([ 43, 515, 19, 32, 16, 374, 554, 848, 188, 279], dtype=int32),\n", + " array([342.71136, 343.1832 , 343.19052, 343.19534, 343.20126, 343.24042,\n", + " 343.29156, 343.3497 , 343.4364 , 343.48505], dtype=float32)),\n", + " (array([ 31, 32, 43, 149, 19, 62, 8, 121, 49, 450], dtype=int32),\n", + " array([283.5595 , 283.77426, 283.77997, 283.8146 , 283.83728, 283.87344,\n", + " 284.04135, 284.04156, 284.35785, 284.42798], dtype=float32)),\n", + " (array([ 31, 19, 32, 268, 29, 43, 121, 173, 255, 105], dtype=int32),\n", + " array([299.0837 , 299.1339 , 299.43283, 299.78424, 299.8547 , 300.03534,\n", + " 300.08292, 300.1606 , 300.24152, 300.32138], dtype=float32)),\n", + " (array([ 31, 32, 19, 268, 43, 62, 358, 120, 103, 61], dtype=int32),\n", + " array([342.61774, 343.27478, 343.2961 , 343.42096, 343.42343, 343.58167,\n", + " 343.6629 , 343.7414 , 343.77548, 343.8112 ], dtype=float32)),\n", + " (array([ 32, 31, 121, 19, 62, 43, 100, 186, 49, 86], dtype=int32),\n", + " array([355.4569 , 355.8592 , 355.93353, 355.93823, 355.9482 , 356.00153,\n", + " 356.1481 , 356.21353, 356.3256 , 356.39185], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", + " array([-5.1433115, -5.1157713, -4.5936127, -4.5406837, -4.5201755,\n", + " -4.3485184, -4.339273 , -4.1452084, -4.127272 , -4.0926104],\n", + " dtype=float32)),\n", + " (array([ 31, 121, 103, 62, 19, 164, 61, 268, 12, 26], dtype=int32),\n", + " array([311.42325, 312.13174, 312.30154, 312.39053, 312.48926, 312.49576,\n", + " 312.57397, 312.738 , 312.74075, 312.7748 ], dtype=float32)),\n", + " (array([262, 8, 149, 32, 369, 31, 450, 539, 19, 153], dtype=int32),\n", + " array([347.69144, 348.17166, 348.2773 , 348.47375, 348.53668, 348.55157,\n", + " 348.7064 , 348.72144, 348.73053, 348.74356], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 29, 121, 62, 100, 268, 164], dtype=int32),\n", + " array([315.89035, 316.10223, 316.16382, 316.4929 , 316.6669 , 316.69183,\n", + " 316.76526, 316.79224, 316.82556, 316.92404], dtype=float32)),\n", + " (array([ 19, 31, 173, 43, 62, 32, 358, 884, 121, 258], dtype=int32),\n", + " array([-13.631014 , -13.378326 , -13.223921 , -13.188473 , -13.166518 ,\n", + " -13.1101885, -12.999098 , -12.868977 , -12.817447 , -12.8084345],\n", + " dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 86, 62, 255, 268, 120, 121], dtype=int32),\n", + " array([263.09036, 263.4136 , 263.59818, 263.66516, 263.6681 , 263.76868,\n", + " 263.94824, 264.07617, 264.0932 , 264.09454], dtype=float32)),\n", + " (array([ 31, 19, 32, 62, 121, 43, 268, 100, 173, 255], dtype=int32),\n", + " array([328.3551 , 328.8731 , 329.07007, 329.23672, 329.2658 , 329.44565,\n", + " 329.59674, 329.67 , 329.74203, 329.76917], dtype=float32)),\n", + " (array([ 32, 43, 19, 305, 31, 62, 100, 29, 111, 121], dtype=int32),\n", + " array([-12.457048, -12.43791 , -12.421761, -12.015521, -11.927298,\n", + " -11.577796, -11.539209, -11.532851, -11.499116, -11.43843 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 120, 62, 268, 305, 255, 121], dtype=int32),\n", + " array([-33.522846, -33.35556 , -33.35172 , -33.176304, -32.79467 ,\n", + " -32.72199 , -32.487892, -32.325 , -32.307495, -32.285484],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 268, 121, 62, 29, 100, 105], dtype=int32),\n", + " array([262.2224 , 262.45544, 262.48013, 262.49313, 262.9379 , 262.99268,\n", + " 263.04614, 263.12292, 263.18018, 263.23492], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 69, 121, 36, 166, 14], dtype=int32),\n", + " array([300.52008, 300.70404, 300.8778 , 300.88055, 301.04742, 301.20938,\n", + " 301.21463, 301.33365, 301.36942, 301.41553], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 62, 43, 186, 268, 86, 100], dtype=int32),\n", + " array([312.77646, 312.87463, 312.89346, 313.0386 , 313.0813 , 313.1837 ,\n", + " 313.34357, 313.42975, 313.43936, 313.44275], dtype=float32)),\n", + " (array([ 31, 86, 43, 19, 62, 255, 32, 121, 268, 75], dtype=int32),\n", + " array([313.66043, 314.0197 , 314.13065, 314.2153 , 314.24585, 314.24954,\n", + " 314.29016, 314.6327 , 314.7106 , 314.7574 ], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 173, 62, 100, 86, 43, 29], dtype=int32),\n", + " array([274.8936 , 275.26773, 275.46094, 275.56436, 275.83417, 275.84564,\n", + " 275.8754 , 276.07532, 276.08908, 276.19504], dtype=float32)),\n", + " (array([ 31, 43, 19, 149, 32, 62, 121, 8, 262, 347], dtype=int32),\n", + " array([347.80334, 347.97336, 348.00525, 348.03125, 348.03476, 348.49036,\n", + " 348.49118, 348.57654, 348.62436, 348.6504 ], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 121, 305, 49, 268, 29, 62], dtype=int32),\n", + " array([307.99734, 308.1842 , 308.20193, 308.31244, 308.43607, 308.5341 ,\n", + " 308.56073, 308.6038 , 308.6299 , 308.64676], dtype=float32)),\n", + " (array([ 19, 31, 173, 12, 121, 32, 62, 100, 29, 43], dtype=int32),\n", + " array([354.41293, 354.57666, 354.9651 , 355.146 , 355.18665, 355.37982,\n", + " 355.63208, 355.6957 , 355.74042, 355.82388], dtype=float32)),\n", + " (array([ 19, 31, 43, 62, 358, 121, 164, 32, 268, 173], dtype=int32),\n", + " array([285.0124 , 285.25577, 285.52927, 285.59317, 285.63513, 285.77396,\n", + " 285.87573, 285.9841 , 286.0442 , 286.08023], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.843 , 345.07404, 345.21347, 345.29462, 345.3463 , 345.5088 ,\n", + " 345.7224 , 345.838 , 345.9285 , 346.00266], dtype=float32)),\n", + " (array([ 19, 31, 121, 43, 173, 62, 100, 32, 268, 105], dtype=int32),\n", + " array([-10.287987, -10.105809, -9.772382, -9.640942, -9.61024 ,\n", + " -9.515656, -9.498697, -9.477242, -9.016497, -8.99341 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 173, 29, 268, 121, 62, 100], dtype=int32),\n", + " array([-4.2063303, -3.8578374, -3.5531025, -3.1375096, -3.1287026,\n", + " -2.9719126, -2.9412744, -2.8817208, -2.7690904, -2.7398794],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 49, 86], dtype=int32),\n", + " array([308.78714, 308.83017, 308.8848 , 308.9159 , 309.2116 , 309.39853,\n", + " 309.61646, 309.62625, 309.71777, 309.71957], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 358, 39, 62, 268, 636, 173], dtype=int32),\n", + " array([344.2082 , 344.44357, 344.57022, 344.61343, 344.8598 , 344.89172,\n", + " 344.89838, 344.961 , 345.0495 , 345.12665], dtype=float32)),\n", + " (array([ 31, 62, 121, 61, 19, 32, 43, 100, 268, 103], dtype=int32),\n", + " array([284.41235, 285.0468 , 285.10342, 285.1888 , 285.2465 , 285.44226,\n", + " 285.45752, 285.51245, 285.5827 , 285.6653 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 105, 268, 120, 86], dtype=int32),\n", + " array([348.055 , 348.26694, 348.52545, 348.58893, 348.59067, 348.61887,\n", + " 348.7269 , 348.77472, 348.99243, 348.99518], dtype=float32)),\n", + " (array([ 19, 31, 43, 62, 121, 32, 164, 100, 173, 268], dtype=int32),\n", + " array([342.90494, 343.1901 , 343.25708, 343.40213, 343.50107, 343.58203,\n", + " 343.82745, 343.87393, 343.9245 , 343.95386], dtype=float32)),\n", + " (array([ 19, 43, 32, 279, 31, 69, 258, 166, 36, 62], dtype=int32),\n", + " array([264.77603, 264.8024 , 264.95255, 265.18588, 265.31503, 265.36118,\n", + " 265.41092, 265.42535, 265.48685, 265.5153 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 120, 103, 164], dtype=int32),\n", + " array([340.2276 , 340.7527 , 340.8746 , 340.93317, 341.01257, 341.2328 ,\n", + " 341.33353, 341.3753 , 341.41675, 341.65338], dtype=float32)),\n", + " (array([ 19, 43, 32, 258, 173, 62, 805, 176, 374, 100], dtype=int32),\n", + " array([311.01227, 311.25955, 311.42825, 311.71817, 311.77762, 311.88116,\n", + " 311.92047, 311.97552, 312.0079 , 312.08768], dtype=float32)),\n", + " (array([ 884, 19, 2181, 3209, 1959, 43, 358, 636, 805, 521],\n", + " dtype=int32),\n", + " array([317.77435, 317.89914, 318.00345, 318.1425 , 318.15417, 318.23245,\n", + " 318.24258, 318.2771 , 318.31848, 318.32968], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 268, 173, 121, 164, 8], dtype=int32),\n", + " array([321.84604, 322.24774, 322.3098 , 322.49057, 322.5661 , 322.82 ,\n", + " 322.8759 , 322.97394, 323.00183, 323.12778], dtype=float32)),\n", + " (array([ 43, 32, 31, 62, 8, 121, 100, 19, 86, 268], dtype=int32),\n", + " array([342.02063, 342.0747 , 342.36108, 342.45218, 342.62222, 342.69666,\n", + " 342.75436, 342.82074, 342.86224, 342.90573], dtype=float32)),\n", + " (array([ 31, 8, 19, 121, 262, 450, 32, 62, 149, 36], dtype=int32),\n", + " array([-13.384605 , -12.933238 , -12.895946 , -12.8417425, -12.780468 ,\n", + " -12.738579 , -12.718014 , -12.675237 , -12.653876 , -12.532298 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([312.41382, 312.62598, 312.84418, 312.9323 , 312.9963 , 313.04727,\n", + " 313.29303, 313.4334 , 313.48193, 313.49994], dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 31, 121, 86, 100, 173, 49], dtype=int32),\n", + " array([277.56442, 277.59464, 277.62943, 277.69528, 277.70322, 278.0039 ,\n", + " 278.16898, 278.20297, 278.28183, 278.33792], dtype=float32)),\n", + " (array([ 43, 69, 279, 36, 19, 62, 32, 974, 258, 118], dtype=int32),\n", + " array([308.372 , 308.47812, 308.52005, 308.6522 , 308.75067, 308.8355 ,\n", + " 308.88028, 308.93564, 308.99506, 309.09064], dtype=float32)),\n", + " (array([ 19, 31, 32, 62, 43, 173, 121, 100, 8, 36], dtype=int32),\n", + " array([319.52982, 319.66534, 319.72327, 319.7336 , 319.74808, 319.78607,\n", + " 319.8202 , 320.0999 , 320.202 , 320.25818], dtype=float32)),\n", + " (array([1556, 31, 43, 19, 57, 69, 32, 212, 62, 36],\n", + " dtype=int32),\n", + " array([343.5553 , 343.64545, 343.71744, 343.8603 , 343.92123, 343.9694 ,\n", + " 343.99402, 344.02194, 344.03406, 344.08356], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 62, 29, 164, 86, 374, 49], dtype=int32),\n", + " array([-13.599033, -13.482429, -13.482097, -13.272527, -13.083915,\n", + " -12.931248, -12.923155, -12.909886, -12.809618, -12.802147],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 255, 268, 100, 86], dtype=int32),\n", + " array([-15.301536, -15.298448, -14.989493, -14.883555, -14.797832,\n", + " -14.693052, -14.636348, -14.392767, -14.36642 , -14.306731],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 173, 268, 100, 12], dtype=int32),\n", + " array([235.15862, 235.27525, 235.70685, 235.83282, 235.83704, 235.8743 ,\n", + " 235.9079 , 236.21094, 236.30933, 236.30952], dtype=float32)),\n", + " (array([ 43, 32, 62, 31, 19, 36, 8, 262, 279, 449], dtype=int32),\n", + " array([339.57626, 339.60147, 339.67606, 339.90118, 339.93845, 340.00714,\n", + " 340.00854, 340.08844, 340.21445, 340.2476 ], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 29, 305, 111, 121, 186, 105], dtype=int32),\n", + " array([320.27344, 320.60013, 320.6929 , 320.81845, 320.8795 , 320.9046 ,\n", + " 321.0976 , 321.09933, 321.22202, 321.2398 ], dtype=float32)),\n", + " (array([149, 43, 32, 262, 8, 62, 31, 19, 369, 36], dtype=int32),\n", + " array([305.47174, 305.62546, 305.62726, 305.66144, 305.78976, 305.8769 ,\n", + " 306.1171 , 306.1323 , 306.1441 , 306.18814], dtype=float32)),\n", + " (array([ 31, 62, 19, 121, 32, 268, 43, 49, 100, 8], dtype=int32),\n", + " array([344.3326 , 344.5726 , 344.66858, 344.8783 , 344.97528, 345.13107,\n", + " 345.14734, 345.17825, 345.28094, 345.29416], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-5.030628 , -5.0019164, -4.4487867, -4.3988233, -4.3920665,\n", + " -4.2199664, -4.2096925, -4.0110087, -3.9966905, -3.9498527],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 62, 32, 121, 12, 173, 100, 268], dtype=int32),\n", + " array([306.87115, 307.20834, 307.53104, 307.67474, 307.69324, 307.80725,\n", + " 307.92273, 307.95023, 308.16998, 308.32336], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([312.3017 , 312.49252, 312.70438, 312.80276, 312.8629 , 312.93243,\n", + " 313.17148, 313.30807, 313.35947, 313.36423], dtype=float32)),\n", + " (array([ 31, 121, 62, 19, 32, 103, 43, 268, 120, 49], dtype=int32),\n", + " array([-13.6003685, -13.386892 , -13.048842 , -12.978064 , -12.923302 ,\n", + " -12.832489 , -12.824678 , -12.782839 , -12.6638775, -12.607466 ],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 305, 31, 86, 49, 121, 268], dtype=int32),\n", + " array([343.1129 , 343.18115, 343.65753, 343.69788, 343.74188, 343.80005,\n", + " 344.05627, 344.16516, 344.18304, 344.1946 ], dtype=float32)),\n", + " (array([ 32, 31, 19, 62, 43, 49, 121, 304, 392, 441], dtype=int32),\n", + " array([293.79663, 293.808 , 294.14117, 294.2369 , 294.32822, 294.4335 ,\n", + " 294.45523, 294.47296, 294.47522, 294.52142], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 305, 166, 105, 121, 29, 62], dtype=int32),\n", + " array([303.94208, 304.10236, 304.21732, 304.29514, 304.48364, 304.60992,\n", + " 304.64877, 304.66302, 304.72363, 304.80734], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 62, 103, 43, 120, 268, 29], dtype=int32),\n", + " array([324.24326, 324.92114, 325.0366 , 325.07632, 325.27628, 325.46164,\n", + " 325.48834, 325.5086 , 325.55966, 325.71478], dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 12, 62, 121, 100, 29, 86], dtype=int32),\n", + " array([312.144 , 312.32962, 312.40576, 312.41193, 312.512 , 312.65973,\n", + " 312.67947, 312.70682, 312.88577, 312.99625], dtype=float32)),\n", + " (array([ 31, 12, 121, 19, 103, 29, 62, 268, 32, 173], dtype=int32),\n", + " array([356.6274 , 357.15707, 357.2626 , 357.52145, 357.6411 , 357.66452,\n", + " 357.90305, 357.9458 , 357.9567 , 357.96454], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 121, 62, 173, 164, 268, 487], dtype=int32),\n", + " array([-15.974582, -15.666498, -15.412963, -15.252548, -15.121224,\n", + " -15.10663 , -15.050113, -14.948169, -14.908808, -14.836789],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 29, 12, 32, 121, 173, 43, 24, 100], dtype=int32),\n", + " array([263.34613, 263.51138, 263.9186 , 263.95224, 263.96582, 264.22995,\n", + " 264.37097, 264.44342, 264.46033, 264.51242], dtype=float32)),\n", + " (array([ 31, 32, 43, 149, 8, 62, 120, 262, 19, 121], dtype=int32),\n", + " array([315.63965, 315.77344, 315.84247, 315.9835 , 316.10825, 316.12128,\n", + " 316.34576, 316.4581 , 316.46384, 316.51608], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 121, 62, 100, 69, 36, 279], dtype=int32),\n", + " array([314.47702, 314.5665 , 314.6491 , 314.72476, 314.8577 , 314.9262 ,\n", + " 315.13724, 315.17795, 315.35522, 315.39377], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.85538, 345.09045, 345.2382 , 345.32623, 345.37555, 345.53754,\n", + " 345.74594, 345.86102, 345.94952, 346.03363], dtype=float32)),\n", + " (array([ 241, 1801, 0, 149, 8, 735, 262, 1619, 31, 552],\n", + " dtype=int32),\n", + " array([349.5574 , 349.63638, 349.97824, 350.0328 , 350.04977, 350.07266,\n", + " 350.08963, 350.15094, 350.15662, 350.1782 ], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 268, 29, 255, 62, 121, 100], dtype=int32),\n", + " array([265.5091 , 265.5642 , 265.65613, 266.2193 , 266.36572, 266.48993,\n", + " 266.49915, 266.52814, 266.66528, 266.68976], dtype=float32)),\n", + " (array([ 31, 19, 12, 121, 43, 173, 62, 32, 120, 29], dtype=int32),\n", + " array([262.91986, 263.21686, 263.73962, 263.97925, 264.0152 , 264.0359 ,\n", + " 264.17685, 264.2683 , 264.29852, 264.37872], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 121, 62, 268, 49, 105, 173], dtype=int32),\n", + " array([251.75104, 252.46007, 252.4919 , 252.58513, 252.59534, 252.77249,\n", + " 252.80959, 252.81326, 252.90184, 252.91351], dtype=float32)),\n", + " (array([ 32, 31, 62, 121, 43, 49, 19, 100, 8, 273], dtype=int32),\n", + " array([286.7004 , 286.71283, 286.79346, 286.84265, 286.9828 , 286.9923 ,\n", + " 287.05884, 287.18152, 287.4453 , 287.45245], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 121, 268, 120, 173, 100], dtype=int32),\n", + " array([265.86395, 265.94437, 266.0512 , 266.32397, 266.50363, 266.5054 ,\n", + " 266.52643, 266.694 , 266.80252, 266.91312], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 268, 49, 100, 173], dtype=int32),\n", + " array([191.912 , 192.11353, 192.17426, 192.3201 , 192.5034 , 192.50595,\n", + " 192.80835, 192.9418 , 192.94662, 192.96214], dtype=float32)),\n", + " (array([ 31, 62, 19, 32, 43, 121, 268, 173, 358, 86], dtype=int32),\n", + " array([316.61246, 316.8937 , 317.03522, 317.10895, 317.16156, 317.32007,\n", + " 317.4309 , 317.45554, 317.51773, 317.61896], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 173, 268, 255, 164], dtype=int32),\n", + " array([324.2678 , 324.6414 , 324.92496, 325.05038, 325.22757, 325.33405,\n", + " 325.51355, 325.52933, 325.6598 , 325.7187 ], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 32, 103, 173, 100, 120, 61], dtype=int32),\n", + " array([317.34003, 317.92337, 318.01788, 318.20483, 318.36285, 318.4596 ,\n", + " 318.46072, 318.6423 , 318.69638, 318.69836], dtype=float32)),\n", + " (array([ 19, 31, 121, 43, 32, 62, 105, 100, 49, 268], dtype=int32),\n", + " array([325.82996, 325.9826 , 326.0693 , 326.28937, 326.31818, 326.40656,\n", + " 326.45306, 326.5878 , 326.66626, 326.75858], dtype=float32)),\n", + " (array([ 43, 149, 62, 36, 32, 240, 31, 69, 330, 8], dtype=int32),\n", + " array([338.58038, 338.77115, 338.88443, 338.92017, 338.95306, 339.01016,\n", + " 339.05963, 339.0873 , 339.08765, 339.09525], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 121, 100, 173, 29, 86], dtype=int32),\n", + " array([285.2647 , 285.46994, 285.58875, 285.7844 , 286.05826, 286.20993,\n", + " 286.34903, 286.3741 , 286.48764, 286.52768], dtype=float32)),\n", + " (array([ 43, 62, 32, 36, 19, 31, 25, 69, 279, 449], dtype=int32),\n", + " array([340.97354, 341.146 , 341.38815, 341.57764, 341.58575, 341.61063,\n", + " 341.71463, 341.74915, 341.80667, 341.82574], dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 121, 62, 100, 49, 8, 173], dtype=int32),\n", + " array([-14.669187 , -14.600939 , -14.571131 , -14.505507 , -14.470985 ,\n", + " -14.393481 , -14.244798 , -14.005135 , -13.9285145, -13.909489 ],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 31, 32, 62, 149, 279, 173, 206, 121], dtype=int32),\n", + " array([349.6084 , 349.84772, 349.8697 , 349.9277 , 349.9692 , 350.07477,\n", + " 350.1816 , 350.27115, 350.27704, 350.38074], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 121, 186, 86, 49, 487], dtype=int32),\n", + " array([288.5658 , 288.70242, 288.7197 , 288.81473, 288.93903, 289.13483,\n", + " 289.25507, 289.34436, 289.3612 , 289.4463 ], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 121, 305, 62, 100, 173, 206], dtype=int32),\n", + " array([-11.456671, -11.446159, -11.423652, -11.416996, -11.064107,\n", + " -10.844979, -10.813096, -10.770634, -10.702918, -10.699669],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 31, 32, 62, 86, 100, 121, 49, 279], dtype=int32),\n", + " array([268.95468, 269.01685, 269.22226, 269.24066, 269.26004, 269.29535,\n", + " 269.38977, 269.43176, 269.53998, 269.55698], dtype=float32)),\n", + " (array([ 19, 31, 62, 32, 149, 43, 121, 173, 735, 347], dtype=int32),\n", + " array([215.332 , 215.37314, 215.48581, 215.62888, 215.64783, 215.65305,\n", + " 215.65874, 215.69524, 215.79202, 215.79424], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 262, 8, 255, 62, 12, 268], dtype=int32),\n", + " array([141.59251, 141.83751, 142.13933, 142.16425, 142.16447, 142.30437,\n", + " 142.30954, 142.45528, 142.49702, 142.51967], dtype=float32)),\n", + " (array([ 19, 31, 62, 173, 358, 32, 2181, 8, 884, 636],\n", + " dtype=int32),\n", + " array([352.74274, 353.2657 , 353.33234, 353.3576 , 353.39316, 353.40036,\n", + " 353.46933, 353.5422 , 353.56155, 353.6238 ], dtype=float32)),\n", + " (array([ 43, 19, 32, 188, 848, 206, 579, 112, 487, 226], dtype=int32),\n", + " array([338.15225, 338.45187, 338.524 , 338.7841 , 338.79407, 338.8417 ,\n", + " 338.90436, 338.92407, 338.93015, 338.952 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 255, 29, 121, 268, 62, 103, 105], dtype=int32),\n", + " array([300.31522, 300.37778, 300.79977, 301.11166, 301.12476, 301.15967,\n", + " 301.2287 , 301.36957, 301.4229 , 301.50925], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 268, 62, 12, 358, 121, 173], dtype=int32),\n", + " array([-15.175397 , -14.3523035, -14.324574 , -14.270303 , -13.996518 ,\n", + " -13.875429 , -13.867051 , -13.852484 , -13.790112 , -13.669666 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 121, 12, 32, 62, 173, 43, 268, 61], dtype=int32),\n", + " array([263.42712, 263.563 , 263.93036, 264.00702, 264.38058, 264.47498,\n", + " 264.50125, 264.52225, 264.5853 , 264.61554], dtype=float32)),\n", + " (array([ 32, 43, 305, 112, 186, 31, 554, 19, 62, 111], dtype=int32),\n", + " array([337.35098, 337.5314 , 337.86545, 337.91376, 337.94345, 337.94797,\n", + " 337.99365, 338.01077, 338.05304, 338.0803 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 173, 121, 100, 268, 149], dtype=int32),\n", + " array([273.55392, 273.77774, 273.83148, 273.8362 , 274.25946, 274.31317,\n", + " 274.32834, 274.46176, 274.5391 , 274.8087 ], dtype=float32)),\n", + " (array([ 31, 19, 173, 12, 62, 121, 32, 43, 268, 86], dtype=int32),\n", + " array([349.18506, 349.31424, 349.6772 , 349.79327, 349.91583, 349.93066,\n", + " 349.94504, 349.95108, 350.343 , 350.40012], dtype=float32)),\n", + " (array([ 552, 539, 0, 149, 965, 3146, 31, 1784, 262, 287],\n", + " dtype=int32),\n", + " array([317.1727 , 317.24374, 317.55713, 317.73663, 317.86557, 317.89526,\n", + " 317.91296, 317.91867, 317.9318 , 317.97437], dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 121, 62, 100, 268, 305, 49], dtype=int32),\n", + " array([314.1853 , 314.31137, 314.42017, 314.44604, 314.57455, 314.77603,\n", + " 314.8114 , 315.02228, 315.10776, 315.1962 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 358, 62, 173, 258, 268, 884], dtype=int32),\n", + " array([347.45734, 347.50494, 347.7619 , 347.82605, 347.98862, 348.14484,\n", + " 348.20886, 348.3074 , 348.32352, 348.42862], dtype=float32)),\n", + " (array([ 19, 32, 62, 31, 121, 43, 173, 268, 100, 8], dtype=int32),\n", + " array([314.78854, 314.91577, 315.16824, 315.24203, 315.32956, 315.36145,\n", + " 315.4264 , 315.52505, 315.65732, 315.69305], dtype=float32)),\n", + " (array([ 32, 19, 305, 43, 31, 188, 528, 69, 204, 226], dtype=int32),\n", + " array([259.37012, 259.38394, 259.40344, 259.46835, 259.77426, 259.87195,\n", + " 259.94037, 260.0137 , 260.05203, 260.1233 ], dtype=float32)),\n", + " (array([ 62, 31, 19, 43, 49, 121, 149, 164, 32, 8], dtype=int32),\n", + " array([338.4056 , 338.77094, 338.81546, 338.83694, 338.95892, 338.99554,\n", + " 339.017 , 339.05597, 339.2428 , 339.24435], dtype=float32)),\n", + " (array([176, 358, 884, 43, 62, 258, 32, 19, 636, 39], dtype=int32),\n", + " array([284.36417, 284.5536 , 284.56604, 284.6107 , 284.7576 , 284.7714 ,\n", + " 284.8168 , 284.82672, 284.87845, 284.9858 ], dtype=float32)),\n", + " (array([1812, 149, 996, 2035, 153, 489, 1482, 1161, 1118, 8],\n", + " dtype=int32),\n", + " array([-7.017111 , -6.8244452, -6.722717 , -6.7156744, -6.6452174,\n", + " -6.567884 , -6.5333624, -6.4514637, -6.36349 , -6.3416147],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 49, 121, 204, 36, 279], dtype=int32),\n", + " array([42.485863, 42.780212, 42.81112 , 42.90133 , 42.978966, 43.1729 ,\n", + " 43.2377 , 43.30827 , 43.372684, 43.37734 ], dtype=float32)),\n", + " (array([ 31, 19, 12, 121, 32, 43, 29, 100, 62, 86], dtype=int32),\n", + " array([-3.692336 , -3.453667 , -3.2474349, -3.2135587, -3.1679478,\n", + " -3.0567408, -3.0422711, -3.0117793, -2.943595 , -2.8708534],\n", + " dtype=float32)),\n", + " (array([ 31, 43, 62, 19, 32, 164, 268, 86, 121, 358], dtype=int32),\n", + " array([306.2654 , 306.33945, 306.4547 , 306.52942, 306.597 , 306.75366,\n", + " 306.84937, 306.86676, 306.8713 , 306.95096], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 166, 358, 62, 204, 258, 268], dtype=int32),\n", + " array([296.3471 , 296.37015, 296.55472, 296.5801 , 296.78766, 296.7985 ,\n", + " 296.87164, 296.8785 , 296.90323, 297.0874 ], dtype=float32)),\n", + " (array([ 149, 735, 965, 19, 0, 552, 262, 8, 31, 1419],\n", + " dtype=int32),\n", + " array([226.01115, 226.10297, 226.1076 , 226.23538, 226.2463 , 226.272 ,\n", + " 226.32721, 226.34567, 226.43701, 226.45033], dtype=float32)),\n", + " (array([ 31, 32, 43, 62, 19, 121, 29, 112, 120, 268], dtype=int32),\n", + " array([344.2748 , 344.44553, 344.52036, 344.72614, 344.80002, 344.90756,\n", + " 344.9791 , 345.01923, 345.11835, 345.192 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 32, 43, 100, 49, 268, 164], dtype=int32),\n", + " array([342.22598, 342.40228, 342.4085 , 342.45544, 342.51126, 342.6811 ,\n", + " 342.8479 , 342.86078, 342.99628, 343.0427 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 105], dtype=int32),\n", + " array([287.51895, 287.61398, 288.0591 , 288.0906 , 288.18866, 288.2007 ,\n", + " 288.51242, 288.524 , 288.70685, 288.716 ], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 62, 173, 121, 305, 268, 374], dtype=int32),\n", + " array([-21.612953, -21.52249 , -21.452255, -21.379147, -21.043661,\n", + " -20.812916, -20.806978, -20.763453, -20.695934, -20.628233],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 32, 43, 173, 268, 61, 358], dtype=int32),\n", + " array([317.82678, 318.26996, 318.60562, 318.65625, 318.7585 , 318.80792,\n", + " 318.8308 , 318.87646, 318.8963 , 318.994 ], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 350, 305, 69, 279, 36], dtype=int32),\n", + " array([343.07288, 343.14206, 343.69296, 343.73373, 343.79886, 343.92645,\n", + " 343.9273 , 343.93744, 343.94446, 343.9494 ], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 268, 255, 487, 42, 805], dtype=int32),\n", + " array([-13.988481 , -13.837422 , -13.704304 , -13.344196 , -13.2673645,\n", + " -13.18387 , -13.172173 , -13.1523285, -13.090306 , -13.086044 ],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 121, 86, 120, 100, 268], dtype=int32),\n", + " array([307.9327 , 308.0714 , 308.10782, 308.20166, 308.48843, 308.88086,\n", + " 308.99414, 309.06448, 309.07455, 309.17303], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 121, 29, 100, 173, 268], dtype=int32),\n", + " array([351.5901 , 351.73917, 351.76743, 352.157 , 352.19598, 352.3126 ,\n", + " 352.45346, 352.4693 , 352.4991 , 352.51056], dtype=float32)),\n", + " (array([ 43, 32, 31, 62, 19, 149, 36, 255, 112, 86], dtype=int32),\n", + " array([316.7614 , 316.99316, 317.07388, 317.26318, 317.48212, 317.56055,\n", + " 317.66666, 317.669 , 317.67285, 317.70544], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-5.0741687, -5.0485473, -4.509162 , -4.445554 , -4.4442058,\n", + " -4.273513 , -4.263999 , -4.065134 , -4.0441136, -4.0163875],\n", + " dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 62, 173, 121, 268, 100, 29], dtype=int32),\n", + " array([343.76868, 343.84 , 343.91858, 344.00677, 344.29614, 344.72903,\n", + " 344.73883, 344.74832, 344.7669 , 344.79733], dtype=float32)),\n", + " (array([ 43, 19, 31, 550, 62, 32, 100, 121, 8, 149], dtype=int32),\n", + " array([53.205914, 53.22059 , 53.28345 , 53.303814, 53.348705, 53.40988 ,\n", + " 53.53761 , 53.585125, 53.77041 , 53.851917], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 105, 268, 173, 358], dtype=int32),\n", + " array([-15.890402, -15.684281, -15.52024 , -15.095209, -15.063954,\n", + " -14.951069, -14.567852, -14.562141, -14.548413, -14.498462],\n", + " dtype=float32)),\n", + " (array([ 32, 31, 19, 43, 121, 29, 62, 305, 100, 268], dtype=int32),\n", + " array([265.64688, 265.69025, 265.89487, 266.02777, 266.2306 , 266.38507,\n", + " 266.44272, 266.5225 , 266.659 , 266.6969 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 29, 268, 62, 441, 103], dtype=int32),\n", + " array([287.11838, 287.34442, 287.65036, 287.82922, 287.90732, 287.91147,\n", + " 287.92307, 288.0329 , 288.13937, 288.15973], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 69, 36, 279, 206, 449], dtype=int32),\n", + " array([311.03232, 311.06607, 311.26587, 311.70935, 311.75217, 311.75443,\n", + " 311.77985, 311.86707, 311.9017 , 311.9381 ], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 120, 305, 62, 121, 371, 49], dtype=int32),\n", + " array([308.45367, 308.49292, 308.61252, 308.7293 , 308.93237, 309.00485,\n", + " 309.08548, 309.09116, 309.10516, 309.23346], dtype=float32)),\n", + " (array([ 31, 19, 62, 32, 121, 43, 100, 173, 268, 214], dtype=int32),\n", + " array([-10.341681, -10.104004, -9.997879, -9.942418, -9.884092,\n", + " -9.841873, -9.751417, -9.676609, -9.173783, -9.16163 ],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 69, 62, 121, 279, 100, 1088],\n", + " dtype=int32),\n", + " array([302.63937, 302.90488, 303.10846, 303.1919 , 303.20636, 303.25427,\n", + " 303.28244, 303.33725, 303.3611 , 303.377 ], dtype=float32)),\n", + " (array([ 32, 241, 43, 31, 149, 19, 8, 262, 62, 100], dtype=int32),\n", + " array([310.07986, 310.12897, 310.22546, 310.24493, 310.3166 , 310.32654,\n", + " 310.52274, 310.53534, 310.72757, 310.9148 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 12, 29, 121, 21, 105, 268, 62], dtype=int32),\n", + " array([356.68155, 357.3134 , 357.53873, 357.7081 , 357.7115 , 357.77197,\n", + " 357.82104, 357.83554, 357.895 , 357.9584 ], dtype=float32)),\n", + " (array([ 19, 32, 31, 173, 255, 43, 62, 121, 86, 100], dtype=int32),\n", + " array([-17.402403, -16.974453, -16.948748, -16.725214, -16.715353,\n", + " -16.714073, -16.631855, -16.513857, -16.409714, -16.278208],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 29, 43, 32, 121, 268, 173, 100, 24], dtype=int32),\n", + " array([-4.2243953, -4.126679 , -3.6223252, -3.6113648, -3.6087067,\n", + " -3.3742836, -3.2807965, -3.2385452, -3.1359859, -3.1099405],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 43, 62, 19, 49, 121, 304, 384, 392], dtype=int32),\n", + " array([303.59982, 303.61542, 303.75247, 303.87396, 304.1185 , 304.11853,\n", + " 304.14862, 304.3223 , 304.32532, 304.41406], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 100, 86, 268, 173], dtype=int32),\n", + " array([-8.085493 , -7.7274246, -7.6989603, -7.6576977, -7.4381723,\n", + " -7.424794 , -7.165704 , -7.1038136, -7.059535 , -7.045127 ],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 86, 121, 347, 112, 8], dtype=int32),\n", + " array([-12.746703, -12.741758, -12.736581, -12.565916, -12.34575 ,\n", + " -12.180504, -12.031655, -11.946743, -11.930024, -11.921896],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 255, 62, 121, 120, 268, 258], dtype=int32),\n", + " array([315.4357 , 315.57855, 315.61682, 316.0451 , 316.3004 , 316.34836,\n", + " 316.37317, 316.4886 , 316.49002, 316.50043], dtype=float32)),\n", + " (array([ 19, 31, 173, 43, 32, 12, 121, 29, 86, 100], dtype=int32),\n", + " array([280.57272, 280.7719 , 281.07443, 281.08145, 281.1216 , 281.18524,\n", + " 281.29205, 281.30084, 281.3151 , 281.45456], dtype=float32)),\n", + " (array([ 31, 19, 32, 12, 43, 62, 173, 268, 29, 255], dtype=int32),\n", + " array([212.05937, 212.52017, 212.58507, 212.63403, 212.72137, 212.80849,\n", + " 213.1062 , 213.11346, 213.26201, 213.30971], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 305, 206, 62, 121, 188, 166], dtype=int32),\n", + " array([214.13506, 214.32698, 214.4319 , 214.82591, 214.9582 , 215.22668,\n", + " 215.25037, 215.32793, 215.35207, 215.35536], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 43, 32, 100, 86, 164, 173], dtype=int32),\n", + " array([344.09488, 344.6076 , 344.66895, 344.8335 , 344.85468, 344.86243,\n", + " 345.18646, 345.26413, 345.31964, 345.32736], dtype=float32)),\n", + " (array([ 31, 19, 62, 32, 121, 49, 8, 100, 43, 255], dtype=int32),\n", + " array([289.59015, 289.7864 , 289.8605 , 289.99622, 290.1746 , 290.34833,\n", + " 290.35764, 290.42117, 290.4458 , 290.47693], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 86, 100, 255, 305, 268], dtype=int32),\n", + " array([309.9911 , 310.2475 , 310.25287, 310.38852, 310.3959 , 310.7034 ,\n", + " 310.78873, 310.84158, 310.85638, 310.94516], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 305, 62, 487, 121, 268, 42], dtype=int32),\n", + " array([344.07626, 344.12146, 344.15652, 344.5141 , 344.67456, 344.82837,\n", + " 344.9355 , 344.95264, 344.96835, 344.9991 ], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 176, 358, 305, 268, 206, 258], dtype=int32),\n", + " array([301.91364, 301.94638, 302.14154, 302.47595, 302.52408, 302.5301 ,\n", + " 302.6429 , 302.66528, 302.67337, 302.7384 ], dtype=float32)),\n", + " (array([ 31, 19, 121, 43, 62, 8, 32, 149, 173, 347], dtype=int32),\n", + " array([311.56973, 311.93002, 312.0687 , 312.26904, 312.3276 , 312.33615,\n", + " 312.4214 , 312.52353, 312.54443, 312.58813], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 149, 62, 262, 8, 121, 153], dtype=int32),\n", + " array([-6.4855523, -6.256936 , -6.063451 , -5.9578786, -5.8819222,\n", + " -5.7880354, -5.7735653, -5.689861 , -5.5408607, -5.512192 ],\n", + " dtype=float32)),\n", + " (array([ 32, 43, 19, 62, 8, 31, 166, 262, 204, 149], dtype=int32),\n", + " array([339.32056, 339.53723, 339.67032, 339.851 , 339.86502, 339.917 ,\n", + " 340.10864, 340.15747, 340.1631 , 340.2363 ], dtype=float32)),\n", + " (array([ 62, 31, 32, 19, 43, 173, 100, 121, 552, 8], dtype=int32),\n", + " array([343.87137, 343.94736, 343.96133, 344.1342 , 344.17688, 344.2921 ,\n", + " 344.3133 , 344.3215 , 344.419 , 344.5248 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 255, 86, 62, 121, 32, 100, 8], dtype=int32),\n", + " array([57.171047, 57.300293, 57.456116, 57.552956, 57.575035, 57.703205,\n", + " 57.74877 , 57.83789 , 57.954014, 58.031185], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 32, 173, 268, 120, 43, 262], dtype=int32),\n", + " array([291.32318, 291.49185, 291.9709 , 292.06073, 292.27478, 292.31512,\n", + " 292.36655, 292.48712, 292.53076, 292.6299 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 29, 43, 105, 121, 268, 62, 100], dtype=int32),\n", + " array([-16.020737 , -15.7931795, -15.599528 , -15.180405 , -15.113835 ,\n", + " -14.977344 , -14.974714 , -14.925344 , -14.925142 , -14.800559 ],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 358, 258, 206, 884, 636, 176], dtype=int32),\n", + " array([295.85547, 296.11914, 296.14532, 296.27072, 296.31024, 296.36993,\n", + " 296.5217 , 296.55975, 296.67944, 296.71323], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 100, 86, 268, 29], dtype=int32),\n", + " array([156.00362, 156.18478, 156.18512, 156.24487, 156.56755, 156.68701,\n", + " 156.89453, 156.92322, 157.02383, 157.05093], dtype=float32)),\n", + " (array([ 31, 19, 43, 29, 32, 121, 86, 24, 268, 105], dtype=int32),\n", + " array([-11.189659, -10.994785, -10.637021, -10.628121, -10.387021,\n", + " -10.361363, -10.263288, -10.212691, -10.182824, -10.142854],\n", + " dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 103, 32, 61, 43, 173, 268], dtype=int32),\n", + " array([-6.005646 , -5.299345 , -5.2527857, -5.0243163, -4.9157457,\n", + " -4.818486 , -4.795618 , -4.764198 , -4.7160826, -4.715994 ],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 86, 16, 121, 173, 100], dtype=int32),\n", + " array([314.16678, 314.39813, 314.40552, 314.43243, 314.6677 , 314.72833,\n", + " 314.74393, 314.7528 , 314.91867, 315.04828], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 255, 268, 121, 120, 86], dtype=int32),\n", + " array([-17.193256, -17.039999, -16.79972 , -16.755228, -16.568996,\n", + " -16.313007, -16.245993, -16.171654, -16.059319, -16.003174],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 121, 103, 62, 32, 268, 120, 164, 29], dtype=int32),\n", + " array([265.82047, 266.27856, 266.48312, 266.73096, 266.7545 , 266.79245,\n", + " 266.86276, 266.98782, 267.03455, 267.05856], dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 62, 121, 268, 305, 100, 49], dtype=int32),\n", + " array([319.28192, 319.45398, 319.54037, 319.54303, 319.75848, 320.0884 ,\n", + " 320.108 , 320.20068, 320.29398, 320.30594], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 121, 62, 49, 100, 268, 164], dtype=int32),\n", + " array([308.2159 , 308.54578, 308.55927, 308.69986, 308.8049 , 308.83264,\n", + " 309.02768, 309.1625 , 309.19815, 309.19907], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 255, 268, 121, 86, 164], dtype=int32),\n", + " array([-19.607666, -19.478085, -19.320446, -19.172272, -18.873766,\n", + " -18.723473, -18.613825, -18.567207, -18.566029, -18.552029],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 121, 173, 206, 29, 86], dtype=int32),\n", + " array([307.87057, 307.9003 , 308.49023, 308.51843, 308.792 , 308.8596 ,\n", + " 308.9318 , 309.06952, 309.15012, 309.17218], dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 31, 206, 121, 279, 173, 100], dtype=int32),\n", + " array([340.90964, 341.18716, 341.33032, 341.65274, 341.65872, 341.7587 ,\n", + " 341.91833, 341.94028, 342.03506, 342.0902 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 29, 173, 268, 86], dtype=int32),\n", + " array([-9.436364, -9.173308, -9.009834, -8.934583, -8.633148, -8.594711,\n", + " -8.540754, -8.493278, -8.441753, -8.38345 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 29, 305, 121, 62, 268, 105], dtype=int32),\n", + " array([327.17972, 327.23294, 327.41696, 327.4331 , 327.9917 , 328.02567,\n", + " 328.03696, 328.19165, 328.22324, 328.28644], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 173, 12, 100, 268], dtype=int32),\n", + " array([343.57242, 343.75925, 344.2317 , 344.29984, 344.31036, 344.33786,\n", + " 344.56778, 344.60086, 344.6228 , 344.7307 ], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 121, 268, 100, 49, 120], dtype=int32),\n", + " array([341.16324, 341.2689 , 341.27478, 341.34 , 341.5751 , 341.85776,\n", + " 342.0424 , 342.05667, 342.07333, 342.2148 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 268, 358, 121, 166, 97], dtype=int32),\n", + " array([306.0728 , 306.09064, 306.22867, 306.42188, 306.9325 , 307.01953,\n", + " 307.0909 , 307.11935, 307.17044, 307.22147], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 62, 121, 204, 487, 166, 164], dtype=int32),\n", + " array([-21.794752, -21.704985, -21.61844 , -21.420767, -21.202236,\n", + " -21.03471 , -20.918108, -20.884716, -20.848198, -20.79975 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", + " array([-5.0159473, -5.0133467, -4.4760823, -4.416821 , -4.405054 ,\n", + " -4.231186 , -4.2287207, -4.0311823, -4.005026 , -3.966051 ],\n", + " dtype=float32)),\n", + " (array([1638, 19, 279, 13, 32, 118, 43, 610, 815, 370],\n", + " dtype=int32),\n", + " array([347.81808, 348.21762, 348.3405 , 348.41226, 348.46475, 348.5277 ,\n", + " 348.643 , 348.6486 , 348.67526, 348.68784], dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 29, 86, 43, 21, 12, 24], dtype=int32),\n", + " array([-6.467538 , -6.4442935, -5.897809 , -5.831173 , -5.8068085,\n", + " -5.765753 , -5.6836014, -5.681742 , -5.658136 , -5.645841 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 173, 121, 62, 358, 268, 100], dtype=int32),\n", + " array([327.39117, 327.41367, 327.46848, 327.79846, 327.94684, 328.021 ,\n", + " 328.08438, 328.10913, 328.11047, 328.37894], dtype=float32)),\n", + " (array([ 31, 19, 12, 173, 121, 29, 268, 32, 100, 24], dtype=int32),\n", + " array([1.7265751, 1.8700533, 2.464658 , 2.5191495, 2.6392179, 2.817502 ,\n", + " 2.9706817, 3.003153 , 3.1233983, 3.1877522], dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 43, 32, 103, 173, 100, 268], dtype=int32),\n", + " array([347.82153, 348.3465 , 348.5297 , 348.65796, 348.79175, 348.92554,\n", + " 349.11295, 349.149 , 349.16806, 349.17993], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 268, 62, 121, 173, 358, 120], dtype=int32),\n", + " array([-20.399937, -20.15641 , -19.97839 , -19.86608 , -19.54196 ,\n", + " -19.526468, -19.35872 , -19.232452, -19.21796 , -19.164282],\n", + " dtype=float32)),\n", + " (array([149, 62, 31, 32, 262, 8, 43, 19, 121, 100], dtype=int32),\n", + " array([349.0581 , 349.15714, 349.18317, 349.21707, 349.42548, 349.4463 ,\n", + " 349.4783 , 349.48047, 349.59106, 349.61743], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", + " array([342.80194, 342.93613, 343.11276, 343.20624, 343.33676, 343.50534,\n", + " 343.70572, 343.81918, 343.90698, 343.91614], dtype=float32)),\n", + " (array([149, 8, 262, 153, 31, 539, 0, 530, 57, 369], dtype=int32),\n", + " array([350.04428, 350.3302 , 350.35052, 350.63522, 350.76788, 350.80096,\n", + " 350.8058 , 350.81235, 350.8247 , 350.83926], dtype=float32)),\n", + " (array([ 19, 149, 31, 8, 552, 32, 62, 121, 43, 262], dtype=int32),\n", + " array([300.33966, 300.46338, 300.58124, 300.637 , 300.81696, 300.81708,\n", + " 300.88522, 300.92712, 300.97235, 301.01892], dtype=float32)),\n", + " (array([ 43, 149, 62, 279, 129, 350, 32, 347, 36, 31], dtype=int32),\n", + " array([-23.871014, -23.72525 , -23.503815, -23.502007, -23.499966,\n", + " -23.463312, -23.450043, -23.448347, -23.438875, -23.437027],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 69, 36, 449, 350, 240], dtype=int32),\n", + " array([295.42017, 295.43604, 295.4444 , 295.44955, 295.53717, 295.63864,\n", + " 295.6832 , 295.73346, 295.87933, 295.88153], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 86, 49], dtype=int32),\n", + " array([308.8244 , 308.8734 , 308.9243 , 308.95322, 309.25433, 309.43945,\n", + " 309.65298, 309.6704 , 309.7664 , 309.76868], dtype=float32)),\n", + " (array([ 43, 31, 19, 32, 358, 589, 97, 62, 121, 173], dtype=int32),\n", + " array([309.85483, 309.93176, 310.34106, 310.38965, 310.39078, 310.4858 ,\n", + " 310.49197, 310.49362, 310.54358, 310.5536 ], dtype=float32)),\n", + " (array([ 31, 121, 43, 32, 19, 62, 86, 120, 268, 255], dtype=int32),\n", + " array([50.76687 , 51.438454, 51.48716 , 51.522655, 51.554604, 51.628387,\n", + " 51.796402, 51.865253, 51.9684 , 52.01172 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 43, 173, 32, 268, 12, 100], dtype=int32),\n", + " array([345.1402 , 345.468 , 345.71017, 345.72964, 346.08655, 346.12393,\n", + " 346.15323, 346.16113, 346.25333, 346.2692 ], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 268, 120, 49, 86], dtype=int32),\n", + " array([309.7443 , 309.79987, 309.8201 , 309.91574, 310.13895, 310.25586,\n", + " 310.41113, 310.48035, 310.4928 , 310.56735], dtype=float32)),\n", + " (array([ 43, 32, 305, 49, 19, 62, 112, 483, 166, 487], dtype=int32),\n", + " array([316.18222, 316.55273, 316.88788, 316.88977, 316.97662, 317.02985,\n", + " 317.12967, 317.12973, 317.18176, 317.20413], dtype=float32)),\n", + " (array([ 31, 19, 32, 358, 121, 43, 62, 173, 268, 97], dtype=int32),\n", + " array([343.0131 , 343.28653, 343.3871 , 343.39142, 343.40115, 343.5621 ,\n", + " 343.58423, 343.78552, 343.8336 , 344.0114 ], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 62, 43, 120, 268, 173, 100], dtype=int32),\n", + " array([-14.42631 , -14.415461, -14.176025, -13.962046, -13.851507,\n", + " -13.797985, -13.685981, -13.650972, -13.570874, -13.45312 ],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 268, 204, 29, 206, 121, 166], dtype=int32),\n", + " array([267.44852, 267.50827, 267.75266, 268.00235, 268.11444, 268.1258 ,\n", + " 268.35196, 268.38818, 268.39667, 268.44592], dtype=float32)),\n", + " (array([ 31, 103, 19, 61, 121, 268, 535, 40, 12, 120], dtype=int32),\n", + " array([343.6989 , 344.47595, 344.70236, 344.94162, 344.95032, 344.97284,\n", + " 345.06775, 345.07593, 345.11835, 345.12515], dtype=float32)),\n", + " (array([149, 262, 31, 32, 19, 835, 241, 0, 369, 43], dtype=int32),\n", + " array([348.56985, 348.64056, 348.84622, 348.9293 , 348.9528 , 348.9548 ,\n", + " 348.96805, 348.9862 , 349.01007, 349.01956], dtype=float32)),\n", + " (array([ 19, 31, 121, 29, 173, 43, 12, 32, 105, 268], dtype=int32),\n", + " array([347.46866, 347.60608, 348.30573, 348.32297, 348.37988, 348.39984,\n", + " 348.5157 , 348.542 , 348.65463, 348.81802], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 268, 255, 100, 29], dtype=int32),\n", + " array([240.94228, 241.10362, 241.12108, 241.21033, 241.59976, 241.61243,\n", + " 241.78494, 241.88823, 241.89291, 241.91635], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 121, 62, 204, 268, 100, 120], dtype=int32),\n", + " array([316.31665, 316.49362, 316.57642, 316.78735, 316.95148, 317.02228,\n", + " 317.1421 , 317.20248, 317.2166 , 317.25565], dtype=float32)),\n", + " (array([ 19, 43, 31, 86, 32, 121, 62, 173, 100, 29], dtype=int32),\n", + " array([314.52826, 314.84546, 315.01562, 315.05515, 315.21722, 315.22354,\n", + " 315.24313, 315.33847, 315.5094 , 315.52777], dtype=float32)),\n", + " (array([149, 735, 262, 8, 31, 552, 450, 32, 62, 19], dtype=int32),\n", + " array([319.87048, 320.07922, 320.1512 , 320.18228, 320.5829 , 320.65225,\n", + " 320.65305, 320.65683, 320.68857, 320.7022 ], dtype=float32)),\n", + " (array([ 19, 31, 21, 121, 32, 29, 173, 12, 100, 268], dtype=int32),\n", + " array([323.00748, 323.50046, 323.51654, 323.83002, 323.8655 , 323.99277,\n", + " 324.0247 , 324.02908, 324.07242, 324.1066 ], dtype=float32)),\n", + " (array([ 31, 19, 103, 43, 29, 121, 12, 268, 32, 120], dtype=int32),\n", + " array([231.82516, 232.01515, 232.36888, 232.60991, 232.66496, 232.70091,\n", + " 232.71054, 232.7194 , 232.79173, 232.8018 ], dtype=float32)),\n", + " (array([ 32, 31, 62, 43, 19, 121, 204, 268, 8, 49], dtype=int32),\n", + " array([346.36383, 346.37796, 346.6725 , 346.87506, 346.9047 , 347.0223 ,\n", + " 347.02927, 347.04068, 347.0678 , 347.12524], dtype=float32)),\n", + " (array([ 32, 19, 62, 43, 31, 112, 100, 69, 173, 86], dtype=int32),\n", + " array([310.82144, 310.92435, 310.9696 , 311.0524 , 311.1181 , 311.1658 ,\n", + " 311.29068, 311.30902, 311.32593, 311.34253], dtype=float32)),\n", + " (array([ 19, 4326, 3162, 2310, 32, 43, 31, 4838, 62, 149],\n", + " dtype=int32),\n", + " array([249.44016, 249.45004, 249.60986, 249.64139, 249.70992, 249.76729,\n", + " 249.7751 , 249.8351 , 249.88657, 249.89322], dtype=float32)),\n", + " (array([ 31, 19, 43, 62, 32, 121, 164, 268, 49, 86], dtype=int32),\n", + " array([-22.562975, -22.560837, -22.413036, -22.334667, -22.316479,\n", + " -22.18161 , -21.895603, -21.873486, -21.817493, -21.754555],\n", + " dtype=float32)),\n", + " (array([ 31, 62, 32, 36, 43, 610, 121, 19, 69, 279], dtype=int32),\n", + " array([312.21576, 312.2401 , 312.26993, 312.38785, 312.49933, 312.54776,\n", + " 312.57104, 312.67737, 312.68393, 312.69513], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 62, 206, 305, 121, 268, 487], dtype=int32),\n", + " array([284.8268 , 284.8659 , 284.89288, 285.07498, 285.2831 , 285.4737 ,\n", + " 285.65622, 285.71848, 285.7789 , 285.7832 ], dtype=float32)),\n", + " (array([ 43, 32, 62, 19, 31, 49, 268, 121, 112, 120], dtype=int32),\n", + " array([305.9512 , 306.17957, 306.6377 , 306.63815, 306.6725 , 306.87018,\n", + " 307.01367, 307.03284, 307.04086, 307.0847 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 69, 173, 258, 279, 665, 62], dtype=int32),\n", + " array([314.8485 , 315.25262, 315.39423, 315.39603, 315.4922 , 315.51727,\n", + " 315.5899 , 315.6018 , 315.6037 , 315.67908], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 268, 49, 100, 305], dtype=int32),\n", + " array([320.40286, 320.466 , 320.54807, 320.55475, 320.90228, 321.0765 ,\n", + " 321.2331 , 321.30875, 321.32114, 321.38458], dtype=float32)),\n", + " (array([ 19, 31, 43, 121, 29, 62, 103, 32, 268, 173], dtype=int32),\n", + " array([-14.950289, -14.756871, -14.075444, -13.935917, -13.838904,\n", + " -13.814549, -13.779864, -13.755139, -13.739934, -13.731543],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 31, 32, 121, 62, 268, 487, 29, 848], dtype=int32),\n", + " array([312.37747, 312.3967 , 312.5323 , 312.5502 , 312.8118 , 312.92868,\n", + " 312.98355, 312.98596, 313.0252 , 313.0504 ], dtype=float32)),\n", + " (array([ 43, 62, 31, 32, 19, 121, 49, 86, 25, 273], dtype=int32),\n", + " array([307.1536 , 307.24713, 307.38647, 307.57568, 307.60028, 307.6711 ,\n", + " 307.88113, 307.95306, 307.97028, 307.97275], dtype=float32)),\n", + " (array([262, 149, 8, 450, 62, 489, 369, 153, 325, 32], dtype=int32),\n", + " array([210.27339, 210.30504, 210.46014, 210.50189, 210.7549 , 210.76389,\n", + " 210.76942, 210.80673, 210.85759, 210.8653 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 268, 62, 105, 120, 29], dtype=int32),\n", + " array([308.6401 , 309.06784, 309.18906, 309.34564, 309.52155, 309.59317,\n", + " 309.65195, 309.7466 , 309.8 , 309.8042 ], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 121, 268, 100, 49, 120], dtype=int32),\n", + " array([341.30023, 341.4049 , 341.40576, 341.47562, 341.7177 , 341.99478,\n", + " 342.17505, 342.1918 , 342.20712, 342.35205], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 86, 100, 173, 268], dtype=int32),\n", + " array([51.62322 , 51.70004 , 51.93884 , 52.08133 , 52.165623, 52.20838 ,\n", + " 52.482906, 52.546368, 52.58254 , 52.628117], dtype=float32)),\n", + " (array([ 31, 32, 62, 19, 121, 43, 8, 173, 347, 100], dtype=int32),\n", + " array([318.883 , 319.01743, 319.23465, 319.35052, 319.38702, 319.4028 ,\n", + " 319.4835 , 319.5272 , 319.6542 , 319.71283], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 121, 62, 49, 164, 206, 105], dtype=int32),\n", + " array([286.465 , 286.51447, 286.5355 , 286.91913, 286.997 , 287.0653 ,\n", + " 287.1553 , 287.20862, 287.35745, 287.35916], dtype=float32)),\n", + " (array([ 43, 62, 49, 31, 32, 19, 164, 121, 100, 139], dtype=int32),\n", + " array([306.247 , 306.2682 , 306.38638, 306.39606, 306.45087, 306.51486,\n", + " 306.53436, 306.64188, 306.70016, 306.8196 ], dtype=float32)),\n", + " (array([ 31, 103, 121, 19, 12, 313, 535, 2180, 43, 62],\n", + " dtype=int32),\n", + " array([351.9761 , 352.98825, 353.0984 , 353.24844, 353.30118, 353.3142 ,\n", + " 353.3811 , 353.4146 , 353.44522, 353.5219 ], dtype=float32)),\n", + " (array([ 43, 31, 32, 19, 62, 121, 279, 86, 100, 69], dtype=int32),\n", + " array([312.92926, 313.1717 , 313.29642, 313.2985 , 313.42117, 313.479 ,\n", + " 313.5497 , 313.5814 , 313.65286, 313.69855], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 62, 43, 49, 8, 100, 268], dtype=int32),\n", + " array([320.81348, 321.05295, 321.05365, 321.16675, 321.19067, 321.1962 ,\n", + " 321.60626, 321.6853 , 321.74094, 321.7631 ], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 121, 268, 49, 100, 305], dtype=int32),\n", + " array([320.5586 , 320.61145, 320.6981 , 320.71088, 321.04718, 321.22855,\n", + " 321.38336, 321.46152, 321.47202, 321.55453], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([312.37073, 312.55405, 312.76764, 312.87885, 312.93515, 313.00577,\n", + " 313.24124, 313.37503, 313.43945, 313.4537 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 62, 43, 121, 268, 120, 8, 149], dtype=int32),\n", + " array([355.07095, 355.7347 , 355.88535, 355.94373, 355.98886, 356.01782,\n", + " 356.12405, 356.1529 , 356.1666 , 356.22464], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 173, 121, 100, 69, 268], dtype=int32),\n", + " array([245.90755, 246.11623, 246.3128 , 246.38005, 246.49422, 246.70197,\n", + " 246.76761, 246.9832 , 247.16249, 247.21341], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 121, 62, 100, 268, 120, 86], dtype=int32),\n", + " array([313.88638, 314.13068, 314.13995, 314.3594 , 314.59048, 314.64545,\n", + " 314.7349 , 314.81088, 314.84097, 314.86066], dtype=float32)),\n", + " (array([ 36, 43, 19, 610, 69, 62, 31, 149, 279, 118], dtype=int32),\n", + " array([-15.567868, -15.50956 , -15.436534, -15.407452, -15.392582,\n", + " -15.325006, -15.272363, -15.271942, -15.259655, -15.244802],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 121, 62, 268, 105, 358, 103], dtype=int32),\n", + " array([323.1203 , 323.18228, 323.5883 , 323.64148, 323.90393, 323.91296,\n", + " 323.9692 , 324.13217, 324.16327, 324.26343], dtype=float32)),\n", + " (array([2080, 4162, 5700, 4841, 6023, 2068, 6400, 4642, 5923, 7746],\n", + " dtype=int32),\n", + " array([326.21127, 326.5274 , 326.69186, 326.7166 , 326.8153 , 326.8331 ,\n", + " 326.8411 , 326.87357, 326.8934 , 326.9687 ], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 121, 268, 100, 49, 120], dtype=int32),\n", + " array([341.18 , 341.27856, 341.28226, 341.34998, 341.58475, 341.86234,\n", + " 342.05392, 342.0674 , 342.07928, 342.2291 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 255, 43, 29, 121, 62, 86, 100], dtype=int32),\n", + " array([240.10457, 240.14316, 240.16333, 240.26564, 240.39934, 240.70921,\n", + " 240.76018, 240.78172, 240.80974, 240.84702], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 173, 255, 268, 86], dtype=int32),\n", + " array([346.95557, 347.2482 , 347.50726, 347.7467 , 347.89117, 348.0756 ,\n", + " 348.09412, 348.3006 , 348.32947, 348.46222], dtype=float32)),\n", + " (array([ 19, 32, 43, 258, 31, 279, 173, 204, 62, 268], dtype=int32),\n", + " array([348.21478, 348.7067 , 348.83075, 348.90067, 348.91003, 349.13455,\n", + " 349.18103, 349.20905, 349.21918, 349.28833], dtype=float32)),\n", + " (array([ 31, 62, 19, 121, 43, 173, 32, 12, 268, 100], dtype=int32),\n", + " array([347.16537, 347.9599 , 347.97238, 348.0496 , 348.1414 , 348.2557 ,\n", + " 348.35638, 348.39505, 348.39636, 348.4529 ], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 279, 62, 121, 173, 8, 100], dtype=int32),\n", + " array([-8.940403, -8.841181, -8.810577, -8.61684 , -8.434095, -8.427022,\n", + " -8.270385, -8.156737, -8.069661, -8.057591], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 62, 121, 268, 86, 105, 173], dtype=int32),\n", + " array([267.6365 , 268.10785, 268.13104, 268.14886, 268.3573 , 268.4447 ,\n", + " 268.73376, 268.7385 , 268.85764, 268.91336], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 173, 121, 268, 29, 12, 62], dtype=int32),\n", + " array([-2.1624694 , -2.1570404 , -1.3937327 , -1.3903593 , -1.2716699 ,\n", + " -1.1796699 , -1.1254017 , -1.0579228 , -0.95602465, -0.94409853],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 268, 62, 305, 120, 166, 121], dtype=int32),\n", + " array([334.43964, 334.55215, 334.59018, 334.9465 , 335.19983, 335.21667,\n", + " 335.31958, 335.32718, 335.46387, 335.58316], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 62, 121, 100, 268, 86, 164], dtype=int32),\n", + " array([340.5543 , 340.61426, 340.882 , 340.99954, 341.10547, 341.32443,\n", + " 341.47726, 341.5122 , 341.54303, 341.63324], dtype=float32)),\n", + " (array([ 43, 19, 31, 32, 62, 121, 86, 100, 173, 268], dtype=int32),\n", + " array([310.93655, 310.98874, 310.99155, 311.00937, 311.27942, 311.43246,\n", + " 311.64612, 311.65787, 311.76938, 311.80804], dtype=float32)),\n", + " (array([ 43, 31, 19, 32, 62, 121, 49, 268, 100, 164], dtype=int32),\n", + " array([307.46826, 307.538 , 307.65506, 307.67123, 307.80823, 308.1331 ,\n", + " 308.25903, 308.2688 , 308.33713, 308.37222], dtype=float32)),\n", + " (array([ 31, 19, 12, 173, 121, 29, 268, 21, 62, 32], dtype=int32),\n", + " array([353.1654 , 353.3736 , 353.45108, 353.79785, 354.06775, 354.1278 ,\n", + " 354.20578, 354.21408, 354.2459 , 354.35483], dtype=float32)),\n", + " (array([ 32, 43, 69, 36, 279, 19, 31, 449, 62, 1380],\n", + " dtype=int32),\n", + " array([239.44693, 239.47939, 239.63757, 239.64905, 239.68205, 239.69392,\n", + " 239.81139, 240.00499, 240.0344 , 240.0877 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 121, 32, 62, 100, 173, 268, 29], dtype=int32),\n", + " array([-5.239605 , -5.0856557, -4.7565556, -4.741194 , -4.5610228,\n", + " -4.3928766, -4.297293 , -4.2819047, -4.2235246, -4.2157755],\n", + " dtype=float32)),\n", + " (array([149, 965, 8, 262, 735, 153, 552, 530, 369, 539], dtype=int32),\n", + " array([306.25558, 306.7805 , 306.9047 , 306.91498, 306.99356, 307.0457 ,\n", + " 307.05005, 307.07913, 307.13007, 307.13458], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 8, 86, 121, 149, 112], dtype=int32),\n", + " array([338.90805, 339.0791 , 339.28116, 339.31406, 339.35803, 339.62582,\n", + " 339.71698, 339.7818 , 339.7959 , 339.80237], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", + " array([310.45065, 310.5636 , 310.81436, 310.88065, 311.05026, 311.1332 ,\n", + " 311.3521 , 311.44955, 311.5422 , 311.5637 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 173, 62, 121, 100, 86, 268], dtype=int32),\n", + " array([-6.415976 , -6.4073477, -5.934216 , -5.760742 , -5.6050553,\n", + " -5.5310054, -5.4855146, -5.3321195, -5.319841 , -5.194134 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 12, 173, 43, 121, 29, 100, 62], dtype=int32),\n", + " array([-1.6162957 , -1.3056909 , -1.038226 , -0.97267723, -0.903343 ,\n", + " -0.83142614, -0.65846634, -0.5760039 , -0.53683317, -0.48959064],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 86, 121, 62, 255, 279, 139], dtype=int32),\n", + " array([292.5342 , 292.58636, 292.59357, 292.71558, 292.8396 , 292.91757,\n", + " 292.97223, 293.16867, 293.18503, 293.18552], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 32, 43, 8, 268, 173, 49], dtype=int32),\n", + " array([-14.722904, -14.659636, -14.137789, -14.063433, -13.997418,\n", + " -13.863566, -13.708372, -13.639454, -13.596024, -13.522898],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 19, 226, 31, 166, 305, 258, 115, 121], dtype=int32),\n", + " array([215.2259 , 215.3823 , 215.40979, 215.55237, 215.72635, 215.85623,\n", + " 215.87796, 215.91803, 215.94086, 215.96031], dtype=float32)),\n", + " (array([ 32, 43, 69, 31, 36, 913, 62, 777, 279, 112], dtype=int32),\n", + " array([281.12018, 281.1225 , 281.21597, 281.40295, 281.4125 , 281.43082,\n", + " 281.4836 , 281.7409 , 281.7557 , 281.78116], dtype=float32)),\n", + " (array([ 306, 19, 32, 36, 43, 2120, 62, 173, 31, 121],\n", + " dtype=int32),\n", + " array([346.39636, 346.45883, 346.53207, 346.6944 , 346.6995 , 346.71216,\n", + " 346.71695, 346.75598, 346.81348, 346.8136 ], dtype=float32)),\n", + " (array([ 19, 43, 32, 279, 188, 31, 62, 255, 173, 258], dtype=int32),\n", + " array([265.20395, 265.38385, 265.41226, 265.945 , 266.07922, 266.08093,\n", + " 266.10687, 266.1931 , 266.21286, 266.23383], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 173, 262, 268, 8, 100], dtype=int32),\n", + " array([295.98895, 296.28027, 296.71243, 296.80356, 296.83167, 296.84036,\n", + " 297.1351 , 297.1437 , 297.14795, 297.23462], dtype=float32)),\n", + " (array([ 31, 19, 62, 32, 173, 121, 43, 61, 120, 268], dtype=int32),\n", + " array([315.45764, 315.91943, 316.05283, 316.27142, 316.35052, 316.36044,\n", + " 316.53232, 316.61996, 316.6919 , 316.80225], dtype=float32)),\n", + " (array([ 19, 31, 12, 43, 173, 121, 32, 268, 62, 29], dtype=int32),\n", + " array([267.67084, 267.72833, 267.73022, 268.4498 , 268.48254, 268.5591 ,\n", + " 268.56265, 268.7254 , 268.77234, 268.90247], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 121, 268, 130, 105, 358, 42], dtype=int32),\n", + " array([-13.564224, -13.329862, -13.319795, -13.118033, -13.063758,\n", + " -12.908173, -12.690205, -12.67433 , -12.569277, -12.548384],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 173, 43, 62, 636, 100, 268, 32, 29], dtype=int32),\n", + " array([-4.9985914, -4.6330805, -4.3344355, -4.0384917, -3.9929457,\n", + " -3.8123507, -3.7999644, -3.7671752, -3.7665796, -3.7560258],\n", + " dtype=float32)),\n", + " (array([ 1512, 12006, 3998, 369, 5596, 262, 2679, 8, 19,\n", + " 6945], dtype=int32),\n", + " array([53.281876, 53.4551 , 53.555305, 53.876358, 54.024883, 54.115963,\n", + " 54.156887, 54.174454, 54.178905, 54.229485], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 262, 8, 149, 62, 552, 121], dtype=int32),\n", + " array([-15.695936, -15.562714, -15.478909, -15.401955, -15.381751,\n", + " -15.342807, -15.107531, -15.05071 , -14.961232, -14.93233 ],\n", + " dtype=float32)),\n", + " (array([ 32, 43, 31, 62, 19, 121, 49, 305, 164, 268], dtype=int32),\n", + " array([310.4991 , 310.56622, 310.6888 , 310.695 , 310.76025, 310.81952,\n", + " 311.04785, 311.05246, 311.27228, 311.29605], dtype=float32)),\n", + " (array([ 19, 31, 121, 43, 32, 173, 62, 105, 29, 268], dtype=int32),\n", + " array([-8.8336735, -8.72695 , -8.494268 , -8.293601 , -8.156838 ,\n", + " -7.978189 , -7.9321666, -7.866111 , -7.846372 , -7.8271933],\n", + " dtype=float32)),\n", + " (array([ 69, 32, 43, 19, 36, 528, 279, 204, 418, 449], dtype=int32),\n", + " array([288.77097, 288.8702 , 288.8752 , 288.98 , 289.02167, 289.0926 ,\n", + " 289.14014, 289.1926 , 289.20764, 289.21567], dtype=float32)),\n", + " (array([ 19, 31, 32, 29, 173, 121, 43, 268, 105, 62], dtype=int32),\n", + " array([300.84222, 301.45874, 301.62894, 301.77847, 301.96283, 302.00342,\n", + " 302.04025, 302.2506 , 302.2876 , 302.30295], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 62, 43, 103, 173, 120, 268], dtype=int32),\n", + " array([349.5395 , 349.84454, 349.94327, 350.18048, 350.27292, 350.41403,\n", + " 350.4802 , 350.57605, 350.5813 , 350.61682], dtype=float32)),\n", + " (array([ 19, 31, 29, 32, 121, 173, 43, 62, 100, 24], dtype=int32),\n", + " array([315.44714, 315.45224, 315.93335, 316.0352 , 316.07327, 316.27966,\n", + " 316.33044, 316.3346 , 316.37753, 316.38028], dtype=float32)),\n", + " (array([ 19, 31, 43, 358, 32, 173, 636, 62, 268, 121], dtype=int32),\n", + " array([-9.963589 , -9.809285 , -9.387534 , -9.205482 , -9.058536 ,\n", + " -9.019632 , -8.964258 , -8.934378 , -8.9212475, -8.746387 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 358, 121, 173, 43, 32, 62, 268, 100], dtype=int32),\n", + " array([-6.7162285, -6.525914 , -6.031356 , -6.007014 , -5.9763145,\n", + " -5.9590397, -5.9580097, -5.8188295, -5.816988 , -5.5363703],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 29, 43, 121, 268, 24, 173, 100], dtype=int32),\n", + " array([305.31534, 305.8434 , 306.06055, 306.10666, 306.2705 , 306.33456,\n", + " 306.43344, 306.50674, 306.56894, 306.5812 ], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 62, 258, 279, 255, 358, 173], dtype=int32),\n", + " array([-16.45056 , -16.081543, -15.938074, -15.785679, -15.57937 ,\n", + " -15.488791, -15.425339, -15.223385, -15.201254, -15.191471],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 43, 120, 19, 255, 268, 29, 121, 86], dtype=int32),\n", + " array([341.2839 , 341.6755 , 341.88043, 341.95566, 341.961 , 342.04584,\n", + " 342.0962 , 342.16168, 342.1698 , 342.1846 ], dtype=float32)),\n", + " (array([ 31, 19, 173, 12, 121, 32, 268, 29, 43, 358], dtype=int32),\n", + " array([-8.667049 , -8.382691 , -7.6888227, -7.6644435, -7.608928 ,\n", + " -7.4436045, -7.3922806, -7.3806834, -7.347027 , -7.2549744],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 268, 173, 358, 49], dtype=int32),\n", + " array([-11.05284 , -10.957485 , -10.892531 , -10.732716 , -10.722958 ,\n", + " -10.552846 , -10.500628 , -10.2660055, -10.130894 , -10.128552 ],\n", + " dtype=float32)),\n", + " (array([ 19, 43, 62, 173, 32, 31, 279, 121, 69, 36], dtype=int32),\n", + " array([314.40063, 314.4845 , 314.64893, 314.79523, 314.82343, 314.85294,\n", + " 315.00952, 315.0771 , 315.07925, 315.1117 ], dtype=float32)),\n", + " (array([ 43, 31, 19, 32, 62, 120, 268, 121, 487, 42], dtype=int32),\n", + " array([307.71738, 307.79037, 308.00027, 308.01938, 308.53983, 308.54434,\n", + " 308.62585, 308.77234, 308.77542, 308.815 ], dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 29, 121, 268, 120, 62, 255], dtype=int32),\n", + " array([346.16766, 346.5481 , 346.63773, 346.8988 , 347.13367, 347.1529 ,\n", + " 347.18713, 347.18732, 347.254 , 347.30856], dtype=float32)),\n", + " (array([ 19, 43, 62, 32, 173, 121, 31, 25, 36, 49], dtype=int32),\n", + " array([207.74565, 208.02919, 208.03604, 208.12025, 208.31384, 208.37885,\n", + " 208.39108, 208.52342, 208.58371, 208.63039], dtype=float32)),\n", + " (array([ 19, 43, 121, 31, 32, 173, 62, 8, 100, 268], dtype=int32),\n", + " array([-11.508071 , -11.152291 , -10.942703 , -10.914831 , -10.911328 ,\n", + " -10.846243 , -10.8276005, -10.660121 , -10.411308 , -10.386348 ],\n", + " dtype=float32)),\n", + " (array([ 262, 718, 2412, 369, 0, 153, 31, 965, 489, 8],\n", + " dtype=int32),\n", + " array([-5.9994774, -5.7627854, -5.5477343, -5.507009 , -5.49233 ,\n", + " -5.4497705, -5.379436 , -5.3342195, -5.2943263, -5.293456 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 62, 32, 173, 121, 12, 86, 268], dtype=int32),\n", + " array([279.0891 , 279.32962, 279.45917, 279.70963, 279.74292, 279.87704,\n", + " 279.97516, 280.049 , 280.11642, 280.20453], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 268, 121, 100, 120, 86], dtype=int32),\n", + " array([306.82788, 306.9972 , 307.03284, 307.22308, 307.33658, 307.4994 ,\n", + " 307.63345, 307.72754, 307.72937, 307.7416 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 268, 29, 173, 86], dtype=int32),\n", + " array([-11.914367 , -11.8615675, -11.374211 , -11.274739 , -11.184766 ,\n", + " -11.099998 , -10.919152 , -10.8941555, -10.873794 , -10.852995 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 43, 62, 268, 164, 105, 29], dtype=int32),\n", + " array([297.84326, 297.99957, 298.17078, 298.4394 , 298.48465, 298.51093,\n", + " 298.60464, 298.76886, 298.82486, 298.83643], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 121, 268, 86, 29, 255], dtype=int32),\n", + " array([288.84937, 289.09406, 289.10565, 289.36545, 289.47668, 289.67447,\n", + " 289.72296, 289.81696, 289.8755 , 289.88028], dtype=float32)),\n", + " (array([ 43, 31, 62, 19, 32, 121, 86, 49, 100, 255], dtype=int32),\n", + " array([247.3394 , 247.38557, 247.49289, 247.5255 , 247.60347, 247.9019 ,\n", + " 247.95514, 248.04012, 248.14587, 248.26149], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 32, 100, 43, 268, 120, 49], dtype=int32),\n", + " array([343.86398, 344.0433 , 344.08322, 344.1318 , 344.47165, 344.60645,\n", + " 344.6228 , 344.65543, 344.76862, 344.81354], dtype=float32)),\n", + " (array([ 32, 31, 19, 43, 62, 268, 121, 29, 305, 120], dtype=int32),\n", + " array([264.50845, 264.57135, 264.65674, 264.78946, 265.1672 , 265.2469 ,\n", + " 265.29602, 265.3416 , 265.39587, 265.46082], dtype=float32)),\n", + " (array([ 32, 31, 19, 255, 43, 121, 120, 29, 86, 100], dtype=int32),\n", + " array([292.5461 , 292.7073 , 292.79117, 292.93466, 293.1772 , 293.21738,\n", + " 293.22174, 293.2516 , 293.29108, 293.3703 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 173, 268, 12, 43, 29, 62], dtype=int32),\n", + " array([348.73694, 348.74698, 349.4377 , 349.66144, 349.7174 , 349.7496 ,\n", + " 349.7988 , 349.833 , 350.0069 , 350.00732], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 62, 268, 100, 173, 204], dtype=int32),\n", + " array([313.35837, 313.49054, 313.5306 , 313.90445, 313.90964, 313.94467,\n", + " 314.20184, 314.27777, 314.3091 , 314.4993 ], dtype=float32)),\n", + " (array([ 43, 2314, 86, 62, 19, 418, 32, 36, 31, 69],\n", + " dtype=int32),\n", + " array([-9.6120825, -9.346699 , -9.207026 , -9.160904 , -9.124111 ,\n", + " -9.095689 , -9.060061 , -9.052945 , -8.98671 , -8.982131 ],\n", + " dtype=float32)),\n", + " (array([ 19, 43, 32, 449, 69, 31, 166, 1277, 350, 610],\n", + " dtype=int32),\n", + " array([287.36234, 287.50375, 287.6907 , 287.71933, 287.79178, 287.8197 ,\n", + " 287.82077, 287.84833, 287.87378, 288.02737], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 86, 255, 268], dtype=int32),\n", + " array([345.5526 , 345.66226, 345.68192, 345.6944 , 346.17093, 346.41824,\n", + " 346.456 , 346.48203, 346.4914 , 346.54904], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 255, 62, 29, 268, 105, 121], dtype=int32),\n", + " array([-14.0868225, -13.886298 , -13.681151 , -13.650404 , -13.164167 ,\n", + " -13.055755 , -13.023791 , -13.013362 , -12.892268 , -12.864099 ],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 121, 268, 305, 49, 100], dtype=int32),\n", + " array([296.5766 , 296.64285, 296.73782, 296.80136, 297.12164, 297.2681 ,\n", + " 297.4555 , 297.49884, 297.5031 , 297.5338 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 29, 105, 100, 166], dtype=int32),\n", + " array([344.40976, 344.41183, 344.6868 , 344.71686, 345.07248, 345.14047,\n", + " 345.15277, 345.26352, 345.33438, 345.34442], dtype=float32)),\n", + " (array([ 31, 19, 12, 32, 121, 21, 62, 173, 268, 120], dtype=int32),\n", + " array([346.2154 , 346.4909 , 346.94992, 347.05362, 347.08423, 347.12668,\n", + " 347.15186, 347.24332, 347.4705 , 347.55835], dtype=float32)),\n", + " (array([ 19, 262, 31, 149, 43, 153, 8, 325, 32, 121], dtype=int32),\n", + " array([-6.206942 , -6.0745444, -5.9809794, -5.6786165, -5.653342 ,\n", + " -5.616562 , -5.5820312, -5.5511646, -5.5446153, -5.5070167],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 62, 121, 8, 120, 49, 268], dtype=int32),\n", + " array([306.33844, 306.62323, 306.89288, 307.00055, 307.03586, 307.13416,\n", + " 307.33762, 307.49387, 307.5142 , 307.5221 ], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 268, 255, 204, 121, 258], dtype=int32),\n", + " array([294.4024 , 294.704 , 294.76086, 295.0443 , 295.2479 , 295.42633,\n", + " 295.5138 , 295.52826, 295.5789 , 295.59912], dtype=float32)),\n", + " (array([ 31, 8, 262, 19, 32, 43, 121, 62, 450, 3146],\n", + " dtype=int32),\n", + " array([-3.9734848, -3.8687088, -3.7507374, -3.7470279, -3.647826 ,\n", + " -3.4301252, -3.4199665, -3.374422 , -3.3716147, -3.340707 ],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 31, 62, 19, 149, 268, 120, 49, 166], dtype=int32),\n", + " array([284.24326, 284.27377, 284.3508 , 284.66156, 284.842 , 284.90616,\n", + " 285.1522 , 285.20038, 285.21167, 285.22134], dtype=float32)),\n", + " (array([ 19, 31, 255, 43, 86, 32, 268, 29, 62, 166], dtype=int32),\n", + " array([247.25244, 247.31169, 247.36824, 247.41881, 247.65016, 247.68929,\n", + " 248.19554, 248.19984, 248.20874, 248.33179], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 166, 120, 268, 173], dtype=int32),\n", + " array([-14.870354, -14.839024, -14.615126, -14.589908, -14.255788,\n", + " -14.196692, -13.983387, -13.971422, -13.958493, -13.887913],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 121, 100, 86, 173, 268], dtype=int32),\n", + " array([343.3399 , 343.40366, 343.44424, 343.4456 , 343.6473 , 343.905 ,\n", + " 344.11575, 344.17105, 344.2046 , 344.24673], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 206, 173, 268, 86], dtype=int32),\n", + " array([290.16843, 290.18997, 290.38217, 290.6731 , 290.9078 , 291.01703,\n", + " 291.07397, 291.1241 , 291.1473 , 291.2019 ], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 268, 121, 305, 173, 29], dtype=int32),\n", + " array([257.74973, 257.931 , 258.04843, 258.28745, 258.60605, 258.7642 ,\n", + " 258.84933, 258.8708 , 258.9978 , 259.0058 ], dtype=float32)),\n", + " (array([ 43, 31, 19, 32, 92, 121, 304, 62, 105, 164], dtype=int32),\n", + " array([301.8668 , 302.12326, 302.34232, 302.45627, 302.7205 , 302.79388,\n", + " 302.89005, 302.93973, 302.9696 , 303.03345], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 305, 206, 100, 121, 112], dtype=int32),\n", + " array([341.35913, 341.43484, 341.79684, 342.1412 , 342.324 , 342.33612,\n", + " 342.50934, 342.6344 , 342.6764 , 342.67975], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 120, 100], dtype=int32),\n", + " array([289.71463, 289.79852, 290.11044, 290.22134, 290.40036, 290.4122 ,\n", + " 290.59308, 290.77255, 290.86734, 290.8776 ], dtype=float32)),\n", + " (array([ 31, 43, 32, 86, 62, 19, 121, 305, 255, 120], dtype=int32),\n", + " array([231.00754, 231.31044, 231.41779, 231.63742, 231.69531, 231.73466,\n", + " 231.99161, 232.06673, 232.09877, 232.11288], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 86, 62, 121, 255, 100, 29], dtype=int32),\n", + " array([235.1547 , 235.54523, 235.55261, 235.61209, 235.77467, 235.79161,\n", + " 235.89807, 235.9805 , 236.07578, 236.09122], dtype=float32)),\n", + " (array([1959, 1120, 2977, 19, 39, 884, 1940, 2653, 1518, 636],\n", + " dtype=int32),\n", + " array([328.74088, 328.81854, 328.95816, 329.13812, 329.15073, 329.20258,\n", + " 329.21838, 329.36902, 329.40176, 329.4096 ], dtype=float32)),\n", + " (array([ 19, 31, 43, 173, 32, 86, 29, 62, 12, 255], dtype=int32),\n", + " array([268.86743, 269.46136, 269.56302, 269.64392, 269.65433, 269.66522,\n", + " 269.84482, 269.95926, 269.96872, 269.9839 ], dtype=float32)),\n", + " (array([ 19, 279, 43, 36, 69, 32, 31, 62, 118, 370], dtype=int32),\n", + " array([343.30206, 343.32822, 343.35498, 343.41068, 343.4234 , 343.4966 ,\n", + " 343.5781 , 343.58517, 343.60013, 343.62402], dtype=float32)),\n", + " (array([ 19, 31, 43, 121, 32, 268, 62, 173, 164, 105], dtype=int32),\n", + " array([-19.262432, -18.970963, -18.968145, -18.747179, -18.50581 ,\n", + " -18.32977 , -18.295729, -18.238485, -18.178022, -18.097466],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 32, 305, 848, 206, 188, 279, 1088, 374],\n", + " dtype=int32),\n", + " array([319.36642, 319.56693, 319.626 , 319.86072, 319.93347, 320.13858,\n", + " 320.19757, 320.20312, 320.2503 , 320.3026 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 43, 255, 62, 86, 173, 120], dtype=int32),\n", + " array([297.0155 , 297.13086, 297.68158, 297.7243 , 297.81842, 297.835 ,\n", + " 297.92056, 298.03732, 298.0758 , 298.14822], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 62, 120, 121, 358, 268, 103], dtype=int32),\n", + " array([276.18808, 276.88028, 277.00955, 277.06067, 277.2256 , 277.3217 ,\n", + " 277.4061 , 277.4596 , 277.4885 , 277.51587], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 43, 173, 62, 12, 268, 100], dtype=int32),\n", + " array([350.00446, 350.17502, 350.43887, 350.6564 , 350.69977, 350.84567,\n", + " 350.88907, 351.07727, 351.1081 , 351.1229 ], dtype=float32)),\n", + " (array([ 345, 4738, 4326, 1277, 36, 32, 610, 240, 13, 1638],\n", + " dtype=int32),\n", + " array([307.03915, 308.22446, 308.28445, 308.74045, 308.90253, 308.90698,\n", + " 308.91098, 308.99344, 309.04437, 309.0559 ], dtype=float32)),\n", + " (array([ 43, 19, 32, 62, 86, 31, 112, 374, 173, 487], dtype=int32),\n", + " array([311.68478, 311.80957, 311.8102 , 312.00293, 312.14935, 312.26733,\n", + " 312.44666, 312.60242, 312.61804, 312.6254 ], dtype=float32)),\n", + " (array([ 43, 31, 32, 19, 62, 268, 358, 121, 173, 166], dtype=int32),\n", + " array([343.7238 , 343.8537 , 344.02582, 344.19736, 344.31094, 344.6312 ,\n", + " 344.6665 , 344.79254, 344.87335, 344.90646], dtype=float32)),\n", + " (array([ 32, 31, 62, 43, 19, 121, 441, 112, 49, 120], dtype=int32),\n", + " array([292.95178, 293.0729 , 293.26694, 293.28125, 293.3645 , 293.50885,\n", + " 293.6507 , 293.7795 , 293.78775, 293.81918], dtype=float32)),\n", + " (array([ 31, 12, 21, 29, 19, 24, 121, 32, 268, 105], dtype=int32),\n", + " array([355.0476 , 355.21933, 355.3185 , 355.55774, 355.6075 , 355.647 ,\n", + " 355.83905, 355.9482 , 356.10522, 356.13074], dtype=float32)),\n", + " (array([ 31, 19, 121, 12, 62, 21, 32, 100, 11, 61], dtype=int32),\n", + " array([304.3875 , 305.11523, 305.17114, 305.4265 , 305.53488, 305.5818 ,\n", + " 305.5941 , 305.75012, 305.76743, 305.82275], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 305, 258, 121, 204, 100], dtype=int32),\n", + " array([284.7862 , 285.05832, 285.2212 , 285.24185, 285.4968 , 285.77765,\n", + " 285.82733, 285.85187, 285.88977, 285.95816], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 105, 29], dtype=int32),\n", + " array([265.61038, 265.70847, 266.01672, 266.18445, 266.30972, 266.35138,\n", + " 266.5342 , 266.69577, 266.7992 , 266.80106], dtype=float32)),\n", + " (array([ 43, 19, 86, 31, 32, 62, 25, 112, 164, 121], dtype=int32),\n", + " array([310.4266 , 310.5223 , 310.55197, 310.6251 , 310.63422, 310.7015 ,\n", + " 311.0051 , 311.0098 , 311.0597 , 311.0854 ], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 166, 121, 206, 305, 487], dtype=int32),\n", + " array([341.55927, 341.70657, 341.72754, 341.93817, 342.15762, 342.35983,\n", + " 342.42426, 342.43643, 342.45593, 342.47552], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 62, 268, 43, 120, 103, 105], dtype=int32),\n", + " array([310.4918 , 310.93274, 311.11896, 311.25186, 311.39307, 311.44058,\n", + " 311.49457, 311.71384, 311.7388 , 311.74344], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 206, 8, 279, 305, 149], dtype=int32),\n", + " array([336.622 , 336.7054 , 336.93042, 337.31628, 337.3898 , 337.5266 ,\n", + " 337.5593 , 337.608 , 337.6443 , 337.6892 ], dtype=float32)),\n", + " (array([ 32, 19, 305, 43, 528, 531, 3563, 31, 112, 579],\n", + " dtype=int32),\n", + " array([347.42548, 347.8113 , 347.92218, 347.9663 , 348.31726, 348.32343,\n", + " 348.39618, 348.4682 , 348.47116, 348.5228 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 268, 103, 62, 43, 164, 105], dtype=int32),\n", + " array([291.31287, 291.79883, 291.94574, 292.1013 , 292.16028, 292.21893,\n", + " 292.33588, 292.34268, 292.38098, 292.5352 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-5.0016017, -4.986882 , -4.451205 , -4.391886 , -4.387713 ,\n", + " -4.2009974, -4.1944404, -4.0058727, -3.9769433, -3.9448647],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 305, 121, 62, 29, 268, 49], dtype=int32),\n", + " array([287.3281 , 287.47498, 287.52948, 287.73807, 288.01025, 288.0994 ,\n", + " 288.17215, 288.20428, 288.21072, 288.31906], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", + " array([-5.0417438, -5.0349703, -4.490544 , -4.437183 , -4.428494 ,\n", + " -4.243727 , -4.2417865, -4.0510836, -4.023711 , -3.9946892],\n", + " dtype=float32)),\n", + " (array([ 32, 43, 305, 62, 49, 36, 528, 279, 19, 31], dtype=int32),\n", + " array([307.3345 , 307.4294 , 307.79126, 308.07477, 308.2332 , 308.24457,\n", + " 308.25793, 308.27167, 308.30646, 308.31348], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 62, 121, 86, 100, 173, 49], dtype=int32),\n", + " array([230.55882, 230.59306, 230.67099, 230.67737, 230.7757 , 230.97089,\n", + " 231.03192, 231.1943 , 231.31966, 231.43828], dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 86, 121, 255, 32, 100, 173], dtype=int32),\n", + " array([-12.179075, -12.055015, -11.658845, -11.474636, -11.45198 ,\n", + " -11.449149, -11.386686, -11.344017, -11.198047, -11.075245],\n", + " dtype=float32)),\n", + " (array([ 19, 43, 31, 62, 32, 86, 121, 204, 173, 100], dtype=int32),\n", + " array([-10.164619, -9.925463, -9.882594, -9.749147, -9.718987,\n", + " -9.615596, -9.499333, -9.329171, -9.290731, -9.212201],\n", + " dtype=float32)),\n", + " (array([ 19, 62, 32, 43, 31, 121, 173, 36, 100, 279], dtype=int32),\n", + " array([310.69125, 310.775 , 310.88123, 311.02145, 311.0617 , 311.11597,\n", + " 311.16595, 311.33707, 311.51437, 311.59106], dtype=float32)),\n", + " (array([ 31, 43, 130, 915, 19, 164, 32, 62, 441, 691], dtype=int32),\n", + " array([338.53754, 338.74622, 339.2825 , 339.3099 , 339.33862, 339.44678,\n", + " 339.45474, 339.46786, 339.50308, 339.64893], dtype=float32)),\n", + " (array([ 32, 43, 528, 305, 1277, 279, 1587, 69, 188, 345],\n", + " dtype=int32),\n", + " array([240.72806, 240.74092, 240.8347 , 240.9205 , 241.01338, 241.2151 ,\n", + " 241.29453, 241.30576, 241.32898, 241.34691], dtype=float32)),\n", + " (array([ 43, 31, 19, 8, 32, 149, 325, 62, 450, 105], dtype=int32),\n", + " array([315.75876, 315.77573, 315.8576 , 315.9668 , 316.0495 , 316.26123,\n", + " 316.34238, 316.3648 , 316.39322, 316.44662], dtype=float32)),\n", + " (array([ 19, 31, 21, 62, 43, 121, 12, 173, 32, 29], dtype=int32),\n", + " array([-13.370353 , -13.199175 , -12.9535885, -12.830408 , -12.722335 ,\n", + " -12.695543 , -12.659686 , -12.57739 , -12.562401 , -12.5078745],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 62, 173, 268, 43, 100, 255], dtype=int32),\n", + " array([290.3794 , 290.47238, 291.04694, 291.05835, 291.1413 , 291.37558,\n", + " 291.43317, 291.44394, 291.54236, 291.61172], dtype=float32)),\n", + " (array([149, 262, 552, 8, 31, 0, 539, 965, 369, 835], dtype=int32),\n", + " array([302.03113, 302.06293, 302.30316, 302.3143 , 302.3187 , 302.45093,\n", + " 302.47653, 302.59784, 302.69586, 302.71732], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", + " array([343.34982, 343.40662, 343.44388, 343.44897, 343.65295, 343.90765,\n", + " 344.1127 , 344.1763 , 344.2082 , 344.2455 ], dtype=float32)),\n", + " (array([ 43, 350, 36, 279, 19, 32, 69, 1277, 258, 62],\n", + " dtype=int32),\n", + " array([334.31732, 334.38333, 334.4554 , 334.63092, 334.68903, 334.6914 ,\n", + " 334.71286, 334.75555, 334.7793 , 334.82663], dtype=float32)),\n", + " (array([ 32, 31, 62, 43, 19, 268, 120, 121, 305, 255], dtype=int32),\n", + " array([297.75244, 297.94473, 298.43997, 298.54663, 298.55225, 298.6357 ,\n", + " 298.85092, 298.8621 , 298.9957 , 299.0392 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 121, 173, 62, 32, 268, 103, 12], dtype=int32),\n", + " array([345.12595, 345.48444, 345.93417, 346.0079 , 346.2208 , 346.26715,\n", + " 346.30457, 346.32483, 346.3851 , 346.47192], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 69, 279, 16, 36, 815, 112], dtype=int32),\n", + " array([312.86844, 312.91083, 313.10187, 313.1675 , 313.25974, 313.26758,\n", + " 313.32526, 313.36523, 313.45132, 313.4681 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", + " array([-5.0946803, -5.077351 , -4.5356355, -4.4874067, -4.4735856,\n", + " -4.2948647, -4.290651 , -4.106251 , -4.066084 , -4.03213 ],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 121, 173, 86, 8, 100], dtype=int32),\n", + " array([345.26007, 345.3555 , 345.5771 , 345.5897 , 345.8045 , 346.0711 ,\n", + " 346.08777, 346.2304 , 346.2648 , 346.27704], dtype=float32)),\n", + " (array([ 31, 62, 19, 121, 43, 32, 164, 255, 86, 49], dtype=int32),\n", + " array([214.0177 , 214.49263, 214.61058, 214.66464, 214.78662, 214.82312,\n", + " 214.84425, 214.94974, 214.9615 , 215.01779], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 305, 62, 121, 36, 100, 149], dtype=int32),\n", + " array([312.1478 , 312.49527, 312.61185, 312.83023, 312.99197, 313.0479 ,\n", + " 313.09927, 313.27527, 313.28778, 313.32355], dtype=float32)),\n", + " (array([ 31, 32, 43, 121, 62, 120, 8, 19, 103, 86], dtype=int32),\n", + " array([-17.195608, -16.587257, -16.459358, -16.368649, -16.358686,\n", + " -16.110693, -16.062782, -16.03438 , -15.907016, -15.808912],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 29, 268, 305, 173, 121, 62], dtype=int32),\n", + " array([247.70435, 247.9233 , 248.18109, 248.31598, 248.67165, 248.70995,\n", + " 248.82982, 248.87949, 248.91016, 249.00935], dtype=float32)),\n", + " (array([ 43, 36, 32, 69, 31, 118, 19, 62, 166, 279], dtype=int32),\n", + " array([341.3737 , 341.67444, 341.76135, 341.8588 , 341.8671 , 341.87106,\n", + " 341.9266 , 341.9679 , 342.0215 , 342.11133], dtype=float32)),\n", + " (array([ 31, 121, 19, 12, 103, 21, 61, 62, 29, 32], dtype=int32),\n", + " array([-13.424848, -12.865175, -12.774822, -12.463811, -12.357937,\n", + " -12.319481, -12.24777 , -12.225303, -12.208757, -12.18961 ],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 374, 305, 112, 31, 848, 454], dtype=int32),\n", + " array([338.48114, 338.79025, 338.81116, 339.09747, 339.3511 , 339.36023,\n", + " 339.36685, 339.40686, 339.41937, 339.47882], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 121, 100, 268, 49, 120], dtype=int32),\n", + " array([341.21753, 341.31866, 341.32355, 341.38373, 341.62173, 341.89523,\n", + " 342.1004 , 342.1031 , 342.12027, 342.2702 ], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 62, 121, 86, 100, 268, 173], dtype=int32),\n", + " array([263.7833 , 263.81995, 263.83786, 263.96176, 264.21823, 264.28357,\n", + " 264.37497, 264.5267 , 264.64972, 264.67917], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 120, 100], dtype=int32),\n", + " array([289.7196 , 289.80026, 290.0958 , 290.212 , 290.42407, 290.4241 ,\n", + " 290.59174, 290.7809 , 290.86972, 290.88995], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 279, 166, 204, 62, 69, 305], dtype=int32),\n", + " array([-22.06019 , -22.022694, -21.977915, -21.779879, -21.61482 ,\n", + " -21.50783 , -21.48641 , -21.42692 , -21.385483, -21.373497],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-5.037512 , -5.0237136, -4.494074 , -4.43174 , -4.4272833,\n", + " -4.244821 , -4.243558 , -4.0467653, -4.016542 , -3.9909475],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 62, 173, 32, 43, 121, 358, 268, 100], dtype=int32),\n", + " array([352.74524, 352.93347, 353.07114, 353.1705 , 353.20566, 353.25763,\n", + " 353.50116, 353.56415, 353.62692, 353.69406], dtype=float32)),\n", + " (array([ 19, 43, 32, 16, 305, 31, 188, 554, 186, 111], dtype=int32),\n", + " array([308.56146, 308.66006, 308.78403, 309.10117, 309.10822, 309.15823,\n", + " 309.20117, 309.23468, 309.24683, 309.33664], dtype=float32)),\n", + " (array([ 32, 43, 31, 62, 19, 166, 305, 120, 86, 49], dtype=int32),\n", + " array([334.5306 , 334.63214, 334.7412 , 335.01828, 335.21945, 335.2589 ,\n", + " 335.35727, 335.55618, 335.57034, 335.58856], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 43, 32, 12, 173, 268, 61], dtype=int32),\n", + " array([308.09946, 308.43088, 308.60757, 308.73572, 308.82132, 308.8971 ,\n", + " 308.8976 , 308.92874, 309.0461 , 309.1812 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 173, 268, 100, 29], dtype=int32),\n", + " array([311.39374, 311.48026, 311.5796 , 311.76224, 311.87125, 311.96405,\n", + " 312.14227, 312.20364, 312.26447, 312.29123], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 268, 121, 173, 100, 29], dtype=int32),\n", + " array([313.57062, 313.67438, 313.90894, 314.19592, 314.22522, 314.35294,\n", + " 314.4183 , 314.5291 , 314.539 , 314.54422], dtype=float32)),\n", + " (array([ 31, 19, 32, 268, 121, 43, 29, 173, 120, 62], dtype=int32),\n", + " array([347.01147, 347.23508, 347.40143, 347.50565, 347.71518, 347.76782,\n", + " 347.84988, 347.86267, 347.96655, 348.03088], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 121, 268, 173, 62, 164, 105], dtype=int32),\n", + " array([-20.464182, -20.362396, -20.002039, -19.757504, -19.63843 ,\n", + " -19.617554, -19.582748, -19.577436, -19.283743, -19.255453],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 62, 19, 31, 121, 100, 86, 49, 173], dtype=int32),\n", + " array([310.09262, 310.1131 , 310.21216, 310.21732, 310.27548, 310.60822,\n", + " 310.78345, 310.83847, 310.845 , 310.86917], dtype=float32)),\n", + " (array([ 31, 19, 121, 43, 173, 32, 62, 12, 268, 100], dtype=int32),\n", + " array([-10.95709 , -10.923313 , -10.351267 , -10.3023815, -10.301873 ,\n", + " -10.272888 , -10.232136 , -10.219132 , -9.9499445, -9.9107 ],\n", + " dtype=float32)),\n", + " (array([ 32, 43, 31, 62, 186, 121, 19, 305, 100, 29], dtype=int32),\n", + " array([278.15305, 278.37817, 278.50995, 278.65338, 278.7143 , 278.7305 ,\n", + " 278.82672, 278.8463 , 279.0097 , 279.03696], dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 279, 31, 528, 49, 188, 164], dtype=int32),\n", + " array([302.68402, 302.99008, 303.10764, 303.3145 , 303.34198, 303.36554,\n", + " 303.37967, 303.43552, 303.50217, 303.50488], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 100, 120, 268, 255], dtype=int32),\n", + " array([-13.530379, -12.864474, -12.844051, -12.832049, -12.690503,\n", + " -12.602685, -12.265813, -12.239744, -12.170782, -12.157627],\n", + " dtype=float32)),\n", + " (array([ 589, 31, 358, 878, 19, 32, 1287, 176, 62, 2964],\n", + " dtype=int32),\n", + " array([338.58856, 338.68777, 338.76834, 339.07806, 339.16458, 339.22958,\n", + " 339.2411 , 339.2634 , 339.28787, 339.352 ], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 268, 62, 255, 173, 42, 86], dtype=int32),\n", + " array([-11.178962 , -11.069656 , -10.9206915, -10.777212 , -10.241608 ,\n", + " -10.224714 , -10.209121 , -10.186697 , -10.110338 , -10.079626 ],\n", + " dtype=float32)),\n", + " (array([2181, 3590, 665, 2676, 2113, 5600, 3738, 2953, 6563, 956],\n", + " dtype=int32),\n", + " array([300.00397, 300.65714, 301.12607, 301.20392, 301.6251 , 302.2963 ,\n", + " 302.3603 , 302.61365, 302.6597 , 302.7265 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([342.96945, 343.11252, 343.29376, 343.37585, 343.49805, 343.6827 ,\n", + " 343.8803 , 343.98334, 344.08954, 344.09555], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 86, 100, 173, 268], dtype=int32),\n", + " array([51.645775, 51.728035, 51.95993 , 52.10309 , 52.202866, 52.22716 ,\n", + " 52.494923, 52.57747 , 52.603672, 52.645454], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 358, 62, 268, 176, 173, 121], dtype=int32),\n", + " array([338.46393, 338.64026, 338.64172, 338.80722, 338.9378 , 339.0534 ,\n", + " 339.28226, 339.37003, 339.46683, 339.49136], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 49, 268, 120, 392], dtype=int32),\n", + " array([302.61954, 302.6806 , 302.8154 , 303.0094 , 303.24045, 303.25885,\n", + " 303.46957, 303.4826 , 303.53622, 303.6376 ], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 305, 166, 204, 528, 121, 62], dtype=int32),\n", + " array([285.48547, 285.6108 , 285.91196, 285.9556 , 286.10684, 286.15298,\n", + " 286.1807 , 286.33746, 286.36145, 286.42834], dtype=float32)),\n", + " (array([2314, 19, 43, 32, 36, 62, 31, 69, 504, 449],\n", + " dtype=int32),\n", + " array([283.41412, 283.97858, 284.06885, 284.24115, 284.28284, 284.4292 ,\n", + " 284.52133, 284.52197, 284.53964, 284.6327 ], dtype=float32)),\n", + " (array([ 31, 19, 173, 62, 121, 32, 43, 12, 1842, 100],\n", + " dtype=int32),\n", + " array([360.42856, 360.9714 , 361.1089 , 361.1391 , 361.17966, 361.3434 ,\n", + " 361.3988 , 361.47015, 361.48196, 361.66397], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 29, 100, 62, 121, 268, 255], dtype=int32),\n", + " array([329.7449 , 330.0215 , 330.18597, 330.36047, 330.46606, 330.5241 ,\n", + " 330.53033, 330.58383, 330.8554 , 330.89307], dtype=float32)),\n", + " (array([ 31, 19, 43, 173, 32, 121, 86, 12, 62, 279], dtype=int32),\n", + " array([318.83676, 318.8765 , 319.27216, 319.48248, 319.62842, 319.63022,\n", + " 319.64417, 319.69492, 319.82974, 320.00836], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 121, 268, 173, 100, 12], dtype=int32),\n", + " array([344.3132 , 344.3722 , 344.6025 , 344.8976 , 344.91922, 345.0265 ,\n", + " 345.22122, 345.29587, 345.32556, 345.3912 ], dtype=float32)),\n", + " (array([ 43, 19, 31, 32, 62, 121, 86, 100, 173, 268], dtype=int32),\n", + " array([310.92206, 310.96536, 310.97714, 310.98904, 311.26248, 311.41983,\n", + " 311.64215, 311.65945, 311.74713, 311.78943], dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 62, 121, 100, 268, 49, 305], dtype=int32),\n", + " array([309.73407, 309.74258, 309.77997, 309.98755, 310.17023, 310.30298,\n", + " 310.49966, 310.50226, 310.5157 , 310.6984 ], dtype=float32)),\n", + " (array([149, 262, 552, 965, 19, 43, 62, 31, 735, 8], dtype=int32),\n", + " array([338.7936 , 338.9113 , 339.23383, 339.29318, 339.36636, 339.3925 ,\n", + " 339.39908, 339.40466, 339.44315, 339.50684], dtype=float32)),\n", + " (array([ 32, 31, 19, 43, 305, 121, 62, 268, 120, 29], dtype=int32),\n", + " array([299.54276, 299.82416, 299.9215 , 300.1283 , 300.2993 , 300.39517,\n", + " 300.42905, 300.47266, 300.5968 , 300.60406], dtype=float32)),\n", + " (array([ 32, 149, 43, 62, 8, 262, 19, 31, 965, 347], dtype=int32),\n", + " array([321.21442, 321.26743, 321.4155 , 321.50497, 321.56006, 321.611 ,\n", + " 321.69006, 321.85132, 321.9675 , 322.0124 ], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 86, 255, 268, 121, 120], dtype=int32),\n", + " array([289.8584 , 289.92667, 289.97864, 290.1437 , 290.38806, 290.5766 ,\n", + " 290.6364 , 290.64615, 290.7013 , 290.70383], dtype=float32)),\n", + " (array([ 31, 62, 19, 121, 173, 86, 268, 32, 120, 61], dtype=int32),\n", + " array([285.05518, 285.42502, 285.44858, 285.59433, 285.8237 , 285.92245,\n", + " 285.9577 , 286.02774, 286.0302 , 286.06293], dtype=float32)),\n", + " (array([ 31, 12, 19, 21, 43, 62, 173, 121, 358, 32], dtype=int32),\n", + " array([312.25607, 312.33475, 312.7304 , 312.7861 , 313.21628, 313.31088,\n", + " 313.32422, 313.5192 , 313.62683, 313.65344], dtype=float32)),\n", + " (array([ 43, 32, 31, 62, 49, 19, 121, 100, 305, 29], dtype=int32),\n", + " array([339.62262, 339.76053, 339.82208, 339.91553, 340.22488, 340.30194,\n", + " 340.32797, 340.34085, 340.55695, 340.60477], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 173, 268, 12, 100], dtype=int32),\n", + " array([280.95374, 281.04294, 281.30386, 281.56708, 281.59814, 281.71246,\n", + " 281.76068, 281.83936, 281.92813, 282.13126], dtype=float32)),\n", + " (array([ 31, 19, 43, 121, 32, 86, 105, 62, 268, 164], dtype=int32),\n", + " array([-9.403651, -9.373893, -8.987466, -8.851008, -8.665498, -8.599025,\n", + " -8.547629, -8.522236, -8.46133 , -8.398083], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-4.986924 , -4.9661355, -4.4244866, -4.3569655, -4.3528247,\n", + " -4.1861296, -4.178986 , -3.9884882, -3.9543579, -3.9225807],\n", + " dtype=float32)),\n", + " (array([ 69, 31, 43, 19, 121, 1380, 36, 279, 62, 118],\n", + " dtype=int32),\n", + " array([311.12405, 311.16483, 311.31955, 311.33456, 311.4418 , 311.4979 ,\n", + " 311.49832, 311.6392 , 311.64697, 311.6873 ], dtype=float32)),\n", + " (array([ 19, 43, 62, 31, 279, 358, 32, 1287, 176, 884],\n", + " dtype=int32),\n", + " array([-13.498163 , -13.462343 , -13.3111315, -13.301067 , -13.287409 ,\n", + " -13.181221 , -13.180961 , -13.051083 , -12.99551 , -12.987873 ],\n", + " dtype=float32)),\n", + " (array([ 19, 43, 31, 62, 32, 1287, 279, 121, 173, 206],\n", + " dtype=int32),\n", + " array([346.14276, 346.33078, 346.54584, 346.61905, 346.6322 , 346.8345 ,\n", + " 347.00287, 347.00433, 347.03168, 347.09067], dtype=float32)),\n", + " (array([255, 19, 31, 32, 43, 62, 173, 86, 121, 100], dtype=int32),\n", + " array([-11.674228 , -11.6636915, -11.418348 , -11.235206 , -11.090764 ,\n", + " -10.999236 , -10.917635 , -10.90773 , -10.886088 , -10.836512 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 32, 100, 12, 43, 173, 105], dtype=int32),\n", + " array([313.2493 , 313.63666, 313.63754, 313.67752, 313.79147, 314.04398,\n", + " 314.0734 , 314.182 , 314.2183 , 314.33435], dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 62, 8, 121, 166, 149, 240], dtype=int32),\n", + " array([300.4301 , 300.81973, 301.03027, 301.10568, 301.20944, 301.23923,\n", + " 301.24026, 301.4705 , 301.59702, 301.64597], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([312.38693, 312.56485, 312.79868, 312.9118 , 312.96448, 313.01743,\n", + " 313.2544 , 313.3963 , 313.45984, 313.4765 ], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 173, 268, 121, 120, 206], dtype=int32),\n", + " array([343.74115, 343.75327, 343.8907 , 344.07642, 344.3839 , 344.4377 ,\n", + " 344.45563, 344.56604, 344.61426, 344.68433], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 268, 305, 121, 49, 105], dtype=int32),\n", + " array([341.80322, 342.03247, 342.04666, 342.18524, 342.57547, 342.61423,\n", + " 342.84094, 342.85788, 342.93777, 342.96387], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 268, 86, 173, 255], dtype=int32),\n", + " array([346.51434, 346.7377 , 346.85852, 346.95734, 347.4286 , 347.53882,\n", + " 347.56973, 347.5792 , 347.5964 , 347.65454], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 62, 164, 120, 268, 121, 49], dtype=int32),\n", + " array([343.4146 , 343.6639 , 343.73102, 343.73853, 343.77475, 344.19873,\n", + " 344.2149 , 344.2228 , 344.2883 , 344.37488], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 255, 121, 305, 86, 29, 120], dtype=int32),\n", + " array([-10.457267 , -10.199842 , -10.056412 , -10.019432 , -9.73673 ,\n", + " -9.598978 , -9.5876045, -9.586909 , -9.564742 , -9.555381 ],\n", + " dtype=float32)),\n", + " (array([ 32, 43, 31, 19, 62, 121, 49, 268, 164, 487], dtype=int32),\n", + " array([318.75555, 318.81253, 318.93958, 318.98978, 319.0273 , 319.19647,\n", + " 319.23032, 319.41107, 319.48895, 319.50415], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 62, 120, 29, 268, 100], dtype=int32),\n", + " array([254.81033, 255.18977, 255.28316, 255.511 , 255.53236, 255.77988,\n", + " 255.91238, 255.92043, 255.99403, 256.05164], dtype=float32)),\n", + " (array([ 262, 149, 153, 8, 1482, 1639, 1118, 2412, 489, 1812],\n", + " dtype=int32),\n", + " array([317.41687, 317.56653, 317.7066 , 317.82538, 317.89273, 317.96765,\n", + " 318.0459 , 318.08994, 318.1292 , 318.16635], dtype=float32)),\n", + " (array([ 31, 19, 121, 43, 86, 32, 62, 100, 29, 120], dtype=int32),\n", + " array([317.84995, 318.14557, 318.17056, 318.24088, 318.32578, 318.43365,\n", + " 318.4487 , 318.6564 , 318.73923, 318.74817], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 268, 62, 173, 255, 29], dtype=int32),\n", + " array([-11.918893 , -11.851038 , -11.449318 , -11.2708025, -11.181248 ,\n", + " -10.961428 , -10.921991 , -10.880789 , -10.856545 , -10.822323 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 43, 62, 103, 268, 173, 120], dtype=int32),\n", + " array([-8.072788 , -7.4184704, -7.1753187, -6.992097 , -6.8998375,\n", + " -6.861067 , -6.808331 , -6.784878 , -6.7715316, -6.6240177],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 32, 279, 36, 86, 69, 62, 31, 2314],\n", + " dtype=int32),\n", + " array([314.96353, 315.24908, 315.40234, 315.4431 , 315.54752, 315.59293,\n", + " 315.60843, 315.65335, 315.69095, 315.7788 ], dtype=float32)),\n", + " (array([ 19, 43, 86, 31, 62, 268, 173, 164, 32, 255], dtype=int32),\n", + " array([266.12836, 266.34158, 266.53992, 266.57846, 266.6248 , 266.66907,\n", + " 266.8483 , 266.87323, 266.91437, 266.9621 ], dtype=float32)),\n", + " (array([ 19, 31, 43, 173, 62, 121, 8, 805, 884, 358], dtype=int32),\n", + " array([-13.432019 , -13.183143 , -13.1153345, -13.080894 , -13.043508 ,\n", + " -12.704055 , -12.695368 , -12.690328 , -12.667596 , -12.649502 ],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 268, 173, 29, 62, 100, 258], dtype=int32),\n", + " array([324.7802 , 325.19388, 325.2295 , 325.4271 , 325.95062, 325.9603 ,\n", + " 325.97086, 326.07904, 326.08762, 326.10327], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 32, 43, 173, 268, 100, 120], dtype=int32),\n", + " array([347.06757, 347.46185, 347.6805 , 347.8658 , 347.87683, 347.93518,\n", + " 348.1861 , 348.2632 , 348.32953, 348.40472], dtype=float32)),\n", + " (array([ 43, 62, 32, 149, 279, 16, 31, 974, 49, 69], dtype=int32),\n", + " array([333.1162 , 333.86624, 333.88013, 333.98053, 334.08423, 334.1702 ,\n", + " 334.18555, 334.21033, 334.2319 , 334.2333 ], dtype=float32)),\n", + " (array([ 43, 19, 31, 279, 32, 8, 149, 262, 86, 62], dtype=int32),\n", + " array([-8.601656 , -8.325794 , -8.261889 , -8.244502 , -8.2417555,\n", + " -8.131131 , -8.119339 , -8.071309 , -7.9272113, -7.9017315],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 166, 62, 69, 120, 36], dtype=int32),\n", + " array([263.0741 , 263.11826, 263.31097, 263.32892, 263.53125, 263.75156,\n", + " 263.9524 , 264.02557, 264.06003, 264.07492], dtype=float32)),\n", + " (array([ 8, 149, 32, 262, 57, 1619, 43, 539, 0, 153],\n", + " dtype=int32),\n", + " array([296.08334, 296.18127, 296.4126 , 296.50995, 296.5372 , 296.57828,\n", + " 296.584 , 296.58594, 296.5934 , 296.60336], dtype=float32)),\n", + " (array([ 31, 32, 43, 121, 19, 62, 268, 100, 173, 358], dtype=int32),\n", + " array([347.23248, 347.32788, 347.4656 , 347.63852, 347.6817 , 347.76965,\n", + " 347.83038, 347.9075 , 348.03604, 348.16458], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 255, 29, 268, 305, 121, 62], dtype=int32),\n", + " array([272.09662, 272.55447, 272.68497, 273.05173, 273.14047, 273.30502,\n", + " 273.47324, 273.5242 , 273.60577, 273.63638], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 149, 62, 8, 262, 121, 552], dtype=int32),\n", + " array([-14.825947, -14.819177, -14.812019, -14.472718, -14.465967,\n", + " -14.454661, -14.301346, -14.280471, -14.038158, -13.899126],\n", + " dtype=float32)),\n", + " (array([ 32, 43, 19, 62, 31, 279, 173, 36, 100, 121], dtype=int32),\n", + " array([313.90482, 313.91418, 314.0386 , 314.4915 , 314.56784, 314.6367 ,\n", + " 314.69028, 314.75497, 314.76318, 314.82654], dtype=float32)),\n", + " (array([ 19, 31, 121, 173, 32, 255, 268, 413, 100, 29], dtype=int32),\n", + " array([6.3029566, 6.325471 , 7.1249914, 7.1439323, 7.271358 , 7.3472466,\n", + " 7.4028363, 7.4395614, 7.4518304, 7.455539 ], dtype=float32)),\n", + " (array([ 31, 43, 86, 62, 121, 19, 120, 32, 103, 164], dtype=int32),\n", + " array([342.04462, 342.42197, 342.5576 , 342.65054, 342.6946 , 342.70132,\n", + " 342.73474, 342.8664 , 342.872 , 342.95425], dtype=float32)),\n", + " (array([ 19, 32, 31, 121, 62, 100, 173, 43, 268, 29], dtype=int32),\n", + " array([248.1499 , 248.47305, 248.52277, 248.6679 , 248.702 , 248.87695,\n", + " 248.94843, 249.04689, 249.1632 , 249.39273], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 121, 62, 268, 173, 100, 29], dtype=int32),\n", + " array([301.9033 , 302.1271 , 302.23303, 302.2696 , 302.42734, 302.58698,\n", + " 302.65298, 302.69012, 302.76334, 302.8002 ], dtype=float32)),\n", + " (array([ 43, 31, 62, 19, 121, 86, 32, 49, 164, 112], dtype=int32),\n", + " array([303.49542, 303.6827 , 303.68573, 303.71063, 303.96054, 303.96176,\n", + " 303.98175, 303.98785, 304.0541 , 304.07434], dtype=float32)),\n", + " (array([ 62, 31, 32, 43, 19, 100, 121, 49, 36, 86], dtype=int32),\n", + " array([311.4336 , 311.6961 , 311.69638, 311.7958 , 311.79938, 311.9889 ,\n", + " 312.01828, 312.07907, 312.0808 , 312.13287], dtype=float32)),\n", + " (array([ 31, 19, 121, 43, 62, 32, 86, 255, 173, 100], dtype=int32),\n", + " array([54.50405 , 54.84396 , 54.866604, 54.930305, 54.956398, 55.073605,\n", + " 55.08074 , 55.2308 , 55.32757 , 55.469753], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 255, 268, 121, 103, 62, 29], dtype=int32),\n", + " array([-5.7195597, -5.137107 , -4.9554033, -4.932697 , -4.9061317,\n", + " -4.82989 , -4.7904043, -4.751795 , -4.6291876, -4.48692 ],\n", + " dtype=float32)),\n", + " (array([ 552, 31, 149, 835, 262, 965, 57, 1842, 19, 43],\n", + " dtype=int32),\n", + " array([347.87418, 347.95306, 348.28564, 348.4731 , 348.5061 , 348.68365,\n", + " 348.72757, 348.76346, 348.85397, 348.87277], dtype=float32)),\n", + " (array([450, 62, 262, 149, 36, 8, 735, 121, 32, 240], dtype=int32),\n", + " array([312.70087, 312.7531 , 312.84186, 312.9744 , 313.0297 , 313.03146,\n", + " 313.1576 , 313.16327, 313.3068 , 313.30963], dtype=float32)),\n", + " (array([ 31, 19, 255, 43, 32, 164, 29, 62, 86, 268], dtype=int32),\n", + " array([294.09708, 294.1484 , 294.27658, 294.51968, 294.6763 , 294.70798,\n", + " 294.87708, 294.95593, 294.9791 , 295.0429 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 62, 100, 173, 8, 105], dtype=int32),\n", + " array([288.44452, 288.84558, 288.85104, 288.98502, 289.20908, 289.24036,\n", + " 289.36612, 289.42758, 289.54694, 289.65704], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 121, 268, 100, 49, 305], dtype=int32),\n", + " array([287.98804, 288.0021 , 288.09988, 288.15427, 288.5115 , 288.59036,\n", + " 288.79196, 288.864 , 288.92755, 288.92938], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 121, 173, 255, 268, 100], dtype=int32),\n", + " array([-7.956836 , -7.9356647, -7.574913 , -7.4195814, -7.0172944,\n", + " -6.934751 , -6.877664 , -6.770093 , -6.7122035, -6.6966424],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 62, 173, 43, 121, 8, 262, 149], dtype=int32),\n", + " array([346.29276, 346.6341 , 346.89227, 346.91644, 347.08945, 347.1381 ,\n", + " 347.16867, 347.32584, 347.33835, 347.3591 ], dtype=float32)),\n", + " (array([ 32, 43, 31, 62, 19, 49, 121, 304, 120, 273], dtype=int32),\n", + " array([336.41507, 336.43527, 336.65244, 336.6793 , 336.85248, 336.86942,\n", + " 337.0669 , 337.0924 , 337.20065, 337.20428], dtype=float32)),\n", + " (array([ 32, 31, 19, 186, 268, 305, 120, 43, 29, 42], dtype=int32),\n", + " array([297.26376, 297.3984 , 297.81757, 298.0148 , 298.08005, 298.13547,\n", + " 298.13654, 298.1406 , 298.26038, 298.29224], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 173, 121, 100, 268, 206], dtype=int32),\n", + " array([315.2561 , 315.4535 , 315.4661 , 315.55038, 315.61688, 315.9148 ,\n", + " 315.9269 , 316.12347, 316.18835, 316.25485], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 268, 173, 29, 121, 62, 105], dtype=int32),\n", + " array([345.83286, 346.3137 , 346.4924 , 346.56885, 347.09875, 347.2348 ,\n", + " 347.23523, 347.30048, 347.3587 , 347.42896], dtype=float32)),\n", + " (array([ 32, 43, 31, 62, 19, 120, 86, 121, 268, 112], dtype=int32),\n", + " array([310.65442, 310.74933, 310.94492, 311.0456 , 311.14282, 311.39108,\n", + " 311.4273 , 311.485 , 311.53815, 311.635 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-4.9424825, -4.9155636, -4.385795 , -4.3284597, -4.3199773,\n", + " -4.147278 , -4.1336265, -3.9436584, -3.912855 , -3.8884976],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 268, 100, 49, 120], dtype=int32),\n", + " array([341.3728 , 341.47614, 341.48126, 341.53735, 341.7902 , 342.04984,\n", + " 342.25253, 342.25882, 342.29233, 342.42172], dtype=float32)),\n", + " (array([ 31, 32, 62, 43, 19, 121, 120, 268, 8, 86], dtype=int32),\n", + " array([244.13846, 244.18678, 244.64307, 244.72765, 244.75182, 244.8955 ,\n", + " 244.92314, 244.93623, 245.28328, 245.29587], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 121, 268, 100, 305, 49], dtype=int32),\n", + " array([288.06125, 288.07013, 288.17285, 288.21442, 288.57718, 288.675 ,\n", + " 288.8593 , 288.93582, 288.99738, 288.9982 ], dtype=float32)),\n", + " (array([ 62, 31, 43, 121, 19, 32, 49, 8, 164, 149], dtype=int32),\n", + " array([306.9274 , 307.0448 , 307.23932, 307.30054, 307.3653 , 307.40097,\n", + " 307.46902, 307.54773, 307.61206, 307.63544], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 100, 49, 279, 268], dtype=int32),\n", + " array([330.16483, 330.30557, 330.34036, 330.44366, 330.65872, 330.86734,\n", + " 331.03766, 331.1014 , 331.19858, 331.20575], dtype=float32)),\n", + " (array([ 31, 130, 19, 121, 43, 358, 173, 62, 32, 21], dtype=int32),\n", + " array([343.72333, 344.38858, 344.43488, 344.45816, 344.56247, 344.56253,\n", + " 344.70657, 344.7167 , 344.72083, 344.7534 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 120, 268, 173, 105], dtype=int32),\n", + " array([-19.018951, -18.657345, -18.235214, -18.119884, -18.018509,\n", + " -17.952024, -17.932493, -17.826878, -17.576494, -17.56839 ],\n", + " dtype=float32)),\n", + " (array([ 31, 103, 19, 121, 501, 703, 441, 392, 535, 384], dtype=int32),\n", + " array([305.8875 , 306.49344, 306.54022, 306.76788, 306.91516, 306.94485,\n", + " 306.98056, 307.00214, 307.0751 , 307.09073], dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 29, 173, 43, 268, 105, 100], dtype=int32),\n", + " array([307.13513, 307.40985, 307.68033, 307.68445, 308.14465, 308.25616,\n", + " 308.2985 , 308.37585, 308.38162, 308.38895], dtype=float32)),\n", + " (array([ 8, 19, 262, 32, 3146, 153, 31, 1482, 43, 0],\n", + " dtype=int32),\n", + " array([-3.0451965, -2.9343429, -2.7803874, -2.6331844, -2.576582 ,\n", + " -2.5600913, -2.5204046, -2.5034306, -2.4394426, -2.421362 ],\n", + " dtype=float32)),\n", + " (array([ 69, 43, 19, 31, 32, 36, 62, 279, 121, 118], dtype=int32),\n", + " array([289.3832 , 289.42673, 289.47562, 289.5072 , 289.5677 , 289.6243 ,\n", + " 289.6437 , 289.69308, 289.7579 , 289.7609 ], dtype=float32)),\n", + " (array([262, 19, 149, 8, 32, 31, 450, 369, 153, 43], dtype=int32),\n", + " array([328.5683 , 328.8512 , 328.91037, 329.08716, 329.08926, 329.09625,\n", + " 329.1799 , 329.24945, 329.41547, 329.54727], dtype=float32)),\n", + " (array([ 43, 32, 149, 262, 62, 19, 8, 31, 86, 835], dtype=int32),\n", + " array([344.51297, 344.73776, 344.90802, 344.9234 , 344.97308, 344.98062,\n", + " 344.9881 , 345.18948, 345.34314, 345.34973], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([312.34116, 312.52338, 312.74097, 312.84436, 312.89795, 312.96802,\n", + " 313.1962 , 313.33765, 313.39905, 313.41345], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", + " array([310.37195, 310.48438, 310.73236, 310.7921 , 310.9571 , 311.06403,\n", + " 311.26767, 311.38147, 311.46518, 311.48535], dtype=float32)),\n", + " (array([ 31, 62, 32, 19, 43, 121, 8, 49, 149, 450], dtype=int32),\n", + " array([319.09277, 319.0982 , 319.16324, 319.30203, 319.4725 , 319.65445,\n", + " 319.73773, 319.7948 , 319.81293, 319.8161 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 86, 100, 173, 268], dtype=int32),\n", + " array([51.56032 , 51.64509 , 51.89514 , 52.040867, 52.113083, 52.160084,\n", + " 52.437153, 52.49843 , 52.52908 , 52.57915 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 29, 121, 62, 86, 255, 100], dtype=int32),\n", + " array([286.01556, 286.208 , 286.4942 , 286.679 , 286.76297, 286.83844,\n", + " 286.89044, 287.01797, 287.05484, 287.13095], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 43, 103, 173, 268, 32, 120], dtype=int32),\n", + " array([-19.457333, -18.714315, -18.369879, -18.300188, -18.220444,\n", + " -18.181852, -18.168312, -18.15627 , -17.997553, -17.949684],\n", + " dtype=float32)),\n", + " (array([ 21, 31, 12, 19, 121, 173, 29, 268, 24, 100], dtype=int32),\n", + " array([321.90228, 322.1381 , 322.27518, 322.32233, 322.91846, 323.1344 ,\n", + " 323.2252 , 323.387 , 323.4961 , 323.51328], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 32, 43, 8, 173, 358, 86], dtype=int32),\n", + " array([310.6909 , 311.09784, 311.26416, 311.31766, 311.43814, 311.49664,\n", + " 311.57227, 311.67944, 311.79572, 311.9097 ], dtype=float32)),\n", + " (array([ 8, 31, 121, 19, 735, 552, 62, 1218, 262, 32],\n", + " dtype=int32),\n", + " array([54.73985 , 54.921024, 55.124485, 55.196564, 55.243668, 55.385918,\n", + " 55.392246, 55.454796, 55.46576 , 55.48683 ], dtype=float32)),\n", + " (array([ 43, 32, 19, 255, 31, 305, 96, 62, 86, 371], dtype=int32),\n", + " array([237.34068, 237.68623, 237.89716, 237.90114, 237.9998 , 238.02856,\n", + " 238.17896, 238.23405, 238.24007, 238.33682], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.89243, 345.13293, 345.28214, 345.36203, 345.4125 , 345.55585,\n", + " 345.78702, 345.90482, 345.98175, 346.0863 ], dtype=float32)),\n", + " (array([ 31, 19, 12, 121, 32, 268, 62, 43, 103, 173], dtype=int32),\n", + " array([-5.8817196, -5.2614293, -5.0825977, -4.850183 , -4.729859 ,\n", + " -4.609657 , -4.492527 , -4.4885426, -4.429251 , -4.3971024],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 121, 86, 100, 173, 255], dtype=int32),\n", + " array([286.65735, 286.82874, 286.86823, 286.889 , 287.12677, 287.4117 ,\n", + " 287.64365, 287.67285, 287.68365, 287.69443], dtype=float32)),\n", + " (array([ 31, 19, 62, 32, 121, 49, 43, 164, 268, 214], dtype=int32),\n", + " array([259.6416 , 259.8257 , 259.9938 , 260.0587 , 260.2523 , 260.3186 ,\n", + " 260.37897, 260.41946, 260.43362, 260.54105], dtype=float32)),\n", + " (array([ 31, 43, 32, 121, 62, 19, 268, 255, 120, 100], dtype=int32),\n", + " array([52.12003 , 52.398285, 52.594257, 52.736996, 52.96305 , 52.977146,\n", + " 53.001183, 53.079437, 53.10935 , 53.13721 ], dtype=float32)),\n", + " (array([ 43, 32, 279, 19, 528, 974, 204, 305, 13, 791], dtype=int32),\n", + " array([283.63626, 283.77692, 284.06302, 284.1349 , 284.19046, 284.28247,\n", + " 284.3817 , 284.43475, 284.45874, 284.48535], dtype=float32)),\n", + " (array([ 43, 31, 62, 86, 32, 19, 121, 112, 49, 279], dtype=int32),\n", + " array([-18.087584, -17.803343, -17.760427, -17.6359 , -17.602201,\n", + " -17.509865, -17.246746, -17.181599, -17.159885, -17.151201],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 121, 268, 49, 100, 305], dtype=int32),\n", + " array([320.65054, 320.68423, 320.79788, 320.80612, 321.1471 , 321.32733,\n", + " 321.48364, 321.56665, 321.5726 , 321.64294], dtype=float32)),\n", + " (array([ 19, 31, 12, 121, 100, 32, 173, 86, 43, 62], dtype=int32),\n", + " array([286.94623, 287.03894, 287.05435, 287.30106, 287.31995, 287.3615 ,\n", + " 287.47394, 287.5053 , 287.51355, 287.56003], dtype=float32)),\n", + " (array([ 32, 43, 19, 305, 31, 268, 111, 42, 188, 206], dtype=int32),\n", + " array([291.84128, 291.9949 , 292.1734 , 292.54523, 292.66608, 292.87045,\n", + " 292.89758, 292.92374, 292.92386, 293.15448], dtype=float32)),\n", + " (array([ 31, 32, 19, 121, 43, 268, 173, 62, 12, 255], dtype=int32),\n", + " array([-11.100351, -10.468095, -10.466587, -10.253364, -10.097407,\n", + " -10.064852, -10.018247, -10.006114, -9.914094, -9.739739],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-4.9254117, -4.903883 , -4.3681984, -4.30716 , -4.300051 ,\n", + " -4.1327434, -4.114312 , -3.93446 , -3.8890843, -3.8635614],\n", + " dtype=float32)),\n", + " (array([ 32, 43, 8, 19, 305, 62, 121, 31, 49, 100], dtype=int32),\n", + " array([306.1436 , 306.63864, 306.75577, 307.041 , 307.17163, 307.19968,\n", + " 307.22598, 307.24814, 307.2702 , 307.34793], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 29, 255, 121, 12, 62, 268], dtype=int32),\n", + " array([289.3988 , 289.4781 , 289.83536, 289.93164, 290.13113, 290.13934,\n", + " 290.26428, 290.29208, 290.29382, 290.3108 ], dtype=float32)),\n", + " (array([ 31, 19, 255, 121, 32, 62, 43, 29, 268, 164], dtype=int32),\n", + " array([236.59924, 237.13544, 237.53168, 237.56348, 237.56618, 237.57274,\n", + " 237.65794, 237.77704, 237.81342, 237.84462], dtype=float32)),\n", + " (array([ 19, 31, 32, 62, 43, 173, 121, 268, 255, 164], dtype=int32),\n", + " array([329.14563, 329.3854 , 329.7733 , 329.97467, 330.03122, 330.2544 ,\n", + " 330.2798 , 330.2937 , 330.398 , 330.42133], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 173, 62, 121, 268, 358, 100], dtype=int32),\n", + " array([350.68387, 350.69342, 350.80106, 350.90695, 351.0972 , 351.2773 ,\n", + " 351.43848, 351.56934, 351.61655, 351.70245], dtype=float32)),\n", + " (array([ 31, 12, 21, 19, 121, 173, 100, 29, 62, 61], dtype=int32),\n", + " array([316.48135, 316.85742, 317.19247, 317.21408, 317.22467, 317.45316,\n", + " 317.4648 , 317.57352, 317.575 , 317.6446 ], dtype=float32)),\n", + " (array([3162, 2310, 1342, 5058, 905, 1026, 4326, 21, 2881, 34],\n", + " dtype=int32),\n", + " array([300.90842, 300.96997, 301.74078, 303.49213, 303.60464, 303.88052,\n", + " 304.16605, 304.49786, 304.53943, 304.6457 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 86, 268], dtype=int32),\n", + " array([279.22168, 279.36438, 279.5201 , 279.55054, 279.60898, 279.7201 ,\n", + " 279.91702, 280.13342, 280.1468 , 280.19965], dtype=float32)),\n", + " (array([ 19, 43, 32, 36, 418, 262, 279, 62, 118, 69], dtype=int32),\n", + " array([262.0025 , 262.25748, 262.27625, 262.38562, 262.4314 , 262.49762,\n", + " 262.53442, 262.5364 , 262.58148, 262.60675], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 149, 100, 279, 262, 8], dtype=int32),\n", + " array([323.7864 , 323.8769 , 324.02374, 324.26825, 324.6423 , 324.68677,\n", + " 324.83203, 324.86484, 324.9063 , 324.97763], dtype=float32)),\n", + " (array([ 19, 358, 31, 43, 636, 173, 884, 32, 258, 176], dtype=int32),\n", + " array([298.38684, 298.8378 , 298.9924 , 299.0933 , 299.1338 , 299.2397 ,\n", + " 299.26535, 299.31244, 299.31366, 299.41064], dtype=float32)),\n", + " (array([ 31, 43, 19, 62, 121, 32, 49, 100, 105, 268], dtype=int32),\n", + " array([324.07172, 324.1925 , 324.25323, 324.29153, 324.4124 , 324.43683,\n", + " 324.5018 , 324.7881 , 324.86203, 324.9179 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 62, 173, 268, 100, 49], dtype=int32),\n", + " array([291.8476 , 291.9148 , 291.9484 , 292.0435 , 292.17603, 292.33145,\n", + " 292.61664, 292.68683, 292.79715, 292.80698], dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", + " array([311.9987 , 312.1394 , 312.24393, 312.28568, 312.32852, 312.52313,\n", + " 312.68362, 312.9114 , 312.96066, 312.9829 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", + " array([-5.125645 , -5.1117697, -4.5883775, -4.522718 , -4.5065985,\n", + " -4.3377857, -4.3346972, -4.136434 , -4.100578 , -4.072297 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 121, 62, 268, 86, 29, 173], dtype=int32),\n", + " array([-11.173502, -10.861092, -10.504527, -10.411109, -10.17119 ,\n", + " -10.068164, -10.056534, -9.945865, -9.90956 , -9.853734],\n", + " dtype=float32)),\n", + " (array([ 31, 262, 8, 32, 149, 19, 43, 255, 62, 121], dtype=int32),\n", + " array([238.19867, 238.20563, 238.34206, 238.37549, 238.5953 , 238.60184,\n", + " 238.61967, 238.65845, 238.69276, 238.80728], dtype=float32)),\n", + " (array([ 31, 32, 62, 43, 121, 19, 86, 120, 100, 268], dtype=int32),\n", + " array([310.1455 , 310.4189 , 310.43335, 310.5555 , 310.5965 , 310.64008,\n", + " 310.79065, 310.7992 , 310.93652, 311.03946], dtype=float32)),\n", + " (array([ 19, 31, 62, 173, 358, 121, 32, 43, 268, 100], dtype=int32),\n", + " array([317.3086 , 317.36652, 317.98584, 318.00388, 318.0438 , 318.06528,\n", + " 318.24594, 318.34775, 318.3744 , 318.4178 ], dtype=float32)),\n", + " (array([ 31, 19, 173, 121, 12, 32, 62, 43, 29, 268], dtype=int32),\n", + " array([246.55493, 246.71327, 247.36504, 247.43756, 247.46124, 247.46684,\n", + " 247.686 , 247.69244, 247.84915, 247.87175], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 100, 120], dtype=int32),\n", + " array([289.67343, 289.75418, 290.05197, 290.17166, 290.35846, 290.37006,\n", + " 290.55157, 290.72638, 290.83023, 290.83817], dtype=float32)),\n", + " (array([ 31, 62, 121, 32, 19, 164, 49, 214, 100, 43], dtype=int32),\n", + " array([-17.452925, -17.082415, -16.977293, -16.79991 , -16.761396,\n", + " -16.711647, -16.59783 , -16.554043, -16.549341, -16.547562],\n", + " dtype=float32)),\n", + " (array([ 31, 43, 32, 121, 62, 120, 19, 268, 214, 100], dtype=int32),\n", + " array([342.10764, 342.40393, 342.601 , 342.6924 , 342.75443, 342.77255,\n", + " 342.8065 , 342.99075, 343.05145, 343.09598], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 552, 32, 100, 173, 262, 8], dtype=int32),\n", + " array([345.06534, 345.51395, 345.66486, 345.87442, 346.02188, 346.09512,\n", + " 346.17108, 346.2074 , 346.23413, 346.28485], dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 62, 120, 121, 100, 268, 49], dtype=int32),\n", + " array([338.6435 , 338.65988, 338.90436, 339.03046, 339.0824 , 339.27548,\n", + " 339.27863, 339.42453, 339.45117, 339.62817], dtype=float32)),\n", + " (array([ 32, 176, 43, 62, 240, 36, 358, 49, 449, 19], dtype=int32),\n", + " array([285.83398, 285.93173, 285.99463, 286.08954, 286.13916, 286.21014,\n", + " 286.2114 , 286.2278 , 286.27185, 286.3039 ], dtype=float32)),\n", + " (array([ 19, 8, 149, 262, 450, 0, 735, 31, 369, 325], dtype=int32),\n", + " array([-9.226801, -9.138501, -9.127476, -9.110326, -8.955484, -8.905296,\n", + " -8.892906, -8.806453, -8.670199, -8.623948], dtype=float32)),\n", + " (array([2181, 884, 176, 358, 1959, 43, 636, 39, 19, 258],\n", + " dtype=int32),\n", + " array([312.3727 , 312.49234, 312.83072, 313.08078, 313.12247, 313.15717,\n", + " 313.2025 , 313.2346 , 313.25156, 313.26837], dtype=float32)),\n", + " (array([ 43, 32, 305, 19, 374, 884, 206, 176, 188, 115], dtype=int32),\n", + " array([336.69034, 336.88113, 336.89825, 337.05707, 337.06216, 337.26108,\n", + " 337.35245, 337.37723, 337.4164 , 337.41843], dtype=float32)),\n", + " (array([ 32, 43, 62, 305, 31, 19, 49, 186, 112, 121], dtype=int32),\n", + " array([342.35617, 342.56393, 342.72467, 342.82828, 342.82965, 342.87332,\n", + " 342.87488, 343.10748, 343.14664, 343.21982], dtype=float32)),\n", + " (array([ 279, 118, 36, 13, 69, 32, 19, 1638, 43, 610],\n", + " dtype=int32),\n", + " array([311.91733, 311.9292 , 312.02463, 312.06647, 312.0825 , 312.10416,\n", + " 312.1174 , 312.15463, 312.15594, 312.20438], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 173, 8, 255, 149], dtype=int32),\n", + " array([-13.143767 , -13.089577 , -12.852583 , -12.779168 , -12.354462 ,\n", + " -12.340083 , -12.334131 , -12.132467 , -12.082108 , -12.0587845],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 62, 268, 121, 120, 29, 100], dtype=int32),\n", + " array([341.08133, 341.08163, 341.2488 , 341.2776 , 341.60825, 341.7576 ,\n", + " 341.79663, 341.8792 , 342.05518, 342.11826], dtype=float32)),\n", + " (array([ 345, 4326, 32, 62, 19, 43, 4738, 279, 36, 240],\n", + " dtype=int32),\n", + " array([313.32443, 313.83334, 313.83386, 313.97906, 314.2233 , 314.2352 ,\n", + " 314.23657, 314.38953, 314.4367 , 314.54684], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 279, 62, 166, 69, 36, 449], dtype=int32),\n", + " array([-15.757784, -15.744331, -15.715742, -15.367012, -15.236301,\n", + " -15.213285, -15.114642, -15.09193 , -15.05998 , -15.049946],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", + " array([-5.0672216, -5.0421457, -4.516862 , -4.4643373, -4.440181 ,\n", + " -4.270182 , -4.265323 , -4.06413 , -4.042031 , -4.0118537],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 121, 268, 206, 358, 173], dtype=int32),\n", + " array([336.34482, 336.53186, 336.6507 , 336.7412 , 336.9497 , 337.23145,\n", + " 337.4187 , 337.49295, 337.50797, 337.5084 ], dtype=float32)),\n", + " (array([ 8, 149, 262, 43, 32, 369, 552, 539, 965, 19], dtype=int32),\n", + " array([259.68927, 259.97995, 260.27322, 260.4497 , 260.45877, 260.51706,\n", + " 260.55112, 260.5933 , 260.64017, 260.67798], dtype=float32)),\n", + " (array([ 19, 32, 255, 43, 31, 86, 62, 121, 120, 268], dtype=int32),\n", + " array([238.10663, 238.45883, 238.5186 , 238.53629, 238.64828, 238.68321,\n", + " 239.056 , 239.14474, 239.14499, 239.14818], dtype=float32)),\n", + " (array([4642, 4841, 7746, 3945, 7054, 2068, 4162, 4991, 5923, 9677],\n", + " dtype=int32),\n", + " array([294.65677, 294.674 , 294.93518, 295.092 , 295.1311 , 295.214 ,\n", + " 295.2705 , 295.28445, 295.35535, 295.3882 ], dtype=float32)),\n", + " (array([ 43, 32, 62, 19, 31, 121, 100, 86, 49, 173], dtype=int32),\n", + " array([310.09192, 310.10608, 310.21176, 310.22104, 310.25888, 310.58765,\n", + " 310.77185, 310.82462, 310.8452 , 310.86765], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 121, 49, 112, 206, 36], dtype=int32),\n", + " array([318.88223, 318.92676, 319.1155 , 319.21268, 319.63818, 319.7363 ,\n", + " 319.8082 , 319.86127, 319.87927, 319.89987], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.993 , 345.20337, 345.35373, 345.4528 , 345.50842, 345.66574,\n", + " 345.88208, 345.9896 , 346.079 , 346.14886], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 121, 305, 86, 268, 255], dtype=int32),\n", + " array([-18.160736, -18.065302, -17.91232 , -17.910124, -17.429615,\n", + " -17.244274, -16.985851, -16.967516, -16.955187, -16.945377],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 121, 32, 62, 12, 173, 100, 29], dtype=int32),\n", + " array([264.25854, 264.44696, 264.95026, 265.03864, 265.04504, 265.0693 ,\n", + " 265.08334, 265.21765, 265.37256, 265.39532], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 268, 173, 62, 121, 100, 16], dtype=int32),\n", + " array([311.671 , 311.94263, 312.1423 , 312.3241 , 312.49414, 312.51218,\n", + " 312.54413, 312.64603, 312.88562, 312.89212], dtype=float32)),\n", + " (array([186, 371, 305, 31, 32, 558, 43, 62, 19, 848], dtype=int32),\n", + " array([259.57016, 260.4812 , 260.4939 , 260.5783 , 260.58813, 260.61566,\n", + " 260.6213 , 260.65884, 260.70975, 260.72714], dtype=float32)),\n", + " (array([ 19, 31, 121, 29, 32, 268, 62, 164, 43, 100], dtype=int32),\n", + " array([262.64905, 262.70822, 263.1871 , 263.19998, 263.2875 , 263.45972,\n", + " 263.49454, 263.61014, 263.64963, 263.6571 ], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 279, 342, 86, 173, 62, 255], dtype=int32),\n", + " array([-2.325954 , -2.287641 , -2.1654544, -1.9056807, -1.7842443,\n", + " -1.556874 , -1.514475 , -1.399868 , -1.3974245, -1.3832269],\n", + " dtype=float32)),\n", + " (array([ 62, 31, 19, 43, 32, 121, 8, 49, 149, 262], dtype=int32),\n", + " array([283.57202, 283.61777, 283.70404, 283.72073, 283.8724 , 283.9825 ,\n", + " 284.1056 , 284.21057, 284.28726, 284.42126], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 8, 100, 173, 268], dtype=int32),\n", + " array([320.68927, 320.87653, 320.9814 , 321.06622, 321.2445 , 321.30072,\n", + " 321.51376, 321.53784, 321.58566, 321.5869 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 29, 268, 62, 121, 105, 100], dtype=int32),\n", + " array([296.44696, 296.53885, 296.69055, 297.06415, 297.24615, 297.2801 ,\n", + " 297.3722 , 297.45248, 297.47623, 297.5988 ], dtype=float32)),\n", + " (array([2855, 19, 1584, 3209, 3351, 2181, 2977, 2953, 2430, 173],\n", + " dtype=int32),\n", + " array([-4.4399524, -4.162832 , -4.1061625, -3.9151645, -3.851419 ,\n", + " -3.7650146, -3.76427 , -3.6905649, -3.5535915, -3.530046 ],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 204, 43, 69, 258, 1184, 528, 31, 449],\n", + " dtype=int32),\n", + " array([292.26984, 292.46652, 292.58127, 292.82812, 292.9008 , 292.9639 ,\n", + " 292.96918, 293.0168 , 293.08652, 293.13058], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 268, 173, 358, 121, 120], dtype=int32),\n", + " array([341.7703 , 341.82343, 341.96713, 342.08362, 342.3323 , 342.35565,\n", + " 342.4744 , 342.6446 , 342.7415 , 342.7637 ], dtype=float32)),\n", + " (array([149, 735, 262, 8, 552, 57, 965, 450, 0, 539], dtype=int32),\n", + " array([314.68176, 314.86447, 314.8728 , 315.0222 , 315.12167, 315.1287 ,\n", + " 315.1573 , 315.17343, 315.25256, 315.2745 ], dtype=float32)),\n", + " (array([ 62, 31, 32, 43, 19, 86, 121, 49, 186, 112], dtype=int32),\n", + " array([263.61386, 263.68927, 263.72574, 263.7482 , 263.8793 , 264.08072,\n", + " 264.09268, 264.1364 , 264.20877, 264.3623 ], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 29, 86, 121, 268, 173, 62], dtype=int32),\n", + " array([-12.726268 , -12.408381 , -12.290524 , -11.975763 , -11.887823 ,\n", + " -11.756745 , -11.6794405, -11.597747 , -11.57287 , -11.558551 ],\n", + " dtype=float32)),\n", + " (array([121, 19, 31, 12, 173, 100, 86, 62, 46, 43], dtype=int32),\n", + " array([-4.0464287, -4.0107164, -3.9052997, -3.682777 , -3.5255613,\n", + " -3.4323666, -3.3947074, -3.3778327, -3.3165789, -3.2057178],\n", + " dtype=float32)),\n", + " (array([ 31, 43, 32, 19, 62, 121, 100, 86, 268, 173], dtype=int32),\n", + " array([308.93225, 309.0416 , 309.14764, 309.39368, 309.73505, 309.7393 ,\n", + " 309.9714 , 309.9879 , 310.1388 , 310.14453], dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 32, 43, 105, 100, 12, 268], dtype=int32),\n", + " array([347.7162 , 347.99213, 348.09198, 348.4327 , 348.53653, 348.6337 ,\n", + " 348.70117, 348.74374, 348.81705, 348.8452 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 258, 121, 358, 173, 268], dtype=int32),\n", + " array([259.4922 , 259.61646, 259.82053, 259.82526, 259.8572 , 260.27432,\n", + " 260.27792, 260.283 , 260.3097 , 260.38434], dtype=float32)),\n", + " (array([ 31, 19, 12, 121, 21, 29, 62, 32, 268, 173], dtype=int32),\n", + " array([-5.5620747, -4.9823895, -4.930903 , -4.861179 , -4.5280743,\n", + " -4.429846 , -4.4135256, -4.3969235, -4.373354 , -4.353081 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 268, 121, 86, 173, 120], dtype=int32),\n", + " array([313.7979 , 314.0508 , 314.1509 , 314.2101 , 314.5619 , 314.6413 ,\n", + " 314.6524 , 314.7491 , 314.75592, 314.81573], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 49, 305, 121, 100, 8], dtype=int32),\n", + " array([343.2616 , 343.43646, 343.54895, 343.6925 , 343.9715 , 344.00845,\n", + " 344.05222, 344.26 , 344.38644, 344.4242 ], dtype=float32)),\n", + " (array([ 19, 31, 255, 86, 32, 121, 173, 43, 62, 29], dtype=int32),\n", + " array([267.66257, 267.93002, 268.08368, 268.35587, 268.56754, 268.57025,\n", + " 268.59268, 268.59445, 268.62003, 268.77203], dtype=float32)),\n", + " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", + " array([-5.037884 , -5.0113072, -4.4723964, -4.4109874, -4.399605 ,\n", + " -4.232592 , -4.2241673, -4.035268 , -4.0049553, -3.958204 ],\n", + " dtype=float32)),\n", + " (array([ 31, 121, 19, 43, 62, 32, 173, 268, 12, 105], dtype=int32),\n", + " array([316.15582, 316.28268, 316.34995, 316.50616, 316.53418, 316.69226,\n", + " 316.6924 , 316.74594, 316.8173 , 316.9725 ], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 62, 173, 268, 121, 358, 120], dtype=int32),\n", + " array([339.40634, 339.42465, 339.62903, 339.79092, 340.04282, 340.28183,\n", + " 340.30557, 340.434 , 340.5182 , 340.5581 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 62, 32, 121, 173, 358, 268, 164], dtype=int32),\n", + " array([-16.94533 , -16.593094, -16.251049, -16.23989 , -16.206335,\n", + " -16.116669, -16.000875, -15.943753, -15.939101, -15.823728],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 268, 164, 100, 29], dtype=int32),\n", + " array([257.90213, 257.9448 , 258.11902, 258.19177, 258.51672, 258.6251 ,\n", + " 258.72946, 258.73135, 258.75577, 258.75784], dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 121, 62, 100, 36, 305, 86], dtype=int32),\n", + " array([345.34592, 345.36462, 345.4666 , 345.80612, 345.91028, 345.9715 ,\n", + " 346.2394 , 346.35544, 346.361 , 346.41788], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.988 , 345.1998 , 345.3611 , 345.4457 , 345.49893, 345.6501 ,\n", + " 345.857 , 345.98996, 346.05872, 346.1615 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 62, 255, 43, 100, 121, 86, 258], dtype=int32),\n", + " array([342.43045, 342.76987, 342.8739 , 342.94647, 342.95477, 342.98242,\n", + " 343.26712, 343.3159 , 343.36328, 343.50333], dtype=float32)),\n", + " (array([ 32, 19, 31, 305, 29, 43, 374, 111, 186, 1145],\n", + " dtype=int32),\n", + " array([347.16852, 347.28668, 347.50537, 347.61746, 347.6677 , 347.7222 ,\n", + " 347.88367, 347.98602, 348.03342, 348.16837], dtype=float32)),\n", + " (array([ 19, 43, 32, 487, 31, 268, 305, 186, 29, 483], dtype=int32),\n", + " array([306.63184, 306.80786, 306.8504 , 307.13535, 307.1441 , 307.1884 ,\n", + " 307.20377, 307.33905, 307.34225, 307.3911 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", + " array([310.39398, 310.51373, 310.7692 , 310.8383 , 310.99908, 311.08456,\n", + " 311.30945, 311.40503, 311.51147, 311.51376], dtype=float32)),\n", + " (array([ 43, 31, 32, 19, 384, 268, 62, 441, 304, 29], dtype=int32),\n", + " array([338.03943, 338.1071 , 338.1291 , 338.34378, 338.3504 , 338.61304,\n", + " 338.66327, 338.7925 , 338.7975 , 338.8082 ], dtype=float32)),\n", + " (array([ 19, 31, 12, 173, 121, 29, 43, 21, 105, 268], dtype=int32),\n", + " array([190.73648, 190.9686 , 191.2562 , 191.86366, 191.87589, 191.95314,\n", + " 192.12808, 192.13351, 192.15643, 192.3491 ], dtype=float32)),\n", + " (array([ 19, 477, 5, 3033, 3141, 173, 31, 32, 4659, 43],\n", + " dtype=int32),\n", + " array([3.430843 , 3.9056013, 4.0418715, 4.046853 , 4.056636 , 4.3053904,\n", + " 4.3968325, 4.487882 , 4.5651164, 4.5840354], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 358, 8, 268, 173, 121], dtype=int32),\n", + " array([341.83475, 342.08228, 342.45984, 342.4907 , 342.54538, 342.69 ,\n", + " 342.72357, 342.73367, 342.74844, 342.7689 ], dtype=float32)),\n", + " (array([ 36, 69, 43, 913, 279, 3738, 62, 777, 610, 118],\n", + " dtype=int32),\n", + " array([310.85855, 311.00134, 311.24194, 311.2462 , 311.31747, 311.3751 ,\n", + " 311.3794 , 311.3809 , 311.4277 , 311.47113], dtype=float32)),\n", + " (array([ 31, 19, 32, 62, 121, 268, 120, 43, 100, 173], dtype=int32),\n", + " array([260.15527, 260.33356, 260.46603, 260.5923 , 260.59818, 260.90775,\n", + " 260.9234 , 260.9475 , 260.95294, 261.12866], dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 62, 121, 120, 268, 204, 173], dtype=int32),\n", + " array([304.8672 , 305.04184, 305.0982 , 305.20557, 305.44165, 305.56686,\n", + " 305.8897 , 305.92307, 305.9696 , 306.02246], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 32, 173, 43, 12, 8, 262], dtype=int32),\n", + " array([315.08173, 315.56567, 315.85 , 316.11234, 316.19305, 316.30652,\n", + " 316.4888 , 316.48947, 316.52362, 316.54233], dtype=float32)),\n", + " (array([ 31, 19, 43, 121, 62, 32, 8, 100, 240, 173], dtype=int32),\n", + " array([-14.16787 , -13.845084, -13.718887, -13.682287, -13.641027,\n", + " -13.453795, -13.231029, -13.199575, -13.135003, -13.134393],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 120, 305, 441, 121, 164, 268], dtype=int32),\n", + " array([317.51428, 317.5627 , 317.6624 , 317.86914, 317.91382, 317.98355,\n", + " 318.06866, 318.08145, 318.11758, 318.1195 ], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 255, 86, 29, 100, 62, 121], dtype=int32),\n", + " array([310.67566, 310.81473, 310.86243, 311.2213 , 311.32886, 311.39627,\n", + " 311.44577, 311.462 , 311.54498, 311.55975], dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 121, 441, 392, 358, 384, 268], dtype=int32),\n", + " array([240.34673, 241.02698, 241.15286, 241.47986, 241.65193, 241.68596,\n", + " 241.69041, 241.69656, 241.7606 , 241.76118], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 62, 120, 268, 100, 43, 12], dtype=int32),\n", + " array([241.09387, 241.20638, 241.52031, 241.92465, 241.94305, 241.9487 ,\n", + " 242.04854, 242.11015, 242.13435, 242.14629], dtype=float32)),\n", + " (array([ 32, 19, 43, 305, 31, 111, 206, 268, 121, 42], dtype=int32),\n", + " array([261.71445, 262.0801 , 262.1176 , 262.32956, 262.36566, 262.68393,\n", + " 262.7763 , 262.77994, 262.8641 , 262.8895 ], dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 32, 43, 100, 12, 8, 105], dtype=int32),\n", + " array([320.52713, 321.20483, 321.22223, 321.32196, 321.3681 , 321.64197,\n", + " 321.73276, 321.76227, 321.9083 , 321.91156], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 305, 121, 62, 29, 268, 166], dtype=int32),\n", + " array([-9.771602, -9.651317, -9.530066, -9.454545, -9.047659, -8.892043,\n", + " -8.818036, -8.708289, -8.69499 , -8.673408], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 100, 62, 29, 86, 121, 268], dtype=int32),\n", + " array([351.55518, 351.5657 , 351.58936, 351.67026, 352.1352 , 352.1884 ,\n", + " 352.34573, 352.35324, 352.35858, 352.41708], dtype=float32)),\n", + " (array([ 31, 19, 29, 43, 121, 32, 100, 86, 24, 62], dtype=int32),\n", + " array([262.9181 , 263.11145, 263.17896, 263.32834, 263.33737, 263.4054 ,\n", + " 263.53165, 263.54105, 263.62784, 263.65033], dtype=float32)),\n", + " (array([539, 149, 0, 835, 552, 965, 43, 262, 31, 57], dtype=int32),\n", + " array([-14.163959 , -14.02205 , -14.019107 , -14.005707 , -13.971053 ,\n", + " -13.963415 , -13.871145 , -13.870991 , -13.8246765, -13.809494 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", + " array([310.3158 , 310.44525, 310.69406, 310.76694, 310.92398, 311.0064 ,\n", + " 311.2275 , 311.32843, 311.42514, 311.44415], dtype=float32)),\n", + " (array([ 19, 32, 43, 118, 121, 1638, 31, 279, 204, 62],\n", + " dtype=int32),\n", + " array([349.05283, 349.37512, 349.3868 , 349.67957, 349.72427, 349.73676,\n", + " 349.75995, 349.77823, 349.83777, 349.87097], dtype=float32)),\n", + " (array([ 43, 31, 32, 19, 62, 121, 49, 100, 206, 36], dtype=int32),\n", + " array([337.28348, 337.38318, 337.52942, 337.58563, 337.78082, 337.8964 ,\n", + " 338.12048, 338.2107 , 338.3415 , 338.34402], dtype=float32)),\n", + " (array([ 31, 19, 173, 12, 29, 121, 24, 32, 268, 43], dtype=int32),\n", + " array([-2.648589 , -2.4846468, -1.8998964, -1.8501105, -1.8254482,\n", + " -1.8077307, -1.5204421, -1.397704 , -1.3898225, -1.2860148],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 62, 43, 268, 120, 103, 100], dtype=int32),\n", + " array([242.83037, 243.1097 , 243.57559, 243.60168, 243.699 , 243.80403,\n", + " 243.8852 , 244.06425, 244.11368, 244.12534], dtype=float32)),\n", + " (array([ 31, 19, 62, 121, 173, 43, 61, 358, 164, 268], dtype=int32),\n", + " array([310.2988 , 310.67978, 310.71878, 311.0019 , 311.1329 , 311.16403,\n", + " 311.21085, 311.28015, 311.392 , 311.47043], dtype=float32)),\n", + " (array([ 43, 32, 62, 19, 31, 121, 86, 305, 268, 164], dtype=int32),\n", + " array([225.7964 , 226.03488, 226.18562, 226.26076, 226.34175, 226.4252 ,\n", + " 226.45828, 226.62724, 226.66763, 226.68503], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([322.40872, 322.4964 , 322.75797, 322.8775 , 323.04678, 323.11957,\n", + " 323.28 , 323.4584 , 323.57642, 323.59494], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 121, 268, 100, 305, 49], dtype=int32),\n", + " array([287.98828, 287.98935, 288.09244, 288.13318, 288.50793, 288.60037,\n", + " 288.78064, 288.86847, 288.90958, 288.93045], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 173, 103, 100, 26, 61, 32], dtype=int32),\n", + " array([248.02551, 248.5906 , 248.74591, 248.97745, 249.16042, 249.38612,\n", + " 249.45505, 249.49806, 249.52469, 249.58205], dtype=float32)),\n", + " (array([ 32, 31, 19, 43, 62, 268, 121, 305, 100, 166], dtype=int32),\n", + " array([309.62067, 309.62674, 309.63077, 309.69672, 310.03232, 310.34808,\n", + " 310.3511 , 310.47876, 310.51645, 310.5232 ], dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 31, 121, 100, 86, 49, 173], dtype=int32),\n", + " array([310.18716, 310.21133, 310.30426, 310.31018, 310.37228, 310.69373,\n", + " 310.8775 , 310.9256 , 310.9428 , 310.95407], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 255, 86, 62, 121, 100, 268], dtype=int32),\n", + " array([247.76933, 248.1085 , 248.17255, 248.30186, 248.45174, 248.50677,\n", + " 248.51407, 248.65228, 248.66599, 248.84972], dtype=float32)),\n", + " (array([ 31, 32, 19, 62, 43, 268, 121, 120, 8, 105], dtype=int32),\n", + " array([309.9547 , 310.37003, 310.69147, 310.72174, 310.75027, 310.7651 ,\n", + " 310.86166, 310.91055, 310.93866, 311.13025], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([310.39288, 310.51492, 310.76657, 310.83185, 310.998 , 311.06955,\n", + " 311.3103 , 311.3945 , 311.49496, 311.50388], dtype=float32)),\n", + " (array([ 31, 19, 62, 32, 43, 121, 204, 49, 268, 120], dtype=int32),\n", + " array([251.034 , 251.35036, 251.36156, 251.41571, 251.51518, 251.5228 ,\n", + " 251.81491, 251.84996, 251.92946, 251.97067], dtype=float32)),\n", + " (array([ 31, 19, 121, 43, 173, 32, 62, 100, 96, 29], dtype=int32),\n", + " array([294.2129 , 294.25903, 294.7758 , 294.779 , 294.83203, 294.9205 ,\n", + " 294.95865, 295.03278, 295.21616, 295.2689 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 62, 43, 268, 255, 103, 358], dtype=int32),\n", + " array([287.50858, 287.82477, 288.05826, 288.34937, 288.37088, 288.37427,\n", + " 288.5164 , 288.5676 , 288.66003, 288.7069 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 36, 8, 173, 240], dtype=int32),\n", + " array([343.65765, 343.70416, 343.89276, 343.92532, 344.0041 , 344.14536,\n", + " 344.2315 , 344.3194 , 344.5548 , 344.57956], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 8, 62, 149, 166, 121, 86], dtype=int32),\n", + " array([238.27538, 238.47679, 238.62265, 238.66264, 238.85207, 239.04405,\n", + " 239.081 , 239.1086 , 239.13249, 239.14513], dtype=float32)),\n", + " (array([ 43, 62, 31, 32, 19, 121, 100, 49, 149, 214], dtype=int32),\n", + " array([309.6256 , 309.77432, 309.84863, 309.93277, 310.12827, 310.4724 ,\n", + " 310.4784 , 310.54883, 310.62494, 310.65784], dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 121, 62, 268, 8, 173, 100], dtype=int32),\n", + " array([-11.14883 , -11.135824 , -11.100656 , -11.0959425, -10.589926 ,\n", + " -10.560493 , -10.358496 , -10.277635 , -10.261923 , -10.219689 ],\n", + " dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 62, 121, 204, 100, 49, 112], dtype=int32),\n", + " array([342.1617 , 342.2518 , 342.37195, 342.5719 , 342.60934, 342.97156,\n", + " 343.05237, 343.07806, 343.1003 , 343.13312], dtype=float32)),\n", + " (array([149, 262, 8, 0, 450, 735, 57, 153, 325, 835], dtype=int32),\n", + " array([291.3952 , 291.58344, 291.61844, 291.7327 , 291.7728 , 291.7857 ,\n", + " 291.80292, 291.88104, 291.90826, 291.9627 ], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 49, 86], dtype=int32),\n", + " array([308.6629 , 308.70493, 308.77167, 308.79907, 309.09406, 309.2825 ,\n", + " 309.50278, 309.5073 , 309.59637, 309.6056 ], dtype=float32)),\n", + " (array([ 43, 32, 279, 19, 31, 62, 258, 69, 204, 36], dtype=int32),\n", + " array([342.79376, 342.88315, 342.96536, 343.05652, 343.21683, 343.25122,\n", + " 343.27512, 343.29242, 343.47818, 343.49545], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 121, 268, 305, 100, 49], dtype=int32),\n", + " array([263.95203, 263.95724, 264.06174, 264.15656, 264.49722, 264.56787,\n", + " 264.7831 , 264.81805, 264.85205, 264.8899 ], dtype=float32)),\n", + " (array([ 31, 19, 103, 121, 32, 268, 120, 235, 62, 43], dtype=int32),\n", + " array([304.77887, 305.67038, 305.69534, 305.78156, 305.8517 , 305.86227,\n", + " 305.8696 , 305.9446 , 306.02246, 306.23358], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 121, 100, 268, 49, 173], dtype=int32),\n", + " array([285.78778, 285.89166, 285.93295, 285.9976 , 286.25592, 286.37717,\n", + " 286.66632, 286.68982, 286.76398, 286.79135], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 121, 268, 100, 49, 86], dtype=int32),\n", + " array([341.1428 , 341.2454 , 341.26138, 341.33563, 341.5653 , 341.8517 ,\n", + " 342.03473, 342.04343, 342.0657 , 342.20627], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 305, 29, 268, 42, 255], dtype=int32),\n", + " array([-11.48454 , -11.395604 , -11.208759 , -10.973148 , -10.661758 ,\n", + " -10.4371605, -10.408198 , -10.327231 , -10.307216 , -10.301584 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 268, 121, 166, 358, 173], dtype=int32),\n", + " array([337.2325 , 337.48584, 337.67468, 337.88406, 338.04434, 338.19308,\n", + " 338.2107 , 338.35446, 338.3612 , 338.4506 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 105, 358], dtype=int32),\n", + " array([341.74457, 341.76517, 342.27618, 342.33643, 342.476 , 342.62463,\n", + " 342.7585 , 342.76505, 342.91162, 343.0361 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 255, 29, 43, 62, 305, 268, 105], dtype=int32),\n", + " array([260.22137, 260.44785, 260.5002 , 260.64163, 260.87787, 260.90338,\n", + " 261.22714, 261.26846, 261.27097, 261.41263], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 62, 173, 206, 121, 268, 358], dtype=int32),\n", + " array([-17.763327, -17.698782, -17.495157, -17.088568, -16.996883,\n", + " -16.893726, -16.84771 , -16.843784, -16.636097, -16.58136 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 268, 103, 120, 29, 121, 86], dtype=int32),\n", + " array([53.359207, 53.7357 , 53.902878, 54.09575 , 54.348656, 54.404644,\n", + " 54.40834 , 54.452847, 54.486202, 54.536404], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 121, 62, 173, 164, 268, 100], dtype=int32),\n", + " array([278.93628, 279.10315, 279.3643 , 279.39157, 279.4668 , 279.5988 ,\n", + " 279.767 , 279.8694 , 279.98492, 280.0099 ], dtype=float32)),\n", + " (array([ 19, 31, 121, 62, 43, 173, 86, 32, 100, 240], dtype=int32),\n", + " array([320.32562, 320.49225, 320.54974, 320.61282, 320.89294, 320.90363,\n", + " 320.92236, 320.98785, 320.99963, 321.12177], dtype=float32)),\n", + " (array([ 31, 103, 121, 19, 235, 120, 268, 32, 427, 671], dtype=int32),\n", + " array([328.35245, 328.66718, 329.02066, 329.23483, 329.23947, 329.27643,\n", + " 329.29593, 329.40677, 329.5381 , 329.54492], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 305, 268, 164, 255, 29, 75], dtype=int32),\n", + " array([255.59294, 255.96443, 256.14178, 256.26993, 256.69574, 256.74728,\n", + " 256.7688 , 256.80414, 256.84137, 256.9127 ], dtype=float32)),\n", + " (array([121, 31, 19, 62, 43, 32, 173, 164, 49, 100], dtype=int32),\n", + " array([264.03766, 264.05295, 264.05984, 264.16226, 264.16476, 264.33493,\n", + " 264.5779 , 264.62375, 264.62778, 264.67984], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 305, 268, 188, 121, 258], dtype=int32),\n", + " array([342.0709 , 342.1489 , 342.35675, 342.44202, 342.58533, 342.77072,\n", + " 342.8552 , 342.86594, 342.8721 , 342.88464], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 164, 374, 49, 121, 487], dtype=int32),\n", + " array([295.33572, 295.5653 , 295.574 , 295.63666, 295.94995, 296.06577,\n", + " 296.12372, 296.1943 , 296.20615, 296.30356], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 268, 62, 358, 75, 258, 487], dtype=int32),\n", + " array([318.56668, 318.6115 , 318.82858, 319.00467, 319.14505, 319.21432,\n", + " 319.2202 , 319.3403 , 319.4197 , 319.4673 ], dtype=float32)),\n", + " (array([ 31, 121, 62, 43, 32, 19, 149, 8, 268, 384], dtype=int32),\n", + " array([341.2926 , 341.8248 , 341.84814, 341.95322, 342.0473 , 342.1127 ,\n", + " 342.20355, 342.32895, 342.34763, 342.45157], dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 62, 43, 268, 120, 173, 164], dtype=int32),\n", + " array([284.609 , 284.9727 , 285.0497 , 285.27374, 285.37445, 285.54816,\n", + " 285.71054, 285.74146, 285.80243, 285.89114], dtype=float32)),\n", + " (array([ 31, 19, 268, 173, 32, 43, 62, 121, 29, 358], dtype=int32),\n", + " array([-4.568763 , -4.5325108, -3.835782 , -3.73649 , -3.7269166,\n", + " -3.6454802, -3.4231503, -3.4121153, -3.401859 , -3.2904484],\n", + " dtype=float32)),\n", + " (array([ 31, 32, 19, 43, 62, 121, 173, 268, 29, 100], dtype=int32),\n", + " array([294.20316, 294.44458, 294.49643, 294.7739 , 294.9908 , 295.02417,\n", + " 295.11185, 295.25266, 295.4514 , 295.48163], dtype=float32)),\n", + " (array([ 31, 43, 19, 121, 268, 32, 62, 86, 358, 103], dtype=int32),\n", + " array([351.53467, 351.95938, 352.01068, 352.21344, 352.42587, 352.43475,\n", + " 352.43863, 352.4668 , 352.5556 , 352.57452], dtype=float32)),\n", + " (array([ 19, 43, 62, 31, 32, 173, 100, 268, 121, 149], dtype=int32),\n", + " array([-18.55561 , -18.457968, -18.363253, -18.250303, -18.073826,\n", + " -17.821415, -17.80263 , -17.796585, -17.793392, -17.748102],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 31, 121, 62, 43, 49, 186, 100, 120], dtype=int32),\n", + " array([323.33008, 323.3734 , 323.6866 , 323.82382, 323.82565, 323.9132 ,\n", + " 323.97067, 324.12558, 324.18567, 324.19006], dtype=float32)),\n", + " (array([ 19, 43, 173, 62, 358, 31, 32, 258, 279, 884], dtype=int32),\n", + " array([309.6789 , 310.07806, 310.3976 , 310.42377, 310.43207, 310.465 ,\n", + " 310.49817, 310.52087, 310.78394, 310.86823], dtype=float32)),\n", + " (array([ 31, 19, 43, 62, 32, 121, 255, 268, 120, 86], dtype=int32),\n", + " array([-16.502213, -16.351 , -16.234737, -16.05482 , -15.98046 ,\n", + " -15.883716, -15.629712, -15.572718, -15.516196, -15.514686],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 36, 62, 19, 279, 31, 121, 118, 69], dtype=int32),\n", + " array([310.43484, 310.5821 , 310.62714, 310.62802, 310.6412 , 310.68756,\n", + " 310.81992, 310.91626, 310.92096, 310.94424], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", + " array([342.974 , 343.11215, 343.2974 , 343.3711 , 343.50464, 343.67923,\n", + " 343.8834 , 343.9941 , 344.0963 , 344.0997 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 255, 121, 43, 268, 62, 100, 29], dtype=int32),\n", + " array([293.97476, 294.19623, 294.31085, 294.50137, 294.6499 , 294.81042,\n", + " 294.8138 , 294.95047, 294.98544, 295.05515], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 305, 166, 62, 121, 268, 204], dtype=int32),\n", + " array([288.87137, 288.974 , 289.02533, 289.16672, 289.71463, 289.7357 ,\n", + " 289.75266, 289.80713, 289.82523, 289.8616 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 62, 43, 86, 121, 268, 204, 29], dtype=int32),\n", + " array([291.09454, 291.14755, 291.258 , 291.45905, 291.46365, 291.6986 ,\n", + " 291.75534, 291.77515, 291.8849 , 292.05923], dtype=float32)),\n", + " (array([ 31, 121, 19, 32, 29, 623, 49, 105, 62, 268], dtype=int32),\n", + " array([239.1703 , 239.32706, 239.38129, 239.67157, 239.81223, 239.99385,\n", + " 239.99573, 239.99854, 240.08499, 240.1449 ], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 112, 121, 186, 204, 258], dtype=int32),\n", + " array([-19.203373, -19.07198 , -18.94647 , -18.829193, -18.68071 ,\n", + " -18.371681, -18.241812, -18.238682, -18.18572 , -18.177637],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", + " array([-5.095121 , -5.0811954, -4.542622 , -4.4812193, -4.4686813,\n", + " -4.3046 , -4.3017554, -4.1008186, -4.0667377, -4.0414615],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 268, 100, 255, 29], dtype=int32),\n", + " array([240.94339, 241.08284, 241.10384, 241.20273, 241.59232, 241.6069 ,\n", + " 241.77856, 241.87619, 241.88518, 241.88893], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 103, 32, 120, 164, 268, 43], dtype=int32),\n", + " array([308.98654, 309.3287 , 309.39178, 309.49506, 309.7175 , 309.86893,\n", + " 309.98517, 309.99533, 310.01056, 310.03674], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 268, 305, 121, 112, 42], dtype=int32),\n", + " array([306.60638, 306.8104 , 307.02942, 307.06912, 307.33035, 307.50674,\n", + " 307.52014, 307.63626, 307.64737, 307.65756], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.8944 , 345.09198, 345.2742 , 345.3555 , 345.40195, 345.55933,\n", + " 345.7688 , 345.88153, 345.98135, 346.06445], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 268, 97, 173, 12, 29, 105], dtype=int32),\n", + " array([245.23692, 245.58582, 245.9251 , 245.94347, 246.13737, 246.3575 ,\n", + " 246.42638, 246.49547, 246.5117 , 246.59662], dtype=float32)),\n", + " (array([ 69, 19, 43, 32, 166, 31, 36, 118, 89, 279], dtype=int32),\n", + " array([251.44089, 251.5388 , 251.5665 , 251.59708, 251.62296, 251.66171,\n", + " 251.66936, 251.80127, 251.93073, 251.93768], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", + " array([343.19736, 343.25546, 343.29657, 343.31116, 343.51572, 343.76465,\n", + " 343.96796, 344.0325 , 344.0802 , 344.11102], dtype=float32)),\n", + " (array([ 19, 8, 31, 32, 121, 262, 173, 100, 62, 43], dtype=int32),\n", + " array([-5.7126856, -5.6494465, -5.5634694, -5.490323 , -5.445427 ,\n", + " -5.4278116, -5.360266 , -5.346415 , -5.252719 , -5.2395916],\n", + " dtype=float32)),\n", + " (array([ 43, 31, 19, 32, 62, 166, 120, 86, 121, 268], dtype=int32),\n", + " array([304.49838, 304.60864, 304.76355, 304.91272, 305.26102, 305.37756,\n", + " 305.48526, 305.51544, 305.54327, 305.54852], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 255, 121, 268, 173, 62, 105], dtype=int32),\n", + " array([332.05402, 332.35547, 332.3562 , 332.85416, 333.00577, 333.02948,\n", + " 333.2143 , 333.2305 , 333.303 , 333.31784], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 105], dtype=int32),\n", + " array([287.37894, 287.50305, 287.9024 , 287.9423 , 288.04437, 288.06732,\n", + " 288.36945, 288.4055 , 288.56866, 288.5846 ], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 121, 62, 173, 105, 100, 8], dtype=int32),\n", + " array([-7.432459 , -7.4023237, -6.9963536, -6.9093738, -6.9006357,\n", + " -6.845482 , -6.6145816, -6.3807535, -6.3080206, -6.211705 ],\n", + " dtype=float32)),\n", + " (array([ 31, 450, 518, 149, 3146, 262, 8, 62, 121, 19],\n", + " dtype=int32),\n", + " array([-7.5563455, -7.5102334, -7.3167133, -7.2882185, -7.2032266,\n", + " -7.1940336, -7.133639 , -7.1186666, -7.0955524, -6.927898 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 100, 29], dtype=int32),\n", + " array([342.60883, 342.81534, 342.94434, 342.96457, 343.16837, 343.2071 ,\n", + " 343.35193, 343.6244 , 343.65048, 343.6524 ], dtype=float32)),\n", + " (array([ 31, 12, 19, 21, 121, 24, 29, 173, 11, 2], dtype=int32),\n", + " array([5.547653 , 5.982525 , 6.0959864, 6.154112 , 6.3330364, 6.3660283,\n", + " 6.4661975, 6.7180567, 6.7465496, 6.7609787], dtype=float32)),\n", + " (array([ 19, 32, 43, 884, 31, 268, 62, 173, 636, 805], dtype=int32),\n", + " array([350.554 , 350.98764, 351.0723 , 351.08783, 351.2328 , 351.27267,\n", + " 351.3909 , 351.40683, 351.42548, 351.4549 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 149, 262, 62, 43, 8, 121, 552], dtype=int32),\n", + " array([321.0757 , 321.41873, 321.45984, 321.61578, 321.65466, 321.6554 ,\n", + " 321.70715, 321.91345, 321.99002, 322.04523], dtype=float32)),\n", + " (array([ 31, 121, 100, 19, 12, 32, 29, 43, 62, 86], dtype=int32),\n", + " array([269.16116, 269.5257 , 269.79166, 269.819 , 269.82602, 269.94995,\n", + " 269.99875, 270.03595, 270.0509 , 270.17642], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 173, 62, 121, 268, 29, 100], dtype=int32),\n", + " array([290.1401 , 290.45145, 290.63785, 290.846 , 291.03488, 291.04205,\n", + " 291.04373, 291.17728, 291.34778, 291.37375], dtype=float32)),\n", + " (array([ 19, 31, 121, 43, 32, 173, 12, 29, 268, 62], dtype=int32),\n", + " array([58.257057, 58.65163 , 58.84349 , 58.92871 , 59.09095 , 59.200607,\n", + " 59.266453, 59.345303, 59.495407, 59.524204], dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 31, 121, 49, 8, 166, 100], dtype=int32),\n", + " array([338.39044, 338.60587, 338.62296, 338.6683 , 338.79056, 338.86874,\n", + " 339.0117 , 339.26624, 339.30063, 339.35672], dtype=float32)),\n", + " (array([ 19, 31, 268, 164, 62, 43, 358, 103, 173, 32], dtype=int32),\n", + " array([262.58487, 262.6545 , 263.44113, 263.54263, 263.58505, 263.59915,\n", + " 263.65552, 263.68054, 263.70303, 263.75363], dtype=float32)),\n", + " (array([2181, 19, 43, 164, 31, 268, 75, 62, 117, 32],\n", + " dtype=int32),\n", + " array([226.9493 , 227.54704, 227.86424, 227.86642, 227.86781, 227.8865 ,\n", + " 227.99623, 228.0828 , 228.11992, 228.13261], dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 49, 36, 279, 31, 69, 112], dtype=int32),\n", + " array([341.6485 , 341.80267, 342.06287, 342.1126 , 342.43652, 342.45364,\n", + " 342.46945, 342.5529 , 342.5595 , 342.56598], dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", + " array([311.84796, 312.00244, 312.0829 , 312.13422, 312.1853 , 312.36942,\n", + " 312.54584, 312.76956, 312.81192, 312.82916], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 268, 130, 173, 75, 164], dtype=int32),\n", + " array([301.59302, 301.7444 , 302.11584, 302.221 , 302.33313, 302.3683 ,\n", + " 302.47525, 302.57733, 302.59845, 302.62924], dtype=float32)),\n", + " (array([ 31, 8, 262, 19, 32, 149, 43, 62, 121, 450], dtype=int32),\n", + " array([315.54672, 315.63876, 315.72702, 315.78513, 315.7888 , 315.82352,\n", + " 315.82822, 315.94617, 316.11276, 316.2316 ], dtype=float32)),\n", + " (array([ 19, 31, 121, 173, 12, 32, 29, 43, 100, 62], dtype=int32),\n", + " array([-2.889264 , -2.857441 , -2.3019035, -2.1709106, -2.0182004,\n", + " -2.0170076, -1.8352119, -1.831348 , -1.8078051, -1.734586 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 358, 29, 268, 105, 173, 62], dtype=int32),\n", + " array([305.072 , 305.1121 , 305.43958, 305.8369 , 305.84692, 305.93185,\n", + " 305.94632, 305.95657, 305.96445, 305.97073], dtype=float32)),\n", + " (array([ 19, 31, 29, 173, 32, 43, 121, 268, 255, 86], dtype=int32),\n", + " array([-6.3802543, -6.15933 , -5.5637207, -5.439764 , -5.398359 ,\n", + " -5.365966 , -5.327169 , -5.2888126, -5.15471 , -5.094646 ],\n", + " dtype=float32)),\n", + " (array([ 43, 32, 226, 528, 19, 974, 305, 166, 16, 69], dtype=int32),\n", + " array([-19.668242, -19.372046, -19.238176, -19.217402, -19.174326,\n", + " -19.100418, -19.036469, -19.020908, -18.995132, -18.93644 ],\n", + " dtype=float32)),\n", + " (array([ 43, 31, 358, 176, 19, 32, 589, 279, 204, 62], dtype=int32),\n", + " array([308.3695 , 308.49863, 308.57086, 308.67227, 308.78406, 308.81134,\n", + " 308.82843, 308.8357 , 308.85745, 308.9028 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 86, 121, 43, 32, 100, 240, 29], dtype=int32),\n", + " array([-9.601175 , -9.578853 , -9.2296 , -9.218114 , -9.2073965,\n", + " -9.183615 , -9.107821 , -8.762698 , -8.713669 , -8.713291 ],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 305, 62, 49, 121, 111, 268], dtype=int32),\n", + " array([293.0617 , 293.72794, 293.78482, 293.8996 , 293.9174 , 293.99716,\n", + " 294.05795, 294.27982, 294.36755, 294.36862], dtype=float32)),\n", + " (array([ 19, 31, 43, 2964, 358, 884, 636, 805, 62, 32],\n", + " dtype=int32),\n", + " array([-11.052489, -10.794892, -10.773016, -10.766544, -10.606944,\n", + " -10.501222, -10.390523, -10.340687, -10.339985, -10.331559],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", + " array([311.77924, 311.91257, 312.01352, 312.0533 , 312.11142, 312.29614,\n", + " 312.4577 , 312.68628, 312.7404 , 312.7641 ], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 121, 62, 100, 29, 173, 268], dtype=int32),\n", + " array([318.08197, 318.10242, 318.41632, 318.53076, 318.5899 , 318.7613 ,\n", + " 318.88425, 318.89056, 318.89328, 318.9135 ], dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 62, 305, 120, 121, 268, 111], dtype=int32),\n", + " array([342.00058, 342.22977, 342.36945, 342.60208, 342.7795 , 342.88486,\n", + " 342.92563, 343.0064 , 343.13535, 343.21445], dtype=float32)),\n", + " (array([255, 19, 31, 32, 86, 43, 120, 29, 268, 103], dtype=int32),\n", + " array([260.36838, 260.38568, 260.53552, 260.89362, 261.00327, 261.0515 ,\n", + " 261.20428, 261.2287 , 261.2419 , 261.43896], dtype=float32)),\n", + " (array([ 34, 19, 32, 31, 43, 1342, 62, 49, 121, 29],\n", + " dtype=int32),\n", + " array([339.60602, 339.7248 , 339.76935, 339.85065, 339.9012 , 339.92526,\n", + " 339.94467, 340.03897, 340.14996, 340.37146], dtype=float32)),\n", + " (array([ 32, 36, 43, 62, 19, 69, 449, 610, 8, 112], dtype=int32),\n", + " array([309.45944, 309.46063, 309.59656, 309.6136 , 309.72336, 309.77878,\n", + " 309.92505, 309.98724, 309.99564, 310.0074 ], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 8, 62, 121, 262, 149, 173], dtype=int32),\n", + " array([315.83636, 315.85812, 315.99908, 316.0639 , 316.1274 , 316.2354 ,\n", + " 316.26718, 316.42227, 316.47372, 316.485 ], dtype=float32)),\n", + " (array([ 19, 31, 268, 32, 43, 62, 121, 173, 358, 255], dtype=int32),\n", + " array([348.4165 , 348.52417, 349.29016, 349.2905 , 349.30084, 349.34302,\n", + " 349.41446, 349.42105, 349.50848, 349.5346 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 8, 149, 262, 43, 32, 121, 552], dtype=int32),\n", + " array([289.21597, 289.56995, 289.74356, 289.79907, 289.83044, 289.8364 ,\n", + " 289.84592, 289.89847, 290.032 , 290.21442], dtype=float32)),\n", + " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", + " array([311.6825 , 311.8511 , 311.93863, 311.98804, 312.04135, 312.21378,\n", + " 312.39114, 312.60446, 312.66852, 312.69647], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 62, 121, 268, 100, 49, 305], dtype=int32),\n", + " array([287.96027, 287.99707, 288.09222, 288.12997, 288.4873 , 288.5817 ,\n", + " 288.77457, 288.84506, 288.9047 , 288.9288 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 100, 105], dtype=int32),\n", + " array([290.30936, 290.45816, 290.79175, 290.85388, 291.0963 , 291.19775,\n", + " 291.30255, 291.40836, 291.57178, 291.65167], dtype=float32)),\n", + " (array([ 8, 62, 43, 149, 610, 32, 262, 279, 129, 36], dtype=int32),\n", + " array([316.0206 , 316.062 , 316.08347, 316.13348, 316.17386, 316.20584,\n", + " 316.23975, 316.24335, 316.26556, 316.27798], dtype=float32)),\n", + " (array([ 8, 32, 43, 31, 19, 62, 149, 86, 552, 347], dtype=int32),\n", + " array([312.72235, 312.74454, 312.77557, 312.939 , 312.98535, 313.14218,\n", + " 313.19333, 313.23883, 313.25974, 313.28384], dtype=float32)),\n", + " (array([ 31, 19, 103, 3318, 121, 43, 235, 173, 268, 12],\n", + " dtype=int32),\n", + " array([316.30136, 316.71924, 316.84506, 316.85983, 316.95398, 317.00595,\n", + " 317.0135 , 317.1464 , 317.14758, 317.21243], dtype=float32)),\n", + " (array([ 43, 69, 32, 382, 36, 279, 31, 62, 330, 19], dtype=int32),\n", + " array([336.7837 , 337.27213, 337.2966 , 337.3207 , 337.33444, 337.4042 ,\n", + " 337.42645, 337.43948, 337.5178 , 337.63284], dtype=float32)),\n", + " (array([ 31, 121, 19, 12, 32, 105, 535, 268, 43, 120], dtype=int32),\n", + " array([-9.293423 , -8.428325 , -8.386113 , -8.237335 , -8.164866 ,\n", + " -8.073025 , -8.015978 , -8.015145 , -7.963448 , -7.9146223],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 31, 100, 43, 121, 62, 86, 173, 29], dtype=int32),\n", + " array([316.03543, 316.0875 , 316.2393 , 316.32257, 316.3967 , 316.4398 ,\n", + " 316.53943, 316.59717, 316.6885 , 316.73395], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 32, 43, 120, 268, 103, 105], dtype=int32),\n", + " array([343.3387 , 344.06702, 344.1057 , 344.12833, 344.2447 , 344.29263,\n", + " 344.5485 , 344.55655, 344.69473, 344.74487], dtype=float32)),\n", + " (array([ 43, 32, 31, 19, 62, 121, 100, 305, 268, 206], dtype=int32),\n", + " array([341.88443, 341.982 , 342.10568, 342.12064, 342.32693, 342.60327,\n", + " 342.75314, 342.7669 , 342.79858, 342.8976 ], dtype=float32)),\n", + " (array([ 32, 43, 19, 31, 62, 100, 49, 121, 29, 255], dtype=int32),\n", + " array([310.80093, 310.96045, 311.0023 , 311.1856 , 311.23758, 311.54846,\n", + " 311.57355, 311.58038, 311.64764, 311.76315], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 166, 121, 8, 279, 120], dtype=int32),\n", + " array([343.47415, 343.59903, 343.7172 , 343.91235, 343.9546 , 344.08197,\n", + " 344.2582 , 344.2676 , 344.31052, 344.31125], dtype=float32)),\n", + " (array([ 32, 43, 31, 62, 19, 8, 149, 262, 121, 100], dtype=int32),\n", + " array([315.31952, 315.40558, 315.54608, 315.56342, 315.58334, 315.60324,\n", + " 315.66925, 315.876 , 315.96924, 316.0061 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 173, 43, 255, 268, 62, 121, 29], dtype=int32),\n", + " array([348.9122 , 349.04974, 349.2378 , 349.8211 , 349.83572, 349.9232 ,\n", + " 349.93332, 349.93613, 350.04193, 350.09467], dtype=float32)),\n", + " (array([ 31, 32, 62, 43, 149, 8, 358, 121, 19, 204], dtype=int32),\n", + " array([317.28693, 317.49088, 317.58295, 317.66425, 317.75284, 317.8083 ,\n", + " 317.8586 , 317.91684, 317.952 , 318.01294], dtype=float32)),\n", + " (array([ 43, 86, 19, 8, 31, 62, 279, 121, 32, 974], dtype=int32),\n", + " array([-9.263846 , -9.103899 , -9.0878105, -8.937294 , -8.886955 ,\n", + " -8.883041 , -8.858941 , -8.827693 , -8.774127 , -8.628111 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 121, 173, 62, 32, 100, 61, 268, 43], dtype=int32),\n", + " array([-9.676186, -9.54141 , -9.396741, -9.205064, -9.044446, -8.82444 ,\n", + " -8.694998, -8.639118, -8.617427, -8.556263], dtype=float32)),\n", + " (array([ 43, 32, 19, 62, 112, 86, 279, 31, 16, 186], dtype=int32),\n", + " array([307.51456, 307.54495, 307.72568, 307.8415 , 308.06662, 308.2694 ,\n", + " 308.31717, 308.38544, 308.4415 , 308.4508 ], dtype=float32)),\n", + " (array([ 96, 19, 31, 43, 121, 86, 32, 62, 173, 112], dtype=int32),\n", + " array([47.96091 , 48.27309 , 48.322277, 48.39021 , 48.596657, 48.648243,\n", + " 48.776752, 48.948055, 48.96972 , 49.07483 ], dtype=float32)),\n", + " (array([ 31, 19, 62, 173, 43, 121, 358, 32, 61, 268], dtype=int32),\n", + " array([204.96822, 205.36955, 205.48169, 205.71176, 205.7392 , 205.77728,\n", + " 205.86227, 205.87718, 206.02858, 206.08852], dtype=float32)),\n", + " (array([ 21, 12, 31, 19, 543, 121, 61, 173, 103, 105], dtype=int32),\n", + " array([353.6244 , 353.88678, 353.91107, 354.55862, 354.7007 , 354.85574,\n", + " 354.9695 , 355.15036, 355.37994, 355.43008], dtype=float32)),\n", + " (array([ 32, 62, 31, 43, 8, 49, 121, 19, 214, 240], dtype=int32),\n", + " array([337.73947, 337.75516, 337.8339 , 338.0181 , 338.06555, 338.23022,\n", + " 338.37 , 338.3929 , 338.45505, 338.46054], dtype=float32)),\n", + " (array([ 149, 57, 347, 325, 835, 43, 38, 3331, 8, 3146],\n", + " dtype=int32),\n", + " array([351.80896, 351.81143, 351.97366, 351.9798 , 351.99634, 352.0092 ,\n", + " 352.03357, 352.0737 , 352.13492, 352.25946], dtype=float32)),\n", + " (array([ 21, 19, 12, 31, 173, 29, 32, 121, 24, 43], dtype=int32),\n", + " array([313.65897, 315.4396 , 315.6556 , 315.86053, 316.2152 , 316.41238,\n", + " 316.55246, 316.555 , 316.58194, 316.68573], dtype=float32)),\n", + " (array([ 32, 43, 19, 305, 31, 29, 111, 268, 374, 206], dtype=int32),\n", + " array([322.85794, 323.07242, 323.11496, 323.4161 , 323.7297 , 323.8448 ,\n", + " 323.8678 , 323.87326, 323.96136, 324.0054 ], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 121, 62, 449, 36, 240, 69], dtype=int32),\n", + " array([300.77554, 300.99875, 301.05685, 301.2397 , 301.4737 , 301.49634,\n", + " 301.71524, 301.7206 , 301.7533 , 301.8178 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 62, 268, 255, 100, 29], dtype=int32),\n", + " array([240.78249, 240.92314, 240.93456, 241.03423, 241.43106, 241.43817,\n", + " 241.60599, 241.71246, 241.72049, 241.73433], dtype=float32)),\n", + " (array([ 31, 19, 121, 32, 62, 12, 100, 29, 43, 61], dtype=int32),\n", + " array([313.82245, 314.60043, 314.8061 , 314.89478, 315.23264, 315.3218 ,\n", + " 315.4298 , 315.47473, 315.54413, 315.56256], dtype=float32)),\n", + " (array([ 31, 43, 62, 32, 19, 358, 268, 121, 441, 164], dtype=int32),\n", + " array([342.0234 , 342.24054, 342.53653, 342.65573, 342.66263, 342.75848,\n", + " 342.76157, 342.79883, 342.9677 , 343.05243], dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 43, 32, 49, 100, 139, 164], dtype=int32),\n", + " array([348.48672, 348.72775, 348.80753, 348.8851 , 348.89285, 348.96744,\n", + " 349.1127 , 349.1894 , 349.24423, 349.26108], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([343.03366, 343.16077, 343.34872, 343.42975, 343.56696, 343.73987,\n", + " 343.93073, 344.03485, 344.15106, 344.1558 ], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 62, 449, 258, 121, 49, 350], dtype=int32),\n", + " array([323.6591 , 323.66876, 323.8467 , 324.2279 , 324.25864, 324.58365,\n", + " 324.6064 , 324.62784, 324.6301 , 324.63162], dtype=float32)),\n", + " (array([ 43, 19, 32, 149, 62, 31, 279, 69, 173, 121], dtype=int32),\n", + " array([345.94846, 345.95123, 346.18982, 346.19083, 346.2606 , 346.2693 ,\n", + " 346.568 , 346.5894 , 346.66135, 346.739 ], dtype=float32)),\n", + " (array([ 8, 32, 149, 62, 43, 450, 262, 31, 49, 735], dtype=int32),\n", + " array([256.2703 , 256.44812, 256.53586, 256.74167, 256.80997, 256.83362,\n", + " 256.9235 , 256.94788, 256.98364, 257.0118 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 49, 62, 121, 43, 384, 268, 392], dtype=int32),\n", + " array([321.22964, 321.28946, 321.39627, 321.49075, 321.50916, 321.53836,\n", + " 321.6192 , 321.64346, 321.70844, 321.75912], dtype=float32)),\n", + " (array([ 19, 31, 173, 32, 43, 121, 62, 100, 86, 268], dtype=int32),\n", + " array([-0.28826267, -0.06532145, 0.3582903 , 0.36676073, 0.3837734 ,\n", + " 0.46872783, 0.4810531 , 0.62910014, 0.7345186 , 0.7688154 ],\n", + " dtype=float32)),\n", + " (array([ 43, 279, 32, 69, 36, 19, 62, 974, 31, 449], dtype=int32),\n", + " array([308.0308 , 308.35928, 308.47665, 308.62778, 308.65277, 308.67145,\n", + " 308.8749 , 308.8921 , 308.9867 , 309.0298 ], dtype=float32)),\n", + " (array([ 31, 19, 43, 62, 32, 255, 121, 86, 120, 8], dtype=int32),\n", + " array([319.63766, 320.09393, 320.12192, 320.1773 , 320.25308, 320.25473,\n", + " 320.43152, 320.50406, 320.5989 , 320.72818], dtype=float32)),\n", + " (array([ 31, 43, 32, 121, 19, 62, 49, 29, 100, 164], dtype=int32),\n", + " array([233.4243 , 233.7595 , 233.81706, 233.88116, 233.9344 , 234.0423 ,\n", + " 234.15884, 234.32816, 234.36333, 234.38605], dtype=float32)),\n", + " (array([ 19, 31, 2964, 358, 173, 636, 1120, 62, 39, 884],\n", + " dtype=int32),\n", + " array([-8.72796 , -8.477619 , -8.294453 , -8.248064 , -8.095911 ,\n", + " -8.010352 , -7.987134 , -7.970608 , -7.9154773, -7.903307 ],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 62, 8, 31, 121, 240, 100, 305], dtype=int32),\n", + " array([291.87738, 291.91418, 292.2438 , 292.40665, 292.44342, 292.4457 ,\n", + " 292.5035 , 292.79794, 292.8258 , 292.82718], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 121, 100, 62, 173, 86, 268], dtype=int32),\n", + " array([-8.934562 , -8.881013 , -8.576623 , -8.541348 , -8.390564 ,\n", + " -8.317347 , -8.3050785, -8.172027 , -8.164956 , -8.118824 ],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 121, 62, 43, 164, 67, 26, 103], dtype=int32),\n", + " array([289.23544, 290.15768, 290.2187 , 290.2313 , 290.23965, 290.28528,\n", + " 290.37408, 290.38663, 290.51068, 290.65753], dtype=float32)),\n", + " (array([ 36, 43, 32, 62, 19, 31, 69, 449, 240, 16], dtype=int32),\n", + " array([334.4823 , 334.6571 , 334.73218, 334.78943, 334.84525, 334.89734,\n", + " 335.09927, 335.24484, 335.2916 , 335.35037], dtype=float32)),\n", + " (array([2181, 2676, 2953, 1584, 884, 3590, 3209, 665, 1959, 2113],\n", + " dtype=int32),\n", + " array([307.5883 , 308.81317, 308.90753, 309.11356, 309.1285 , 309.1489 ,\n", + " 309.28903, 309.42285, 309.51862, 309.7406 ], dtype=float32)),\n", + " (array([ 31, 43, 32, 62, 121, 86, 19, 173, 268, 100], dtype=int32),\n", + " array([349.0459 , 349.49622, 349.5976 , 349.61066, 349.62006, 349.68793,\n", + " 349.69485, 349.9983 , 350.07812, 350.09158], dtype=float32)),\n", + " (array([ 32, 43, 19, 8, 62, 204, 166, 31, 149, 449], dtype=int32),\n", + " array([211.0054 , 211.32883, 211.46419, 211.54022, 211.736 , 211.76773,\n", + " 211.77206, 211.77232, 211.79556, 211.80998], dtype=float32)),\n", + " (array([149, 62, 43, 31, 32, 450, 552, 262, 19, 121], dtype=int32),\n", + " array([338.12436, 338.4792 , 338.55847, 338.64368, 338.7438 , 338.78503,\n", + " 338.7949 , 338.83014, 338.98648, 338.99924], dtype=float32)),\n", + " (array([ 43, 32, 31, 305, 19, 120, 49, 62, 1145, 42],\n", + " dtype=int32),\n", + " array([301.79224, 301.82645, 302.2941 , 302.3314 , 302.63702, 302.7346 ,\n", + " 302.77237, 302.8122 , 302.86105, 302.90433], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 121, 86, 173, 29, 100, 62], dtype=int32),\n", + " array([-3.7455661, -3.5058565, -3.378895 , -3.083093 , -3.0261757,\n", + " -2.8962672, -2.7405283, -2.6841812, -2.6584632, -2.6042924],\n", + " dtype=float32)),\n", + " (array([ 19, 32, 31, 121, 62, 43, 358, 8, 268, 49], dtype=int32),\n", + " array([345.23105, 345.34973, 345.352 , 345.4656 , 345.4969 , 345.49823,\n", + " 345.7349 , 345.7673 , 345.8411 , 345.9589 ], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", + " array([310.334 , 310.4527 , 310.69635, 310.76443, 310.91458, 311.01938,\n", + " 311.2425 , 311.34207, 311.42963, 311.44357], dtype=float32)),\n", + " (array([ 19, 31, 62, 32, 121, 43, 173, 268, 105, 103], dtype=int32),\n", + " array([298.10413, 298.3428 , 298.93362, 298.99365, 298.99472, 299.0177 ,\n", + " 299.14453, 299.20395, 299.41028, 299.44534], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 62, 121, 149, 8, 173, 86], dtype=int32),\n", + " array([310.54572, 310.715 , 310.81372, 310.84702, 311.08026, 311.4198 ,\n", + " 311.51077, 311.53085, 311.59818, 311.6255 ], dtype=float32)),\n", + " (array([ 19, 31, 121, 32, 29, 43, 100, 62, 173, 86], dtype=int32),\n", + " array([350.98785, 351.70575, 351.82846, 351.92685, 351.94547, 351.99237,\n", + " 352.01846, 352.08197, 352.09503, 352.17386], dtype=float32)),\n", + " (array([ 19, 43, 31, 32, 173, 62, 86, 255, 268, 121], dtype=int32),\n", + " array([348.07153, 348.28183, 348.50174, 348.64114, 348.78644, 348.79187,\n", + " 349.04266, 349.04465, 349.0592 , 349.06927], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 149, 62, 262, 255, 121, 100], dtype=int32),\n", + " array([319.1982 , 319.5954 , 319.61157, 319.78308, 319.97806, 320.00876,\n", + " 320.01703, 320.10095, 320.13397, 320.19705], dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 86, 49], dtype=int32),\n", + " array([308.81808, 308.8686 , 308.9243 , 308.9482 , 309.24347, 309.42706,\n", + " 309.64746, 309.6636 , 309.7493 , 309.7499 ], dtype=float32)),\n", + " (array([ 43, 19, 32, 31, 62, 112, 120, 121, 268, 204], dtype=int32),\n", + " array([342.47653, 342.63837, 342.71918, 342.97488, 343.2606 , 343.53824,\n", + " 343.55115, 343.62396, 343.64276, 343.69244], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 173, 121, 62, 100, 255, 268], dtype=int32),\n", + " array([-12.540138, -12.137171, -12.049283, -11.839132, -11.656746,\n", + " -11.64068 , -11.638612, -11.303928, -11.260633, -11.251936],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 62, 121, 173, 8, 347, 149], dtype=int32),\n", + " array([-10.065559, -9.88775 , -9.813306, -9.638669, -9.538965,\n", + " -9.379344, -9.280427, -9.243657, -9.152026, -9.105689],\n", + " dtype=float32)),\n", + " (array([ 31, 121, 19, 62, 164, 103, 43, 32, 268, 173], dtype=int32),\n", + " array([-11.971802 , -11.366394 , -11.242047 , -11.026398 , -10.853961 ,\n", + " -10.830669 , -10.797222 , -10.7918415, -10.766682 , -10.726046 ],\n", + " dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 62, 8, 121, 268, 173, 120], dtype=int32),\n", + " array([-19.76228 , -19.501608, -19.460285, -19.223957, -19.216587,\n", + " -19.053604, -19.011719, -18.901064, -18.745901, -18.609486],\n", + " dtype=float32)),\n", + " (array([ 32, 19, 43, 31, 62, 121, 268, 100, 49, 86], dtype=int32),\n", + " array([308.63876, 308.67154, 308.73718, 308.75357, 309.05753, 309.24628,\n", + " 309.46777, 309.47766, 309.5633 , 309.5821 ], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 62, 8, 100, 121, 173, 268], dtype=int32),\n", + " array([326.4597 , 326.64896, 326.72073, 326.79077, 327.05215, 327.1703 ,\n", + " 327.2165 , 327.31693, 327.40082, 327.45242], dtype=float32)),\n", + " (array([ 31, 121, 62, 19, 32, 43, 103, 105, 49, 268], dtype=int32),\n", + " array([290.10074, 290.8684 , 290.92242, 291.06454, 291.10657, 291.11957,\n", + " 291.45142, 291.51614, 291.5271 , 291.5313 ], dtype=float32)),\n", + " (array([ 19, 31, 43, 62, 32, 121, 273, 164, 173, 8], dtype=int32),\n", + " array([288.896 , 288.95532, 289.16782, 289.21255, 289.36972, 289.64258,\n", + " 289.66537, 289.69272, 289.92862, 289.9483 ], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 305, 29, 111, 121, 206, 268], dtype=int32),\n", + " array([295.3294 , 295.46652, 295.56708, 295.62234, 295.72226, 295.9829 ,\n", + " 295.99542, 296.04922, 296.08768, 296.1316 ], dtype=float32)),\n", + " (array([ 32, 19, 31, 43, 62, 121, 100, 268, 49, 173], dtype=int32),\n", + " array([237.21964, 237.30243, 237.34221, 237.34872, 237.63086, 237.89078,\n", + " 238.06018, 238.08797, 238.16368, 238.24571], dtype=float32)),\n", + " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", + " array([344.96542, 345.16913, 345.3167 , 345.41116, 345.46573, 345.62463,\n", + " 345.84436, 345.95703, 346.0414 , 346.10632], dtype=float32)),\n", + " (array([ 19, 32, 43, 31, 62, 121, 204, 305, 86, 279], dtype=int32),\n", + " array([293.34134, 293.5153 , 293.5335 , 293.8237 , 294.19867, 294.35904,\n", + " 294.38388, 294.38916, 294.4591 , 294.47192], dtype=float32)),\n", + " (array([ 31, 19, 32, 29, 268, 121, 24, 62, 100, 105], dtype=int32),\n", + " array([327.68845, 327.79 , 328.07837, 328.20386, 328.44595, 328.5652 ,\n", + " 328.58017, 328.7822 , 328.81186, 328.84622], dtype=float32)),\n", + " (array([ 43, 32, 19, 31, 62, 279, 305, 16, 554, 173], dtype=int32),\n", + " array([341.12244, 341.29324, 341.53418, 341.66843, 341.82727, 341.9335 ,\n", + " 342.04108, 342.10278, 342.12744, 342.1919 ], dtype=float32)),\n", + " (array([ 19, 382, 43, 31, 559, 2314, 36, 69, 32, 370],\n", + " dtype=int32),\n", + " array([-8.544027, -8.379682, -8.359372, -8.356681, -8.344806, -8.336197,\n", + " -8.321445, -8.274008, -8.233007, -8.205231], dtype=float32)),\n", + " (array([ 19, 31, 32, 43, 268, 606, 120, 105, 29, 121], dtype=int32),\n", + " array([258.2543 , 258.27756, 258.63324, 258.785 , 259.0118 , 259.17218,\n", + " 259.2521 , 259.27142, 259.28043, 259.2985 ], dtype=float32)),\n", + " (array([ 19, 32, 31, 43, 121, 173, 62, 268, 204, 258], dtype=int32),\n", + " array([-18.5358 , -18.301643, -17.97004 , -17.85837 , -17.834467,\n", + " -17.750002, -17.688705, -17.603228, -17.533812, -17.531893],\n", + " dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", + " array([322.3767 , 322.4656 , 322.72333, 322.848 , 323.02774, 323.09827,\n", + " 323.25403, 323.424 , 323.55148, 323.57767], dtype=float32)),\n", + " (array([ 32, 31, 43, 19, 62, 112, 120, 268, 121, 49], dtype=int32),\n", + " array([342.02606, 342.2531 , 342.47992, 342.4926 , 342.55563, 342.63525,\n", + " 342.71747, 342.79602, 342.83182, 342.94263], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 43, 32, 173, 100, 268, 86], dtype=int32),\n", + " array([-4.250471 , -4.1314707, -3.6435182, -3.600346 , -3.55154 ,\n", + " -3.5489879, -3.4938495, -3.3561318, -3.1982527, -3.1129708],\n", + " dtype=float32)),\n", + " (array([ 43, 31, 32, 255, 19, 86, 305, 62, 29, 121], dtype=int32),\n", + " array([344.42413, 344.57016, 344.6782 , 344.7684 , 344.8865 , 344.9333 ,\n", + " 345.12305, 345.14386, 345.35318, 345.37628], dtype=float32)),\n", + " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 105], dtype=int32),\n", + " array([298.18875, 298.30505, 298.53882, 298.7262 , 298.87653, 298.91403,\n", + " 299.10852, 299.29218, 299.39276, 299.3932 ], dtype=float32)),\n", + " (array([ 31, 19, 121, 62, 173, 32, 2314, 43, 36, 382],\n", + " dtype=int32),\n", + " array([318.865 , 319.396 , 319.43295, 319.58615, 319.60837, 319.6555 ,\n", + " 319.7711 , 319.79584, 320.05832, 320.21387], dtype=float32)),\n", + " (array([ 19, 31, 43, 32, 268, 173, 358, 121, 62, 97], dtype=int32),\n", + " array([346.16516, 346.23053, 346.68127, 346.75272, 346.86407, 347.0499 ,\n", + " 347.11044, 347.12326, 347.14447, 347.16522], dtype=float32)),\n", + " (array([ 32, 19, 31, 29, 43, 305, 186, 111, 255, 121], dtype=int32),\n", + " array([294.34894, 294.67987, 294.75375, 294.936 , 295.03058, 295.06128,\n", + " 295.13828, 295.2355 , 295.32452, 295.38873], dtype=float32)),\n", + " (array([ 31, 19, 12, 43, 32, 121, 62, 173, 100, 268], dtype=int32),\n", + " array([316.84103, 316.90164, 317.0408 , 317.26376, 317.33588, 317.34082,\n", + " 317.5151 , 317.5332 , 317.69632, 317.70505], dtype=float32)),\n", + " (array([ 31, 43, 19, 32, 62, 255, 86, 121, 268, 49], dtype=int32),\n", + " array([-19.382977, -19.33198 , -19.223627, -19.067013, -18.919756,\n", + " -18.868162, -18.770218, -18.512556, -18.481125, -18.430311],\n", + " dtype=float32)),\n", + " (array([ 43, 19, 62, 32, 31, 268, 8, 121, 358, 206], dtype=int32),\n", + " array([341.82053, 342.0832 , 342.16116, 342.1844 , 342.1869 , 342.64536,\n", + " 342.6651 , 342.68823, 342.69305, 342.7631 ], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 100, 86, 121, 279, 173], dtype=int32),\n", + " array([349.07028, 349.1043 , 349.3774 , 349.5384 , 349.6618 , 349.88547,\n", + " 349.9679 , 349.97458, 350.02924, 350.09366], dtype=float32)),\n", + " (array([ 43, 32, 31, 62, 19, 112, 86, 305, 120, 121], dtype=int32),\n", + " array([227.76135, 227.919 , 228.14313, 228.22289, 228.23537, 228.49525,\n", + " 228.50725, 228.5122 , 228.59908, 228.63554], dtype=float32)),\n", + " (array([ 19, 31, 62, 121, 32, 43, 173, 268, 100, 49], dtype=int32),\n", + " array([-10.240508, -10.232598, -9.979655, -9.906664, -9.827645,\n", + " -9.691288, -9.585058, -9.347253, -9.33783 , -9.272427],\n", + " dtype=float32)),\n", + " (array([ 43, 62, 32, 16, 19, 164, 36, 554, 279, 49], dtype=int32),\n", + " array([303.90997, 303.96088, 304.15942, 304.1783 , 304.20358, 304.2933 ,\n", + " 304.40802, 304.4497 , 304.51547, 304.55966], dtype=float32)),\n", + " (array([ 31, 19, 358, 62, 176, 173, 636, 268, 121, 884], dtype=int32),\n", + " array([345.50827, 345.61258, 345.7802 , 346.08682, 346.16553, 346.2851 ,\n", + " 346.3079 , 346.35077, 346.3635 , 346.3904 ], dtype=float32)),\n", + " (array([ 19, 43, 32, 31, 62, 173, 268, 121, 487, 86], dtype=int32),\n", + " array([315.2453 , 315.32028, 315.7209 , 315.74374, 315.90012, 316.01874,\n", + " 316.1155 , 316.1264 , 316.17056, 316.18793], dtype=float32)),\n", + " (array([ 31, 32, 43, 19, 62, 86, 121, 120, 255, 186], dtype=int32),\n", + " array([-14.443677 , -14.09697 , -13.9354105, -13.908954 , -13.638619 ,\n", + " -13.529042 , -13.515282 , -13.379453 , -13.273871 , -13.268393 ],\n", + " dtype=float32)),\n", + " ...]" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nbrs" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "id": "cac18e0e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 32, 19, 43, ..., 31, 36, 69],\n", + " [ 31, 262, 62, ..., 32, 121, 735],\n", + " [ 19, 31, 121, ..., 29, 62, 105],\n", + " ...,\n", + " [ 31, 19, 43, ..., 268, 100, 86],\n", + " [ 19, 31, 32, ..., 268, 49, 173],\n", + " [ 19, 31, 32, ..., 100, 105, 268]])" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# рекомендации для всех пользователей \n", + "recos_old_persons = np.array(nbrs, dtype=int)[:,0][:len(nbrs) - 3]\n", + "recos_old_persons" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "918c6976", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 31, 19, 32, 43, 62, 121, 173, 268, 100,\n", + " 86],\n", + " [12018, 10998, 7308, 12006, 10159, 10215, 3543, 8118, 8180,\n", + " 11511],\n", + " [ 8453, 6400, 3557, 3945, 6642, 4779, 3583, 2068, 8668,\n", + " 371]])" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# рекомендации для добавленных пользователей \n", + "recos_new_persons = np.array(nbrs, dtype=int)[:,0][-3:]\n", + "recos_new_persons" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "id": "c78fbc6a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_id
0032
1019
2043
3062
40449
.........
756544575654443
756544675654429
7565447756544100
7565448756544105
7565449756544268
\n", + "

7565450 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id\n", + "0 0 32\n", + "1 0 19\n", + "2 0 43\n", + "3 0 62\n", + "4 0 449\n", + "... ... ...\n", + "7565445 756544 43\n", + "7565446 756544 29\n", + "7565447 756544 100\n", + "7565448 756544 105\n", + "7565449 756544 268\n", + "\n", + "[7565450 rows x 2 columns]" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_r = \\\n", + " pd.DataFrame({'user_id': np.repeat(np.arange(len(recos_old_persons)),\n", + " 10), Columns.Item: recos_old_persons.ravel()})\n", + "df_r\n" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "902cbca6", + "metadata": {}, + "outputs": [], + "source": [ + "df_r.to_csv('nmslib.csv.gz', index=False, compression='gzip')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd71e28b", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 726dd893b2ba4aea22ededb96f081ec894cf9fe2 Mon Sep 17 00:00:00 2001 From: rezarayev Date: Tue, 13 Dec 2022 17:26:27 +0300 Subject: [PATCH 06/12] [second check] --- ...0\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" index 6303cdae..3b1e6c39 100644 --- "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" +++ "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" @@ -7696,7 +7696,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -7710,7 +7710,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.8" + "version": "3.8.10" } }, "nbformat": 4, From 9aa8dd5fe8eed945eb862be1f29918d7e2f3bb0a Mon Sep 17 00:00:00 2001 From: rezarayev Date: Tue, 13 Dec 2022 17:28:12 +0300 Subject: [PATCH 07/12] [check] --- ...0\275\320\270\320\265 \342\204\2264.ipynb" | 3306 +---------------- 1 file changed, 8 insertions(+), 3298 deletions(-) diff --git "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" index 3b1e6c39..1b381cbb 100644 --- "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" +++ "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" @@ -3721,7 +3721,7 @@ }, { "cell_type": "markdown", - "id": "b16ab957", + "id": "3989645b", "metadata": {}, "source": [ "## Пришлось остановить обучение, тк эти 30 эпох обучались 6 часов" @@ -3751,7 +3751,7 @@ { "cell_type": "code", "execution_count": 133, - "id": "326e1a8b", + "id": "d1f6069a", "metadata": {}, "outputs": [], "source": [ @@ -3862,7 +3862,7 @@ { "cell_type": "code", "execution_count": 67, - "id": "aea61562", + "id": "5d1161b4", "metadata": {}, "outputs": [], "source": [ @@ -3873,7 +3873,7 @@ { "cell_type": "code", "execution_count": 68, - "id": "8e86a071", + "id": "9f20ae6e", "metadata": {}, "outputs": [], "source": [ @@ -3894,7 +3894,7 @@ { "cell_type": "code", "execution_count": 69, - "id": "324039bb", + "id": "9982d55c", "metadata": {}, "outputs": [ { @@ -3915,7 +3915,7 @@ { "cell_type": "code", "execution_count": 72, - "id": "1150ce8e", + "id": "348b4fd6", "metadata": {}, "outputs": [], "source": [ @@ -4215,3288 +4215,6 @@ " * float(end - start) / query_qty)\n" ] }, - { - "cell_type": "code", - "execution_count": 85, - "id": "3e24230f", - "metadata": { - "collapsed": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[(array([ 32, 19, 43, 62, 449, 279, 305, 31, 36, 69], dtype=int32),\n", - " array([313.13745, 313.2156 , 313.23563, 313.69226, 313.96838, 314.01437,\n", - " 314.05713, 314.0591 , 314.07086, 314.1464 ], dtype=float32)),\n", - " (array([ 31, 262, 62, 149, 8, 450, 19, 32, 121, 735], dtype=int32),\n", - " array([312.03275, 312.2426 , 312.44092, 312.47754, 312.50558, 312.55057,\n", - " 312.5966 , 312.61896, 312.65695, 312.85553], dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 173, 268, 43, 29, 62, 105], dtype=int32),\n", - " array([292.56287, 292.7267 , 293.37714, 293.398 , 293.52377, 293.58594,\n", - " 293.59534, 293.6454 , 293.80536, 293.9107 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 43, 32, 173, 268, 103, 105], dtype=int32),\n", - " array([345.13394, 345.63568, 345.96344, 346.01605, 346.06268, 346.1905 ,\n", - " 346.40475, 346.4218 , 346.5124 , 346.5745 ], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 36, 449, 279, 121, 206], dtype=int32),\n", - " array([-17.293152, -17.268269, -17.04797 , -16.923717, -16.860167,\n", - " -16.833693, -16.554005, -16.493723, -16.479094, -16.403612],\n", - " dtype=float32)),\n", - " (array([ 43, 884, 19, 358, 31, 62, 805, 1120, 458, 176],\n", - " dtype=int32),\n", - " array([308.01877, 308.03784, 308.04642, 308.27057, 308.37463, 308.40018,\n", - " 308.41226, 308.4986 , 308.5467 , 308.54898], dtype=float32)),\n", - " (array([ 19, 62, 173, 43, 86, 31, 32, 121, 100, 279], dtype=int32),\n", - " array([288.27673, 288.5546 , 288.56357, 288.70715, 288.70715, 288.72052,\n", - " 288.77975, 288.93396, 289.05566, 289.07333], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 121, 268, 49, 100, 305], dtype=int32),\n", - " array([320.5494 , 320.60464, 320.6968 , 320.70566, 321.05185, 321.22174,\n", - " 321.37576, 321.45926, 321.46765, 321.53632], dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", - " array([311.83444, 311.98633, 312.07584, 312.1188 , 312.1717 , 312.35593,\n", - " 312.52664, 312.74872, 312.81677, 312.8287 ], dtype=float32)),\n", - " (array([ 262, 1, 718, 369, 8, 153, 149, 1482, 835, 1118],\n", - " dtype=int32),\n", - " array([317.74112, 317.9094 , 317.93765, 317.9422 , 318.0492 , 318.05173,\n", - " 318.19272, 318.27676, 318.28412, 318.2907 ], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 100, 268, 29, 121, 255], dtype=int32),\n", - " array([-20.910645, -20.845661, -20.804134, -20.656986, -20.396063,\n", - " -20.082872, -20.038603, -20.029623, -20.027676, -20.001362],\n", - " dtype=float32)),\n", - " (array([ 32, 43, 62, 31, 19, 121, 49, 100, 29, 305], dtype=int32),\n", - " array([306.48294, 306.60352, 306.69205, 306.74927, 306.93555, 306.99304,\n", - " 307.14734, 307.16812, 307.42227, 307.44482], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 173, 358, 268, 100], dtype=int32),\n", - " array([242.05086, 242.39929, 242.54828, 242.56117, 242.58932, 242.84547,\n", - " 243.04828, 243.12746, 243.22084, 243.24095], dtype=float32)),\n", - " (array([2855, 3209, 3546, 1584, 19, 2430, 2181, 3351, 1171, 2953],\n", - " dtype=int32),\n", - " array([-9.165584 , -8.613427 , -7.7613564, -7.308004 , -7.0333157,\n", - " -6.942323 , -6.783264 , -6.7762623, -6.652196 , -6.534201 ],\n", - " dtype=float32)),\n", - " (array([ 13, 32, 43, 279, 36, 350, 19, 62, 31, 69], dtype=int32),\n", - " array([343.35373, 343.62512, 343.6554 , 343.8275 , 343.93793, 344.03436,\n", - " 344.0428 , 344.10455, 344.14474, 344.1633 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 8, 173, 204, 120], dtype=int32),\n", - " array([345.64352, 345.67572, 345.6923 , 345.88 , 345.98047, 346.0731 ,\n", - " 346.19617, 346.36945, 346.39755, 346.41702], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 86, 268, 305, 487, 121], dtype=int32),\n", - " array([313.79404, 313.84033, 313.8432 , 314.10782, 314.28986, 314.4456 ,\n", - " 314.4678 , 314.48093, 314.526 , 314.55356], dtype=float32)),\n", - " (array([ 32, 43, 19, 305, 31, 62, 121, 49, 16, 528], dtype=int32),\n", - " array([311.67966, 311.6894 , 312.01752, 312.02475, 312.0784 , 312.22818,\n", - " 312.30634, 312.35004, 312.38342, 312.40384], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 121, 62, 100, 29, 173, 105], dtype=int32),\n", - " array([318.74945, 318.89972, 318.94348, 319.02133, 319.2833 , 319.4113 ,\n", - " 319.5563 , 319.66492, 319.7494 , 319.75116], dtype=float32)),\n", - " (array([ 31, 19, 121, 100, 62, 32, 173, 86, 43, 12], dtype=int32),\n", - " array([290.89676, 291.22546, 291.24185, 291.418 , 291.50125, 291.53076,\n", - " 291.66797, 291.8173 , 291.83707, 291.92416], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-5.0916862, -5.0628467, -4.526428 , -4.460362 , -4.4587893,\n", - " -4.283753 , -4.275841 , -4.082758 , -4.0510454, -4.0182204],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 120, 43, 268, 62, 2180, 103, 121],\n", - " dtype=int32),\n", - " array([338.37042, 339.149 , 339.20544, 339.22913, 339.23502, 339.49866,\n", - " 339.5416 , 339.5564 , 339.5816 , 339.58572], dtype=float32)),\n", - " (array([ 31, 103, 19, 61, 62, 268, 40, 121, 12, 164], dtype=int32),\n", - " array([340.85242, 341.49536, 341.90274, 341.90433, 342.1021 , 342.1285 ,\n", - " 342.14203, 342.14774, 342.2698 , 342.28677], dtype=float32)),\n", - " (array([ 31, 19, 62, 164, 121, 103, 173, 268, 43, 32], dtype=int32),\n", - " array([313.59637, 313.59827, 314.18777, 314.25516, 314.29272, 314.47693,\n", - " 314.48468, 314.5138 , 314.5995 , 314.6321 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", - " array([311.75436, 311.90695, 311.9811 , 312.04282, 312.101 , 312.277 ,\n", - " 312.45184, 312.67252, 312.71725, 312.74603], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-4.956269 , -4.929399 , -4.380765 , -4.3234515, -4.3203835,\n", - " -4.1493745, -4.1366277, -3.9477794, -3.9138684, -3.889961 ],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 49, 86], dtype=int32),\n", - " array([308.77475, 308.83475, 308.88083, 308.90268, 309.20108, 309.39276,\n", - " 309.61237, 309.62393, 309.70663, 309.73032], dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 32, 100, 43, 8, 268, 49], dtype=int32),\n", - " array([-13.882435, -13.882223, -13.619325, -13.587515, -13.471606,\n", - " -13.293805, -13.28355 , -13.157932, -13.013595, -12.973706],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 43, 62, 173, 121, 32, 12, 268, 100], dtype=int32),\n", - " array([-12.391222 , -12.185223 , -11.797996 , -11.6746235, -11.539297 ,\n", - " -11.5266075, -11.525804 , -11.367205 , -11.29679 , -11.026756 ],\n", - " dtype=float32)),\n", - " (array([ 43, 31, 32, 610, 19, 62, 36, 86, 279, 121], dtype=int32),\n", - " array([309.64053, 309.86337, 309.9061 , 309.97876, 309.98526, 310.06454,\n", - " 310.1976 , 310.20383, 310.35623, 310.36185], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", - " array([343.35208, 343.41168, 343.44373, 343.44824, 343.66055, 343.91107,\n", - " 344.12186, 344.1866 , 344.2187 , 344.25067], dtype=float32)),\n", - " (array([ 31, 19, 12, 121, 62, 32, 268, 173, 43, 120], dtype=int32),\n", - " array([-8.2037525, -7.8561625, -7.32616 , -7.2407165, -7.217618 ,\n", - " -7.2110157, -7.114374 , -7.101262 , -7.086527 , -6.8286524],\n", - " dtype=float32)),\n", - " (array([ 43, 69, 188, 31, 279, 112, 86, 528, 19, 848], dtype=int32),\n", - " array([274.54037, 274.7362 , 274.78943, 274.95895, 274.97327, 275.00256,\n", - " 275.0414 , 275.06506, 275.1002 , 275.107 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 268, 121, 43, 12, 120, 62, 103], dtype=int32),\n", - " array([214.02432, 214.2606 , 214.53061, 214.61006, 214.63873, 214.67516,\n", - " 214.92061, 214.97589, 215.06847, 215.12253], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-5.0349526, -5.018808 , -4.4812174, -4.4271564, -4.417553 ,\n", - " -4.2393327, -4.2360854, -4.0470505, -4.01184 , -3.9929585],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 43, 21, 32, 121, 62, 164, 12, 268], dtype=int32),\n", - " array([269.79233, 269.91074, 270.33194, 270.33887, 270.49026, 270.51355,\n", - " 270.7281 , 270.7439 , 270.7531 , 270.76456], dtype=float32)),\n", - " (array([ 19, 31, 3408, 241, 2196, 43, 149, 62, 32, 173],\n", - " dtype=int32),\n", - " array([0.024508 , 0.14910242, 0.34831434, 0.37699768, 0.46431854,\n", - " 0.534814 , 0.5353782 , 0.5813904 , 0.60867965, 0.6309118 ],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 305, 29, 268, 111, 186], dtype=int32),\n", - " array([341.07092, 341.19382, 341.26025, 341.45108, 341.7736 , 341.86887,\n", - " 341.95206, 342.01297, 342.01733, 342.02136], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 268, 86, 120, 62, 29, 255], dtype=int32),\n", - " array([312.9404 , 312.94547, 312.96555, 313.21994, 313.44928, 313.46713,\n", - " 313.51907, 313.5326 , 313.5641 , 313.78125], dtype=float32)),\n", - " (array([ 149, 57, 735, 530, 1118, 552, 325, 262, 965, 539],\n", - " dtype=int32),\n", - " array([341.78226, 342.1679 , 342.20877, 342.442 , 342.44888, 342.5751 ,\n", - " 342.66943, 342.71283, 342.72598, 342.86658], dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 62, 121, 166, 49, 204, 255], dtype=int32),\n", - " array([297.6658 , 297.68994, 297.76672, 298.01215, 298.0355 , 298.18173,\n", - " 298.46136, 298.49863, 298.50992, 298.5142 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 43, 100, 62, 29, 12, 105], dtype=int32),\n", - " array([353.61127, 353.68066, 353.8292 , 353.89127, 354.0306 , 354.11322,\n", - " 354.19388, 354.24356, 354.32172, 354.4584 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([238.92976, 239.10492, 239.30301, 239.40337, 239.51256, 239.67253,\n", - " 239.87503, 239.93681, 240.0481 , 240.17143], dtype=float32)),\n", - " (array([ 19, 32, 43, 342, 279, 848, 305, 16, 528, 13], dtype=int32),\n", - " array([324.29257, 324.29764, 324.3113 , 324.7585 , 324.8286 , 324.88263,\n", - " 324.8934 , 324.9032 , 324.94672, 324.95236], dtype=float32)),\n", - " (array([ 262, 149, 8, 961, 450, 153, 369, 0, 718, 1482],\n", - " dtype=int32),\n", - " array([-10.602786, -10.398672, -10.261883, -10.200603, -10.195368,\n", - " -10.174867, -10.102303, -10.084438, -10.054341, -10.048715],\n", - " dtype=float32)),\n", - " (array([ 19, 43, 32, 279, 31, 848, 173, 206, 62, 188], dtype=int32),\n", - " array([348.31458, 348.40448, 348.69327, 348.92053, 348.9937 , 349.0691 ,\n", - " 349.14886, 349.1566 , 349.19763, 349.289 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 121, 255, 173, 100, 268], dtype=int32),\n", - " array([-6.228593 , -6.046022 , -5.878892 , -5.686447 , -5.545691 ,\n", - " -5.4963074, -5.3257055, -5.306989 , -5.234576 , -5.19708 ],\n", - " dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 62, 121, 100, 86, 268, 29], dtype=int32),\n", - " array([155.9606 , 156.14497, 156.1596 , 156.20587, 156.54088, 156.65228,\n", - " 156.86281, 156.89601, 156.99948, 157.02376], dtype=float32)),\n", - " (array([ 31, 19, 32, 62, 43, 121, 100, 173, 164, 268], dtype=int32),\n", - " array([301.5933 , 301.77182, 301.88055, 301.8956 , 301.93088, 302.1367 ,\n", - " 302.32584, 302.5011 , 302.61255, 302.62833], dtype=float32)),\n", - " (array([ 43, 19, 32, 848, 279, 31, 1088, 188, 206, 305],\n", - " dtype=int32),\n", - " array([242.30208, 242.4566 , 242.50288, 242.64774, 242.6903 , 242.70723,\n", - " 242.8998 , 242.94298, 243.01842, 243.10117], dtype=float32)),\n", - " (array([ 32, 43, 19, 8, 262, 149, 31, 62, 965, 153], dtype=int32),\n", - " array([325.99268, 326.01578, 326.10822, 326.13806, 326.19952, 326.33246,\n", - " 326.42374, 326.44608, 326.71274, 326.75964], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 62, 121, 268, 105, 29, 173], dtype=int32),\n", - " array([348.06845, 348.13095, 348.13138, 348.38913, 348.7707 , 348.8059 ,\n", - " 348.90616, 348.93887, 348.97375, 349.02744], dtype=float32)),\n", - " (array([ 43, 31, 32, 19, 62, 305, 384, 121, 86, 49], dtype=int32),\n", - " array([-19.180525, -18.978985, -18.847485, -18.57598 , -18.398008,\n", - " -18.037577, -17.899921, -17.898565, -17.893497, -17.85743 ],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 43, 62, 19, 49, 121, 120, 305, 186], dtype=int32),\n", - " array([316.81924, 316.98322, 317.02298, 317.17685, 317.2592 , 317.46994,\n", - " 317.53558, 317.6029 , 317.62537, 317.70798], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 268, 86, 120, 255], dtype=int32),\n", - " array([234.87148, 235.01166, 235.40932, 235.53763, 235.59041, 235.67786,\n", - " 235.8497 , 235.95566, 235.96455, 236.03766], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 112, 62, 305, 204, 186, 487], dtype=int32),\n", - " array([320.0586 , 320.17426, 320.28238, 320.5273 , 320.5556 , 320.582 ,\n", - " 320.7148 , 320.73547, 320.74487, 320.7662 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.86703, 345.08035, 345.2343 , 345.32755, 345.37546, 345.52267,\n", - " 345.7457 , 345.87714, 345.94556, 346.0212 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 32, 8, 43, 149, 121, 268, 49], dtype=int32),\n", - " array([322.33954, 322.37024, 322.60202, 322.62314, 322.70538, 322.7285 ,\n", - " 322.82034, 322.983 , 323.09814, 323.11078], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 29, 173, 120], dtype=int32),\n", - " array([242.67905, 242.71577, 243.18695, 243.23677, 243.37122, 243.47752,\n", - " 243.55363, 243.79132, 243.79521, 243.812 ], dtype=float32)),\n", - " (array([ 31, 62, 43, 32, 358, 149, 8, 117, 552, 347], dtype=int32),\n", - " array([-22.578669, -22.562916, -22.470627, -22.347956, -22.297577,\n", - " -22.153297, -22.151903, -22.0696 , -22.06733 , -22.051004],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 121, 204, 166, 69, 62, 268], dtype=int32),\n", - " array([328.0418 , 328.0906 , 328.16348, 328.231 , 328.41153, 328.50214,\n", - " 328.59714, 328.67847, 328.70084, 328.85712], dtype=float32)),\n", - " (array([ 31, 121, 32, 62, 19, 43, 49, 100, 8, 268], dtype=int32),\n", - " array([287.95667, 288.24008, 288.26828, 288.27618, 288.4324 , 288.57266,\n", - " 288.66376, 288.74893, 288.77286, 288.8862 ], dtype=float32)),\n", - " (array([ 19, 31, 173, 121, 62, 32, 103, 268, 43, 12], dtype=int32),\n", - " array([-9.673244, -9.537863, -8.806235, -8.794689, -8.630214, -8.552435,\n", - " -8.547477, -8.524884, -8.503831, -8.393221], dtype=float32)),\n", - " (array([ 31, 19, 173, 358, 268, 32, 62, 121, 636, 43], dtype=int32),\n", - " array([345.0455 , 345.10556, 345.55307, 345.6344 , 345.7094 , 345.7181 ,\n", - " 345.7714 , 345.85223, 345.96268, 346.00952], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 29, 305, 255, 105, 121, 164], dtype=int32),\n", - " array([-13.802836, -13.402133, -13.22652 , -13.114232, -12.968248,\n", - " -12.774135, -12.758164, -12.713695, -12.6649 , -12.606666],\n", - " dtype=float32)),\n", - " (array([ 31, 121, 62, 43, 32, 19, 120, 12, 86, 100], dtype=int32),\n", - " array([343.27493, 343.95023, 344.08218, 344.1211 , 344.2443 , 344.2454 ,\n", - " 344.417 , 344.41772, 344.58157, 344.59363], dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 149, 62, 57, 8, 305, 262], dtype=int32),\n", - " array([304.57358, 304.69336, 304.9109 , 305.06064, 305.1308 , 305.14938,\n", - " 305.32532, 305.43835, 305.45303, 305.4926 ], dtype=float32)),\n", - " (array([ 31, 32, 62, 43, 19, 121, 100, 49, 120, 268], dtype=int32),\n", - " array([342.73886, 342.82443, 342.94052, 343.03305, 343.0704 , 343.2753 ,\n", - " 343.43192, 343.43774, 343.53738, 343.54156], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 173, 12, 43, 32, 100, 268], dtype=int32),\n", - " array([346.24307, 346.76843, 347.12042, 347.22662, 347.28696, 347.3403 ,\n", - " 347.37088, 347.489 , 347.49182, 347.57352], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", - " array([343.2749 , 343.3322 , 343.36847, 343.39383, 343.58325, 343.83533,\n", - " 344.04684, 344.1072 , 344.1612 , 344.16885], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 100, 120], dtype=int32),\n", - " array([289.75934, 289.83258, 290.14587, 290.26434, 290.43954, 290.46304,\n", - " 290.6384 , 290.79724, 290.9155 , 290.927 ], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 173, 62, 100, 4049, 8, 4086],\n", - " dtype=int32),\n", - " array([-1.0573236 , -0.84619975, -0.65467846, -0.5441257 , -0.33517003,\n", - " -0.2748596 , -0.26382744, -0.1981795 , -0.10777314, -0.08880416],\n", - " dtype=float32)),\n", - " (array([ 31, 62, 19, 8, 149, 240, 121, 32, 262, 347], dtype=int32),\n", - " array([342.65033, 342.66632, 342.67032, 342.70035, 342.71603, 342.73782,\n", - " 342.94247, 342.99304, 343.08875, 343.09988], dtype=float32)),\n", - " (array([ 31, 43, 62, 32, 121, 19, 149, 49, 69, 100], dtype=int32),\n", - " array([342.75912, 342.7855 , 342.9729 , 343.00104, 343.07062, 343.31467,\n", - " 343.31744, 343.4589 , 343.50546, 343.59317], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 173, 62, 268, 100, 12, 120], dtype=int32),\n", - " array([-5.5847416, -5.46135 , -5.327554 , -5.1129932, -4.891976 ,\n", - " -4.7081285, -4.666163 , -4.5997343, -4.582306 , -4.449086 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 173, 121, 32, 29, 12, 43, 100, 62], dtype=int32),\n", - " array([-1.8461745 , -1.7337073 , -1.0355114 , -0.99675316, -0.84427077,\n", - " -0.8012683 , -0.6919193 , -0.66187763, -0.6253451 , -0.56059986],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 31, 32, 62, 121, 86, 100, 173, 268], dtype=int32),\n", - " array([310.91208, 310.94843, 310.95355, 310.98315, 311.24374, 311.39185,\n", - " 311.6052 , 311.6181 , 311.7201 , 311.77524], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 29, 105, 255, 268, 62], dtype=int32),\n", - " array([266.47375, 266.66608, 266.73834, 266.86328, 267.0835 , 267.21884,\n", - " 267.28024, 267.28027, 267.30478, 267.33682], dtype=float32)),\n", - " (array([ 19, 32, 43, 62, 31, 173, 8, 204, 112, 149], dtype=int32),\n", - " array([343.2632 , 343.45453, 343.62622, 343.878 , 344.12677, 344.13196,\n", - " 344.14893, 344.1754 , 344.30896, 344.357 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", - " array([311.78104, 311.92377, 312.00885, 312.05548, 312.11484, 312.3027 ,\n", - " 312.47028, 312.69635, 312.74988, 312.77103], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 86, 305, 255, 483, 268, 62], dtype=int32),\n", - " array([306.78027, 306.89676, 307.04138, 307.1993 , 307.41788, 307.44092,\n", - " 307.52713, 307.54416, 307.61343, 307.70517], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 121, 100, 268, 49, 120], dtype=int32),\n", - " array([341.15765, 341.25577, 341.25867, 341.33832, 341.56152, 341.84787,\n", - " 342.04324, 342.04425, 342.06607, 342.21762], dtype=float32)),\n", - " (array([ 31, 19, 32, 62, 121, 43, 100, 173, 262, 86], dtype=int32),\n", - " array([267.49988, 267.76523, 267.87183, 267.93344, 268.03348, 268.05356,\n", - " 268.25632, 268.48865, 268.50696, 268.51288], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 268, 62, 49, 100, 255, 121], dtype=int32),\n", - " array([346.49777, 346.51266, 346.7497 , 346.81296, 347.1502 , 347.20084,\n", - " 347.38962, 347.43158, 347.43805, 347.47437], dtype=float32)),\n", - " (array([ 31, 19, 21, 121, 12, 173, 358, 61, 268, 62], dtype=int32),\n", - " array([332.9891 , 333.0644 , 333.0821 , 333.63422, 333.898 , 333.94617,\n", - " 333.95294, 333.98947, 334.0268 , 334.07285], dtype=float32)),\n", - " (array([ 62, 43, 31, 121, 32, 19, 49, 8, 149, 86], dtype=int32),\n", - " array([337.5237 , 337.58023, 337.59036, 337.77313, 337.83856, 337.9132 ,\n", - " 337.95486, 337.96304, 337.9762 , 338.20206], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 255, 62, 120, 268, 121, 173], dtype=int32),\n", - " array([-7.41297 , -7.3131714, -6.996518 , -6.5799 , -6.553384 ,\n", - " -6.4600983, -6.4193177, -6.4142714, -6.391178 , -6.2705107],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 121, 29, 255, 12, 86, 100], dtype=int32),\n", - " array([318.9655 , 319.48196, 319.58127, 319.85565, 319.88397, 319.8869 ,\n", - " 319.91284, 320.0058 , 320.11743, 320.326 ], dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 121, 255, 120, 268, 62, 305], dtype=int32),\n", - " array([342.2747 , 342.81036, 342.8518 , 343.1069 , 343.13345, 343.14868,\n", - " 343.21085, 343.30496, 343.3074 , 343.4081 ], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 86, 36, 166, 279, 69, 8], dtype=int32),\n", - " array([238.89128, 239.07706, 239.37599, 239.43842, 239.66939, 239.72287,\n", - " 239.83084, 239.84314, 239.85434, 239.91563], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 305, 29, 121, 255, 62, 120], dtype=int32),\n", - " array([-13.285771 , -13.1329 , -13.046364 , -12.953725 , -12.392658 ,\n", - " -12.3227825, -12.292379 , -12.193694 , -12.176666 , -12.170973 ],\n", - " dtype=float32)),\n", - " (array([ 19, 43, 358, 31, 32, 173, 121, 62, 974, 258], dtype=int32),\n", - " array([268.67563, 269.15594, 269.2859 , 269.2988 , 269.53354, 269.67276,\n", - " 269.67557, 269.74835, 269.77563, 269.81207], dtype=float32)),\n", - " (array([ 31, 43, 19, 62, 32, 121, 86, 268, 358, 120], dtype=int32),\n", - " array([340.41257, 340.81824, 341.0423 , 341.1104 , 341.1158 , 341.36127,\n", - " 341.5532 , 341.55826, 341.68536, 341.71152], dtype=float32)),\n", - " (array([ 43, 69, 36, 32, 350, 279, 62, 449, 913, 89], dtype=int32),\n", - " array([302.2446 , 302.455 , 302.52432, 302.6092 , 302.65167, 302.70242,\n", - " 302.74884, 302.7768 , 302.83377, 302.92834], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 268, 358, 97, 305, 173, 258], dtype=int32),\n", - " array([291.71432, 292.0191 , 292.13284, 292.35666, 292.4423 , 292.69443,\n", - " 292.7329 , 292.76465, 292.79208, 292.80676], dtype=float32)),\n", - " (array([ 19, 31, 62, 43, 32, 173, 121, 268, 100, 29], dtype=int32),\n", - " array([-11.688484 , -11.125582 , -10.9086075, -10.868964 , -10.853149 ,\n", - " -10.779191 , -10.752395 , -10.378834 , -10.325179 , -10.316356 ],\n", - " dtype=float32)),\n", - " (array([ 19, 43, 32, 62, 86, 31, 262, 100, 279, 121], dtype=int32),\n", - " array([243.38695, 243.4355 , 243.47537, 243.87566, 243.88516, 243.97946,\n", - " 243.985 , 244.00552, 244.01039, 244.02129], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 173, 121, 36, 279, 100], dtype=int32),\n", - " array([346.06186, 346.3155 , 346.4341 , 346.66858, 346.73395, 346.93384,\n", - " 347.01212, 347.13586, 347.1704 , 347.20654], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([322.2912 , 322.39038, 322.63904, 322.75272, 322.93408, 322.99997,\n", - " 323.1657 , 323.34866, 323.4547 , 323.47766], dtype=float32)),\n", - " (array([ 43, 31, 32, 19, 279, 100, 62, 121, 173, 149], dtype=int32),\n", - " array([348.38797, 348.51193, 348.58295, 348.73206, 349.00638, 349.08313,\n", - " 349.1072 , 349.18314, 349.1896 , 349.3602 ], dtype=float32)),\n", - " (array([ 43, 32, 36, 62, 19, 279, 69, 31, 350, 913], dtype=int32),\n", - " array([201.66779, 202.24219, 202.32242, 202.54419, 202.57008, 202.5704 ,\n", - " 202.58543, 202.62018, 202.7129 , 202.7193 ], dtype=float32)),\n", - " (array([ 19, 279, 43, 31, 974, 32, 173, 342, 258, 358], dtype=int32),\n", - " array([-6.737044 , -6.4661856, -6.335514 , -6.1007633, -6.018259 ,\n", - " -5.8393497, -5.7927628, -5.7813506, -5.7542744, -5.7353625],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 19, 62, 43, 121, 49, 186, 268, 100], dtype=int32),\n", - " array([237.638 , 237.65561, 237.74834, 237.90337, 238.15375, 238.16351,\n", - " 238.19691, 238.31027, 238.31354, 238.31615], dtype=float32)),\n", - " (array([ 43, 31, 62, 19, 32, 69, 149, 121, 36, 279], dtype=int32),\n", - " array([313.75217, 313.76544, 313.92413, 314.07645, 314.0797 , 314.1986 ,\n", - " 314.21243, 314.2998 , 314.3333 , 314.35022], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 305, 268, 62, 75, 29, 487], dtype=int32),\n", - " array([306.58862, 306.707 , 306.83008, 306.98032, 307.40878, 307.41513,\n", - " 307.52386, 307.54425, 307.55472, 307.56903], dtype=float32)),\n", - " (array([ 19, 31, 62, 32, 43, 121, 173, 86, 100, 49], dtype=int32),\n", - " array([311.85876, 312.34027, 312.35883, 312.51312, 312.51736, 312.5776 ,\n", - " 312.6214 , 312.71265, 312.812 , 313.06488], dtype=float32)),\n", - " (array([ 32, 43, 31, 62, 19, 347, 121, 120, 8, 149], dtype=int32),\n", - " array([340.20966, 340.24063, 340.39673, 340.58658, 340.69055, 340.91504,\n", - " 340.9395 , 341.01114, 341.0885 , 341.08972], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 32, 173, 43, 100, 61, 268], dtype=int32),\n", - " array([315.38632, 315.81006, 315.8251 , 315.97635, 316.28314, 316.3262 ,\n", - " 316.42813, 316.5111 , 316.52377, 316.53525], dtype=float32)),\n", - " (array([ 31, 19, 103, 121, 32, 268, 43, 62, 105, 164], dtype=int32),\n", - " array([309.3906 , 309.6671 , 310.19968, 310.20175, 310.21674, 310.25854,\n", - " 310.25912, 310.3019 , 310.4493 , 310.50653], dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 173, 43, 358, 268, 62, 100], dtype=int32),\n", - " array([-7.4531083, -7.4069843, -7.1199527, -7.0514636, -6.9424915,\n", - " -6.7885723, -6.786592 , -6.7568116, -6.65103 , -6.6452637],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 173, 358, 268, 62, 121, 43, 97], dtype=int32),\n", - " array([293.18036, 293.28452, 293.64398, 293.79703, 293.80237, 293.8423 ,\n", - " 293.91156, 293.9354 , 293.97946, 294.1902 ], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 268, 121, 62, 103, 164, 120], dtype=int32),\n", - " array([287.96588, 288.04755, 288.34372, 288.45853, 288.68408, 288.6929 ,\n", - " 288.7793 , 288.86368, 288.9352 , 288.94495], dtype=float32)),\n", - " (array([ 19, 31, 43, 121, 32, 62, 173, 86, 268, 100], dtype=int32),\n", - " array([314.06598, 314.1612 , 314.46637, 314.58292, 314.66385, 314.7214 ,\n", - " 314.75793, 314.80377, 315.03503, 315.08655], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", - " array([343.33026, 343.38437, 343.41385, 343.43347, 343.6325 , 343.88467,\n", - " 344.08762, 344.1461 , 344.19424, 344.22925], dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 32, 43, 120, 8, 100, 149], dtype=int32),\n", - " array([312.45236, 312.47968, 312.59567, 312.64728, 312.67422, 312.6901 ,\n", - " 312.93405, 312.9464 , 312.9713 , 313.12497], dtype=float32)),\n", - " (array([ 31, 19, 32, 62, 43, 121, 268, 103, 255, 358], dtype=int32),\n", - " array([282.46292, 283.05493, 283.19315, 283.2847 , 283.39166, 283.46155,\n", - " 283.59256, 283.6934 , 283.7161 , 283.911 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 62, 43, 121, 268, 8, 173, 100], dtype=int32),\n", - " array([345.65524, 345.9262 , 346.16885, 346.1865 , 346.21036, 346.32147,\n", - " 346.58743, 346.62735, 346.72934, 346.7569 ], dtype=float32)),\n", - " (array([552, 241, 149, 31, 19, 43, 835, 965, 62, 32], dtype=int32),\n", - " array([340.22452, 340.23013, 340.35202, 340.40323, 340.5305 , 340.61328,\n", - " 340.63605, 340.76526, 340.7976 , 340.83078], dtype=float32)),\n", - " (array([ 0, 149, 19, 31, 262, 8, 57, 2196, 835, 287],\n", - " dtype=int32),\n", - " array([-6.6349945, -6.434936 , -6.4298882, -6.3276916, -6.2651544,\n", - " -6.2419343, -6.2317705, -6.149833 , -6.084716 , -6.0592847],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([342.9787 , 343.1185 , 343.303 , 343.38464, 343.51157, 343.69272,\n", - " 343.88483, 343.9932 , 344.09888, 344.10062], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-4.967532 , -4.927384 , -4.3966413, -4.338209 , -4.332314 ,\n", - " -4.170254 , -4.155649 , -3.9548771, -3.9246242, -3.8911352],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 268, 29, 62, 43, 173, 100], dtype=int32),\n", - " array([308.04425, 308.07153, 308.2269 , 308.80017, 308.8662 , 308.99945,\n", - " 309.00992, 309.02774, 309.07608, 309.08847], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 173, 164, 268, 358, 103, 86], dtype=int32),\n", - " array([350.3946 , 350.56 , 351.00375, 351.08243, 351.1222 , 351.22012,\n", - " 351.3107 , 351.3321 , 351.3452 , 351.3912 ], dtype=float32)),\n", - " (array([ 31, 12, 19, 62, 86, 121, 255, 43, 32, 173], dtype=int32),\n", - " array([344.86353, 345.49313, 345.5193 , 345.57196, 345.64996, 345.70776,\n", - " 345.77866, 345.78577, 345.85107, 345.93347], dtype=float32)),\n", - " (array([ 43, 32, 62, 19, 31, 305, 121, 49, 29, 100], dtype=int32),\n", - " array([309.69183, 309.72003, 310.1108 , 310.12317, 310.19186, 310.20572,\n", - " 310.25827, 310.38513, 310.44757, 310.48715], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 43, 62, 103, 268, 164, 173], dtype=int32),\n", - " array([346.98663, 347.161 , 347.6466 , 347.66846, 347.7361 , 347.87103,\n", - " 347.9015 , 347.98883, 348.1148 , 348.1953 ], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 255, 121, 268, 120, 173], dtype=int32),\n", - " array([344.63037, 344.96603, 345.0624 , 345.35706, 345.6743 , 345.75803,\n", - " 345.79025, 345.7998 , 345.86005, 345.89853], dtype=float32)),\n", - " (array([ 31, 606, 19, 32, 12, 43, 62, 268, 29, 121], dtype=int32),\n", - " array([296.2893 , 296.70212, 296.86227, 296.93552, 297.2532 , 297.5014 ,\n", - " 297.51282, 297.62958, 297.6524 , 297.6867 ], dtype=float32)),\n", - " (array([ 19, 43, 32, 173, 62, 31, 258, 69, 279, 358], dtype=int32),\n", - " array([345.94232, 346.3208 , 346.47083, 346.536 , 346.57697, 346.5811 ,\n", - " 346.60034, 346.7322 , 346.74197, 346.81818], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 62, 121, 173, 268, 100, 164], dtype=int32),\n", - " array([344.73718, 344.74698, 345.1139 , 345.21097, 345.30167, 345.40225,\n", - " 345.47433, 345.5714 , 345.84488, 345.90356], dtype=float32)),\n", - " (array([ 8, 43, 149, 262, 965, 36, 325, 118, 450, 31], dtype=int32),\n", - " array([339.9371 , 339.94836, 339.9582 , 340.12228, 340.15903, 340.193 ,\n", - " 340.26828, 340.27094, 340.28644, 340.40198], dtype=float32)),\n", - " (array([ 43, 32, 31, 62, 305, 19, 49, 111, 350, 255], dtype=int32),\n", - " array([282.34915, 282.55243, 282.9279 , 283.03018, 283.04544, 283.1338 ,\n", - " 283.19824, 283.21097, 283.3 , 283.31216], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 121, 268, 100, 255, 120], dtype=int32),\n", - " array([345.68124, 345.80133, 345.8418 , 345.94818, 346.2074 , 346.42343,\n", - " 346.56555, 346.5872 , 346.67224, 346.709 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 268, 121, 86, 305, 105], dtype=int32),\n", - " array([312.97928, 313.02115, 313.0263 , 313.12262, 313.30692, 313.51068,\n", - " 313.5661 , 313.8236 , 313.87775, 313.9069 ], dtype=float32)),\n", - " (array([ 43, 19, 31, 32, 86, 121, 62, 166, 374, 279], dtype=int32),\n", - " array([-13.556057 , -13.332751 , -13.110254 , -12.861042 , -12.839451 ,\n", - " -12.7131405, -12.609385 , -12.46355 , -12.367276 , -12.366643 ],\n", - " dtype=float32)),\n", - " (array([1959, 3354, 985, 796, 1120, 458, 2181, 884, 827, 39],\n", - " dtype=int32),\n", - " array([206.00974, 206.01682, 206.33737, 206.3616 , 206.4415 , 206.48859,\n", - " 206.50409, 206.52463, 206.69136, 206.6996 ], dtype=float32)),\n", - " (array([ 31, 32, 62, 19, 121, 268, 43, 100, 173, 120], dtype=int32),\n", - " array([239.53592, 240.14597, 240.1554 , 240.20403, 240.37437, 240.52495,\n", - " 240.60902, 240.6724 , 240.76917, 240.77725], dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 173, 62, 43, 100, 12, 262], dtype=int32),\n", - " array([321.57968, 321.7376 , 322.36234, 322.3648 , 322.4114 , 322.46686,\n", - " 322.46756, 322.56653, 322.83417, 322.897 ], dtype=float32)),\n", - " (array([ 43, 32, 279, 62, 36, 202, 19, 31, 118, 129], dtype=int32),\n", - " array([342.04837, 342.36404, 342.5594 , 342.57648, 342.6203 , 342.7652 ,\n", - " 342.80353, 342.8174 , 342.84668, 342.86243], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([322.29755, 322.40707, 322.6554 , 322.7699 , 322.94193, 323.00052,\n", - " 323.17963, 323.35965, 323.46408, 323.4884 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.94446, 345.15247, 345.30548, 345.39865, 345.44852, 345.61697,\n", - " 345.81113, 345.93576, 346.0243 , 346.10663], dtype=float32)),\n", - " (array([ 31, 19, 62, 32, 43, 121, 173, 268, 100, 49], dtype=int32),\n", - " array([-18.67583 , -18.660309, -18.417833, -18.359253, -18.311916,\n", - " -18.297022, -17.962929, -17.872766, -17.866323, -17.787956],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 173, 86, 268, 100], dtype=int32),\n", - " array([265.35388, 265.51334, 265.8318 , 265.98834, 266.0196 , 266.0399 ,\n", - " 266.3121 , 266.329 , 266.36688, 266.4785 ], dtype=float32)),\n", - " (array([ 19, 31, 62, 43, 32, 121, 49, 164, 487, 268], dtype=int32),\n", - " array([318.11493, 318.2129 , 318.48407, 318.5036 , 318.6542 , 318.85413,\n", - " 319.08267, 319.12872, 319.17377, 319.17834], dtype=float32)),\n", - " (array([ 19, 32, 43, 62, 149, 31, 8, 262, 49, 100], dtype=int32),\n", - " array([311.7225 , 311.72437, 311.865 , 311.92014, 312.01312, 312.05374,\n", - " 312.10504, 312.19315, 312.32663, 312.4075 ], dtype=float32)),\n", - " (array([ 43, 19, 31, 32, 62, 121, 86, 164, 49, 255], dtype=int32),\n", - " array([-19.813524, -19.804207, -19.728668, -19.522465, -19.514381,\n", - " -19.144453, -19.036312, -19.008139, -18.869104, -18.85116 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 173, 86, 268, 100], dtype=int32),\n", - " array([265.12915, 265.2871 , 265.59576, 265.74454, 265.7797 , 265.80145,\n", - " 266.07492, 266.12085, 266.1362 , 266.24216], dtype=float32)),\n", - " (array([1380, 69, 279, 36, 43, 118, 2314, 370, 31, 129],\n", - " dtype=int32),\n", - " array([344.4259 , 345.0539 , 345.24893, 345.3121 , 345.52026, 345.52222,\n", - " 345.54364, 345.6231 , 345.63965, 345.73315], dtype=float32)),\n", - " (array([ 19, 32, 31, 62, 121, 268, 43, 173, 358, 258], dtype=int32),\n", - " array([295.7728 , 296.09378, 296.16385, 296.46597, 296.63776, 296.6984 ,\n", - " 296.7833 , 296.7903 , 297.00592, 297.0654 ], dtype=float32)),\n", - " (array([ 31, 103, 19, 32, 268, 40, 43, 62, 121, 120], dtype=int32),\n", - " array([300.94043, 301.23984, 301.47314, 301.7147 , 301.79453, 301.82016,\n", - " 301.8464 , 301.89368, 301.9198 , 301.93735], dtype=float32)),\n", - " (array([ 31, 43, 32, 358, 62, 19, 121, 441, 149, 268], dtype=int32),\n", - " array([338.95685, 339.508 , 339.67297, 339.73325, 339.74152, 339.75598,\n", - " 340.20038, 340.21057, 340.222 , 340.24942], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 62, 262, 8, 268, 173, 489], dtype=int32),\n", - " array([325.10217, 325.2386 , 325.4241 , 325.49515, 325.5875 , 325.60492,\n", - " 325.66873, 325.72284, 325.73413, 325.74463], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 206, 121, 69, 36, 279], dtype=int32),\n", - " array([320.6978 , 320.7718 , 320.82007, 320.8214 , 321.34268, 321.38998,\n", - " 321.45862, 321.49222, 321.5061 , 321.50754], dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 62, 255, 86, 305, 121, 120], dtype=int32),\n", - " array([307.69656, 307.91446, 308.12283, 308.1325 , 308.37936, 308.39438,\n", - " 308.4579 , 308.5237 , 308.5974 , 308.6452 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 268, 173, 62, 121, 255, 43, 86], dtype=int32),\n", - " array([-5.3790417, -5.09458 , -4.8331766, -4.789051 , -4.7823205,\n", - " -4.7822595, -4.7535043, -4.7527666, -4.6321225, -4.5882025],\n", - " dtype=float32)),\n", - " (array([ 43, 62, 32, 8, 31, 149, 262, 121, 19, 49], dtype=int32),\n", - " array([306.98486, 307.0449 , 307.16565, 307.17218, 307.22464, 307.2487 ,\n", - " 307.5891 , 307.61765, 307.6228 , 307.71387], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 62, 173, 268, 86, 121, 206], dtype=int32),\n", - " array([345.04468, 345.1523 , 345.15298, 345.21475, 345.5471 , 345.63983,\n", - " 345.75662, 345.81226, 345.8635 , 345.89917], dtype=float32)),\n", - " (array([ 32, 19, 43, 305, 31, 62, 848, 528, 206, 111], dtype=int32),\n", - " array([285.80884, 286.03918, 286.08514, 286.37485, 286.55283, 286.5899 ,\n", - " 286.72803, 286.73105, 286.73996, 286.74646], dtype=float32)),\n", - " (array([ 19, 31, 29, 173, 121, 86, 43, 32, 268, 12], dtype=int32),\n", - " array([-4.130883 , -4.03582 , -3.3995347, -3.3950984, -3.363095 ,\n", - " -3.2856205, -3.2271123, -3.1006253, -3.0423734, -3.0390787],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 62, 262, 149, 173, 121, 1801, 552, 32],\n", - " dtype=int32),\n", - " array([321.75845, 321.78885, 322.08078, 322.20398, 322.23715, 322.39954,\n", - " 322.42 , 322.4579 , 322.5363 , 322.5482 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 105, 29], dtype=int32),\n", - " array([265.6478 , 265.7476 , 266.03217, 266.21774, 266.3553 , 266.38412,\n", - " 266.56482, 266.73804, 266.83734, 266.8432 ], dtype=float32)),\n", - " (array([ 19, 31, 173, 121, 29, 32, 100, 268, 62, 43], dtype=int32),\n", - " array([172.11482, 172.73111, 172.8957 , 172.95479, 172.99104, 173.08199,\n", - " 173.39893, 173.47232, 173.52538, 173.52583], dtype=float32)),\n", - " (array([ 32, 19, 31, 121, 62, 43, 149, 8, 268, 120], dtype=int32),\n", - " array([290.4755 , 290.66855, 290.73358, 290.89438, 290.90457, 290.98746,\n", - " 291.13034, 291.1794 , 291.2842 , 291.30426], dtype=float32)),\n", - " (array([ 43, 31, 19, 36, 32, 62, 69, 121, 118, 166], dtype=int32),\n", - " array([-19.948433, -19.865835, -19.767326, -19.715992, -19.686586,\n", - " -19.623251, -19.613674, -19.511026, -19.272453, -19.251122],\n", - " dtype=float32)),\n", - " (array([ 31, 43, 32, 19, 62, 268, 121, 120, 173, 164], dtype=int32),\n", - " array([310.11475, 310.49615, 310.5521 , 310.56354, 310.88065, 310.94458,\n", - " 311.0378 , 311.28223, 311.28406, 311.31076], dtype=float32)),\n", - " (array([ 31, 19, 606, 268, 164, 103, 29, 121, 24, 105], dtype=int32),\n", - " array([317.68994, 317.96915, 318.5397 , 318.62595, 318.64584, 318.66415,\n", - " 318.70285, 318.7048 , 318.7665 , 318.8746 ], dtype=float32)),\n", - " (array([ 31, 62, 121, 19, 268, 43, 120, 164, 214, 32], dtype=int32),\n", - " array([262.13736, 262.50522, 262.60654, 262.91647, 262.9387 , 262.94522,\n", - " 263.01373, 263.01846, 263.05392, 263.10217], dtype=float32)),\n", - " (array([ 43, 19, 62, 31, 32, 112, 148, 1137, 117, 121],\n", - " dtype=int32),\n", - " array([314.6324 , 314.9748 , 315.0158 , 315.05917, 315.0685 , 315.1134 ,\n", - " 315.20398, 315.21063, 315.22266, 315.25092], dtype=float32)),\n", - " (array([ 43, 32, 31, 149, 62, 8, 835, 305, 19, 255], dtype=int32),\n", - " array([317.45267, 317.56024, 317.86456, 317.92487, 318.19208, 318.31525,\n", - " 318.4304 , 318.4578 , 318.47083, 318.60315], dtype=float32)),\n", - " (array([ 32, 43, 31, 19, 121, 305, 62, 120, 86, 166], dtype=int32),\n", - " array([340.92197, 341.07843, 341.2549 , 341.26987, 341.57135, 341.644 ,\n", - " 341.64444, 341.79153, 341.84293, 341.89413], dtype=float32)),\n", - " (array([ 262, 1482, 153, 369, 149, 0, 1118, 2412, 718, 1],\n", - " dtype=int32),\n", - " array([-7.1548753, -6.9324064, -6.911993 , -6.759491 , -6.718952 ,\n", - " -6.7030196, -6.678854 , -6.6310854, -6.593932 , -6.5888405],\n", - " dtype=float32)),\n", - " (array([ 31, 43, 32, 62, 86, 19, 268, 255, 49, 258], dtype=int32),\n", - " array([341.9816 , 342.15033, 342.1702 , 342.173 , 342.22507, 342.36948,\n", - " 342.6958 , 342.78616, 342.80396, 342.80933], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 255, 268, 62, 358, 103, 120], dtype=int32),\n", - " array([288.07123, 288.49142, 288.733 , 288.738 , 289.01697, 289.03793,\n", - " 289.21478, 289.28265, 289.48224, 289.51526], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 186, 305, 121, 86, 29, 112], dtype=int32),\n", - " array([344.77808, 344.9268 , 345.0211 , 345.12537, 345.19983, 345.23236,\n", - " 345.34995, 345.38492, 345.52972, 345.55905], dtype=float32)),\n", - " (array([ 31, 19, 12, 121, 268, 32, 173, 21, 62, 86], dtype=int32),\n", - " array([242.72072, 243.02757, 243.07562, 243.29799, 243.47444, 243.50716,\n", - " 243.51355, 243.53151, 243.63689, 243.65224], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 121, 173, 29, 100, 62, 268], dtype=int32),\n", - " array([-1.7275019 , -1.5240912 , -1.5131664 , -1.302887 , -1.0184895 ,\n", - " -0.9363806 , -0.83797127, -0.7796087 , -0.7261653 , -0.58068794],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 43, 62, 121, 49, 120, 19, 240, 273], dtype=int32),\n", - " array([306.33493, 306.36124, 306.46613, 306.48672, 306.6366 , 306.75226,\n", - " 306.878 , 306.9205 , 306.9364 , 306.98468], dtype=float32)),\n", - " (array([ 43, 19, 32, 62, 31, 255, 86, 49, 121, 305], dtype=int32),\n", - " array([338.62006, 338.6211 , 338.85815, 339.0491 , 339.1276 , 339.22012,\n", - " 339.278 , 339.45724, 339.577 , 339.62994], dtype=float32)),\n", - " (array([ 43, 32, 62, 86, 279, 69, 31, 19, 36, 347], dtype=int32),\n", - " array([310.36154, 310.56738, 310.9095 , 310.92197, 310.9578 , 311.01923,\n", - " 311.08517, 311.0926 , 311.2108 , 311.3261 ], dtype=float32)),\n", - " (array([ 62, 43, 49, 19, 32, 69, 149, 36, 121, 31], dtype=int32),\n", - " array([306.1763 , 306.17786, 306.38458, 306.39423, 306.49142, 306.50192,\n", - " 306.55487, 306.70963, 306.71368, 306.77325], dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 32, 43, 240, 358, 105, 49], dtype=int32),\n", - " array([269.36642, 269.51428, 269.58096, 269.80392, 269.83282, 269.93283,\n", - " 270.1375 , 270.20126, 270.2353 , 270.26593], dtype=float32)),\n", - " (array([ 31, 19, 43, 29, 32, 121, 268, 255, 62, 105], dtype=int32),\n", - " array([258.56244, 258.65323, 259.31674, 259.44766, 259.45993, 259.5162 ,\n", - " 259.66318, 259.68094, 259.77652, 259.77942], dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 29, 268, 255, 12, 121, 62], dtype=int32),\n", - " array([304.15906, 304.51242, 304.56384, 305.05228, 305.09103, 305.18475,\n", - " 305.30072, 305.34534, 305.35364, 305.45563], dtype=float32)),\n", - " (array([ 31, 19, 62, 32, 43, 86, 255, 121, 173, 100], dtype=int32),\n", - " array([344.4151 , 344.68985, 344.75046, 344.78992, 344.79123, 344.85745,\n", - " 344.88364, 345.25653, 345.28488, 345.2936 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 29, 173, 120], dtype=int32),\n", - " array([242.73578, 242.77695, 243.25046, 243.3083 , 243.42842, 243.54744,\n", - " 243.61342, 243.84935, 243.86339, 243.86943], dtype=float32)),\n", - " (array([ 31, 121, 19, 103, 62, 12, 164, 268, 120, 43], dtype=int32),\n", - " array([267.23877, 267.92746, 268.0079 , 268.0668 , 268.13895, 268.27744,\n", - " 268.3579 , 268.37933, 268.37994, 268.40927], dtype=float32)),\n", - " (array([ 19, 32, 31, 121, 62, 49, 43, 392, 100, 186], dtype=int32),\n", - " array([299.38724, 299.5782 , 299.9818 , 299.98248, 300.07025, 300.1459 ,\n", - " 300.22537, 300.25055, 300.27667, 300.31436], dtype=float32)),\n", - " (array([ 43, 32, 62, 31, 19, 86, 36, 112, 69, 305], dtype=int32),\n", - " array([307.471 , 307.6228 , 307.91605, 307.96405, 307.9878 , 308.32446,\n", - " 308.32645, 308.41098, 308.4709 , 308.47647], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 255, 62, 342, 279, 86, 268], dtype=int32),\n", - " array([349.6414 , 349.76047, 349.80942, 349.84158, 350.01733, 350.15176,\n", - " 350.3185 , 350.3313 , 350.3726 , 350.50482], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 86, 100, 173, 268], dtype=int32),\n", - " array([51.6959 , 51.76991 , 52.026886, 52.168182, 52.248154, 52.29082 ,\n", - " 52.56731 , 52.63062 , 52.649 , 52.71079 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-4.979111 , -4.9550138, -4.4053645, -4.362955 , -4.347425 ,\n", - " -4.1834154, -4.1732507, -3.9843915, -3.946623 , -3.9122121],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", - " array([343.29697, 343.36044, 343.3889 , 343.4099 , 343.61017, 343.8627 ,\n", - " 344.0746 , 344.13998, 344.1806 , 344.19122], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", - " array([343.23718, 343.31253, 343.3428 , 343.3581 , 343.56107, 343.81424,\n", - " 344.0172 , 344.06387, 344.123 , 344.16122], dtype=float32)),\n", - " (array([ 19, 43, 2149, 32, 69, 279, 36, 62, 3738, 848],\n", - " dtype=int32),\n", - " array([281.35736, 281.57596, 281.74463, 281.86624, 282.01538, 282.01828,\n", - " 282.16446, 282.21942, 282.25064, 282.26828], dtype=float32)),\n", - " (array([ 31, 43, 19, 62, 32, 121, 173, 358, 268, 100], dtype=int32),\n", - " array([308.28625, 308.80652, 308.92523, 308.9867 , 309.12177, 309.32 ,\n", - " 309.37027, 309.45898, 309.54633, 309.56366], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 12, 268, 120, 121, 173], dtype=int32),\n", - " array([306.65912, 307.02588, 307.1139 , 307.16785, 307.45615, 307.5961 ,\n", - " 307.60892, 307.68198, 307.81 , 307.85135], dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 43, 62, 8, 173, 262, 100], dtype=int32),\n", - " array([-4.9612145, -4.7801676, -4.4426303, -4.362227 , -4.29175 ,\n", - " -4.232999 , -4.1409297, -4.1223755, -4.1110063, -3.9338346],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", - " array([310.42456, 310.54694, 310.79398, 310.86536, 311.01654, 311.1057 ,\n", - " 311.32666, 311.43158, 311.51782, 311.53967], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 268, 62, 120, 255, 164, 121], dtype=int32),\n", - " array([213.3347 , 213.55576, 213.58586, 213.88168, 214.03857, 214.15764,\n", - " 214.29588, 214.30124, 214.33507, 214.33618], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 268, 62, 105, 164, 29], dtype=int32),\n", - " array([289.43854, 289.73373, 289.78995, 289.80457, 289.96722, 290.09177,\n", - " 290.18765, 290.3794 , 290.43402, 290.46213], dtype=float32)),\n", - " (array([ 32, 31, 121, 19, 62, 43, 49, 120, 100, 105], dtype=int32),\n", - " array([259.71948, 259.7744 , 259.9528 , 260.16757, 260.21237, 260.21616,\n", - " 260.2609 , 260.31436, 260.42203, 260.53326], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 268, 62, 29, 120, 121, 100], dtype=int32),\n", - " array([341.1209 , 341.1635 , 341.37372, 341.50504, 341.74292, 341.90494,\n", - " 342.08875, 342.14835, 342.15802, 342.20963], dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 62, 100, 43, 173, 69, 86], dtype=int32),\n", - " array([262.8588 , 262.8746 , 263.1927 , 263.4276 , 263.54294, 263.59656,\n", - " 263.649 , 263.73904, 264.07852, 264.0804 ], dtype=float32)),\n", - " (array([ 69, 118, 36, 610, 370, 2314, 705, 559, 62, 32],\n", - " dtype=int32),\n", - " array([312.58954, 312.62265, 312.6653 , 312.7235 , 312.76132, 312.80417,\n", - " 312.84802, 312.89355, 312.90686, 312.90787], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 49, 120], dtype=int32),\n", - " array([341.39944, 341.51138, 341.5183 , 341.58606, 341.82016, 342.09595,\n", - " 342.28403, 342.29416, 342.31415, 342.46347], dtype=float32)),\n", - " (array([ 31, 8, 32, 43, 121, 19, 12, 62, 268, 21], dtype=int32),\n", - " array([346.1303 , 346.16727, 346.54965, 346.58475, 346.79022, 346.88788,\n", - " 346.984 , 347.08054, 347.128 , 347.177 ], dtype=float32)),\n", - " (array([ 43, 32, 19, 305, 16, 374, 188, 206, 116, 487], dtype=int32),\n", - " array([338.19223, 338.36545, 338.87158, 338.94052, 339.00848, 339.08832,\n", - " 339.11365, 339.114 , 339.13242, 339.13516], dtype=float32)),\n", - " (array([ 8, 31, 149, 262, 19, 62, 32, 450, 43, 121], dtype=int32),\n", - " array([347.69055, 347.8411 , 347.8882 , 348.03934, 348.10352, 348.2643 ,\n", - " 348.31277, 348.50272, 348.50607, 348.59665], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 173, 100, 268, 358], dtype=int32),\n", - " array([-14.646804 , -14.412246 , -14.14266 , -14.138294 , -14.106711 ,\n", - " -13.979977 , -13.71926 , -13.628071 , -13.555971 , -13.4387665],\n", - " dtype=float32)),\n", - " (array([ 21, 2310, 3162, 31, 19, 12, 1342, 121, 29, 32],\n", - " dtype=int32),\n", - " array([238.73308, 240.39923, 240.75497, 240.90102, 241.0412 , 241.18866,\n", - " 241.24402, 241.51207, 241.59366, 241.80627], dtype=float32)),\n", - " (array([ 43, 515, 19, 32, 16, 374, 554, 848, 188, 279], dtype=int32),\n", - " array([342.71136, 343.1832 , 343.19052, 343.19534, 343.20126, 343.24042,\n", - " 343.29156, 343.3497 , 343.4364 , 343.48505], dtype=float32)),\n", - " (array([ 31, 32, 43, 149, 19, 62, 8, 121, 49, 450], dtype=int32),\n", - " array([283.5595 , 283.77426, 283.77997, 283.8146 , 283.83728, 283.87344,\n", - " 284.04135, 284.04156, 284.35785, 284.42798], dtype=float32)),\n", - " (array([ 31, 19, 32, 268, 29, 43, 121, 173, 255, 105], dtype=int32),\n", - " array([299.0837 , 299.1339 , 299.43283, 299.78424, 299.8547 , 300.03534,\n", - " 300.08292, 300.1606 , 300.24152, 300.32138], dtype=float32)),\n", - " (array([ 31, 32, 19, 268, 43, 62, 358, 120, 103, 61], dtype=int32),\n", - " array([342.61774, 343.27478, 343.2961 , 343.42096, 343.42343, 343.58167,\n", - " 343.6629 , 343.7414 , 343.77548, 343.8112 ], dtype=float32)),\n", - " (array([ 32, 31, 121, 19, 62, 43, 100, 186, 49, 86], dtype=int32),\n", - " array([355.4569 , 355.8592 , 355.93353, 355.93823, 355.9482 , 356.00153,\n", - " 356.1481 , 356.21353, 356.3256 , 356.39185], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", - " array([-5.1433115, -5.1157713, -4.5936127, -4.5406837, -4.5201755,\n", - " -4.3485184, -4.339273 , -4.1452084, -4.127272 , -4.0926104],\n", - " dtype=float32)),\n", - " (array([ 31, 121, 103, 62, 19, 164, 61, 268, 12, 26], dtype=int32),\n", - " array([311.42325, 312.13174, 312.30154, 312.39053, 312.48926, 312.49576,\n", - " 312.57397, 312.738 , 312.74075, 312.7748 ], dtype=float32)),\n", - " (array([262, 8, 149, 32, 369, 31, 450, 539, 19, 153], dtype=int32),\n", - " array([347.69144, 348.17166, 348.2773 , 348.47375, 348.53668, 348.55157,\n", - " 348.7064 , 348.72144, 348.73053, 348.74356], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 29, 121, 62, 100, 268, 164], dtype=int32),\n", - " array([315.89035, 316.10223, 316.16382, 316.4929 , 316.6669 , 316.69183,\n", - " 316.76526, 316.79224, 316.82556, 316.92404], dtype=float32)),\n", - " (array([ 19, 31, 173, 43, 62, 32, 358, 884, 121, 258], dtype=int32),\n", - " array([-13.631014 , -13.378326 , -13.223921 , -13.188473 , -13.166518 ,\n", - " -13.1101885, -12.999098 , -12.868977 , -12.817447 , -12.8084345],\n", - " dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 86, 62, 255, 268, 120, 121], dtype=int32),\n", - " array([263.09036, 263.4136 , 263.59818, 263.66516, 263.6681 , 263.76868,\n", - " 263.94824, 264.07617, 264.0932 , 264.09454], dtype=float32)),\n", - " (array([ 31, 19, 32, 62, 121, 43, 268, 100, 173, 255], dtype=int32),\n", - " array([328.3551 , 328.8731 , 329.07007, 329.23672, 329.2658 , 329.44565,\n", - " 329.59674, 329.67 , 329.74203, 329.76917], dtype=float32)),\n", - " (array([ 32, 43, 19, 305, 31, 62, 100, 29, 111, 121], dtype=int32),\n", - " array([-12.457048, -12.43791 , -12.421761, -12.015521, -11.927298,\n", - " -11.577796, -11.539209, -11.532851, -11.499116, -11.43843 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 120, 62, 268, 305, 255, 121], dtype=int32),\n", - " array([-33.522846, -33.35556 , -33.35172 , -33.176304, -32.79467 ,\n", - " -32.72199 , -32.487892, -32.325 , -32.307495, -32.285484],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 268, 121, 62, 29, 100, 105], dtype=int32),\n", - " array([262.2224 , 262.45544, 262.48013, 262.49313, 262.9379 , 262.99268,\n", - " 263.04614, 263.12292, 263.18018, 263.23492], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 69, 121, 36, 166, 14], dtype=int32),\n", - " array([300.52008, 300.70404, 300.8778 , 300.88055, 301.04742, 301.20938,\n", - " 301.21463, 301.33365, 301.36942, 301.41553], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 62, 43, 186, 268, 86, 100], dtype=int32),\n", - " array([312.77646, 312.87463, 312.89346, 313.0386 , 313.0813 , 313.1837 ,\n", - " 313.34357, 313.42975, 313.43936, 313.44275], dtype=float32)),\n", - " (array([ 31, 86, 43, 19, 62, 255, 32, 121, 268, 75], dtype=int32),\n", - " array([313.66043, 314.0197 , 314.13065, 314.2153 , 314.24585, 314.24954,\n", - " 314.29016, 314.6327 , 314.7106 , 314.7574 ], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 173, 62, 100, 86, 43, 29], dtype=int32),\n", - " array([274.8936 , 275.26773, 275.46094, 275.56436, 275.83417, 275.84564,\n", - " 275.8754 , 276.07532, 276.08908, 276.19504], dtype=float32)),\n", - " (array([ 31, 43, 19, 149, 32, 62, 121, 8, 262, 347], dtype=int32),\n", - " array([347.80334, 347.97336, 348.00525, 348.03125, 348.03476, 348.49036,\n", - " 348.49118, 348.57654, 348.62436, 348.6504 ], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 121, 305, 49, 268, 29, 62], dtype=int32),\n", - " array([307.99734, 308.1842 , 308.20193, 308.31244, 308.43607, 308.5341 ,\n", - " 308.56073, 308.6038 , 308.6299 , 308.64676], dtype=float32)),\n", - " (array([ 19, 31, 173, 12, 121, 32, 62, 100, 29, 43], dtype=int32),\n", - " array([354.41293, 354.57666, 354.9651 , 355.146 , 355.18665, 355.37982,\n", - " 355.63208, 355.6957 , 355.74042, 355.82388], dtype=float32)),\n", - " (array([ 19, 31, 43, 62, 358, 121, 164, 32, 268, 173], dtype=int32),\n", - " array([285.0124 , 285.25577, 285.52927, 285.59317, 285.63513, 285.77396,\n", - " 285.87573, 285.9841 , 286.0442 , 286.08023], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.843 , 345.07404, 345.21347, 345.29462, 345.3463 , 345.5088 ,\n", - " 345.7224 , 345.838 , 345.9285 , 346.00266], dtype=float32)),\n", - " (array([ 19, 31, 121, 43, 173, 62, 100, 32, 268, 105], dtype=int32),\n", - " array([-10.287987, -10.105809, -9.772382, -9.640942, -9.61024 ,\n", - " -9.515656, -9.498697, -9.477242, -9.016497, -8.99341 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 173, 29, 268, 121, 62, 100], dtype=int32),\n", - " array([-4.2063303, -3.8578374, -3.5531025, -3.1375096, -3.1287026,\n", - " -2.9719126, -2.9412744, -2.8817208, -2.7690904, -2.7398794],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 49, 86], dtype=int32),\n", - " array([308.78714, 308.83017, 308.8848 , 308.9159 , 309.2116 , 309.39853,\n", - " 309.61646, 309.62625, 309.71777, 309.71957], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 358, 39, 62, 268, 636, 173], dtype=int32),\n", - " array([344.2082 , 344.44357, 344.57022, 344.61343, 344.8598 , 344.89172,\n", - " 344.89838, 344.961 , 345.0495 , 345.12665], dtype=float32)),\n", - " (array([ 31, 62, 121, 61, 19, 32, 43, 100, 268, 103], dtype=int32),\n", - " array([284.41235, 285.0468 , 285.10342, 285.1888 , 285.2465 , 285.44226,\n", - " 285.45752, 285.51245, 285.5827 , 285.6653 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 105, 268, 120, 86], dtype=int32),\n", - " array([348.055 , 348.26694, 348.52545, 348.58893, 348.59067, 348.61887,\n", - " 348.7269 , 348.77472, 348.99243, 348.99518], dtype=float32)),\n", - " (array([ 19, 31, 43, 62, 121, 32, 164, 100, 173, 268], dtype=int32),\n", - " array([342.90494, 343.1901 , 343.25708, 343.40213, 343.50107, 343.58203,\n", - " 343.82745, 343.87393, 343.9245 , 343.95386], dtype=float32)),\n", - " (array([ 19, 43, 32, 279, 31, 69, 258, 166, 36, 62], dtype=int32),\n", - " array([264.77603, 264.8024 , 264.95255, 265.18588, 265.31503, 265.36118,\n", - " 265.41092, 265.42535, 265.48685, 265.5153 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 120, 103, 164], dtype=int32),\n", - " array([340.2276 , 340.7527 , 340.8746 , 340.93317, 341.01257, 341.2328 ,\n", - " 341.33353, 341.3753 , 341.41675, 341.65338], dtype=float32)),\n", - " (array([ 19, 43, 32, 258, 173, 62, 805, 176, 374, 100], dtype=int32),\n", - " array([311.01227, 311.25955, 311.42825, 311.71817, 311.77762, 311.88116,\n", - " 311.92047, 311.97552, 312.0079 , 312.08768], dtype=float32)),\n", - " (array([ 884, 19, 2181, 3209, 1959, 43, 358, 636, 805, 521],\n", - " dtype=int32),\n", - " array([317.77435, 317.89914, 318.00345, 318.1425 , 318.15417, 318.23245,\n", - " 318.24258, 318.2771 , 318.31848, 318.32968], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 268, 173, 121, 164, 8], dtype=int32),\n", - " array([321.84604, 322.24774, 322.3098 , 322.49057, 322.5661 , 322.82 ,\n", - " 322.8759 , 322.97394, 323.00183, 323.12778], dtype=float32)),\n", - " (array([ 43, 32, 31, 62, 8, 121, 100, 19, 86, 268], dtype=int32),\n", - " array([342.02063, 342.0747 , 342.36108, 342.45218, 342.62222, 342.69666,\n", - " 342.75436, 342.82074, 342.86224, 342.90573], dtype=float32)),\n", - " (array([ 31, 8, 19, 121, 262, 450, 32, 62, 149, 36], dtype=int32),\n", - " array([-13.384605 , -12.933238 , -12.895946 , -12.8417425, -12.780468 ,\n", - " -12.738579 , -12.718014 , -12.675237 , -12.653876 , -12.532298 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([312.41382, 312.62598, 312.84418, 312.9323 , 312.9963 , 313.04727,\n", - " 313.29303, 313.4334 , 313.48193, 313.49994], dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 31, 121, 86, 100, 173, 49], dtype=int32),\n", - " array([277.56442, 277.59464, 277.62943, 277.69528, 277.70322, 278.0039 ,\n", - " 278.16898, 278.20297, 278.28183, 278.33792], dtype=float32)),\n", - " (array([ 43, 69, 279, 36, 19, 62, 32, 974, 258, 118], dtype=int32),\n", - " array([308.372 , 308.47812, 308.52005, 308.6522 , 308.75067, 308.8355 ,\n", - " 308.88028, 308.93564, 308.99506, 309.09064], dtype=float32)),\n", - " (array([ 19, 31, 32, 62, 43, 173, 121, 100, 8, 36], dtype=int32),\n", - " array([319.52982, 319.66534, 319.72327, 319.7336 , 319.74808, 319.78607,\n", - " 319.8202 , 320.0999 , 320.202 , 320.25818], dtype=float32)),\n", - " (array([1556, 31, 43, 19, 57, 69, 32, 212, 62, 36],\n", - " dtype=int32),\n", - " array([343.5553 , 343.64545, 343.71744, 343.8603 , 343.92123, 343.9694 ,\n", - " 343.99402, 344.02194, 344.03406, 344.08356], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 62, 29, 164, 86, 374, 49], dtype=int32),\n", - " array([-13.599033, -13.482429, -13.482097, -13.272527, -13.083915,\n", - " -12.931248, -12.923155, -12.909886, -12.809618, -12.802147],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 255, 268, 100, 86], dtype=int32),\n", - " array([-15.301536, -15.298448, -14.989493, -14.883555, -14.797832,\n", - " -14.693052, -14.636348, -14.392767, -14.36642 , -14.306731],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 173, 268, 100, 12], dtype=int32),\n", - " array([235.15862, 235.27525, 235.70685, 235.83282, 235.83704, 235.8743 ,\n", - " 235.9079 , 236.21094, 236.30933, 236.30952], dtype=float32)),\n", - " (array([ 43, 32, 62, 31, 19, 36, 8, 262, 279, 449], dtype=int32),\n", - " array([339.57626, 339.60147, 339.67606, 339.90118, 339.93845, 340.00714,\n", - " 340.00854, 340.08844, 340.21445, 340.2476 ], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 29, 305, 111, 121, 186, 105], dtype=int32),\n", - " array([320.27344, 320.60013, 320.6929 , 320.81845, 320.8795 , 320.9046 ,\n", - " 321.0976 , 321.09933, 321.22202, 321.2398 ], dtype=float32)),\n", - " (array([149, 43, 32, 262, 8, 62, 31, 19, 369, 36], dtype=int32),\n", - " array([305.47174, 305.62546, 305.62726, 305.66144, 305.78976, 305.8769 ,\n", - " 306.1171 , 306.1323 , 306.1441 , 306.18814], dtype=float32)),\n", - " (array([ 31, 62, 19, 121, 32, 268, 43, 49, 100, 8], dtype=int32),\n", - " array([344.3326 , 344.5726 , 344.66858, 344.8783 , 344.97528, 345.13107,\n", - " 345.14734, 345.17825, 345.28094, 345.29416], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-5.030628 , -5.0019164, -4.4487867, -4.3988233, -4.3920665,\n", - " -4.2199664, -4.2096925, -4.0110087, -3.9966905, -3.9498527],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 62, 32, 121, 12, 173, 100, 268], dtype=int32),\n", - " array([306.87115, 307.20834, 307.53104, 307.67474, 307.69324, 307.80725,\n", - " 307.92273, 307.95023, 308.16998, 308.32336], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([312.3017 , 312.49252, 312.70438, 312.80276, 312.8629 , 312.93243,\n", - " 313.17148, 313.30807, 313.35947, 313.36423], dtype=float32)),\n", - " (array([ 31, 121, 62, 19, 32, 103, 43, 268, 120, 49], dtype=int32),\n", - " array([-13.6003685, -13.386892 , -13.048842 , -12.978064 , -12.923302 ,\n", - " -12.832489 , -12.824678 , -12.782839 , -12.6638775, -12.607466 ],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 305, 31, 86, 49, 121, 268], dtype=int32),\n", - " array([343.1129 , 343.18115, 343.65753, 343.69788, 343.74188, 343.80005,\n", - " 344.05627, 344.16516, 344.18304, 344.1946 ], dtype=float32)),\n", - " (array([ 32, 31, 19, 62, 43, 49, 121, 304, 392, 441], dtype=int32),\n", - " array([293.79663, 293.808 , 294.14117, 294.2369 , 294.32822, 294.4335 ,\n", - " 294.45523, 294.47296, 294.47522, 294.52142], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 305, 166, 105, 121, 29, 62], dtype=int32),\n", - " array([303.94208, 304.10236, 304.21732, 304.29514, 304.48364, 304.60992,\n", - " 304.64877, 304.66302, 304.72363, 304.80734], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 62, 103, 43, 120, 268, 29], dtype=int32),\n", - " array([324.24326, 324.92114, 325.0366 , 325.07632, 325.27628, 325.46164,\n", - " 325.48834, 325.5086 , 325.55966, 325.71478], dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 12, 62, 121, 100, 29, 86], dtype=int32),\n", - " array([312.144 , 312.32962, 312.40576, 312.41193, 312.512 , 312.65973,\n", - " 312.67947, 312.70682, 312.88577, 312.99625], dtype=float32)),\n", - " (array([ 31, 12, 121, 19, 103, 29, 62, 268, 32, 173], dtype=int32),\n", - " array([356.6274 , 357.15707, 357.2626 , 357.52145, 357.6411 , 357.66452,\n", - " 357.90305, 357.9458 , 357.9567 , 357.96454], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 121, 62, 173, 164, 268, 487], dtype=int32),\n", - " array([-15.974582, -15.666498, -15.412963, -15.252548, -15.121224,\n", - " -15.10663 , -15.050113, -14.948169, -14.908808, -14.836789],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 29, 12, 32, 121, 173, 43, 24, 100], dtype=int32),\n", - " array([263.34613, 263.51138, 263.9186 , 263.95224, 263.96582, 264.22995,\n", - " 264.37097, 264.44342, 264.46033, 264.51242], dtype=float32)),\n", - " (array([ 31, 32, 43, 149, 8, 62, 120, 262, 19, 121], dtype=int32),\n", - " array([315.63965, 315.77344, 315.84247, 315.9835 , 316.10825, 316.12128,\n", - " 316.34576, 316.4581 , 316.46384, 316.51608], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 121, 62, 100, 69, 36, 279], dtype=int32),\n", - " array([314.47702, 314.5665 , 314.6491 , 314.72476, 314.8577 , 314.9262 ,\n", - " 315.13724, 315.17795, 315.35522, 315.39377], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.85538, 345.09045, 345.2382 , 345.32623, 345.37555, 345.53754,\n", - " 345.74594, 345.86102, 345.94952, 346.03363], dtype=float32)),\n", - " (array([ 241, 1801, 0, 149, 8, 735, 262, 1619, 31, 552],\n", - " dtype=int32),\n", - " array([349.5574 , 349.63638, 349.97824, 350.0328 , 350.04977, 350.07266,\n", - " 350.08963, 350.15094, 350.15662, 350.1782 ], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 268, 29, 255, 62, 121, 100], dtype=int32),\n", - " array([265.5091 , 265.5642 , 265.65613, 266.2193 , 266.36572, 266.48993,\n", - " 266.49915, 266.52814, 266.66528, 266.68976], dtype=float32)),\n", - " (array([ 31, 19, 12, 121, 43, 173, 62, 32, 120, 29], dtype=int32),\n", - " array([262.91986, 263.21686, 263.73962, 263.97925, 264.0152 , 264.0359 ,\n", - " 264.17685, 264.2683 , 264.29852, 264.37872], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 121, 62, 268, 49, 105, 173], dtype=int32),\n", - " array([251.75104, 252.46007, 252.4919 , 252.58513, 252.59534, 252.77249,\n", - " 252.80959, 252.81326, 252.90184, 252.91351], dtype=float32)),\n", - " (array([ 32, 31, 62, 121, 43, 49, 19, 100, 8, 273], dtype=int32),\n", - " array([286.7004 , 286.71283, 286.79346, 286.84265, 286.9828 , 286.9923 ,\n", - " 287.05884, 287.18152, 287.4453 , 287.45245], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 121, 268, 120, 173, 100], dtype=int32),\n", - " array([265.86395, 265.94437, 266.0512 , 266.32397, 266.50363, 266.5054 ,\n", - " 266.52643, 266.694 , 266.80252, 266.91312], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 268, 49, 100, 173], dtype=int32),\n", - " array([191.912 , 192.11353, 192.17426, 192.3201 , 192.5034 , 192.50595,\n", - " 192.80835, 192.9418 , 192.94662, 192.96214], dtype=float32)),\n", - " (array([ 31, 62, 19, 32, 43, 121, 268, 173, 358, 86], dtype=int32),\n", - " array([316.61246, 316.8937 , 317.03522, 317.10895, 317.16156, 317.32007,\n", - " 317.4309 , 317.45554, 317.51773, 317.61896], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 173, 268, 255, 164], dtype=int32),\n", - " array([324.2678 , 324.6414 , 324.92496, 325.05038, 325.22757, 325.33405,\n", - " 325.51355, 325.52933, 325.6598 , 325.7187 ], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 32, 103, 173, 100, 120, 61], dtype=int32),\n", - " array([317.34003, 317.92337, 318.01788, 318.20483, 318.36285, 318.4596 ,\n", - " 318.46072, 318.6423 , 318.69638, 318.69836], dtype=float32)),\n", - " (array([ 19, 31, 121, 43, 32, 62, 105, 100, 49, 268], dtype=int32),\n", - " array([325.82996, 325.9826 , 326.0693 , 326.28937, 326.31818, 326.40656,\n", - " 326.45306, 326.5878 , 326.66626, 326.75858], dtype=float32)),\n", - " (array([ 43, 149, 62, 36, 32, 240, 31, 69, 330, 8], dtype=int32),\n", - " array([338.58038, 338.77115, 338.88443, 338.92017, 338.95306, 339.01016,\n", - " 339.05963, 339.0873 , 339.08765, 339.09525], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 121, 100, 173, 29, 86], dtype=int32),\n", - " array([285.2647 , 285.46994, 285.58875, 285.7844 , 286.05826, 286.20993,\n", - " 286.34903, 286.3741 , 286.48764, 286.52768], dtype=float32)),\n", - " (array([ 43, 62, 32, 36, 19, 31, 25, 69, 279, 449], dtype=int32),\n", - " array([340.97354, 341.146 , 341.38815, 341.57764, 341.58575, 341.61063,\n", - " 341.71463, 341.74915, 341.80667, 341.82574], dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 121, 62, 100, 49, 8, 173], dtype=int32),\n", - " array([-14.669187 , -14.600939 , -14.571131 , -14.505507 , -14.470985 ,\n", - " -14.393481 , -14.244798 , -14.005135 , -13.9285145, -13.909489 ],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 31, 32, 62, 149, 279, 173, 206, 121], dtype=int32),\n", - " array([349.6084 , 349.84772, 349.8697 , 349.9277 , 349.9692 , 350.07477,\n", - " 350.1816 , 350.27115, 350.27704, 350.38074], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 121, 186, 86, 49, 487], dtype=int32),\n", - " array([288.5658 , 288.70242, 288.7197 , 288.81473, 288.93903, 289.13483,\n", - " 289.25507, 289.34436, 289.3612 , 289.4463 ], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 121, 305, 62, 100, 173, 206], dtype=int32),\n", - " array([-11.456671, -11.446159, -11.423652, -11.416996, -11.064107,\n", - " -10.844979, -10.813096, -10.770634, -10.702918, -10.699669],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 31, 32, 62, 86, 100, 121, 49, 279], dtype=int32),\n", - " array([268.95468, 269.01685, 269.22226, 269.24066, 269.26004, 269.29535,\n", - " 269.38977, 269.43176, 269.53998, 269.55698], dtype=float32)),\n", - " (array([ 19, 31, 62, 32, 149, 43, 121, 173, 735, 347], dtype=int32),\n", - " array([215.332 , 215.37314, 215.48581, 215.62888, 215.64783, 215.65305,\n", - " 215.65874, 215.69524, 215.79202, 215.79424], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 262, 8, 255, 62, 12, 268], dtype=int32),\n", - " array([141.59251, 141.83751, 142.13933, 142.16425, 142.16447, 142.30437,\n", - " 142.30954, 142.45528, 142.49702, 142.51967], dtype=float32)),\n", - " (array([ 19, 31, 62, 173, 358, 32, 2181, 8, 884, 636],\n", - " dtype=int32),\n", - " array([352.74274, 353.2657 , 353.33234, 353.3576 , 353.39316, 353.40036,\n", - " 353.46933, 353.5422 , 353.56155, 353.6238 ], dtype=float32)),\n", - " (array([ 43, 19, 32, 188, 848, 206, 579, 112, 487, 226], dtype=int32),\n", - " array([338.15225, 338.45187, 338.524 , 338.7841 , 338.79407, 338.8417 ,\n", - " 338.90436, 338.92407, 338.93015, 338.952 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 255, 29, 121, 268, 62, 103, 105], dtype=int32),\n", - " array([300.31522, 300.37778, 300.79977, 301.11166, 301.12476, 301.15967,\n", - " 301.2287 , 301.36957, 301.4229 , 301.50925], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 268, 62, 12, 358, 121, 173], dtype=int32),\n", - " array([-15.175397 , -14.3523035, -14.324574 , -14.270303 , -13.996518 ,\n", - " -13.875429 , -13.867051 , -13.852484 , -13.790112 , -13.669666 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 121, 12, 32, 62, 173, 43, 268, 61], dtype=int32),\n", - " array([263.42712, 263.563 , 263.93036, 264.00702, 264.38058, 264.47498,\n", - " 264.50125, 264.52225, 264.5853 , 264.61554], dtype=float32)),\n", - " (array([ 32, 43, 305, 112, 186, 31, 554, 19, 62, 111], dtype=int32),\n", - " array([337.35098, 337.5314 , 337.86545, 337.91376, 337.94345, 337.94797,\n", - " 337.99365, 338.01077, 338.05304, 338.0803 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 173, 121, 100, 268, 149], dtype=int32),\n", - " array([273.55392, 273.77774, 273.83148, 273.8362 , 274.25946, 274.31317,\n", - " 274.32834, 274.46176, 274.5391 , 274.8087 ], dtype=float32)),\n", - " (array([ 31, 19, 173, 12, 62, 121, 32, 43, 268, 86], dtype=int32),\n", - " array([349.18506, 349.31424, 349.6772 , 349.79327, 349.91583, 349.93066,\n", - " 349.94504, 349.95108, 350.343 , 350.40012], dtype=float32)),\n", - " (array([ 552, 539, 0, 149, 965, 3146, 31, 1784, 262, 287],\n", - " dtype=int32),\n", - " array([317.1727 , 317.24374, 317.55713, 317.73663, 317.86557, 317.89526,\n", - " 317.91296, 317.91867, 317.9318 , 317.97437], dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 121, 62, 100, 268, 305, 49], dtype=int32),\n", - " array([314.1853 , 314.31137, 314.42017, 314.44604, 314.57455, 314.77603,\n", - " 314.8114 , 315.02228, 315.10776, 315.1962 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 358, 62, 173, 258, 268, 884], dtype=int32),\n", - " array([347.45734, 347.50494, 347.7619 , 347.82605, 347.98862, 348.14484,\n", - " 348.20886, 348.3074 , 348.32352, 348.42862], dtype=float32)),\n", - " (array([ 19, 32, 62, 31, 121, 43, 173, 268, 100, 8], dtype=int32),\n", - " array([314.78854, 314.91577, 315.16824, 315.24203, 315.32956, 315.36145,\n", - " 315.4264 , 315.52505, 315.65732, 315.69305], dtype=float32)),\n", - " (array([ 32, 19, 305, 43, 31, 188, 528, 69, 204, 226], dtype=int32),\n", - " array([259.37012, 259.38394, 259.40344, 259.46835, 259.77426, 259.87195,\n", - " 259.94037, 260.0137 , 260.05203, 260.1233 ], dtype=float32)),\n", - " (array([ 62, 31, 19, 43, 49, 121, 149, 164, 32, 8], dtype=int32),\n", - " array([338.4056 , 338.77094, 338.81546, 338.83694, 338.95892, 338.99554,\n", - " 339.017 , 339.05597, 339.2428 , 339.24435], dtype=float32)),\n", - " (array([176, 358, 884, 43, 62, 258, 32, 19, 636, 39], dtype=int32),\n", - " array([284.36417, 284.5536 , 284.56604, 284.6107 , 284.7576 , 284.7714 ,\n", - " 284.8168 , 284.82672, 284.87845, 284.9858 ], dtype=float32)),\n", - " (array([1812, 149, 996, 2035, 153, 489, 1482, 1161, 1118, 8],\n", - " dtype=int32),\n", - " array([-7.017111 , -6.8244452, -6.722717 , -6.7156744, -6.6452174,\n", - " -6.567884 , -6.5333624, -6.4514637, -6.36349 , -6.3416147],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 49, 121, 204, 36, 279], dtype=int32),\n", - " array([42.485863, 42.780212, 42.81112 , 42.90133 , 42.978966, 43.1729 ,\n", - " 43.2377 , 43.30827 , 43.372684, 43.37734 ], dtype=float32)),\n", - " (array([ 31, 19, 12, 121, 32, 43, 29, 100, 62, 86], dtype=int32),\n", - " array([-3.692336 , -3.453667 , -3.2474349, -3.2135587, -3.1679478,\n", - " -3.0567408, -3.0422711, -3.0117793, -2.943595 , -2.8708534],\n", - " dtype=float32)),\n", - " (array([ 31, 43, 62, 19, 32, 164, 268, 86, 121, 358], dtype=int32),\n", - " array([306.2654 , 306.33945, 306.4547 , 306.52942, 306.597 , 306.75366,\n", - " 306.84937, 306.86676, 306.8713 , 306.95096], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 166, 358, 62, 204, 258, 268], dtype=int32),\n", - " array([296.3471 , 296.37015, 296.55472, 296.5801 , 296.78766, 296.7985 ,\n", - " 296.87164, 296.8785 , 296.90323, 297.0874 ], dtype=float32)),\n", - " (array([ 149, 735, 965, 19, 0, 552, 262, 8, 31, 1419],\n", - " dtype=int32),\n", - " array([226.01115, 226.10297, 226.1076 , 226.23538, 226.2463 , 226.272 ,\n", - " 226.32721, 226.34567, 226.43701, 226.45033], dtype=float32)),\n", - " (array([ 31, 32, 43, 62, 19, 121, 29, 112, 120, 268], dtype=int32),\n", - " array([344.2748 , 344.44553, 344.52036, 344.72614, 344.80002, 344.90756,\n", - " 344.9791 , 345.01923, 345.11835, 345.192 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 32, 43, 100, 49, 268, 164], dtype=int32),\n", - " array([342.22598, 342.40228, 342.4085 , 342.45544, 342.51126, 342.6811 ,\n", - " 342.8479 , 342.86078, 342.99628, 343.0427 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 105], dtype=int32),\n", - " array([287.51895, 287.61398, 288.0591 , 288.0906 , 288.18866, 288.2007 ,\n", - " 288.51242, 288.524 , 288.70685, 288.716 ], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 62, 173, 121, 305, 268, 374], dtype=int32),\n", - " array([-21.612953, -21.52249 , -21.452255, -21.379147, -21.043661,\n", - " -20.812916, -20.806978, -20.763453, -20.695934, -20.628233],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 32, 43, 173, 268, 61, 358], dtype=int32),\n", - " array([317.82678, 318.26996, 318.60562, 318.65625, 318.7585 , 318.80792,\n", - " 318.8308 , 318.87646, 318.8963 , 318.994 ], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 350, 305, 69, 279, 36], dtype=int32),\n", - " array([343.07288, 343.14206, 343.69296, 343.73373, 343.79886, 343.92645,\n", - " 343.9273 , 343.93744, 343.94446, 343.9494 ], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 268, 255, 487, 42, 805], dtype=int32),\n", - " array([-13.988481 , -13.837422 , -13.704304 , -13.344196 , -13.2673645,\n", - " -13.18387 , -13.172173 , -13.1523285, -13.090306 , -13.086044 ],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 121, 86, 120, 100, 268], dtype=int32),\n", - " array([307.9327 , 308.0714 , 308.10782, 308.20166, 308.48843, 308.88086,\n", - " 308.99414, 309.06448, 309.07455, 309.17303], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 121, 29, 100, 173, 268], dtype=int32),\n", - " array([351.5901 , 351.73917, 351.76743, 352.157 , 352.19598, 352.3126 ,\n", - " 352.45346, 352.4693 , 352.4991 , 352.51056], dtype=float32)),\n", - " (array([ 43, 32, 31, 62, 19, 149, 36, 255, 112, 86], dtype=int32),\n", - " array([316.7614 , 316.99316, 317.07388, 317.26318, 317.48212, 317.56055,\n", - " 317.66666, 317.669 , 317.67285, 317.70544], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-5.0741687, -5.0485473, -4.509162 , -4.445554 , -4.4442058,\n", - " -4.273513 , -4.263999 , -4.065134 , -4.0441136, -4.0163875],\n", - " dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 62, 173, 121, 268, 100, 29], dtype=int32),\n", - " array([343.76868, 343.84 , 343.91858, 344.00677, 344.29614, 344.72903,\n", - " 344.73883, 344.74832, 344.7669 , 344.79733], dtype=float32)),\n", - " (array([ 43, 19, 31, 550, 62, 32, 100, 121, 8, 149], dtype=int32),\n", - " array([53.205914, 53.22059 , 53.28345 , 53.303814, 53.348705, 53.40988 ,\n", - " 53.53761 , 53.585125, 53.77041 , 53.851917], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 105, 268, 173, 358], dtype=int32),\n", - " array([-15.890402, -15.684281, -15.52024 , -15.095209, -15.063954,\n", - " -14.951069, -14.567852, -14.562141, -14.548413, -14.498462],\n", - " dtype=float32)),\n", - " (array([ 32, 31, 19, 43, 121, 29, 62, 305, 100, 268], dtype=int32),\n", - " array([265.64688, 265.69025, 265.89487, 266.02777, 266.2306 , 266.38507,\n", - " 266.44272, 266.5225 , 266.659 , 266.6969 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 29, 268, 62, 441, 103], dtype=int32),\n", - " array([287.11838, 287.34442, 287.65036, 287.82922, 287.90732, 287.91147,\n", - " 287.92307, 288.0329 , 288.13937, 288.15973], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 69, 36, 279, 206, 449], dtype=int32),\n", - " array([311.03232, 311.06607, 311.26587, 311.70935, 311.75217, 311.75443,\n", - " 311.77985, 311.86707, 311.9017 , 311.9381 ], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 120, 305, 62, 121, 371, 49], dtype=int32),\n", - " array([308.45367, 308.49292, 308.61252, 308.7293 , 308.93237, 309.00485,\n", - " 309.08548, 309.09116, 309.10516, 309.23346], dtype=float32)),\n", - " (array([ 31, 19, 62, 32, 121, 43, 100, 173, 268, 214], dtype=int32),\n", - " array([-10.341681, -10.104004, -9.997879, -9.942418, -9.884092,\n", - " -9.841873, -9.751417, -9.676609, -9.173783, -9.16163 ],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 69, 62, 121, 279, 100, 1088],\n", - " dtype=int32),\n", - " array([302.63937, 302.90488, 303.10846, 303.1919 , 303.20636, 303.25427,\n", - " 303.28244, 303.33725, 303.3611 , 303.377 ], dtype=float32)),\n", - " (array([ 32, 241, 43, 31, 149, 19, 8, 262, 62, 100], dtype=int32),\n", - " array([310.07986, 310.12897, 310.22546, 310.24493, 310.3166 , 310.32654,\n", - " 310.52274, 310.53534, 310.72757, 310.9148 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 12, 29, 121, 21, 105, 268, 62], dtype=int32),\n", - " array([356.68155, 357.3134 , 357.53873, 357.7081 , 357.7115 , 357.77197,\n", - " 357.82104, 357.83554, 357.895 , 357.9584 ], dtype=float32)),\n", - " (array([ 19, 32, 31, 173, 255, 43, 62, 121, 86, 100], dtype=int32),\n", - " array([-17.402403, -16.974453, -16.948748, -16.725214, -16.715353,\n", - " -16.714073, -16.631855, -16.513857, -16.409714, -16.278208],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 29, 43, 32, 121, 268, 173, 100, 24], dtype=int32),\n", - " array([-4.2243953, -4.126679 , -3.6223252, -3.6113648, -3.6087067,\n", - " -3.3742836, -3.2807965, -3.2385452, -3.1359859, -3.1099405],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 43, 62, 19, 49, 121, 304, 384, 392], dtype=int32),\n", - " array([303.59982, 303.61542, 303.75247, 303.87396, 304.1185 , 304.11853,\n", - " 304.14862, 304.3223 , 304.32532, 304.41406], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 100, 86, 268, 173], dtype=int32),\n", - " array([-8.085493 , -7.7274246, -7.6989603, -7.6576977, -7.4381723,\n", - " -7.424794 , -7.165704 , -7.1038136, -7.059535 , -7.045127 ],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 86, 121, 347, 112, 8], dtype=int32),\n", - " array([-12.746703, -12.741758, -12.736581, -12.565916, -12.34575 ,\n", - " -12.180504, -12.031655, -11.946743, -11.930024, -11.921896],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 255, 62, 121, 120, 268, 258], dtype=int32),\n", - " array([315.4357 , 315.57855, 315.61682, 316.0451 , 316.3004 , 316.34836,\n", - " 316.37317, 316.4886 , 316.49002, 316.50043], dtype=float32)),\n", - " (array([ 19, 31, 173, 43, 32, 12, 121, 29, 86, 100], dtype=int32),\n", - " array([280.57272, 280.7719 , 281.07443, 281.08145, 281.1216 , 281.18524,\n", - " 281.29205, 281.30084, 281.3151 , 281.45456], dtype=float32)),\n", - " (array([ 31, 19, 32, 12, 43, 62, 173, 268, 29, 255], dtype=int32),\n", - " array([212.05937, 212.52017, 212.58507, 212.63403, 212.72137, 212.80849,\n", - " 213.1062 , 213.11346, 213.26201, 213.30971], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 305, 206, 62, 121, 188, 166], dtype=int32),\n", - " array([214.13506, 214.32698, 214.4319 , 214.82591, 214.9582 , 215.22668,\n", - " 215.25037, 215.32793, 215.35207, 215.35536], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 43, 32, 100, 86, 164, 173], dtype=int32),\n", - " array([344.09488, 344.6076 , 344.66895, 344.8335 , 344.85468, 344.86243,\n", - " 345.18646, 345.26413, 345.31964, 345.32736], dtype=float32)),\n", - " (array([ 31, 19, 62, 32, 121, 49, 8, 100, 43, 255], dtype=int32),\n", - " array([289.59015, 289.7864 , 289.8605 , 289.99622, 290.1746 , 290.34833,\n", - " 290.35764, 290.42117, 290.4458 , 290.47693], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 86, 100, 255, 305, 268], dtype=int32),\n", - " array([309.9911 , 310.2475 , 310.25287, 310.38852, 310.3959 , 310.7034 ,\n", - " 310.78873, 310.84158, 310.85638, 310.94516], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 305, 62, 487, 121, 268, 42], dtype=int32),\n", - " array([344.07626, 344.12146, 344.15652, 344.5141 , 344.67456, 344.82837,\n", - " 344.9355 , 344.95264, 344.96835, 344.9991 ], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 176, 358, 305, 268, 206, 258], dtype=int32),\n", - " array([301.91364, 301.94638, 302.14154, 302.47595, 302.52408, 302.5301 ,\n", - " 302.6429 , 302.66528, 302.67337, 302.7384 ], dtype=float32)),\n", - " (array([ 31, 19, 121, 43, 62, 8, 32, 149, 173, 347], dtype=int32),\n", - " array([311.56973, 311.93002, 312.0687 , 312.26904, 312.3276 , 312.33615,\n", - " 312.4214 , 312.52353, 312.54443, 312.58813], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 149, 62, 262, 8, 121, 153], dtype=int32),\n", - " array([-6.4855523, -6.256936 , -6.063451 , -5.9578786, -5.8819222,\n", - " -5.7880354, -5.7735653, -5.689861 , -5.5408607, -5.512192 ],\n", - " dtype=float32)),\n", - " (array([ 32, 43, 19, 62, 8, 31, 166, 262, 204, 149], dtype=int32),\n", - " array([339.32056, 339.53723, 339.67032, 339.851 , 339.86502, 339.917 ,\n", - " 340.10864, 340.15747, 340.1631 , 340.2363 ], dtype=float32)),\n", - " (array([ 62, 31, 32, 19, 43, 173, 100, 121, 552, 8], dtype=int32),\n", - " array([343.87137, 343.94736, 343.96133, 344.1342 , 344.17688, 344.2921 ,\n", - " 344.3133 , 344.3215 , 344.419 , 344.5248 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 255, 86, 62, 121, 32, 100, 8], dtype=int32),\n", - " array([57.171047, 57.300293, 57.456116, 57.552956, 57.575035, 57.703205,\n", - " 57.74877 , 57.83789 , 57.954014, 58.031185], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 32, 173, 268, 120, 43, 262], dtype=int32),\n", - " array([291.32318, 291.49185, 291.9709 , 292.06073, 292.27478, 292.31512,\n", - " 292.36655, 292.48712, 292.53076, 292.6299 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 29, 43, 105, 121, 268, 62, 100], dtype=int32),\n", - " array([-16.020737 , -15.7931795, -15.599528 , -15.180405 , -15.113835 ,\n", - " -14.977344 , -14.974714 , -14.925344 , -14.925142 , -14.800559 ],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 358, 258, 206, 884, 636, 176], dtype=int32),\n", - " array([295.85547, 296.11914, 296.14532, 296.27072, 296.31024, 296.36993,\n", - " 296.5217 , 296.55975, 296.67944, 296.71323], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 100, 86, 268, 29], dtype=int32),\n", - " array([156.00362, 156.18478, 156.18512, 156.24487, 156.56755, 156.68701,\n", - " 156.89453, 156.92322, 157.02383, 157.05093], dtype=float32)),\n", - " (array([ 31, 19, 43, 29, 32, 121, 86, 24, 268, 105], dtype=int32),\n", - " array([-11.189659, -10.994785, -10.637021, -10.628121, -10.387021,\n", - " -10.361363, -10.263288, -10.212691, -10.182824, -10.142854],\n", - " dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 103, 32, 61, 43, 173, 268], dtype=int32),\n", - " array([-6.005646 , -5.299345 , -5.2527857, -5.0243163, -4.9157457,\n", - " -4.818486 , -4.795618 , -4.764198 , -4.7160826, -4.715994 ],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 86, 16, 121, 173, 100], dtype=int32),\n", - " array([314.16678, 314.39813, 314.40552, 314.43243, 314.6677 , 314.72833,\n", - " 314.74393, 314.7528 , 314.91867, 315.04828], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 255, 268, 121, 120, 86], dtype=int32),\n", - " array([-17.193256, -17.039999, -16.79972 , -16.755228, -16.568996,\n", - " -16.313007, -16.245993, -16.171654, -16.059319, -16.003174],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 121, 103, 62, 32, 268, 120, 164, 29], dtype=int32),\n", - " array([265.82047, 266.27856, 266.48312, 266.73096, 266.7545 , 266.79245,\n", - " 266.86276, 266.98782, 267.03455, 267.05856], dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 62, 121, 268, 305, 100, 49], dtype=int32),\n", - " array([319.28192, 319.45398, 319.54037, 319.54303, 319.75848, 320.0884 ,\n", - " 320.108 , 320.20068, 320.29398, 320.30594], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 121, 62, 49, 100, 268, 164], dtype=int32),\n", - " array([308.2159 , 308.54578, 308.55927, 308.69986, 308.8049 , 308.83264,\n", - " 309.02768, 309.1625 , 309.19815, 309.19907], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 255, 268, 121, 86, 164], dtype=int32),\n", - " array([-19.607666, -19.478085, -19.320446, -19.172272, -18.873766,\n", - " -18.723473, -18.613825, -18.567207, -18.566029, -18.552029],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 121, 173, 206, 29, 86], dtype=int32),\n", - " array([307.87057, 307.9003 , 308.49023, 308.51843, 308.792 , 308.8596 ,\n", - " 308.9318 , 309.06952, 309.15012, 309.17218], dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 31, 206, 121, 279, 173, 100], dtype=int32),\n", - " array([340.90964, 341.18716, 341.33032, 341.65274, 341.65872, 341.7587 ,\n", - " 341.91833, 341.94028, 342.03506, 342.0902 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 29, 173, 268, 86], dtype=int32),\n", - " array([-9.436364, -9.173308, -9.009834, -8.934583, -8.633148, -8.594711,\n", - " -8.540754, -8.493278, -8.441753, -8.38345 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 29, 305, 121, 62, 268, 105], dtype=int32),\n", - " array([327.17972, 327.23294, 327.41696, 327.4331 , 327.9917 , 328.02567,\n", - " 328.03696, 328.19165, 328.22324, 328.28644], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 173, 12, 100, 268], dtype=int32),\n", - " array([343.57242, 343.75925, 344.2317 , 344.29984, 344.31036, 344.33786,\n", - " 344.56778, 344.60086, 344.6228 , 344.7307 ], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 121, 268, 100, 49, 120], dtype=int32),\n", - " array([341.16324, 341.2689 , 341.27478, 341.34 , 341.5751 , 341.85776,\n", - " 342.0424 , 342.05667, 342.07333, 342.2148 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 268, 358, 121, 166, 97], dtype=int32),\n", - " array([306.0728 , 306.09064, 306.22867, 306.42188, 306.9325 , 307.01953,\n", - " 307.0909 , 307.11935, 307.17044, 307.22147], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 62, 121, 204, 487, 166, 164], dtype=int32),\n", - " array([-21.794752, -21.704985, -21.61844 , -21.420767, -21.202236,\n", - " -21.03471 , -20.918108, -20.884716, -20.848198, -20.79975 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", - " array([-5.0159473, -5.0133467, -4.4760823, -4.416821 , -4.405054 ,\n", - " -4.231186 , -4.2287207, -4.0311823, -4.005026 , -3.966051 ],\n", - " dtype=float32)),\n", - " (array([1638, 19, 279, 13, 32, 118, 43, 610, 815, 370],\n", - " dtype=int32),\n", - " array([347.81808, 348.21762, 348.3405 , 348.41226, 348.46475, 348.5277 ,\n", - " 348.643 , 348.6486 , 348.67526, 348.68784], dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 29, 86, 43, 21, 12, 24], dtype=int32),\n", - " array([-6.467538 , -6.4442935, -5.897809 , -5.831173 , -5.8068085,\n", - " -5.765753 , -5.6836014, -5.681742 , -5.658136 , -5.645841 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 173, 121, 62, 358, 268, 100], dtype=int32),\n", - " array([327.39117, 327.41367, 327.46848, 327.79846, 327.94684, 328.021 ,\n", - " 328.08438, 328.10913, 328.11047, 328.37894], dtype=float32)),\n", - " (array([ 31, 19, 12, 173, 121, 29, 268, 32, 100, 24], dtype=int32),\n", - " array([1.7265751, 1.8700533, 2.464658 , 2.5191495, 2.6392179, 2.817502 ,\n", - " 2.9706817, 3.003153 , 3.1233983, 3.1877522], dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 43, 32, 103, 173, 100, 268], dtype=int32),\n", - " array([347.82153, 348.3465 , 348.5297 , 348.65796, 348.79175, 348.92554,\n", - " 349.11295, 349.149 , 349.16806, 349.17993], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 268, 62, 121, 173, 358, 120], dtype=int32),\n", - " array([-20.399937, -20.15641 , -19.97839 , -19.86608 , -19.54196 ,\n", - " -19.526468, -19.35872 , -19.232452, -19.21796 , -19.164282],\n", - " dtype=float32)),\n", - " (array([149, 62, 31, 32, 262, 8, 43, 19, 121, 100], dtype=int32),\n", - " array([349.0581 , 349.15714, 349.18317, 349.21707, 349.42548, 349.4463 ,\n", - " 349.4783 , 349.48047, 349.59106, 349.61743], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", - " array([342.80194, 342.93613, 343.11276, 343.20624, 343.33676, 343.50534,\n", - " 343.70572, 343.81918, 343.90698, 343.91614], dtype=float32)),\n", - " (array([149, 8, 262, 153, 31, 539, 0, 530, 57, 369], dtype=int32),\n", - " array([350.04428, 350.3302 , 350.35052, 350.63522, 350.76788, 350.80096,\n", - " 350.8058 , 350.81235, 350.8247 , 350.83926], dtype=float32)),\n", - " (array([ 19, 149, 31, 8, 552, 32, 62, 121, 43, 262], dtype=int32),\n", - " array([300.33966, 300.46338, 300.58124, 300.637 , 300.81696, 300.81708,\n", - " 300.88522, 300.92712, 300.97235, 301.01892], dtype=float32)),\n", - " (array([ 43, 149, 62, 279, 129, 350, 32, 347, 36, 31], dtype=int32),\n", - " array([-23.871014, -23.72525 , -23.503815, -23.502007, -23.499966,\n", - " -23.463312, -23.450043, -23.448347, -23.438875, -23.437027],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 69, 36, 449, 350, 240], dtype=int32),\n", - " array([295.42017, 295.43604, 295.4444 , 295.44955, 295.53717, 295.63864,\n", - " 295.6832 , 295.73346, 295.87933, 295.88153], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 86, 49], dtype=int32),\n", - " array([308.8244 , 308.8734 , 308.9243 , 308.95322, 309.25433, 309.43945,\n", - " 309.65298, 309.6704 , 309.7664 , 309.76868], dtype=float32)),\n", - " (array([ 43, 31, 19, 32, 358, 589, 97, 62, 121, 173], dtype=int32),\n", - " array([309.85483, 309.93176, 310.34106, 310.38965, 310.39078, 310.4858 ,\n", - " 310.49197, 310.49362, 310.54358, 310.5536 ], dtype=float32)),\n", - " (array([ 31, 121, 43, 32, 19, 62, 86, 120, 268, 255], dtype=int32),\n", - " array([50.76687 , 51.438454, 51.48716 , 51.522655, 51.554604, 51.628387,\n", - " 51.796402, 51.865253, 51.9684 , 52.01172 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 43, 173, 32, 268, 12, 100], dtype=int32),\n", - " array([345.1402 , 345.468 , 345.71017, 345.72964, 346.08655, 346.12393,\n", - " 346.15323, 346.16113, 346.25333, 346.2692 ], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 268, 120, 49, 86], dtype=int32),\n", - " array([309.7443 , 309.79987, 309.8201 , 309.91574, 310.13895, 310.25586,\n", - " 310.41113, 310.48035, 310.4928 , 310.56735], dtype=float32)),\n", - " (array([ 43, 32, 305, 49, 19, 62, 112, 483, 166, 487], dtype=int32),\n", - " array([316.18222, 316.55273, 316.88788, 316.88977, 316.97662, 317.02985,\n", - " 317.12967, 317.12973, 317.18176, 317.20413], dtype=float32)),\n", - " (array([ 31, 19, 32, 358, 121, 43, 62, 173, 268, 97], dtype=int32),\n", - " array([343.0131 , 343.28653, 343.3871 , 343.39142, 343.40115, 343.5621 ,\n", - " 343.58423, 343.78552, 343.8336 , 344.0114 ], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 62, 43, 120, 268, 173, 100], dtype=int32),\n", - " array([-14.42631 , -14.415461, -14.176025, -13.962046, -13.851507,\n", - " -13.797985, -13.685981, -13.650972, -13.570874, -13.45312 ],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 268, 204, 29, 206, 121, 166], dtype=int32),\n", - " array([267.44852, 267.50827, 267.75266, 268.00235, 268.11444, 268.1258 ,\n", - " 268.35196, 268.38818, 268.39667, 268.44592], dtype=float32)),\n", - " (array([ 31, 103, 19, 61, 121, 268, 535, 40, 12, 120], dtype=int32),\n", - " array([343.6989 , 344.47595, 344.70236, 344.94162, 344.95032, 344.97284,\n", - " 345.06775, 345.07593, 345.11835, 345.12515], dtype=float32)),\n", - " (array([149, 262, 31, 32, 19, 835, 241, 0, 369, 43], dtype=int32),\n", - " array([348.56985, 348.64056, 348.84622, 348.9293 , 348.9528 , 348.9548 ,\n", - " 348.96805, 348.9862 , 349.01007, 349.01956], dtype=float32)),\n", - " (array([ 19, 31, 121, 29, 173, 43, 12, 32, 105, 268], dtype=int32),\n", - " array([347.46866, 347.60608, 348.30573, 348.32297, 348.37988, 348.39984,\n", - " 348.5157 , 348.542 , 348.65463, 348.81802], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 268, 255, 100, 29], dtype=int32),\n", - " array([240.94228, 241.10362, 241.12108, 241.21033, 241.59976, 241.61243,\n", - " 241.78494, 241.88823, 241.89291, 241.91635], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 121, 62, 204, 268, 100, 120], dtype=int32),\n", - " array([316.31665, 316.49362, 316.57642, 316.78735, 316.95148, 317.02228,\n", - " 317.1421 , 317.20248, 317.2166 , 317.25565], dtype=float32)),\n", - " (array([ 19, 43, 31, 86, 32, 121, 62, 173, 100, 29], dtype=int32),\n", - " array([314.52826, 314.84546, 315.01562, 315.05515, 315.21722, 315.22354,\n", - " 315.24313, 315.33847, 315.5094 , 315.52777], dtype=float32)),\n", - " (array([149, 735, 262, 8, 31, 552, 450, 32, 62, 19], dtype=int32),\n", - " array([319.87048, 320.07922, 320.1512 , 320.18228, 320.5829 , 320.65225,\n", - " 320.65305, 320.65683, 320.68857, 320.7022 ], dtype=float32)),\n", - " (array([ 19, 31, 21, 121, 32, 29, 173, 12, 100, 268], dtype=int32),\n", - " array([323.00748, 323.50046, 323.51654, 323.83002, 323.8655 , 323.99277,\n", - " 324.0247 , 324.02908, 324.07242, 324.1066 ], dtype=float32)),\n", - " (array([ 31, 19, 103, 43, 29, 121, 12, 268, 32, 120], dtype=int32),\n", - " array([231.82516, 232.01515, 232.36888, 232.60991, 232.66496, 232.70091,\n", - " 232.71054, 232.7194 , 232.79173, 232.8018 ], dtype=float32)),\n", - " (array([ 32, 31, 62, 43, 19, 121, 204, 268, 8, 49], dtype=int32),\n", - " array([346.36383, 346.37796, 346.6725 , 346.87506, 346.9047 , 347.0223 ,\n", - " 347.02927, 347.04068, 347.0678 , 347.12524], dtype=float32)),\n", - " (array([ 32, 19, 62, 43, 31, 112, 100, 69, 173, 86], dtype=int32),\n", - " array([310.82144, 310.92435, 310.9696 , 311.0524 , 311.1181 , 311.1658 ,\n", - " 311.29068, 311.30902, 311.32593, 311.34253], dtype=float32)),\n", - " (array([ 19, 4326, 3162, 2310, 32, 43, 31, 4838, 62, 149],\n", - " dtype=int32),\n", - " array([249.44016, 249.45004, 249.60986, 249.64139, 249.70992, 249.76729,\n", - " 249.7751 , 249.8351 , 249.88657, 249.89322], dtype=float32)),\n", - " (array([ 31, 19, 43, 62, 32, 121, 164, 268, 49, 86], dtype=int32),\n", - " array([-22.562975, -22.560837, -22.413036, -22.334667, -22.316479,\n", - " -22.18161 , -21.895603, -21.873486, -21.817493, -21.754555],\n", - " dtype=float32)),\n", - " (array([ 31, 62, 32, 36, 43, 610, 121, 19, 69, 279], dtype=int32),\n", - " array([312.21576, 312.2401 , 312.26993, 312.38785, 312.49933, 312.54776,\n", - " 312.57104, 312.67737, 312.68393, 312.69513], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 62, 206, 305, 121, 268, 487], dtype=int32),\n", - " array([284.8268 , 284.8659 , 284.89288, 285.07498, 285.2831 , 285.4737 ,\n", - " 285.65622, 285.71848, 285.7789 , 285.7832 ], dtype=float32)),\n", - " (array([ 43, 32, 62, 19, 31, 49, 268, 121, 112, 120], dtype=int32),\n", - " array([305.9512 , 306.17957, 306.6377 , 306.63815, 306.6725 , 306.87018,\n", - " 307.01367, 307.03284, 307.04086, 307.0847 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 69, 173, 258, 279, 665, 62], dtype=int32),\n", - " array([314.8485 , 315.25262, 315.39423, 315.39603, 315.4922 , 315.51727,\n", - " 315.5899 , 315.6018 , 315.6037 , 315.67908], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 268, 49, 100, 305], dtype=int32),\n", - " array([320.40286, 320.466 , 320.54807, 320.55475, 320.90228, 321.0765 ,\n", - " 321.2331 , 321.30875, 321.32114, 321.38458], dtype=float32)),\n", - " (array([ 19, 31, 43, 121, 29, 62, 103, 32, 268, 173], dtype=int32),\n", - " array([-14.950289, -14.756871, -14.075444, -13.935917, -13.838904,\n", - " -13.814549, -13.779864, -13.755139, -13.739934, -13.731543],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 31, 32, 121, 62, 268, 487, 29, 848], dtype=int32),\n", - " array([312.37747, 312.3967 , 312.5323 , 312.5502 , 312.8118 , 312.92868,\n", - " 312.98355, 312.98596, 313.0252 , 313.0504 ], dtype=float32)),\n", - " (array([ 43, 62, 31, 32, 19, 121, 49, 86, 25, 273], dtype=int32),\n", - " array([307.1536 , 307.24713, 307.38647, 307.57568, 307.60028, 307.6711 ,\n", - " 307.88113, 307.95306, 307.97028, 307.97275], dtype=float32)),\n", - " (array([262, 149, 8, 450, 62, 489, 369, 153, 325, 32], dtype=int32),\n", - " array([210.27339, 210.30504, 210.46014, 210.50189, 210.7549 , 210.76389,\n", - " 210.76942, 210.80673, 210.85759, 210.8653 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 268, 62, 105, 120, 29], dtype=int32),\n", - " array([308.6401 , 309.06784, 309.18906, 309.34564, 309.52155, 309.59317,\n", - " 309.65195, 309.7466 , 309.8 , 309.8042 ], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 121, 268, 100, 49, 120], dtype=int32),\n", - " array([341.30023, 341.4049 , 341.40576, 341.47562, 341.7177 , 341.99478,\n", - " 342.17505, 342.1918 , 342.20712, 342.35205], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 86, 100, 173, 268], dtype=int32),\n", - " array([51.62322 , 51.70004 , 51.93884 , 52.08133 , 52.165623, 52.20838 ,\n", - " 52.482906, 52.546368, 52.58254 , 52.628117], dtype=float32)),\n", - " (array([ 31, 32, 62, 19, 121, 43, 8, 173, 347, 100], dtype=int32),\n", - " array([318.883 , 319.01743, 319.23465, 319.35052, 319.38702, 319.4028 ,\n", - " 319.4835 , 319.5272 , 319.6542 , 319.71283], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 121, 62, 49, 164, 206, 105], dtype=int32),\n", - " array([286.465 , 286.51447, 286.5355 , 286.91913, 286.997 , 287.0653 ,\n", - " 287.1553 , 287.20862, 287.35745, 287.35916], dtype=float32)),\n", - " (array([ 43, 62, 49, 31, 32, 19, 164, 121, 100, 139], dtype=int32),\n", - " array([306.247 , 306.2682 , 306.38638, 306.39606, 306.45087, 306.51486,\n", - " 306.53436, 306.64188, 306.70016, 306.8196 ], dtype=float32)),\n", - " (array([ 31, 103, 121, 19, 12, 313, 535, 2180, 43, 62],\n", - " dtype=int32),\n", - " array([351.9761 , 352.98825, 353.0984 , 353.24844, 353.30118, 353.3142 ,\n", - " 353.3811 , 353.4146 , 353.44522, 353.5219 ], dtype=float32)),\n", - " (array([ 43, 31, 32, 19, 62, 121, 279, 86, 100, 69], dtype=int32),\n", - " array([312.92926, 313.1717 , 313.29642, 313.2985 , 313.42117, 313.479 ,\n", - " 313.5497 , 313.5814 , 313.65286, 313.69855], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 62, 43, 49, 8, 100, 268], dtype=int32),\n", - " array([320.81348, 321.05295, 321.05365, 321.16675, 321.19067, 321.1962 ,\n", - " 321.60626, 321.6853 , 321.74094, 321.7631 ], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 121, 268, 49, 100, 305], dtype=int32),\n", - " array([320.5586 , 320.61145, 320.6981 , 320.71088, 321.04718, 321.22855,\n", - " 321.38336, 321.46152, 321.47202, 321.55453], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([312.37073, 312.55405, 312.76764, 312.87885, 312.93515, 313.00577,\n", - " 313.24124, 313.37503, 313.43945, 313.4537 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 62, 43, 121, 268, 120, 8, 149], dtype=int32),\n", - " array([355.07095, 355.7347 , 355.88535, 355.94373, 355.98886, 356.01782,\n", - " 356.12405, 356.1529 , 356.1666 , 356.22464], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 173, 121, 100, 69, 268], dtype=int32),\n", - " array([245.90755, 246.11623, 246.3128 , 246.38005, 246.49422, 246.70197,\n", - " 246.76761, 246.9832 , 247.16249, 247.21341], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 121, 62, 100, 268, 120, 86], dtype=int32),\n", - " array([313.88638, 314.13068, 314.13995, 314.3594 , 314.59048, 314.64545,\n", - " 314.7349 , 314.81088, 314.84097, 314.86066], dtype=float32)),\n", - " (array([ 36, 43, 19, 610, 69, 62, 31, 149, 279, 118], dtype=int32),\n", - " array([-15.567868, -15.50956 , -15.436534, -15.407452, -15.392582,\n", - " -15.325006, -15.272363, -15.271942, -15.259655, -15.244802],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 121, 62, 268, 105, 358, 103], dtype=int32),\n", - " array([323.1203 , 323.18228, 323.5883 , 323.64148, 323.90393, 323.91296,\n", - " 323.9692 , 324.13217, 324.16327, 324.26343], dtype=float32)),\n", - " (array([2080, 4162, 5700, 4841, 6023, 2068, 6400, 4642, 5923, 7746],\n", - " dtype=int32),\n", - " array([326.21127, 326.5274 , 326.69186, 326.7166 , 326.8153 , 326.8331 ,\n", - " 326.8411 , 326.87357, 326.8934 , 326.9687 ], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 121, 268, 100, 49, 120], dtype=int32),\n", - " array([341.18 , 341.27856, 341.28226, 341.34998, 341.58475, 341.86234,\n", - " 342.05392, 342.0674 , 342.07928, 342.2291 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 255, 43, 29, 121, 62, 86, 100], dtype=int32),\n", - " array([240.10457, 240.14316, 240.16333, 240.26564, 240.39934, 240.70921,\n", - " 240.76018, 240.78172, 240.80974, 240.84702], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 173, 255, 268, 86], dtype=int32),\n", - " array([346.95557, 347.2482 , 347.50726, 347.7467 , 347.89117, 348.0756 ,\n", - " 348.09412, 348.3006 , 348.32947, 348.46222], dtype=float32)),\n", - " (array([ 19, 32, 43, 258, 31, 279, 173, 204, 62, 268], dtype=int32),\n", - " array([348.21478, 348.7067 , 348.83075, 348.90067, 348.91003, 349.13455,\n", - " 349.18103, 349.20905, 349.21918, 349.28833], dtype=float32)),\n", - " (array([ 31, 62, 19, 121, 43, 173, 32, 12, 268, 100], dtype=int32),\n", - " array([347.16537, 347.9599 , 347.97238, 348.0496 , 348.1414 , 348.2557 ,\n", - " 348.35638, 348.39505, 348.39636, 348.4529 ], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 279, 62, 121, 173, 8, 100], dtype=int32),\n", - " array([-8.940403, -8.841181, -8.810577, -8.61684 , -8.434095, -8.427022,\n", - " -8.270385, -8.156737, -8.069661, -8.057591], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 62, 121, 268, 86, 105, 173], dtype=int32),\n", - " array([267.6365 , 268.10785, 268.13104, 268.14886, 268.3573 , 268.4447 ,\n", - " 268.73376, 268.7385 , 268.85764, 268.91336], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 173, 121, 268, 29, 12, 62], dtype=int32),\n", - " array([-2.1624694 , -2.1570404 , -1.3937327 , -1.3903593 , -1.2716699 ,\n", - " -1.1796699 , -1.1254017 , -1.0579228 , -0.95602465, -0.94409853],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 268, 62, 305, 120, 166, 121], dtype=int32),\n", - " array([334.43964, 334.55215, 334.59018, 334.9465 , 335.19983, 335.21667,\n", - " 335.31958, 335.32718, 335.46387, 335.58316], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 62, 121, 100, 268, 86, 164], dtype=int32),\n", - " array([340.5543 , 340.61426, 340.882 , 340.99954, 341.10547, 341.32443,\n", - " 341.47726, 341.5122 , 341.54303, 341.63324], dtype=float32)),\n", - " (array([ 43, 19, 31, 32, 62, 121, 86, 100, 173, 268], dtype=int32),\n", - " array([310.93655, 310.98874, 310.99155, 311.00937, 311.27942, 311.43246,\n", - " 311.64612, 311.65787, 311.76938, 311.80804], dtype=float32)),\n", - " (array([ 43, 31, 19, 32, 62, 121, 49, 268, 100, 164], dtype=int32),\n", - " array([307.46826, 307.538 , 307.65506, 307.67123, 307.80823, 308.1331 ,\n", - " 308.25903, 308.2688 , 308.33713, 308.37222], dtype=float32)),\n", - " (array([ 31, 19, 12, 173, 121, 29, 268, 21, 62, 32], dtype=int32),\n", - " array([353.1654 , 353.3736 , 353.45108, 353.79785, 354.06775, 354.1278 ,\n", - " 354.20578, 354.21408, 354.2459 , 354.35483], dtype=float32)),\n", - " (array([ 32, 43, 69, 36, 279, 19, 31, 449, 62, 1380],\n", - " dtype=int32),\n", - " array([239.44693, 239.47939, 239.63757, 239.64905, 239.68205, 239.69392,\n", - " 239.81139, 240.00499, 240.0344 , 240.0877 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 121, 32, 62, 100, 173, 268, 29], dtype=int32),\n", - " array([-5.239605 , -5.0856557, -4.7565556, -4.741194 , -4.5610228,\n", - " -4.3928766, -4.297293 , -4.2819047, -4.2235246, -4.2157755],\n", - " dtype=float32)),\n", - " (array([149, 965, 8, 262, 735, 153, 552, 530, 369, 539], dtype=int32),\n", - " array([306.25558, 306.7805 , 306.9047 , 306.91498, 306.99356, 307.0457 ,\n", - " 307.05005, 307.07913, 307.13007, 307.13458], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 8, 86, 121, 149, 112], dtype=int32),\n", - " array([338.90805, 339.0791 , 339.28116, 339.31406, 339.35803, 339.62582,\n", - " 339.71698, 339.7818 , 339.7959 , 339.80237], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", - " array([310.45065, 310.5636 , 310.81436, 310.88065, 311.05026, 311.1332 ,\n", - " 311.3521 , 311.44955, 311.5422 , 311.5637 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 173, 62, 121, 100, 86, 268], dtype=int32),\n", - " array([-6.415976 , -6.4073477, -5.934216 , -5.760742 , -5.6050553,\n", - " -5.5310054, -5.4855146, -5.3321195, -5.319841 , -5.194134 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 12, 173, 43, 121, 29, 100, 62], dtype=int32),\n", - " array([-1.6162957 , -1.3056909 , -1.038226 , -0.97267723, -0.903343 ,\n", - " -0.83142614, -0.65846634, -0.5760039 , -0.53683317, -0.48959064],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 86, 121, 62, 255, 279, 139], dtype=int32),\n", - " array([292.5342 , 292.58636, 292.59357, 292.71558, 292.8396 , 292.91757,\n", - " 292.97223, 293.16867, 293.18503, 293.18552], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 32, 43, 8, 268, 173, 49], dtype=int32),\n", - " array([-14.722904, -14.659636, -14.137789, -14.063433, -13.997418,\n", - " -13.863566, -13.708372, -13.639454, -13.596024, -13.522898],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 19, 226, 31, 166, 305, 258, 115, 121], dtype=int32),\n", - " array([215.2259 , 215.3823 , 215.40979, 215.55237, 215.72635, 215.85623,\n", - " 215.87796, 215.91803, 215.94086, 215.96031], dtype=float32)),\n", - " (array([ 32, 43, 69, 31, 36, 913, 62, 777, 279, 112], dtype=int32),\n", - " array([281.12018, 281.1225 , 281.21597, 281.40295, 281.4125 , 281.43082,\n", - " 281.4836 , 281.7409 , 281.7557 , 281.78116], dtype=float32)),\n", - " (array([ 306, 19, 32, 36, 43, 2120, 62, 173, 31, 121],\n", - " dtype=int32),\n", - " array([346.39636, 346.45883, 346.53207, 346.6944 , 346.6995 , 346.71216,\n", - " 346.71695, 346.75598, 346.81348, 346.8136 ], dtype=float32)),\n", - " (array([ 19, 43, 32, 279, 188, 31, 62, 255, 173, 258], dtype=int32),\n", - " array([265.20395, 265.38385, 265.41226, 265.945 , 266.07922, 266.08093,\n", - " 266.10687, 266.1931 , 266.21286, 266.23383], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 173, 262, 268, 8, 100], dtype=int32),\n", - " array([295.98895, 296.28027, 296.71243, 296.80356, 296.83167, 296.84036,\n", - " 297.1351 , 297.1437 , 297.14795, 297.23462], dtype=float32)),\n", - " (array([ 31, 19, 62, 32, 173, 121, 43, 61, 120, 268], dtype=int32),\n", - " array([315.45764, 315.91943, 316.05283, 316.27142, 316.35052, 316.36044,\n", - " 316.53232, 316.61996, 316.6919 , 316.80225], dtype=float32)),\n", - " (array([ 19, 31, 12, 43, 173, 121, 32, 268, 62, 29], dtype=int32),\n", - " array([267.67084, 267.72833, 267.73022, 268.4498 , 268.48254, 268.5591 ,\n", - " 268.56265, 268.7254 , 268.77234, 268.90247], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 121, 268, 130, 105, 358, 42], dtype=int32),\n", - " array([-13.564224, -13.329862, -13.319795, -13.118033, -13.063758,\n", - " -12.908173, -12.690205, -12.67433 , -12.569277, -12.548384],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 173, 43, 62, 636, 100, 268, 32, 29], dtype=int32),\n", - " array([-4.9985914, -4.6330805, -4.3344355, -4.0384917, -3.9929457,\n", - " -3.8123507, -3.7999644, -3.7671752, -3.7665796, -3.7560258],\n", - " dtype=float32)),\n", - " (array([ 1512, 12006, 3998, 369, 5596, 262, 2679, 8, 19,\n", - " 6945], dtype=int32),\n", - " array([53.281876, 53.4551 , 53.555305, 53.876358, 54.024883, 54.115963,\n", - " 54.156887, 54.174454, 54.178905, 54.229485], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 262, 8, 149, 62, 552, 121], dtype=int32),\n", - " array([-15.695936, -15.562714, -15.478909, -15.401955, -15.381751,\n", - " -15.342807, -15.107531, -15.05071 , -14.961232, -14.93233 ],\n", - " dtype=float32)),\n", - " (array([ 32, 43, 31, 62, 19, 121, 49, 305, 164, 268], dtype=int32),\n", - " array([310.4991 , 310.56622, 310.6888 , 310.695 , 310.76025, 310.81952,\n", - " 311.04785, 311.05246, 311.27228, 311.29605], dtype=float32)),\n", - " (array([ 19, 31, 121, 43, 32, 173, 62, 105, 29, 268], dtype=int32),\n", - " array([-8.8336735, -8.72695 , -8.494268 , -8.293601 , -8.156838 ,\n", - " -7.978189 , -7.9321666, -7.866111 , -7.846372 , -7.8271933],\n", - " dtype=float32)),\n", - " (array([ 69, 32, 43, 19, 36, 528, 279, 204, 418, 449], dtype=int32),\n", - " array([288.77097, 288.8702 , 288.8752 , 288.98 , 289.02167, 289.0926 ,\n", - " 289.14014, 289.1926 , 289.20764, 289.21567], dtype=float32)),\n", - " (array([ 19, 31, 32, 29, 173, 121, 43, 268, 105, 62], dtype=int32),\n", - " array([300.84222, 301.45874, 301.62894, 301.77847, 301.96283, 302.00342,\n", - " 302.04025, 302.2506 , 302.2876 , 302.30295], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 62, 43, 103, 173, 120, 268], dtype=int32),\n", - " array([349.5395 , 349.84454, 349.94327, 350.18048, 350.27292, 350.41403,\n", - " 350.4802 , 350.57605, 350.5813 , 350.61682], dtype=float32)),\n", - " (array([ 19, 31, 29, 32, 121, 173, 43, 62, 100, 24], dtype=int32),\n", - " array([315.44714, 315.45224, 315.93335, 316.0352 , 316.07327, 316.27966,\n", - " 316.33044, 316.3346 , 316.37753, 316.38028], dtype=float32)),\n", - " (array([ 19, 31, 43, 358, 32, 173, 636, 62, 268, 121], dtype=int32),\n", - " array([-9.963589 , -9.809285 , -9.387534 , -9.205482 , -9.058536 ,\n", - " -9.019632 , -8.964258 , -8.934378 , -8.9212475, -8.746387 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 358, 121, 173, 43, 32, 62, 268, 100], dtype=int32),\n", - " array([-6.7162285, -6.525914 , -6.031356 , -6.007014 , -5.9763145,\n", - " -5.9590397, -5.9580097, -5.8188295, -5.816988 , -5.5363703],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 29, 43, 121, 268, 24, 173, 100], dtype=int32),\n", - " array([305.31534, 305.8434 , 306.06055, 306.10666, 306.2705 , 306.33456,\n", - " 306.43344, 306.50674, 306.56894, 306.5812 ], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 62, 258, 279, 255, 358, 173], dtype=int32),\n", - " array([-16.45056 , -16.081543, -15.938074, -15.785679, -15.57937 ,\n", - " -15.488791, -15.425339, -15.223385, -15.201254, -15.191471],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 43, 120, 19, 255, 268, 29, 121, 86], dtype=int32),\n", - " array([341.2839 , 341.6755 , 341.88043, 341.95566, 341.961 , 342.04584,\n", - " 342.0962 , 342.16168, 342.1698 , 342.1846 ], dtype=float32)),\n", - " (array([ 31, 19, 173, 12, 121, 32, 268, 29, 43, 358], dtype=int32),\n", - " array([-8.667049 , -8.382691 , -7.6888227, -7.6644435, -7.608928 ,\n", - " -7.4436045, -7.3922806, -7.3806834, -7.347027 , -7.2549744],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 268, 173, 358, 49], dtype=int32),\n", - " array([-11.05284 , -10.957485 , -10.892531 , -10.732716 , -10.722958 ,\n", - " -10.552846 , -10.500628 , -10.2660055, -10.130894 , -10.128552 ],\n", - " dtype=float32)),\n", - " (array([ 19, 43, 62, 173, 32, 31, 279, 121, 69, 36], dtype=int32),\n", - " array([314.40063, 314.4845 , 314.64893, 314.79523, 314.82343, 314.85294,\n", - " 315.00952, 315.0771 , 315.07925, 315.1117 ], dtype=float32)),\n", - " (array([ 43, 31, 19, 32, 62, 120, 268, 121, 487, 42], dtype=int32),\n", - " array([307.71738, 307.79037, 308.00027, 308.01938, 308.53983, 308.54434,\n", - " 308.62585, 308.77234, 308.77542, 308.815 ], dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 29, 121, 268, 120, 62, 255], dtype=int32),\n", - " array([346.16766, 346.5481 , 346.63773, 346.8988 , 347.13367, 347.1529 ,\n", - " 347.18713, 347.18732, 347.254 , 347.30856], dtype=float32)),\n", - " (array([ 19, 43, 62, 32, 173, 121, 31, 25, 36, 49], dtype=int32),\n", - " array([207.74565, 208.02919, 208.03604, 208.12025, 208.31384, 208.37885,\n", - " 208.39108, 208.52342, 208.58371, 208.63039], dtype=float32)),\n", - " (array([ 19, 43, 121, 31, 32, 173, 62, 8, 100, 268], dtype=int32),\n", - " array([-11.508071 , -11.152291 , -10.942703 , -10.914831 , -10.911328 ,\n", - " -10.846243 , -10.8276005, -10.660121 , -10.411308 , -10.386348 ],\n", - " dtype=float32)),\n", - " (array([ 262, 718, 2412, 369, 0, 153, 31, 965, 489, 8],\n", - " dtype=int32),\n", - " array([-5.9994774, -5.7627854, -5.5477343, -5.507009 , -5.49233 ,\n", - " -5.4497705, -5.379436 , -5.3342195, -5.2943263, -5.293456 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 62, 32, 173, 121, 12, 86, 268], dtype=int32),\n", - " array([279.0891 , 279.32962, 279.45917, 279.70963, 279.74292, 279.87704,\n", - " 279.97516, 280.049 , 280.11642, 280.20453], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 268, 121, 100, 120, 86], dtype=int32),\n", - " array([306.82788, 306.9972 , 307.03284, 307.22308, 307.33658, 307.4994 ,\n", - " 307.63345, 307.72754, 307.72937, 307.7416 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 268, 29, 173, 86], dtype=int32),\n", - " array([-11.914367 , -11.8615675, -11.374211 , -11.274739 , -11.184766 ,\n", - " -11.099998 , -10.919152 , -10.8941555, -10.873794 , -10.852995 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 43, 62, 268, 164, 105, 29], dtype=int32),\n", - " array([297.84326, 297.99957, 298.17078, 298.4394 , 298.48465, 298.51093,\n", - " 298.60464, 298.76886, 298.82486, 298.83643], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 121, 268, 86, 29, 255], dtype=int32),\n", - " array([288.84937, 289.09406, 289.10565, 289.36545, 289.47668, 289.67447,\n", - " 289.72296, 289.81696, 289.8755 , 289.88028], dtype=float32)),\n", - " (array([ 43, 31, 62, 19, 32, 121, 86, 49, 100, 255], dtype=int32),\n", - " array([247.3394 , 247.38557, 247.49289, 247.5255 , 247.60347, 247.9019 ,\n", - " 247.95514, 248.04012, 248.14587, 248.26149], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 32, 100, 43, 268, 120, 49], dtype=int32),\n", - " array([343.86398, 344.0433 , 344.08322, 344.1318 , 344.47165, 344.60645,\n", - " 344.6228 , 344.65543, 344.76862, 344.81354], dtype=float32)),\n", - " (array([ 32, 31, 19, 43, 62, 268, 121, 29, 305, 120], dtype=int32),\n", - " array([264.50845, 264.57135, 264.65674, 264.78946, 265.1672 , 265.2469 ,\n", - " 265.29602, 265.3416 , 265.39587, 265.46082], dtype=float32)),\n", - " (array([ 32, 31, 19, 255, 43, 121, 120, 29, 86, 100], dtype=int32),\n", - " array([292.5461 , 292.7073 , 292.79117, 292.93466, 293.1772 , 293.21738,\n", - " 293.22174, 293.2516 , 293.29108, 293.3703 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 173, 268, 12, 43, 29, 62], dtype=int32),\n", - " array([348.73694, 348.74698, 349.4377 , 349.66144, 349.7174 , 349.7496 ,\n", - " 349.7988 , 349.833 , 350.0069 , 350.00732], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 62, 268, 100, 173, 204], dtype=int32),\n", - " array([313.35837, 313.49054, 313.5306 , 313.90445, 313.90964, 313.94467,\n", - " 314.20184, 314.27777, 314.3091 , 314.4993 ], dtype=float32)),\n", - " (array([ 43, 2314, 86, 62, 19, 418, 32, 36, 31, 69],\n", - " dtype=int32),\n", - " array([-9.6120825, -9.346699 , -9.207026 , -9.160904 , -9.124111 ,\n", - " -9.095689 , -9.060061 , -9.052945 , -8.98671 , -8.982131 ],\n", - " dtype=float32)),\n", - " (array([ 19, 43, 32, 449, 69, 31, 166, 1277, 350, 610],\n", - " dtype=int32),\n", - " array([287.36234, 287.50375, 287.6907 , 287.71933, 287.79178, 287.8197 ,\n", - " 287.82077, 287.84833, 287.87378, 288.02737], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 86, 255, 268], dtype=int32),\n", - " array([345.5526 , 345.66226, 345.68192, 345.6944 , 346.17093, 346.41824,\n", - " 346.456 , 346.48203, 346.4914 , 346.54904], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 255, 62, 29, 268, 105, 121], dtype=int32),\n", - " array([-14.0868225, -13.886298 , -13.681151 , -13.650404 , -13.164167 ,\n", - " -13.055755 , -13.023791 , -13.013362 , -12.892268 , -12.864099 ],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 121, 268, 305, 49, 100], dtype=int32),\n", - " array([296.5766 , 296.64285, 296.73782, 296.80136, 297.12164, 297.2681 ,\n", - " 297.4555 , 297.49884, 297.5031 , 297.5338 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 29, 105, 100, 166], dtype=int32),\n", - " array([344.40976, 344.41183, 344.6868 , 344.71686, 345.07248, 345.14047,\n", - " 345.15277, 345.26352, 345.33438, 345.34442], dtype=float32)),\n", - " (array([ 31, 19, 12, 32, 121, 21, 62, 173, 268, 120], dtype=int32),\n", - " array([346.2154 , 346.4909 , 346.94992, 347.05362, 347.08423, 347.12668,\n", - " 347.15186, 347.24332, 347.4705 , 347.55835], dtype=float32)),\n", - " (array([ 19, 262, 31, 149, 43, 153, 8, 325, 32, 121], dtype=int32),\n", - " array([-6.206942 , -6.0745444, -5.9809794, -5.6786165, -5.653342 ,\n", - " -5.616562 , -5.5820312, -5.5511646, -5.5446153, -5.5070167],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 62, 121, 8, 120, 49, 268], dtype=int32),\n", - " array([306.33844, 306.62323, 306.89288, 307.00055, 307.03586, 307.13416,\n", - " 307.33762, 307.49387, 307.5142 , 307.5221 ], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 268, 255, 204, 121, 258], dtype=int32),\n", - " array([294.4024 , 294.704 , 294.76086, 295.0443 , 295.2479 , 295.42633,\n", - " 295.5138 , 295.52826, 295.5789 , 295.59912], dtype=float32)),\n", - " (array([ 31, 8, 262, 19, 32, 43, 121, 62, 450, 3146],\n", - " dtype=int32),\n", - " array([-3.9734848, -3.8687088, -3.7507374, -3.7470279, -3.647826 ,\n", - " -3.4301252, -3.4199665, -3.374422 , -3.3716147, -3.340707 ],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 31, 62, 19, 149, 268, 120, 49, 166], dtype=int32),\n", - " array([284.24326, 284.27377, 284.3508 , 284.66156, 284.842 , 284.90616,\n", - " 285.1522 , 285.20038, 285.21167, 285.22134], dtype=float32)),\n", - " (array([ 19, 31, 255, 43, 86, 32, 268, 29, 62, 166], dtype=int32),\n", - " array([247.25244, 247.31169, 247.36824, 247.41881, 247.65016, 247.68929,\n", - " 248.19554, 248.19984, 248.20874, 248.33179], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 166, 120, 268, 173], dtype=int32),\n", - " array([-14.870354, -14.839024, -14.615126, -14.589908, -14.255788,\n", - " -14.196692, -13.983387, -13.971422, -13.958493, -13.887913],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 121, 100, 86, 173, 268], dtype=int32),\n", - " array([343.3399 , 343.40366, 343.44424, 343.4456 , 343.6473 , 343.905 ,\n", - " 344.11575, 344.17105, 344.2046 , 344.24673], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 206, 173, 268, 86], dtype=int32),\n", - " array([290.16843, 290.18997, 290.38217, 290.6731 , 290.9078 , 291.01703,\n", - " 291.07397, 291.1241 , 291.1473 , 291.2019 ], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 268, 121, 305, 173, 29], dtype=int32),\n", - " array([257.74973, 257.931 , 258.04843, 258.28745, 258.60605, 258.7642 ,\n", - " 258.84933, 258.8708 , 258.9978 , 259.0058 ], dtype=float32)),\n", - " (array([ 43, 31, 19, 32, 92, 121, 304, 62, 105, 164], dtype=int32),\n", - " array([301.8668 , 302.12326, 302.34232, 302.45627, 302.7205 , 302.79388,\n", - " 302.89005, 302.93973, 302.9696 , 303.03345], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 305, 206, 100, 121, 112], dtype=int32),\n", - " array([341.35913, 341.43484, 341.79684, 342.1412 , 342.324 , 342.33612,\n", - " 342.50934, 342.6344 , 342.6764 , 342.67975], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 120, 100], dtype=int32),\n", - " array([289.71463, 289.79852, 290.11044, 290.22134, 290.40036, 290.4122 ,\n", - " 290.59308, 290.77255, 290.86734, 290.8776 ], dtype=float32)),\n", - " (array([ 31, 43, 32, 86, 62, 19, 121, 305, 255, 120], dtype=int32),\n", - " array([231.00754, 231.31044, 231.41779, 231.63742, 231.69531, 231.73466,\n", - " 231.99161, 232.06673, 232.09877, 232.11288], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 86, 62, 121, 255, 100, 29], dtype=int32),\n", - " array([235.1547 , 235.54523, 235.55261, 235.61209, 235.77467, 235.79161,\n", - " 235.89807, 235.9805 , 236.07578, 236.09122], dtype=float32)),\n", - " (array([1959, 1120, 2977, 19, 39, 884, 1940, 2653, 1518, 636],\n", - " dtype=int32),\n", - " array([328.74088, 328.81854, 328.95816, 329.13812, 329.15073, 329.20258,\n", - " 329.21838, 329.36902, 329.40176, 329.4096 ], dtype=float32)),\n", - " (array([ 19, 31, 43, 173, 32, 86, 29, 62, 12, 255], dtype=int32),\n", - " array([268.86743, 269.46136, 269.56302, 269.64392, 269.65433, 269.66522,\n", - " 269.84482, 269.95926, 269.96872, 269.9839 ], dtype=float32)),\n", - " (array([ 19, 279, 43, 36, 69, 32, 31, 62, 118, 370], dtype=int32),\n", - " array([343.30206, 343.32822, 343.35498, 343.41068, 343.4234 , 343.4966 ,\n", - " 343.5781 , 343.58517, 343.60013, 343.62402], dtype=float32)),\n", - " (array([ 19, 31, 43, 121, 32, 268, 62, 173, 164, 105], dtype=int32),\n", - " array([-19.262432, -18.970963, -18.968145, -18.747179, -18.50581 ,\n", - " -18.32977 , -18.295729, -18.238485, -18.178022, -18.097466],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 32, 305, 848, 206, 188, 279, 1088, 374],\n", - " dtype=int32),\n", - " array([319.36642, 319.56693, 319.626 , 319.86072, 319.93347, 320.13858,\n", - " 320.19757, 320.20312, 320.2503 , 320.3026 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 43, 255, 62, 86, 173, 120], dtype=int32),\n", - " array([297.0155 , 297.13086, 297.68158, 297.7243 , 297.81842, 297.835 ,\n", - " 297.92056, 298.03732, 298.0758 , 298.14822], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 62, 120, 121, 358, 268, 103], dtype=int32),\n", - " array([276.18808, 276.88028, 277.00955, 277.06067, 277.2256 , 277.3217 ,\n", - " 277.4061 , 277.4596 , 277.4885 , 277.51587], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 43, 173, 62, 12, 268, 100], dtype=int32),\n", - " array([350.00446, 350.17502, 350.43887, 350.6564 , 350.69977, 350.84567,\n", - " 350.88907, 351.07727, 351.1081 , 351.1229 ], dtype=float32)),\n", - " (array([ 345, 4738, 4326, 1277, 36, 32, 610, 240, 13, 1638],\n", - " dtype=int32),\n", - " array([307.03915, 308.22446, 308.28445, 308.74045, 308.90253, 308.90698,\n", - " 308.91098, 308.99344, 309.04437, 309.0559 ], dtype=float32)),\n", - " (array([ 43, 19, 32, 62, 86, 31, 112, 374, 173, 487], dtype=int32),\n", - " array([311.68478, 311.80957, 311.8102 , 312.00293, 312.14935, 312.26733,\n", - " 312.44666, 312.60242, 312.61804, 312.6254 ], dtype=float32)),\n", - " (array([ 43, 31, 32, 19, 62, 268, 358, 121, 173, 166], dtype=int32),\n", - " array([343.7238 , 343.8537 , 344.02582, 344.19736, 344.31094, 344.6312 ,\n", - " 344.6665 , 344.79254, 344.87335, 344.90646], dtype=float32)),\n", - " (array([ 32, 31, 62, 43, 19, 121, 441, 112, 49, 120], dtype=int32),\n", - " array([292.95178, 293.0729 , 293.26694, 293.28125, 293.3645 , 293.50885,\n", - " 293.6507 , 293.7795 , 293.78775, 293.81918], dtype=float32)),\n", - " (array([ 31, 12, 21, 29, 19, 24, 121, 32, 268, 105], dtype=int32),\n", - " array([355.0476 , 355.21933, 355.3185 , 355.55774, 355.6075 , 355.647 ,\n", - " 355.83905, 355.9482 , 356.10522, 356.13074], dtype=float32)),\n", - " (array([ 31, 19, 121, 12, 62, 21, 32, 100, 11, 61], dtype=int32),\n", - " array([304.3875 , 305.11523, 305.17114, 305.4265 , 305.53488, 305.5818 ,\n", - " 305.5941 , 305.75012, 305.76743, 305.82275], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 305, 258, 121, 204, 100], dtype=int32),\n", - " array([284.7862 , 285.05832, 285.2212 , 285.24185, 285.4968 , 285.77765,\n", - " 285.82733, 285.85187, 285.88977, 285.95816], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 105, 29], dtype=int32),\n", - " array([265.61038, 265.70847, 266.01672, 266.18445, 266.30972, 266.35138,\n", - " 266.5342 , 266.69577, 266.7992 , 266.80106], dtype=float32)),\n", - " (array([ 43, 19, 86, 31, 32, 62, 25, 112, 164, 121], dtype=int32),\n", - " array([310.4266 , 310.5223 , 310.55197, 310.6251 , 310.63422, 310.7015 ,\n", - " 311.0051 , 311.0098 , 311.0597 , 311.0854 ], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 166, 121, 206, 305, 487], dtype=int32),\n", - " array([341.55927, 341.70657, 341.72754, 341.93817, 342.15762, 342.35983,\n", - " 342.42426, 342.43643, 342.45593, 342.47552], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 62, 268, 43, 120, 103, 105], dtype=int32),\n", - " array([310.4918 , 310.93274, 311.11896, 311.25186, 311.39307, 311.44058,\n", - " 311.49457, 311.71384, 311.7388 , 311.74344], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 206, 8, 279, 305, 149], dtype=int32),\n", - " array([336.622 , 336.7054 , 336.93042, 337.31628, 337.3898 , 337.5266 ,\n", - " 337.5593 , 337.608 , 337.6443 , 337.6892 ], dtype=float32)),\n", - " (array([ 32, 19, 305, 43, 528, 531, 3563, 31, 112, 579],\n", - " dtype=int32),\n", - " array([347.42548, 347.8113 , 347.92218, 347.9663 , 348.31726, 348.32343,\n", - " 348.39618, 348.4682 , 348.47116, 348.5228 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 268, 103, 62, 43, 164, 105], dtype=int32),\n", - " array([291.31287, 291.79883, 291.94574, 292.1013 , 292.16028, 292.21893,\n", - " 292.33588, 292.34268, 292.38098, 292.5352 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-5.0016017, -4.986882 , -4.451205 , -4.391886 , -4.387713 ,\n", - " -4.2009974, -4.1944404, -4.0058727, -3.9769433, -3.9448647],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 305, 121, 62, 29, 268, 49], dtype=int32),\n", - " array([287.3281 , 287.47498, 287.52948, 287.73807, 288.01025, 288.0994 ,\n", - " 288.17215, 288.20428, 288.21072, 288.31906], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", - " array([-5.0417438, -5.0349703, -4.490544 , -4.437183 , -4.428494 ,\n", - " -4.243727 , -4.2417865, -4.0510836, -4.023711 , -3.9946892],\n", - " dtype=float32)),\n", - " (array([ 32, 43, 305, 62, 49, 36, 528, 279, 19, 31], dtype=int32),\n", - " array([307.3345 , 307.4294 , 307.79126, 308.07477, 308.2332 , 308.24457,\n", - " 308.25793, 308.27167, 308.30646, 308.31348], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 62, 121, 86, 100, 173, 49], dtype=int32),\n", - " array([230.55882, 230.59306, 230.67099, 230.67737, 230.7757 , 230.97089,\n", - " 231.03192, 231.1943 , 231.31966, 231.43828], dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 86, 121, 255, 32, 100, 173], dtype=int32),\n", - " array([-12.179075, -12.055015, -11.658845, -11.474636, -11.45198 ,\n", - " -11.449149, -11.386686, -11.344017, -11.198047, -11.075245],\n", - " dtype=float32)),\n", - " (array([ 19, 43, 31, 62, 32, 86, 121, 204, 173, 100], dtype=int32),\n", - " array([-10.164619, -9.925463, -9.882594, -9.749147, -9.718987,\n", - " -9.615596, -9.499333, -9.329171, -9.290731, -9.212201],\n", - " dtype=float32)),\n", - " (array([ 19, 62, 32, 43, 31, 121, 173, 36, 100, 279], dtype=int32),\n", - " array([310.69125, 310.775 , 310.88123, 311.02145, 311.0617 , 311.11597,\n", - " 311.16595, 311.33707, 311.51437, 311.59106], dtype=float32)),\n", - " (array([ 31, 43, 130, 915, 19, 164, 32, 62, 441, 691], dtype=int32),\n", - " array([338.53754, 338.74622, 339.2825 , 339.3099 , 339.33862, 339.44678,\n", - " 339.45474, 339.46786, 339.50308, 339.64893], dtype=float32)),\n", - " (array([ 32, 43, 528, 305, 1277, 279, 1587, 69, 188, 345],\n", - " dtype=int32),\n", - " array([240.72806, 240.74092, 240.8347 , 240.9205 , 241.01338, 241.2151 ,\n", - " 241.29453, 241.30576, 241.32898, 241.34691], dtype=float32)),\n", - " (array([ 43, 31, 19, 8, 32, 149, 325, 62, 450, 105], dtype=int32),\n", - " array([315.75876, 315.77573, 315.8576 , 315.9668 , 316.0495 , 316.26123,\n", - " 316.34238, 316.3648 , 316.39322, 316.44662], dtype=float32)),\n", - " (array([ 19, 31, 21, 62, 43, 121, 12, 173, 32, 29], dtype=int32),\n", - " array([-13.370353 , -13.199175 , -12.9535885, -12.830408 , -12.722335 ,\n", - " -12.695543 , -12.659686 , -12.57739 , -12.562401 , -12.5078745],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 62, 173, 268, 43, 100, 255], dtype=int32),\n", - " array([290.3794 , 290.47238, 291.04694, 291.05835, 291.1413 , 291.37558,\n", - " 291.43317, 291.44394, 291.54236, 291.61172], dtype=float32)),\n", - " (array([149, 262, 552, 8, 31, 0, 539, 965, 369, 835], dtype=int32),\n", - " array([302.03113, 302.06293, 302.30316, 302.3143 , 302.3187 , 302.45093,\n", - " 302.47653, 302.59784, 302.69586, 302.71732], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", - " array([343.34982, 343.40662, 343.44388, 343.44897, 343.65295, 343.90765,\n", - " 344.1127 , 344.1763 , 344.2082 , 344.2455 ], dtype=float32)),\n", - " (array([ 43, 350, 36, 279, 19, 32, 69, 1277, 258, 62],\n", - " dtype=int32),\n", - " array([334.31732, 334.38333, 334.4554 , 334.63092, 334.68903, 334.6914 ,\n", - " 334.71286, 334.75555, 334.7793 , 334.82663], dtype=float32)),\n", - " (array([ 32, 31, 62, 43, 19, 268, 120, 121, 305, 255], dtype=int32),\n", - " array([297.75244, 297.94473, 298.43997, 298.54663, 298.55225, 298.6357 ,\n", - " 298.85092, 298.8621 , 298.9957 , 299.0392 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 121, 173, 62, 32, 268, 103, 12], dtype=int32),\n", - " array([345.12595, 345.48444, 345.93417, 346.0079 , 346.2208 , 346.26715,\n", - " 346.30457, 346.32483, 346.3851 , 346.47192], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 69, 279, 16, 36, 815, 112], dtype=int32),\n", - " array([312.86844, 312.91083, 313.10187, 313.1675 , 313.25974, 313.26758,\n", - " 313.32526, 313.36523, 313.45132, 313.4681 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", - " array([-5.0946803, -5.077351 , -4.5356355, -4.4874067, -4.4735856,\n", - " -4.2948647, -4.290651 , -4.106251 , -4.066084 , -4.03213 ],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 121, 173, 86, 8, 100], dtype=int32),\n", - " array([345.26007, 345.3555 , 345.5771 , 345.5897 , 345.8045 , 346.0711 ,\n", - " 346.08777, 346.2304 , 346.2648 , 346.27704], dtype=float32)),\n", - " (array([ 31, 62, 19, 121, 43, 32, 164, 255, 86, 49], dtype=int32),\n", - " array([214.0177 , 214.49263, 214.61058, 214.66464, 214.78662, 214.82312,\n", - " 214.84425, 214.94974, 214.9615 , 215.01779], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 305, 62, 121, 36, 100, 149], dtype=int32),\n", - " array([312.1478 , 312.49527, 312.61185, 312.83023, 312.99197, 313.0479 ,\n", - " 313.09927, 313.27527, 313.28778, 313.32355], dtype=float32)),\n", - " (array([ 31, 32, 43, 121, 62, 120, 8, 19, 103, 86], dtype=int32),\n", - " array([-17.195608, -16.587257, -16.459358, -16.368649, -16.358686,\n", - " -16.110693, -16.062782, -16.03438 , -15.907016, -15.808912],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 29, 268, 305, 173, 121, 62], dtype=int32),\n", - " array([247.70435, 247.9233 , 248.18109, 248.31598, 248.67165, 248.70995,\n", - " 248.82982, 248.87949, 248.91016, 249.00935], dtype=float32)),\n", - " (array([ 43, 36, 32, 69, 31, 118, 19, 62, 166, 279], dtype=int32),\n", - " array([341.3737 , 341.67444, 341.76135, 341.8588 , 341.8671 , 341.87106,\n", - " 341.9266 , 341.9679 , 342.0215 , 342.11133], dtype=float32)),\n", - " (array([ 31, 121, 19, 12, 103, 21, 61, 62, 29, 32], dtype=int32),\n", - " array([-13.424848, -12.865175, -12.774822, -12.463811, -12.357937,\n", - " -12.319481, -12.24777 , -12.225303, -12.208757, -12.18961 ],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 374, 305, 112, 31, 848, 454], dtype=int32),\n", - " array([338.48114, 338.79025, 338.81116, 339.09747, 339.3511 , 339.36023,\n", - " 339.36685, 339.40686, 339.41937, 339.47882], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 121, 100, 268, 49, 120], dtype=int32),\n", - " array([341.21753, 341.31866, 341.32355, 341.38373, 341.62173, 341.89523,\n", - " 342.1004 , 342.1031 , 342.12027, 342.2702 ], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 62, 121, 86, 100, 268, 173], dtype=int32),\n", - " array([263.7833 , 263.81995, 263.83786, 263.96176, 264.21823, 264.28357,\n", - " 264.37497, 264.5267 , 264.64972, 264.67917], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 120, 100], dtype=int32),\n", - " array([289.7196 , 289.80026, 290.0958 , 290.212 , 290.42407, 290.4241 ,\n", - " 290.59174, 290.7809 , 290.86972, 290.88995], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 279, 166, 204, 62, 69, 305], dtype=int32),\n", - " array([-22.06019 , -22.022694, -21.977915, -21.779879, -21.61482 ,\n", - " -21.50783 , -21.48641 , -21.42692 , -21.385483, -21.373497],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-5.037512 , -5.0237136, -4.494074 , -4.43174 , -4.4272833,\n", - " -4.244821 , -4.243558 , -4.0467653, -4.016542 , -3.9909475],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 62, 173, 32, 43, 121, 358, 268, 100], dtype=int32),\n", - " array([352.74524, 352.93347, 353.07114, 353.1705 , 353.20566, 353.25763,\n", - " 353.50116, 353.56415, 353.62692, 353.69406], dtype=float32)),\n", - " (array([ 19, 43, 32, 16, 305, 31, 188, 554, 186, 111], dtype=int32),\n", - " array([308.56146, 308.66006, 308.78403, 309.10117, 309.10822, 309.15823,\n", - " 309.20117, 309.23468, 309.24683, 309.33664], dtype=float32)),\n", - " (array([ 32, 43, 31, 62, 19, 166, 305, 120, 86, 49], dtype=int32),\n", - " array([334.5306 , 334.63214, 334.7412 , 335.01828, 335.21945, 335.2589 ,\n", - " 335.35727, 335.55618, 335.57034, 335.58856], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 43, 32, 12, 173, 268, 61], dtype=int32),\n", - " array([308.09946, 308.43088, 308.60757, 308.73572, 308.82132, 308.8971 ,\n", - " 308.8976 , 308.92874, 309.0461 , 309.1812 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 173, 268, 100, 29], dtype=int32),\n", - " array([311.39374, 311.48026, 311.5796 , 311.76224, 311.87125, 311.96405,\n", - " 312.14227, 312.20364, 312.26447, 312.29123], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 268, 121, 173, 100, 29], dtype=int32),\n", - " array([313.57062, 313.67438, 313.90894, 314.19592, 314.22522, 314.35294,\n", - " 314.4183 , 314.5291 , 314.539 , 314.54422], dtype=float32)),\n", - " (array([ 31, 19, 32, 268, 121, 43, 29, 173, 120, 62], dtype=int32),\n", - " array([347.01147, 347.23508, 347.40143, 347.50565, 347.71518, 347.76782,\n", - " 347.84988, 347.86267, 347.96655, 348.03088], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 121, 268, 173, 62, 164, 105], dtype=int32),\n", - " array([-20.464182, -20.362396, -20.002039, -19.757504, -19.63843 ,\n", - " -19.617554, -19.582748, -19.577436, -19.283743, -19.255453],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 62, 19, 31, 121, 100, 86, 49, 173], dtype=int32),\n", - " array([310.09262, 310.1131 , 310.21216, 310.21732, 310.27548, 310.60822,\n", - " 310.78345, 310.83847, 310.845 , 310.86917], dtype=float32)),\n", - " (array([ 31, 19, 121, 43, 173, 32, 62, 12, 268, 100], dtype=int32),\n", - " array([-10.95709 , -10.923313 , -10.351267 , -10.3023815, -10.301873 ,\n", - " -10.272888 , -10.232136 , -10.219132 , -9.9499445, -9.9107 ],\n", - " dtype=float32)),\n", - " (array([ 32, 43, 31, 62, 186, 121, 19, 305, 100, 29], dtype=int32),\n", - " array([278.15305, 278.37817, 278.50995, 278.65338, 278.7143 , 278.7305 ,\n", - " 278.82672, 278.8463 , 279.0097 , 279.03696], dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 279, 31, 528, 49, 188, 164], dtype=int32),\n", - " array([302.68402, 302.99008, 303.10764, 303.3145 , 303.34198, 303.36554,\n", - " 303.37967, 303.43552, 303.50217, 303.50488], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 100, 120, 268, 255], dtype=int32),\n", - " array([-13.530379, -12.864474, -12.844051, -12.832049, -12.690503,\n", - " -12.602685, -12.265813, -12.239744, -12.170782, -12.157627],\n", - " dtype=float32)),\n", - " (array([ 589, 31, 358, 878, 19, 32, 1287, 176, 62, 2964],\n", - " dtype=int32),\n", - " array([338.58856, 338.68777, 338.76834, 339.07806, 339.16458, 339.22958,\n", - " 339.2411 , 339.2634 , 339.28787, 339.352 ], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 268, 62, 255, 173, 42, 86], dtype=int32),\n", - " array([-11.178962 , -11.069656 , -10.9206915, -10.777212 , -10.241608 ,\n", - " -10.224714 , -10.209121 , -10.186697 , -10.110338 , -10.079626 ],\n", - " dtype=float32)),\n", - " (array([2181, 3590, 665, 2676, 2113, 5600, 3738, 2953, 6563, 956],\n", - " dtype=int32),\n", - " array([300.00397, 300.65714, 301.12607, 301.20392, 301.6251 , 302.2963 ,\n", - " 302.3603 , 302.61365, 302.6597 , 302.7265 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([342.96945, 343.11252, 343.29376, 343.37585, 343.49805, 343.6827 ,\n", - " 343.8803 , 343.98334, 344.08954, 344.09555], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 86, 100, 173, 268], dtype=int32),\n", - " array([51.645775, 51.728035, 51.95993 , 52.10309 , 52.202866, 52.22716 ,\n", - " 52.494923, 52.57747 , 52.603672, 52.645454], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 358, 62, 268, 176, 173, 121], dtype=int32),\n", - " array([338.46393, 338.64026, 338.64172, 338.80722, 338.9378 , 339.0534 ,\n", - " 339.28226, 339.37003, 339.46683, 339.49136], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 49, 268, 120, 392], dtype=int32),\n", - " array([302.61954, 302.6806 , 302.8154 , 303.0094 , 303.24045, 303.25885,\n", - " 303.46957, 303.4826 , 303.53622, 303.6376 ], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 305, 166, 204, 528, 121, 62], dtype=int32),\n", - " array([285.48547, 285.6108 , 285.91196, 285.9556 , 286.10684, 286.15298,\n", - " 286.1807 , 286.33746, 286.36145, 286.42834], dtype=float32)),\n", - " (array([2314, 19, 43, 32, 36, 62, 31, 69, 504, 449],\n", - " dtype=int32),\n", - " array([283.41412, 283.97858, 284.06885, 284.24115, 284.28284, 284.4292 ,\n", - " 284.52133, 284.52197, 284.53964, 284.6327 ], dtype=float32)),\n", - " (array([ 31, 19, 173, 62, 121, 32, 43, 12, 1842, 100],\n", - " dtype=int32),\n", - " array([360.42856, 360.9714 , 361.1089 , 361.1391 , 361.17966, 361.3434 ,\n", - " 361.3988 , 361.47015, 361.48196, 361.66397], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 29, 100, 62, 121, 268, 255], dtype=int32),\n", - " array([329.7449 , 330.0215 , 330.18597, 330.36047, 330.46606, 330.5241 ,\n", - " 330.53033, 330.58383, 330.8554 , 330.89307], dtype=float32)),\n", - " (array([ 31, 19, 43, 173, 32, 121, 86, 12, 62, 279], dtype=int32),\n", - " array([318.83676, 318.8765 , 319.27216, 319.48248, 319.62842, 319.63022,\n", - " 319.64417, 319.69492, 319.82974, 320.00836], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 121, 268, 173, 100, 12], dtype=int32),\n", - " array([344.3132 , 344.3722 , 344.6025 , 344.8976 , 344.91922, 345.0265 ,\n", - " 345.22122, 345.29587, 345.32556, 345.3912 ], dtype=float32)),\n", - " (array([ 43, 19, 31, 32, 62, 121, 86, 100, 173, 268], dtype=int32),\n", - " array([310.92206, 310.96536, 310.97714, 310.98904, 311.26248, 311.41983,\n", - " 311.64215, 311.65945, 311.74713, 311.78943], dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 62, 121, 100, 268, 49, 305], dtype=int32),\n", - " array([309.73407, 309.74258, 309.77997, 309.98755, 310.17023, 310.30298,\n", - " 310.49966, 310.50226, 310.5157 , 310.6984 ], dtype=float32)),\n", - " (array([149, 262, 552, 965, 19, 43, 62, 31, 735, 8], dtype=int32),\n", - " array([338.7936 , 338.9113 , 339.23383, 339.29318, 339.36636, 339.3925 ,\n", - " 339.39908, 339.40466, 339.44315, 339.50684], dtype=float32)),\n", - " (array([ 32, 31, 19, 43, 305, 121, 62, 268, 120, 29], dtype=int32),\n", - " array([299.54276, 299.82416, 299.9215 , 300.1283 , 300.2993 , 300.39517,\n", - " 300.42905, 300.47266, 300.5968 , 300.60406], dtype=float32)),\n", - " (array([ 32, 149, 43, 62, 8, 262, 19, 31, 965, 347], dtype=int32),\n", - " array([321.21442, 321.26743, 321.4155 , 321.50497, 321.56006, 321.611 ,\n", - " 321.69006, 321.85132, 321.9675 , 322.0124 ], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 86, 255, 268, 121, 120], dtype=int32),\n", - " array([289.8584 , 289.92667, 289.97864, 290.1437 , 290.38806, 290.5766 ,\n", - " 290.6364 , 290.64615, 290.7013 , 290.70383], dtype=float32)),\n", - " (array([ 31, 62, 19, 121, 173, 86, 268, 32, 120, 61], dtype=int32),\n", - " array([285.05518, 285.42502, 285.44858, 285.59433, 285.8237 , 285.92245,\n", - " 285.9577 , 286.02774, 286.0302 , 286.06293], dtype=float32)),\n", - " (array([ 31, 12, 19, 21, 43, 62, 173, 121, 358, 32], dtype=int32),\n", - " array([312.25607, 312.33475, 312.7304 , 312.7861 , 313.21628, 313.31088,\n", - " 313.32422, 313.5192 , 313.62683, 313.65344], dtype=float32)),\n", - " (array([ 43, 32, 31, 62, 49, 19, 121, 100, 305, 29], dtype=int32),\n", - " array([339.62262, 339.76053, 339.82208, 339.91553, 340.22488, 340.30194,\n", - " 340.32797, 340.34085, 340.55695, 340.60477], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 173, 268, 12, 100], dtype=int32),\n", - " array([280.95374, 281.04294, 281.30386, 281.56708, 281.59814, 281.71246,\n", - " 281.76068, 281.83936, 281.92813, 282.13126], dtype=float32)),\n", - " (array([ 31, 19, 43, 121, 32, 86, 105, 62, 268, 164], dtype=int32),\n", - " array([-9.403651, -9.373893, -8.987466, -8.851008, -8.665498, -8.599025,\n", - " -8.547629, -8.522236, -8.46133 , -8.398083], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-4.986924 , -4.9661355, -4.4244866, -4.3569655, -4.3528247,\n", - " -4.1861296, -4.178986 , -3.9884882, -3.9543579, -3.9225807],\n", - " dtype=float32)),\n", - " (array([ 69, 31, 43, 19, 121, 1380, 36, 279, 62, 118],\n", - " dtype=int32),\n", - " array([311.12405, 311.16483, 311.31955, 311.33456, 311.4418 , 311.4979 ,\n", - " 311.49832, 311.6392 , 311.64697, 311.6873 ], dtype=float32)),\n", - " (array([ 19, 43, 62, 31, 279, 358, 32, 1287, 176, 884],\n", - " dtype=int32),\n", - " array([-13.498163 , -13.462343 , -13.3111315, -13.301067 , -13.287409 ,\n", - " -13.181221 , -13.180961 , -13.051083 , -12.99551 , -12.987873 ],\n", - " dtype=float32)),\n", - " (array([ 19, 43, 31, 62, 32, 1287, 279, 121, 173, 206],\n", - " dtype=int32),\n", - " array([346.14276, 346.33078, 346.54584, 346.61905, 346.6322 , 346.8345 ,\n", - " 347.00287, 347.00433, 347.03168, 347.09067], dtype=float32)),\n", - " (array([255, 19, 31, 32, 43, 62, 173, 86, 121, 100], dtype=int32),\n", - " array([-11.674228 , -11.6636915, -11.418348 , -11.235206 , -11.090764 ,\n", - " -10.999236 , -10.917635 , -10.90773 , -10.886088 , -10.836512 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 32, 100, 12, 43, 173, 105], dtype=int32),\n", - " array([313.2493 , 313.63666, 313.63754, 313.67752, 313.79147, 314.04398,\n", - " 314.0734 , 314.182 , 314.2183 , 314.33435], dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 62, 8, 121, 166, 149, 240], dtype=int32),\n", - " array([300.4301 , 300.81973, 301.03027, 301.10568, 301.20944, 301.23923,\n", - " 301.24026, 301.4705 , 301.59702, 301.64597], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([312.38693, 312.56485, 312.79868, 312.9118 , 312.96448, 313.01743,\n", - " 313.2544 , 313.3963 , 313.45984, 313.4765 ], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 173, 268, 121, 120, 206], dtype=int32),\n", - " array([343.74115, 343.75327, 343.8907 , 344.07642, 344.3839 , 344.4377 ,\n", - " 344.45563, 344.56604, 344.61426, 344.68433], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 268, 305, 121, 49, 105], dtype=int32),\n", - " array([341.80322, 342.03247, 342.04666, 342.18524, 342.57547, 342.61423,\n", - " 342.84094, 342.85788, 342.93777, 342.96387], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 268, 86, 173, 255], dtype=int32),\n", - " array([346.51434, 346.7377 , 346.85852, 346.95734, 347.4286 , 347.53882,\n", - " 347.56973, 347.5792 , 347.5964 , 347.65454], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 62, 164, 120, 268, 121, 49], dtype=int32),\n", - " array([343.4146 , 343.6639 , 343.73102, 343.73853, 343.77475, 344.19873,\n", - " 344.2149 , 344.2228 , 344.2883 , 344.37488], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 255, 121, 305, 86, 29, 120], dtype=int32),\n", - " array([-10.457267 , -10.199842 , -10.056412 , -10.019432 , -9.73673 ,\n", - " -9.598978 , -9.5876045, -9.586909 , -9.564742 , -9.555381 ],\n", - " dtype=float32)),\n", - " (array([ 32, 43, 31, 19, 62, 121, 49, 268, 164, 487], dtype=int32),\n", - " array([318.75555, 318.81253, 318.93958, 318.98978, 319.0273 , 319.19647,\n", - " 319.23032, 319.41107, 319.48895, 319.50415], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 62, 120, 29, 268, 100], dtype=int32),\n", - " array([254.81033, 255.18977, 255.28316, 255.511 , 255.53236, 255.77988,\n", - " 255.91238, 255.92043, 255.99403, 256.05164], dtype=float32)),\n", - " (array([ 262, 149, 153, 8, 1482, 1639, 1118, 2412, 489, 1812],\n", - " dtype=int32),\n", - " array([317.41687, 317.56653, 317.7066 , 317.82538, 317.89273, 317.96765,\n", - " 318.0459 , 318.08994, 318.1292 , 318.16635], dtype=float32)),\n", - " (array([ 31, 19, 121, 43, 86, 32, 62, 100, 29, 120], dtype=int32),\n", - " array([317.84995, 318.14557, 318.17056, 318.24088, 318.32578, 318.43365,\n", - " 318.4487 , 318.6564 , 318.73923, 318.74817], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 268, 62, 173, 255, 29], dtype=int32),\n", - " array([-11.918893 , -11.851038 , -11.449318 , -11.2708025, -11.181248 ,\n", - " -10.961428 , -10.921991 , -10.880789 , -10.856545 , -10.822323 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 43, 62, 103, 268, 173, 120], dtype=int32),\n", - " array([-8.072788 , -7.4184704, -7.1753187, -6.992097 , -6.8998375,\n", - " -6.861067 , -6.808331 , -6.784878 , -6.7715316, -6.6240177],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 32, 279, 36, 86, 69, 62, 31, 2314],\n", - " dtype=int32),\n", - " array([314.96353, 315.24908, 315.40234, 315.4431 , 315.54752, 315.59293,\n", - " 315.60843, 315.65335, 315.69095, 315.7788 ], dtype=float32)),\n", - " (array([ 19, 43, 86, 31, 62, 268, 173, 164, 32, 255], dtype=int32),\n", - " array([266.12836, 266.34158, 266.53992, 266.57846, 266.6248 , 266.66907,\n", - " 266.8483 , 266.87323, 266.91437, 266.9621 ], dtype=float32)),\n", - " (array([ 19, 31, 43, 173, 62, 121, 8, 805, 884, 358], dtype=int32),\n", - " array([-13.432019 , -13.183143 , -13.1153345, -13.080894 , -13.043508 ,\n", - " -12.704055 , -12.695368 , -12.690328 , -12.667596 , -12.649502 ],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 268, 173, 29, 62, 100, 258], dtype=int32),\n", - " array([324.7802 , 325.19388, 325.2295 , 325.4271 , 325.95062, 325.9603 ,\n", - " 325.97086, 326.07904, 326.08762, 326.10327], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 32, 43, 173, 268, 100, 120], dtype=int32),\n", - " array([347.06757, 347.46185, 347.6805 , 347.8658 , 347.87683, 347.93518,\n", - " 348.1861 , 348.2632 , 348.32953, 348.40472], dtype=float32)),\n", - " (array([ 43, 62, 32, 149, 279, 16, 31, 974, 49, 69], dtype=int32),\n", - " array([333.1162 , 333.86624, 333.88013, 333.98053, 334.08423, 334.1702 ,\n", - " 334.18555, 334.21033, 334.2319 , 334.2333 ], dtype=float32)),\n", - " (array([ 43, 19, 31, 279, 32, 8, 149, 262, 86, 62], dtype=int32),\n", - " array([-8.601656 , -8.325794 , -8.261889 , -8.244502 , -8.2417555,\n", - " -8.131131 , -8.119339 , -8.071309 , -7.9272113, -7.9017315],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 166, 62, 69, 120, 36], dtype=int32),\n", - " array([263.0741 , 263.11826, 263.31097, 263.32892, 263.53125, 263.75156,\n", - " 263.9524 , 264.02557, 264.06003, 264.07492], dtype=float32)),\n", - " (array([ 8, 149, 32, 262, 57, 1619, 43, 539, 0, 153],\n", - " dtype=int32),\n", - " array([296.08334, 296.18127, 296.4126 , 296.50995, 296.5372 , 296.57828,\n", - " 296.584 , 296.58594, 296.5934 , 296.60336], dtype=float32)),\n", - " (array([ 31, 32, 43, 121, 19, 62, 268, 100, 173, 358], dtype=int32),\n", - " array([347.23248, 347.32788, 347.4656 , 347.63852, 347.6817 , 347.76965,\n", - " 347.83038, 347.9075 , 348.03604, 348.16458], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 255, 29, 268, 305, 121, 62], dtype=int32),\n", - " array([272.09662, 272.55447, 272.68497, 273.05173, 273.14047, 273.30502,\n", - " 273.47324, 273.5242 , 273.60577, 273.63638], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 149, 62, 8, 262, 121, 552], dtype=int32),\n", - " array([-14.825947, -14.819177, -14.812019, -14.472718, -14.465967,\n", - " -14.454661, -14.301346, -14.280471, -14.038158, -13.899126],\n", - " dtype=float32)),\n", - " (array([ 32, 43, 19, 62, 31, 279, 173, 36, 100, 121], dtype=int32),\n", - " array([313.90482, 313.91418, 314.0386 , 314.4915 , 314.56784, 314.6367 ,\n", - " 314.69028, 314.75497, 314.76318, 314.82654], dtype=float32)),\n", - " (array([ 19, 31, 121, 173, 32, 255, 268, 413, 100, 29], dtype=int32),\n", - " array([6.3029566, 6.325471 , 7.1249914, 7.1439323, 7.271358 , 7.3472466,\n", - " 7.4028363, 7.4395614, 7.4518304, 7.455539 ], dtype=float32)),\n", - " (array([ 31, 43, 86, 62, 121, 19, 120, 32, 103, 164], dtype=int32),\n", - " array([342.04462, 342.42197, 342.5576 , 342.65054, 342.6946 , 342.70132,\n", - " 342.73474, 342.8664 , 342.872 , 342.95425], dtype=float32)),\n", - " (array([ 19, 32, 31, 121, 62, 100, 173, 43, 268, 29], dtype=int32),\n", - " array([248.1499 , 248.47305, 248.52277, 248.6679 , 248.702 , 248.87695,\n", - " 248.94843, 249.04689, 249.1632 , 249.39273], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 121, 62, 268, 173, 100, 29], dtype=int32),\n", - " array([301.9033 , 302.1271 , 302.23303, 302.2696 , 302.42734, 302.58698,\n", - " 302.65298, 302.69012, 302.76334, 302.8002 ], dtype=float32)),\n", - " (array([ 43, 31, 62, 19, 121, 86, 32, 49, 164, 112], dtype=int32),\n", - " array([303.49542, 303.6827 , 303.68573, 303.71063, 303.96054, 303.96176,\n", - " 303.98175, 303.98785, 304.0541 , 304.07434], dtype=float32)),\n", - " (array([ 62, 31, 32, 43, 19, 100, 121, 49, 36, 86], dtype=int32),\n", - " array([311.4336 , 311.6961 , 311.69638, 311.7958 , 311.79938, 311.9889 ,\n", - " 312.01828, 312.07907, 312.0808 , 312.13287], dtype=float32)),\n", - " (array([ 31, 19, 121, 43, 62, 32, 86, 255, 173, 100], dtype=int32),\n", - " array([54.50405 , 54.84396 , 54.866604, 54.930305, 54.956398, 55.073605,\n", - " 55.08074 , 55.2308 , 55.32757 , 55.469753], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 255, 268, 121, 103, 62, 29], dtype=int32),\n", - " array([-5.7195597, -5.137107 , -4.9554033, -4.932697 , -4.9061317,\n", - " -4.82989 , -4.7904043, -4.751795 , -4.6291876, -4.48692 ],\n", - " dtype=float32)),\n", - " (array([ 552, 31, 149, 835, 262, 965, 57, 1842, 19, 43],\n", - " dtype=int32),\n", - " array([347.87418, 347.95306, 348.28564, 348.4731 , 348.5061 , 348.68365,\n", - " 348.72757, 348.76346, 348.85397, 348.87277], dtype=float32)),\n", - " (array([450, 62, 262, 149, 36, 8, 735, 121, 32, 240], dtype=int32),\n", - " array([312.70087, 312.7531 , 312.84186, 312.9744 , 313.0297 , 313.03146,\n", - " 313.1576 , 313.16327, 313.3068 , 313.30963], dtype=float32)),\n", - " (array([ 31, 19, 255, 43, 32, 164, 29, 62, 86, 268], dtype=int32),\n", - " array([294.09708, 294.1484 , 294.27658, 294.51968, 294.6763 , 294.70798,\n", - " 294.87708, 294.95593, 294.9791 , 295.0429 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 62, 100, 173, 8, 105], dtype=int32),\n", - " array([288.44452, 288.84558, 288.85104, 288.98502, 289.20908, 289.24036,\n", - " 289.36612, 289.42758, 289.54694, 289.65704], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 121, 268, 100, 49, 305], dtype=int32),\n", - " array([287.98804, 288.0021 , 288.09988, 288.15427, 288.5115 , 288.59036,\n", - " 288.79196, 288.864 , 288.92755, 288.92938], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 121, 173, 255, 268, 100], dtype=int32),\n", - " array([-7.956836 , -7.9356647, -7.574913 , -7.4195814, -7.0172944,\n", - " -6.934751 , -6.877664 , -6.770093 , -6.7122035, -6.6966424],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 62, 173, 43, 121, 8, 262, 149], dtype=int32),\n", - " array([346.29276, 346.6341 , 346.89227, 346.91644, 347.08945, 347.1381 ,\n", - " 347.16867, 347.32584, 347.33835, 347.3591 ], dtype=float32)),\n", - " (array([ 32, 43, 31, 62, 19, 49, 121, 304, 120, 273], dtype=int32),\n", - " array([336.41507, 336.43527, 336.65244, 336.6793 , 336.85248, 336.86942,\n", - " 337.0669 , 337.0924 , 337.20065, 337.20428], dtype=float32)),\n", - " (array([ 32, 31, 19, 186, 268, 305, 120, 43, 29, 42], dtype=int32),\n", - " array([297.26376, 297.3984 , 297.81757, 298.0148 , 298.08005, 298.13547,\n", - " 298.13654, 298.1406 , 298.26038, 298.29224], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 173, 121, 100, 268, 206], dtype=int32),\n", - " array([315.2561 , 315.4535 , 315.4661 , 315.55038, 315.61688, 315.9148 ,\n", - " 315.9269 , 316.12347, 316.18835, 316.25485], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 268, 173, 29, 121, 62, 105], dtype=int32),\n", - " array([345.83286, 346.3137 , 346.4924 , 346.56885, 347.09875, 347.2348 ,\n", - " 347.23523, 347.30048, 347.3587 , 347.42896], dtype=float32)),\n", - " (array([ 32, 43, 31, 62, 19, 120, 86, 121, 268, 112], dtype=int32),\n", - " array([310.65442, 310.74933, 310.94492, 311.0456 , 311.14282, 311.39108,\n", - " 311.4273 , 311.485 , 311.53815, 311.635 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-4.9424825, -4.9155636, -4.385795 , -4.3284597, -4.3199773,\n", - " -4.147278 , -4.1336265, -3.9436584, -3.912855 , -3.8884976],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 268, 100, 49, 120], dtype=int32),\n", - " array([341.3728 , 341.47614, 341.48126, 341.53735, 341.7902 , 342.04984,\n", - " 342.25253, 342.25882, 342.29233, 342.42172], dtype=float32)),\n", - " (array([ 31, 32, 62, 43, 19, 121, 120, 268, 8, 86], dtype=int32),\n", - " array([244.13846, 244.18678, 244.64307, 244.72765, 244.75182, 244.8955 ,\n", - " 244.92314, 244.93623, 245.28328, 245.29587], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 121, 268, 100, 305, 49], dtype=int32),\n", - " array([288.06125, 288.07013, 288.17285, 288.21442, 288.57718, 288.675 ,\n", - " 288.8593 , 288.93582, 288.99738, 288.9982 ], dtype=float32)),\n", - " (array([ 62, 31, 43, 121, 19, 32, 49, 8, 164, 149], dtype=int32),\n", - " array([306.9274 , 307.0448 , 307.23932, 307.30054, 307.3653 , 307.40097,\n", - " 307.46902, 307.54773, 307.61206, 307.63544], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 100, 49, 279, 268], dtype=int32),\n", - " array([330.16483, 330.30557, 330.34036, 330.44366, 330.65872, 330.86734,\n", - " 331.03766, 331.1014 , 331.19858, 331.20575], dtype=float32)),\n", - " (array([ 31, 130, 19, 121, 43, 358, 173, 62, 32, 21], dtype=int32),\n", - " array([343.72333, 344.38858, 344.43488, 344.45816, 344.56247, 344.56253,\n", - " 344.70657, 344.7167 , 344.72083, 344.7534 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 120, 268, 173, 105], dtype=int32),\n", - " array([-19.018951, -18.657345, -18.235214, -18.119884, -18.018509,\n", - " -17.952024, -17.932493, -17.826878, -17.576494, -17.56839 ],\n", - " dtype=float32)),\n", - " (array([ 31, 103, 19, 121, 501, 703, 441, 392, 535, 384], dtype=int32),\n", - " array([305.8875 , 306.49344, 306.54022, 306.76788, 306.91516, 306.94485,\n", - " 306.98056, 307.00214, 307.0751 , 307.09073], dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 29, 173, 43, 268, 105, 100], dtype=int32),\n", - " array([307.13513, 307.40985, 307.68033, 307.68445, 308.14465, 308.25616,\n", - " 308.2985 , 308.37585, 308.38162, 308.38895], dtype=float32)),\n", - " (array([ 8, 19, 262, 32, 3146, 153, 31, 1482, 43, 0],\n", - " dtype=int32),\n", - " array([-3.0451965, -2.9343429, -2.7803874, -2.6331844, -2.576582 ,\n", - " -2.5600913, -2.5204046, -2.5034306, -2.4394426, -2.421362 ],\n", - " dtype=float32)),\n", - " (array([ 69, 43, 19, 31, 32, 36, 62, 279, 121, 118], dtype=int32),\n", - " array([289.3832 , 289.42673, 289.47562, 289.5072 , 289.5677 , 289.6243 ,\n", - " 289.6437 , 289.69308, 289.7579 , 289.7609 ], dtype=float32)),\n", - " (array([262, 19, 149, 8, 32, 31, 450, 369, 153, 43], dtype=int32),\n", - " array([328.5683 , 328.8512 , 328.91037, 329.08716, 329.08926, 329.09625,\n", - " 329.1799 , 329.24945, 329.41547, 329.54727], dtype=float32)),\n", - " (array([ 43, 32, 149, 262, 62, 19, 8, 31, 86, 835], dtype=int32),\n", - " array([344.51297, 344.73776, 344.90802, 344.9234 , 344.97308, 344.98062,\n", - " 344.9881 , 345.18948, 345.34314, 345.34973], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([312.34116, 312.52338, 312.74097, 312.84436, 312.89795, 312.96802,\n", - " 313.1962 , 313.33765, 313.39905, 313.41345], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", - " array([310.37195, 310.48438, 310.73236, 310.7921 , 310.9571 , 311.06403,\n", - " 311.26767, 311.38147, 311.46518, 311.48535], dtype=float32)),\n", - " (array([ 31, 62, 32, 19, 43, 121, 8, 49, 149, 450], dtype=int32),\n", - " array([319.09277, 319.0982 , 319.16324, 319.30203, 319.4725 , 319.65445,\n", - " 319.73773, 319.7948 , 319.81293, 319.8161 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 86, 100, 173, 268], dtype=int32),\n", - " array([51.56032 , 51.64509 , 51.89514 , 52.040867, 52.113083, 52.160084,\n", - " 52.437153, 52.49843 , 52.52908 , 52.57915 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 29, 121, 62, 86, 255, 100], dtype=int32),\n", - " array([286.01556, 286.208 , 286.4942 , 286.679 , 286.76297, 286.83844,\n", - " 286.89044, 287.01797, 287.05484, 287.13095], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 43, 103, 173, 268, 32, 120], dtype=int32),\n", - " array([-19.457333, -18.714315, -18.369879, -18.300188, -18.220444,\n", - " -18.181852, -18.168312, -18.15627 , -17.997553, -17.949684],\n", - " dtype=float32)),\n", - " (array([ 21, 31, 12, 19, 121, 173, 29, 268, 24, 100], dtype=int32),\n", - " array([321.90228, 322.1381 , 322.27518, 322.32233, 322.91846, 323.1344 ,\n", - " 323.2252 , 323.387 , 323.4961 , 323.51328], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 32, 43, 8, 173, 358, 86], dtype=int32),\n", - " array([310.6909 , 311.09784, 311.26416, 311.31766, 311.43814, 311.49664,\n", - " 311.57227, 311.67944, 311.79572, 311.9097 ], dtype=float32)),\n", - " (array([ 8, 31, 121, 19, 735, 552, 62, 1218, 262, 32],\n", - " dtype=int32),\n", - " array([54.73985 , 54.921024, 55.124485, 55.196564, 55.243668, 55.385918,\n", - " 55.392246, 55.454796, 55.46576 , 55.48683 ], dtype=float32)),\n", - " (array([ 43, 32, 19, 255, 31, 305, 96, 62, 86, 371], dtype=int32),\n", - " array([237.34068, 237.68623, 237.89716, 237.90114, 237.9998 , 238.02856,\n", - " 238.17896, 238.23405, 238.24007, 238.33682], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.89243, 345.13293, 345.28214, 345.36203, 345.4125 , 345.55585,\n", - " 345.78702, 345.90482, 345.98175, 346.0863 ], dtype=float32)),\n", - " (array([ 31, 19, 12, 121, 32, 268, 62, 43, 103, 173], dtype=int32),\n", - " array([-5.8817196, -5.2614293, -5.0825977, -4.850183 , -4.729859 ,\n", - " -4.609657 , -4.492527 , -4.4885426, -4.429251 , -4.3971024],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 121, 86, 100, 173, 255], dtype=int32),\n", - " array([286.65735, 286.82874, 286.86823, 286.889 , 287.12677, 287.4117 ,\n", - " 287.64365, 287.67285, 287.68365, 287.69443], dtype=float32)),\n", - " (array([ 31, 19, 62, 32, 121, 49, 43, 164, 268, 214], dtype=int32),\n", - " array([259.6416 , 259.8257 , 259.9938 , 260.0587 , 260.2523 , 260.3186 ,\n", - " 260.37897, 260.41946, 260.43362, 260.54105], dtype=float32)),\n", - " (array([ 31, 43, 32, 121, 62, 19, 268, 255, 120, 100], dtype=int32),\n", - " array([52.12003 , 52.398285, 52.594257, 52.736996, 52.96305 , 52.977146,\n", - " 53.001183, 53.079437, 53.10935 , 53.13721 ], dtype=float32)),\n", - " (array([ 43, 32, 279, 19, 528, 974, 204, 305, 13, 791], dtype=int32),\n", - " array([283.63626, 283.77692, 284.06302, 284.1349 , 284.19046, 284.28247,\n", - " 284.3817 , 284.43475, 284.45874, 284.48535], dtype=float32)),\n", - " (array([ 43, 31, 62, 86, 32, 19, 121, 112, 49, 279], dtype=int32),\n", - " array([-18.087584, -17.803343, -17.760427, -17.6359 , -17.602201,\n", - " -17.509865, -17.246746, -17.181599, -17.159885, -17.151201],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 121, 268, 49, 100, 305], dtype=int32),\n", - " array([320.65054, 320.68423, 320.79788, 320.80612, 321.1471 , 321.32733,\n", - " 321.48364, 321.56665, 321.5726 , 321.64294], dtype=float32)),\n", - " (array([ 19, 31, 12, 121, 100, 32, 173, 86, 43, 62], dtype=int32),\n", - " array([286.94623, 287.03894, 287.05435, 287.30106, 287.31995, 287.3615 ,\n", - " 287.47394, 287.5053 , 287.51355, 287.56003], dtype=float32)),\n", - " (array([ 32, 43, 19, 305, 31, 268, 111, 42, 188, 206], dtype=int32),\n", - " array([291.84128, 291.9949 , 292.1734 , 292.54523, 292.66608, 292.87045,\n", - " 292.89758, 292.92374, 292.92386, 293.15448], dtype=float32)),\n", - " (array([ 31, 32, 19, 121, 43, 268, 173, 62, 12, 255], dtype=int32),\n", - " array([-11.100351, -10.468095, -10.466587, -10.253364, -10.097407,\n", - " -10.064852, -10.018247, -10.006114, -9.914094, -9.739739],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-4.9254117, -4.903883 , -4.3681984, -4.30716 , -4.300051 ,\n", - " -4.1327434, -4.114312 , -3.93446 , -3.8890843, -3.8635614],\n", - " dtype=float32)),\n", - " (array([ 32, 43, 8, 19, 305, 62, 121, 31, 49, 100], dtype=int32),\n", - " array([306.1436 , 306.63864, 306.75577, 307.041 , 307.17163, 307.19968,\n", - " 307.22598, 307.24814, 307.2702 , 307.34793], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 29, 255, 121, 12, 62, 268], dtype=int32),\n", - " array([289.3988 , 289.4781 , 289.83536, 289.93164, 290.13113, 290.13934,\n", - " 290.26428, 290.29208, 290.29382, 290.3108 ], dtype=float32)),\n", - " (array([ 31, 19, 255, 121, 32, 62, 43, 29, 268, 164], dtype=int32),\n", - " array([236.59924, 237.13544, 237.53168, 237.56348, 237.56618, 237.57274,\n", - " 237.65794, 237.77704, 237.81342, 237.84462], dtype=float32)),\n", - " (array([ 19, 31, 32, 62, 43, 173, 121, 268, 255, 164], dtype=int32),\n", - " array([329.14563, 329.3854 , 329.7733 , 329.97467, 330.03122, 330.2544 ,\n", - " 330.2798 , 330.2937 , 330.398 , 330.42133], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 173, 62, 121, 268, 358, 100], dtype=int32),\n", - " array([350.68387, 350.69342, 350.80106, 350.90695, 351.0972 , 351.2773 ,\n", - " 351.43848, 351.56934, 351.61655, 351.70245], dtype=float32)),\n", - " (array([ 31, 12, 21, 19, 121, 173, 100, 29, 62, 61], dtype=int32),\n", - " array([316.48135, 316.85742, 317.19247, 317.21408, 317.22467, 317.45316,\n", - " 317.4648 , 317.57352, 317.575 , 317.6446 ], dtype=float32)),\n", - " (array([3162, 2310, 1342, 5058, 905, 1026, 4326, 21, 2881, 34],\n", - " dtype=int32),\n", - " array([300.90842, 300.96997, 301.74078, 303.49213, 303.60464, 303.88052,\n", - " 304.16605, 304.49786, 304.53943, 304.6457 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 86, 268], dtype=int32),\n", - " array([279.22168, 279.36438, 279.5201 , 279.55054, 279.60898, 279.7201 ,\n", - " 279.91702, 280.13342, 280.1468 , 280.19965], dtype=float32)),\n", - " (array([ 19, 43, 32, 36, 418, 262, 279, 62, 118, 69], dtype=int32),\n", - " array([262.0025 , 262.25748, 262.27625, 262.38562, 262.4314 , 262.49762,\n", - " 262.53442, 262.5364 , 262.58148, 262.60675], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 149, 100, 279, 262, 8], dtype=int32),\n", - " array([323.7864 , 323.8769 , 324.02374, 324.26825, 324.6423 , 324.68677,\n", - " 324.83203, 324.86484, 324.9063 , 324.97763], dtype=float32)),\n", - " (array([ 19, 358, 31, 43, 636, 173, 884, 32, 258, 176], dtype=int32),\n", - " array([298.38684, 298.8378 , 298.9924 , 299.0933 , 299.1338 , 299.2397 ,\n", - " 299.26535, 299.31244, 299.31366, 299.41064], dtype=float32)),\n", - " (array([ 31, 43, 19, 62, 121, 32, 49, 100, 105, 268], dtype=int32),\n", - " array([324.07172, 324.1925 , 324.25323, 324.29153, 324.4124 , 324.43683,\n", - " 324.5018 , 324.7881 , 324.86203, 324.9179 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 62, 173, 268, 100, 49], dtype=int32),\n", - " array([291.8476 , 291.9148 , 291.9484 , 292.0435 , 292.17603, 292.33145,\n", - " 292.61664, 292.68683, 292.79715, 292.80698], dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", - " array([311.9987 , 312.1394 , 312.24393, 312.28568, 312.32852, 312.52313,\n", - " 312.68362, 312.9114 , 312.96066, 312.9829 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", - " array([-5.125645 , -5.1117697, -4.5883775, -4.522718 , -4.5065985,\n", - " -4.3377857, -4.3346972, -4.136434 , -4.100578 , -4.072297 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 121, 62, 268, 86, 29, 173], dtype=int32),\n", - " array([-11.173502, -10.861092, -10.504527, -10.411109, -10.17119 ,\n", - " -10.068164, -10.056534, -9.945865, -9.90956 , -9.853734],\n", - " dtype=float32)),\n", - " (array([ 31, 262, 8, 32, 149, 19, 43, 255, 62, 121], dtype=int32),\n", - " array([238.19867, 238.20563, 238.34206, 238.37549, 238.5953 , 238.60184,\n", - " 238.61967, 238.65845, 238.69276, 238.80728], dtype=float32)),\n", - " (array([ 31, 32, 62, 43, 121, 19, 86, 120, 100, 268], dtype=int32),\n", - " array([310.1455 , 310.4189 , 310.43335, 310.5555 , 310.5965 , 310.64008,\n", - " 310.79065, 310.7992 , 310.93652, 311.03946], dtype=float32)),\n", - " (array([ 19, 31, 62, 173, 358, 121, 32, 43, 268, 100], dtype=int32),\n", - " array([317.3086 , 317.36652, 317.98584, 318.00388, 318.0438 , 318.06528,\n", - " 318.24594, 318.34775, 318.3744 , 318.4178 ], dtype=float32)),\n", - " (array([ 31, 19, 173, 121, 12, 32, 62, 43, 29, 268], dtype=int32),\n", - " array([246.55493, 246.71327, 247.36504, 247.43756, 247.46124, 247.46684,\n", - " 247.686 , 247.69244, 247.84915, 247.87175], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 100, 120], dtype=int32),\n", - " array([289.67343, 289.75418, 290.05197, 290.17166, 290.35846, 290.37006,\n", - " 290.55157, 290.72638, 290.83023, 290.83817], dtype=float32)),\n", - " (array([ 31, 62, 121, 32, 19, 164, 49, 214, 100, 43], dtype=int32),\n", - " array([-17.452925, -17.082415, -16.977293, -16.79991 , -16.761396,\n", - " -16.711647, -16.59783 , -16.554043, -16.549341, -16.547562],\n", - " dtype=float32)),\n", - " (array([ 31, 43, 32, 121, 62, 120, 19, 268, 214, 100], dtype=int32),\n", - " array([342.10764, 342.40393, 342.601 , 342.6924 , 342.75443, 342.77255,\n", - " 342.8065 , 342.99075, 343.05145, 343.09598], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 552, 32, 100, 173, 262, 8], dtype=int32),\n", - " array([345.06534, 345.51395, 345.66486, 345.87442, 346.02188, 346.09512,\n", - " 346.17108, 346.2074 , 346.23413, 346.28485], dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 62, 120, 121, 100, 268, 49], dtype=int32),\n", - " array([338.6435 , 338.65988, 338.90436, 339.03046, 339.0824 , 339.27548,\n", - " 339.27863, 339.42453, 339.45117, 339.62817], dtype=float32)),\n", - " (array([ 32, 176, 43, 62, 240, 36, 358, 49, 449, 19], dtype=int32),\n", - " array([285.83398, 285.93173, 285.99463, 286.08954, 286.13916, 286.21014,\n", - " 286.2114 , 286.2278 , 286.27185, 286.3039 ], dtype=float32)),\n", - " (array([ 19, 8, 149, 262, 450, 0, 735, 31, 369, 325], dtype=int32),\n", - " array([-9.226801, -9.138501, -9.127476, -9.110326, -8.955484, -8.905296,\n", - " -8.892906, -8.806453, -8.670199, -8.623948], dtype=float32)),\n", - " (array([2181, 884, 176, 358, 1959, 43, 636, 39, 19, 258],\n", - " dtype=int32),\n", - " array([312.3727 , 312.49234, 312.83072, 313.08078, 313.12247, 313.15717,\n", - " 313.2025 , 313.2346 , 313.25156, 313.26837], dtype=float32)),\n", - " (array([ 43, 32, 305, 19, 374, 884, 206, 176, 188, 115], dtype=int32),\n", - " array([336.69034, 336.88113, 336.89825, 337.05707, 337.06216, 337.26108,\n", - " 337.35245, 337.37723, 337.4164 , 337.41843], dtype=float32)),\n", - " (array([ 32, 43, 62, 305, 31, 19, 49, 186, 112, 121], dtype=int32),\n", - " array([342.35617, 342.56393, 342.72467, 342.82828, 342.82965, 342.87332,\n", - " 342.87488, 343.10748, 343.14664, 343.21982], dtype=float32)),\n", - " (array([ 279, 118, 36, 13, 69, 32, 19, 1638, 43, 610],\n", - " dtype=int32),\n", - " array([311.91733, 311.9292 , 312.02463, 312.06647, 312.0825 , 312.10416,\n", - " 312.1174 , 312.15463, 312.15594, 312.20438], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 173, 8, 255, 149], dtype=int32),\n", - " array([-13.143767 , -13.089577 , -12.852583 , -12.779168 , -12.354462 ,\n", - " -12.340083 , -12.334131 , -12.132467 , -12.082108 , -12.0587845],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 62, 268, 121, 120, 29, 100], dtype=int32),\n", - " array([341.08133, 341.08163, 341.2488 , 341.2776 , 341.60825, 341.7576 ,\n", - " 341.79663, 341.8792 , 342.05518, 342.11826], dtype=float32)),\n", - " (array([ 345, 4326, 32, 62, 19, 43, 4738, 279, 36, 240],\n", - " dtype=int32),\n", - " array([313.32443, 313.83334, 313.83386, 313.97906, 314.2233 , 314.2352 ,\n", - " 314.23657, 314.38953, 314.4367 , 314.54684], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 279, 62, 166, 69, 36, 449], dtype=int32),\n", - " array([-15.757784, -15.744331, -15.715742, -15.367012, -15.236301,\n", - " -15.213285, -15.114642, -15.09193 , -15.05998 , -15.049946],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", - " array([-5.0672216, -5.0421457, -4.516862 , -4.4643373, -4.440181 ,\n", - " -4.270182 , -4.265323 , -4.06413 , -4.042031 , -4.0118537],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 121, 268, 206, 358, 173], dtype=int32),\n", - " array([336.34482, 336.53186, 336.6507 , 336.7412 , 336.9497 , 337.23145,\n", - " 337.4187 , 337.49295, 337.50797, 337.5084 ], dtype=float32)),\n", - " (array([ 8, 149, 262, 43, 32, 369, 552, 539, 965, 19], dtype=int32),\n", - " array([259.68927, 259.97995, 260.27322, 260.4497 , 260.45877, 260.51706,\n", - " 260.55112, 260.5933 , 260.64017, 260.67798], dtype=float32)),\n", - " (array([ 19, 32, 255, 43, 31, 86, 62, 121, 120, 268], dtype=int32),\n", - " array([238.10663, 238.45883, 238.5186 , 238.53629, 238.64828, 238.68321,\n", - " 239.056 , 239.14474, 239.14499, 239.14818], dtype=float32)),\n", - " (array([4642, 4841, 7746, 3945, 7054, 2068, 4162, 4991, 5923, 9677],\n", - " dtype=int32),\n", - " array([294.65677, 294.674 , 294.93518, 295.092 , 295.1311 , 295.214 ,\n", - " 295.2705 , 295.28445, 295.35535, 295.3882 ], dtype=float32)),\n", - " (array([ 43, 32, 62, 19, 31, 121, 100, 86, 49, 173], dtype=int32),\n", - " array([310.09192, 310.10608, 310.21176, 310.22104, 310.25888, 310.58765,\n", - " 310.77185, 310.82462, 310.8452 , 310.86765], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 121, 49, 112, 206, 36], dtype=int32),\n", - " array([318.88223, 318.92676, 319.1155 , 319.21268, 319.63818, 319.7363 ,\n", - " 319.8082 , 319.86127, 319.87927, 319.89987], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.993 , 345.20337, 345.35373, 345.4528 , 345.50842, 345.66574,\n", - " 345.88208, 345.9896 , 346.079 , 346.14886], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 121, 305, 86, 268, 255], dtype=int32),\n", - " array([-18.160736, -18.065302, -17.91232 , -17.910124, -17.429615,\n", - " -17.244274, -16.985851, -16.967516, -16.955187, -16.945377],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 121, 32, 62, 12, 173, 100, 29], dtype=int32),\n", - " array([264.25854, 264.44696, 264.95026, 265.03864, 265.04504, 265.0693 ,\n", - " 265.08334, 265.21765, 265.37256, 265.39532], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 268, 173, 62, 121, 100, 16], dtype=int32),\n", - " array([311.671 , 311.94263, 312.1423 , 312.3241 , 312.49414, 312.51218,\n", - " 312.54413, 312.64603, 312.88562, 312.89212], dtype=float32)),\n", - " (array([186, 371, 305, 31, 32, 558, 43, 62, 19, 848], dtype=int32),\n", - " array([259.57016, 260.4812 , 260.4939 , 260.5783 , 260.58813, 260.61566,\n", - " 260.6213 , 260.65884, 260.70975, 260.72714], dtype=float32)),\n", - " (array([ 19, 31, 121, 29, 32, 268, 62, 164, 43, 100], dtype=int32),\n", - " array([262.64905, 262.70822, 263.1871 , 263.19998, 263.2875 , 263.45972,\n", - " 263.49454, 263.61014, 263.64963, 263.6571 ], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 279, 342, 86, 173, 62, 255], dtype=int32),\n", - " array([-2.325954 , -2.287641 , -2.1654544, -1.9056807, -1.7842443,\n", - " -1.556874 , -1.514475 , -1.399868 , -1.3974245, -1.3832269],\n", - " dtype=float32)),\n", - " (array([ 62, 31, 19, 43, 32, 121, 8, 49, 149, 262], dtype=int32),\n", - " array([283.57202, 283.61777, 283.70404, 283.72073, 283.8724 , 283.9825 ,\n", - " 284.1056 , 284.21057, 284.28726, 284.42126], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 8, 100, 173, 268], dtype=int32),\n", - " array([320.68927, 320.87653, 320.9814 , 321.06622, 321.2445 , 321.30072,\n", - " 321.51376, 321.53784, 321.58566, 321.5869 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 29, 268, 62, 121, 105, 100], dtype=int32),\n", - " array([296.44696, 296.53885, 296.69055, 297.06415, 297.24615, 297.2801 ,\n", - " 297.3722 , 297.45248, 297.47623, 297.5988 ], dtype=float32)),\n", - " (array([2855, 19, 1584, 3209, 3351, 2181, 2977, 2953, 2430, 173],\n", - " dtype=int32),\n", - " array([-4.4399524, -4.162832 , -4.1061625, -3.9151645, -3.851419 ,\n", - " -3.7650146, -3.76427 , -3.6905649, -3.5535915, -3.530046 ],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 204, 43, 69, 258, 1184, 528, 31, 449],\n", - " dtype=int32),\n", - " array([292.26984, 292.46652, 292.58127, 292.82812, 292.9008 , 292.9639 ,\n", - " 292.96918, 293.0168 , 293.08652, 293.13058], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 268, 173, 358, 121, 120], dtype=int32),\n", - " array([341.7703 , 341.82343, 341.96713, 342.08362, 342.3323 , 342.35565,\n", - " 342.4744 , 342.6446 , 342.7415 , 342.7637 ], dtype=float32)),\n", - " (array([149, 735, 262, 8, 552, 57, 965, 450, 0, 539], dtype=int32),\n", - " array([314.68176, 314.86447, 314.8728 , 315.0222 , 315.12167, 315.1287 ,\n", - " 315.1573 , 315.17343, 315.25256, 315.2745 ], dtype=float32)),\n", - " (array([ 62, 31, 32, 43, 19, 86, 121, 49, 186, 112], dtype=int32),\n", - " array([263.61386, 263.68927, 263.72574, 263.7482 , 263.8793 , 264.08072,\n", - " 264.09268, 264.1364 , 264.20877, 264.3623 ], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 29, 86, 121, 268, 173, 62], dtype=int32),\n", - " array([-12.726268 , -12.408381 , -12.290524 , -11.975763 , -11.887823 ,\n", - " -11.756745 , -11.6794405, -11.597747 , -11.57287 , -11.558551 ],\n", - " dtype=float32)),\n", - " (array([121, 19, 31, 12, 173, 100, 86, 62, 46, 43], dtype=int32),\n", - " array([-4.0464287, -4.0107164, -3.9052997, -3.682777 , -3.5255613,\n", - " -3.4323666, -3.3947074, -3.3778327, -3.3165789, -3.2057178],\n", - " dtype=float32)),\n", - " (array([ 31, 43, 32, 19, 62, 121, 100, 86, 268, 173], dtype=int32),\n", - " array([308.93225, 309.0416 , 309.14764, 309.39368, 309.73505, 309.7393 ,\n", - " 309.9714 , 309.9879 , 310.1388 , 310.14453], dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 32, 43, 105, 100, 12, 268], dtype=int32),\n", - " array([347.7162 , 347.99213, 348.09198, 348.4327 , 348.53653, 348.6337 ,\n", - " 348.70117, 348.74374, 348.81705, 348.8452 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 258, 121, 358, 173, 268], dtype=int32),\n", - " array([259.4922 , 259.61646, 259.82053, 259.82526, 259.8572 , 260.27432,\n", - " 260.27792, 260.283 , 260.3097 , 260.38434], dtype=float32)),\n", - " (array([ 31, 19, 12, 121, 21, 29, 62, 32, 268, 173], dtype=int32),\n", - " array([-5.5620747, -4.9823895, -4.930903 , -4.861179 , -4.5280743,\n", - " -4.429846 , -4.4135256, -4.3969235, -4.373354 , -4.353081 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 268, 121, 86, 173, 120], dtype=int32),\n", - " array([313.7979 , 314.0508 , 314.1509 , 314.2101 , 314.5619 , 314.6413 ,\n", - " 314.6524 , 314.7491 , 314.75592, 314.81573], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 49, 305, 121, 100, 8], dtype=int32),\n", - " array([343.2616 , 343.43646, 343.54895, 343.6925 , 343.9715 , 344.00845,\n", - " 344.05222, 344.26 , 344.38644, 344.4242 ], dtype=float32)),\n", - " (array([ 19, 31, 255, 86, 32, 121, 173, 43, 62, 29], dtype=int32),\n", - " array([267.66257, 267.93002, 268.08368, 268.35587, 268.56754, 268.57025,\n", - " 268.59268, 268.59445, 268.62003, 268.77203], dtype=float32)),\n", - " (array([ 19, 31, 32, 121, 43, 173, 62, 100, 268, 86], dtype=int32),\n", - " array([-5.037884 , -5.0113072, -4.4723964, -4.4109874, -4.399605 ,\n", - " -4.232592 , -4.2241673, -4.035268 , -4.0049553, -3.958204 ],\n", - " dtype=float32)),\n", - " (array([ 31, 121, 19, 43, 62, 32, 173, 268, 12, 105], dtype=int32),\n", - " array([316.15582, 316.28268, 316.34995, 316.50616, 316.53418, 316.69226,\n", - " 316.6924 , 316.74594, 316.8173 , 316.9725 ], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 62, 173, 268, 121, 358, 120], dtype=int32),\n", - " array([339.40634, 339.42465, 339.62903, 339.79092, 340.04282, 340.28183,\n", - " 340.30557, 340.434 , 340.5182 , 340.5581 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 62, 32, 121, 173, 358, 268, 164], dtype=int32),\n", - " array([-16.94533 , -16.593094, -16.251049, -16.23989 , -16.206335,\n", - " -16.116669, -16.000875, -15.943753, -15.939101, -15.823728],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 268, 164, 100, 29], dtype=int32),\n", - " array([257.90213, 257.9448 , 258.11902, 258.19177, 258.51672, 258.6251 ,\n", - " 258.72946, 258.73135, 258.75577, 258.75784], dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 121, 62, 100, 36, 305, 86], dtype=int32),\n", - " array([345.34592, 345.36462, 345.4666 , 345.80612, 345.91028, 345.9715 ,\n", - " 346.2394 , 346.35544, 346.361 , 346.41788], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.988 , 345.1998 , 345.3611 , 345.4457 , 345.49893, 345.6501 ,\n", - " 345.857 , 345.98996, 346.05872, 346.1615 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 62, 255, 43, 100, 121, 86, 258], dtype=int32),\n", - " array([342.43045, 342.76987, 342.8739 , 342.94647, 342.95477, 342.98242,\n", - " 343.26712, 343.3159 , 343.36328, 343.50333], dtype=float32)),\n", - " (array([ 32, 19, 31, 305, 29, 43, 374, 111, 186, 1145],\n", - " dtype=int32),\n", - " array([347.16852, 347.28668, 347.50537, 347.61746, 347.6677 , 347.7222 ,\n", - " 347.88367, 347.98602, 348.03342, 348.16837], dtype=float32)),\n", - " (array([ 19, 43, 32, 487, 31, 268, 305, 186, 29, 483], dtype=int32),\n", - " array([306.63184, 306.80786, 306.8504 , 307.13535, 307.1441 , 307.1884 ,\n", - " 307.20377, 307.33905, 307.34225, 307.3911 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", - " array([310.39398, 310.51373, 310.7692 , 310.8383 , 310.99908, 311.08456,\n", - " 311.30945, 311.40503, 311.51147, 311.51376], dtype=float32)),\n", - " (array([ 43, 31, 32, 19, 384, 268, 62, 441, 304, 29], dtype=int32),\n", - " array([338.03943, 338.1071 , 338.1291 , 338.34378, 338.3504 , 338.61304,\n", - " 338.66327, 338.7925 , 338.7975 , 338.8082 ], dtype=float32)),\n", - " (array([ 19, 31, 12, 173, 121, 29, 43, 21, 105, 268], dtype=int32),\n", - " array([190.73648, 190.9686 , 191.2562 , 191.86366, 191.87589, 191.95314,\n", - " 192.12808, 192.13351, 192.15643, 192.3491 ], dtype=float32)),\n", - " (array([ 19, 477, 5, 3033, 3141, 173, 31, 32, 4659, 43],\n", - " dtype=int32),\n", - " array([3.430843 , 3.9056013, 4.0418715, 4.046853 , 4.056636 , 4.3053904,\n", - " 4.3968325, 4.487882 , 4.5651164, 4.5840354], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 358, 8, 268, 173, 121], dtype=int32),\n", - " array([341.83475, 342.08228, 342.45984, 342.4907 , 342.54538, 342.69 ,\n", - " 342.72357, 342.73367, 342.74844, 342.7689 ], dtype=float32)),\n", - " (array([ 36, 69, 43, 913, 279, 3738, 62, 777, 610, 118],\n", - " dtype=int32),\n", - " array([310.85855, 311.00134, 311.24194, 311.2462 , 311.31747, 311.3751 ,\n", - " 311.3794 , 311.3809 , 311.4277 , 311.47113], dtype=float32)),\n", - " (array([ 31, 19, 32, 62, 121, 268, 120, 43, 100, 173], dtype=int32),\n", - " array([260.15527, 260.33356, 260.46603, 260.5923 , 260.59818, 260.90775,\n", - " 260.9234 , 260.9475 , 260.95294, 261.12866], dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 62, 121, 120, 268, 204, 173], dtype=int32),\n", - " array([304.8672 , 305.04184, 305.0982 , 305.20557, 305.44165, 305.56686,\n", - " 305.8897 , 305.92307, 305.9696 , 306.02246], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 32, 173, 43, 12, 8, 262], dtype=int32),\n", - " array([315.08173, 315.56567, 315.85 , 316.11234, 316.19305, 316.30652,\n", - " 316.4888 , 316.48947, 316.52362, 316.54233], dtype=float32)),\n", - " (array([ 31, 19, 43, 121, 62, 32, 8, 100, 240, 173], dtype=int32),\n", - " array([-14.16787 , -13.845084, -13.718887, -13.682287, -13.641027,\n", - " -13.453795, -13.231029, -13.199575, -13.135003, -13.134393],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 120, 305, 441, 121, 164, 268], dtype=int32),\n", - " array([317.51428, 317.5627 , 317.6624 , 317.86914, 317.91382, 317.98355,\n", - " 318.06866, 318.08145, 318.11758, 318.1195 ], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 255, 86, 29, 100, 62, 121], dtype=int32),\n", - " array([310.67566, 310.81473, 310.86243, 311.2213 , 311.32886, 311.39627,\n", - " 311.44577, 311.462 , 311.54498, 311.55975], dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 121, 441, 392, 358, 384, 268], dtype=int32),\n", - " array([240.34673, 241.02698, 241.15286, 241.47986, 241.65193, 241.68596,\n", - " 241.69041, 241.69656, 241.7606 , 241.76118], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 62, 120, 268, 100, 43, 12], dtype=int32),\n", - " array([241.09387, 241.20638, 241.52031, 241.92465, 241.94305, 241.9487 ,\n", - " 242.04854, 242.11015, 242.13435, 242.14629], dtype=float32)),\n", - " (array([ 32, 19, 43, 305, 31, 111, 206, 268, 121, 42], dtype=int32),\n", - " array([261.71445, 262.0801 , 262.1176 , 262.32956, 262.36566, 262.68393,\n", - " 262.7763 , 262.77994, 262.8641 , 262.8895 ], dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 32, 43, 100, 12, 8, 105], dtype=int32),\n", - " array([320.52713, 321.20483, 321.22223, 321.32196, 321.3681 , 321.64197,\n", - " 321.73276, 321.76227, 321.9083 , 321.91156], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 305, 121, 62, 29, 268, 166], dtype=int32),\n", - " array([-9.771602, -9.651317, -9.530066, -9.454545, -9.047659, -8.892043,\n", - " -8.818036, -8.708289, -8.69499 , -8.673408], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 100, 62, 29, 86, 121, 268], dtype=int32),\n", - " array([351.55518, 351.5657 , 351.58936, 351.67026, 352.1352 , 352.1884 ,\n", - " 352.34573, 352.35324, 352.35858, 352.41708], dtype=float32)),\n", - " (array([ 31, 19, 29, 43, 121, 32, 100, 86, 24, 62], dtype=int32),\n", - " array([262.9181 , 263.11145, 263.17896, 263.32834, 263.33737, 263.4054 ,\n", - " 263.53165, 263.54105, 263.62784, 263.65033], dtype=float32)),\n", - " (array([539, 149, 0, 835, 552, 965, 43, 262, 31, 57], dtype=int32),\n", - " array([-14.163959 , -14.02205 , -14.019107 , -14.005707 , -13.971053 ,\n", - " -13.963415 , -13.871145 , -13.870991 , -13.8246765, -13.809494 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", - " array([310.3158 , 310.44525, 310.69406, 310.76694, 310.92398, 311.0064 ,\n", - " 311.2275 , 311.32843, 311.42514, 311.44415], dtype=float32)),\n", - " (array([ 19, 32, 43, 118, 121, 1638, 31, 279, 204, 62],\n", - " dtype=int32),\n", - " array([349.05283, 349.37512, 349.3868 , 349.67957, 349.72427, 349.73676,\n", - " 349.75995, 349.77823, 349.83777, 349.87097], dtype=float32)),\n", - " (array([ 43, 31, 32, 19, 62, 121, 49, 100, 206, 36], dtype=int32),\n", - " array([337.28348, 337.38318, 337.52942, 337.58563, 337.78082, 337.8964 ,\n", - " 338.12048, 338.2107 , 338.3415 , 338.34402], dtype=float32)),\n", - " (array([ 31, 19, 173, 12, 29, 121, 24, 32, 268, 43], dtype=int32),\n", - " array([-2.648589 , -2.4846468, -1.8998964, -1.8501105, -1.8254482,\n", - " -1.8077307, -1.5204421, -1.397704 , -1.3898225, -1.2860148],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 62, 43, 268, 120, 103, 100], dtype=int32),\n", - " array([242.83037, 243.1097 , 243.57559, 243.60168, 243.699 , 243.80403,\n", - " 243.8852 , 244.06425, 244.11368, 244.12534], dtype=float32)),\n", - " (array([ 31, 19, 62, 121, 173, 43, 61, 358, 164, 268], dtype=int32),\n", - " array([310.2988 , 310.67978, 310.71878, 311.0019 , 311.1329 , 311.16403,\n", - " 311.21085, 311.28015, 311.392 , 311.47043], dtype=float32)),\n", - " (array([ 43, 32, 62, 19, 31, 121, 86, 305, 268, 164], dtype=int32),\n", - " array([225.7964 , 226.03488, 226.18562, 226.26076, 226.34175, 226.4252 ,\n", - " 226.45828, 226.62724, 226.66763, 226.68503], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([322.40872, 322.4964 , 322.75797, 322.8775 , 323.04678, 323.11957,\n", - " 323.28 , 323.4584 , 323.57642, 323.59494], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 121, 268, 100, 305, 49], dtype=int32),\n", - " array([287.98828, 287.98935, 288.09244, 288.13318, 288.50793, 288.60037,\n", - " 288.78064, 288.86847, 288.90958, 288.93045], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 173, 103, 100, 26, 61, 32], dtype=int32),\n", - " array([248.02551, 248.5906 , 248.74591, 248.97745, 249.16042, 249.38612,\n", - " 249.45505, 249.49806, 249.52469, 249.58205], dtype=float32)),\n", - " (array([ 32, 31, 19, 43, 62, 268, 121, 305, 100, 166], dtype=int32),\n", - " array([309.62067, 309.62674, 309.63077, 309.69672, 310.03232, 310.34808,\n", - " 310.3511 , 310.47876, 310.51645, 310.5232 ], dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 31, 121, 100, 86, 49, 173], dtype=int32),\n", - " array([310.18716, 310.21133, 310.30426, 310.31018, 310.37228, 310.69373,\n", - " 310.8775 , 310.9256 , 310.9428 , 310.95407], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 255, 86, 62, 121, 100, 268], dtype=int32),\n", - " array([247.76933, 248.1085 , 248.17255, 248.30186, 248.45174, 248.50677,\n", - " 248.51407, 248.65228, 248.66599, 248.84972], dtype=float32)),\n", - " (array([ 31, 32, 19, 62, 43, 268, 121, 120, 8, 105], dtype=int32),\n", - " array([309.9547 , 310.37003, 310.69147, 310.72174, 310.75027, 310.7651 ,\n", - " 310.86166, 310.91055, 310.93866, 311.13025], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([310.39288, 310.51492, 310.76657, 310.83185, 310.998 , 311.06955,\n", - " 311.3103 , 311.3945 , 311.49496, 311.50388], dtype=float32)),\n", - " (array([ 31, 19, 62, 32, 43, 121, 204, 49, 268, 120], dtype=int32),\n", - " array([251.034 , 251.35036, 251.36156, 251.41571, 251.51518, 251.5228 ,\n", - " 251.81491, 251.84996, 251.92946, 251.97067], dtype=float32)),\n", - " (array([ 31, 19, 121, 43, 173, 32, 62, 100, 96, 29], dtype=int32),\n", - " array([294.2129 , 294.25903, 294.7758 , 294.779 , 294.83203, 294.9205 ,\n", - " 294.95865, 295.03278, 295.21616, 295.2689 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 62, 43, 268, 255, 103, 358], dtype=int32),\n", - " array([287.50858, 287.82477, 288.05826, 288.34937, 288.37088, 288.37427,\n", - " 288.5164 , 288.5676 , 288.66003, 288.7069 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 36, 8, 173, 240], dtype=int32),\n", - " array([343.65765, 343.70416, 343.89276, 343.92532, 344.0041 , 344.14536,\n", - " 344.2315 , 344.3194 , 344.5548 , 344.57956], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 8, 62, 149, 166, 121, 86], dtype=int32),\n", - " array([238.27538, 238.47679, 238.62265, 238.66264, 238.85207, 239.04405,\n", - " 239.081 , 239.1086 , 239.13249, 239.14513], dtype=float32)),\n", - " (array([ 43, 62, 31, 32, 19, 121, 100, 49, 149, 214], dtype=int32),\n", - " array([309.6256 , 309.77432, 309.84863, 309.93277, 310.12827, 310.4724 ,\n", - " 310.4784 , 310.54883, 310.62494, 310.65784], dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 121, 62, 268, 8, 173, 100], dtype=int32),\n", - " array([-11.14883 , -11.135824 , -11.100656 , -11.0959425, -10.589926 ,\n", - " -10.560493 , -10.358496 , -10.277635 , -10.261923 , -10.219689 ],\n", - " dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 62, 121, 204, 100, 49, 112], dtype=int32),\n", - " array([342.1617 , 342.2518 , 342.37195, 342.5719 , 342.60934, 342.97156,\n", - " 343.05237, 343.07806, 343.1003 , 343.13312], dtype=float32)),\n", - " (array([149, 262, 8, 0, 450, 735, 57, 153, 325, 835], dtype=int32),\n", - " array([291.3952 , 291.58344, 291.61844, 291.7327 , 291.7728 , 291.7857 ,\n", - " 291.80292, 291.88104, 291.90826, 291.9627 ], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 49, 86], dtype=int32),\n", - " array([308.6629 , 308.70493, 308.77167, 308.79907, 309.09406, 309.2825 ,\n", - " 309.50278, 309.5073 , 309.59637, 309.6056 ], dtype=float32)),\n", - " (array([ 43, 32, 279, 19, 31, 62, 258, 69, 204, 36], dtype=int32),\n", - " array([342.79376, 342.88315, 342.96536, 343.05652, 343.21683, 343.25122,\n", - " 343.27512, 343.29242, 343.47818, 343.49545], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 121, 268, 305, 100, 49], dtype=int32),\n", - " array([263.95203, 263.95724, 264.06174, 264.15656, 264.49722, 264.56787,\n", - " 264.7831 , 264.81805, 264.85205, 264.8899 ], dtype=float32)),\n", - " (array([ 31, 19, 103, 121, 32, 268, 120, 235, 62, 43], dtype=int32),\n", - " array([304.77887, 305.67038, 305.69534, 305.78156, 305.8517 , 305.86227,\n", - " 305.8696 , 305.9446 , 306.02246, 306.23358], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 121, 100, 268, 49, 173], dtype=int32),\n", - " array([285.78778, 285.89166, 285.93295, 285.9976 , 286.25592, 286.37717,\n", - " 286.66632, 286.68982, 286.76398, 286.79135], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 121, 268, 100, 49, 86], dtype=int32),\n", - " array([341.1428 , 341.2454 , 341.26138, 341.33563, 341.5653 , 341.8517 ,\n", - " 342.03473, 342.04343, 342.0657 , 342.20627], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 305, 29, 268, 42, 255], dtype=int32),\n", - " array([-11.48454 , -11.395604 , -11.208759 , -10.973148 , -10.661758 ,\n", - " -10.4371605, -10.408198 , -10.327231 , -10.307216 , -10.301584 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 268, 121, 166, 358, 173], dtype=int32),\n", - " array([337.2325 , 337.48584, 337.67468, 337.88406, 338.04434, 338.19308,\n", - " 338.2107 , 338.35446, 338.3612 , 338.4506 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 105, 358], dtype=int32),\n", - " array([341.74457, 341.76517, 342.27618, 342.33643, 342.476 , 342.62463,\n", - " 342.7585 , 342.76505, 342.91162, 343.0361 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 255, 29, 43, 62, 305, 268, 105], dtype=int32),\n", - " array([260.22137, 260.44785, 260.5002 , 260.64163, 260.87787, 260.90338,\n", - " 261.22714, 261.26846, 261.27097, 261.41263], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 62, 173, 206, 121, 268, 358], dtype=int32),\n", - " array([-17.763327, -17.698782, -17.495157, -17.088568, -16.996883,\n", - " -16.893726, -16.84771 , -16.843784, -16.636097, -16.58136 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 268, 103, 120, 29, 121, 86], dtype=int32),\n", - " array([53.359207, 53.7357 , 53.902878, 54.09575 , 54.348656, 54.404644,\n", - " 54.40834 , 54.452847, 54.486202, 54.536404], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 121, 62, 173, 164, 268, 100], dtype=int32),\n", - " array([278.93628, 279.10315, 279.3643 , 279.39157, 279.4668 , 279.5988 ,\n", - " 279.767 , 279.8694 , 279.98492, 280.0099 ], dtype=float32)),\n", - " (array([ 19, 31, 121, 62, 43, 173, 86, 32, 100, 240], dtype=int32),\n", - " array([320.32562, 320.49225, 320.54974, 320.61282, 320.89294, 320.90363,\n", - " 320.92236, 320.98785, 320.99963, 321.12177], dtype=float32)),\n", - " (array([ 31, 103, 121, 19, 235, 120, 268, 32, 427, 671], dtype=int32),\n", - " array([328.35245, 328.66718, 329.02066, 329.23483, 329.23947, 329.27643,\n", - " 329.29593, 329.40677, 329.5381 , 329.54492], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 305, 268, 164, 255, 29, 75], dtype=int32),\n", - " array([255.59294, 255.96443, 256.14178, 256.26993, 256.69574, 256.74728,\n", - " 256.7688 , 256.80414, 256.84137, 256.9127 ], dtype=float32)),\n", - " (array([121, 31, 19, 62, 43, 32, 173, 164, 49, 100], dtype=int32),\n", - " array([264.03766, 264.05295, 264.05984, 264.16226, 264.16476, 264.33493,\n", - " 264.5779 , 264.62375, 264.62778, 264.67984], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 305, 268, 188, 121, 258], dtype=int32),\n", - " array([342.0709 , 342.1489 , 342.35675, 342.44202, 342.58533, 342.77072,\n", - " 342.8552 , 342.86594, 342.8721 , 342.88464], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 164, 374, 49, 121, 487], dtype=int32),\n", - " array([295.33572, 295.5653 , 295.574 , 295.63666, 295.94995, 296.06577,\n", - " 296.12372, 296.1943 , 296.20615, 296.30356], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 268, 62, 358, 75, 258, 487], dtype=int32),\n", - " array([318.56668, 318.6115 , 318.82858, 319.00467, 319.14505, 319.21432,\n", - " 319.2202 , 319.3403 , 319.4197 , 319.4673 ], dtype=float32)),\n", - " (array([ 31, 121, 62, 43, 32, 19, 149, 8, 268, 384], dtype=int32),\n", - " array([341.2926 , 341.8248 , 341.84814, 341.95322, 342.0473 , 342.1127 ,\n", - " 342.20355, 342.32895, 342.34763, 342.45157], dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 62, 43, 268, 120, 173, 164], dtype=int32),\n", - " array([284.609 , 284.9727 , 285.0497 , 285.27374, 285.37445, 285.54816,\n", - " 285.71054, 285.74146, 285.80243, 285.89114], dtype=float32)),\n", - " (array([ 31, 19, 268, 173, 32, 43, 62, 121, 29, 358], dtype=int32),\n", - " array([-4.568763 , -4.5325108, -3.835782 , -3.73649 , -3.7269166,\n", - " -3.6454802, -3.4231503, -3.4121153, -3.401859 , -3.2904484],\n", - " dtype=float32)),\n", - " (array([ 31, 32, 19, 43, 62, 121, 173, 268, 29, 100], dtype=int32),\n", - " array([294.20316, 294.44458, 294.49643, 294.7739 , 294.9908 , 295.02417,\n", - " 295.11185, 295.25266, 295.4514 , 295.48163], dtype=float32)),\n", - " (array([ 31, 43, 19, 121, 268, 32, 62, 86, 358, 103], dtype=int32),\n", - " array([351.53467, 351.95938, 352.01068, 352.21344, 352.42587, 352.43475,\n", - " 352.43863, 352.4668 , 352.5556 , 352.57452], dtype=float32)),\n", - " (array([ 19, 43, 62, 31, 32, 173, 100, 268, 121, 149], dtype=int32),\n", - " array([-18.55561 , -18.457968, -18.363253, -18.250303, -18.073826,\n", - " -17.821415, -17.80263 , -17.796585, -17.793392, -17.748102],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 31, 121, 62, 43, 49, 186, 100, 120], dtype=int32),\n", - " array([323.33008, 323.3734 , 323.6866 , 323.82382, 323.82565, 323.9132 ,\n", - " 323.97067, 324.12558, 324.18567, 324.19006], dtype=float32)),\n", - " (array([ 19, 43, 173, 62, 358, 31, 32, 258, 279, 884], dtype=int32),\n", - " array([309.6789 , 310.07806, 310.3976 , 310.42377, 310.43207, 310.465 ,\n", - " 310.49817, 310.52087, 310.78394, 310.86823], dtype=float32)),\n", - " (array([ 31, 19, 43, 62, 32, 121, 255, 268, 120, 86], dtype=int32),\n", - " array([-16.502213, -16.351 , -16.234737, -16.05482 , -15.98046 ,\n", - " -15.883716, -15.629712, -15.572718, -15.516196, -15.514686],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 36, 62, 19, 279, 31, 121, 118, 69], dtype=int32),\n", - " array([310.43484, 310.5821 , 310.62714, 310.62802, 310.6412 , 310.68756,\n", - " 310.81992, 310.91626, 310.92096, 310.94424], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", - " array([342.974 , 343.11215, 343.2974 , 343.3711 , 343.50464, 343.67923,\n", - " 343.8834 , 343.9941 , 344.0963 , 344.0997 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 255, 121, 43, 268, 62, 100, 29], dtype=int32),\n", - " array([293.97476, 294.19623, 294.31085, 294.50137, 294.6499 , 294.81042,\n", - " 294.8138 , 294.95047, 294.98544, 295.05515], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 305, 166, 62, 121, 268, 204], dtype=int32),\n", - " array([288.87137, 288.974 , 289.02533, 289.16672, 289.71463, 289.7357 ,\n", - " 289.75266, 289.80713, 289.82523, 289.8616 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 62, 43, 86, 121, 268, 204, 29], dtype=int32),\n", - " array([291.09454, 291.14755, 291.258 , 291.45905, 291.46365, 291.6986 ,\n", - " 291.75534, 291.77515, 291.8849 , 292.05923], dtype=float32)),\n", - " (array([ 31, 121, 19, 32, 29, 623, 49, 105, 62, 268], dtype=int32),\n", - " array([239.1703 , 239.32706, 239.38129, 239.67157, 239.81223, 239.99385,\n", - " 239.99573, 239.99854, 240.08499, 240.1449 ], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 112, 121, 186, 204, 258], dtype=int32),\n", - " array([-19.203373, -19.07198 , -18.94647 , -18.829193, -18.68071 ,\n", - " -18.371681, -18.241812, -18.238682, -18.18572 , -18.177637],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 173, 100, 268, 86], dtype=int32),\n", - " array([-5.095121 , -5.0811954, -4.542622 , -4.4812193, -4.4686813,\n", - " -4.3046 , -4.3017554, -4.1008186, -4.0667377, -4.0414615],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 268, 100, 255, 29], dtype=int32),\n", - " array([240.94339, 241.08284, 241.10384, 241.20273, 241.59232, 241.6069 ,\n", - " 241.77856, 241.87619, 241.88518, 241.88893], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 103, 32, 120, 164, 268, 43], dtype=int32),\n", - " array([308.98654, 309.3287 , 309.39178, 309.49506, 309.7175 , 309.86893,\n", - " 309.98517, 309.99533, 310.01056, 310.03674], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 268, 305, 121, 112, 42], dtype=int32),\n", - " array([306.60638, 306.8104 , 307.02942, 307.06912, 307.33035, 307.50674,\n", - " 307.52014, 307.63626, 307.64737, 307.65756], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.8944 , 345.09198, 345.2742 , 345.3555 , 345.40195, 345.55933,\n", - " 345.7688 , 345.88153, 345.98135, 346.06445], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 268, 97, 173, 12, 29, 105], dtype=int32),\n", - " array([245.23692, 245.58582, 245.9251 , 245.94347, 246.13737, 246.3575 ,\n", - " 246.42638, 246.49547, 246.5117 , 246.59662], dtype=float32)),\n", - " (array([ 69, 19, 43, 32, 166, 31, 36, 118, 89, 279], dtype=int32),\n", - " array([251.44089, 251.5388 , 251.5665 , 251.59708, 251.62296, 251.66171,\n", - " 251.66936, 251.80127, 251.93073, 251.93768], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 121, 100, 86, 173, 268], dtype=int32),\n", - " array([343.19736, 343.25546, 343.29657, 343.31116, 343.51572, 343.76465,\n", - " 343.96796, 344.0325 , 344.0802 , 344.11102], dtype=float32)),\n", - " (array([ 19, 8, 31, 32, 121, 262, 173, 100, 62, 43], dtype=int32),\n", - " array([-5.7126856, -5.6494465, -5.5634694, -5.490323 , -5.445427 ,\n", - " -5.4278116, -5.360266 , -5.346415 , -5.252719 , -5.2395916],\n", - " dtype=float32)),\n", - " (array([ 43, 31, 19, 32, 62, 166, 120, 86, 121, 268], dtype=int32),\n", - " array([304.49838, 304.60864, 304.76355, 304.91272, 305.26102, 305.37756,\n", - " 305.48526, 305.51544, 305.54327, 305.54852], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 255, 121, 268, 173, 62, 105], dtype=int32),\n", - " array([332.05402, 332.35547, 332.3562 , 332.85416, 333.00577, 333.02948,\n", - " 333.2143 , 333.2305 , 333.303 , 333.31784], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 105], dtype=int32),\n", - " array([287.37894, 287.50305, 287.9024 , 287.9423 , 288.04437, 288.06732,\n", - " 288.36945, 288.4055 , 288.56866, 288.5846 ], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 121, 62, 173, 105, 100, 8], dtype=int32),\n", - " array([-7.432459 , -7.4023237, -6.9963536, -6.9093738, -6.9006357,\n", - " -6.845482 , -6.6145816, -6.3807535, -6.3080206, -6.211705 ],\n", - " dtype=float32)),\n", - " (array([ 31, 450, 518, 149, 3146, 262, 8, 62, 121, 19],\n", - " dtype=int32),\n", - " array([-7.5563455, -7.5102334, -7.3167133, -7.2882185, -7.2032266,\n", - " -7.1940336, -7.133639 , -7.1186666, -7.0955524, -6.927898 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 100, 29], dtype=int32),\n", - " array([342.60883, 342.81534, 342.94434, 342.96457, 343.16837, 343.2071 ,\n", - " 343.35193, 343.6244 , 343.65048, 343.6524 ], dtype=float32)),\n", - " (array([ 31, 12, 19, 21, 121, 24, 29, 173, 11, 2], dtype=int32),\n", - " array([5.547653 , 5.982525 , 6.0959864, 6.154112 , 6.3330364, 6.3660283,\n", - " 6.4661975, 6.7180567, 6.7465496, 6.7609787], dtype=float32)),\n", - " (array([ 19, 32, 43, 884, 31, 268, 62, 173, 636, 805], dtype=int32),\n", - " array([350.554 , 350.98764, 351.0723 , 351.08783, 351.2328 , 351.27267,\n", - " 351.3909 , 351.40683, 351.42548, 351.4549 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 149, 262, 62, 43, 8, 121, 552], dtype=int32),\n", - " array([321.0757 , 321.41873, 321.45984, 321.61578, 321.65466, 321.6554 ,\n", - " 321.70715, 321.91345, 321.99002, 322.04523], dtype=float32)),\n", - " (array([ 31, 121, 100, 19, 12, 32, 29, 43, 62, 86], dtype=int32),\n", - " array([269.16116, 269.5257 , 269.79166, 269.819 , 269.82602, 269.94995,\n", - " 269.99875, 270.03595, 270.0509 , 270.17642], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 173, 62, 121, 268, 29, 100], dtype=int32),\n", - " array([290.1401 , 290.45145, 290.63785, 290.846 , 291.03488, 291.04205,\n", - " 291.04373, 291.17728, 291.34778, 291.37375], dtype=float32)),\n", - " (array([ 19, 31, 121, 43, 32, 173, 12, 29, 268, 62], dtype=int32),\n", - " array([58.257057, 58.65163 , 58.84349 , 58.92871 , 59.09095 , 59.200607,\n", - " 59.266453, 59.345303, 59.495407, 59.524204], dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 31, 121, 49, 8, 166, 100], dtype=int32),\n", - " array([338.39044, 338.60587, 338.62296, 338.6683 , 338.79056, 338.86874,\n", - " 339.0117 , 339.26624, 339.30063, 339.35672], dtype=float32)),\n", - " (array([ 19, 31, 268, 164, 62, 43, 358, 103, 173, 32], dtype=int32),\n", - " array([262.58487, 262.6545 , 263.44113, 263.54263, 263.58505, 263.59915,\n", - " 263.65552, 263.68054, 263.70303, 263.75363], dtype=float32)),\n", - " (array([2181, 19, 43, 164, 31, 268, 75, 62, 117, 32],\n", - " dtype=int32),\n", - " array([226.9493 , 227.54704, 227.86424, 227.86642, 227.86781, 227.8865 ,\n", - " 227.99623, 228.0828 , 228.11992, 228.13261], dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 49, 36, 279, 31, 69, 112], dtype=int32),\n", - " array([341.6485 , 341.80267, 342.06287, 342.1126 , 342.43652, 342.45364,\n", - " 342.46945, 342.5529 , 342.5595 , 342.56598], dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", - " array([311.84796, 312.00244, 312.0829 , 312.13422, 312.1853 , 312.36942,\n", - " 312.54584, 312.76956, 312.81192, 312.82916], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 268, 130, 173, 75, 164], dtype=int32),\n", - " array([301.59302, 301.7444 , 302.11584, 302.221 , 302.33313, 302.3683 ,\n", - " 302.47525, 302.57733, 302.59845, 302.62924], dtype=float32)),\n", - " (array([ 31, 8, 262, 19, 32, 149, 43, 62, 121, 450], dtype=int32),\n", - " array([315.54672, 315.63876, 315.72702, 315.78513, 315.7888 , 315.82352,\n", - " 315.82822, 315.94617, 316.11276, 316.2316 ], dtype=float32)),\n", - " (array([ 19, 31, 121, 173, 12, 32, 29, 43, 100, 62], dtype=int32),\n", - " array([-2.889264 , -2.857441 , -2.3019035, -2.1709106, -2.0182004,\n", - " -2.0170076, -1.8352119, -1.831348 , -1.8078051, -1.734586 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 358, 29, 268, 105, 173, 62], dtype=int32),\n", - " array([305.072 , 305.1121 , 305.43958, 305.8369 , 305.84692, 305.93185,\n", - " 305.94632, 305.95657, 305.96445, 305.97073], dtype=float32)),\n", - " (array([ 19, 31, 29, 173, 32, 43, 121, 268, 255, 86], dtype=int32),\n", - " array([-6.3802543, -6.15933 , -5.5637207, -5.439764 , -5.398359 ,\n", - " -5.365966 , -5.327169 , -5.2888126, -5.15471 , -5.094646 ],\n", - " dtype=float32)),\n", - " (array([ 43, 32, 226, 528, 19, 974, 305, 166, 16, 69], dtype=int32),\n", - " array([-19.668242, -19.372046, -19.238176, -19.217402, -19.174326,\n", - " -19.100418, -19.036469, -19.020908, -18.995132, -18.93644 ],\n", - " dtype=float32)),\n", - " (array([ 43, 31, 358, 176, 19, 32, 589, 279, 204, 62], dtype=int32),\n", - " array([308.3695 , 308.49863, 308.57086, 308.67227, 308.78406, 308.81134,\n", - " 308.82843, 308.8357 , 308.85745, 308.9028 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 86, 121, 43, 32, 100, 240, 29], dtype=int32),\n", - " array([-9.601175 , -9.578853 , -9.2296 , -9.218114 , -9.2073965,\n", - " -9.183615 , -9.107821 , -8.762698 , -8.713669 , -8.713291 ],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 305, 62, 49, 121, 111, 268], dtype=int32),\n", - " array([293.0617 , 293.72794, 293.78482, 293.8996 , 293.9174 , 293.99716,\n", - " 294.05795, 294.27982, 294.36755, 294.36862], dtype=float32)),\n", - " (array([ 19, 31, 43, 2964, 358, 884, 636, 805, 62, 32],\n", - " dtype=int32),\n", - " array([-11.052489, -10.794892, -10.773016, -10.766544, -10.606944,\n", - " -10.501222, -10.390523, -10.340687, -10.339985, -10.331559],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", - " array([311.77924, 311.91257, 312.01352, 312.0533 , 312.11142, 312.29614,\n", - " 312.4577 , 312.68628, 312.7404 , 312.7641 ], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 121, 62, 100, 29, 173, 268], dtype=int32),\n", - " array([318.08197, 318.10242, 318.41632, 318.53076, 318.5899 , 318.7613 ,\n", - " 318.88425, 318.89056, 318.89328, 318.9135 ], dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 62, 305, 120, 121, 268, 111], dtype=int32),\n", - " array([342.00058, 342.22977, 342.36945, 342.60208, 342.7795 , 342.88486,\n", - " 342.92563, 343.0064 , 343.13535, 343.21445], dtype=float32)),\n", - " (array([255, 19, 31, 32, 86, 43, 120, 29, 268, 103], dtype=int32),\n", - " array([260.36838, 260.38568, 260.53552, 260.89362, 261.00327, 261.0515 ,\n", - " 261.20428, 261.2287 , 261.2419 , 261.43896], dtype=float32)),\n", - " (array([ 34, 19, 32, 31, 43, 1342, 62, 49, 121, 29],\n", - " dtype=int32),\n", - " array([339.60602, 339.7248 , 339.76935, 339.85065, 339.9012 , 339.92526,\n", - " 339.94467, 340.03897, 340.14996, 340.37146], dtype=float32)),\n", - " (array([ 32, 36, 43, 62, 19, 69, 449, 610, 8, 112], dtype=int32),\n", - " array([309.45944, 309.46063, 309.59656, 309.6136 , 309.72336, 309.77878,\n", - " 309.92505, 309.98724, 309.99564, 310.0074 ], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 8, 62, 121, 262, 149, 173], dtype=int32),\n", - " array([315.83636, 315.85812, 315.99908, 316.0639 , 316.1274 , 316.2354 ,\n", - " 316.26718, 316.42227, 316.47372, 316.485 ], dtype=float32)),\n", - " (array([ 19, 31, 268, 32, 43, 62, 121, 173, 358, 255], dtype=int32),\n", - " array([348.4165 , 348.52417, 349.29016, 349.2905 , 349.30084, 349.34302,\n", - " 349.41446, 349.42105, 349.50848, 349.5346 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 8, 149, 262, 43, 32, 121, 552], dtype=int32),\n", - " array([289.21597, 289.56995, 289.74356, 289.79907, 289.83044, 289.8364 ,\n", - " 289.84592, 289.89847, 290.032 , 290.21442], dtype=float32)),\n", - " (array([ 31, 19, 62, 43, 32, 121, 173, 100, 268, 86], dtype=int32),\n", - " array([311.6825 , 311.8511 , 311.93863, 311.98804, 312.04135, 312.21378,\n", - " 312.39114, 312.60446, 312.66852, 312.69647], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 62, 121, 268, 100, 49, 305], dtype=int32),\n", - " array([287.96027, 287.99707, 288.09222, 288.12997, 288.4873 , 288.5817 ,\n", - " 288.77457, 288.84506, 288.9047 , 288.9288 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 121, 62, 268, 173, 100, 105], dtype=int32),\n", - " array([290.30936, 290.45816, 290.79175, 290.85388, 291.0963 , 291.19775,\n", - " 291.30255, 291.40836, 291.57178, 291.65167], dtype=float32)),\n", - " (array([ 8, 62, 43, 149, 610, 32, 262, 279, 129, 36], dtype=int32),\n", - " array([316.0206 , 316.062 , 316.08347, 316.13348, 316.17386, 316.20584,\n", - " 316.23975, 316.24335, 316.26556, 316.27798], dtype=float32)),\n", - " (array([ 8, 32, 43, 31, 19, 62, 149, 86, 552, 347], dtype=int32),\n", - " array([312.72235, 312.74454, 312.77557, 312.939 , 312.98535, 313.14218,\n", - " 313.19333, 313.23883, 313.25974, 313.28384], dtype=float32)),\n", - " (array([ 31, 19, 103, 3318, 121, 43, 235, 173, 268, 12],\n", - " dtype=int32),\n", - " array([316.30136, 316.71924, 316.84506, 316.85983, 316.95398, 317.00595,\n", - " 317.0135 , 317.1464 , 317.14758, 317.21243], dtype=float32)),\n", - " (array([ 43, 69, 32, 382, 36, 279, 31, 62, 330, 19], dtype=int32),\n", - " array([336.7837 , 337.27213, 337.2966 , 337.3207 , 337.33444, 337.4042 ,\n", - " 337.42645, 337.43948, 337.5178 , 337.63284], dtype=float32)),\n", - " (array([ 31, 121, 19, 12, 32, 105, 535, 268, 43, 120], dtype=int32),\n", - " array([-9.293423 , -8.428325 , -8.386113 , -8.237335 , -8.164866 ,\n", - " -8.073025 , -8.015978 , -8.015145 , -7.963448 , -7.9146223],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 31, 100, 43, 121, 62, 86, 173, 29], dtype=int32),\n", - " array([316.03543, 316.0875 , 316.2393 , 316.32257, 316.3967 , 316.4398 ,\n", - " 316.53943, 316.59717, 316.6885 , 316.73395], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 32, 43, 120, 268, 103, 105], dtype=int32),\n", - " array([343.3387 , 344.06702, 344.1057 , 344.12833, 344.2447 , 344.29263,\n", - " 344.5485 , 344.55655, 344.69473, 344.74487], dtype=float32)),\n", - " (array([ 43, 32, 31, 19, 62, 121, 100, 305, 268, 206], dtype=int32),\n", - " array([341.88443, 341.982 , 342.10568, 342.12064, 342.32693, 342.60327,\n", - " 342.75314, 342.7669 , 342.79858, 342.8976 ], dtype=float32)),\n", - " (array([ 32, 43, 19, 31, 62, 100, 49, 121, 29, 255], dtype=int32),\n", - " array([310.80093, 310.96045, 311.0023 , 311.1856 , 311.23758, 311.54846,\n", - " 311.57355, 311.58038, 311.64764, 311.76315], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 166, 121, 8, 279, 120], dtype=int32),\n", - " array([343.47415, 343.59903, 343.7172 , 343.91235, 343.9546 , 344.08197,\n", - " 344.2582 , 344.2676 , 344.31052, 344.31125], dtype=float32)),\n", - " (array([ 32, 43, 31, 62, 19, 8, 149, 262, 121, 100], dtype=int32),\n", - " array([315.31952, 315.40558, 315.54608, 315.56342, 315.58334, 315.60324,\n", - " 315.66925, 315.876 , 315.96924, 316.0061 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 173, 43, 255, 268, 62, 121, 29], dtype=int32),\n", - " array([348.9122 , 349.04974, 349.2378 , 349.8211 , 349.83572, 349.9232 ,\n", - " 349.93332, 349.93613, 350.04193, 350.09467], dtype=float32)),\n", - " (array([ 31, 32, 62, 43, 149, 8, 358, 121, 19, 204], dtype=int32),\n", - " array([317.28693, 317.49088, 317.58295, 317.66425, 317.75284, 317.8083 ,\n", - " 317.8586 , 317.91684, 317.952 , 318.01294], dtype=float32)),\n", - " (array([ 43, 86, 19, 8, 31, 62, 279, 121, 32, 974], dtype=int32),\n", - " array([-9.263846 , -9.103899 , -9.0878105, -8.937294 , -8.886955 ,\n", - " -8.883041 , -8.858941 , -8.827693 , -8.774127 , -8.628111 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 121, 173, 62, 32, 100, 61, 268, 43], dtype=int32),\n", - " array([-9.676186, -9.54141 , -9.396741, -9.205064, -9.044446, -8.82444 ,\n", - " -8.694998, -8.639118, -8.617427, -8.556263], dtype=float32)),\n", - " (array([ 43, 32, 19, 62, 112, 86, 279, 31, 16, 186], dtype=int32),\n", - " array([307.51456, 307.54495, 307.72568, 307.8415 , 308.06662, 308.2694 ,\n", - " 308.31717, 308.38544, 308.4415 , 308.4508 ], dtype=float32)),\n", - " (array([ 96, 19, 31, 43, 121, 86, 32, 62, 173, 112], dtype=int32),\n", - " array([47.96091 , 48.27309 , 48.322277, 48.39021 , 48.596657, 48.648243,\n", - " 48.776752, 48.948055, 48.96972 , 49.07483 ], dtype=float32)),\n", - " (array([ 31, 19, 62, 173, 43, 121, 358, 32, 61, 268], dtype=int32),\n", - " array([204.96822, 205.36955, 205.48169, 205.71176, 205.7392 , 205.77728,\n", - " 205.86227, 205.87718, 206.02858, 206.08852], dtype=float32)),\n", - " (array([ 21, 12, 31, 19, 543, 121, 61, 173, 103, 105], dtype=int32),\n", - " array([353.6244 , 353.88678, 353.91107, 354.55862, 354.7007 , 354.85574,\n", - " 354.9695 , 355.15036, 355.37994, 355.43008], dtype=float32)),\n", - " (array([ 32, 62, 31, 43, 8, 49, 121, 19, 214, 240], dtype=int32),\n", - " array([337.73947, 337.75516, 337.8339 , 338.0181 , 338.06555, 338.23022,\n", - " 338.37 , 338.3929 , 338.45505, 338.46054], dtype=float32)),\n", - " (array([ 149, 57, 347, 325, 835, 43, 38, 3331, 8, 3146],\n", - " dtype=int32),\n", - " array([351.80896, 351.81143, 351.97366, 351.9798 , 351.99634, 352.0092 ,\n", - " 352.03357, 352.0737 , 352.13492, 352.25946], dtype=float32)),\n", - " (array([ 21, 19, 12, 31, 173, 29, 32, 121, 24, 43], dtype=int32),\n", - " array([313.65897, 315.4396 , 315.6556 , 315.86053, 316.2152 , 316.41238,\n", - " 316.55246, 316.555 , 316.58194, 316.68573], dtype=float32)),\n", - " (array([ 32, 43, 19, 305, 31, 29, 111, 268, 374, 206], dtype=int32),\n", - " array([322.85794, 323.07242, 323.11496, 323.4161 , 323.7297 , 323.8448 ,\n", - " 323.8678 , 323.87326, 323.96136, 324.0054 ], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 121, 62, 449, 36, 240, 69], dtype=int32),\n", - " array([300.77554, 300.99875, 301.05685, 301.2397 , 301.4737 , 301.49634,\n", - " 301.71524, 301.7206 , 301.7533 , 301.8178 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 62, 268, 255, 100, 29], dtype=int32),\n", - " array([240.78249, 240.92314, 240.93456, 241.03423, 241.43106, 241.43817,\n", - " 241.60599, 241.71246, 241.72049, 241.73433], dtype=float32)),\n", - " (array([ 31, 19, 121, 32, 62, 12, 100, 29, 43, 61], dtype=int32),\n", - " array([313.82245, 314.60043, 314.8061 , 314.89478, 315.23264, 315.3218 ,\n", - " 315.4298 , 315.47473, 315.54413, 315.56256], dtype=float32)),\n", - " (array([ 31, 43, 62, 32, 19, 358, 268, 121, 441, 164], dtype=int32),\n", - " array([342.0234 , 342.24054, 342.53653, 342.65573, 342.66263, 342.75848,\n", - " 342.76157, 342.79883, 342.9677 , 343.05243], dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 43, 32, 49, 100, 139, 164], dtype=int32),\n", - " array([348.48672, 348.72775, 348.80753, 348.8851 , 348.89285, 348.96744,\n", - " 349.1127 , 349.1894 , 349.24423, 349.26108], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([343.03366, 343.16077, 343.34872, 343.42975, 343.56696, 343.73987,\n", - " 343.93073, 344.03485, 344.15106, 344.1558 ], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 62, 449, 258, 121, 49, 350], dtype=int32),\n", - " array([323.6591 , 323.66876, 323.8467 , 324.2279 , 324.25864, 324.58365,\n", - " 324.6064 , 324.62784, 324.6301 , 324.63162], dtype=float32)),\n", - " (array([ 43, 19, 32, 149, 62, 31, 279, 69, 173, 121], dtype=int32),\n", - " array([345.94846, 345.95123, 346.18982, 346.19083, 346.2606 , 346.2693 ,\n", - " 346.568 , 346.5894 , 346.66135, 346.739 ], dtype=float32)),\n", - " (array([ 8, 32, 149, 62, 43, 450, 262, 31, 49, 735], dtype=int32),\n", - " array([256.2703 , 256.44812, 256.53586, 256.74167, 256.80997, 256.83362,\n", - " 256.9235 , 256.94788, 256.98364, 257.0118 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 49, 62, 121, 43, 384, 268, 392], dtype=int32),\n", - " array([321.22964, 321.28946, 321.39627, 321.49075, 321.50916, 321.53836,\n", - " 321.6192 , 321.64346, 321.70844, 321.75912], dtype=float32)),\n", - " (array([ 19, 31, 173, 32, 43, 121, 62, 100, 86, 268], dtype=int32),\n", - " array([-0.28826267, -0.06532145, 0.3582903 , 0.36676073, 0.3837734 ,\n", - " 0.46872783, 0.4810531 , 0.62910014, 0.7345186 , 0.7688154 ],\n", - " dtype=float32)),\n", - " (array([ 43, 279, 32, 69, 36, 19, 62, 974, 31, 449], dtype=int32),\n", - " array([308.0308 , 308.35928, 308.47665, 308.62778, 308.65277, 308.67145,\n", - " 308.8749 , 308.8921 , 308.9867 , 309.0298 ], dtype=float32)),\n", - " (array([ 31, 19, 43, 62, 32, 255, 121, 86, 120, 8], dtype=int32),\n", - " array([319.63766, 320.09393, 320.12192, 320.1773 , 320.25308, 320.25473,\n", - " 320.43152, 320.50406, 320.5989 , 320.72818], dtype=float32)),\n", - " (array([ 31, 43, 32, 121, 19, 62, 49, 29, 100, 164], dtype=int32),\n", - " array([233.4243 , 233.7595 , 233.81706, 233.88116, 233.9344 , 234.0423 ,\n", - " 234.15884, 234.32816, 234.36333, 234.38605], dtype=float32)),\n", - " (array([ 19, 31, 2964, 358, 173, 636, 1120, 62, 39, 884],\n", - " dtype=int32),\n", - " array([-8.72796 , -8.477619 , -8.294453 , -8.248064 , -8.095911 ,\n", - " -8.010352 , -7.987134 , -7.970608 , -7.9154773, -7.903307 ],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 62, 8, 31, 121, 240, 100, 305], dtype=int32),\n", - " array([291.87738, 291.91418, 292.2438 , 292.40665, 292.44342, 292.4457 ,\n", - " 292.5035 , 292.79794, 292.8258 , 292.82718], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 121, 100, 62, 173, 86, 268], dtype=int32),\n", - " array([-8.934562 , -8.881013 , -8.576623 , -8.541348 , -8.390564 ,\n", - " -8.317347 , -8.3050785, -8.172027 , -8.164956 , -8.118824 ],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 121, 62, 43, 164, 67, 26, 103], dtype=int32),\n", - " array([289.23544, 290.15768, 290.2187 , 290.2313 , 290.23965, 290.28528,\n", - " 290.37408, 290.38663, 290.51068, 290.65753], dtype=float32)),\n", - " (array([ 36, 43, 32, 62, 19, 31, 69, 449, 240, 16], dtype=int32),\n", - " array([334.4823 , 334.6571 , 334.73218, 334.78943, 334.84525, 334.89734,\n", - " 335.09927, 335.24484, 335.2916 , 335.35037], dtype=float32)),\n", - " (array([2181, 2676, 2953, 1584, 884, 3590, 3209, 665, 1959, 2113],\n", - " dtype=int32),\n", - " array([307.5883 , 308.81317, 308.90753, 309.11356, 309.1285 , 309.1489 ,\n", - " 309.28903, 309.42285, 309.51862, 309.7406 ], dtype=float32)),\n", - " (array([ 31, 43, 32, 62, 121, 86, 19, 173, 268, 100], dtype=int32),\n", - " array([349.0459 , 349.49622, 349.5976 , 349.61066, 349.62006, 349.68793,\n", - " 349.69485, 349.9983 , 350.07812, 350.09158], dtype=float32)),\n", - " (array([ 32, 43, 19, 8, 62, 204, 166, 31, 149, 449], dtype=int32),\n", - " array([211.0054 , 211.32883, 211.46419, 211.54022, 211.736 , 211.76773,\n", - " 211.77206, 211.77232, 211.79556, 211.80998], dtype=float32)),\n", - " (array([149, 62, 43, 31, 32, 450, 552, 262, 19, 121], dtype=int32),\n", - " array([338.12436, 338.4792 , 338.55847, 338.64368, 338.7438 , 338.78503,\n", - " 338.7949 , 338.83014, 338.98648, 338.99924], dtype=float32)),\n", - " (array([ 43, 32, 31, 305, 19, 120, 49, 62, 1145, 42],\n", - " dtype=int32),\n", - " array([301.79224, 301.82645, 302.2941 , 302.3314 , 302.63702, 302.7346 ,\n", - " 302.77237, 302.8122 , 302.86105, 302.90433], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 121, 86, 173, 29, 100, 62], dtype=int32),\n", - " array([-3.7455661, -3.5058565, -3.378895 , -3.083093 , -3.0261757,\n", - " -2.8962672, -2.7405283, -2.6841812, -2.6584632, -2.6042924],\n", - " dtype=float32)),\n", - " (array([ 19, 32, 31, 121, 62, 43, 358, 8, 268, 49], dtype=int32),\n", - " array([345.23105, 345.34973, 345.352 , 345.4656 , 345.4969 , 345.49823,\n", - " 345.7349 , 345.7673 , 345.8411 , 345.9589 ], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 120, 100], dtype=int32),\n", - " array([310.334 , 310.4527 , 310.69635, 310.76443, 310.91458, 311.01938,\n", - " 311.2425 , 311.34207, 311.42963, 311.44357], dtype=float32)),\n", - " (array([ 19, 31, 62, 32, 121, 43, 173, 268, 105, 103], dtype=int32),\n", - " array([298.10413, 298.3428 , 298.93362, 298.99365, 298.99472, 299.0177 ,\n", - " 299.14453, 299.20395, 299.41028, 299.44534], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 62, 121, 149, 8, 173, 86], dtype=int32),\n", - " array([310.54572, 310.715 , 310.81372, 310.84702, 311.08026, 311.4198 ,\n", - " 311.51077, 311.53085, 311.59818, 311.6255 ], dtype=float32)),\n", - " (array([ 19, 31, 121, 32, 29, 43, 100, 62, 173, 86], dtype=int32),\n", - " array([350.98785, 351.70575, 351.82846, 351.92685, 351.94547, 351.99237,\n", - " 352.01846, 352.08197, 352.09503, 352.17386], dtype=float32)),\n", - " (array([ 19, 43, 31, 32, 173, 62, 86, 255, 268, 121], dtype=int32),\n", - " array([348.07153, 348.28183, 348.50174, 348.64114, 348.78644, 348.79187,\n", - " 349.04266, 349.04465, 349.0592 , 349.06927], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 149, 62, 262, 255, 121, 100], dtype=int32),\n", - " array([319.1982 , 319.5954 , 319.61157, 319.78308, 319.97806, 320.00876,\n", - " 320.01703, 320.10095, 320.13397, 320.19705], dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 100, 268, 86, 49], dtype=int32),\n", - " array([308.81808, 308.8686 , 308.9243 , 308.9482 , 309.24347, 309.42706,\n", - " 309.64746, 309.6636 , 309.7493 , 309.7499 ], dtype=float32)),\n", - " (array([ 43, 19, 32, 31, 62, 112, 120, 121, 268, 204], dtype=int32),\n", - " array([342.47653, 342.63837, 342.71918, 342.97488, 343.2606 , 343.53824,\n", - " 343.55115, 343.62396, 343.64276, 343.69244], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 173, 121, 62, 100, 255, 268], dtype=int32),\n", - " array([-12.540138, -12.137171, -12.049283, -11.839132, -11.656746,\n", - " -11.64068 , -11.638612, -11.303928, -11.260633, -11.251936],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 62, 121, 173, 8, 347, 149], dtype=int32),\n", - " array([-10.065559, -9.88775 , -9.813306, -9.638669, -9.538965,\n", - " -9.379344, -9.280427, -9.243657, -9.152026, -9.105689],\n", - " dtype=float32)),\n", - " (array([ 31, 121, 19, 62, 164, 103, 43, 32, 268, 173], dtype=int32),\n", - " array([-11.971802 , -11.366394 , -11.242047 , -11.026398 , -10.853961 ,\n", - " -10.830669 , -10.797222 , -10.7918415, -10.766682 , -10.726046 ],\n", - " dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 62, 8, 121, 268, 173, 120], dtype=int32),\n", - " array([-19.76228 , -19.501608, -19.460285, -19.223957, -19.216587,\n", - " -19.053604, -19.011719, -18.901064, -18.745901, -18.609486],\n", - " dtype=float32)),\n", - " (array([ 32, 19, 43, 31, 62, 121, 268, 100, 49, 86], dtype=int32),\n", - " array([308.63876, 308.67154, 308.73718, 308.75357, 309.05753, 309.24628,\n", - " 309.46777, 309.47766, 309.5633 , 309.5821 ], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 62, 8, 100, 121, 173, 268], dtype=int32),\n", - " array([326.4597 , 326.64896, 326.72073, 326.79077, 327.05215, 327.1703 ,\n", - " 327.2165 , 327.31693, 327.40082, 327.45242], dtype=float32)),\n", - " (array([ 31, 121, 62, 19, 32, 43, 103, 105, 49, 268], dtype=int32),\n", - " array([290.10074, 290.8684 , 290.92242, 291.06454, 291.10657, 291.11957,\n", - " 291.45142, 291.51614, 291.5271 , 291.5313 ], dtype=float32)),\n", - " (array([ 19, 31, 43, 62, 32, 121, 273, 164, 173, 8], dtype=int32),\n", - " array([288.896 , 288.95532, 289.16782, 289.21255, 289.36972, 289.64258,\n", - " 289.66537, 289.69272, 289.92862, 289.9483 ], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 305, 29, 111, 121, 206, 268], dtype=int32),\n", - " array([295.3294 , 295.46652, 295.56708, 295.62234, 295.72226, 295.9829 ,\n", - " 295.99542, 296.04922, 296.08768, 296.1316 ], dtype=float32)),\n", - " (array([ 32, 19, 31, 43, 62, 121, 100, 268, 49, 173], dtype=int32),\n", - " array([237.21964, 237.30243, 237.34221, 237.34872, 237.63086, 237.89078,\n", - " 238.06018, 238.08797, 238.16368, 238.24571], dtype=float32)),\n", - " (array([ 31, 19, 43, 32, 62, 121, 173, 268, 100, 86], dtype=int32),\n", - " array([344.96542, 345.16913, 345.3167 , 345.41116, 345.46573, 345.62463,\n", - " 345.84436, 345.95703, 346.0414 , 346.10632], dtype=float32)),\n", - " (array([ 19, 32, 43, 31, 62, 121, 204, 305, 86, 279], dtype=int32),\n", - " array([293.34134, 293.5153 , 293.5335 , 293.8237 , 294.19867, 294.35904,\n", - " 294.38388, 294.38916, 294.4591 , 294.47192], dtype=float32)),\n", - " (array([ 31, 19, 32, 29, 268, 121, 24, 62, 100, 105], dtype=int32),\n", - " array([327.68845, 327.79 , 328.07837, 328.20386, 328.44595, 328.5652 ,\n", - " 328.58017, 328.7822 , 328.81186, 328.84622], dtype=float32)),\n", - " (array([ 43, 32, 19, 31, 62, 279, 305, 16, 554, 173], dtype=int32),\n", - " array([341.12244, 341.29324, 341.53418, 341.66843, 341.82727, 341.9335 ,\n", - " 342.04108, 342.10278, 342.12744, 342.1919 ], dtype=float32)),\n", - " (array([ 19, 382, 43, 31, 559, 2314, 36, 69, 32, 370],\n", - " dtype=int32),\n", - " array([-8.544027, -8.379682, -8.359372, -8.356681, -8.344806, -8.336197,\n", - " -8.321445, -8.274008, -8.233007, -8.205231], dtype=float32)),\n", - " (array([ 19, 31, 32, 43, 268, 606, 120, 105, 29, 121], dtype=int32),\n", - " array([258.2543 , 258.27756, 258.63324, 258.785 , 259.0118 , 259.17218,\n", - " 259.2521 , 259.27142, 259.28043, 259.2985 ], dtype=float32)),\n", - " (array([ 19, 32, 31, 43, 121, 173, 62, 268, 204, 258], dtype=int32),\n", - " array([-18.5358 , -18.301643, -17.97004 , -17.85837 , -17.834467,\n", - " -17.750002, -17.688705, -17.603228, -17.533812, -17.531893],\n", - " dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 120], dtype=int32),\n", - " array([322.3767 , 322.4656 , 322.72333, 322.848 , 323.02774, 323.09827,\n", - " 323.25403, 323.424 , 323.55148, 323.57767], dtype=float32)),\n", - " (array([ 32, 31, 43, 19, 62, 112, 120, 268, 121, 49], dtype=int32),\n", - " array([342.02606, 342.2531 , 342.47992, 342.4926 , 342.55563, 342.63525,\n", - " 342.71747, 342.79602, 342.83182, 342.94263], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 43, 32, 173, 100, 268, 86], dtype=int32),\n", - " array([-4.250471 , -4.1314707, -3.6435182, -3.600346 , -3.55154 ,\n", - " -3.5489879, -3.4938495, -3.3561318, -3.1982527, -3.1129708],\n", - " dtype=float32)),\n", - " (array([ 43, 31, 32, 255, 19, 86, 305, 62, 29, 121], dtype=int32),\n", - " array([344.42413, 344.57016, 344.6782 , 344.7684 , 344.8865 , 344.9333 ,\n", - " 345.12305, 345.14386, 345.35318, 345.37628], dtype=float32)),\n", - " (array([ 31, 19, 32, 43, 62, 121, 268, 173, 100, 105], dtype=int32),\n", - " array([298.18875, 298.30505, 298.53882, 298.7262 , 298.87653, 298.91403,\n", - " 299.10852, 299.29218, 299.39276, 299.3932 ], dtype=float32)),\n", - " (array([ 31, 19, 121, 62, 173, 32, 2314, 43, 36, 382],\n", - " dtype=int32),\n", - " array([318.865 , 319.396 , 319.43295, 319.58615, 319.60837, 319.6555 ,\n", - " 319.7711 , 319.79584, 320.05832, 320.21387], dtype=float32)),\n", - " (array([ 19, 31, 43, 32, 268, 173, 358, 121, 62, 97], dtype=int32),\n", - " array([346.16516, 346.23053, 346.68127, 346.75272, 346.86407, 347.0499 ,\n", - " 347.11044, 347.12326, 347.14447, 347.16522], dtype=float32)),\n", - " (array([ 32, 19, 31, 29, 43, 305, 186, 111, 255, 121], dtype=int32),\n", - " array([294.34894, 294.67987, 294.75375, 294.936 , 295.03058, 295.06128,\n", - " 295.13828, 295.2355 , 295.32452, 295.38873], dtype=float32)),\n", - " (array([ 31, 19, 12, 43, 32, 121, 62, 173, 100, 268], dtype=int32),\n", - " array([316.84103, 316.90164, 317.0408 , 317.26376, 317.33588, 317.34082,\n", - " 317.5151 , 317.5332 , 317.69632, 317.70505], dtype=float32)),\n", - " (array([ 31, 43, 19, 32, 62, 255, 86, 121, 268, 49], dtype=int32),\n", - " array([-19.382977, -19.33198 , -19.223627, -19.067013, -18.919756,\n", - " -18.868162, -18.770218, -18.512556, -18.481125, -18.430311],\n", - " dtype=float32)),\n", - " (array([ 43, 19, 62, 32, 31, 268, 8, 121, 358, 206], dtype=int32),\n", - " array([341.82053, 342.0832 , 342.16116, 342.1844 , 342.1869 , 342.64536,\n", - " 342.6651 , 342.68823, 342.69305, 342.7631 ], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 100, 86, 121, 279, 173], dtype=int32),\n", - " array([349.07028, 349.1043 , 349.3774 , 349.5384 , 349.6618 , 349.88547,\n", - " 349.9679 , 349.97458, 350.02924, 350.09366], dtype=float32)),\n", - " (array([ 43, 32, 31, 62, 19, 112, 86, 305, 120, 121], dtype=int32),\n", - " array([227.76135, 227.919 , 228.14313, 228.22289, 228.23537, 228.49525,\n", - " 228.50725, 228.5122 , 228.59908, 228.63554], dtype=float32)),\n", - " (array([ 19, 31, 62, 121, 32, 43, 173, 268, 100, 49], dtype=int32),\n", - " array([-10.240508, -10.232598, -9.979655, -9.906664, -9.827645,\n", - " -9.691288, -9.585058, -9.347253, -9.33783 , -9.272427],\n", - " dtype=float32)),\n", - " (array([ 43, 62, 32, 16, 19, 164, 36, 554, 279, 49], dtype=int32),\n", - " array([303.90997, 303.96088, 304.15942, 304.1783 , 304.20358, 304.2933 ,\n", - " 304.40802, 304.4497 , 304.51547, 304.55966], dtype=float32)),\n", - " (array([ 31, 19, 358, 62, 176, 173, 636, 268, 121, 884], dtype=int32),\n", - " array([345.50827, 345.61258, 345.7802 , 346.08682, 346.16553, 346.2851 ,\n", - " 346.3079 , 346.35077, 346.3635 , 346.3904 ], dtype=float32)),\n", - " (array([ 19, 43, 32, 31, 62, 173, 268, 121, 487, 86], dtype=int32),\n", - " array([315.2453 , 315.32028, 315.7209 , 315.74374, 315.90012, 316.01874,\n", - " 316.1155 , 316.1264 , 316.17056, 316.18793], dtype=float32)),\n", - " (array([ 31, 32, 43, 19, 62, 86, 121, 120, 255, 186], dtype=int32),\n", - " array([-14.443677 , -14.09697 , -13.9354105, -13.908954 , -13.638619 ,\n", - " -13.529042 , -13.515282 , -13.379453 , -13.273871 , -13.268393 ],\n", - " dtype=float32)),\n", - " ...]" - ] - }, - "execution_count": 85, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "nbrs" - ] - }, { "cell_type": "code", "execution_count": 86, @@ -7684,19 +4402,11 @@ "source": [ "df_r.to_csv('nmslib.csv.gz', index=False, compression='gzip')" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cd71e28b", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -7710,7 +4420,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.8.8" } }, "nbformat": 4, From f40b1b43db44cea0496911e6277c0b017c6f53d1 Mon Sep 17 00:00:00 2001 From: Shakirov Renat Date: Wed, 14 Dec 2022 01:10:56 +0300 Subject: [PATCH 08/12] update ALS and ANN --- ...0\275\320\270\320\265 \342\204\2264.ipynb" | 3072 +++-------------- 1 file changed, 525 insertions(+), 2547 deletions(-) diff --git "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" index 1b381cbb..3f4c842e 100644 --- "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" +++ "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" @@ -1,56 +1,72 @@ { "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Домашнее задание\n", + "\n", + "Домашнее задание состоит из нескольких блоков.\n", + "\n", + "\n", + "## Эксперименты в ipynb ноутбуках (15 баллов)\n", + "- Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", + " - Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)\n", + "- Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", + " - Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д\n", + "- Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**\n", + "- Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", + "\n", + "Примечание: за невоспроизводимый код в ноутбуках (например, нарушен порядок выполнения ячеек, вызываются переменные, которые нигде не были объявлены ранее и.т.п) будут штрафы на усмотрение проверяющего.\n", + "\n", + "\n", + "## Реализация итоговой модели в сервисе (10 баллов)\n", + "- Пробитие бейзлайна $MAP@10 \\geq 0.074921$ **(6 баллов)**\n", + "- Код сервиса соответствует критериям читаемости и воспроизводимости **(4 балла)**" + ], + "metadata": { + "collapsed": false + } + }, { "cell_type": "code", "execution_count": 1, - "id": "7780d9a2", - "metadata": {}, "outputs": [], "source": [ "import warnings\n", "warnings.filterwarnings('ignore')" - ] + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 246, "id": "e42a5585", "metadata": {}, "outputs": [], "source": [ "import os\n", + "import time\n", + "import random\n", + "from pathlib import Path\n", "\n", - "import pandas as pd\n", "import numpy as np\n", + "import optuna\n", + "import pandas as pd\n", "\n", + "import nmslib\n", "from implicit.als import AlternatingLeastSquares\n", - "\n", - "from rectools.metrics import Precision, Recall, MAP, calc_metrics\n", - "from rectools.models import PopularModel, RandomModel, ImplicitALSWrapperModel\n", + "from lightfm import LightFM\n", "from rectools import Columns\n", "from rectools.dataset import Dataset\n", - "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "\n", - "import matplotlib.pyplot as plt\n", - "from pathlib import Path\n", - "import typing as tp\n", - "from tqdm import tqdm\n", - "\n", - "from lightfm import LightFM\n", - "\n", - "from implicit.bpr import BayesianPersonalizedRanking\n", - "\n", - "from implicit.lmf import LogisticMatrixFactorization\n", - "\n", - "import optuna" + "from rectools.metrics import MAP, Precision, Recall, calc_metrics\n", + "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 180, "id": "8cd36e1a", "metadata": {}, "outputs": [], @@ -60,17 +76,17 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 185, "id": "4cb722c3", "metadata": {}, "outputs": [], "source": [ - "DATA_PATH = Path(\"../data\")" + "DATA_PATH = Path(\"../data/kion_train/\")" ] }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 186, "id": "8195e56b", "metadata": {}, "outputs": [ @@ -78,8 +94,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 2.69 s, sys: 212 ms, total: 2.9 s\n", - "Wall time: 3.2 s\n" + "CPU times: user 2.61 s, sys: 924 ms, total: 3.53 s\n", + "Wall time: 5.74 s\n" ] } ], @@ -92,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 187, "id": "01c2bdef", "metadata": {}, "outputs": [], @@ -110,176 +126,35 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 188, "id": "0a3b4b12", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
..................
5476246648596122252021-08-13760.0
547624754686296732021-04-13230849.0
5476248697262152972021-08-201830763.0
5476249384202161972021-04-196203100.0
547625031970944362021-08-15392145.0
\n", - "

5476251 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct\n", - "0 176549 9506 2021-05-11 4250 72.0\n", - "1 699317 1659 2021-05-29 8317 100.0\n", - "2 656683 7107 2021-05-09 10 0.0\n", - "3 864613 7638 2021-07-05 14483 100.0\n", - "4 964868 9506 2021-04-30 6725 100.0\n", - "... ... ... ... ... ...\n", - "5476246 648596 12225 2021-08-13 76 0.0\n", - "5476247 546862 9673 2021-04-13 2308 49.0\n", - "5476248 697262 15297 2021-08-20 18307 63.0\n", - "5476249 384202 16197 2021-04-19 6203 100.0\n", - "5476250 319709 4436 2021-08-15 3921 45.0\n", - "\n", - "[5476251 rows x 5 columns]" - ] + "text/plain": " user_id item_id last_watch_dt total_dur watched_pct\n0 176549 9506 2021-05-11 4250 72.0\n1 699317 1659 2021-05-29 8317 100.0\n2 656683 7107 2021-05-09 10 0.0\n3 864613 7638 2021-07-05 14483 100.0\n4 964868 9506 2021-04-30 6725 100.0", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
\n
" }, - "execution_count": 95, + "execution_count": 188, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "interactions" + "interactions.head()" ] }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 189, "id": "260b1c48", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "user_id int64\n", - "item_id int64\n", - "last_watch_dt object\n", - "total_dur int64\n", - "watched_pct float64\n", - "dtype: object" - ] + "text/plain": "user_id int64\nitem_id int64\nlast_watch_dt object\ntotal_dur int64\nwatched_pct float64\ndtype: object" }, - "execution_count": 96, + "execution_count": 189, "metadata": {}, "output_type": "execute_result" } @@ -290,22 +165,15 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 190, "id": "fe2dbc06", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "user_id 0\n", - "item_id 0\n", - "last_watch_dt 0\n", - "total_dur 0\n", - "watched_pct 828\n", - "dtype: int64" - ] + "text/plain": "user_id 0\nitem_id 0\nlast_watch_dt 0\ntotal_dur 0\nwatched_pct 828\ndtype: int64" }, - "execution_count": 97, + "execution_count": 190, "metadata": {}, "output_type": "execute_result" } @@ -316,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 191, "id": "71f61e81", "metadata": {}, "outputs": [], @@ -327,7 +195,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 192, "id": "39646cb5", "metadata": {}, "outputs": [], @@ -337,20 +205,16 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 193, "id": "f98ae95d", "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" + "text/plain": "
", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGsCAYAAAAPJKchAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAsU0lEQVR4nO3df3RU5YHG8WcmmUxIMSBEEojB4K+CC4RIShqpp7AmRJYTl3XtWqGSRqUHJbvoHH8QFUiWYigVFt1FOVqBdRWh9Aj+YoFsMCAlggmklaogBY0LJIAcGEjsMGbu/uHJ0OwEyMS585rw/ZzjOZ2b9773nYfAPL33zozDsixLAAAAhjhNLwAAAFzaKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAqC5VRrZu3aqCggINGDBADodD69atC3sOy7L09NNP6/rrr5fb7VZqaqrmzZsX+cUCAIAOiTW9gHA0NTUpIyND99xzj26//fZOzTFjxgxt2rRJTz/9tIYNG6YTJ07oxIkTEV4pAADoKEdX/aI8h8OhtWvXauLEicFtPp9PTzzxhF577TWdPHlSQ4cO1a9+9SuNGTNGkvTxxx9r+PDh2rNnj77//e+bWTgAAGijS12muZji4mJVV1dr1apV+uMf/6if/OQnuvXWW/Xpp59Kkt566y1dffXVevvttzVo0CClp6frvvvu48wIAAAGdZsyUl9fr+XLl2vNmjW6+eabdc011+jhhx/Wj370Iy1fvlySdODAAX3++edas2aNXn75Za1YsUK1tbW64447DK8eAIBLV5e6Z+RCPvzwQ7W0tOj6669vs93n86lv376SpEAgIJ/Pp5dffjk47qWXXtLIkSO1d+9eLt0AAGBAtykjZ86cUUxMjGpraxUTE9PmZz179pQk9e/fX7GxsW0Ky5AhQyR9c2aFMgIAQPR1mzKSmZmplpYWHT16VDfffHO7Y0aPHq2vv/5af/7zn3XNNddIkvbt2ydJuuqqq6K2VgAAcE6XejfNmTNntH//fknflI9FixZp7Nix6tOnjwYOHKif/exn+v3vf6+FCxcqMzNTx44dU2VlpYYPH64JEyYoEAjoBz/4gXr27KnFixcrEAho+vTpSkxM1KZNmww/OwAALk1dqoxUVVVp7NixIdsLCwu1YsUK+f1+/fKXv9TLL7+sQ4cOKSkpST/84Q9VVlamYcOGSZIOHz6sf/7nf9amTZv0ve99T+PHj9fChQvVp0+faD8dAACgLlZGAABA99Nt3toLAAC6JsoIAAAwqku8myYQCOjw4cO67LLL5HA4TC8HAAB0gGVZOn36tAYMGCCn8/znP7pEGTl8+LDS0tJMLwMAAHTCF198oSuvvPK8P+8SZeSyyy6T9M2TSUxMjNi8fr9fmzZt0rhx4+RyuSI2L0KRdXSQc3SQc3SQc3TYmbPX61VaWlrwdfx8ukQZab00k5iYGPEykpCQoMTERH7RbUbW0UHO0UHO0UHO0RGNnC92iwU3sAIAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwKhY0wsAAAAdkz7znYjP6Y6xtGBUxKcNS9hnRrZu3aqCggINGDBADodD69atu+g+Pp9PTzzxhK666iq53W6lp6dr2bJlnVkvAADoZsI+M9LU1KSMjAzdc889uv322zu0zz/90z+psbFRL730kq699lodOXJEgUAg7MUCAIDuJ+wyMn78eI0fP77D4zds2KAtW7bowIED6tOnjyQpPT093MMCAIBuyvZ7Rt58801lZWVpwYIF+q//+i9973vf02233aa5c+eqR48e7e7j8/nk8/mCj71eryTJ7/fL7/dHbG2tc0VyTrSPrKODnKODnKODnEO5Y6zIz+n8Zk47cu7onLaXkQMHDmjbtm2Kj4/X2rVrdfz4cT3wwAP68ssvtXz58nb3KS8vV1lZWcj2TZs2KSEhIeJrrKioiPicaB9ZRwc5Rwc5Rwc5n2PnjaZ25Nzc3NyhcQ7LsjpdsxwOh9auXauJEyeed8y4ceP03nvvqaGhQb169ZIkvf7667rjjjvU1NTU7tmR9s6MpKWl6fjx40pMTOzsckP4/X5VVFQoLy9PLpcrYvMiFFlHBzlHBzlHBzmHGlq6MeJzup2W5mYFbMnZ6/UqKSlJp06duuDrt+1nRvr376/U1NRgEZGkIUOGyLIs/e///q+uu+66kH3cbrfcbnfIdpfLZcsvpF3zIhRZRwc5Rwc5Rwc5n+Nrcdg2tx05d3Q+2z/0bPTo0Tp8+LDOnDkT3LZv3z45nU5deeWVdh8eAAB8x4VdRs6cOaO6ujrV1dVJkg4ePKi6ujrV19dLkkpKSjRlypTg+EmTJqlv374qKirSRx99pK1bt+qRRx7RPffcc94bWAEAwKUj7DJSU1OjzMxMZWZmSpI8Ho8yMzM1e/ZsSdKRI0eCxUSSevbsqYqKCp08eVJZWVmaPHmyCgoK9Oyzz0boKQAAgK4s7HtGxowZowvd87pixYqQbYMHD+ZuaAAA0C6+KA8AABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYFXYZ2bp1qwoKCjRgwAA5HA6tW7euw/v+/ve/V2xsrEaMGBHuYQEAQDcVdhlpampSRkaGlixZEtZ+J0+e1JQpU3TLLbeEe0gAANCNxYa7w/jx4zV+/PiwDzRt2jRNmjRJMTExYZ1NAQAA3VvYZaQzli9frgMHDuiVV17RL3/5y4uO9/l88vl8wcder1eS5Pf75ff7I7au1rkiOSfaR9bRQc7RQc7RQc6h3DFW5Od0fjOnHTl3dE7by8inn36qmTNn6r333lNsbMcOV15errKyspDtmzZtUkJCQqSXqIqKiojPifaRdXSQc3SQc3SQ8zkLRtk3tx05Nzc3d2icrWWkpaVFkyZNUllZma6//voO71dSUiKPxxN87PV6lZaWpnHjxikxMTFi6/P7/aqoqFBeXp5cLlfE5kUoso4Oco4Oco4Ocg41tHRjxOd0Oy3NzQrYknPrlY2LsbWMnD59WjU1Ndq9e7eKi4slSYFAQJZlKTY2Vps2bdLf/u3fhuzndrvldrtDtrtcLlt+ITPnbZavxRHxeT+bPyHic3Z1dv0Zoi1yjg5yjg5yPseO16pWduTc0flsLSOJiYn68MMP22x77rnntHnzZv3ud7/ToEGD7Dw8AADoAsIuI2fOnNH+/fuDjw8ePKi6ujr16dNHAwcOVElJiQ4dOqSXX35ZTqdTQ4cObbN/v379FB8fH7IdAABcmsIuIzU1NRo7dmzwceu9HYWFhVqxYoWOHDmi+vr6yK0QAAB0a2GXkTFjxsiyzv/WohUrVlxw/9LSUpWWloZ7WAAA0E3x3TQAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAo8IuI1u3blVBQYEGDBggh8OhdevWXXD866+/rry8PF1xxRVKTExUTk6ONm7c2Nn1AgCAbibsMtLU1KSMjAwtWbKkQ+O3bt2qvLw8rV+/XrW1tRo7dqwKCgq0e/fusBcLAAC6n9hwdxg/frzGjx/f4fGLFy9u8/ipp57SG2+8obfeekuZmZnhHh4AAHQzYZeRbysQCOj06dPq06fPecf4fD75fL7gY6/XK0ny+/3y+/0RW0vrXG6nFbE525sf57IgE3uRc3SQc3SQcyh3TORfr1pfA+3IuaNzOizL6vQzczgcWrt2rSZOnNjhfRYsWKD58+frk08+Ub9+/dodU1paqrKyspDtK1euVEJCQmeXCwAAoqi5uVmTJk3SqVOnlJiYeN5xUS0jK1eu1NSpU/XGG28oNzf3vOPaOzOSlpam48ePX/DJhMvv96uiokKzapzyBRwRm7fVntL8iM/ZVbVmnZeXJ5fLZXo53RY5Rwc5Rwc5hxpaGvk3gLidluZmBWzJ2ev1Kikp6aJlJGqXaVatWqX77rtPa9asuWARkSS32y232x2y3eVy2fIL6Qs45GuJfBnhL08ou/4M0RY5Rwc5Rwc5n2PHa1UrO3Lu6HxR+ZyR1157TUVFRXrttdc0YcKEaBwSAAB0EWGfGTlz5oz2798ffHzw4EHV1dWpT58+GjhwoEpKSnTo0CG9/PLLkr65NFNYWKhnnnlG2dnZamhokCT16NFDvXr1itDTAAAAXVXYZ0ZqamqUmZkZfFuux+NRZmamZs+eLUk6cuSI6uvrg+NfeOEFff3115o+fbr69+8f/G/GjBkRegoAAKArC/vMyJgxY3She15XrFjR5nFVVVW4hwAAAJcQvpsGAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYFTYZWTr1q0qKCjQgAED5HA4tG7duovuU1VVpRtvvFFut1vXXnutVqxY0YmlAgCA7ijsMtLU1KSMjAwtWbKkQ+MPHjyoCRMmaOzYsaqrq9ODDz6o++67Txs3bgx7sQAAoPuJDXeH8ePHa/z48R0ev3TpUg0aNEgLFy6UJA0ZMkTbtm3Tv/3bvyk/Pz/cwwMAgG4m7DISrurqauXm5rbZlp+frwcffPC8+/h8Pvl8vuBjr9crSfL7/fL7/RFbW+tcbqcVsTnbmx/nsiATe5FzdJBzdJBzKHdM5F+vWl8D7ci5o3PaXkYaGhqUnJzcZltycrK8Xq+++uor9ejRI2Sf8vJylZWVhWzftGmTEhISIr7GuVmBiM8pSevXr7dl3q6soqLC9BIuCeQcHeQcHeR8zoJR9s1tR87Nzc0dGmd7GemMkpISeTye4GOv16u0tDSNGzdOiYmJETuO3+9XRUWFZtU45Qs4IjZvqz2lXIZq1Zp1Xl6eXC6X6eV0W+QcHeQcHeQcamhp5O+3dDstzc0K2JJz65WNi7G9jKSkpKixsbHNtsbGRiUmJrZ7VkSS3G633G53yHaXy2XLL6Qv4JCvJfJlhL88oez6M0Rb5Bwd5Bwd5HyOHa9VrezIuaPz2f45Izk5OaqsrGyzraKiQjk5OXYfGgAAdAFhl5EzZ86orq5OdXV1kr55625dXZ3q6+slfXOJZcqUKcHx06ZN04EDB/Too4/qk08+0XPPPaff/va3euihhyLzDAAAQJcWdhmpqalRZmamMjMzJUkej0eZmZmaPXu2JOnIkSPBYiJJgwYN0jvvvKOKigplZGRo4cKF+s1vfsPbegEAgKRO3DMyZswYWdb531rU3qerjhkzRrt37w73UAAA4BLAd9MAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAozpVRpYsWaL09HTFx8crOztbO3fuvOD4xYsX6/vf/7569OihtLQ0PfTQQ/rLX/7SqQUDAIDuJewysnr1ank8Hs2ZM0e7du1SRkaG8vPzdfTo0XbHr1y5UjNnztScOXP08ccf66WXXtLq1av1+OOPf+vFAwCAri/sMrJo0SJNnTpVRUVFuuGGG7R06VIlJCRo2bJl7Y7fvn27Ro8erUmTJik9PV3jxo3TXXfdddGzKQAA4NIQG87gs2fPqra2ViUlJcFtTqdTubm5qq6ubnefm266Sa+88op27typUaNG6cCBA1q/fr3uvvvu8x7H5/PJ5/MFH3u9XkmS3++X3+8PZ8kX1DqX22lFbM725se5LMjEXuQcHeQcHeQcyh0T+der1tdAO3Lu6JwOy7I6/MwOHz6s1NRUbd++XTk5OcHtjz76qLZs2aIdO3a0u9+zzz6rhx9+WJZl6euvv9a0adP0/PPPn/c4paWlKisrC9m+cuVKJSQkdHS5AADAoObmZk2aNEmnTp1SYmLieceFdWakM6qqqvTUU0/pueeeU3Z2tvbv368ZM2Zo7ty5mjVrVrv7lJSUyOPxBB97vV6lpaVp3LhxF3wy4fL7/aqoqNCsGqd8AUfE5m21pzQ/4nN2Va1Z5+XlyeVymV5Ot0XO0UHO0UHOoYaWboz4nG6npblZAVtybr2ycTFhlZGkpCTFxMSosbGxzfbGxkalpKS0u8+sWbN0991367777pMkDRs2TE1NTfrFL36hJ554Qk5n6G0rbrdbbrc7ZLvL5bLlF9IXcMjXEvkywl+eUHb9GaItco4Oco4Ocj7HjteqVnbk3NH5wrqBNS4uTiNHjlRlZWVwWyAQUGVlZZvLNn+tubk5pHDExMRIksK4QgQAALqpsC/TeDweFRYWKisrS6NGjdLixYvV1NSkoqIiSdKUKVOUmpqq8vJySVJBQYEWLVqkzMzM4GWaWbNmqaCgIFhKAADApSvsMnLnnXfq2LFjmj17thoaGjRixAht2LBBycnJkqT6+vo2Z0KefPJJORwOPfnkkzp06JCuuOIKFRQUaN68eZF7FgAAoMvq1A2sxcXFKi4ubvdnVVVVbQ8QG6s5c+Zozpw5nTkUAADo5vhuGgAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRnSojS5YsUXp6uuLj45Wdna2dO3decPzJkyc1ffp09e/fX263W9dff73Wr1/fqQUDAIDuJTbcHVavXi2Px6OlS5cqOztbixcvVn5+vvbu3at+/fqFjD979qzy8vLUr18//e53v1Nqaqo+//xz9e7dOxLrBwAAXVzYZWTRokWaOnWqioqKJElLly7VO++8o2XLlmnmzJkh45ctW6YTJ05o+/btcrlckqT09PRvt2oAANBthFVGzp49q9raWpWUlAS3OZ1O5ebmqrq6ut193nzzTeXk5Gj69Ol64403dMUVV2jSpEl67LHHFBMT0+4+Pp9PPp8v+Njr9UqS/H6//H5/OEu+oNa53E4rYnO2Nz/OZUEm9iLn6CDn6CDnUO6YyL9etb4G2pFzR+cMq4wcP35cLS0tSk5ObrM9OTlZn3zySbv7HDhwQJs3b9bkyZO1fv167d+/Xw888ID8fr/mzJnT7j7l5eUqKysL2b5p0yYlJCSEs+QOmZsViPickrgvph0VFRWml3BJIOfoIOfoIOdzFoyyb247cm5ubu7QuLAv04QrEAioX79+euGFFxQTE6ORI0fq0KFD+vWvf33eMlJSUiKPxxN87PV6lZaWpnHjxikxMTFia/P7/aqoqNCsGqd8AUfE5m21pzQ/4nN2Va1Z5+XlBS/XIfLIOTrIOTrIOdTQ0o0Rn9PttDQ3K2BLzq1XNi4mrDKSlJSkmJgYNTY2ttne2NiolJSUdvfp37+/XC5Xm0syQ4YMUUNDg86ePau4uLiQfdxut9xud8h2l8tlyy+kL+CQryXyZYS/PKHs+jNEW+QcHeQcHeR8jh2vVa3syLmj84X11t64uDiNHDlSlZWVwW2BQECVlZXKyclpd5/Ro0dr//79CgTOXQrZt2+f+vfv324RAQAAl5awP2fE4/HoxRdf1H/+53/q448/1v3336+mpqbgu2umTJnS5gbX+++/XydOnNCMGTO0b98+vfPOO3rqqac0ffr0yD0LAADQZYV9z8idd96pY8eOafbs2WpoaNCIESO0YcOG4E2t9fX1cjrPdZy0tDRt3LhRDz30kIYPH67U1FTNmDFDjz32WOSeBQAA6LI6dQNrcXGxiouL2/1ZVVVVyLacnBy9//77nTkUAADo5vhuGgAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYFWt6AQhf+sx3bJv7s/kTbJsbAID2cGYEAAAYRRkBAABGdaqMLFmyROnp6YqPj1d2drZ27tzZof1WrVolh8OhiRMnduawAACgGwq7jKxevVoej0dz5szRrl27lJGRofz8fB09evSC+3322Wd6+OGHdfPNN3d6sQAAoPsJu4wsWrRIU6dOVVFRkW644QYtXbpUCQkJWrZs2Xn3aWlp0eTJk1VWVqarr776Wy0YAAB0L2G9m+bs2bOqra1VSUlJcJvT6VRubq6qq6vPu9+//uu/ql+/frr33nv13nvvXfQ4Pp9PPp8v+Njr9UqS/H6//H5/OEu+oNa53E4rYnO2N3+kuWPsWa9k35pb57VrfnyDnKODnKODnEPZ8e9/62ugHTl3dE6HZVkdfmaHDx9Wamqqtm/frpycnOD2Rx99VFu2bNGOHTtC9tm2bZt++tOfqq6uTklJSfr5z3+ukydPat26dec9TmlpqcrKykK2r1y5UgkJCR1dLgAAMKi5uVmTJk3SqVOnlJiYeN5xtn7OyOnTp3X33XfrxRdfVFJSUof3KykpkcfjCT72er1KS0vTuHHjLvhkwuX3+1VRUaFZNU75Ao6IzdtqT2l+xOeUpKGlG22ZV7Jvza1Z5+XlyeVy2XIMkHO0kHN0kHMoO/79dzstzc0K2JJz65WNiwmrjCQlJSkmJkaNjY1ttjc2NiolJSVk/J///Gd99tlnKigoCG4LBALfHDg2Vnv37tU111wTsp/b7Zbb7Q7Z7nK5bPmF9AUc8rVEvozY9ZfHjrW2svsvvF1/hmiLnKODnKODnM+x+9//SOfc0fnCuoE1Li5OI0eOVGVlZXBbIBBQZWVlm8s2rQYPHqwPP/xQdXV1wf9uu+02jR07VnV1dUpLSwvn8AAAoBsK+zKNx+NRYWGhsrKyNGrUKC1evFhNTU0qKiqSJE2ZMkWpqakqLy9XfHy8hg4d2mb/3r17S1LIdgAAcGkKu4zceeedOnbsmGbPnq2GhgaNGDFCGzZsUHJysiSpvr5eTicf7AoAADqmUzewFhcXq7i4uN2fVVVVXXDfFStWdOaQAACgm+Jbe21k57frAgDQXXA9BQAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRnSojS5YsUXp6uuLj45Wdna2dO3eed+yLL76om2++WZdffrkuv/xy5ebmXnA8AAC4tIRdRlavXi2Px6M5c+Zo165dysjIUH5+vo4ePdru+KqqKt1111169913VV1drbS0NI0bN06HDh361osHAABdX9hlZNGiRZo6daqKiop0ww03aOnSpUpISNCyZcvaHf/qq6/qgQce0IgRIzR48GD95je/USAQUGVl5bdePAAA6Ppiwxl89uxZ1dbWqqSkJLjN6XQqNzdX1dXVHZqjublZfr9fffr0Oe8Yn88nn88XfOz1eiVJfr9ffr8/nCVfUOtcbqcVsTm7ukjm2968ds2Pb5BzdJBzdJBzKHdM5F+vWl8D7ci5o3M6LMvq8DM7fPiwUlNTtX37duXk5AS3P/roo9qyZYt27Nhx0TkeeOABbdy4UX/6058UHx/f7pjS0lKVlZWFbF+5cqUSEhI6ulwAAGBQc3OzJk2apFOnTikxMfG848I6M/JtzZ8/X6tWrVJVVdV5i4gklZSUyOPxBB97vd7gvSYXejLh8vv9qqio0Kwap3wBR8Tm7cr2lObbMm9r1nl5eXK5XLYcA+QcLeQcHeQcamjpxojP6XZampsVsCXn1isbFxNWGUlKSlJMTIwaGxvbbG9sbFRKSsoF93366ac1f/58/c///I+GDx9+wbFut1tutztku8vlsuUX0hdwyNdCGZFk+194u/4M0RY5Rwc5Rwc5n2Pna5UdOXd0vrBuYI2Li9PIkSPb3HzaejPqX1+2+f8WLFiguXPnasOGDcrKygrnkAAAoJsL+zKNx+NRYWGhsrKyNGrUKC1evFhNTU0qKiqSJE2ZMkWpqakqLy+XJP3qV7/S7NmztXLlSqWnp6uhoUGS1LNnT/Xs2TOCTwWRkD7zHVvmdcdYWjDKlqkBAF1c2GXkzjvv1LFjxzR79mw1NDRoxIgR2rBhg5KTkyVJ9fX1cjrPnXB5/vnndfbsWd1xxx1t5pkzZ45KS0u/3eoBAECX16kbWIuLi1VcXNzuz6qqqto8/uyzzzpzCAAAcIngu2kAAIBRlBEAAGAUZQQAABgV1Q89A+xg1zuAJOmz+RNsmxsA8A3KCAAAEWTn/0HqrigjiKqhpRv5tFsAQBvcMwIAAIyijAAAAKMoIwAAwCjuGQEuwK4b0XiXDgCcw5kRAABgFGdGABjHGSjg0saZEQAAYBRnRgAD7DoT4I6xtGCULVMDgG04MwIAAIzizAjQDdnxSbfcfwHALpQRAOgkSl/XxnfIfHdwmQYAABjFmREAwLdmx1kGbsi+dHBmBAAAGEUZAQAARnGZBkCHcLMfTLHjRmF8t1BGAHRbfLhcWxRKfFdxmQYAABjFmREA+A7h7AUuRZwZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGBUp8rIkiVLlJ6ervj4eGVnZ2vnzp0XHL9mzRoNHjxY8fHxGjZsmNavX9+pxQIAgO4n7DKyevVqeTwezZkzR7t27VJGRoby8/N19OjRdsdv375dd911l+69917t3r1bEydO1MSJE7Vnz55vvXgAAND1hV1GFi1apKlTp6qoqEg33HCDli5dqoSEBC1btqzd8c8884xuvfVWPfLIIxoyZIjmzp2rG2+8Uf/xH//xrRcPAAC6vrA+Dv7s2bOqra1VSUlJcJvT6VRubq6qq6vb3ae6uloej6fNtvz8fK1bt+68x/H5fPL5fMHHp06dkiSdOHFCfr8/nCVfkN/vV3Nzs2L9TrUE+EZIO8UGLDU3B8jaZuQcHeQcHeQcHa05f/nll3K5XBGd+/Tp05Iky7IuvIZwJj1+/LhaWlqUnJzcZntycrI++eSTdvdpaGhod3xDQ8N5j1NeXq6ysrKQ7YMGDQpnufiOmWR6AZcIco4Oco4Oco4Ou3M+ffq0evXqdd6ffye/KK+kpKTN2ZRAIKATJ06ob9++cjgi1469Xq/S0tL0xRdfKDExMWLzIhRZRwc5Rwc5Rwc5R4edOVuWpdOnT2vAgAEXHBdWGUlKSlJMTIwaGxvbbG9sbFRKSkq7+6SkpIQ1XpLcbrfcbnebbb179w5nqWFJTEzkFz1KyDo6yDk6yDk6yDk67Mr5QmdEWoV1A2tcXJxGjhypysrK4LZAIKDKykrl5OS0u09OTk6b8ZJUUVFx3vEAAODSEvZlGo/Ho8LCQmVlZWnUqFFavHixmpqaVFRUJEmaMmWKUlNTVV5eLkmaMWOGfvzjH2vhwoWaMGGCVq1apZqaGr3wwguRfSYAAKBLCruM3HnnnTp27Jhmz56thoYGjRgxQhs2bAjepFpfXy+n89wJl5tuukkrV67Uk08+qccff1zXXXed1q1bp6FDh0buWXSS2+3WnDlzQi4JIfLIOjrIOTrIOTrIOTq+Czk7rIu93wYAAMBGfDcNAAAwijICAACMoowAAACjKCMAAMCoS7qMLFmyROnp6YqPj1d2drZ27txpekldWnl5uX7wgx/osssuU79+/TRx4kTt3bu3zZi//OUvmj59uvr27auePXvqH//xH0M+FA/hmT9/vhwOhx588MHgNnKOjEOHDulnP/uZ+vbtqx49emjYsGGqqakJ/tyyLM2ePVv9+/dXjx49lJubq08//dTgiruelpYWzZo1S4MGDVKPHj10zTXXaO7cuW2+y4ScO2fr1q0qKCjQgAED5HA4Qr4TriO5njhxQpMnT1ZiYqJ69+6te++9V2fOnIn8Yq1L1KpVq6y4uDhr2bJl1p/+9Cdr6tSpVu/eva3GxkbTS+uy8vPzreXLl1t79uyx6urqrL/7u7+zBg4caJ05cyY4Ztq0aVZaWppVWVlp1dTUWD/84Q+tm266yeCqu7adO3da6enp1vDhw60ZM2YEt5Pzt3fixAnrqquusn7+859bO3bssA4cOGBt3LjR2r9/f3DM/PnzrV69elnr1q2z/vCHP1i33XabNWjQIOurr74yuPKuZd68eVbfvn2tt99+2zp48KC1Zs0aq2fPntYzzzwTHEPOnbN+/XrriSeesF5//XVLkrV27do2P+9IrrfeequVkZFhvf/++9Z7771nXXvttdZdd90V8bVesmVk1KhR1vTp04OPW1parAEDBljl5eUGV9W9HD161JJkbdmyxbIsyzp58qTlcrmsNWvWBMd8/PHHliSrurra1DK7rNOnT1vXXXedVVFRYf34xz8OlhFyjozHHnvM+tGPfnTenwcCASslJcX69a9/Hdx28uRJy+12W6+99lo0ltgtTJgwwbrnnnvabLv99tutyZMnW5ZFzpHy/8tIR3L96KOPLEnWBx98EBzz3//935bD4bAOHToU0fVdkpdpzp49q9raWuXm5ga3OZ1O5ebmqrq62uDKupdTp05Jkvr06SNJqq2tld/vb5P74MGDNXDgQHLvhOnTp2vChAlt8pTIOVLefPNNZWVl6Sc/+Yn69eunzMxMvfjii8GfHzx4UA0NDW1y7tWrl7Kzs8k5DDfddJMqKyu1b98+SdIf/vAHbdu2TePHj5dEznbpSK7V1dXq3bu3srKygmNyc3PldDq1Y8eOiK7nO/mtvXY7fvy4Wlpagp8a2yo5OVmffPKJoVV1L4FAQA8++KBGjx4d/LTdhoYGxcXFhXzpYXJyshoaGgyssutatWqVdu3apQ8++CDkZ+QcGQcOHNDzzz8vj8ejxx9/XB988IH+5V/+RXFxcSosLAxm2d6/I+TccTNnzpTX69XgwYMVExOjlpYWzZs3T5MnT5YkcrZJR3JtaGhQv3792vw8NjZWffr0iXj2l2QZgf2mT5+uPXv2aNu2baaX0u188cUXmjFjhioqKhQfH296Od1WIBBQVlaWnnrqKUlSZmam9uzZo6VLl6qwsNDw6rqP3/72t3r11Ve1cuVK/c3f/I3q6ur04IMPasCAAeR8CbkkL9MkJSUpJiYm5N0FjY2NSklJMbSq7qO4uFhvv/223n33XV155ZXB7SkpKTp79qxOnjzZZjy5h6e2tlZHjx7VjTfeqNjYWMXGxmrLli169tlnFRsbq+TkZHKOgP79++uGG25os23IkCGqr6+XpGCW/Dvy7TzyyCOaOXOmfvrTn2rYsGG6++679dBDDwW/bJWc7dGRXFNSUnT06NE2P//666914sSJiGd/SZaRuLg4jRw5UpWVlcFtgUBAlZWVysnJMbiyrs2yLBUXF2vt2rXavHmzBg0a1ObnI0eOlMvlapP73r17VV9fT+5huOWWW/Thhx+qrq4u+F9WVpYmT54c/N/k/O2NHj065K3p+/bt01VXXSVJGjRokFJSUtrk7PV6tWPHDnIOQ3Nzc5svV5WkmJgYBQIBSeRsl47kmpOTo5MnT6q2tjY4ZvPmzQoEAsrOzo7sgiJ6O2wXsmrVKsvtdlsrVqywPvroI+sXv/iF1bt3b6uhocH00rqs+++/3+rVq5dVVVVlHTlyJPhfc3NzcMy0adOsgQMHWps3b7ZqamqsnJwcKycnx+Cqu4e/fjeNZZFzJOzcudOKjY215s2bZ3366afWq6++aiUkJFivvPJKcMz8+fOt3r17W2+88Yb1xz/+0fr7v/973nIapsLCQis1NTX41t7XX3/dSkpKsh599NHgGHLunNOnT1u7d++2du/ebUmyFi1aZO3evdv6/PPPLcvqWK633nqrlZmZae3YscPatm2bdd111/HW3kj793//d2vgwIFWXFycNWrUKOv99983vaQuTVK7/y1fvjw45quvvrIeeOAB6/LLL7cSEhKsf/iHf7COHDlibtHdxP8vI+QcGW+99ZY1dOhQy+12W4MHD7ZeeOGFNj8PBALWrFmzrOTkZMvtdlu33HKLtXfvXkOr7Zq8Xq81Y8YMa+DAgVZ8fLx19dVXW0888YTl8/mCY8i5c9599912/00uLCy0LKtjuX755ZfWXXfdZfXs2dNKTEy0ioqKrNOnT0d8rQ7L+quPuQMAAIiyS/KeEQAA8N1BGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGDU/wEIAqfNOovLdgAAAABJRU5ErkJggg==\n" }, + "metadata": {}, "output_type": "display_data" } ], @@ -363,61 +227,44 @@ "id": "1a0ad9f8", "metadata": {}, "source": [ - "Делю график просмотра на 5 категорий, где: \n", - "от 0% до 20% = 1, \n", - "от 21% до 40% = 2, \n", - "... , \n", + "Делю график просмотра на 5 категорий, где:\n", + "от 0% до 20% = 1,\n", + "от 21% до 40% = 2,\n", + "... ,\n", "от 80% до 100% = 5" ] }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 194, "id": "1424e744", "metadata": {}, "outputs": [], "source": [ - "interactions[Columns.Weight] = np.where(interactions['watched_pct']\n", - " > 20, 2, 1)\n", - "interactions[Columns.Weight].mask(interactions['watched_pct'] > 40, 3,\n", - " inplace=True)\n", - "interactions[Columns.Weight].mask(interactions['watched_pct'] > 60, 4,\n", - " inplace=True)\n", - "interactions[Columns.Weight].mask(interactions['watched_pct'] > 80, 5,\n", - " inplace=True)" + "interactions[Columns.Weight] = pd.cut(\n", + " x=interactions['watched_pct'],\n", + " bins=5,\n", + " labels=[1, 2, 3, 4, 5]\n", + ")" ] }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 196, "id": "052d2fb0", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "" - ] + "text/plain": "
", + "image/png": "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\n" }, - "execution_count": 102, "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, "output_type": "display_data" } ], "source": [ - "interactions[Columns.Datetime].hist(bins=20)" + "interactions[Columns.Datetime].hist(bins=20);" ] }, { @@ -430,48 +277,33 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 197, "id": "0fbd2bbc", "metadata": {}, "outputs": [], "source": [ "cold_users = \\\n", - " interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts()\n", - " == 1].index" + " interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts() == 1].index" ] }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 198, "id": "150e1593", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "" - ] + "text/plain": "
", + "image/png": "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\n" }, - "execution_count": 104, "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, "output_type": "display_data" } ], "source": [ "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'\n", - " ].hist(bins=20)" + " ].hist(bins=20);" ] }, { @@ -484,162 +316,16 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 199, "id": "cca06e3f", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n", - "

355162 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "10 791466 8199 2021-07-27 713 9.0 1\n", - "26 181144 10440 2021-08-08 27408 40.0 2\n", - "37 161176 10440 2021-07-29 22 0.0 1\n", - "38 21723 1819 2021-04-11 8535 100.0 5\n", - "60 77216 8143 2021-05-08 660 11.0 1\n", - "... ... ... ... ... ... ...\n", - "5476222 1007900 9728 2021-08-12 416 6.0 1\n", - "5476225 882138 4716 2021-05-21 1594 2.0 1\n", - "5476238 805174 13125 2021-06-27 1 0.0 1\n", - "5476246 648596 12225 2021-08-13 76 0.0 1\n", - "5476248 697262 15297 2021-08-20 18307 63.0 4\n", - "\n", - "[355162 rows x 6 columns]" - ] + "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n10 791466 8199 2021-07-27 713 9.0 1\n26 181144 10440 2021-08-08 27408 40.0 2\n37 161176 10440 2021-07-29 22 0.0 1\n38 21723 1819 2021-04-11 8535 100.0 5\n60 77216 8143 2021-05-08 660 11.0 1\n... ... ... ... ... ... ...\n5476222 1007900 9728 2021-08-12 416 6.0 1\n5476225 882138 4716 2021-05-21 1594 2.0 1\n5476238 805174 13125 2021-06-27 1 0.0 1\n5476246 648596 12225 2021-08-13 76 0.0 1\n5476248 697262 15297 2021-08-20 18307 63.0 4\n\n[355162 rows x 6 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n

355162 rows × 6 columns

\n
" }, - "execution_count": 105, + "execution_count": 199, "metadata": {}, "output_type": "execute_result" } @@ -652,162 +338,16 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 200, "id": "a691676f", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n", - "

5475423 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "0 176549 9506 2021-05-11 4250 72.0 4\n", - "1 699317 1659 2021-05-29 8317 100.0 5\n", - "2 656683 7107 2021-05-09 10 0.0 1\n", - "3 864613 7638 2021-07-05 14483 100.0 5\n", - "4 964868 9506 2021-04-30 6725 100.0 5\n", - "... ... ... ... ... ... ...\n", - "5476246 648596 12225 2021-08-13 76 0.0 1\n", - "5476247 546862 9673 2021-04-13 2308 49.0 3\n", - "5476248 697262 15297 2021-08-20 18307 63.0 4\n", - "5476249 384202 16197 2021-04-19 6203 100.0 5\n", - "5476250 319709 4436 2021-08-15 3921 45.0 3\n", - "\n", - "[5475423 rows x 6 columns]" - ] + "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n0 176549 9506 2021-05-11 4250 72.0 4\n1 699317 1659 2021-05-29 8317 100.0 5\n2 656683 7107 2021-05-09 10 0.0 1\n3 864613 7638 2021-07-05 14483 100.0 5\n4 964868 9506 2021-04-30 6725 100.0 5\n... ... ... ... ... ... ...\n5476246 648596 12225 2021-08-13 76 0.0 1\n5476247 546862 9673 2021-04-13 2308 49.0 3\n5476248 697262 15297 2021-08-20 18307 63.0 4\n5476249 384202 16197 2021-04-19 6203 100.0 5\n5476250 319709 4436 2021-08-15 3921 45.0 3\n\n[5475423 rows x 6 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n

5475423 rows × 6 columns

\n
" }, - "execution_count": 106, + "execution_count": 200, "metadata": {}, "output_type": "execute_result" } @@ -818,102 +358,16 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 201, "id": "a64701c2", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n", - "

6440 rows × 1 columns

\n", - "
" - ], - "text/plain": [ - " item_id\n", - "10440 45695\n", - "15297 39309\n", - "2657 20474\n", - "9728 15140\n", - "4740 11455\n", - "... ...\n", - "1946 1\n", - "13886 1\n", - "14090 1\n", - "5730 1\n", - "13125 1\n", - "\n", - "[6440 rows x 1 columns]" - ] + "text/plain": " item_id\n10440 45695\n15297 39309\n2657 20474\n9728 15140\n4740 11455\n... ...\n1946 1\n13886 1\n14090 1\n5730 1\n13125 1\n\n[6440 rows x 1 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n

6440 rows × 1 columns

\n
" }, - "execution_count": 107, + "execution_count": 201, "metadata": {}, "output_type": "execute_result" } @@ -924,17 +378,15 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 202, "id": "cef9cfa6", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" - ] + "text/plain": "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" }, - "execution_count": 108, + "execution_count": 202, "metadata": {}, "output_type": "execute_result" } @@ -953,7 +405,7 @@ }, { "cell_type": "code", - "execution_count": 109, + "execution_count": 203, "id": "bd68d3fe", "metadata": {}, "outputs": [], @@ -963,7 +415,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": 204, "id": "3092fe4b", "metadata": {}, "outputs": [ @@ -988,7 +440,7 @@ }, { "cell_type": "code", - "execution_count": 111, + "execution_count": 205, "id": "ec286bdc", "metadata": {}, "outputs": [], @@ -998,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 206, "id": "52241fed", "metadata": {}, "outputs": [], @@ -1017,150 +469,16 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 207, "id": "c57e2b2f", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n", - "

840197 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " user_id age income sex kids_flg\n", - "0 973171 age_25_34 income_60_90 М 1\n", - "1 962099 age_18_24 income_20_40 М 0\n", - "2 1047345 age_45_54 income_40_60 Ж 0\n", - "3 721985 age_45_54 income_20_40 Ж 0\n", - "4 704055 age_35_44 income_60_90 Ж 0\n", - "... ... ... ... ... ...\n", - "840192 339025 age_65_inf income_0_20 Ж 0\n", - "840193 983617 age_18_24 income_20_40 Ж 1\n", - "840194 251008 NaN NaN NaN 0\n", - "840195 590706 NaN NaN Ж 0\n", - "840196 166555 age_65_inf income_20_40 Ж 0\n", - "\n", - "[840197 rows x 5 columns]" - ] + "text/plain": " user_id age income sex kids_flg\n0 973171 age_25_34 income_60_90 М 1\n1 962099 age_18_24 income_20_40 М 0\n2 1047345 age_45_54 income_40_60 Ж 0\n3 721985 age_45_54 income_20_40 Ж 0\n4 704055 age_35_44 income_60_90 Ж 0\n... ... ... ... ... ...\n840192 339025 age_65_inf income_0_20 Ж 0\n840193 983617 age_18_24 income_20_40 Ж 1\n840194 251008 NaN NaN NaN 0\n840195 590706 NaN NaN Ж 0\n840196 166555 age_65_inf income_20_40 Ж 0\n\n[840197 rows x 5 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n

840197 rows × 5 columns

\n
" }, - "execution_count": 113, + "execution_count": 207, "metadata": {}, "output_type": "execute_result" } @@ -1171,7 +489,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 208, "id": "24cc138a", "metadata": {}, "outputs": [], @@ -1181,150 +499,16 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 209, "id": "6e5e2d92", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
..................
840184529394age_25_34income_40_60Ж0
84018680113age_25_34income_40_60Ж0
840188312839age_65_infincome_60_90Ж0
840189191349age_45_54income_40_60М1
840190393868age_25_34income_20_40М0
\n", - "

586653 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " user_id age income sex kids_flg\n", - "0 973171 age_25_34 income_60_90 М 1\n", - "1 962099 age_18_24 income_20_40 М 0\n", - "3 721985 age_45_54 income_20_40 Ж 0\n", - "4 704055 age_35_44 income_60_90 Ж 0\n", - "5 1037719 age_45_54 income_60_90 М 0\n", - "... ... ... ... .. ...\n", - "840184 529394 age_25_34 income_40_60 Ж 0\n", - "840186 80113 age_25_34 income_40_60 Ж 0\n", - "840188 312839 age_65_inf income_60_90 Ж 0\n", - "840189 191349 age_45_54 income_40_60 М 1\n", - "840190 393868 age_25_34 income_20_40 М 0\n", - "\n", - "[586653 rows x 5 columns]" - ] + "text/plain": " user_id age income sex kids_flg\n0 973171 age_25_34 income_60_90 М 1\n1 962099 age_18_24 income_20_40 М 0\n3 721985 age_45_54 income_20_40 Ж 0\n4 704055 age_35_44 income_60_90 Ж 0\n5 1037719 age_45_54 income_60_90 М 0\n... ... ... ... .. ...\n840184 529394 age_25_34 income_40_60 Ж 0\n840186 80113 age_25_34 income_40_60 Ж 0\n840188 312839 age_65_inf income_60_90 Ж 0\n840189 191349 age_45_54 income_40_60 М 1\n840190 393868 age_25_34 income_20_40 М 0\n\n[586653 rows x 5 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
..................
840184529394age_25_34income_40_60Ж0
84018680113age_25_34income_40_60Ж0
840188312839age_65_infincome_60_90Ж0
840189191349age_45_54income_40_60М1
840190393868age_25_34income_20_40М0
\n

586653 rows × 5 columns

\n
" }, - "execution_count": 115, + "execution_count": 209, "metadata": {}, "output_type": "execute_result" } @@ -1343,7 +527,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 210, "id": "1286eb60", "metadata": {}, "outputs": [], @@ -1353,81 +537,16 @@ }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 211, "id": "1ccccf0f", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 973171 М sex\n", - "1 962099 М sex\n", - "3 721985 Ж sex\n", - "4 704055 Ж sex\n", - "5 1037719 М sex" - ] + "text/plain": " id value feature\n0 973171 М sex\n1 962099 М sex\n3 721985 Ж sex\n4 704055 Ж sex\n5 1037719 М sex", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n
" }, - "execution_count": 117, + "execution_count": 211, "metadata": {}, "output_type": "execute_result" } @@ -1453,347 +572,27 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 213, "id": "8bbe9ee4", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
.............................................
159586443seriesПолярный кругArctic Circle2018.0драмы, триллеры, криминалФинляндия, ГерманияNaN16.0NaNХанну СалоненИина Куустонен, Максимилиан Брюкнер, Пихла Вии...Во время погони за браконьерами по лесу, сотру...убийство, вирус, расследование преступления, н...
159592367seriesНадеждаNaN2020.0драмы, боевикиРоссия0.018.0NaNЕлена ХазановаВиктория Исакова, Александр Кузьмин, Алексей М...Оригинальный киносериал от создателей «Бывших»...Надежда, 2020, Россия
1596010632seriesСговорHassel2017.0драмы, триллеры, криминалРоссия0.018.0NaNЭшреф Рейбрук, Амир Камдин, Эрик ЭгерОла Рапас, Алиетт Офейм, Уильма Лиден, Шанти Р...Криминальная драма по мотивам романов о шведск...Сговор, 2017, Россия
159614538seriesСреди камнейDarklands2019.0драмы, спорт, криминалРоссия0.018.0NaNМарк О’Коннор, Конор МакМахонДэйн Уайт О’Хара, Томас Кэйн-Бирн, Джудит Родд...Семнадцатилетний Дэмиен мечтает вырваться за п...Среди, камней, 2019, Россия
159623206seriesГошаNaN2019.0комедииРоссия0.016.0NaNМихаил МироновМкртыч Арзуманян, Виктория РунцоваДобродушный Гоша не может выйти из дома, чтобы...Гоша, 2019, Россия
\n", - "

15963 rows × 14 columns

\n", - "
" - ], - "text/plain": [ - " item_id content_type title title_orig \\\n", - "0 10711 film Поговори с ней Hable con ella \n", - "1 2508 film Голые перцы Search Party \n", - "2 10716 film Тактическая сила Tactical Force \n", - "3 7868 film 45 лет 45 Years \n", - "4 16268 film Все решает мгновение NaN \n", - "... ... ... ... ... \n", - "15958 6443 series Полярный круг Arctic Circle \n", - "15959 2367 series Надежда NaN \n", - "15960 10632 series Сговор Hassel \n", - "15961 4538 series Среди камней Darklands \n", - "15962 3206 series Гоша NaN \n", - "\n", - " release_year genres \\\n", - "0 2002.0 драмы, зарубежные, детективы, мелодрамы \n", - "1 2014.0 зарубежные, приключения, комедии \n", - "2 2011.0 криминал, зарубежные, триллеры, боевики, комедии \n", - "3 2015.0 драмы, зарубежные, мелодрамы \n", - "4 1978.0 драмы, спорт, советские, мелодрамы \n", - "... ... ... \n", - "15958 2018.0 драмы, триллеры, криминал \n", - "15959 2020.0 драмы, боевики \n", - "15960 2017.0 драмы, триллеры, криминал \n", - "15961 2019.0 драмы, спорт, криминал \n", - "15962 2019.0 комедии \n", - "\n", - " countries for_kids age_rating studios \\\n", - "0 Испания NaN 16.0 NaN \n", - "1 США NaN 16.0 NaN \n", - "2 Канада NaN 16.0 NaN \n", - "3 Великобритания NaN 16.0 NaN \n", - "4 СССР NaN 12.0 Ленфильм \n", - "... ... ... ... ... \n", - "15958 Финляндия, Германия NaN 16.0 NaN \n", - "15959 Россия 0.0 18.0 NaN \n", - "15960 Россия 0.0 18.0 NaN \n", - "15961 Россия 0.0 18.0 NaN \n", - "15962 Россия 0.0 16.0 NaN \n", - "\n", - " directors \\\n", - "0 Педро Альмодовар \n", - "1 Скот Армстронг \n", - "2 Адам П. Калтраро \n", - "3 Эндрю Хэй \n", - "4 Виктор Садовский \n", - "... ... \n", - "15958 Ханну Салонен \n", - "15959 Елена Хазанова \n", - "15960 Эшреф Рейбрук, Амир Камдин, Эрик Эгер \n", - "15961 Марк О’Коннор, Конор МакМахон \n", - "15962 Михаил Миронов \n", - "\n", - " actors \\\n", - "0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n", - "1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n", - "2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n", - "3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n", - "4 Александр Абдулов, Александр Демьяненко, Алекс... \n", - "... ... \n", - "15958 Иина Куустонен, Максимилиан Брюкнер, Пихла Вии... \n", - "15959 Виктория Исакова, Александр Кузьмин, Алексей М... \n", - "15960 Ола Рапас, Алиетт Офейм, Уильма Лиден, Шанти Р... \n", - "15961 Дэйн Уайт О’Хара, Томас Кэйн-Бирн, Джудит Родд... \n", - "15962 Мкртыч Арзуманян, Виктория Рунцова \n", - "\n", - " description \\\n", - "0 Мелодрама легендарного Педро Альмодовара «Пого... \n", - "1 Уморительная современная комедия на популярную... \n", - "2 Профессиональный рестлер Стив Остин («Все или ... \n", - "3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n", - "4 Расчетливая чаровница из советского кинохита «... \n", - "... ... \n", - "15958 Во время погони за браконьерами по лесу, сотру... \n", - "15959 Оригинальный киносериал от создателей «Бывших»... \n", - "15960 Криминальная драма по мотивам романов о шведск... \n", - "15961 Семнадцатилетний Дэмиен мечтает вырваться за п... \n", - "15962 Добродушный Гоша не может выйти из дома, чтобы... \n", - "\n", - " keywords \n", - "0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n", - "1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n", - "2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n", - "3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n", - "4 Все, решает, мгновение, 1978, СССР, сильные, ж... \n", - "... ... \n", - "15958 убийство, вирус, расследование преступления, н... \n", - "15959 Надежда, 2020, Россия \n", - "15960 Сговор, 2017, Россия \n", - "15961 Среди, камней, 2019, Россия \n", - "15962 Гоша, 2019, Россия \n", - "\n", - "[15963 rows x 14 columns]" - ] + "text/plain": " item_id content_type title title_orig release_year \\\n0 10711 film Поговори с ней Hable con ella 2002.0 \n1 2508 film Голые перцы Search Party 2014.0 \n2 10716 film Тактическая сила Tactical Force 2011.0 \n3 7868 film 45 лет 45 Years 2015.0 \n4 16268 film Все решает мгновение NaN 1978.0 \n\n genres countries for_kids \\\n0 драмы, зарубежные, детективы, мелодрамы Испания NaN \n1 зарубежные, приключения, комедии США NaN \n2 криминал, зарубежные, триллеры, боевики, комедии Канада NaN \n3 драмы, зарубежные, мелодрамы Великобритания NaN \n4 драмы, спорт, советские, мелодрамы СССР NaN \n\n age_rating studios directors \\\n0 16.0 NaN Педро Альмодовар \n1 16.0 NaN Скот Армстронг \n2 16.0 NaN Адам П. Калтраро \n3 16.0 NaN Эндрю Хэй \n4 12.0 Ленфильм Виктор Садовский \n\n actors \\\n0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n4 Александр Абдулов, Александр Демьяненко, Алекс... \n\n description \\\n0 Мелодрама легендарного Педро Альмодовара «Пого... \n1 Уморительная современная комедия на популярную... \n2 Профессиональный рестлер Стив Остин («Все или ... \n3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n4 Расчетливая чаровница из советского кинохита «... \n\n keywords \n0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n4 Все, решает, мгновение, 1978, СССР, сильные, ж... ", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
\n
" }, - "execution_count": 118, + "execution_count": 213, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "items" + "items.head()" ] }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 214, "id": "72fa86a0", "metadata": { "scrolled": true @@ -1801,25 +600,9 @@ "outputs": [ { "data": { - "text/plain": [ - "item_id 0\n", - "content_type 0\n", - "title 0\n", - "title_orig 4745\n", - "release_year 98\n", - "genres 0\n", - "countries 37\n", - "for_kids 15397\n", - "age_rating 2\n", - "studios 14898\n", - "directors 1509\n", - "actors 2619\n", - "description 2\n", - "keywords 423\n", - "dtype: int64" - ] + "text/plain": "item_id 0\ncontent_type 0\ntitle 0\ntitle_orig 4745\nrelease_year 98\ngenres 0\ncountries 37\nfor_kids 15397\nage_rating 2\nstudios 14898\ndirectors 1509\nactors 2619\ndescription 2\nkeywords 423\ndtype: int64" }, - "execution_count": 119, + "execution_count": 214, "metadata": {}, "output_type": "execute_result" } @@ -1830,7 +613,7 @@ }, { "cell_type": "code", - "execution_count": 120, + "execution_count": 215, "id": "50f0611f", "metadata": {}, "outputs": [], @@ -1840,31 +623,15 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": 216, "id": "280cf47d", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "item_id 0\n", - "content_type 0\n", - "title 0\n", - "title_orig 3775\n", - "release_year 31\n", - "genres 0\n", - "countries 14\n", - "for_kids 13415\n", - "age_rating 1\n", - "studios 13047\n", - "directors 939\n", - "actors 1858\n", - "description 0\n", - "keywords 388\n", - "dtype: int64" - ] + "text/plain": "item_id 0\ncontent_type 0\ntitle 0\ntitle_orig 3775\nrelease_year 31\ngenres 0\ncountries 14\nfor_kids 13415\nage_rating 1\nstudios 13047\ndirectors 939\nactors 1858\ndescription 0\nkeywords 388\ndtype: int64" }, - "execution_count": 121, + "execution_count": 216, "metadata": {}, "output_type": "execute_result" } @@ -1883,81 +650,16 @@ }, { "cell_type": "code", - "execution_count": 122, + "execution_count": 217, "id": "bf6da75c", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 драмы genre\n", - "0 10711 зарубежные genre\n", - "0 10711 детективы genre\n", - "0 10711 мелодрамы genre\n", - "1 2508 зарубежные genre" - ] + "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n
" }, - "execution_count": 122, + "execution_count": 217, "metadata": {}, "output_type": "execute_result" } @@ -1974,126 +676,16 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": 218, "id": "913b9c27", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n", - "

36128 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 драмы genre\n", - "0 10711 зарубежные genre\n", - "0 10711 детективы genre\n", - "0 10711 мелодрамы genre\n", - "1 2508 зарубежные genre\n", - "... ... ... ...\n", - "15960 10632 криминал genre\n", - "15961 4538 драмы genre\n", - "15961 4538 спорт genre\n", - "15961 4538 криминал genre\n", - "15962 3206 комедии genre\n", - "\n", - "[36128 rows x 3 columns]" - ] + "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre\n... ... ... ...\n15960 10632 криминал genre\n15961 4538 драмы genre\n15961 4538 спорт genre\n15961 4538 криминал genre\n15962 3206 комедии genre\n\n[36128 rows x 3 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n

36128 rows × 3 columns

\n
" }, - "execution_count": 123, + "execution_count": 218, "metadata": {}, "output_type": "execute_result" } @@ -2112,126 +704,16 @@ }, { "cell_type": "code", - "execution_count": 124, + "execution_count": 220, "id": "65f8b5d9", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
............
159586443seriescontent_type
159592367seriescontent_type
1596010632seriescontent_type
159614538seriescontent_type
159623206seriescontent_type
\n", - "

13963 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 film content_type\n", - "1 2508 film content_type\n", - "2 10716 film content_type\n", - "3 7868 film content_type\n", - "4 16268 film content_type\n", - "... ... ... ...\n", - "15958 6443 series content_type\n", - "15959 2367 series content_type\n", - "15960 10632 series content_type\n", - "15961 4538 series content_type\n", - "15962 3206 series content_type\n", - "\n", - "[13963 rows x 3 columns]" - ] + "text/plain": " id value feature\n0 10711 film content_type\n1 2508 film content_type\n2 10716 film content_type\n3 7868 film content_type\n4 16268 film content_type", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
\n
" }, - "execution_count": 124, + "execution_count": 220, "metadata": {}, "output_type": "execute_result" } @@ -2240,7 +722,7 @@ "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", "content_feature.columns = [\"id\", \"value\"]\n", "content_feature[\"feature\"] = \"content_type\"\n", - "content_feature" + "content_feature.head()" ] }, { @@ -2253,126 +735,16 @@ }, { "cell_type": "code", - "execution_count": 125, + "execution_count": 221, "id": "fdc43660", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
............
159614538джудит роддиactors
159614538марк о’халлоранactors
159614538джимми смоллхорнactors
159623206мкртыч арзуманянactors
159623206виктория рунцоваactors
\n", - "

128926 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 адольфо фернандес actors\n", - "0 10711 ана фернандес actors\n", - "0 10711 дарио грандинетти actors\n", - "0 10711 джеральдин чаплин actors\n", - "0 10711 елена анайя actors\n", - "... ... ... ...\n", - "15961 4538 джудит родди actors\n", - "15961 4538 марк о’халлоран actors\n", - "15961 4538 джимми смоллхорн actors\n", - "15962 3206 мкртыч арзуманян actors\n", - "15962 3206 виктория рунцова actors\n", - "\n", - "[128926 rows x 3 columns]" - ] + "text/plain": " id value feature\n0 10711 адольфо фернандес actors\n0 10711 ана фернандес actors\n0 10711 дарио грандинетти actors\n0 10711 джеральдин чаплин actors\n0 10711 елена анайя actors", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
\n
" }, - "execution_count": 125, + "execution_count": 221, "metadata": {}, "output_type": "execute_result" } @@ -2383,7 +755,7 @@ "actors_feature = items[['item_id', 'actors']].explode('actors')\n", "actors_feature.columns = ['id', 'value']\n", "actors_feature['feature'] = 'actors'\n", - "actors_feature" + "actors_feature.head()" ] }, { @@ -2396,126 +768,16 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": 222, "id": "594abe5c", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
............
1596145382019keywords
159614538россияkeywords
159623206гошаkeywords
1596232062019keywords
159623206россияkeywords
\n", - "

341629 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 поговори keywords\n", - "0 10711 ней keywords\n", - "0 10711 2002 keywords\n", - "0 10711 испания keywords\n", - "0 10711 друзья keywords\n", - "... ... ... ...\n", - "15961 4538 2019 keywords\n", - "15961 4538 россия keywords\n", - "15962 3206 гоша keywords\n", - "15962 3206 2019 keywords\n", - "15962 3206 россия keywords\n", - "\n", - "[341629 rows x 3 columns]" - ] + "text/plain": " id value feature\n0 10711 поговори keywords\n0 10711 ней keywords\n0 10711 2002 keywords\n0 10711 испания keywords\n0 10711 друзья keywords", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
\n
" }, - "execution_count": 126, + "execution_count": 222, "metadata": {}, "output_type": "execute_result" } @@ -2526,7 +788,7 @@ "keywords_feature = items[['item_id', 'keywords']].explode('keywords')\n", "keywords_feature.columns = ['id', 'value']\n", "keywords_feature['feature'] = 'keywords'\n", - "keywords_feature" + "keywords_feature.head()" ] }, { @@ -2534,131 +796,21 @@ "id": "d3eb0a37", "metadata": {}, "source": [ - "# Countries\t" + "# Countries" ] }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 223, "id": "8eb8a621", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
............
159586443Финляндия, Германияcountries
159592367Россияcountries
1596010632Россияcountries
159614538Россияcountries
159623206Россияcountries
\n", - "

13963 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 Испания countries\n", - "1 2508 США countries\n", - "2 10716 Канада countries\n", - "3 7868 Великобритания countries\n", - "4 16268 СССР countries\n", - "... ... ... ...\n", - "15958 6443 Финляндия, Германия countries\n", - "15959 2367 Россия countries\n", - "15960 10632 Россия countries\n", - "15961 4538 Россия countries\n", - "15962 3206 Россия countries\n", - "\n", - "[13963 rows x 3 columns]" - ] + "text/plain": " id value feature\n0 10711 Испания countries\n1 2508 США countries\n2 10716 Канада countries\n3 7868 Великобритания countries\n4 16268 СССР countries", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
\n
" }, - "execution_count": 39, + "execution_count": 223, "metadata": {}, "output_type": "execute_result" } @@ -2667,290 +819,70 @@ "country_feature = items.reindex(columns=[Columns.Item, 'countries'])\n", "country_feature.columns = ['id', 'value']\n", "country_feature['feature'] = 'countries'\n", - "country_feature" - ] - }, - { - "cell_type": "markdown", - "id": "5e477ee1", - "metadata": {}, - "source": [ - "# Age Rating" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "0894154a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
............
15958644316.0age_feature
15959236718.0age_feature
159601063218.0age_feature
15961453818.0age_feature
15962320616.0age_feature
\n", - "

13963 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 16.0 age_feature\n", - "1 2508 16.0 age_feature\n", - "2 10716 16.0 age_feature\n", - "3 7868 16.0 age_feature\n", - "4 16268 12.0 age_feature\n", - "... ... ... ...\n", - "15958 6443 16.0 age_feature\n", - "15959 2367 18.0 age_feature\n", - "15960 10632 18.0 age_feature\n", - "15961 4538 18.0 age_feature\n", - "15962 3206 16.0 age_feature\n", - "\n", - "[13963 rows x 3 columns]" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", - "age_feature.columns = [\"id\", \"value\"]\n", - "age_feature[\"feature\"] = \"age_feature\"\n", - "age_feature" - ] - }, - { - "cell_type": "markdown", - "id": "c09df1ec", - "metadata": {}, - "source": [ - "# Studios" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "ff937b4f", - "metadata": {}, - "outputs": [], - "source": [ - "items.fillna('Unknown', inplace=True)" + "country_feature.head()" ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "cee42708", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711Unknownstudios
12508Unknownstudios
210716Unknownstudios
37868Unknownstudios
416268Ленфильмstudios
............
159586443Unknownstudios
159592367Unknownstudios
1596010632Unknownstudios
159614538Unknownstudios
159623206Unknownstudios
\n", - "

13963 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 Unknown studios\n", - "1 2508 Unknown studios\n", - "2 10716 Unknown studios\n", - "3 7868 Unknown studios\n", - "4 16268 Ленфильм studios\n", - "... ... ... ...\n", - "15958 6443 Unknown studios\n", - "15959 2367 Unknown studios\n", - "15960 10632 Unknown studios\n", - "15961 4538 Unknown studios\n", - "15962 3206 Unknown studios\n", - "\n", - "[13963 rows x 3 columns]" - ] + }, + { + "cell_type": "markdown", + "id": "5e477ee1", + "metadata": {}, + "source": [ + "# Age Rating" + ] + }, + { + "cell_type": "code", + "execution_count": 224, + "id": "0894154a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": " id value feature\n0 10711 16.0 age_feature\n1 2508 16.0 age_feature\n2 10716 16.0 age_feature\n3 7868 16.0 age_feature\n4 16268 12.0 age_feature", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
\n
" + }, + "execution_count": 224, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", + "age_feature.columns = [\"id\", \"value\"]\n", + "age_feature[\"feature\"] = \"age_feature\"\n", + "age_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "c09df1ec", + "metadata": {}, + "source": [ + "# Studios" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "ff937b4f", + "metadata": {}, + "outputs": [], + "source": [ + "items.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 225, + "id": "cee42708", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": " id value feature\n0 10711 NaN studios\n1 2508 NaN studios\n2 10716 NaN studios\n3 7868 NaN studios\n4 16268 Ленфильм studios", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711NaNstudios
12508NaNstudios
210716NaNstudios
37868NaNstudios
416268Ленфильмstudios
\n
" }, - "execution_count": 42, + "execution_count": 225, "metadata": {}, "output_type": "execute_result" } @@ -2959,131 +891,21 @@ "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", "studios_feature.columns = [\"id\", \"value\"]\n", "studios_feature[\"feature\"] = \"studios\"\n", - "studios_feature" + "studios_feature.head()" ] }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 226, "id": "7234f13b", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
159586443seriescontent_type
159592367seriescontent_type
1596010632seriescontent_type
159614538seriescontent_type
159623206seriescontent_type
\n", - "

50091 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 драмы genre\n", - "0 10711 зарубежные genre\n", - "0 10711 детективы genre\n", - "0 10711 мелодрамы genre\n", - "1 2508 зарубежные genre\n", - "... ... ... ...\n", - "15958 6443 series content_type\n", - "15959 2367 series content_type\n", - "15960 10632 series content_type\n", - "15961 4538 series content_type\n", - "15962 3206 series content_type\n", - "\n", - "[50091 rows x 3 columns]" - ] + "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n
" }, - "execution_count": 128, + "execution_count": 226, "metadata": {}, "output_type": "execute_result" } @@ -3092,7 +914,7 @@ "# studios_feature, age_feature, country_feature - фичи которые хотелось бы использовать,\n", "# но длительность обучения \"OPTUNA\" увеличивается в разы\n", "item_features = pd.concat((genre_feature, content_feature ))\n", - "item_features" + "item_features.head()" ] }, { @@ -3105,46 +927,15 @@ }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 227, "id": "b082e667", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "{'Precision@1': Precision(k=1),\n", - " 'Precision@2': Precision(k=2),\n", - " 'Precision@3': Precision(k=3),\n", - " 'Precision@4': Precision(k=4),\n", - " 'Precision@5': Precision(k=5),\n", - " 'Precision@6': Precision(k=6),\n", - " 'Precision@7': Precision(k=7),\n", - " 'Precision@8': Precision(k=8),\n", - " 'Precision@9': Precision(k=9),\n", - " 'Precision@10': Precision(k=10),\n", - " 'Recall@1': Recall(k=1),\n", - " 'Recall@2': Recall(k=2),\n", - " 'Recall@3': Recall(k=3),\n", - " 'Recall@4': Recall(k=4),\n", - " 'Recall@5': Recall(k=5),\n", - " 'Recall@6': Recall(k=6),\n", - " 'Recall@7': Recall(k=7),\n", - " 'Recall@8': Recall(k=8),\n", - " 'Recall@9': Recall(k=9),\n", - " 'Recall@10': Recall(k=10),\n", - " 'MAP@1': MAP(k=1, divide_by_k=False),\n", - " 'MAP@2': MAP(k=2, divide_by_k=False),\n", - " 'MAP@3': MAP(k=3, divide_by_k=False),\n", - " 'MAP@4': MAP(k=4, divide_by_k=False),\n", - " 'MAP@5': MAP(k=5, divide_by_k=False),\n", - " 'MAP@6': MAP(k=6, divide_by_k=False),\n", - " 'MAP@7': MAP(k=7, divide_by_k=False),\n", - " 'MAP@8': MAP(k=8, divide_by_k=False),\n", - " 'MAP@9': MAP(k=9, divide_by_k=False),\n", - " 'MAP@10': MAP(k=10, divide_by_k=False)}" - ] + "text/plain": "{'Precision@1': Precision(k=1),\n 'Precision@2': Precision(k=2),\n 'Precision@3': Precision(k=3),\n 'Precision@4': Precision(k=4),\n 'Precision@5': Precision(k=5),\n 'Precision@6': Precision(k=6),\n 'Precision@7': Precision(k=7),\n 'Precision@8': Precision(k=8),\n 'Precision@9': Precision(k=9),\n 'Precision@10': Precision(k=10),\n 'Recall@1': Recall(k=1),\n 'Recall@2': Recall(k=2),\n 'Recall@3': Recall(k=3),\n 'Recall@4': Recall(k=4),\n 'Recall@5': Recall(k=5),\n 'Recall@6': Recall(k=6),\n 'Recall@7': Recall(k=7),\n 'Recall@8': Recall(k=8),\n 'Recall@9': Recall(k=9),\n 'Recall@10': Recall(k=10),\n 'MAP@1': MAP(k=1, divide_by_k=False),\n 'MAP@2': MAP(k=2, divide_by_k=False),\n 'MAP@3': MAP(k=3, divide_by_k=False),\n 'MAP@4': MAP(k=4, divide_by_k=False),\n 'MAP@5': MAP(k=5, divide_by_k=False),\n 'MAP@6': MAP(k=6, divide_by_k=False),\n 'MAP@7': MAP(k=7, divide_by_k=False),\n 'MAP@8': MAP(k=8, divide_by_k=False),\n 'MAP@9': MAP(k=9, divide_by_k=False),\n 'MAP@10': MAP(k=10, divide_by_k=False)}" }, - "execution_count": 129, + "execution_count": 227, "metadata": {}, "output_type": "execute_result" } @@ -3163,27 +954,20 @@ "metrics" ] }, - { - "cell_type": "code", - "execution_count": 130, - "id": "d027f149", - "metadata": {}, - "outputs": [], - "source": [ - "TEST_USERS = test[Columns.User].unique()" - ] - }, { "cell_type": "markdown", "id": "2c603783", "metadata": {}, "source": [ - "# Optuna" + "# Optuna\n", + "\n", + "Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", + "Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)" ] }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 229, "id": "fb193c2f", "metadata": {}, "outputs": [], @@ -3197,16 +981,32 @@ }, { "cell_type": "code", - "execution_count": 132, + "execution_count": 230, "id": "3328645d", "metadata": {}, "outputs": [], "source": [ - "USER_ALPHA = 0 \n", - "ITEM_ALPHA = 0 \n", + "USER_ALPHA = 0\n", + "ITEM_ALPHA = 0\n", "K_RECOS = 10" ] }, + { + "cell_type": "code", + "execution_count": 231, + "outputs": [], + "source": [ + "dataset = Dataset.construct(interactions_df=train,\n", + " user_features_df=user_features,\n", + " cat_user_features=['sex', 'age', 'income'],\n", + " item_features_df=item_features,\n", + " cat_item_features=['content_type', 'genre'])\n", + "TEST_USERS = test[Columns.User].unique()" + ], + "metadata": { + "collapsed": false + } + }, { "cell_type": "code", "execution_count": 54, @@ -3219,8 +1019,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 18:32:01,241]\u001b[0m A new study created in memory with name: no-name-d2c12238-d18d-4c6f-bca4-840e7d3f29b0\u001b[0m\n", - "\u001b[32m[I 2022-12-12 18:41:40,178]\u001b[0m Trial 0 finished with value: 0.07156314077881751 and parameters: {'recomender': 'ALS', 'regularization': 0.0035671951579306937}. Best is trial 0 with value: 0.07156314077881751.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 18:32:01,241]\u001B[0m A new study created in memory with name: no-name-d2c12238-d18d-4c6f-bca4-840e7d3f29b0\u001B[0m\n", + "\u001B[32m[I 2022-12-12 18:41:40,178]\u001B[0m Trial 0 finished with value: 0.07156314077881751 and parameters: {'recomender': 'ALS', 'regularization': 0.0035671951579306937}. Best is trial 0 with value: 0.07156314077881751.\u001B[0m\n" ] }, { @@ -3234,7 +1034,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 18:51:48,671]\u001b[0m Trial 1 finished with value: 0.07241639094290958 and parameters: {'recomender': 'ALS', 'regularization': 0.006724126527816994}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 18:51:48,671]\u001B[0m Trial 1 finished with value: 0.07241639094290958 and parameters: {'recomender': 'ALS', 'regularization': 0.006724126527816994}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3248,7 +1048,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 18:53:18,697]\u001b[0m Trial 2 finished with value: 1.4050149479540313e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8190152272980945, 'k': 6, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 18:53:18,697]\u001B[0m Trial 2 finished with value: 1.4050149479540313e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8190152272980945, 'k': 6, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3262,7 +1062,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 18:54:36,340]\u001b[0m Trial 3 finished with value: 0.005366068762176463 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.18723291153626603, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 18:54:36,340]\u001B[0m Trial 3 finished with value: 0.005366068762176463 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.18723291153626603, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3276,7 +1076,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 18:56:21,781]\u001b[0m Trial 4 finished with value: 0.0002205827579874263 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.6560234930178588, 'k': 6, 'loss': 'logistic'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 18:56:21,781]\u001B[0m Trial 4 finished with value: 0.0002205827579874263 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.6560234930178588, 'k': 6, 'loss': 'logistic'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3290,7 +1090,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:05:46,138]\u001b[0m Trial 5 finished with value: 0.07173988822226253 and parameters: {'recomender': 'ALS', 'regularization': 0.009044651486228098}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:05:46,138]\u001B[0m Trial 5 finished with value: 0.07173988822226253 and parameters: {'recomender': 'ALS', 'regularization': 0.009044651486228098}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3304,7 +1104,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:07:05,748]\u001b[0m Trial 6 finished with value: 3.943062688880311e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.44751878244334975, 'k': 7, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:07:05,748]\u001B[0m Trial 6 finished with value: 3.943062688880311e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.44751878244334975, 'k': 7, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3318,7 +1118,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:08:22,099]\u001b[0m Trial 7 finished with value: 0.06793721324055035 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.10438302844592218, 'k': 3, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:08:22,099]\u001B[0m Trial 7 finished with value: 0.06793721324055035 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.10438302844592218, 'k': 3, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3332,7 +1132,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:17:32,898]\u001b[0m Trial 8 finished with value: 0.07184311920591484 and parameters: {'recomender': 'ALS', 'regularization': 0.0005806772800434514}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:17:32,898]\u001B[0m Trial 8 finished with value: 0.07184311920591484 and parameters: {'recomender': 'ALS', 'regularization': 0.0005806772800434514}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3346,7 +1146,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:18:59,268]\u001b[0m Trial 9 finished with value: 2.2409988419866796e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.805131840226543, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:18:59,268]\u001B[0m Trial 9 finished with value: 2.2409988419866796e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.805131840226543, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3360,7 +1160,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:28:09,202]\u001b[0m Trial 10 finished with value: 0.07180954187357708 and parameters: {'recomender': 'ALS', 'regularization': 0.008190821633209066}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:28:09,202]\u001B[0m Trial 10 finished with value: 0.07180954187357708 and parameters: {'recomender': 'ALS', 'regularization': 0.008190821633209066}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" ] }, { @@ -3374,7 +1174,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:37:15,147]\u001b[0m Trial 11 finished with value: 0.07244222251339615 and parameters: {'recomender': 'ALS', 'regularization': 0.00026970098377155163}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:37:15,147]\u001B[0m Trial 11 finished with value: 0.07244222251339615 and parameters: {'recomender': 'ALS', 'regularization': 0.00026970098377155163}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3388,7 +1188,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:46:24,260]\u001b[0m Trial 12 finished with value: 0.07202031081710311 and parameters: {'recomender': 'ALS', 'regularization': 0.0066363513358619185}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:46:24,260]\u001B[0m Trial 12 finished with value: 0.07202031081710311 and parameters: {'recomender': 'ALS', 'regularization': 0.0066363513358619185}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3402,7 +1202,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 19:55:34,176]\u001b[0m Trial 13 finished with value: 0.07199398893026046 and parameters: {'recomender': 'ALS', 'regularization': 0.004156107607150058}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 19:55:34,176]\u001B[0m Trial 13 finished with value: 0.07199398893026046 and parameters: {'recomender': 'ALS', 'regularization': 0.004156107607150058}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3416,7 +1216,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 20:04:42,589]\u001b[0m Trial 14 finished with value: 0.07167963259586223 and parameters: {'recomender': 'ALS', 'regularization': 0.0006228566403390988}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 20:04:42,589]\u001B[0m Trial 14 finished with value: 0.07167963259586223 and parameters: {'recomender': 'ALS', 'regularization': 0.0006228566403390988}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3430,7 +1230,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 20:13:49,348]\u001b[0m Trial 15 finished with value: 0.07202106855494453 and parameters: {'recomender': 'ALS', 'regularization': 0.00598705937836684}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 20:13:49,348]\u001B[0m Trial 15 finished with value: 0.07202106855494453 and parameters: {'recomender': 'ALS', 'regularization': 0.00598705937836684}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3444,7 +1244,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 20:22:57,770]\u001b[0m Trial 16 finished with value: 0.07193963920172777 and parameters: {'recomender': 'ALS', 'regularization': 0.0028834604694796696}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 20:22:57,770]\u001B[0m Trial 16 finished with value: 0.07193963920172777 and parameters: {'recomender': 'ALS', 'regularization': 0.0028834604694796696}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3458,7 +1258,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 20:32:04,614]\u001b[0m Trial 17 finished with value: 0.07186249836889418 and parameters: {'recomender': 'ALS', 'regularization': 0.007249626991281137}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 20:32:04,614]\u001B[0m Trial 17 finished with value: 0.07186249836889418 and parameters: {'recomender': 'ALS', 'regularization': 0.007249626991281137}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3472,7 +1272,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 20:41:24,258]\u001b[0m Trial 18 finished with value: 0.07164870366757094 and parameters: {'recomender': 'ALS', 'regularization': 0.005115162467576984}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 20:41:24,258]\u001B[0m Trial 18 finished with value: 0.07164870366757094 and parameters: {'recomender': 'ALS', 'regularization': 0.005115162467576984}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3486,7 +1286,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 20:50:49,059]\u001b[0m Trial 19 finished with value: 0.07179004415938793 and parameters: {'recomender': 'ALS', 'regularization': 0.0018963762834092678}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 20:50:49,059]\u001B[0m Trial 19 finished with value: 0.07179004415938793 and parameters: {'recomender': 'ALS', 'regularization': 0.0018963762834092678}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3500,7 +1300,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 21:42:16,853]\u001b[0m Trial 20 finished with value: 0.07167129296212232 and parameters: {'recomender': 'ALS', 'regularization': 0.009804091535656343}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 21:42:16,853]\u001B[0m Trial 20 finished with value: 0.07167129296212232 and parameters: {'recomender': 'ALS', 'regularization': 0.009804091535656343}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3514,7 +1314,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 21:52:20,413]\u001b[0m Trial 21 finished with value: 0.07191839766465505 and parameters: {'recomender': 'ALS', 'regularization': 0.005764203522687446}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 21:52:20,413]\u001B[0m Trial 21 finished with value: 0.07191839766465505 and parameters: {'recomender': 'ALS', 'regularization': 0.005764203522687446}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3528,7 +1328,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 22:02:12,773]\u001b[0m Trial 22 finished with value: 0.07159025974450188 and parameters: {'recomender': 'ALS', 'regularization': 0.006209360331833826}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 22:02:12,773]\u001B[0m Trial 22 finished with value: 0.07159025974450188 and parameters: {'recomender': 'ALS', 'regularization': 0.006209360331833826}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3542,7 +1342,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 22:12:55,936]\u001b[0m Trial 23 finished with value: 0.07167021208897958 and parameters: {'recomender': 'ALS', 'regularization': 0.007825089420401029}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 22:12:55,936]\u001B[0m Trial 23 finished with value: 0.07167021208897958 and parameters: {'recomender': 'ALS', 'regularization': 0.007825089420401029}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3556,7 +1356,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 22:23:04,762]\u001b[0m Trial 24 finished with value: 0.07191850988173716 and parameters: {'recomender': 'ALS', 'regularization': 0.004979324924695012}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 22:23:04,762]\u001B[0m Trial 24 finished with value: 0.07191850988173716 and parameters: {'recomender': 'ALS', 'regularization': 0.004979324924695012}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3570,7 +1370,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 22:34:38,654]\u001b[0m Trial 25 finished with value: 0.07178449755342503 and parameters: {'recomender': 'ALS', 'regularization': 0.002381286135370409}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 22:34:38,654]\u001B[0m Trial 25 finished with value: 0.07178449755342503 and parameters: {'recomender': 'ALS', 'regularization': 0.002381286135370409}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3584,7 +1384,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 22:45:43,850]\u001b[0m Trial 26 finished with value: 0.07177449403191542 and parameters: {'recomender': 'ALS', 'regularization': 0.004677821831829}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 22:45:43,850]\u001B[0m Trial 26 finished with value: 0.07177449403191542 and parameters: {'recomender': 'ALS', 'regularization': 0.004677821831829}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3598,7 +1398,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 22:56:45,636]\u001b[0m Trial 27 finished with value: 0.07214439856613958 and parameters: {'recomender': 'ALS', 'regularization': 0.0069504676367203744}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 22:56:45,636]\u001B[0m Trial 27 finished with value: 0.07214439856613958 and parameters: {'recomender': 'ALS', 'regularization': 0.0069504676367203744}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3612,7 +1412,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 23:08:13,361]\u001b[0m Trial 28 finished with value: 0.07237690498752612 and parameters: {'recomender': 'ALS', 'regularization': 0.0074561399301387955}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 23:08:13,361]\u001B[0m Trial 28 finished with value: 0.07237690498752612 and parameters: {'recomender': 'ALS', 'regularization': 0.0074561399301387955}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3626,7 +1426,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m[I 2022-12-12 23:18:05,878]\u001b[0m Trial 29 finished with value: 0.07173589378156864 and parameters: {'recomender': 'ALS', 'regularization': 0.00848249465326267}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + "\u001B[32m[I 2022-12-12 23:18:05,878]\u001B[0m Trial 29 finished with value: 0.07173589378156864 and parameters: {'recomender': 'ALS', 'regularization': 0.00848249465326267}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" ] }, { @@ -3640,7 +1440,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[33m[W 2022-12-12 23:27:26,180]\u001b[0m Trial 30 failed because of the following error: KeyboardInterrupt()\u001b[0m\n", + "\u001B[33m[W 2022-12-12 23:27:26,180]\u001B[0m Trial 30 failed because of the following error: KeyboardInterrupt()\u001B[0m\n", "Traceback (most recent call last):\n", " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", " value_or_values = func(trial)\n", @@ -3660,31 +1460,23 @@ "evalue": "", "output_type": "error", "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/tmp/ipykernel_5286/352742220.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[0mstudy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptuna\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_study\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdirection\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'maximize'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 50\u001b[0;31m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobjective\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_trials\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 417\u001b[0m \"\"\"\n\u001b[1;32m 418\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 419\u001b[0;31m _optimize(\n\u001b[0m\u001b[1;32m 420\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 421\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize\u001b[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 65\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn_jobs\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 66\u001b[0;31m _optimize_sequential(\n\u001b[0m\u001b[1;32m 67\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize_sequential\u001b[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 160\u001b[0;31m \u001b[0mfrozen_trial\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_run_trial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 161\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[0;31m# The following line mitigates memory problems that can be occurred in some\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 232\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc_err\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 233\u001b[0m ):\n\u001b[0;32m--> 234\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mfunc_err\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 235\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfrozen_trial\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 236\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 194\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mget_heartbeat_thread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_trial_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_storage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 195\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 196\u001b[0;31m \u001b[0mvalue_or_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 197\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTrialPruned\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[0;31m# TODO(mamu): Handle multi-objective cases.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/tmp/ipykernel_5286/352742220.py\u001b[0m in \u001b[0;36mobjective\u001b[0;34m(trial)\u001b[0m\n\u001b[1;32m 38\u001b[0m fit_features_together=True)\n\u001b[1;32m 39\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m recos = model.recommend(\n\u001b[0m\u001b[1;32m 41\u001b[0m \u001b[0musers\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTEST_USERS\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0mdataset\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001b[0m in \u001b[0;36mrecommend\u001b[0;34m(self, users, dataset, k, filter_viewed, items_to_recommend, add_rank_col)\u001b[0m\n\u001b[1;32m 130\u001b[0m \u001b[0msorted_item_ids_to_recommend\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 131\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 132\u001b[0;31m reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n\u001b[0m\u001b[1;32m 133\u001b[0m \u001b[0muser_ids\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 134\u001b[0m \u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001b[0m in \u001b[0;36m_recommend_u2i\u001b[0;34m(self, user_ids, dataset, k, filter_viewed, sorted_item_ids_to_recommend)\u001b[0m\n\u001b[1;32m 139\u001b[0m \u001b[0mall_scores\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mtp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mList\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mtarget_id\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0muser_ids\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mverbose\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 141\u001b[0;31m \u001b[0mscores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mscores_calculator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcalc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtarget_id\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 142\u001b[0m reco_ids, reco_scores = recommend_from_scores(\n\u001b[1;32m 143\u001b[0m \u001b[0mscores\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mscores\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001b[0m in \u001b[0;36mcalc\u001b[0;34m(self, subject_id)\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0msubject_factors\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubjects_factors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msubject_id\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdistance\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mDistance\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDOT\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 98\u001b[0;31m \u001b[0mscores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobjects_factors\u001b[0m \u001b[0;34m@\u001b[0m \u001b[0msubject_factors\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 99\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdistance\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mDistance\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mEUCLIDEAN\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0msubject_dot\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubjects_dots\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msubject_id\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", + "\u001B[0;32m/tmp/ipykernel_5286/352742220.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 48\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 49\u001B[0m \u001B[0mstudy\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0moptuna\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcreate_study\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mdirection\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m'maximize'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 50\u001B[0;31m \u001B[0mstudy\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0moptimize\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mobjective\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mn_trials\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;36m100\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001B[0m in \u001B[0;36moptimize\u001B[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 417\u001B[0m \"\"\"\n\u001B[1;32m 418\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 419\u001B[0;31m _optimize(\n\u001B[0m\u001B[1;32m 420\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 421\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_optimize\u001B[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 64\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 65\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mn_jobs\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0;36m1\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 66\u001B[0;31m _optimize_sequential(\n\u001B[0m\u001B[1;32m 67\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 68\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_optimize_sequential\u001B[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001B[0m\n\u001B[1;32m 158\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 159\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 160\u001B[0;31m \u001B[0mfrozen_trial\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0m_run_trial\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mstudy\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcatch\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 161\u001B[0m \u001B[0;32mfinally\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 162\u001B[0m \u001B[0;31m# The following line mitigates memory problems that can be occurred in some\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 232\u001B[0m \u001B[0;32mand\u001B[0m \u001B[0;32mnot\u001B[0m \u001B[0misinstance\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mfunc_err\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcatch\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 233\u001B[0m ):\n\u001B[0;32m--> 234\u001B[0;31m \u001B[0;32mraise\u001B[0m \u001B[0mfunc_err\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 235\u001B[0m \u001B[0;32mreturn\u001B[0m \u001B[0mfrozen_trial\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 236\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 194\u001B[0m \u001B[0;32mwith\u001B[0m \u001B[0mget_heartbeat_thread\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtrial\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_trial_id\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_storage\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 195\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 196\u001B[0;31m \u001B[0mvalue_or_values\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtrial\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 197\u001B[0m \u001B[0;32mexcept\u001B[0m \u001B[0mexceptions\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mTrialPruned\u001B[0m \u001B[0;32mas\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 198\u001B[0m \u001B[0;31m# TODO(mamu): Handle multi-objective cases.\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m/tmp/ipykernel_5286/352742220.py\u001B[0m in \u001B[0;36mobjective\u001B[0;34m(trial)\u001B[0m\n\u001B[1;32m 38\u001B[0m fit_features_together=True)\n\u001B[1;32m 39\u001B[0m \u001B[0mmodel\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mfit\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mdataset\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 40\u001B[0;31m recos = model.recommend(\n\u001B[0m\u001B[1;32m 41\u001B[0m \u001B[0musers\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mTEST_USERS\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 42\u001B[0m \u001B[0mdataset\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mdataset\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001B[0m in \u001B[0;36mrecommend\u001B[0;34m(self, users, dataset, k, filter_viewed, items_to_recommend, add_rank_col)\u001B[0m\n\u001B[1;32m 130\u001B[0m \u001B[0msorted_item_ids_to_recommend\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;32mNone\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 131\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 132\u001B[0;31m reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n\u001B[0m\u001B[1;32m 133\u001B[0m \u001B[0muser_ids\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 134\u001B[0m \u001B[0mdataset\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001B[0m in \u001B[0;36m_recommend_u2i\u001B[0;34m(self, user_ids, dataset, k, filter_viewed, sorted_item_ids_to_recommend)\u001B[0m\n\u001B[1;32m 139\u001B[0m \u001B[0mall_scores\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0mtp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mList\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mndarray\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m[\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 140\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mtarget_id\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mtqdm\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0muser_ids\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mdisable\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mverbose\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0;36m0\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 141\u001B[0;31m \u001B[0mscores\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mscores_calculator\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcalc\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtarget_id\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 142\u001B[0m reco_ids, reco_scores = recommend_from_scores(\n\u001B[1;32m 143\u001B[0m \u001B[0mscores\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mscores\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001B[0m in \u001B[0;36mcalc\u001B[0;34m(self, subject_id)\u001B[0m\n\u001B[1;32m 96\u001B[0m \u001B[0msubject_factors\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msubjects_factors\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0msubject_id\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 97\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdistance\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0mDistance\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mDOT\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 98\u001B[0;31m \u001B[0mscores\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mobjects_factors\u001B[0m \u001B[0;34m@\u001B[0m \u001B[0msubject_factors\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 99\u001B[0m \u001B[0;32melif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdistance\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0mDistance\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mEUCLIDEAN\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 100\u001B[0m \u001B[0msubject_dot\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msubjects_dots\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0msubject_id\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;31mKeyboardInterrupt\u001B[0m: " ] } ], "source": [ - "dataset = Dataset.construct(interactions_df=train,\n", - " user_features_df=user_features,\n", - " cat_user_features=['sex', 'age', 'income'],\n", - " item_features_df=item_features,\n", - " cat_item_features=['content_type', 'genre'])\n", - "TEST_USERS = test[Columns.User].unique()\n", - "\n", - "\n", "def objective(trial):\n", " model_name = trial.suggest_categorical('recomender', ['LightFM',\n", " 'ALS'])\n", @@ -3750,23 +1542,37 @@ }, { "cell_type": "code", - "execution_count": 133, + "execution_count": 233, + "outputs": [], + "source": [ + "REGULARIZATION = 0.00026970098377155163" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 234, "id": "d1f6069a", "metadata": {}, "outputs": [], "source": [ "# обучаем best model после optuna\n", - "model = \\\n", - " ImplicitALSWrapperModel(model=AlternatingLeastSquares(factors=32,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=study.best_params['regularization'\n", - " ]), fit_features_together=True)" + "model = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=32,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=REGULARIZATION\n", + " ),\n", + " fit_features_together=True\n", + ")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 236, "id": "d3907c1d", "metadata": {}, "outputs": [], @@ -3776,16 +1582,17 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": null, "id": "b2050a6e", "metadata": {}, "outputs": [], "source": [ "recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True)" + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True\n", + ")" ] }, { @@ -3822,41 +1629,189 @@ }, { "cell_type": "markdown", - "id": "ab12c89f", - "metadata": {}, "source": [ - " ## Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. " - ] + "# Добавление аватаров\n", + "Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**" + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 216, - "id": "bcdc650a", - "metadata": {}, + "execution_count": 264, "outputs": [], "source": [ - "#pip install --no-binary :all: nmslib" - ] + "some_avatars = pd.DataFrame(\n", + " {\n", + " Columns.User: [11111111, 11111112, 11111113],\n", + " Columns.Item: [\n", + " [10732, 3369, 15885], # Аватар, который любит мультики [губка боб, кунг-фу панда, ]\n", + " [3506, 1107, 11235], # Аватар, который любит боевики [форсаж, обитель зла, плохие парни]\n", + " [931, 389, 8315] # Аватар, который любит драмы [после, хатико, сумерки]\n", + " ],\n", + " 'last_watch_dt': [\n", + " [random.choice(sorted(interactions.last_watch_dt.unique())[-10:]) for _ in range(3)] for i in range(3)\n", + " ],\n", + " \"total_dur\": [\n", + " [34343, 6000, 9000],\n", + " [5000, 45452, 9000],\n", + " [5000, 3200, 3232]\n", + " ],\n", + " \"watched_pct\": [\n", + " [100.0, 95.0, 99.0],\n", + " [67.0, 95.0, 99.0],\n", + " [100.0, 53.0, 99.0]\n", + " ],\n", + " Columns.Weight: [\n", + " [5, 5, 5],\n", + " [3, 5, 5],\n", + " [5, 2, 5]\n", + " ]\n", + " }\n", + ")\n", + "\n", + "some_avatars = some_avatars.explode(\n", + " [Columns.Item, Columns.Datetime, \"total_dur\", \"watched_pct\", Columns.Weight]\n", + ").reset_index(drop=True)" + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 62, - "id": "f6fc49dc", - "metadata": {}, + "execution_count": 265, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "Your CPU supports instructions that this binary was not compiled to use: SSE3 SSE4.1 SSE4.2 AVX AVX2\n", - "For maximum performance, you can install NMSLIB from sources \n", - "pip install --no-binary :all: nmslib\n" - ] + "data": { + "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n0 11111111 10732 2021-08-22 34343 100.0 5\n1 11111111 3369 2021-08-19 6000 95.0 5\n2 11111111 15885 2021-08-17 9000 99.0 5\n3 11111112 3506 2021-08-20 5000 67.0 3\n4 11111112 1107 2021-08-14 45452 95.0 5\n5 11111112 11235 2021-08-19 9000 99.0 5\n6 11111113 931 2021-08-14 5000 100.0 5\n7 11111113 389 2021-08-19 3200 53.0 2\n8 11111113 8315 2021-08-22 3232 99.0 5", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
011111111107322021-08-2234343100.05
11111111133692021-08-19600095.05
211111111158852021-08-17900099.05
31111111235062021-08-20500067.03
41111111211072021-08-144545295.05
511111112112352021-08-19900099.05
6111111139312021-08-145000100.05
7111111133892021-08-19320053.02
81111111383152021-08-22323299.05
\n
" + }, + "execution_count": 265, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "import nmslib\n", - "import time" + "some_avatars" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 266, + "outputs": [], + "source": [ + "interactions_with_avatars = pd.concat([interactions, some_avatars])\n", + "\n", + "dataset_with_avatars = Dataset.construct(\n", + " interactions_df=interactions_with_avatars,\n", + ")\n", + "\n", + "# обучаем best model после optuna\n", + "model_with_avatars = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=32,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=REGULARIZATION\n", + " ),\n", + " fit_features_together=True\n", + ")" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 267, + "outputs": [ + { + "data": { + "text/plain": "" + }, + "execution_count": 267, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_with_avatars.fit(dataset_with_avatars)" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 268, + "outputs": [ + { + "data": { + "text/plain": " user_id item_id score rank\n0 11111111 11985 0.040700 1\n1 11111111 2954 0.039466 2\n2 11111111 7310 0.036591 3\n3 11111111 3182 0.035423 4\n4 11111111 4475 0.034422 5\n5 11111112 7793 0.035639 1\n6 11111112 4702 0.035139 2\n7 11111112 16361 0.034857 3\n8 11111112 1287 0.034327 4\n9 11111112 11018 0.032349 5\n10 11111113 1916 0.245655 1\n11 11111113 14470 0.242786 2\n12 11111113 101 0.219231 3\n13 11111113 12463 0.206615 4\n14 11111113 5732 0.183012 5", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idscorerank
011111111119850.0407001
11111111129540.0394662
21111111173100.0365913
31111111131820.0354234
41111111144750.0344225
51111111277930.0356391
61111111247020.0351392
711111112163610.0348573
81111111212870.0343274
911111112110180.0323495
101111111319160.2456551
1111111113144700.2427862
12111111131010.2192313
1311111113124630.2066154
141111111357320.1830125
\n
" + }, + "execution_count": 268, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recos_with_avatars = model_with_avatars.recommend(\n", + " users=[11111111, 11111112, 11111113],\n", + " dataset=dataset_with_avatars,\n", + " k=5,\n", + " filter_viewed=True\n", + ")\n", + "recos_with_avatars" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 269, + "outputs": [ + { + "data": { + "text/plain": " user_id item_id score rank content_type title \\\n0 11111111 11985 0.040700 1 film История игрушек 4 \n1 11111111 2954 0.039466 2 film Миньоны \n2 11111111 7310 0.036591 3 film Гадкий я 2 \n3 11111111 3182 0.035423 4 film Ральф против Интернета \n4 11111111 4475 0.034422 5 film Тачки \n5 11111112 7793 0.035639 1 film Радиовспышка \n6 11111112 4702 0.035139 2 film Хищник \n7 11111112 16361 0.034857 3 film Doom: Аннигиляция \n8 11111112 1287 0.034327 4 film Терминатор: Тёмные судьбы \n9 11111112 11018 0.032349 5 film Хищники \n10 11111113 1916 0.245655 1 film Секс и ничего лишнего \n11 11111113 14470 0.242786 2 film Любовь \n12 11111113 101 0.219231 3 film Куриоса \n13 11111113 12463 0.206615 4 film Студентка по вызову \n14 11111113 5732 0.183012 5 film Тайное влечение \n\n title_orig release_year \\\n0 Toy Story 4 2019.0 \n1 Minions 2015.0 \n2 Despicable Me 2 2013.0 \n3 Ralph Breaks the Internet 2018.0 \n4 Cars 2006.0 \n5 Radioflash 2019.0 \n6 Predator 1987.0 \n7 Doom: Annihilation 2019.0 \n8 Terminator: Dark Fate 2019.0 \n9 Predators 2010.0 \n10 My Awkward Sexual Adventure 2012.0 \n11 Love 2015.0 \n12 Curiosa 2019.0 \n13 Mes chères études 2010.0 \n14 Adore 2013.0 \n\n genres countries \\\n0 мультфильм, фэнтези, комедии США \n1 фантастика, мультфильм, приключения, комедии США \n2 мультфильм, приключения, фантастика, фэнтези, ... США, Франция, Япония \n3 мультфильм, приключения, фантастика, семейное,... США \n4 спорт, мультфильм, комедии США \n5 боевики, драмы, фантастика, триллеры США \n6 боевики, фантастика, триллеры, приключения США, Мексика \n7 боевики, ужасы, фантастика, триллеры США \n8 боевики, фантастика, приключения США, Китай \n9 боевики, фантастика, триллеры, приключения США \n10 мелодрамы Канада \n11 драмы, мелодрамы Франция \n12 историческое, мелодрамы Франция \n13 драмы, мелодрамы Франция \n14 драмы, мелодрамы Австралия, Франция \n\n for_kids age_rating studios directors \\\n0 NaN 6.0 NaN Джош Кули \n1 NaN 6.0 NaN Кайл Балда, Пьер Коффан \n2 NaN 0.0 NaN Пьер Коффан, Крис Рено \n3 NaN 6.0 NaN Рич Мур, Фил Джонстон \n4 NaN 6.0 NaN Джон Лассетер, Джо Рэнфт \n5 NaN 16.0 NaN Бен Макферсон \n6 NaN 16.0 NaN Джон МакТирнан \n7 NaN 18.0 NaN Тони Гиглио \n8 NaN 16.0 NaN Тим Миллер \n9 NaN 16.0 NaN Нимрод Антал \n10 NaN 18.0 NaN Шон Гэррити \n11 NaN 18.0 NaN Гаспар Ноэ \n12 NaN 18.0 NaN Лу Жене \n13 NaN 18.0 NaN Эмманюэль Берко \n14 NaN 16.0 NaN Анн Фонтен \n\n actors \\\n0 [том хэнкс, тим аллен, энни поттс, тони хейл, ... \n1 [сандра буллок, джон хэмм, майкл китон, эллисо... \n2 [стив карелл, кристен уиг, бенджамин брэтт, ми... \n3 [джон си райли, сара силверман, галь гадот, та... \n4 [оуэн уилсон, пол ньюман, бонни хант, ларри-ка... \n5 [брайтон шарбино, доминик монахэн, уилл пэттон... \n6 [арнольд шварценеггер, карл уэзерс, эльпидия к... \n7 [эми мэнсон, доминик мафэм, люк аллен-гейл, дж... \n8 [линда хэмилтон, арнольд шварценеггер, маккенз... \n9 [эдриан броуди, тофер грейс, алиси брага, уолт... \n10 [джонас черник, эмили хэмпшир, сара мэннинен, ... \n11 [аоми муйок, карл глусман, клара кристин, уго ... \n12 [ноэми мерлан, нильс шнайдер, бенжамен лаверн,... \n13 [дебора франсуа, ален коши, матье деми, бенжам... \n14 [наоми уоттс, робин райт, завьер сэмюэл, джейм... \n\n description \\\n0 Космический рейнджер Баз Лайтер, ковбой Вуди, ... \n1 Миньоны живут на планете гораздо дольше нас. У... \n2 В то время как Грю, бывший суперзлодей, приспо... \n3 На этот раз Ральф и Ванилопа фон Кекс выйдут з... \n4 Неукротимый в своем желании всегда и во всем п... \n5 Риз с легкостью проходит виртуальные квесты, н... \n6 Американский вертолет был сбит партизанами в Ю... \n7 Отряд морпехов прилетает на марсианский спутни... \n8 Мексика. Милая девушка Даниэла Рамос, а для др... \n9 Наемник Ройс невольно вынужден возглавить груп... \n10 Чтобы вернуть свою неудовлетворенную бывшую де... \n11 Любовь вне добра и зла. Любовь — это генетичес... \n12 Историческая драма про любовный треугольник, к... \n13 Лаура — 19-летняя первокурсница французского у... \n14 Главные героини картины – Лил и Роз — две давн... \n\n keywords \\\n0 [игрушка, дружба, ковбой, история игрушек 4, ,... \n1 [помощник, сцена после титров, сцена во время ... \n2 [отношения родитель-ребенок, секретный агент, ... \n3 [видеоигра, мультфильм, продолжение, интернет,... \n4 [автомобильная гонка, трасса 66, porsche, выхо... \n5 [2019, соединенные штаты, радиовспышка] \n6 [центральная и южная америка, хищник, иноплане... \n7 [планета марс, ад, космос, демон, по мотивам в... \n8 [искуственный интеллект, киборг, вертолет, мех... \n9 [охотник, хищник, якудза, охота на людей, иноп... \n10 [нижнее белье, массажистка, секс втроем, фалло... \n11 [париж, франция, секс, сексуальность, галерея,... \n12 [, 1890-е, большой пенис, брак без секса, вдох... \n13 [франция, гостиница, по роману или книге, гост... \n14 [пляж, нагота, любовники, месть, лучший друг, ... \n\n genre \n0 [мультфильм, фэнтези, комедии] \n1 [фантастика, мультфильм, приключения, комедии] \n2 [мультфильм, приключения, фантастика, фэнтези,... \n3 [мультфильм, приключения, фантастика, семейное... \n4 [спорт, мультфильм, комедии] \n5 [боевики, драмы, фантастика, триллеры] \n6 [боевики, фантастика, триллеры, приключения] \n7 [боевики, ужасы, фантастика, триллеры] \n8 [боевики, фантастика, приключения] \n9 [боевики, фантастика, триллеры, приключения] \n10 [мелодрамы] \n11 [драмы, мелодрамы] \n12 [историческое, мелодрамы] \n13 [драмы, мелодрамы] \n14 [драмы, мелодрамы] ", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idscorerankcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywordsgenre
011111111119850.0407001filmИстория игрушек 4Toy Story 42019.0мультфильм, фэнтези, комедииСШАNaN6.0NaNДжош Кули[том хэнкс, тим аллен, энни поттс, тони хейл, ...Космический рейнджер Баз Лайтер, ковбой Вуди, ...[игрушка, дружба, ковбой, история игрушек 4, ,...[мультфильм, фэнтези, комедии]
11111111129540.0394662filmМиньоныMinions2015.0фантастика, мультфильм, приключения, комедииСШАNaN6.0NaNКайл Балда, Пьер Коффан[сандра буллок, джон хэмм, майкл китон, эллисо...Миньоны живут на планете гораздо дольше нас. У...[помощник, сцена после титров, сцена во время ...[фантастика, мультфильм, приключения, комедии]
21111111173100.0365913filmГадкий я 2Despicable Me 22013.0мультфильм, приключения, фантастика, фэнтези, ...США, Франция, ЯпонияNaN0.0NaNПьер Коффан, Крис Рено[стив карелл, кристен уиг, бенджамин брэтт, ми...В то время как Грю, бывший суперзлодей, приспо...[отношения родитель-ребенок, секретный агент, ...[мультфильм, приключения, фантастика, фэнтези,...
31111111131820.0354234filmРальф против ИнтернетаRalph Breaks the Internet2018.0мультфильм, приключения, фантастика, семейное,...СШАNaN6.0NaNРич Мур, Фил Джонстон[джон си райли, сара силверман, галь гадот, та...На этот раз Ральф и Ванилопа фон Кекс выйдут з...[видеоигра, мультфильм, продолжение, интернет,...[мультфильм, приключения, фантастика, семейное...
41111111144750.0344225filmТачкиCars2006.0спорт, мультфильм, комедииСШАNaN6.0NaNДжон Лассетер, Джо Рэнфт[оуэн уилсон, пол ньюман, бонни хант, ларри-ка...Неукротимый в своем желании всегда и во всем п...[автомобильная гонка, трасса 66, porsche, выхо...[спорт, мультфильм, комедии]
51111111277930.0356391filmРадиовспышкаRadioflash2019.0боевики, драмы, фантастика, триллерыСШАNaN16.0NaNБен Макферсон[брайтон шарбино, доминик монахэн, уилл пэттон...Риз с легкостью проходит виртуальные квесты, н...[2019, соединенные штаты, радиовспышка][боевики, драмы, фантастика, триллеры]
61111111247020.0351392filmХищникPredator1987.0боевики, фантастика, триллеры, приключенияСША, МексикаNaN16.0NaNДжон МакТирнан[арнольд шварценеггер, карл уэзерс, эльпидия к...Американский вертолет был сбит партизанами в Ю...[центральная и южная америка, хищник, иноплане...[боевики, фантастика, триллеры, приключения]
711111112163610.0348573filmDoom: АннигиляцияDoom: Annihilation2019.0боевики, ужасы, фантастика, триллерыСШАNaN18.0NaNТони Гиглио[эми мэнсон, доминик мафэм, люк аллен-гейл, дж...Отряд морпехов прилетает на марсианский спутни...[планета марс, ад, космос, демон, по мотивам в...[боевики, ужасы, фантастика, триллеры]
81111111212870.0343274filmТерминатор: Тёмные судьбыTerminator: Dark Fate2019.0боевики, фантастика, приключенияСША, КитайNaN16.0NaNТим Миллер[линда хэмилтон, арнольд шварценеггер, маккенз...Мексика. Милая девушка Даниэла Рамос, а для др...[искуственный интеллект, киборг, вертолет, мех...[боевики, фантастика, приключения]
911111112110180.0323495filmХищникиPredators2010.0боевики, фантастика, триллеры, приключенияСШАNaN16.0NaNНимрод Антал[эдриан броуди, тофер грейс, алиси брага, уолт...Наемник Ройс невольно вынужден возглавить груп...[охотник, хищник, якудза, охота на людей, иноп...[боевики, фантастика, триллеры, приключения]
101111111319160.2456551filmСекс и ничего лишнегоMy Awkward Sexual Adventure2012.0мелодрамыКанадаNaN18.0NaNШон Гэррити[джонас черник, эмили хэмпшир, сара мэннинен, ...Чтобы вернуть свою неудовлетворенную бывшую де...[нижнее белье, массажистка, секс втроем, фалло...[мелодрамы]
1111111113144700.2427862filmЛюбовьLove2015.0драмы, мелодрамыФранцияNaN18.0NaNГаспар Ноэ[аоми муйок, карл глусман, клара кристин, уго ...Любовь вне добра и зла. Любовь — это генетичес...[париж, франция, секс, сексуальность, галерея,...[драмы, мелодрамы]
12111111131010.2192313filmКуриосаCuriosa2019.0историческое, мелодрамыФранцияNaN18.0NaNЛу Жене[ноэми мерлан, нильс шнайдер, бенжамен лаверн,...Историческая драма про любовный треугольник, к...[, 1890-е, большой пенис, брак без секса, вдох...[историческое, мелодрамы]
1311111113124630.2066154filmСтудентка по вызовуMes chères études2010.0драмы, мелодрамыФранцияNaN18.0NaNЭмманюэль Берко[дебора франсуа, ален коши, матье деми, бенжам...Лаура — 19-летняя первокурсница французского у...[франция, гостиница, по роману или книге, гост...[драмы, мелодрамы]
141111111357320.1830125filmТайное влечениеAdore2013.0драмы, мелодрамыАвстралия, ФранцияNaN16.0NaNАнн Фонтен[наоми уоттс, робин райт, завьер сэмюэл, джейм...Главные героини картины – Лил и Роз — две давн...[пляж, нагота, любовники, месть, лучший друг, ...[драмы, мелодрамы]
\n
" + }, + "execution_count": 269, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recos_with_avatars.merge(items, on='item_id', how='left')" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "markdown", + "source": [ + "В целом, все рекомендации к каждому аватару получились неплохие" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "markdown", + "id": "ab12c89f", + "metadata": {}, + "source": [ + " # Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций.\n", + "\n", + "Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", + "Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д" ] }, { @@ -3881,14 +1836,16 @@ "model = LightFMWrapperModel(\n", " LightFM(\n", " k=K,\n", - " no_components=NO_COMPONENTS, \n", - " loss= LOSS, \n", + " no_components=NO_COMPONENTS,\n", + " loss= LOSS,\n", " random_state=RANDOM_STATE,\n", " learning_rate=LEARNING_RATE,\n", " user_alpha=USER_ALPHA,\n", - " item_alpha=ITEM_ALPHA),\n", + " item_alpha=ITEM_ALPHA\n", + " ),\n", " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS) " + " num_threads=NUM_THREADS\n", + ")" ] }, { @@ -4239,7 +2196,7 @@ } ], "source": [ - "# рекомендации для всех пользователей \n", + "# рекомендации для всех пользователей\n", "recos_old_persons = np.array(nbrs, dtype=int)[:,0][:len(nbrs) - 3]\n", "recos_old_persons" ] @@ -4267,7 +2224,7 @@ } ], "source": [ - "# рекомендации для добавленных пользователей \n", + "# рекомендации для добавленных пользователей\n", "recos_new_persons = np.array(nbrs, dtype=int)[:,0][-3:]\n", "recos_new_persons" ] @@ -4400,8 +2357,29 @@ "metadata": {}, "outputs": [], "source": [ - "df_r.to_csv('nmslib.csv.gz', index=False, compression='gzip')" + "df_r.to_csv('nmslib.csv.gz', index=False, compression='gzip')\n" ] + }, + { + "cell_type": "markdown", + "source": [ + "# Холодные пользователи\n", + "Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", + "\n", + "В предыдущей домашке, мы выяснили, что на этом датасете лучше всего себя ведет топ за последний месяц. Поэтому каждую модель мы использовали с подобным методом добивки холодных пользователей\n" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + } } ], "metadata": { From 8f3ed0b722ede4dd08300390fac23123bb233ef1 Mon Sep 17 00:00:00 2001 From: Shakirov Renat Date: Wed, 14 Dec 2022 01:20:40 +0300 Subject: [PATCH 09/12] update ALS and ANN --- notebooks/ALS_LightFM_MF.ipynb | 4187 ++++++----------- ...0\275\320\270\320\265 \342\204\2264.ipynb" | 2406 ---------- 2 files changed, 1345 insertions(+), 5248 deletions(-) delete mode 100644 "notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" diff --git a/notebooks/ALS_LightFM_MF.ipynb b/notebooks/ALS_LightFM_MF.ipynb index c1e10c42..921e134d 100644 --- a/notebooks/ALS_LightFM_MF.ipynb +++ b/notebooks/ALS_LightFM_MF.ipynb @@ -2,8 +2,6 @@ "cells": [ { "cell_type": "markdown", - "id": "7322c9ec", - "metadata": {}, "source": [ "# Домашнее задание\n", "\n", @@ -24,46 +22,40 @@ "## Реализация итоговой модели в сервисе (10 баллов)\n", "- Пробитие бейзлайна $MAP@10 \\geq 0.074921$ **(6 баллов)**\n", "- Код сервиса соответствует критериям читаемости и воспроизводимости **(4 балла)**" - ] + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", "execution_count": 1, - "id": "7780d9a2", - "metadata": {}, "outputs": [], "source": [ "import warnings\n", "warnings.filterwarnings('ignore')" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "6e60b1cf", - "metadata": {}, - "outputs": [], - "source": [ - "# import sys\n", - "# !{sys.executable} -m pip install rectools=0.3.0" - ] + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 246, "id": "e42a5585", "metadata": {}, "outputs": [], "source": [ "import os\n", "import time\n", + "import random\n", "from pathlib import Path\n", "\n", "import numpy as np\n", "import optuna\n", "import pandas as pd\n", "\n", - "# import nmslib\n", + "import nmslib\n", "from implicit.als import AlternatingLeastSquares\n", "from lightfm import LightFM\n", "from rectools import Columns\n", @@ -74,40 +66,27 @@ }, { "cell_type": "code", - "execution_count": 4, - "id": "46bfbe38", + "execution_count": 180, + "id": "8cd36e1a", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'item_id'" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "Columns.Item" + "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"" ] }, { "cell_type": "code", - "execution_count": 3, - "id": "8cd36e1a", + "execution_count": 185, + "id": "4cb722c3", "metadata": {}, "outputs": [], "source": [ - "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"\n", - "Columns.Datetime = 'last_watch_dt'\n", "DATA_PATH = Path(\"../data/kion_train/\")" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 186, "id": "8195e56b", "metadata": {}, "outputs": [ @@ -115,8 +94,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 2.23 s, sys: 464 ms, total: 2.69 s\n", - "Wall time: 2.9 s\n" + "CPU times: user 2.61 s, sys: 924 ms, total: 3.53 s\n", + "Wall time: 5.74 s\n" ] } ], @@ -127,6 +106,16 @@ "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" ] }, + { + "cell_type": "code", + "execution_count": 187, + "id": "01c2bdef", + "metadata": {}, + "outputs": [], + "source": [ + "Columns.Datetime = 'last_watch_dt'" + ] + }, { "cell_type": "markdown", "id": "00b5584e", @@ -137,119 +126,35 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 188, "id": "0a3b4b12", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct\n", - "0 176549 9506 2021-05-11 4250 72.0\n", - "1 699317 1659 2021-05-29 8317 100.0\n", - "2 656683 7107 2021-05-09 10 0.0\n", - "3 864613 7638 2021-07-05 14483 100.0\n", - "4 964868 9506 2021-04-30 6725 100.0" - ] + "text/plain": " user_id item_id last_watch_dt total_dur watched_pct\n0 176549 9506 2021-05-11 4250 72.0\n1 699317 1659 2021-05-29 8317 100.0\n2 656683 7107 2021-05-09 10 0.0\n3 864613 7638 2021-07-05 14483 100.0\n4 964868 9506 2021-04-30 6725 100.0", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
\n
" }, - "execution_count": 5, + "execution_count": 188, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "interactions.head(5)" + "interactions.head()" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 189, "id": "260b1c48", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "user_id int64\n", - "item_id int64\n", - "last_watch_dt object\n", - "total_dur int64\n", - "watched_pct float64\n", - "dtype: object" - ] + "text/plain": "user_id int64\nitem_id int64\nlast_watch_dt object\ntotal_dur int64\nwatched_pct float64\ndtype: object" }, - "execution_count": 6, + "execution_count": 189, "metadata": {}, "output_type": "execute_result" } @@ -260,215 +165,61 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 190, "id": "fe2dbc06", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "user_id 0\n", - "item_id 0\n", - "last_watch_dt 0\n", - "total_dur 0\n", - "watched_pct 828\n", - "dtype: int64" - ] + "text/plain": "user_id 0\nitem_id 0\nlast_watch_dt 0\ntotal_dur 0\nwatched_pct 828\ndtype: int64" }, - "execution_count": 7, + "execution_count": 190, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Количество пустых значений в каждой колонке\n", "interactions.isna().sum()" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 191, "id": "71f61e81", "metadata": {}, "outputs": [], "source": [ - "interactions[Columns.Datetime] = pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')\n", - "interactions.dropna(inplace=True)" + "interactions[Columns.Datetime] = \\\n", + " pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')" ] }, { "cell_type": "code", - "execution_count": 9, - "id": "f98ae95d", + "execution_count": 192, + "id": "39646cb5", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "interactions['watched_pct'].hist(bins=20);" + "interactions.dropna(inplace=True)" ] }, { "cell_type": "code", - "execution_count": 10, - "id": "aa7af6a8", + "execution_count": 193, + "id": "f98ae95d", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
..................
5476246648596122252021-08-13760.0
547624754686296732021-04-13230849.0
5476248697262152972021-08-201830763.0
5476249384202161972021-04-196203100.0
547625031970944362021-08-15392145.0
\n", - "

5475423 rows × 5 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct\n", - "0 176549 9506 2021-05-11 4250 72.0\n", - "1 699317 1659 2021-05-29 8317 100.0\n", - "2 656683 7107 2021-05-09 10 0.0\n", - "3 864613 7638 2021-07-05 14483 100.0\n", - "4 964868 9506 2021-04-30 6725 100.0\n", - "... ... ... ... ... ...\n", - "5476246 648596 12225 2021-08-13 76 0.0\n", - "5476247 546862 9673 2021-04-13 2308 49.0\n", - "5476248 697262 15297 2021-08-20 18307 63.0\n", - "5476249 384202 16197 2021-04-19 6203 100.0\n", - "5476250 319709 4436 2021-08-15 3921 45.0\n", - "\n", - "[5475423 rows x 5 columns]" - ] + "text/plain": "
", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGsCAYAAAAPJKchAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAsU0lEQVR4nO3df3RU5YHG8WcmmUxIMSBEEojB4K+CC4RIShqpp7AmRJYTl3XtWqGSRqUHJbvoHH8QFUiWYigVFt1FOVqBdRWh9Aj+YoFsMCAlggmklaogBY0LJIAcGEjsMGbu/uHJ0OwEyMS585rw/ZzjOZ2b9773nYfAPL33zozDsixLAAAAhjhNLwAAAFzaKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAqC5VRrZu3aqCggINGDBADodD69atC3sOy7L09NNP6/rrr5fb7VZqaqrmzZsX+cUCAIAOiTW9gHA0NTUpIyND99xzj26//fZOzTFjxgxt2rRJTz/9tIYNG6YTJ07oxIkTEV4pAADoKEdX/aI8h8OhtWvXauLEicFtPp9PTzzxhF577TWdPHlSQ4cO1a9+9SuNGTNGkvTxxx9r+PDh2rNnj77//e+bWTgAAGijS12muZji4mJVV1dr1apV+uMf/6if/OQnuvXWW/Xpp59Kkt566y1dffXVevvttzVo0CClp6frvvvu48wIAAAGdZsyUl9fr+XLl2vNmjW6+eabdc011+jhhx/Wj370Iy1fvlySdODAAX3++edas2aNXn75Za1YsUK1tbW64447DK8eAIBLV5e6Z+RCPvzwQ7W0tOj6669vs93n86lv376SpEAgIJ/Pp5dffjk47qWXXtLIkSO1d+9eLt0AAGBAtykjZ86cUUxMjGpraxUTE9PmZz179pQk9e/fX7GxsW0Ky5AhQyR9c2aFMgIAQPR1mzKSmZmplpYWHT16VDfffHO7Y0aPHq2vv/5af/7zn3XNNddIkvbt2ydJuuqqq6K2VgAAcE6XejfNmTNntH//fknflI9FixZp7Nix6tOnjwYOHKif/exn+v3vf6+FCxcqMzNTx44dU2VlpYYPH64JEyYoEAjoBz/4gXr27KnFixcrEAho+vTpSkxM1KZNmww/OwAALk1dqoxUVVVp7NixIdsLCwu1YsUK+f1+/fKXv9TLL7+sQ4cOKSkpST/84Q9VVlamYcOGSZIOHz6sf/7nf9amTZv0ve99T+PHj9fChQvVp0+faD8dAACgLlZGAABA99Nt3toLAAC6JsoIAAAwqku8myYQCOjw4cO67LLL5HA4TC8HAAB0gGVZOn36tAYMGCCn8/znP7pEGTl8+LDS0tJMLwMAAHTCF198oSuvvPK8P+8SZeSyyy6T9M2TSUxMjNi8fr9fmzZt0rhx4+RyuSI2L0KRdXSQc3SQc3SQc3TYmbPX61VaWlrwdfx8ukQZab00k5iYGPEykpCQoMTERH7RbUbW0UHO0UHO0UHO0RGNnC92iwU3sAIAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwKhY0wsAAAAdkz7znYjP6Y6xtGBUxKcNS9hnRrZu3aqCggINGDBADodD69atu+g+Pp9PTzzxhK666iq53W6lp6dr2bJlnVkvAADoZsI+M9LU1KSMjAzdc889uv322zu0zz/90z+psbFRL730kq699lodOXJEgUAg7MUCAIDuJ+wyMn78eI0fP77D4zds2KAtW7bowIED6tOnjyQpPT093MMCAIBuyvZ7Rt58801lZWVpwYIF+q//+i9973vf02233aa5c+eqR48e7e7j8/nk8/mCj71eryTJ7/fL7/dHbG2tc0VyTrSPrKODnKODnKODnEO5Y6zIz+n8Zk47cu7onLaXkQMHDmjbtm2Kj4/X2rVrdfz4cT3wwAP68ssvtXz58nb3KS8vV1lZWcj2TZs2KSEhIeJrrKioiPicaB9ZRwc5Rwc5Rwc5n2PnjaZ25Nzc3NyhcQ7LsjpdsxwOh9auXauJEyeed8y4ceP03nvvqaGhQb169ZIkvf7667rjjjvU1NTU7tmR9s6MpKWl6fjx40pMTOzsckP4/X5VVFQoLy9PLpcrYvMiFFlHBzlHBzlHBzmHGlq6MeJzup2W5mYFbMnZ6/UqKSlJp06duuDrt+1nRvr376/U1NRgEZGkIUOGyLIs/e///q+uu+66kH3cbrfcbnfIdpfLZcsvpF3zIhRZRwc5Rwc5Rwc5n+Nrcdg2tx05d3Q+2z/0bPTo0Tp8+LDOnDkT3LZv3z45nU5deeWVdh8eAAB8x4VdRs6cOaO6ujrV1dVJkg4ePKi6ujrV19dLkkpKSjRlypTg+EmTJqlv374qKirSRx99pK1bt+qRRx7RPffcc94bWAEAwKUj7DJSU1OjzMxMZWZmSpI8Ho8yMzM1e/ZsSdKRI0eCxUSSevbsqYqKCp08eVJZWVmaPHmyCgoK9Oyzz0boKQAAgK4s7HtGxowZowvd87pixYqQbYMHD+ZuaAAA0C6+KA8AABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYFXYZ2bp1qwoKCjRgwAA5HA6tW7euw/v+/ve/V2xsrEaMGBHuYQEAQDcVdhlpampSRkaGlixZEtZ+J0+e1JQpU3TLLbeEe0gAANCNxYa7w/jx4zV+/PiwDzRt2jRNmjRJMTExYZ1NAQAA3VvYZaQzli9frgMHDuiVV17RL3/5y4uO9/l88vl8wcder1eS5Pf75ff7I7au1rkiOSfaR9bRQc7RQc7RQc6h3DFW5Od0fjOnHTl3dE7by8inn36qmTNn6r333lNsbMcOV15errKyspDtmzZtUkJCQqSXqIqKiojPifaRdXSQc3SQc3SQ8zkLRtk3tx05Nzc3d2icrWWkpaVFkyZNUllZma6//voO71dSUiKPxxN87PV6lZaWpnHjxikxMTFi6/P7/aqoqFBeXp5cLlfE5kUoso4Oco4Oco4Ocg41tHRjxOd0Oy3NzQrYknPrlY2LsbWMnD59WjU1Ndq9e7eKi4slSYFAQJZlKTY2Vps2bdLf/u3fhuzndrvldrtDtrtcLlt+ITPnbZavxRHxeT+bPyHic3Z1dv0Zoi1yjg5yjg5yPseO16pWduTc0flsLSOJiYn68MMP22x77rnntHnzZv3ud7/ToEGD7Dw8AADoAsIuI2fOnNH+/fuDjw8ePKi6ujr16dNHAwcOVElJiQ4dOqSXX35ZTqdTQ4cObbN/v379FB8fH7IdAABcmsIuIzU1NRo7dmzwceu9HYWFhVqxYoWOHDmi+vr6yK0QAAB0a2GXkTFjxsiyzv/WohUrVlxw/9LSUpWWloZ7WAAA0E3x3TQAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAo8IuI1u3blVBQYEGDBggh8OhdevWXXD866+/rry8PF1xxRVKTExUTk6ONm7c2Nn1AgCAbibsMtLU1KSMjAwtWbKkQ+O3bt2qvLw8rV+/XrW1tRo7dqwKCgq0e/fusBcLAAC6n9hwdxg/frzGjx/f4fGLFy9u8/ipp57SG2+8obfeekuZmZnhHh4AAHQzYZeRbysQCOj06dPq06fPecf4fD75fL7gY6/XK0ny+/3y+/0RW0vrXG6nFbE525sf57IgE3uRc3SQc3SQcyh3TORfr1pfA+3IuaNzOizL6vQzczgcWrt2rSZOnNjhfRYsWKD58+frk08+Ub9+/dodU1paqrKyspDtK1euVEJCQmeXCwAAoqi5uVmTJk3SqVOnlJiYeN5xUS0jK1eu1NSpU/XGG28oNzf3vOPaOzOSlpam48ePX/DJhMvv96uiokKzapzyBRwRm7fVntL8iM/ZVbVmnZeXJ5fLZXo53RY5Rwc5Rwc5hxpaGvk3gLidluZmBWzJ2ev1Kikp6aJlJGqXaVatWqX77rtPa9asuWARkSS32y232x2y3eVy2fIL6Qs45GuJfBnhL08ou/4M0RY5Rwc5Rwc5n2PHa1UrO3Lu6HxR+ZyR1157TUVFRXrttdc0YcKEaBwSAAB0EWGfGTlz5oz2798ffHzw4EHV1dWpT58+GjhwoEpKSnTo0CG9/PLLkr65NFNYWKhnnnlG2dnZamhokCT16NFDvXr1itDTAAAAXVXYZ0ZqamqUmZkZfFuux+NRZmamZs+eLUk6cuSI6uvrg+NfeOEFff3115o+fbr69+8f/G/GjBkRegoAAKArC/vMyJgxY3She15XrFjR5nFVVVW4hwAAAJcQvpsGAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYFTYZWTr1q0qKCjQgAED5HA4tG7duovuU1VVpRtvvFFut1vXXnutVqxY0YmlAgCA7ijsMtLU1KSMjAwtWbKkQ+MPHjyoCRMmaOzYsaqrq9ODDz6o++67Txs3bgx7sQAAoPuJDXeH8ePHa/z48R0ev3TpUg0aNEgLFy6UJA0ZMkTbtm3Tv/3bvyk/Pz/cwwMAgG4m7DISrurqauXm5rbZlp+frwcffPC8+/h8Pvl8vuBjr9crSfL7/fL7/RFbW+tcbqcVsTnbmx/nsiATe5FzdJBzdJBzKHdM5F+vWl8D7ci5o3PaXkYaGhqUnJzcZltycrK8Xq+++uor9ejRI2Sf8vJylZWVhWzftGmTEhISIr7GuVmBiM8pSevXr7dl3q6soqLC9BIuCeQcHeQcHeR8zoJR9s1tR87Nzc0dGmd7GemMkpISeTye4GOv16u0tDSNGzdOiYmJETuO3+9XRUWFZtU45Qs4IjZvqz2lXIZq1Zp1Xl6eXC6X6eV0W+QcHeQcHeQcamhp5O+3dDstzc0K2JJz65WNi7G9jKSkpKixsbHNtsbGRiUmJrZ7VkSS3G633G53yHaXy2XLL6Qv4JCvJfJlhL88oez6M0Rb5Bwd5Bwd5HyOHa9VrezIuaPz2f45Izk5OaqsrGyzraKiQjk5OXYfGgAAdAFhl5EzZ86orq5OdXV1kr55625dXZ3q6+slfXOJZcqUKcHx06ZN04EDB/Too4/qk08+0XPPPaff/va3euihhyLzDAAAQJcWdhmpqalRZmamMjMzJUkej0eZmZmaPXu2JOnIkSPBYiJJgwYN0jvvvKOKigplZGRo4cKF+s1vfsPbegEAgKRO3DMyZswYWdb531rU3qerjhkzRrt37w73UAAA4BLAd9MAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAoygjAADAKMoIAAAwijICAACMoowAAACjKCMAAMAoyggAADCKMgIAAIyijAAAAKMoIwAAwCjKCAAAMIoyAgAAjKKMAAAAozpVRpYsWaL09HTFx8crOztbO3fuvOD4xYsX6/vf/7569OihtLQ0PfTQQ/rLX/7SqQUDAIDuJewysnr1ank8Hs2ZM0e7du1SRkaG8vPzdfTo0XbHr1y5UjNnztScOXP08ccf66WXXtLq1av1+OOPf+vFAwCAri/sMrJo0SJNnTpVRUVFuuGGG7R06VIlJCRo2bJl7Y7fvn27Ro8erUmTJik9PV3jxo3TXXfdddGzKQAA4NIQG87gs2fPqra2ViUlJcFtTqdTubm5qq6ubnefm266Sa+88op27typUaNG6cCBA1q/fr3uvvvu8x7H5/PJ5/MFH3u9XkmS3++X3+8PZ8kX1DqX22lFbM725se5LMjEXuQcHeQcHeQcyh0T+der1tdAO3Lu6JwOy7I6/MwOHz6s1NRUbd++XTk5OcHtjz76qLZs2aIdO3a0u9+zzz6rhx9+WJZl6euvv9a0adP0/PPPn/c4paWlKisrC9m+cuVKJSQkdHS5AADAoObmZk2aNEmnTp1SYmLieceFdWakM6qqqvTUU0/pueeeU3Z2tvbv368ZM2Zo7ty5mjVrVrv7lJSUyOPxBB97vV6lpaVp3LhxF3wy4fL7/aqoqNCsGqd8AUfE5m21pzQ/4nN2Va1Z5+XlyeVymV5Ot0XO0UHO0UHOoYaWboz4nG6npblZAVtybr2ycTFhlZGkpCTFxMSosbGxzfbGxkalpKS0u8+sWbN0991367777pMkDRs2TE1NTfrFL36hJ554Qk5n6G0rbrdbbrc7ZLvL5bLlF9IXcMjXEvkywl+eUHb9GaItco4Oco4Ocj7HjteqVnbk3NH5wrqBNS4uTiNHjlRlZWVwWyAQUGVlZZvLNn+tubk5pHDExMRIksK4QgQAALqpsC/TeDweFRYWKisrS6NGjdLixYvV1NSkoqIiSdKUKVOUmpqq8vJySVJBQYEWLVqkzMzM4GWaWbNmqaCgIFhKAADApSvsMnLnnXfq2LFjmj17thoaGjRixAht2LBBycnJkqT6+vo2Z0KefPJJORwOPfnkkzp06JCuuOIKFRQUaN68eZF7FgAAoMvq1A2sxcXFKi4ubvdnVVVVbQ8QG6s5c+Zozpw5nTkUAADo5vhuGgAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRnSojS5YsUXp6uuLj45Wdna2dO3decPzJkyc1ffp09e/fX263W9dff73Wr1/fqQUDAIDuJTbcHVavXi2Px6OlS5cqOztbixcvVn5+vvbu3at+/fqFjD979qzy8vLUr18//e53v1Nqaqo+//xz9e7dOxLrBwAAXVzYZWTRokWaOnWqioqKJElLly7VO++8o2XLlmnmzJkh45ctW6YTJ05o+/btcrlckqT09PRvt2oAANBthFVGzp49q9raWpWUlAS3OZ1O5ebmqrq6ut193nzzTeXk5Gj69Ol64403dMUVV2jSpEl67LHHFBMT0+4+Pp9PPp8v+Njr9UqS/H6//H5/OEu+oNa53E4rYnO2Nz/OZUEm9iLn6CDn6CDnUO6YyL9etb4G2pFzR+cMq4wcP35cLS0tSk5ObrM9OTlZn3zySbv7HDhwQJs3b9bkyZO1fv167d+/Xw888ID8fr/mzJnT7j7l5eUqKysL2b5p0yYlJCSEs+QOmZsViPickrgvph0VFRWml3BJIOfoIOfoIOdzFoyyb247cm5ubu7QuLAv04QrEAioX79+euGFFxQTE6ORI0fq0KFD+vWvf33eMlJSUiKPxxN87PV6lZaWpnHjxikxMTFia/P7/aqoqNCsGqd8AUfE5m21pzQ/4nN2Va1Z5+XlBS/XIfLIOTrIOTrIOdTQ0o0Rn9PttDQ3K2BLzq1XNi4mrDKSlJSkmJgYNTY2ttne2NiolJSUdvfp37+/XC5Xm0syQ4YMUUNDg86ePau4uLiQfdxut9xud8h2l8tlyy+kL+CQryXyZYS/PKHs+jNEW+QcHeQcHeR8jh2vVa3syLmj84X11t64uDiNHDlSlZWVwW2BQECVlZXKyclpd5/Ro0dr//79CgTOXQrZt2+f+vfv324RAQAAl5awP2fE4/HoxRdf1H/+53/q448/1v3336+mpqbgu2umTJnS5gbX+++/XydOnNCMGTO0b98+vfPOO3rqqac0ffr0yD0LAADQZYV9z8idd96pY8eOafbs2WpoaNCIESO0YcOG4E2t9fX1cjrPdZy0tDRt3LhRDz30kIYPH67U1FTNmDFDjz32WOSeBQAA6LI6dQNrcXGxiouL2/1ZVVVVyLacnBy9//77nTkUAADo5vhuGgAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYFWt6AQhf+sx3bJv7s/kTbJsbAID2cGYEAAAYRRkBAABGdaqMLFmyROnp6YqPj1d2drZ27tzZof1WrVolh8OhiRMnduawAACgGwq7jKxevVoej0dz5szRrl27lJGRofz8fB09evSC+3322Wd6+OGHdfPNN3d6sQAAoPsJu4wsWrRIU6dOVVFRkW644QYtXbpUCQkJWrZs2Xn3aWlp0eTJk1VWVqarr776Wy0YAAB0L2G9m+bs2bOqra1VSUlJcJvT6VRubq6qq6vPu9+//uu/ql+/frr33nv13nvvXfQ4Pp9PPp8v+Njr9UqS/H6//H5/OEu+oNa53E4rYnO2N3+kuWPsWa9k35pb57VrfnyDnKODnKODnEPZ8e9/62ugHTl3dE6HZVkdfmaHDx9Wamqqtm/frpycnOD2Rx99VFu2bNGOHTtC9tm2bZt++tOfqq6uTklJSfr5z3+ukydPat26dec9TmlpqcrKykK2r1y5UgkJCR1dLgAAMKi5uVmTJk3SqVOnlJiYeN5xtn7OyOnTp3X33XfrxRdfVFJSUof3KykpkcfjCT72er1KS0vTuHHjLvhkwuX3+1VRUaFZNU75Ao6IzdtqT2l+xOeUpKGlG22ZV7Jvza1Z5+XlyeVy2XIMkHO0kHN0kHMoO/79dzstzc0K2JJz65WNiwmrjCQlJSkmJkaNjY1ttjc2NiolJSVk/J///Gd99tlnKigoCG4LBALfHDg2Vnv37tU111wTsp/b7Zbb7Q7Z7nK5bPmF9AUc8rVEvozY9ZfHjrW2svsvvF1/hmiLnKODnKODnM+x+9//SOfc0fnCuoE1Li5OI0eOVGVlZXBbIBBQZWVlm8s2rQYPHqwPP/xQdXV1wf9uu+02jR07VnV1dUpLSwvn8AAAoBsK+zKNx+NRYWGhsrKyNGrUKC1evFhNTU0qKiqSJE2ZMkWpqakqLy9XfHy8hg4d2mb/3r17S1LIdgAAcGkKu4zceeedOnbsmGbPnq2GhgaNGDFCGzZsUHJysiSpvr5eTicf7AoAADqmUzewFhcXq7i4uN2fVVVVXXDfFStWdOaQAACgm+Jbe21k57frAgDQXXA9BQAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGAUZQQAABhFGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRnSojS5YsUXp6uuLj45Wdna2dO3eed+yLL76om2++WZdffrkuv/xy5ebmXnA8AAC4tIRdRlavXi2Px6M5c+Zo165dysjIUH5+vo4ePdru+KqqKt1111169913VV1drbS0NI0bN06HDh361osHAABdX9hlZNGiRZo6daqKiop0ww03aOnSpUpISNCyZcvaHf/qq6/qgQce0IgRIzR48GD95je/USAQUGVl5bdePAAA6Ppiwxl89uxZ1dbWqqSkJLjN6XQqNzdX1dXVHZqjublZfr9fffr0Oe8Yn88nn88XfOz1eiVJfr9ffr8/nCVfUOtcbqcVsTm7ukjm2968ds2Pb5BzdJBzdJBzKHdM5F+vWl8D7ci5o3M6LMvq8DM7fPiwUlNTtX37duXk5AS3P/roo9qyZYt27Nhx0TkeeOABbdy4UX/6058UHx/f7pjS0lKVlZWFbF+5cqUSEhI6ulwAAGBQc3OzJk2apFOnTikxMfG848I6M/JtzZ8/X6tWrVJVVdV5i4gklZSUyOPxBB97vd7gvSYXejLh8vv9qqio0Kwap3wBR8Tm7cr2lObbMm9r1nl5eXK5XLYcA+QcLeQcHeQcamjpxojP6XZampsVsCXn1isbFxNWGUlKSlJMTIwaGxvbbG9sbFRKSsoF93366ac1f/58/c///I+GDx9+wbFut1tutztku8vlsuUX0hdwyNdCGZFk+194u/4M0RY5Rwc5Rwc5n2Pna5UdOXd0vrBuYI2Li9PIkSPb3HzaejPqX1+2+f8WLFiguXPnasOGDcrKygrnkAAAoJsL+zKNx+NRYWGhsrKyNGrUKC1evFhNTU0qKiqSJE2ZMkWpqakqLy+XJP3qV7/S7NmztXLlSqWnp6uhoUGS1LNnT/Xs2TOCTwWRkD7zHVvmdcdYWjDKlqkBAF1c2GXkzjvv1LFjxzR79mw1NDRoxIgR2rBhg5KTkyVJ9fX1cjrPnXB5/vnndfbsWd1xxx1t5pkzZ45KS0u/3eoBAECX16kbWIuLi1VcXNzuz6qqqto8/uyzzzpzCAAAcIngu2kAAIBRlBEAAGAUZQQAABgV1Q89A+xg1zuAJOmz+RNsmxsA8A3KCAAAEWTn/0HqrigjiKqhpRv5tFsAQBvcMwIAAIyijAAAAKMoIwAAwCjuGQEuwK4b0XiXDgCcw5kRAABgFGdGABjHGSjg0saZEQAAYBRnRgAD7DoT4I6xtGCULVMDgG04MwIAAIzizAjQDdnxSbfcfwHALpQRAOgkSl/XxnfIfHdwmQYAABjFmREAwLdmx1kGbsi+dHBmBAAAGEUZAQAARnGZBkCHcLMfTLHjRmF8t1BGAHRbfLhcWxRKfFdxmQYAABjFmREA+A7h7AUuRZwZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGBUp8rIkiVLlJ6ervj4eGVnZ2vnzp0XHL9mzRoNHjxY8fHxGjZsmNavX9+pxQIAgO4n7DKyevVqeTwezZkzR7t27VJGRoby8/N19OjRdsdv375dd911l+69917t3r1bEydO1MSJE7Vnz55vvXgAAND1hV1GFi1apKlTp6qoqEg33HCDli5dqoSEBC1btqzd8c8884xuvfVWPfLIIxoyZIjmzp2rG2+8Uf/xH//xrRcPAAC6vrA+Dv7s2bOqra1VSUlJcJvT6VRubq6qq6vb3ae6uloej6fNtvz8fK1bt+68x/H5fPL5fMHHp06dkiSdOHFCfr8/nCVfkN/vV3Nzs2L9TrUE+EZIO8UGLDU3B8jaZuQcHeQcHeQcHa05f/nll3K5XBGd+/Tp05Iky7IuvIZwJj1+/LhaWlqUnJzcZntycrI++eSTdvdpaGhod3xDQ8N5j1NeXq6ysrKQ7YMGDQpnufiOmWR6AZcIco4Oco4Oco4Ou3M+ffq0evXqdd6ffye/KK+kpKTN2ZRAIKATJ06ob9++cjgi1469Xq/S0tL0xRdfKDExMWLzIhRZRwc5Rwc5Rwc5R4edOVuWpdOnT2vAgAEXHBdWGUlKSlJMTIwaGxvbbG9sbFRKSkq7+6SkpIQ1XpLcbrfcbnebbb179w5nqWFJTEzkFz1KyDo6yDk6yDk6yDk67Mr5QmdEWoV1A2tcXJxGjhypysrK4LZAIKDKykrl5OS0u09OTk6b8ZJUUVFx3vEAAODSEvZlGo/Ho8LCQmVlZWnUqFFavHixmpqaVFRUJEmaMmWKUlNTVV5eLkmaMWOGfvzjH2vhwoWaMGGCVq1apZqaGr3wwguRfSYAAKBLCruM3HnnnTp27Jhmz56thoYGjRgxQhs2bAjepFpfXy+n89wJl5tuukkrV67Uk08+qccff1zXXXed1q1bp6FDh0buWXSS2+3WnDlzQi4JIfLIOjrIOTrIOTrIOTq+Czk7rIu93wYAAMBGfDcNAAAwijICAACMoowAAACjKCMAAMCoS7qMLFmyROnp6YqPj1d2drZ27txpekldWnl5uX7wgx/osssuU79+/TRx4kTt3bu3zZi//OUvmj59uvr27auePXvqH//xH0M+FA/hmT9/vhwOhx588MHgNnKOjEOHDulnP/uZ+vbtqx49emjYsGGqqakJ/tyyLM2ePVv9+/dXjx49lJubq08//dTgiruelpYWzZo1S4MGDVKPHj10zTXXaO7cuW2+y4ScO2fr1q0qKCjQgAED5HA4Qr4TriO5njhxQpMnT1ZiYqJ69+6te++9V2fOnIn8Yq1L1KpVq6y4uDhr2bJl1p/+9Cdr6tSpVu/eva3GxkbTS+uy8vPzreXLl1t79uyx6urqrL/7u7+zBg4caJ05cyY4Ztq0aVZaWppVWVlp1dTUWD/84Q+tm266yeCqu7adO3da6enp1vDhw60ZM2YEt5Pzt3fixAnrqquusn7+859bO3bssA4cOGBt3LjR2r9/f3DM/PnzrV69elnr1q2z/vCHP1i33XabNWjQIOurr74yuPKuZd68eVbfvn2tt99+2zp48KC1Zs0aq2fPntYzzzwTHEPOnbN+/XrriSeesF5//XVLkrV27do2P+9IrrfeequVkZFhvf/++9Z7771nXXvttdZdd90V8bVesmVk1KhR1vTp04OPW1parAEDBljl5eUGV9W9HD161JJkbdmyxbIsyzp58qTlcrmsNWvWBMd8/PHHliSrurra1DK7rNOnT1vXXXedVVFRYf34xz8OlhFyjozHHnvM+tGPfnTenwcCASslJcX69a9/Hdx28uRJy+12W6+99lo0ltgtTJgwwbrnnnvabLv99tutyZMnW5ZFzpHy/8tIR3L96KOPLEnWBx98EBzz3//935bD4bAOHToU0fVdkpdpzp49q9raWuXm5ga3OZ1O5ebmqrq62uDKupdTp05Jkvr06SNJqq2tld/vb5P74MGDNXDgQHLvhOnTp2vChAlt8pTIOVLefPNNZWVl6Sc/+Yn69eunzMxMvfjii8GfHzx4UA0NDW1y7tWrl7Kzs8k5DDfddJMqKyu1b98+SdIf/vAHbdu2TePHj5dEznbpSK7V1dXq3bu3srKygmNyc3PldDq1Y8eOiK7nO/mtvXY7fvy4Wlpagp8a2yo5OVmffPKJoVV1L4FAQA8++KBGjx4d/LTdhoYGxcXFhXzpYXJyshoaGgyssutatWqVdu3apQ8++CDkZ+QcGQcOHNDzzz8vj8ejxx9/XB988IH+5V/+RXFxcSosLAxm2d6/I+TccTNnzpTX69XgwYMVExOjlpYWzZs3T5MnT5YkcrZJR3JtaGhQv3792vw8NjZWffr0iXj2l2QZgf2mT5+uPXv2aNu2baaX0u188cUXmjFjhioqKhQfH296Od1WIBBQVlaWnnrqKUlSZmam9uzZo6VLl6qwsNDw6rqP3/72t3r11Ve1cuVK/c3f/I3q6ur04IMPasCAAeR8CbkkL9MkJSUpJiYm5N0FjY2NSklJMbSq7qO4uFhvv/223n33XV155ZXB7SkpKTp79qxOnjzZZjy5h6e2tlZHjx7VjTfeqNjYWMXGxmrLli169tlnFRsbq+TkZHKOgP79++uGG25os23IkCGqr6+XpGCW/Dvy7TzyyCOaOXOmfvrTn2rYsGG6++679dBDDwW/bJWc7dGRXFNSUnT06NE2P//666914sSJiGd/SZaRuLg4jRw5UpWVlcFtgUBAlZWVysnJMbiyrs2yLBUXF2vt2rXavHmzBg0a1ObnI0eOlMvlapP73r17VV9fT+5huOWWW/Thhx+qrq4u+F9WVpYmT54c/N/k/O2NHj065K3p+/bt01VXXSVJGjRokFJSUtrk7PV6tWPHDnIOQ3Nzc5svV5WkmJgYBQIBSeRsl47kmpOTo5MnT6q2tjY4ZvPmzQoEAsrOzo7sgiJ6O2wXsmrVKsvtdlsrVqywPvroI+sXv/iF1bt3b6uhocH00rqs+++/3+rVq5dVVVVlHTlyJPhfc3NzcMy0adOsgQMHWps3b7ZqamqsnJwcKycnx+Cqu4e/fjeNZZFzJOzcudOKjY215s2bZ3366afWq6++aiUkJFivvPJKcMz8+fOt3r17W2+88Yb1xz/+0fr7v/973nIapsLCQis1NTX41t7XX3/dSkpKsh599NHgGHLunNOnT1u7d++2du/ebUmyFi1aZO3evdv6/PPPLcvqWK633nqrlZmZae3YscPatm2bdd111/HW3kj793//d2vgwIFWXFycNWrUKOv99983vaQuTVK7/y1fvjw45quvvrIeeOAB6/LLL7cSEhKsf/iHf7COHDlibtHdxP8vI+QcGW+99ZY1dOhQy+12W4MHD7ZeeOGFNj8PBALWrFmzrOTkZMvtdlu33HKLtXfvXkOr7Zq8Xq81Y8YMa+DAgVZ8fLx19dVXW0888YTl8/mCY8i5c9599912/00uLCy0LKtjuX755ZfWXXfdZfXs2dNKTEy0ioqKrNOnT0d8rQ7L+quPuQMAAIiyS/KeEQAA8N1BGQEAAEZRRgAAgFGUEQAAYBRlBAAAGEUZAQAARlFGAACAUZQRAABgFGUEAAAYRRkBAABGUUYAAIBRlBEAAGDU/wEIAqfNOovLdgAAAABJRU5ErkJggg==\n" }, - "execution_count": 10, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ - "interactions" + "interactions['watched_pct'].hist(bins=20);" ] }, { @@ -476,16 +227,16 @@ "id": "1a0ad9f8", "metadata": {}, "source": [ - "Разбиваем длительность просмотра на 5 частей, где:\n", - " - от 0% до 20% = 1,\n", - " - от 21% до 40% = 2,\n", - " - ... ,\n", - " - от 80% до 100% = 5" + "Делю график просмотра на 5 категорий, где:\n", + "от 0% до 20% = 1,\n", + "от 21% до 40% = 2,\n", + "... ,\n", + "от 80% до 100% = 5" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 194, "id": "1424e744", "metadata": {}, "outputs": [], @@ -499,16 +250,14 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 196, "id": "052d2fb0", "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAGdCAYAAAD+JxxnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAuRklEQVR4nO3df3DU9Z3H8VcSkg0BNgiaxJQAuUOFCBIJJa6tFjFkpRlHjjil6mkOEQ+aOIadw5or5Ye0F4dTfrTE5q4C0VFHwDutEgtJw4BaFpFAKj8KVUsn3pBNbBWi/Nisyff+6OQrS5Bkk11D8nk+ZjJ0v9/3fr7vvBvCy+9+v7tRlmVZAgAAMFB0bzcAAADQWwhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjDejtBi5nbW1tOnHihIYMGaKoqKjebgcAAHSBZVn6/PPPlZqaqujoS5/zIQhdwokTJ5SWltbbbQAAgG74+OOPNWLEiEvWEIQuYciQIZL+Pkin09nL3Vz+AoGAqqqqlJubq9jY2N5up09jlpHDbMOHWUYGc+255uZmpaWl2f+OXwpB6BLaXw5zOp0EoS4IBAJKSEiQ0+nkL28PMcvIYbbhwywjg7mGT1cua+FiaQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjDejtBgAAwOVt9OOVEVv7L0/mRWztruCMEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAY4UUhJYtW6aoqKigr7Fjx9r7z507p8LCQg0fPlyDBw9Wfn6+Ghsbg9aor69XXl6eEhISlJSUpEWLFunLL78Mqtm5c6cmTZokh8OhMWPGqKKiokMvZWVlGj16tOLj45Wdna29e/cG7e9KLwAAwGwhnxG6/vrr1dDQYH+988479r6FCxfqjTfe0JYtW7Rr1y6dOHFCs2bNsve3trYqLy9PLS0t2r17t5577jlVVFRoyZIlds3x48eVl5en2267TXV1dSouLtZDDz2k7du32zWbNm2Sx+PR0qVLtX//fk2cOFFut1tNTU1d7gUAACDkIDRgwAClpKTYX1deeaUk6dSpU1q/fr1WrVqladOmKSsrSxs3btTu3bu1Z88eSVJVVZWOHDmiF154QZmZmZoxY4ZWrFihsrIytbS0SJLKy8uVnp6up59+WuPGjVNRUZHuvvturV692u5h1apVmjdvnubMmaOMjAyVl5crISFBGzZs6HIvAAAAA0J9wgcffKDU1FTFx8fL5XKptLRUI0eOVG1trQKBgHJycuzasWPHauTIkfJ6vbrpppvk9Xo1YcIEJScn2zVut1sLFizQ4cOHdeONN8rr9Qat0V5TXFwsSWppaVFtba1KSkrs/dHR0crJyZHX65WkLvVyMX6/X36/337c3NwsSQoEAgoEAqGOyjjtM2JWPccsI4fZhg+zjIzLca6OGCtia0fi+wxlzZCCUHZ2tioqKnTdddepoaFBy5cv1y233KJDhw7J5/MpLi5OQ4cODXpOcnKyfD6fJMnn8wWFoPb97fsuVdPc3KyzZ8/qs88+U2tr60Vrjh49aq/RWS8XU1paquXLl3fYXlVVpYSEhK99HoJVV1f3dgv9BrOMHGYbPswyMi6nua6cErm133zzzbCveebMmS7XhhSEZsyYYf/vG264QdnZ2Ro1apQ2b96sgQMHhrLUZamkpEQej8d+3NzcrLS0NOXm5srpdPZiZ31DIBBQdXW1pk+frtjY2N5up09jlpHDbMOHWUbG5TjX8cu2d17UTYeWucO+ZvsrOl0R8ktj5xs6dKiuvfZaffjhh5o+fbpaWlp08uTJoDMxjY2NSklJkSSlpKR0uLur/U6u82suvLursbFRTqdTAwcOVExMjGJiYi5ac/4anfVyMQ6HQw6Ho8P22NjYy+aHsS9gXuHDLCOH2YYPs4yMy2mu/taoiK0die8xlDV79D5CX3zxhT766CNdffXVysrKUmxsrGpqauz9x44dU319vVwulyTJ5XLp4MGDQXd3VVdXy+l0KiMjw645f432mvY14uLilJWVFVTT1tammpoau6YrvQAAAIR0Rujf/u3fdOedd2rUqFE6ceKEli5dqpiYGN1zzz1KTEzU3Llz5fF4NGzYMDmdTj3yyCNyuVz2xcm5ubnKyMjQ/fffr5UrV8rn82nx4sUqLCy0z8TMnz9f69at02OPPaYHH3xQO3bs0ObNm1VZWWn34fF4VFBQoMmTJ2vKlClas2aNTp8+rTlz5khSl3oBAAAIKQj93//9n+655x797W9/01VXXaXvfve72rNnj6666ipJ0urVqxUdHa38/Hz5/X653W4988wz9vNjYmK0detWLViwQC6XS4MGDVJBQYGeeOIJuyY9PV2VlZVauHCh1q5dqxEjRujZZ5+V2/3Va4izZ8/WJ598oiVLlsjn8ykzM1Pbtm0LuoC6s14AAABCCkIvv/zyJffHx8errKxMZWVlX1szatSoTq8Qnzp1qg4cOHDJmqKiIhUVFfWoFwAAYDY+awwAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABhrQG83AAAAwmP045W93UKfwxkhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAs3lkaAIBvUGfv/uyIsbRyijR+2Xb5W6O+oa7MxRkhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFg9CkJPPvmkoqKiVFxcbG87d+6cCgsLNXz4cA0ePFj5+flqbGwMel59fb3y8vKUkJCgpKQkLVq0SF9++WVQzc6dOzVp0iQ5HA6NGTNGFRUVHY5fVlam0aNHKz4+XtnZ2dq7d2/Q/q70AgAAzDWgu09877339F//9V+64YYbgrYvXLhQlZWV2rJlixITE1VUVKRZs2bp97//vSSptbVVeXl5SklJ0e7du9XQ0KAHHnhAsbGx+o//+A9J0vHjx5WXl6f58+frxRdfVE1NjR566CFdffXVcrvdkqRNmzbJ4/GovLxc2dnZWrNmjdxut44dO6akpKQu9QIA+MroxytDqnfEWFo5RRq/bLv8rVGXrP3Lk3k9aQ2ImG6dEfriiy9033336de//rWuuOIKe/upU6e0fv16rVq1StOmTVNWVpY2btyo3bt3a8+ePZKkqqoqHTlyRC+88IIyMzM1Y8YMrVixQmVlZWppaZEklZeXKz09XU8//bTGjRunoqIi3X333Vq9erV9rFWrVmnevHmaM2eOMjIyVF5eroSEBG3YsKHLvQAAALN164xQYWGh8vLylJOTo5/97Gf29traWgUCAeXk5Njbxo4dq5EjR8rr9eqmm26S1+vVhAkTlJycbNe43W4tWLBAhw8f1o033iiv1xu0RntN+0twLS0tqq2tVUlJib0/OjpaOTk58nq9Xe7lQn6/X36/337c3NwsSQoEAgoEAt0ZlVHaZ8Sseo5ZRg6z/XqOGCu0+mgr6M9LYd5f6WzOocy1P4jEz0Yoa4YchF5++WXt379f7733Xod9Pp9PcXFxGjp0aND25ORk+Xw+u+b8ENS+v33fpWqam5t19uxZffbZZ2ptbb1ozdGjR7vcy4VKS0u1fPnyDturqqqUkJBw0eego+rq6t5uod9glpHDbDtaOaV7z1sxua3TmjfffLN7i/dDXZ1zV+baH0TiZ+PMmTNdrg0pCH388cd69NFHVV1drfj4+JAbu9yVlJTI4/HYj5ubm5WWlqbc3Fw5nc5e7KxvCAQCqq6u1vTp0xUbG9vb7fRpzDJymO3XG79se0j1jmhLKya36af7ouVvu/Q1QoeWuXvSWr/S2ZxDmWt/EImfjfZXdLoipCBUW1urpqYmTZo0yd7W2tqqt956S+vWrdP27dvV0tKikydPBp2JaWxsVEpKiiQpJSWlw91d7XdynV9z4d1djY2NcjqdGjhwoGJiYhQTE3PRmvPX6KyXCzkcDjkcjg7bY2Nj+YUZAuYVPswycphtR51d8Py1z2uL6vS5zPorXZ1zV+baH0TiZyOUNUO6WPr222/XwYMHVVdXZ39NnjxZ9913n/2/Y2NjVVNTYz/n2LFjqq+vl8vlkiS5XC4dPHhQTU1Ndk11dbWcTqcyMjLsmvPXaK9pXyMuLk5ZWVlBNW1tbaqpqbFrsrKyOu0FAACYLaQzQkOGDNH48eODtg0aNEjDhw+3t8+dO1cej0fDhg2T0+nUI488IpfLZV+cnJubq4yMDN1///1auXKlfD6fFi9erMLCQvtszPz587Vu3To99thjevDBB7Vjxw5t3rxZlZVf3drp8XhUUFCgyZMna8qUKVqzZo1Onz6tOXPmSJISExM77QUAAJit2+8j9HVWr16t6Oho5efny+/3y+1265lnnrH3x8TEaOvWrVqwYIFcLpcGDRqkgoICPfHEE3ZNenq6KisrtXDhQq1du1YjRozQs88+a7+HkCTNnj1bn3zyiZYsWSKfz6fMzExt27Yt6ALqznoBAABm63EQ2rlzZ9Dj+Ph4lZWVqays7GufM2rUqE6vEp86daoOHDhwyZqioiIVFRV97f6u9AIAAMwV9jNCAAD0B6G+0zb6Jj50FQAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICx+PR5AECfxSfEo6c4IwQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYa0BvNwAA6P9GP17Z2y0AF8UZIQAAYCzOCAFAH8KZFSC8OCMEAACMxRkhAIgAztwAfQNnhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxQgpCv/rVr3TDDTfI6XTK6XTK5XLpt7/9rb3/3LlzKiws1PDhwzV48GDl5+ersbExaI36+nrl5eUpISFBSUlJWrRokb788sugmp07d2rSpElyOBwaM2aMKioqOvRSVlam0aNHKz4+XtnZ2dq7d2/Q/q70AgAAzBZSEBoxYoSefPJJ1dbWat++fZo2bZruuusuHT58WJK0cOFCvfHGG9qyZYt27dqlEydOaNasWfbzW1tblZeXp5aWFu3evVvPPfecKioqtGTJErvm+PHjysvL02233aa6ujoVFxfroYce0vbt2+2aTZs2yePxaOnSpdq/f78mTpwot9utpqYmu6azXgAAAEIKQnfeeae+//3v65prrtG1116rn//85xo8eLD27NmjU6dOaf369Vq1apWmTZumrKwsbdy4Ubt379aePXskSVVVVTpy5IheeOEFZWZmasaMGVqxYoXKysrU0tIiSSovL1d6erqefvppjRs3TkVFRbr77ru1evVqu49Vq1Zp3rx5mjNnjjIyMlReXq6EhARt2LBBkrrUCwAAwIDuPrG1tVVbtmzR6dOn5XK5VFtbq0AgoJycHLtm7NixGjlypLxer2666SZ5vV5NmDBBycnJdo3b7daCBQt0+PBh3XjjjfJ6vUFrtNcUFxdLklpaWlRbW6uSkhJ7f3R0tHJycuT1eiWpS71cjN/vl9/vtx83NzdLkgKBgAKBQDcnZY72GTGrnmOWkfNNzdYRY0V0/cuBI9oK+hPhYdpcI/F3MZQ1Qw5CBw8elMvl0rlz5zR48GC9+uqrysjIUF1dneLi4jR06NCg+uTkZPl8PkmSz+cLCkHt+9v3XaqmublZZ8+e1WeffabW1taL1hw9etReo7NeLqa0tFTLly/vsL2qqkoJCQlf+zwEq66u7u0W+g1mGTmRnu3KKRFd/rKyYnJbb7fQL5ky1zfffDPsa545c6bLtSEHoeuuu051dXU6deqUXnnlFRUUFGjXrl2hLnNZKikpkcfjsR83NzcrLS1Nubm5cjqdvdhZ3xAIBFRdXa3p06crNja2t9vp05hl5HxTsx2/bHvnRX2cI9rSislt+um+aPnbonq7nX7DtLkeWuYO+5rtr+h0RchBKC4uTmPGjJEkZWVl6b333tPatWs1e/ZstbS06OTJk0FnYhobG5WSkiJJSklJ6XB3V/udXOfXXHh3V2Njo5xOpwYOHKiYmBjFxMRctOb8NTrr5WIcDoccDkeH7bGxsfxjFALmFT7MMnIiPVt/a///B6ydvy3KqO/3m2LKXCPx9zCUNbt9jVC7trY2+f1+ZWVlKTY2VjU1NcrPz5ckHTt2TPX19XK5XJIkl8uln//852pqalJSUpKkv5+edjqdysjIsGsuPE1WXV1trxEXF6esrCzV1NRo5syZdg81NTUqKiqSpC71AgCjH6/s7RYA9LKQglBJSYlmzJihkSNH6vPPP9dLL72knTt3avv27UpMTNTcuXPl8Xg0bNgwOZ1OPfLII3K5XPbFybm5ucrIyND999+vlStXyufzafHixSosLLTPxMyfP1/r1q3TY489pgcffFA7duzQ5s2bVVn51S8sj8ejgoICTZ48WVOmTNGaNWt0+vRpzZkzR5K61AsAAEBIQaipqUkPPPCAGhoalJiYqBtuuEHbt2/X9OnTJUmrV69WdHS08vPz5ff75Xa79cwzz9jPj4mJ0datW7VgwQK5XC4NGjRIBQUFeuKJJ+ya9PR0VVZWauHChVq7dq1GjBihZ599Vm73V68hzp49W5988omWLFkin8+nzMxMbdu2LegC6s56AQAACCkIrV+//pL74+PjVVZWprKysq+tGTVqVKdXiE+dOlUHDhy4ZE1RUZH9Ulh3ewEAAGbjs8YAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADDWgN5uAAA6M/rxyrCt5YixtHKKNH7ZdklRYVsXQN8U0hmh0tJSffvb39aQIUOUlJSkmTNn6tixY0E1586dU2FhoYYPH67BgwcrPz9fjY2NQTX19fXKy8tTQkKCkpKStGjRIn355ZdBNTt37tSkSZPkcDg0ZswYVVRUdOinrKxMo0ePVnx8vLKzs7V3796QewEAAOYKKQjt2rVLhYWF2rNnj6qrqxUIBJSbm6vTp0/bNQsXLtQbb7yhLVu2aNeuXTpx4oRmzZpl729tbVVeXp5aWlq0e/duPffcc6qoqNCSJUvsmuPHjysvL0+33Xab6urqVFxcrIceekjbt2+3azZt2iSPx6OlS5dq//79mjhxotxut5qamrrcCwAAMFtIL41t27Yt6HFFRYWSkpJUW1urW2+9VadOndL69ev10ksvadq0aZKkjRs3aty4cdqzZ49uuukmVVVV6ciRI/rd736n5ORkZWZmasWKFfrxj3+sZcuWKS4uTuXl5UpPT9fTTz8tSRo3bpzeeecdrV69Wm63W5K0atUqzZs3T3PmzJEklZeXq7KyUhs2bNDjjz/epV4AAIDZenSN0KlTpyRJw4YNkyTV1tYqEAgoJyfHrhk7dqxGjhwpr9erm266SV6vVxMmTFBycrJd43a7tWDBAh0+fFg33nijvF5v0BrtNcXFxZKklpYW1dbWqqSkxN4fHR2tnJwceb3eLvdyIb/fL7/fbz9ubm6WJAUCAQUCgW7NyCTtM2JWPccsgzlirPCtFW0F/YnuY5aRYdpcI/F7LpQ1ux2E2traVFxcrO985zsaP368JMnn8ykuLk5Dhw4Nqk1OTpbP57Nrzg9B7fvb912qprm5WWfPntVnn32m1tbWi9YcPXq0y71cqLS0VMuXL++wvaqqSgkJCV83Clygurq6t1voN5jl362cEv41V0xuC/+ihmKWkWHKXN98882wr3nmzJku13Y7CBUWFurQoUN65513urvEZaekpEQej8d+3NzcrLS0NOXm5srpdPZiZ31DIBBQdXW1pk+frtjY2N5up0/LemKbVkxu00/3RcvfFt47mw4tc4d1vW/C3+/wCg9HtBWx2ZqGWUaGaXONxO+k9ld0uqJbQaioqEhbt27VW2+9pREjRtjbU1JS1NLSopMnTwadiWlsbFRKSopdc+HdXe13cp1fc+HdXY2NjXI6nRo4cKBiYmIUExNz0Zrz1+islws5HA45HI4O22NjY/mHPQTMq+faf/n526Lkbw3vL8K++P9NuGcgRWa2pmKWkWHKXCPxOymUNUO6a8yyLBUVFenVV1/Vjh07lJ6eHrQ/KytLsbGxqqmpsbcdO3ZM9fX1crlckiSXy6WDBw8G3d1VXV0tp9OpjIwMu+b8Ndpr2teIi4tTVlZWUE1bW5tqamrsmq70AgAAzBbSGaHCwkK99NJL+s1vfqMhQ4bY19okJiZq4MCBSkxM1Ny5c+XxeDRs2DA5nU498sgjcrlc9sXJubm5ysjI0P3336+VK1fK5/Np8eLFKiwstM/GzJ8/X+vWrdNjjz2mBx98UDt27NDmzZtVWfnVm6p5PB4VFBRo8uTJmjJlitasWaPTp0/bd5F1pRcA4RPONz0EgG9KSEHoV7/6lSRp6tSpQds3btyof/mXf5EkrV69WtHR0crPz5ff75fb7dYzzzxj18bExGjr1q1asGCBXC6XBg0apIKCAj3xxBN2TXp6uiorK7Vw4UKtXbtWI0aM0LPPPmvfOi9Js2fP1ieffKIlS5bI5/MpMzNT27ZtC7qAurNeAACA2UIKQpbV+a188fHxKisrU1lZ2dfWjBo1qtOrxKdOnaoDBw5csqaoqEhFRUU96gUAAJiLD10FAADGIggBAABj8enzgGG4qBkAvkIQAnogUqHCERORZQEAF+ClMQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxhrQ2w0AkTb68crebgEAcJnijBAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLG4fb4XReq27r88mReRdQEA6G84IwQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjMU7S/dDkXrHaimy71odyb4BALgYghBCcqmw4oixtHKKNH7Zdvlbo77BrgAA6J6QXxp76623dOeddyo1NVVRUVF67bXXgvZblqUlS5bo6quv1sCBA5WTk6MPPvggqObTTz/VfffdJ6fTqaFDh2ru3Ln64osvgmref/993XLLLYqPj1daWppWrlzZoZctW7Zo7Nixio+P14QJE/Tmm2+G3AsAADBXyEHo9OnTmjhxosrKyi66f+XKlfrFL36h8vJyvfvuuxo0aJDcbrfOnTtn19x33306fPiwqqurtXXrVr311lt6+OGH7f3Nzc3Kzc3VqFGjVFtbq//8z//UsmXL9N///d92ze7du3XPPfdo7ty5OnDggGbOnKmZM2fq0KFDIfUCAADMFfJLYzNmzNCMGTMuus+yLK1Zs0aLFy/WXXfdJUl6/vnnlZycrNdee00//OEP9cc//lHbtm3Te++9p8mTJ0uSfvnLX+r73/++nnrqKaWmpurFF19US0uLNmzYoLi4OF1//fWqq6vTqlWr7MC0du1a3XHHHVq0aJEkacWKFaqurta6detUXl7epV4AAIDZwnrX2PHjx+Xz+ZSTk2NvS0xMVHZ2trxeryTJ6/Vq6NChdgiSpJycHEVHR+vdd9+1a2699VbFxcXZNW63W8eOHdNnn31m15x/nPaa9uN0pRcAAGC2sF4s7fP5JEnJyclB25OTk+19Pp9PSUlJwU0MGKBhw4YF1aSnp3dYo33fFVdcIZ/P1+lxOuvlQn6/X36/337c3NwsSQoEAgoEApf61rvFEWOFfc3e5Ii2gv5E9zHLyGG24cMsI8O0uUbi39dQ1uSusfOUlpZq+fLlHbZXVVUpISEh7MdbOSXsS14WVkxu6+0W+g1mGTnMNnyYZWSYMtcLb3QKhzNnznS5NqxBKCUlRZLU2Nioq6++2t7e2NiozMxMu6apqSnoeV9++aU+/fRT+/kpKSlqbGwMqml/3FnN+fs76+VCJSUl8ng89uPm5malpaUpNzdXTqez8wGEaPyy7WFfszc5oi2tmNymn+6Llr+N2+d7gllGDrMNH2YZGabN9dAyd9jXbH9FpyvCGoTS09OVkpKimpoaO2w0Nzfr3Xff1YIFCyRJLpdLJ0+eVG1trbKysiRJO3bsUFtbm7Kzs+2an/zkJwoEAoqNjZUkVVdX67rrrtMVV1xh19TU1Ki4uNg+fnV1tVwuV5d7uZDD4ZDD4eiwPTY21u4jnPrre+3426L67ff2TWOWkcNsw4dZRoYpc43Ev6+hrBnyxdJffPGF6urqVFdXJ+nvFyXX1dWpvr5eUVFRKi4u1s9+9jO9/vrrOnjwoB544AGlpqZq5syZkqRx48bpjjvu0Lx587R37179/ve/V1FRkX74wx8qNTVVknTvvfcqLi5Oc+fO1eHDh7Vp0yatXbs26GzNo48+qm3btunpp5/W0aNHtWzZMu3bt09FRUWS1KVeAACA2UI+I7Rv3z7ddttt9uP2cFJQUKCKigo99thjOn36tB5++GGdPHlS3/3ud7Vt2zbFx8fbz3nxxRdVVFSk22+/XdHR0crPz9cvfvELe39iYqKqqqpUWFiorKwsXXnllVqyZEnQew3dfPPNeumll7R48WL9+7//u6655hq99tprGj9+vF3TlV4AAIC5oizLMuOy9G5obm5WYmKiTp06FZFrhPrbZ2v9/SM2WvXY3hgjTudGErOMHGYbPswyMkybayQ+wzKUf7/59HkAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYyIgiVlZVp9OjRio+PV3Z2tvbu3dvbLQEAgMtAvw9CmzZtksfj0dKlS7V//35NnDhRbrdbTU1Nvd0aAADoZf0+CK1atUrz5s3TnDlzlJGRofLyciUkJGjDhg293RoAAOhlA3q7gUhqaWlRbW2tSkpK7G3R0dHKycmR1+vtUO/3++X3++3Hp06dkiR9+umnCgQCYe9vwJenw75mbxrQZunMmTYNCESrtS2qt9vp05hl5DDb8GGWkWHaXP/2t7+Ffc3PP/9ckmRZVqe1/ToI/fWvf1Vra6uSk5ODticnJ+vo0aMd6ktLS7V8+fIO29PT0yPWY39zb2830I8wy8hhtuHDLCPDpLle+XTk1v7888+VmJh4yZp+HYRCVVJSIo/HYz9ua2vTp59+quHDhysqqv+n8p5qbm5WWlqaPv74Yzmdzt5up09jlpHDbMOHWUYGc+05y7L0+eefKzU1tdPafh2ErrzySsXExKixsTFoe2Njo1JSUjrUOxwOORyOoG1Dhw6NZIv9ktPp5C9vmDDLyGG24cMsI4O59kxnZ4La9euLpePi4pSVlaWamhp7W1tbm2pqauRyuXqxMwAAcDno12eEJMnj8aigoECTJ0/WlClTtGbNGp0+fVpz5szp7dYAAEAv6/dBaPbs2frkk0+0ZMkS+Xw+ZWZmatu2bR0uoEbPORwOLV26tMPLiwgds4wcZhs+zDIymOs3K8rqyr1lAAAA/VC/vkYIAADgUghCAADAWAQhAABgLIIQAAAwFkGonystLdW3v/1tDRkyRElJSZo5c6aOHTsWVHPu3DkVFhZq+PDhGjx4sPLz84PehPIPf/iD7rnnHqWlpWngwIEaN26c1q5dG7RGQ0OD7r33Xl177bWKjo5WcXFxl3ssKyvT6NGjFR8fr+zsbO3du/eidZZlacaMGYqKitJrr73W5fXDqT/Mc+rUqYqKigr6mj9/fujDCKP+MFdJ8nq9mjZtmgYNGiSn06lbb71VZ8+eDW0YPdTXZ/mXv/ylw89n+9eWLVu6N5Qw6euzlSSfz6f7779fKSkpGjRokCZNmqT/+Z//CX0Y/QhBqJ/btWuXCgsLtWfPHlVXVysQCCg3N1enT3/1ga8LFy7UG2+8oS1btmjXrl06ceKEZs2aZe+vra1VUlKSXnjhBR0+fFg/+clPVFJSonXr1tk1fr9fV111lRYvXqyJEyd2ub9NmzbJ4/Fo6dKl2r9/vyZOnCi3262mpqYOtWvWrOn1jzrpL/OcN2+eGhoa7K+VK1f2YCo91x/m6vV6dccddyg3N1d79+7Ve++9p6KiIkVHf7O/Zvv6LNPS0oJ+NhsaGrR8+XINHjxYM2bMCMOEuq+vz1aSHnjgAR07dkyvv/66Dh48qFmzZukHP/iBDhw40MPp9GEWjNLU1GRJsnbt2mVZlmWdPHnSio2NtbZs2WLX/PGPf7QkWV6v92vX+dGPfmTddtttF933ve99z3r00Ue71M+UKVOswsJC+3Fra6uVmppqlZaWBtUdOHDA+ta3vmU1NDRYkqxXX321S+tHWl+cZyjr9Za+ONfs7Gxr8eLFXVrvm9QXZ3mhzMxM68EHH+zS+t+kvjjbQYMGWc8//3zQ84YNG2b9+te/7tIx+iPOCBnm1KlTkqRhw4ZJ+vt/nQQCAeXk5Ng1Y8eO1ciRI+X1ei+5Tvsa3dXS0qLa2tqgY0dHRysnJyfo2GfOnNG9996rsrKyi35GXG/qi/OUpBdffFFXXnmlxo8fr5KSEp05c6ZHxw63vjbXpqYmvfvuu0pKStLNN9+s5ORkfe9739M777zTo2OHQ1+b5YVqa2tVV1enuXPn9ujYkdAXZ3vzzTdr06ZN+vTTT9XW1qaXX35Z586d09SpU3t0/L6s37+zNL7S1tam4uJifec739H48eMl/f314ri4uA4fLpucnCyfz3fRdXbv3q1NmzapsrKyR/389a9/VWtra4d3+U5OTtbRo0ftxwsXLtTNN9+su+66q0fHC7e+Os97771Xo0aNUmpqqt5//339+Mc/1rFjx/S///u/PTp+uPTFuf75z3+WJC1btkxPPfWUMjMz9fzzz+v222/XoUOHdM011/Soh+7qi7O80Pr16zVu3DjdfPPNPTp2uPXV2W7evFmzZ8/W8OHDNWDAACUkJOjVV1/VmDFjenT8vowzQgYpLCzUoUOH9PLLL3d7jUOHDumuu+7S0qVLlZub2+Xnvf322xo8eLD99eKLL3bpea+//rp27NihNWvWdLPjyOmL85Skhx9+WG63WxMmTNB9992n559/Xq+++qo++uij7nwLYdcX59rW1iZJ+td//VfNmTNHN954o1avXq3rrrtOGzZs6Nb3EA59cZbnO3v2rF566aXL8mxQX53tT3/6U508eVK/+93vtG/fPnk8Hv3gBz/QwYMHu/Mt9AucETJEUVGRtm7dqrfeeksjRoywt6ekpKilpUUnT54M+q+YxsbGDi9DHTlyRLfffrsefvhhLV68OKTjT548WXV1dfbj5ORkORwOxcTEBN1RceGxd+zYoY8++qjDf2Hl5+frlltu0c6dO0PqI1z66jwvJjs7W5L04Ycf6h//8R9D6iPc+upcr776aklSRkZGUM24ceNUX18fUg/h0ldneb5XXnlFZ86c0QMPPBDSsSOtr872o48+0rp163To0CFdf/31kqSJEyfq7bffVllZmcrLy0Pqo9/o7YuUEFltbW1WYWGhlZqaav3pT3/qsL/94r5XXnnF3nb06NEOF/cdOnTISkpKshYtWtTpMUO9uK+oqMh+3Nraan3rW9+yL+5raGiwDh48GPQlyVq7dq315z//uUvHCKe+Ps+LeeeddyxJ1h/+8IcuHSMS+vpc29rarNTU1A4XS2dmZlolJSVdOka49PVZXrhufn5+l9b9JvT12b7//vuWJOvIkSNBz8vNzbXmzZvXpWP0RwShfm7BggVWYmKitXPnTquhocH+OnPmjF0zf/58a+TIkdaOHTusffv2WS6Xy3K5XPb+gwcPWldddZX1z//8z0FrNDU1BR3rwIED1oEDB6ysrCzr3nvvtQ4cOGAdPnz4kv29/PLLlsPhsCoqKqwjR45YDz/8sDV06FDL5/N97XPUi3eN9fV5fvjhh9YTTzxh7du3zzp+/Lj1m9/8xvqHf/gH69Zbbw3jlELX1+dqWZa1evVqy+l0Wlu2bLE++OADa/HixVZ8fLz14YcfhmlKXdMfZmlZlvXBBx9YUVFR1m9/+9swTCU8+vpsW1parDFjxli33HKL9e6771offvih9dRTT1lRUVFWZWVlGCfVtxCE+jlJF/3auHGjXXP27FnrRz/6kXXFFVdYCQkJ1j/90z9ZDQ0N9v6lS5dedI1Ro0Z1eqwLay7ml7/8pTVy5EgrLi7OmjJlirVnz55Ov6feCkJ9fZ719fXWrbfeag0bNsxyOBzWmDFjrEWLFlmnTp3q6Wh6pK/PtV1paak1YsQIKyEhwXK5XNbbb7/d3ZF0W3+ZZUlJiZWWlma1trZ2dxRh1x9m+6c//cmaNWuWlZSUZCUkJFg33HBDh9vpTRNlWZbV1ZfRAAAA+hPuGgMAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWP8PBm6uOvw4+XoAAAAASUVORK5CYII=\n", - "text/plain": [ - "
" - ] + "text/plain": "
", + "image/png": "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\n" }, "metadata": {}, "output_type": "display_data" @@ -523,39 +272,38 @@ "id": "5adb80ee", "metadata": {}, "source": [ - "Видно, что кол-во пользователей растет" + "Вообще, видно, что кол-во пользователей растет" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 197, "id": "0fbd2bbc", "metadata": {}, "outputs": [], "source": [ - "cold_users = interactions[Columns.User].value_counts()\n", - "cold_users = cold_users[cold_users < 3].index" + "cold_users = \\\n", + " interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts() == 1].index" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 198, "id": "150e1593", "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] + "text/plain": "
", + "image/png": "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\n" }, "metadata": {}, "output_type": "display_data" } ], "source": [ - "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'].hist(bins=20);" + "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'\n", + " ].hist(bins=20);" ] }, { @@ -563,341 +311,88 @@ "id": "b5fa83eb", "metadata": {}, "source": [ - "Для холодных пользователей, мы бы рекомендовали айтемы с самый высоким просмотром в среднем по холодным пользователям" + "Для холодных пользователей, я бы рекомендовал айтемы с самый высоким просмотром в среднем по холодным пользователям" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 199, "id": "cca06e3f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n10 791466 8199 2021-07-27 713 9.0 1\n26 181144 10440 2021-08-08 27408 40.0 2\n37 161176 10440 2021-07-29 22 0.0 1\n38 21723 1819 2021-04-11 8535 100.0 5\n60 77216 8143 2021-05-08 660 11.0 1\n... ... ... ... ... ... ...\n5476222 1007900 9728 2021-08-12 416 6.0 1\n5476225 882138 4716 2021-05-21 1594 2.0 1\n5476238 805174 13125 2021-06-27 1 0.0 1\n5476246 648596 12225 2021-08-13 76 0.0 1\n5476248 697262 15297 2021-08-20 18307 63.0 4\n\n[355162 rows x 6 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n

355162 rows × 6 columns

\n
" + }, + "execution_count": 199, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "cold_users_interactions = interactions[interactions[Columns.User].isin(cold_users)]\n", - "hot_users_interactions = interactions[~interactions[Columns.User].isin(cold_users)]" + "cold_users = interactions[interactions[Columns.User].isin(cold_users)]\n", + "hot_users = interactions[~interactions[Columns.User].isin(cold_users)]\n", + "cold_users" ] }, { "cell_type": "code", - "execution_count": 16, - "id": "422d0455", + "execution_count": 200, + "id": "a691676f", "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "shape cold_users_interactions - 650696\n" - ] - }, { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
16646903162282021-07-235737546.03
22505244152972021-08-151599163.04
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "10 791466 8199 2021-07-27 713 9.0 1\n", - "16 646903 16228 2021-07-23 57375 46.0 3\n", - "22 505244 15297 2021-08-15 15991 63.0 4\n", - "26 181144 10440 2021-08-08 27408 40.0 2\n", - "37 161176 10440 2021-07-29 22 0.0 1" - ] + "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n0 176549 9506 2021-05-11 4250 72.0 4\n1 699317 1659 2021-05-29 8317 100.0 5\n2 656683 7107 2021-05-09 10 0.0 1\n3 864613 7638 2021-07-05 14483 100.0 5\n4 964868 9506 2021-04-30 6725 100.0 5\n... ... ... ... ... ... ...\n5476246 648596 12225 2021-08-13 76 0.0 1\n5476247 546862 9673 2021-04-13 2308 49.0 3\n5476248 697262 15297 2021-08-20 18307 63.0 4\n5476249 384202 16197 2021-04-19 6203 100.0 5\n5476250 319709 4436 2021-08-15 3921 45.0 3\n\n[5475423 rows x 6 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n

5475423 rows × 6 columns

\n
" }, - "execution_count": 16, + "execution_count": 200, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "print('shape cold_users_interactions -', cold_users_interactions.shape[0])\n", - "cold_users_interactions.head()" + "hot_users" ] }, { "cell_type": "code", - "execution_count": 17, - "id": "a691676f", + "execution_count": 201, + "id": "a64701c2", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "shape hot_users_interactions - 4824727\n" - ] - }, + "data": { + "text/plain": " item_id\n10440 45695\n15297 39309\n2657 20474\n9728 15140\n4740 11455\n... ...\n1946 1\n13886 1\n14090 1\n5730 1\n13125 1\n\n[6440 rows x 1 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n

6440 rows × 1 columns

\n
" + }, + "execution_count": 201, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users['item_id'].value_counts().to_frame()" + ] + }, + { + "cell_type": "code", + "execution_count": 202, + "id": "cef9cfa6", + "metadata": {}, + "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "0 176549 9506 2021-05-11 4250 72.0 4\n", - "1 699317 1659 2021-05-29 8317 100.0 5\n", - "2 656683 7107 2021-05-09 10 0.0 1\n", - "3 864613 7638 2021-07-05 14483 100.0 5\n", - "4 964868 9506 2021-04-30 6725 100.0 5" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print('shape hot_users_interactions -', hot_users_interactions.shape[0])\n", - "hot_users_interactions.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "a64701c2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
item_id
1044069181
1529764307
972828294
265725592
1386522653
\n", - "
" - ], - "text/plain": [ - " item_id\n", - "10440 69181\n", - "15297 64307\n", - "9728 28294\n", - "2657 25592\n", - "13865 22653" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users_interactions['item_id'].value_counts().to_frame().head()" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "cef9cfa6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Int64Index([609, 3825, 4895, 5069, 2271, 11566, 13390, 9954, 5733, 7434], dtype='int64', name='item_id')" - ] + "text/plain": "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" }, - "execution_count": 19, + "execution_count": 202, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "(\n", - " cold_users_interactions[['item_id', 'total_dur']]\n", - " .groupby('item_id')\n", - " .mean()\n", - " .sort_values(by='total_dur', ascending=False)\n", - " .head(10)\n", - " .index\n", - ")" + "cold_users[['item_id', 'total_dur']].groupby('item_id').mean().sort_values(by='total_dur', ascending=False).head(10).index" ] }, { @@ -910,17 +405,17 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 203, "id": "bd68d3fe", "metadata": {}, "outputs": [], "source": [ - "max_date = hot_users_interactions[Columns.Datetime].max()" + "max_date = interactions[Columns.Datetime].max()" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 204, "id": "3092fe4b", "metadata": {}, "outputs": [ @@ -934,8 +429,10 @@ } ], "source": [ - "train = interactions[interactions[Columns.Datetime] < max_date - pd.Timedelta(days=7)].copy()\n", - "test = interactions[interactions[Columns.Datetime] >= max_date - pd.Timedelta(days=7)].copy()\n", + "train = interactions[interactions[Columns.Datetime] < max_date\n", + " - pd.Timedelta(days=7)].copy()\n", + "test = interactions[interactions[Columns.Datetime] >= max_date\n", + " - pd.Timedelta(days=7)].copy()\n", "\n", "print(f\"train: {train.shape}\")\n", "print(f\"test: {test.shape}\")" @@ -943,7 +440,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 205, "id": "ec286bdc", "metadata": {}, "outputs": [], @@ -953,1598 +450,492 @@ }, { "cell_type": "code", - "execution_count": 23, - "id": "c32fcaae", + "execution_count": 206, + "id": "52241fed", "metadata": {}, "outputs": [], "source": [ - "drop_user = set(test[Columns.User]) - set(train[Columns.User])" + "drop_user = set(test[Columns.User]) - set(train[Columns.User])\n", + "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" ] }, { - "cell_type": "code", - "execution_count": 24, - "id": "7183cb6f", + "cell_type": "markdown", + "id": "b5eec6da", "metadata": {}, - "outputs": [], "source": [ - "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" + "## User preprocess" ] }, { "cell_type": "code", - "execution_count": 25, - "id": "1ff85593", + "execution_count": 207, + "id": "c57e2b2f", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
9203219135822021-08-226975100.05
5420019793352021-08-16832.01
6473446144882021-08-196011100.05
84100105122021-08-15140.01
94890735142002021-08-16117928.02
.....................
54761695895899832021-08-21240343.03
547618859089286182021-08-21133523.02
5476191857162123602021-08-16110.01
5476201273558106052021-08-2134030100.05
547625031970944362021-08-15392145.03
\n", - "

333022 rows × 6 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id last_watch_dt total_dur watched_pct weight\n", - "9 203219 13582 2021-08-22 6975 100.0 5\n", - "54 200197 9335 2021-08-16 83 2.0 1\n", - "64 73446 14488 2021-08-19 6011 100.0 5\n", - "84 10010 512 2021-08-15 14 0.0 1\n", - "94 890735 14200 2021-08-16 1179 28.0 2\n", - "... ... ... ... ... ... ...\n", - "5476169 589589 983 2021-08-21 2403 43.0 3\n", - "5476188 590892 8618 2021-08-21 1335 23.0 2\n", - "5476191 857162 12360 2021-08-16 11 0.0 1\n", - "5476201 273558 10605 2021-08-21 34030 100.0 5\n", - "5476250 319709 4436 2021-08-15 3921 45.0 3\n", - "\n", - "[333022 rows x 6 columns]" - ] + "text/plain": " user_id age income sex kids_flg\n0 973171 age_25_34 income_60_90 М 1\n1 962099 age_18_24 income_20_40 М 0\n2 1047345 age_45_54 income_40_60 Ж 0\n3 721985 age_45_54 income_20_40 Ж 0\n4 704055 age_35_44 income_60_90 Ж 0\n... ... ... ... ... ...\n840192 339025 age_65_inf income_0_20 Ж 0\n840193 983617 age_18_24 income_20_40 Ж 1\n840194 251008 NaN NaN NaN 0\n840195 590706 NaN NaN Ж 0\n840196 166555 age_65_inf income_20_40 Ж 0\n\n[840197 rows x 5 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n

840197 rows × 5 columns

\n
" }, - "execution_count": 25, + "execution_count": 207, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "test" + "users" ] }, { - "cell_type": "markdown", - "id": "b5eec6da", + "cell_type": "code", + "execution_count": 208, + "id": "24cc138a", "metadata": {}, + "outputs": [], "source": [ - "# User preprocess" + "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" ] }, { "cell_type": "code", - "execution_count": 26, - "id": "c57e2b2f", + "execution_count": 209, + "id": "6e5e2d92", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
\n", - "
" - ], - "text/plain": [ - " user_id age income sex kids_flg\n", - "0 973171 age_25_34 income_60_90 М 1\n", - "1 962099 age_18_24 income_20_40 М 0\n", - "2 1047345 age_45_54 income_40_60 Ж 0\n", - "3 721985 age_45_54 income_20_40 Ж 0\n", - "4 704055 age_35_44 income_60_90 Ж 0" - ] + "text/plain": " user_id age income sex kids_flg\n0 973171 age_25_34 income_60_90 М 1\n1 962099 age_18_24 income_20_40 М 0\n3 721985 age_45_54 income_20_40 Ж 0\n4 704055 age_35_44 income_60_90 Ж 0\n5 1037719 age_45_54 income_60_90 М 0\n... ... ... ... .. ...\n840184 529394 age_25_34 income_40_60 Ж 0\n840186 80113 age_25_34 income_40_60 Ж 0\n840188 312839 age_65_inf income_60_90 Ж 0\n840189 191349 age_45_54 income_40_60 М 1\n840190 393868 age_25_34 income_20_40 М 0\n\n[586653 rows x 5 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
..................
840184529394age_25_34income_40_60Ж0
84018680113age_25_34income_40_60Ж0
840188312839age_65_infincome_60_90Ж0
840189191349age_45_54income_40_60М1
840190393868age_25_34income_20_40М0
\n

586653 rows × 5 columns

\n
" }, - "execution_count": 26, + "execution_count": 209, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "users.head()" + "users" ] }, { - "cell_type": "code", - "execution_count": 27, - "id": "63996e92", + "cell_type": "markdown", + "id": "c7f9a6e7", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "user_id 0.000000\n", - "age 0.016776\n", - "income 0.017586\n", - "sex 0.016462\n", - "kids_flg 0.000000\n", - "dtype: float64" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "users.isnull().sum()/840197" + "Заменяю Nan'ы на Unknown" ] }, { "cell_type": "code", - "execution_count": 28, - "id": "24cc138a", + "execution_count": 210, + "id": "1286eb60", "metadata": {}, "outputs": [], "source": [ - "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" + "users.fillna('Unknown', inplace=True)" ] }, { "cell_type": "code", - "execution_count": 29, - "id": "b2283c6d", + "execution_count": 211, + "id": "1ccccf0f", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
\n", - "
" - ], - "text/plain": [ - " user_id age income sex kids_flg\n", - "0 973171 age_25_34 income_60_90 М 1\n", - "1 962099 age_18_24 income_20_40 М 0\n", - "3 721985 age_45_54 income_20_40 Ж 0\n", - "4 704055 age_35_44 income_60_90 Ж 0\n", - "5 1037719 age_45_54 income_60_90 М 0" - ] + "text/plain": " id value feature\n0 973171 М sex\n1 962099 М sex\n3 721985 Ж sex\n4 704055 Ж sex\n5 1037719 М sex", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n
" }, - "execution_count": 29, + "execution_count": 211, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "users.head()" + "user_features_frames = []\n", + "for feature in ['sex', 'age', 'income']:\n", + " feature_frame = users.reindex(columns=[Columns.User, feature])\n", + " feature_frame.columns = ['id', 'value']\n", + " feature_frame['feature'] = feature\n", + " user_features_frames.append(feature_frame)\n", + "user_features = pd.concat(user_features_frames)\n", + "user_features.head()" ] }, { "cell_type": "markdown", - "id": "c7f9a6e7", + "id": "b9220b0b", "metadata": {}, "source": [ - "Заменяем Nan'ы на Unknown" + "## Item preprocess" ] }, { "cell_type": "code", - "execution_count": 30, - "id": "1286eb60", + "execution_count": 213, + "id": "8bbe9ee4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": " item_id content_type title title_orig release_year \\\n0 10711 film Поговори с ней Hable con ella 2002.0 \n1 2508 film Голые перцы Search Party 2014.0 \n2 10716 film Тактическая сила Tactical Force 2011.0 \n3 7868 film 45 лет 45 Years 2015.0 \n4 16268 film Все решает мгновение NaN 1978.0 \n\n genres countries for_kids \\\n0 драмы, зарубежные, детективы, мелодрамы Испания NaN \n1 зарубежные, приключения, комедии США NaN \n2 криминал, зарубежные, триллеры, боевики, комедии Канада NaN \n3 драмы, зарубежные, мелодрамы Великобритания NaN \n4 драмы, спорт, советские, мелодрамы СССР NaN \n\n age_rating studios directors \\\n0 16.0 NaN Педро Альмодовар \n1 16.0 NaN Скот Армстронг \n2 16.0 NaN Адам П. Калтраро \n3 16.0 NaN Эндрю Хэй \n4 12.0 Ленфильм Виктор Садовский \n\n actors \\\n0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n4 Александр Абдулов, Александр Демьяненко, Алекс... \n\n description \\\n0 Мелодрама легендарного Педро Альмодовара «Пого... \n1 Уморительная современная комедия на популярную... \n2 Профессиональный рестлер Стив Остин («Все или ... \n3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n4 Расчетливая чаровница из советского кинохита «... \n\n keywords \n0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n4 Все, решает, мгновение, 1978, СССР, сильные, ж... ", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
\n
" + }, + "execution_count": 213, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 214, + "id": "72fa86a0", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": "item_id 0\ncontent_type 0\ntitle 0\ntitle_orig 4745\nrelease_year 98\ngenres 0\ncountries 37\nfor_kids 15397\nage_rating 2\nstudios 14898\ndirectors 1509\nactors 2619\ndescription 2\nkeywords 423\ndtype: int64" + }, + "execution_count": 214, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 215, + "id": "50f0611f", "metadata": {}, "outputs": [], "source": [ - "users.fillna('Unknown', inplace=True)" + "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" ] }, { "cell_type": "code", - "execution_count": 31, - "id": "1ccccf0f", + "execution_count": 216, + "id": "280cf47d", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 973171 М sex\n", - "1 962099 М sex\n", - "3 721985 Ж sex\n", - "4 704055 Ж sex\n", - "5 1037719 М sex" - ] + "text/plain": "item_id 0\ncontent_type 0\ntitle 0\ntitle_orig 3775\nrelease_year 31\ngenres 0\ncountries 14\nfor_kids 13415\nage_rating 1\nstudios 13047\ndirectors 939\nactors 1858\ndescription 0\nkeywords 388\ndtype: int64" }, - "execution_count": 31, + "execution_count": 216, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "user_features_frames = []\n", - "for feature in [\"sex\", \"age\", \"income\"]:\n", - " feature_frame = users.reindex(columns=[Columns.User, feature])\n", - " feature_frame.columns = [\"id\", \"value\"]\n", - " feature_frame[\"feature\"] = feature\n", - " user_features_frames.append(feature_frame)\n", - "user_features = pd.concat(user_features_frames)\n", - "user_features.head()" + "items.isna().sum()" ] }, { "cell_type": "markdown", - "id": "b9220b0b", + "id": "eddd93b5", "metadata": {}, "source": [ - "# Item preprocess" + "## Genre" ] }, { "cell_type": "code", - "execution_count": 32, - "id": "8bbe9ee4", + "execution_count": 217, + "id": "bf6da75c", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
6657602filmЧем заняться дома?Chem zanyat'sya doma?2020.0мультфильм, комедииКипрNaN0.0NaNНаумов АртемСаранцева ВаряЧем заняться ребёнку, если никуда не получаетс...2020, кипр, чем, заняться, дома
1231315798filmВ мире динозавровNaN2005.0русские, для детей, хочу всё знать, русские му...РоссияNaN0.0NaNРоберт СаакянцNaNПознавательный мультфильм для детей, рассказыв...мире, динозавров, 2005, Россия, динозавры, пут...
842810616filmРождение нацииThe Birth of a Nation2016.0драмы, биография, историческоеСША, КанадаNaN18.0NaNНэйт ПаркерНэйт Паркер, Арми Хаммер, Пенелопа Энн Миллер,...Историко-драматический байопик о чернокожем ра...южные сша, рабство, биография, основанная на р...
\n", - "
" - ], - "text/plain": [ - " item_id content_type title title_orig \\\n", - "6657 602 film Чем заняться дома? Chem zanyat'sya doma? \n", - "12313 15798 film В мире динозавров NaN \n", - "8428 10616 film Рождение нации The Birth of a Nation \n", - "\n", - " release_year genres \\\n", - "6657 2020.0 мультфильм, комедии \n", - "12313 2005.0 русские, для детей, хочу всё знать, русские му... \n", - "8428 2016.0 драмы, биография, историческое \n", - "\n", - " countries for_kids age_rating studios directors \\\n", - "6657 Кипр NaN 0.0 NaN Наумов Артем \n", - "12313 Россия NaN 0.0 NaN Роберт Саакянц \n", - "8428 США, Канада NaN 18.0 NaN Нэйт Паркер \n", - "\n", - " actors \\\n", - "6657 Саранцева Варя \n", - "12313 NaN \n", - "8428 Нэйт Паркер, Арми Хаммер, Пенелопа Энн Миллер,... \n", - "\n", - " description \\\n", - "6657 Чем заняться ребёнку, если никуда не получаетс... \n", - "12313 Познавательный мультфильм для детей, рассказыв... \n", - "8428 Историко-драматический байопик о чернокожем ра... \n", - "\n", - " keywords \n", - "6657 2020, кипр, чем, заняться, дома \n", - "12313 мире, динозавров, 2005, Россия, динозавры, пут... \n", - "8428 южные сша, рабство, биография, основанная на р... " - ] + "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n
" }, - "execution_count": 32, + "execution_count": 217, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "items.sample(3)" + "# Explode genres to flatten table\n", + "items['genre'] = items['genres'].str.lower().str.replace(', ', ',',\n", + " regex=False).str.split(',')\n", + "genre_feature = items[['item_id', 'genre']].explode('genre')\n", + "genre_feature.columns = ['id', 'value']\n", + "genre_feature['feature'] = 'genre'\n", + "genre_feature.head()\n" ] }, { "cell_type": "code", - "execution_count": 33, - "id": "72fa86a0", - "metadata": { - "scrolled": true - }, + "execution_count": 218, + "id": "913b9c27", + "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "item_id 0\n", - "content_type 0\n", - "title 0\n", - "title_orig 4745\n", - "release_year 98\n", - "genres 0\n", - "countries 37\n", - "for_kids 15397\n", - "age_rating 2\n", - "studios 14898\n", - "directors 1509\n", - "actors 2619\n", - "description 2\n", - "keywords 423\n", - "dtype: int64" - ] + "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre\n... ... ... ...\n15960 10632 криминал genre\n15961 4538 драмы genre\n15961 4538 спорт genre\n15961 4538 криминал genre\n15962 3206 комедии genre\n\n[36128 rows x 3 columns]", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n

36128 rows × 3 columns

\n
" }, - "execution_count": 33, + "execution_count": 218, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "items.isna().sum()" + "genre_feature" ] }, { - "cell_type": "code", - "execution_count": 34, - "id": "50f0611f", + "cell_type": "markdown", + "id": "478bf1e3", "metadata": {}, - "outputs": [], "source": [ - "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" + "## Content" ] }, { "cell_type": "code", - "execution_count": 35, - "id": "280cf47d", + "execution_count": 220, + "id": "65f8b5d9", "metadata": {}, "outputs": [ { "data": { - "text/plain": [ - "item_id 0\n", - "content_type 0\n", - "title 0\n", - "title_orig 3775\n", - "release_year 31\n", - "genres 0\n", - "countries 14\n", - "for_kids 13415\n", - "age_rating 1\n", - "studios 13047\n", - "directors 939\n", - "actors 1858\n", - "description 0\n", - "keywords 388\n", - "dtype: int64" - ] + "text/plain": " id value feature\n0 10711 film content_type\n1 2508 film content_type\n2 10716 film content_type\n3 7868 film content_type\n4 16268 film content_type", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
\n
" }, - "execution_count": 35, + "execution_count": 220, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "items.isna().sum()" + "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", + "content_feature.columns = [\"id\", \"value\"]\n", + "content_feature[\"feature\"] = \"content_type\"\n", + "content_feature.head()" ] }, { "cell_type": "markdown", - "id": "eddd93b5", + "id": "a62ebee4", "metadata": {}, "source": [ - "# Genre" + "## Actors" ] }, { "cell_type": "code", - "execution_count": 36, - "id": "bf6da75c", + "execution_count": 221, + "id": "fdc43660", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 драмы genre\n", - "0 10711 зарубежные genre\n", - "0 10711 детективы genre\n", - "0 10711 мелодрамы genre\n", - "1 2508 зарубежные genre" - ] + "text/plain": " id value feature\n0 10711 адольфо фернандес actors\n0 10711 ана фернандес actors\n0 10711 дарио грандинетти actors\n0 10711 джеральдин чаплин actors\n0 10711 елена анайя actors", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
\n
" }, - "execution_count": 36, + "execution_count": 221, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Explode genres to flatten table\n", - "items[\"genre\"] = items[\"genres\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "genre_feature = items[[\"item_id\", \"genre\"]].explode(\"genre\")\n", - "genre_feature.columns = [\"id\", \"value\"]\n", - "genre_feature[\"feature\"] = \"genre\"\n", - "genre_feature.head()" + "items['actors'] = items['actors'].str.lower().str.replace(', ', ',',\n", + " regex=False).str.split(',')\n", + "actors_feature = items[['item_id', 'actors']].explode('actors')\n", + "actors_feature.columns = ['id', 'value']\n", + "actors_feature['feature'] = 'actors'\n", + "actors_feature.head()" ] }, { "cell_type": "markdown", - "id": "478bf1e3", + "id": "73801647", "metadata": {}, "source": [ - "# Content" + "## Keywords" ] }, { "cell_type": "code", - "execution_count": 37, - "id": "65f8b5d9", + "execution_count": 222, + "id": "594abe5c", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 film content_type\n", - "1 2508 film content_type\n", - "2 10716 film content_type\n", - "3 7868 film content_type\n", - "4 16268 film content_type" - ] + "text/plain": " id value feature\n0 10711 поговори keywords\n0 10711 ней keywords\n0 10711 2002 keywords\n0 10711 испания keywords\n0 10711 друзья keywords", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
\n
" }, - "execution_count": 37, + "execution_count": 222, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", - "content_feature.columns = [\"id\", \"value\"]\n", - "content_feature[\"feature\"] = \"content_type\"\n", - "content_feature.head()" + "items['keywords'] = items['keywords'].str.lower().str.replace(', ', ','\n", + " , regex=False).str.split(',')\n", + "keywords_feature = items[['item_id', 'keywords']].explode('keywords')\n", + "keywords_feature.columns = ['id', 'value']\n", + "keywords_feature['feature'] = 'keywords'\n", + "keywords_feature.head()" ] }, { "cell_type": "markdown", - "id": "a62ebee4", + "id": "d3eb0a37", "metadata": {}, "source": [ - "# Actors" + "## Countries" ] }, { "cell_type": "code", - "execution_count": 38, - "id": "fdc43660", + "execution_count": 223, + "id": "8eb8a621", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 адольфо фернандес actors\n", - "0 10711 ана фернандес actors\n", - "0 10711 дарио грандинетти actors\n", - "0 10711 джеральдин чаплин actors\n", - "0 10711 елена анайя actors" - ] + "text/plain": " id value feature\n0 10711 Испания countries\n1 2508 США countries\n2 10716 Канада countries\n3 7868 Великобритания countries\n4 16268 СССР countries", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
\n
" }, - "execution_count": 38, + "execution_count": 223, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "items[\"actors\"] = items[\"actors\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "actors_feature = items[[\"item_id\", \"actors\"]].explode(\"actors\")\n", - "actors_feature.columns = [\"id\", \"value\"]\n", - "actors_feature[\"feature\"] = \"actors\"\n", - "actors_feature.head()" + "country_feature = items.reindex(columns=[Columns.Item, 'countries'])\n", + "country_feature.columns = ['id', 'value']\n", + "country_feature['feature'] = 'countries'\n", + "country_feature.head()" ] }, { "cell_type": "markdown", - "id": "73801647", + "id": "5e477ee1", "metadata": {}, "source": [ - "# Keywords" + "## Age Rating" ] }, { "cell_type": "code", - "execution_count": 39, - "id": "594abe5c", + "execution_count": 224, + "id": "0894154a", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 поговори keywords\n", - "0 10711 ней keywords\n", - "0 10711 2002 keywords\n", - "0 10711 испания keywords\n", - "0 10711 друзья keywords" - ] + "text/plain": " id value feature\n0 10711 16.0 age_feature\n1 2508 16.0 age_feature\n2 10716 16.0 age_feature\n3 7868 16.0 age_feature\n4 16268 12.0 age_feature", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
\n
" }, - "execution_count": 39, + "execution_count": 224, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "items[\"keywords\"] = items[\"keywords\"].str.lower().str.replace(\", \", \",\", regex=False).str.split(\",\")\n", - "keywords_feature = items[[\"item_id\", \"keywords\"]].explode(\"keywords\")\n", - "keywords_feature.columns = [\"id\", \"value\"]\n", - "keywords_feature[\"feature\"] = \"keywords\"\n", - "keywords_feature.head()" + "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", + "age_feature.columns = [\"id\", \"value\"]\n", + "age_feature[\"feature\"] = \"age_feature\"\n", + "age_feature.head()" ] }, { "cell_type": "markdown", - "id": "d3eb0a37", + "id": "c09df1ec", "metadata": {}, "source": [ - "# Countries" + "## Studios" ] }, { "cell_type": "code", - "execution_count": 40, - "id": "8eb8a621", + "execution_count": 41, + "id": "ff937b4f", + "metadata": {}, + "outputs": [], + "source": [ + "items.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 225, + "id": "cee42708", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 Испания countries\n", - "1 2508 США countries\n", - "2 10716 Канада countries\n", - "3 7868 Великобритания countries\n", - "4 16268 СССР countries" - ] + "text/plain": " id value feature\n0 10711 NaN studios\n1 2508 NaN studios\n2 10716 NaN studios\n3 7868 NaN studios\n4 16268 Ленфильм studios", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711NaNstudios
12508NaNstudios
210716NaNstudios
37868NaNstudios
416268Ленфильмstudios
\n
" }, - "execution_count": 40, + "execution_count": 225, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "country_feature = items.reindex(columns=[Columns.Item, \"countries\"])\n", - "country_feature.columns = [\"id\", \"value\"]\n", - "country_feature[\"feature\"] = \"countries\"\n", - "country_feature.head()" + "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", + "studios_feature.columns = [\"id\", \"value\"]\n", + "studios_feature[\"feature\"] = \"studios\"\n", + "studios_feature.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 226, + "id": "7234f13b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n
" + }, + "execution_count": 226, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# studios_feature, age_feature, country_feature - фичи которые хотелось бы использовать,\n", + "# но длительность обучения \"OPTUNA\" увеличивается в разы\n", + "item_features = pd.concat((genre_feature, content_feature ))\n", + "item_features.head()" ] }, { "cell_type": "markdown", - "id": "5e477ee1", + "id": "09b8d756", "metadata": {}, "source": [ - "# Age Rating" + "## Metrics" ] }, { "cell_type": "code", - "execution_count": 41, - "id": "0894154a", + "execution_count": 227, + "id": "b082e667", "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 16.0 age_feature\n", - "1 2508 16.0 age_feature\n", - "2 10716 16.0 age_feature\n", - "3 7868 16.0 age_feature\n", - "4 16268 12.0 age_feature" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", - "age_feature.columns = [\"id\", \"value\"]\n", - "age_feature[\"feature\"] = \"age_feature\"\n", - "age_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "c09df1ec", - "metadata": {}, - "source": [ - "# Studios" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "ff937b4f", - "metadata": {}, - "outputs": [], - "source": [ - "items.fillna('Unknown', inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "cee42708", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
010711Unknownstudios
12508Unknownstudios
210716Unknownstudios
37868Unknownstudios
416268Ленфильмstudios
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "0 10711 Unknown studios\n", - "1 2508 Unknown studios\n", - "2 10716 Unknown studios\n", - "3 7868 Unknown studios\n", - "4 16268 Ленфильм studios" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", - "studios_feature.columns = [\"id\", \"value\"]\n", - "studios_feature[\"feature\"] = \"studios\"\n", - "studios_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "82558d41", - "metadata": {}, - "source": [ - "### Конкатим все доп фичи в один датасет" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "6158b0bd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
idvaluefeature
27556781Unknownstudios
18859843Unknownstudios
7472690912.0age_feature
339510751для детейgenre
39159872триллерыgenre
\n", - "
" - ], - "text/plain": [ - " id value feature\n", - "2755 6781 Unknown studios\n", - "1885 9843 Unknown studios\n", - "7472 6909 12.0 age_feature\n", - "3395 10751 для детей genre\n", - "3915 9872 триллеры genre" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "item_features = pd.concat((genre_feature, content_feature, studios_feature, age_feature, country_feature))\n", - "item_features.sample(5)" - ] - }, - { - "cell_type": "markdown", - "id": "09b8d756", - "metadata": {}, - "source": [ - "# Metrics" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "b082e667", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Precision@1': Precision(k=1),\n", - " 'Precision@2': Precision(k=2),\n", - " 'Precision@3': Precision(k=3),\n", - " 'Precision@4': Precision(k=4),\n", - " 'Precision@5': Precision(k=5),\n", - " 'Precision@6': Precision(k=6),\n", - " 'Precision@7': Precision(k=7),\n", - " 'Precision@8': Precision(k=8),\n", - " 'Precision@9': Precision(k=9),\n", - " 'Precision@10': Precision(k=10),\n", - " 'Recall@1': Recall(k=1),\n", - " 'Recall@2': Recall(k=2),\n", - " 'Recall@3': Recall(k=3),\n", - " 'Recall@4': Recall(k=4),\n", - " 'Recall@5': Recall(k=5),\n", - " 'Recall@6': Recall(k=6),\n", - " 'Recall@7': Recall(k=7),\n", - " 'Recall@8': Recall(k=8),\n", - " 'Recall@9': Recall(k=9),\n", - " 'Recall@10': Recall(k=10),\n", - " 'MAP@1': MAP(k=1, divide_by_k=False),\n", - " 'MAP@2': MAP(k=2, divide_by_k=False),\n", - " 'MAP@3': MAP(k=3, divide_by_k=False),\n", - " 'MAP@4': MAP(k=4, divide_by_k=False),\n", - " 'MAP@5': MAP(k=5, divide_by_k=False),\n", - " 'MAP@6': MAP(k=6, divide_by_k=False),\n", - " 'MAP@7': MAP(k=7, divide_by_k=False),\n", - " 'MAP@8': MAP(k=8, divide_by_k=False),\n", - " 'MAP@9': MAP(k=9, divide_by_k=False),\n", - " 'MAP@10': MAP(k=10, divide_by_k=False)}" - ] + "text/plain": "{'Precision@1': Precision(k=1),\n 'Precision@2': Precision(k=2),\n 'Precision@3': Precision(k=3),\n 'Precision@4': Precision(k=4),\n 'Precision@5': Precision(k=5),\n 'Precision@6': Precision(k=6),\n 'Precision@7': Precision(k=7),\n 'Precision@8': Precision(k=8),\n 'Precision@9': Precision(k=9),\n 'Precision@10': Precision(k=10),\n 'Recall@1': Recall(k=1),\n 'Recall@2': Recall(k=2),\n 'Recall@3': Recall(k=3),\n 'Recall@4': Recall(k=4),\n 'Recall@5': Recall(k=5),\n 'Recall@6': Recall(k=6),\n 'Recall@7': Recall(k=7),\n 'Recall@8': Recall(k=8),\n 'Recall@9': Recall(k=9),\n 'Recall@10': Recall(k=10),\n 'MAP@1': MAP(k=1, divide_by_k=False),\n 'MAP@2': MAP(k=2, divide_by_k=False),\n 'MAP@3': MAP(k=3, divide_by_k=False),\n 'MAP@4': MAP(k=4, divide_by_k=False),\n 'MAP@5': MAP(k=5, divide_by_k=False),\n 'MAP@6': MAP(k=6, divide_by_k=False),\n 'MAP@7': MAP(k=7, divide_by_k=False),\n 'MAP@8': MAP(k=8, divide_by_k=False),\n 'MAP@9': MAP(k=9, divide_by_k=False),\n 'MAP@10': MAP(k=10, divide_by_k=False)}" }, - "execution_count": 45, + "execution_count": 227, "metadata": {}, "output_type": "execute_result" } @@ -2565,139 +956,633 @@ }, { "cell_type": "markdown", - "id": "0bce189f", + "id": "2c603783", "metadata": {}, "source": [ - "# Обучение моделей" + "# Optuna\n", + "\n", + "Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", + "Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)" ] }, { "cell_type": "code", - "execution_count": 46, - "id": "864a7990", + "execution_count": 229, + "id": "fb193c2f", "metadata": {}, "outputs": [], "source": [ - "K_RECOS = 10\n", - "RANDOM_STATE = 42\n", "NUM_THREADS = 8\n", - "N_FACTORS = (32,)\n", - "N_EPOCHS = 1 # Lightfm\n", - "USER_ALPHA = 0 # Lightfm\n", - "ITEM_ALPHA = 0 # Lightfm\n", - "LEARNING_RATE = 0.05 # Lightfm" + "RANDOM_STATE = 42\n", + "K = 5\n", + "NO_COMPONENTS = 32\n", + "N_EPOCHS = 1" ] }, { "cell_type": "code", - "execution_count": 66, - "id": "89c1cedb", + "execution_count": 230, + "id": "3328645d", "metadata": {}, + "outputs": [], + "source": [ + "USER_ALPHA = 0\n", + "ITEM_ALPHA = 0\n", + "K_RECOS = 10" + ] + }, + { + "cell_type": "code", + "execution_count": 231, + "outputs": [], + "source": [ + "dataset = Dataset.construct(interactions_df=train,\n", + " user_features_df=user_features,\n", + " cat_user_features=['sex', 'age', 'income'],\n", + " item_features_df=item_features,\n", + " cat_item_features=['content_type', 'genre'])\n", + "TEST_USERS = test[Columns.User].unique()" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "a17b8b66", + "metadata": { + "scrolled": true + }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 18:32:01,241]\u001B[0m A new study created in memory with name: no-name-d2c12238-d18d-4c6f-bca4-840e7d3f29b0\u001B[0m\n", + "\u001B[32m[I 2022-12-12 18:41:40,178]\u001B[0m Trial 0 finished with value: 0.07156314077881751 and parameters: {'recomender': 'ALS', 'regularization': 0.0035671951579306937}. Best is trial 0 with value: 0.07156314077881751.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07156314077881751\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 18:51:48,671]\u001B[0m Trial 1 finished with value: 0.07241639094290958 and parameters: {'recomender': 'ALS', 'regularization': 0.006724126527816994}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07241639094290958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 18:53:18,697]\u001B[0m Trial 2 finished with value: 1.4050149479540313e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8190152272980945, 'k': 6, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 1.4050149479540313e-07\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 18:54:36,340]\u001B[0m Trial 3 finished with value: 0.005366068762176463 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.18723291153626603, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.005366068762176463\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 18:56:21,781]\u001B[0m Trial 4 finished with value: 0.0002205827579874263 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.6560234930178588, 'k': 6, 'loss': 'logistic'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.0002205827579874263\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:05:46,138]\u001B[0m Trial 5 finished with value: 0.07173988822226253 and parameters: {'recomender': 'ALS', 'regularization': 0.009044651486228098}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07173988822226253\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:07:05,748]\u001B[0m Trial 6 finished with value: 3.943062688880311e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.44751878244334975, 'k': 7, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 3.943062688880311e-06\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:08:22,099]\u001B[0m Trial 7 finished with value: 0.06793721324055035 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.10438302844592218, 'k': 3, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.06793721324055035\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:17:32,898]\u001B[0m Trial 8 finished with value: 0.07184311920591484 and parameters: {'recomender': 'ALS', 'regularization': 0.0005806772800434514}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07184311920591484\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:18:59,268]\u001B[0m Trial 9 finished with value: 2.2409988419866796e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.805131840226543, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 2.2409988419866796e-06\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:28:09,202]\u001B[0m Trial 10 finished with value: 0.07180954187357708 and parameters: {'recomender': 'ALS', 'regularization': 0.008190821633209066}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07180954187357708\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:37:15,147]\u001B[0m Trial 11 finished with value: 0.07244222251339615 and parameters: {'recomender': 'ALS', 'regularization': 0.00026970098377155163}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07244222251339615\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:46:24,260]\u001B[0m Trial 12 finished with value: 0.07202031081710311 and parameters: {'recomender': 'ALS', 'regularization': 0.0066363513358619185}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07202031081710311\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 19:55:34,176]\u001B[0m Trial 13 finished with value: 0.07199398893026046 and parameters: {'recomender': 'ALS', 'regularization': 0.004156107607150058}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07199398893026046\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 20:04:42,589]\u001B[0m Trial 14 finished with value: 0.07167963259586223 and parameters: {'recomender': 'ALS', 'regularization': 0.0006228566403390988}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167963259586223\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 20:13:49,348]\u001B[0m Trial 15 finished with value: 0.07202106855494453 and parameters: {'recomender': 'ALS', 'regularization': 0.00598705937836684}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07202106855494453\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 20:22:57,770]\u001B[0m Trial 16 finished with value: 0.07193963920172777 and parameters: {'recomender': 'ALS', 'regularization': 0.0028834604694796696}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07193963920172777\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 20:32:04,614]\u001B[0m Trial 17 finished with value: 0.07186249836889418 and parameters: {'recomender': 'ALS', 'regularization': 0.007249626991281137}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07186249836889418\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 20:41:24,258]\u001B[0m Trial 18 finished with value: 0.07164870366757094 and parameters: {'recomender': 'ALS', 'regularization': 0.005115162467576984}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07164870366757094\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 20:50:49,059]\u001B[0m Trial 19 finished with value: 0.07179004415938793 and parameters: {'recomender': 'ALS', 'regularization': 0.0018963762834092678}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07179004415938793\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 21:42:16,853]\u001B[0m Trial 20 finished with value: 0.07167129296212232 and parameters: {'recomender': 'ALS', 'regularization': 0.009804091535656343}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167129296212232\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 21:52:20,413]\u001B[0m Trial 21 finished with value: 0.07191839766465505 and parameters: {'recomender': 'ALS', 'regularization': 0.005764203522687446}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07191839766465505\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 22:02:12,773]\u001B[0m Trial 22 finished with value: 0.07159025974450188 and parameters: {'recomender': 'ALS', 'regularization': 0.006209360331833826}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07159025974450188\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 22:12:55,936]\u001B[0m Trial 23 finished with value: 0.07167021208897958 and parameters: {'recomender': 'ALS', 'regularization': 0.007825089420401029}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167021208897958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 22:23:04,762]\u001B[0m Trial 24 finished with value: 0.07191850988173716 and parameters: {'recomender': 'ALS', 'regularization': 0.004979324924695012}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07191850988173716\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 22:34:38,654]\u001B[0m Trial 25 finished with value: 0.07178449755342503 and parameters: {'recomender': 'ALS', 'regularization': 0.002381286135370409}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07178449755342503\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 22:45:43,850]\u001B[0m Trial 26 finished with value: 0.07177449403191542 and parameters: {'recomender': 'ALS', 'regularization': 0.004677821831829}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07177449403191542\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 22:56:45,636]\u001B[0m Trial 27 finished with value: 0.07214439856613958 and parameters: {'recomender': 'ALS', 'regularization': 0.0069504676367203744}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07214439856613958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 23:08:13,361]\u001B[0m Trial 28 finished with value: 0.07237690498752612 and parameters: {'recomender': 'ALS', 'regularization': 0.0074561399301387955}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07237690498752612\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m[I 2022-12-12 23:18:05,878]\u001B[0m Trial 29 finished with value: 0.07173589378156864 and parameters: {'recomender': 'ALS', 'regularization': 0.00848249465326267}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "user_features - {'income', 'age', 'sex'}\n", - "item_features - {'age_feature', 'countries', 'studios', 'genre', 'content_type'}\n" + "MAP@10 0.07173589378156864\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[33m[W 2022-12-12 23:27:26,180]\u001B[0m Trial 30 failed because of the following error: KeyboardInterrupt()\u001B[0m\n", + "Traceback (most recent call last):\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", + " value_or_values = func(trial)\n", + " File \"/tmp/ipykernel_5286/352742220.py\", line 40, in objective\n", + " recos = model.recommend(\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\", line 132, in recommend\n", + " reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 141, in _recommend_u2i\n", + " scores = scores_calculator.calc(target_id)\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 98, in calc\n", + " scores = self.objects_factors @ subject_factors\n", + "KeyboardInterrupt\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", + "\u001B[0;32m/tmp/ipykernel_5286/352742220.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 48\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 49\u001B[0m \u001B[0mstudy\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0moptuna\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcreate_study\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mdirection\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m'maximize'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 50\u001B[0;31m \u001B[0mstudy\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0moptimize\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mobjective\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mn_trials\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;36m100\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001B[0m in \u001B[0;36moptimize\u001B[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 417\u001B[0m \"\"\"\n\u001B[1;32m 418\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 419\u001B[0;31m _optimize(\n\u001B[0m\u001B[1;32m 420\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 421\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_optimize\u001B[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 64\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 65\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mn_jobs\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0;36m1\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 66\u001B[0;31m _optimize_sequential(\n\u001B[0m\u001B[1;32m 67\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 68\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_optimize_sequential\u001B[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001B[0m\n\u001B[1;32m 158\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 159\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 160\u001B[0;31m \u001B[0mfrozen_trial\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0m_run_trial\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mstudy\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcatch\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 161\u001B[0m \u001B[0;32mfinally\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 162\u001B[0m \u001B[0;31m# The following line mitigates memory problems that can be occurred in some\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 232\u001B[0m \u001B[0;32mand\u001B[0m \u001B[0;32mnot\u001B[0m \u001B[0misinstance\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mfunc_err\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcatch\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 233\u001B[0m ):\n\u001B[0;32m--> 234\u001B[0;31m \u001B[0;32mraise\u001B[0m \u001B[0mfunc_err\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 235\u001B[0m \u001B[0;32mreturn\u001B[0m \u001B[0mfrozen_trial\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 236\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 194\u001B[0m \u001B[0;32mwith\u001B[0m \u001B[0mget_heartbeat_thread\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtrial\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_trial_id\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_storage\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 195\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 196\u001B[0;31m \u001B[0mvalue_or_values\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtrial\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 197\u001B[0m \u001B[0;32mexcept\u001B[0m \u001B[0mexceptions\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mTrialPruned\u001B[0m \u001B[0;32mas\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 198\u001B[0m \u001B[0;31m# TODO(mamu): Handle multi-objective cases.\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m/tmp/ipykernel_5286/352742220.py\u001B[0m in \u001B[0;36mobjective\u001B[0;34m(trial)\u001B[0m\n\u001B[1;32m 38\u001B[0m fit_features_together=True)\n\u001B[1;32m 39\u001B[0m \u001B[0mmodel\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mfit\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mdataset\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 40\u001B[0;31m recos = model.recommend(\n\u001B[0m\u001B[1;32m 41\u001B[0m \u001B[0musers\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mTEST_USERS\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 42\u001B[0m \u001B[0mdataset\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mdataset\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001B[0m in \u001B[0;36mrecommend\u001B[0;34m(self, users, dataset, k, filter_viewed, items_to_recommend, add_rank_col)\u001B[0m\n\u001B[1;32m 130\u001B[0m \u001B[0msorted_item_ids_to_recommend\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;32mNone\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 131\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 132\u001B[0;31m reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n\u001B[0m\u001B[1;32m 133\u001B[0m \u001B[0muser_ids\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 134\u001B[0m \u001B[0mdataset\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001B[0m in \u001B[0;36m_recommend_u2i\u001B[0;34m(self, user_ids, dataset, k, filter_viewed, sorted_item_ids_to_recommend)\u001B[0m\n\u001B[1;32m 139\u001B[0m \u001B[0mall_scores\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0mtp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mList\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mndarray\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m[\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 140\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mtarget_id\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mtqdm\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0muser_ids\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mdisable\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mverbose\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0;36m0\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 141\u001B[0;31m \u001B[0mscores\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mscores_calculator\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcalc\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtarget_id\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 142\u001B[0m reco_ids, reco_scores = recommend_from_scores(\n\u001B[1;32m 143\u001B[0m \u001B[0mscores\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mscores\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001B[0m in \u001B[0;36mcalc\u001B[0;34m(self, subject_id)\u001B[0m\n\u001B[1;32m 96\u001B[0m \u001B[0msubject_factors\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msubjects_factors\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0msubject_id\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 97\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdistance\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0mDistance\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mDOT\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 98\u001B[0;31m \u001B[0mscores\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mobjects_factors\u001B[0m \u001B[0;34m@\u001B[0m \u001B[0msubject_factors\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 99\u001B[0m \u001B[0;32melif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdistance\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0mDistance\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mEUCLIDEAN\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 100\u001B[0m \u001B[0msubject_dot\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msubjects_dots\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0msubject_id\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;31mKeyboardInterrupt\u001B[0m: " ] } ], "source": [ - "print('user_features -', set(user_features.feature))\n", - "print('item_features -', set(item_features.feature))" + "def objective(trial):\n", + " model_name = trial.suggest_categorical('recomender', ['LightFM',\n", + " 'ALS'])\n", + " if model_name == 'LightFM':\n", + " learning_rate = trial.suggest_float('learning_rate', 1e-10, 1)\n", + " k = trial.suggest_int('k', 2, 10)\n", + " loss = trial.suggest_categorical('loss', ['logistic', 'bpr',\n", + " 'warp'])\n", + " model = LightFMWrapperModel(LightFM(k=k,\n", + " learning_rate=learning_rate,\n", + " loss=loss, no_components=10),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS)\n", + " else:\n", + " regularization = trial.suggest_float('regularization', 1e-4,\n", + " 1e-2)\n", + " model = \\\n", + " ImplicitALSWrapperModel(model=AlternatingLeastSquares(factors=10,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=regularization),\n", + " fit_features_together=True)\n", + " model.fit(dataset)\n", + " recos = model.recommend(users=TEST_USERS, dataset=dataset,\n", + " k=K_RECOS, filter_viewed=True)\n", + " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", + " print ('MAP@10', metric)\n", + " return metric\n", + "\n", + "\n", + "study = optuna.create_study(direction='maximize')\n", + "study.optimize(objective, n_trials=100)" + ] + }, + { + "cell_type": "markdown", + "id": "3989645b", + "metadata": {}, + "source": [ + "## Пришлось остановить обучение, тк эти 30 эпох обучались 6 часов" ] }, { "cell_type": "code", - "execution_count": 64, - "id": "6288eea7", + "execution_count": 55, + "id": "99aae61e", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 663 ms, sys: 165 ms, total: 828 ms\n", - "Wall time: 900 ms\n" - ] + "data": { + "text/plain": [ + "{'recomender': 'ALS', 'regularization': 0.00026970098377155163}" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "%%time\n", - "dataset = Dataset.construct(\n", - " interactions_df=train,\n", - " user_features_df=user_features,\n", - " item_features_df=item_features,\n", - " cat_user_features=[\"sex\", \"age\", \"income\"],\n", - " cat_item_features=['age_feature', 'content_type', 'countries', 'genre', 'studios']\n", - ")" + "study.best_params" ] }, { "cell_type": "code", - "execution_count": 67, - "id": "d027f149", - "metadata": {}, + "execution_count": 233, "outputs": [], "source": [ - "TEST_USERS = test[Columns.User].unique()" - ] - }, - { - "cell_type": "markdown", - "id": "b73393d0", - "metadata": {}, - "source": [ - "## Baseline LightFM" - ] + "REGULARIZATION = 0.00026970098377155163" + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 69, - "id": "c99924ca", + "execution_count": 234, + "id": "d1f6069a", "metadata": {}, "outputs": [], "source": [ - "model = LightFMWrapperModel(\n", - " LightFM(\n", - " k=5,\n", - " no_components=32,\n", - " loss='warp',\n", + "# обучаем best model после optuna\n", + "model = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=32,\n", " random_state=RANDOM_STATE,\n", - " learning_rate=0.081651,\n", - " user_alpha=USER_ALPHA,\n", - " item_alpha=ITEM_ALPHA\n", + " num_threads=NUM_THREADS,\n", + " regularization=REGULARIZATION\n", " ),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS\n", + " fit_features_together=True\n", ")" ] }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 236, "id": "d3907c1d", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "model.fit(dataset)" ] }, { "cell_type": "code", - "execution_count": 71, + "execution_count": null, "id": "b2050a6e", "metadata": {}, "outputs": [], @@ -2706,822 +1591,536 @@ " users=TEST_USERS,\n", " dataset=dataset,\n", " k=K_RECOS,\n", - " filter_viewed=True,\n", + " filter_viewed=True\n", ")" ] }, { "cell_type": "code", - "execution_count": 72, - "id": "8c7da423", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_idscorerank
0203219104406.9803371
1203219152976.9500362
2203219138656.4135013
320321997286.3615484
420321941516.2872445
\n", - "
" - ], - "text/plain": [ - " user_id item_id score rank\n", - "0 203219 10440 6.980337 1\n", - "1 203219 15297 6.950036 2\n", - "2 203219 13865 6.413501 3\n", - "3 203219 9728 6.361548 4\n", - "4 203219 4151 6.287244 5" - ] - }, - "execution_count": 72, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "recos.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 73, + "execution_count": 59, "id": "6bbe3ff3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'Precision@1': 0.07467204843592332,\n", - " 'Recall@1': 0.03845573009300656,\n", - " 'Precision@2': 0.0649131658611716,\n", - " 'Recall@2': 0.06533320917725449,\n", - " 'Precision@3': 0.05858575129380801,\n", - " 'Recall@3': 0.08732125781565075,\n", - " 'Precision@4': 0.053242338945244036,\n", - " 'Recall@4': 0.10450467843880465,\n", - " 'Precision@5': 0.04813673942677076,\n", - " 'Recall@5': 0.11660090113349054,\n", - " 'Precision@6': 0.04386112438850237,\n", - " 'Recall@6': 0.12606432618063965,\n", - " 'Precision@7': 0.04029751472525916,\n", - " 'Recall@7': 0.13385118540696275,\n", - " 'Precision@8': 0.037416795014782164,\n", - " 'Recall@8': 0.14120255388899725,\n", - " 'Precision@9': 0.03498445069957099,\n", - " 'Recall@9': 0.14776157788428726,\n", - " 'Precision@10': 0.03296510701577354,\n", - " 'Recall@10': 0.15403037510704012,\n", - " 'MAP@1': 0.03845573009300656,\n", - " 'MAP@2': 0.05246902559206522,\n", - " 'MAP@3': 0.06034291707347781,\n", - " 'MAP@4': 0.06511711937144428,\n", - " 'MAP@5': 0.06788409272317658,\n", - " 'MAP@6': 0.06973275065780024,\n", - " 'MAP@7': 0.071056944551092,\n", - " 'MAP@8': 0.07213601259055538,\n", - " 'MAP@9': 0.0730308574271295,\n", - " 'MAP@10': 0.07379233810864445}" + "0.07124010116092815" ] }, - "execution_count": 73, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "metric_values = calc_metrics(metrics, recos, test, train)\n", - "metric_values" + "calc_metrics(metrics, recos, test, train)['MAP@10']" ] }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 61, "id": "d3eead34", "metadata": {}, "outputs": [], "source": [ "recos = recos[['user_id', 'item_id']]\n", - "recos.to_csv('../data/base_LightFM.csv.gz', index=False, compression='gzip')" + "recos.to_csv('ALS_after_optuna.csv.gz', index=False, compression='gzip')" ] }, { "cell_type": "markdown", - "id": "bb0b92d4", - "metadata": {}, "source": [ - "## Grid Search ALS and LightFM" - ] + "# Добавление аватаров\n", + "Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**" + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": null, - "id": "1740223a", - "metadata": {}, + "execution_count": 264, "outputs": [], "source": [ - "models = {}\n", - "implicit_models = {\n", - " 'ALS': AlternatingLeastSquares,\n", - "}\n", - "for implicit_name, implicit_model in implicit_models.items():\n", - " for is_fitting_features in (True, False):\n", - " for n_factors in N_FACTORS:\n", - " models[f\"{implicit_name}_{n_factors}_{is_fitting_features}\"] = (\n", - " ImplicitALSWrapperModel(\n", - " model=implicit_model(\n", - " factors=n_factors,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " ),\n", - " fit_features_together=is_fitting_features,\n", - " )\n", - " )\n", - "\n", - "for loss in ('logistic', 'bpr', 'warp'): # lightfm losses\n", - " for n_factors in N_FACTORS:\n", - " models[f\"LightFM_{loss}_{n_factors}\"] = LightFMWrapperModel(\n", - " LightFM(\n", - " no_components=n_factors,\n", - " loss=loss,\n", - " random_state=RANDOM_STATE,\n", - " learning_rate=LEARNING_RATE,\n", - " user_alpha=USER_ALPHA,\n", - " item_alpha=ITEM_ALPHA,\n", - " ),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS,\n", - " )\n", + "some_avatars = pd.DataFrame(\n", + " {\n", + " Columns.User: [11111111, 11111112, 11111113],\n", + " Columns.Item: [\n", + " [10732, 3369, 15885], # Аватар, который любит мультики [губка боб, кунг-фу панда, ]\n", + " [3506, 1107, 11235], # Аватар, который любит боевики [форсаж, обитель зла, плохие парни]\n", + " [931, 389, 8315] # Аватар, который любит драмы [после, хатико, сумерки]\n", + " ],\n", + " 'last_watch_dt': [\n", + " [random.choice(sorted(interactions.last_watch_dt.unique())[-10:]) for _ in range(3)] for i in range(3)\n", + " ],\n", + " \"total_dur\": [\n", + " [34343, 6000, 9000],\n", + " [5000, 45452, 9000],\n", + " [5000, 3200, 3232]\n", + " ],\n", + " \"watched_pct\": [\n", + " [100.0, 95.0, 99.0],\n", + " [67.0, 95.0, 99.0],\n", + " [100.0, 53.0, 99.0]\n", + " ],\n", + " Columns.Weight: [\n", + " [5, 5, 5],\n", + " [3, 5, 5],\n", + " [5, 2, 5]\n", + " ]\n", + " }\n", + ")\n", "\n", - "print(models)" - ] + "some_avatars = some_avatars.explode(\n", + " [Columns.Item, Columns.Datetime, \"total_dur\", \"watched_pct\", Columns.Weight]\n", + ").reset_index(drop=True)" + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 76, - "id": "0d5edb2b", - "metadata": {}, + "execution_count": 265, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitting model ALS_32_True...\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", - "File \u001B[0;32m:6\u001B[0m\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/base.py:55\u001B[0m, in \u001B[0;36mModelBase.fit\u001B[0;34m(self, dataset, *args, **kwargs)\u001B[0m\n\u001B[1;32m 42\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mfit\u001B[39m(\u001B[38;5;28mself\u001B[39m: T, dataset: Dataset, \u001B[38;5;241m*\u001B[39margs: tp\u001B[38;5;241m.\u001B[39mAny, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: tp\u001B[38;5;241m.\u001B[39mAny) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m T:\n\u001B[1;32m 43\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 44\u001B[0m \u001B[38;5;124;03m Fit model.\u001B[39;00m\n\u001B[1;32m 45\u001B[0m \n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 53\u001B[0m \u001B[38;5;124;03m self\u001B[39;00m\n\u001B[1;32m 54\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m---> 55\u001B[0m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_fit\u001B[49m\u001B[43m(\u001B[49m\u001B[43mdataset\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43margs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 56\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mis_fitted \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m 57\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:71\u001B[0m, in \u001B[0;36mImplicitALSWrapperModel._fit\u001B[0;34m(self, dataset)\u001B[0m\n\u001B[1;32m 68\u001B[0m ui_csr \u001B[38;5;241m=\u001B[39m dataset\u001B[38;5;241m.\u001B[39mget_user_item_matrix(include_weights\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[1;32m 70\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfit_features_together:\n\u001B[0;32m---> 71\u001B[0m user_factors, item_factors \u001B[38;5;241m=\u001B[39m \u001B[43mfit_als_with_features_together\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 72\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 73\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 74\u001B[0m \u001B[43m \u001B[49m\u001B[43mdataset\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43muser_features\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 75\u001B[0m \u001B[43m \u001B[49m\u001B[43mdataset\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mitem_features\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 76\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mverbose\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 77\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 78\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 79\u001B[0m user_factors, item_factors \u001B[38;5;241m=\u001B[39m fit_als_with_features_separately(\n\u001B[1;32m 80\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmodel,\n\u001B[1;32m 81\u001B[0m ui_csr,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 84\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mverbose,\n\u001B[1;32m 85\u001B[0m )\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:317\u001B[0m, in \u001B[0;36mfit_als_with_features_together\u001B[0;34m(model, ui_csr, user_features, item_features, verbose)\u001B[0m\n\u001B[1;32m 307\u001B[0m _fit_combined_factors_on_gpu_inplace(\n\u001B[1;32m 308\u001B[0m model,\n\u001B[1;32m 309\u001B[0m ui_csr,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 314\u001B[0m verbose,\n\u001B[1;32m 315\u001B[0m )\n\u001B[1;32m 316\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m--> 317\u001B[0m \u001B[43m_fit_combined_factors_on_cpu_inplace\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 318\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 319\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 320\u001B[0m \u001B[43m \u001B[49m\u001B[43muser_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 321\u001B[0m \u001B[43m \u001B[49m\u001B[43mitem_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 322\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_user_explicit_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 323\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_item_explicit_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 324\u001B[0m \u001B[43m \u001B[49m\u001B[43mverbose\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 325\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 327\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m user_factors, item_factors\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:345\u001B[0m, in \u001B[0;36m_fit_combined_factors_on_cpu_inplace\u001B[0;34m(model, ui_csr, user_factors, item_factors, n_user_explicit_factors, n_item_explicit_factors, verbose)\u001B[0m\n\u001B[1;32m 342\u001B[0m iu_csr \u001B[38;5;241m=\u001B[39m ui_csr\u001B[38;5;241m.\u001B[39mT\u001B[38;5;241m.\u001B[39mtocsr(copy\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m)\n\u001B[1;32m 344\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m _ \u001B[38;5;129;01min\u001B[39;00m tqdm(\u001B[38;5;28mrange\u001B[39m(model\u001B[38;5;241m.\u001B[39miterations), disable\u001B[38;5;241m=\u001B[39mverbose \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m0\u001B[39m):\n\u001B[0;32m--> 345\u001B[0m \u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43msolver\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 346\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 347\u001B[0m \u001B[43m \u001B[49m\u001B[43muser_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 348\u001B[0m \u001B[43m \u001B[49m\u001B[43mitem_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 349\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mregularization\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 350\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mnum_threads\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 351\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 352\u001B[0m user_factors[:, :n_user_explicit_factors] \u001B[38;5;241m=\u001B[39m user_explicit_factors\n\u001B[1;32m 354\u001B[0m model\u001B[38;5;241m.\u001B[39msolver(\n\u001B[1;32m 355\u001B[0m iu_csr,\n\u001B[1;32m 356\u001B[0m item_factors,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 359\u001B[0m model\u001B[38;5;241m.\u001B[39mnum_threads,\n\u001B[1;32m 360\u001B[0m )\n", - "\u001B[0;31mKeyboardInterrupt\u001B[0m: " - ] + "data": { + "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n0 11111111 10732 2021-08-22 34343 100.0 5\n1 11111111 3369 2021-08-19 6000 95.0 5\n2 11111111 15885 2021-08-17 9000 99.0 5\n3 11111112 3506 2021-08-20 5000 67.0 3\n4 11111112 1107 2021-08-14 45452 95.0 5\n5 11111112 11235 2021-08-19 9000 99.0 5\n6 11111113 931 2021-08-14 5000 100.0 5\n7 11111113 389 2021-08-19 3200 53.0 2\n8 11111113 8315 2021-08-22 3232 99.0 5", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
011111111107322021-08-2234343100.05
11111111133692021-08-19600095.05
211111111158852021-08-17900099.05
31111111235062021-08-20500067.03
41111111211072021-08-144545295.05
511111112112352021-08-19900099.05
6111111139312021-08-145000100.05
7111111133892021-08-19320053.02
81111111383152021-08-22323299.05
\n
" + }, + "execution_count": 265, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "%%time\n", - "results = []\n", - "for model_name, model in models.items():\n", - " print(f\"Fitting model {model_name}...\")\n", - " model_quality = {'model': model_name}\n", - "\n", - " model.fit(dataset)\n", - " recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True,\n", - " )\n", - " metric_values = calc_metrics(metrics, recos, test, train)\n", - " model_quality.update(metric_values)\n", - " results.append(model_quality)\n", - "\n", - "df_quality_grid_search = pd.DataFrame(results).T\n", - "df_quality_grid_search.columns = df_quality_grid_search.iloc[0]\n", - "df_quality_grid_search.drop('model', inplace=True)\n", - "\n", - "df_quality_grid_search.style.highlight_max(color='lightgreen', axis=1)" - ] + "some_avatars" + ], + "metadata": { + "collapsed": false + } }, { - "cell_type": "markdown", - "id": "2c603783", - "metadata": {}, + "cell_type": "code", + "execution_count": 266, + "outputs": [], "source": [ - "# Optuna" - ] + "interactions_with_avatars = pd.concat([interactions, some_avatars])\n", + "\n", + "dataset_with_avatars = Dataset.construct(\n", + " interactions_df=interactions_with_avatars,\n", + ")\n", + "\n", + "# обучаем best model после optuna\n", + "model_with_avatars = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=32,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=REGULARIZATION\n", + " ),\n", + " fit_features_together=True\n", + ")" + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 77, - "id": "a17b8b66", - "metadata": {}, + "execution_count": 267, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-11 01:16:32,212]\u001B[0m A new study created in memory with name: no-name-db609323-c8c4-4475-8bcf-6d559813862c\u001B[0m\n", - "\u001B[32m[I 2022-12-11 01:17:37,725]\u001B[0m Trial 0 finished with value: 3.6209115294627156e-05 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.5486709126434274, 'k': 3, 'loss': 'warp', 'no_components': 57}. Best is trial 0 with value: 3.6209115294627156e-05.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 3.6209115294627156e-05\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[33m[W 2022-12-11 01:36:33,239]\u001B[0m Trial 1 failed because of the following error: KeyboardInterrupt()\u001B[0m\n", - "Traceback (most recent call last):\n", - " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", - " value_or_values = func(trial)\n", - " File \"/var/folders/f8/ytvrd_xj4gvd76trh8sqryh80000gn/T/ipykernel_2736/210213320.py\", line 38, in objective\n", - " model.fit(dataset)\n", - " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/base.py\", line 55, in fit\n", - " self._fit(dataset, *args, **kwargs)\n", - " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py\", line 71, in _fit\n", - " user_factors, item_factors = fit_als_with_features_together(\n", - " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py\", line 317, in fit_als_with_features_together\n", - " _fit_combined_factors_on_cpu_inplace(\n", - " File \"/Users/renat/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py\", line 345, in _fit_combined_factors_on_cpu_inplace\n", - " model.solver(\n", - "KeyboardInterrupt\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", - "Cell \u001B[0;32mIn[77], line 51\u001B[0m\n\u001B[1;32m 48\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m metric\n\u001B[1;32m 50\u001B[0m study \u001B[38;5;241m=\u001B[39m optuna\u001B[38;5;241m.\u001B[39mcreate_study(direction \u001B[38;5;241m=\u001B[39m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mmaximize\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[0;32m---> 51\u001B[0m \u001B[43mstudy\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43moptimize\u001B[49m\u001B[43m(\u001B[49m\u001B[43mobjective\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mn_trials\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m \u001B[49m\u001B[38;5;241;43m10\u001B[39;49m\u001B[43m)\u001B[49m\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/study.py:419\u001B[0m, in \u001B[0;36mStudy.optimize\u001B[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 315\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21moptimize\u001B[39m(\n\u001B[1;32m 316\u001B[0m \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m 317\u001B[0m func: ObjectiveFuncType,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 324\u001B[0m show_progress_bar: \u001B[38;5;28mbool\u001B[39m \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m 325\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m 326\u001B[0m \u001B[38;5;124;03m\"\"\"Optimize an objective function.\u001B[39;00m\n\u001B[1;32m 327\u001B[0m \n\u001B[1;32m 328\u001B[0m \u001B[38;5;124;03m Optimization is done by choosing a suitable set of hyperparameter values from a given\u001B[39;00m\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 416\u001B[0m \u001B[38;5;124;03m If nested invocation of this method occurs.\u001B[39;00m\n\u001B[1;32m 417\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m--> 419\u001B[0m \u001B[43m_optimize\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 420\u001B[0m \u001B[43m \u001B[49m\u001B[43mstudy\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[1;32m 421\u001B[0m \u001B[43m \u001B[49m\u001B[43mfunc\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mfunc\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 422\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_trials\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mn_trials\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 423\u001B[0m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 424\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_jobs\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mn_jobs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 425\u001B[0m \u001B[43m \u001B[49m\u001B[43mcatch\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mcatch\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 426\u001B[0m \u001B[43m \u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mcallbacks\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 427\u001B[0m \u001B[43m \u001B[49m\u001B[43mgc_after_trial\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mgc_after_trial\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 428\u001B[0m \u001B[43m \u001B[49m\u001B[43mshow_progress_bar\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mshow_progress_bar\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 429\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py:66\u001B[0m, in \u001B[0;36m_optimize\u001B[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 64\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m 65\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m n_jobs \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m1\u001B[39m:\n\u001B[0;32m---> 66\u001B[0m \u001B[43m_optimize_sequential\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 67\u001B[0m \u001B[43m \u001B[49m\u001B[43mstudy\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 68\u001B[0m \u001B[43m \u001B[49m\u001B[43mfunc\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 69\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_trials\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 70\u001B[0m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 71\u001B[0m \u001B[43m \u001B[49m\u001B[43mcatch\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 72\u001B[0m \u001B[43m \u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 73\u001B[0m \u001B[43m \u001B[49m\u001B[43mgc_after_trial\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 74\u001B[0m \u001B[43m \u001B[49m\u001B[43mreseed_sampler_rng\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[1;32m 75\u001B[0m \u001B[43m \u001B[49m\u001B[43mtime_start\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mNone\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[1;32m 76\u001B[0m \u001B[43m \u001B[49m\u001B[43mprogress_bar\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mprogress_bar\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 77\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 78\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 79\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m n_jobs \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m1\u001B[39m:\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py:160\u001B[0m, in \u001B[0;36m_optimize_sequential\u001B[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001B[0m\n\u001B[1;32m 157\u001B[0m \u001B[38;5;28;01mbreak\u001B[39;00m\n\u001B[1;32m 159\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 160\u001B[0m frozen_trial \u001B[38;5;241m=\u001B[39m \u001B[43m_run_trial\u001B[49m\u001B[43m(\u001B[49m\u001B[43mstudy\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mfunc\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcatch\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 161\u001B[0m \u001B[38;5;28;01mfinally\u001B[39;00m:\n\u001B[1;32m 162\u001B[0m \u001B[38;5;66;03m# The following line mitigates memory problems that can be occurred in some\u001B[39;00m\n\u001B[1;32m 163\u001B[0m \u001B[38;5;66;03m# environments (e.g., services that use computing containers such as CircleCI).\u001B[39;00m\n\u001B[1;32m 164\u001B[0m \u001B[38;5;66;03m# Please refer to the following PR for further details:\u001B[39;00m\n\u001B[1;32m 165\u001B[0m \u001B[38;5;66;03m# https://github.com/optuna/optuna/pull/325.\u001B[39;00m\n\u001B[1;32m 166\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m gc_after_trial:\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py:234\u001B[0m, in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 227\u001B[0m \u001B[38;5;28;01massert\u001B[39;00m \u001B[38;5;28;01mFalse\u001B[39;00m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mShould not reach.\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 229\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m (\n\u001B[1;32m 230\u001B[0m frozen_trial\u001B[38;5;241m.\u001B[39mstate \u001B[38;5;241m==\u001B[39m TrialState\u001B[38;5;241m.\u001B[39mFAIL\n\u001B[1;32m 231\u001B[0m \u001B[38;5;129;01mand\u001B[39;00m func_err \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(func_err, catch)\n\u001B[1;32m 233\u001B[0m ):\n\u001B[0;32m--> 234\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m func_err\n\u001B[1;32m 235\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m frozen_trial\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/optuna/study/_optimize.py:196\u001B[0m, in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 194\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m get_heartbeat_thread(trial\u001B[38;5;241m.\u001B[39m_trial_id, study\u001B[38;5;241m.\u001B[39m_storage):\n\u001B[1;32m 195\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 196\u001B[0m value_or_values \u001B[38;5;241m=\u001B[39m \u001B[43mfunc\u001B[49m\u001B[43m(\u001B[49m\u001B[43mtrial\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 197\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m exceptions\u001B[38;5;241m.\u001B[39mTrialPruned \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m 198\u001B[0m \u001B[38;5;66;03m# TODO(mamu): Handle multi-objective cases.\u001B[39;00m\n\u001B[1;32m 199\u001B[0m state \u001B[38;5;241m=\u001B[39m TrialState\u001B[38;5;241m.\u001B[39mPRUNED\n", - "Cell \u001B[0;32mIn[77], line 38\u001B[0m, in \u001B[0;36mobjective\u001B[0;34m(trial)\u001B[0m\n\u001B[1;32m 28\u001B[0m model \u001B[38;5;241m=\u001B[39m ImplicitALSWrapperModel(\n\u001B[1;32m 29\u001B[0m model\u001B[38;5;241m=\u001B[39mAlternatingLeastSquares(\n\u001B[1;32m 30\u001B[0m factors\u001B[38;5;241m=\u001B[39mfactors,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 35\u001B[0m fit_features_together\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m 36\u001B[0m )\n\u001B[1;32m 37\u001B[0m \u001B[38;5;66;03m# Обучение модели и предикт для подсчета метрик\u001B[39;00m\n\u001B[0;32m---> 38\u001B[0m \u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mfit\u001B[49m\u001B[43m(\u001B[49m\u001B[43mdataset\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 40\u001B[0m recos \u001B[38;5;241m=\u001B[39m model\u001B[38;5;241m.\u001B[39mrecommend(\n\u001B[1;32m 41\u001B[0m users\u001B[38;5;241m=\u001B[39mTEST_USERS,\n\u001B[1;32m 42\u001B[0m dataset\u001B[38;5;241m=\u001B[39mdataset,\n\u001B[1;32m 43\u001B[0m k\u001B[38;5;241m=\u001B[39mK_RECOS,\n\u001B[1;32m 44\u001B[0m filter_viewed\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m 45\u001B[0m )\n\u001B[1;32m 46\u001B[0m metric \u001B[38;5;241m=\u001B[39m calc_metrics(metrics, recos, test, train)[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mMAP@10\u001B[39m\u001B[38;5;124m'\u001B[39m]\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/base.py:55\u001B[0m, in \u001B[0;36mModelBase.fit\u001B[0;34m(self, dataset, *args, **kwargs)\u001B[0m\n\u001B[1;32m 42\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mfit\u001B[39m(\u001B[38;5;28mself\u001B[39m: T, dataset: Dataset, \u001B[38;5;241m*\u001B[39margs: tp\u001B[38;5;241m.\u001B[39mAny, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: tp\u001B[38;5;241m.\u001B[39mAny) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m T:\n\u001B[1;32m 43\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 44\u001B[0m \u001B[38;5;124;03m Fit model.\u001B[39;00m\n\u001B[1;32m 45\u001B[0m \n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 53\u001B[0m \u001B[38;5;124;03m self\u001B[39;00m\n\u001B[1;32m 54\u001B[0m \u001B[38;5;124;03m \"\"\"\u001B[39;00m\n\u001B[0;32m---> 55\u001B[0m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_fit\u001B[49m\u001B[43m(\u001B[49m\u001B[43mdataset\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43margs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 56\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mis_fitted \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m 57\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:71\u001B[0m, in \u001B[0;36mImplicitALSWrapperModel._fit\u001B[0;34m(self, dataset)\u001B[0m\n\u001B[1;32m 68\u001B[0m ui_csr \u001B[38;5;241m=\u001B[39m dataset\u001B[38;5;241m.\u001B[39mget_user_item_matrix(include_weights\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[1;32m 70\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfit_features_together:\n\u001B[0;32m---> 71\u001B[0m user_factors, item_factors \u001B[38;5;241m=\u001B[39m \u001B[43mfit_als_with_features_together\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 72\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 73\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 74\u001B[0m \u001B[43m \u001B[49m\u001B[43mdataset\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43muser_features\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 75\u001B[0m \u001B[43m \u001B[49m\u001B[43mdataset\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mitem_features\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 76\u001B[0m \u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mverbose\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 77\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 78\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 79\u001B[0m user_factors, item_factors \u001B[38;5;241m=\u001B[39m fit_als_with_features_separately(\n\u001B[1;32m 80\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmodel,\n\u001B[1;32m 81\u001B[0m ui_csr,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 84\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mverbose,\n\u001B[1;32m 85\u001B[0m )\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:317\u001B[0m, in \u001B[0;36mfit_als_with_features_together\u001B[0;34m(model, ui_csr, user_features, item_features, verbose)\u001B[0m\n\u001B[1;32m 307\u001B[0m _fit_combined_factors_on_gpu_inplace(\n\u001B[1;32m 308\u001B[0m model,\n\u001B[1;32m 309\u001B[0m ui_csr,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 314\u001B[0m verbose,\n\u001B[1;32m 315\u001B[0m )\n\u001B[1;32m 316\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m--> 317\u001B[0m \u001B[43m_fit_combined_factors_on_cpu_inplace\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 318\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 319\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 320\u001B[0m \u001B[43m \u001B[49m\u001B[43muser_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 321\u001B[0m \u001B[43m \u001B[49m\u001B[43mitem_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 322\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_user_explicit_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 323\u001B[0m \u001B[43m \u001B[49m\u001B[43mn_item_explicit_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 324\u001B[0m \u001B[43m \u001B[49m\u001B[43mverbose\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 325\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 327\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m user_factors, item_factors\n", - "File \u001B[0;32m~/PycharmProjects/RecoServiceMTS_v2/.venv/lib/python3.9/site-packages/rectools/models/implicit_als.py:345\u001B[0m, in \u001B[0;36m_fit_combined_factors_on_cpu_inplace\u001B[0;34m(model, ui_csr, user_factors, item_factors, n_user_explicit_factors, n_item_explicit_factors, verbose)\u001B[0m\n\u001B[1;32m 342\u001B[0m iu_csr \u001B[38;5;241m=\u001B[39m ui_csr\u001B[38;5;241m.\u001B[39mT\u001B[38;5;241m.\u001B[39mtocsr(copy\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m)\n\u001B[1;32m 344\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m _ \u001B[38;5;129;01min\u001B[39;00m tqdm(\u001B[38;5;28mrange\u001B[39m(model\u001B[38;5;241m.\u001B[39miterations), disable\u001B[38;5;241m=\u001B[39mverbose \u001B[38;5;241m==\u001B[39m \u001B[38;5;241m0\u001B[39m):\n\u001B[0;32m--> 345\u001B[0m \u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43msolver\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m 346\u001B[0m \u001B[43m \u001B[49m\u001B[43mui_csr\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 347\u001B[0m \u001B[43m \u001B[49m\u001B[43muser_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 348\u001B[0m \u001B[43m \u001B[49m\u001B[43mitem_factors\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 349\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mregularization\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 350\u001B[0m \u001B[43m \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mnum_threads\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m 351\u001B[0m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 352\u001B[0m user_factors[:, :n_user_explicit_factors] \u001B[38;5;241m=\u001B[39m user_explicit_factors\n\u001B[1;32m 354\u001B[0m model\u001B[38;5;241m.\u001B[39msolver(\n\u001B[1;32m 355\u001B[0m iu_csr,\n\u001B[1;32m 356\u001B[0m item_factors,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 359\u001B[0m model\u001B[38;5;241m.\u001B[39mnum_threads,\n\u001B[1;32m 360\u001B[0m )\n", - "\u001B[0;31mKeyboardInterrupt\u001B[0m: " - ] + "data": { + "text/plain": "" + }, + "execution_count": 267, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "def objective(trial):\n", - " # параметры для подбора типа модели\n", - " model_name = trial.suggest_categorical('recomender', ['LightFM', 'ALS'])\n", - "\n", - " if model_name == 'LightFM':\n", - " # параметры для подбора модели LightFM\n", - " learning_rate = trial.suggest_float('learning_rate', 0.001, 0.1)\n", - " k = trial.suggest_int('k', 2, 10)\n", - " loss = trial.suggest_categorical('loss',['logistic', 'bpr', 'warp'])\n", - " no_components = trial.suggest_int('no_components', 5, 64)\n", - "\n", - " # Создание инстанса модели\n", - " model = LightFMWrapperModel(\n", - " LightFM(\n", - " no_components=no_components,\n", - " k=k,\n", - " learning_rate=learning_rate,\n", - " loss=loss,\n", - " ),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS\n", - " )\n", - " else:\n", - " # параметры для подбора модели ALS\n", - " factors = trial.suggest_int('factors', 32, 128)\n", - " regularization = trial.suggest_float('regularization', 0.001, 0.1)\n", - "\n", - " # Создание инстанса модели\n", - " model = ImplicitALSWrapperModel(\n", - " model=AlternatingLeastSquares(\n", - " factors=factors,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=regularization\n", - " ),\n", - " fit_features_together=True\n", - " )\n", - " # Обучение модели и предикт для подсчета метрик\n", - " model.fit(dataset)\n", - "\n", - " recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True\n", - " )\n", - " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", - " print(\"MAP@10\", metric)\n", - " return metric\n", - "\n", - "study = optuna.create_study(direction = 'maximize')\n", - "study.optimize(objective, n_trials = 10)" - ] + "model_with_avatars.fit(dataset_with_avatars)" + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 78, - "id": "99aae61e", - "metadata": {}, + "execution_count": 268, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "best params from optuna - {'recomender': 'LightFM', 'learning_rate': 0.5486709126434274, 'k': 3, 'loss': 'warp', 'no_components': 57}\n" - ] + { + "data": { + "text/plain": " user_id item_id score rank\n0 11111111 11985 0.040700 1\n1 11111111 2954 0.039466 2\n2 11111111 7310 0.036591 3\n3 11111111 3182 0.035423 4\n4 11111111 4475 0.034422 5\n5 11111112 7793 0.035639 1\n6 11111112 4702 0.035139 2\n7 11111112 16361 0.034857 3\n8 11111112 1287 0.034327 4\n9 11111112 11018 0.032349 5\n10 11111113 1916 0.245655 1\n11 11111113 14470 0.242786 2\n12 11111113 101 0.219231 3\n13 11111113 12463 0.206615 4\n14 11111113 5732 0.183012 5", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idscorerank
011111111119850.0407001
11111111129540.0394662
21111111173100.0365913
31111111131820.0354234
41111111144750.0344225
51111111277930.0356391
61111111247020.0351392
711111112163610.0348573
81111111212870.0343274
911111112110180.0323495
101111111319160.2456551
1111111113144700.2427862
12111111131010.2192313
1311111113124630.2066154
141111111357320.1830125
\n
" + }, + "execution_count": 268, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "print('best params from optuna -', study.best_params)" - ] + "recos_with_avatars = model_with_avatars.recommend(\n", + " users=[11111111, 11111112, 11111113],\n", + " dataset=dataset_with_avatars,\n", + " k=5,\n", + " filter_viewed=True\n", + ")\n", + "recos_with_avatars" + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 84, - "id": "8428c4c7", - "metadata": {}, + "execution_count": 269, "outputs": [ { "data": { - "text/plain": [ - "{'Precision@1': 3.540637668844159e-05,\n", - " 'Recall@1': 1.4548389395699396e-05,\n", - " 'Precision@2': 3.098057960238639e-05,\n", - " 'Recall@2': 1.9395690966140803e-05,\n", - " 'Precision@3': 2.3604251125627725e-05,\n", - " 'Recall@3': 2.824728513825121e-05,\n", - " 'Precision@4': 2.8767681059358792e-05,\n", - " 'Recall@4': 3.996894166313679e-05,\n", - " 'Precision@5': 2.4784463681909114e-05,\n", - " 'Recall@5': 4.144420735848852e-05,\n", - " 'Precision@6': 2.0653719734924258e-05,\n", - " 'Recall@6': 4.144420735848852e-05,\n", - " 'Precision@7': 1.896770179737942e-05,\n", - " 'Recall@7': 4.1526932537667124e-05,\n", - " 'Precision@8': 1.8809637615734594e-05,\n", - " 'Recall@8': 4.7427995319074045e-05,\n", - " 'Precision@9': 1.868669880778862e-05,\n", - " 'Recall@9': 4.834627294577257e-05,\n", - " 'Precision@10': 1.8588347761431833e-05,\n", - " 'Recall@10': 5.295271481085044e-05,\n", - " 'MAP@1': 1.4548389395699396e-05,\n", - " 'MAP@2': 1.69720401809201e-05,\n", - " 'MAP@3': 1.9922571571623564e-05,\n", - " 'MAP@4': 2.2852985702844963e-05,\n", - " 'MAP@5': 2.3148038841915313e-05,\n", - " 'MAP@6': 2.3148038841915313e-05,\n", - " 'MAP@7': 2.3159856724655112e-05,\n", - " 'MAP@8': 2.3897489572330977e-05,\n", - " 'MAP@9': 2.3999520419741923e-05,\n", - " 'MAP@10': 2.4460164606249712e-05}" - ] + "text/plain": " user_id item_id score rank content_type title \\\n0 11111111 11985 0.040700 1 film История игрушек 4 \n1 11111111 2954 0.039466 2 film Миньоны \n2 11111111 7310 0.036591 3 film Гадкий я 2 \n3 11111111 3182 0.035423 4 film Ральф против Интернета \n4 11111111 4475 0.034422 5 film Тачки \n5 11111112 7793 0.035639 1 film Радиовспышка \n6 11111112 4702 0.035139 2 film Хищник \n7 11111112 16361 0.034857 3 film Doom: Аннигиляция \n8 11111112 1287 0.034327 4 film Терминатор: Тёмные судьбы \n9 11111112 11018 0.032349 5 film Хищники \n10 11111113 1916 0.245655 1 film Секс и ничего лишнего \n11 11111113 14470 0.242786 2 film Любовь \n12 11111113 101 0.219231 3 film Куриоса \n13 11111113 12463 0.206615 4 film Студентка по вызову \n14 11111113 5732 0.183012 5 film Тайное влечение \n\n title_orig release_year \\\n0 Toy Story 4 2019.0 \n1 Minions 2015.0 \n2 Despicable Me 2 2013.0 \n3 Ralph Breaks the Internet 2018.0 \n4 Cars 2006.0 \n5 Radioflash 2019.0 \n6 Predator 1987.0 \n7 Doom: Annihilation 2019.0 \n8 Terminator: Dark Fate 2019.0 \n9 Predators 2010.0 \n10 My Awkward Sexual Adventure 2012.0 \n11 Love 2015.0 \n12 Curiosa 2019.0 \n13 Mes chères études 2010.0 \n14 Adore 2013.0 \n\n genres countries \\\n0 мультфильм, фэнтези, комедии США \n1 фантастика, мультфильм, приключения, комедии США \n2 мультфильм, приключения, фантастика, фэнтези, ... США, Франция, Япония \n3 мультфильм, приключения, фантастика, семейное,... США \n4 спорт, мультфильм, комедии США \n5 боевики, драмы, фантастика, триллеры США \n6 боевики, фантастика, триллеры, приключения США, Мексика \n7 боевики, ужасы, фантастика, триллеры США \n8 боевики, фантастика, приключения США, Китай \n9 боевики, фантастика, триллеры, приключения США \n10 мелодрамы Канада \n11 драмы, мелодрамы Франция \n12 историческое, мелодрамы Франция \n13 драмы, мелодрамы Франция \n14 драмы, мелодрамы Австралия, Франция \n\n for_kids age_rating studios directors \\\n0 NaN 6.0 NaN Джош Кули \n1 NaN 6.0 NaN Кайл Балда, Пьер Коффан \n2 NaN 0.0 NaN Пьер Коффан, Крис Рено \n3 NaN 6.0 NaN Рич Мур, Фил Джонстон \n4 NaN 6.0 NaN Джон Лассетер, Джо Рэнфт \n5 NaN 16.0 NaN Бен Макферсон \n6 NaN 16.0 NaN Джон МакТирнан \n7 NaN 18.0 NaN Тони Гиглио \n8 NaN 16.0 NaN Тим Миллер \n9 NaN 16.0 NaN Нимрод Антал \n10 NaN 18.0 NaN Шон Гэррити \n11 NaN 18.0 NaN Гаспар Ноэ \n12 NaN 18.0 NaN Лу Жене \n13 NaN 18.0 NaN Эмманюэль Берко \n14 NaN 16.0 NaN Анн Фонтен \n\n actors \\\n0 [том хэнкс, тим аллен, энни поттс, тони хейл, ... \n1 [сандра буллок, джон хэмм, майкл китон, эллисо... \n2 [стив карелл, кристен уиг, бенджамин брэтт, ми... \n3 [джон си райли, сара силверман, галь гадот, та... \n4 [оуэн уилсон, пол ньюман, бонни хант, ларри-ка... \n5 [брайтон шарбино, доминик монахэн, уилл пэттон... \n6 [арнольд шварценеггер, карл уэзерс, эльпидия к... \n7 [эми мэнсон, доминик мафэм, люк аллен-гейл, дж... \n8 [линда хэмилтон, арнольд шварценеггер, маккенз... \n9 [эдриан броуди, тофер грейс, алиси брага, уолт... \n10 [джонас черник, эмили хэмпшир, сара мэннинен, ... \n11 [аоми муйок, карл глусман, клара кристин, уго ... \n12 [ноэми мерлан, нильс шнайдер, бенжамен лаверн,... \n13 [дебора франсуа, ален коши, матье деми, бенжам... \n14 [наоми уоттс, робин райт, завьер сэмюэл, джейм... \n\n description \\\n0 Космический рейнджер Баз Лайтер, ковбой Вуди, ... \n1 Миньоны живут на планете гораздо дольше нас. У... \n2 В то время как Грю, бывший суперзлодей, приспо... \n3 На этот раз Ральф и Ванилопа фон Кекс выйдут з... \n4 Неукротимый в своем желании всегда и во всем п... \n5 Риз с легкостью проходит виртуальные квесты, н... \n6 Американский вертолет был сбит партизанами в Ю... \n7 Отряд морпехов прилетает на марсианский спутни... \n8 Мексика. Милая девушка Даниэла Рамос, а для др... \n9 Наемник Ройс невольно вынужден возглавить груп... \n10 Чтобы вернуть свою неудовлетворенную бывшую де... \n11 Любовь вне добра и зла. Любовь — это генетичес... \n12 Историческая драма про любовный треугольник, к... \n13 Лаура — 19-летняя первокурсница французского у... \n14 Главные героини картины – Лил и Роз — две давн... \n\n keywords \\\n0 [игрушка, дружба, ковбой, история игрушек 4, ,... \n1 [помощник, сцена после титров, сцена во время ... \n2 [отношения родитель-ребенок, секретный агент, ... \n3 [видеоигра, мультфильм, продолжение, интернет,... \n4 [автомобильная гонка, трасса 66, porsche, выхо... \n5 [2019, соединенные штаты, радиовспышка] \n6 [центральная и южная америка, хищник, иноплане... \n7 [планета марс, ад, космос, демон, по мотивам в... \n8 [искуственный интеллект, киборг, вертолет, мех... \n9 [охотник, хищник, якудза, охота на людей, иноп... \n10 [нижнее белье, массажистка, секс втроем, фалло... \n11 [париж, франция, секс, сексуальность, галерея,... \n12 [, 1890-е, большой пенис, брак без секса, вдох... \n13 [франция, гостиница, по роману или книге, гост... \n14 [пляж, нагота, любовники, месть, лучший друг, ... \n\n genre \n0 [мультфильм, фэнтези, комедии] \n1 [фантастика, мультфильм, приключения, комедии] \n2 [мультфильм, приключения, фантастика, фэнтези,... \n3 [мультфильм, приключения, фантастика, семейное... \n4 [спорт, мультфильм, комедии] \n5 [боевики, драмы, фантастика, триллеры] \n6 [боевики, фантастика, триллеры, приключения] \n7 [боевики, ужасы, фантастика, триллеры] \n8 [боевики, фантастика, приключения] \n9 [боевики, фантастика, триллеры, приключения] \n10 [мелодрамы] \n11 [драмы, мелодрамы] \n12 [историческое, мелодрамы] \n13 [драмы, мелодрамы] \n14 [драмы, мелодрамы] ", + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idscorerankcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywordsgenre
011111111119850.0407001filmИстория игрушек 4Toy Story 42019.0мультфильм, фэнтези, комедииСШАNaN6.0NaNДжош Кули[том хэнкс, тим аллен, энни поттс, тони хейл, ...Космический рейнджер Баз Лайтер, ковбой Вуди, ...[игрушка, дружба, ковбой, история игрушек 4, ,...[мультфильм, фэнтези, комедии]
11111111129540.0394662filmМиньоныMinions2015.0фантастика, мультфильм, приключения, комедииСШАNaN6.0NaNКайл Балда, Пьер Коффан[сандра буллок, джон хэмм, майкл китон, эллисо...Миньоны живут на планете гораздо дольше нас. У...[помощник, сцена после титров, сцена во время ...[фантастика, мультфильм, приключения, комедии]
21111111173100.0365913filmГадкий я 2Despicable Me 22013.0мультфильм, приключения, фантастика, фэнтези, ...США, Франция, ЯпонияNaN0.0NaNПьер Коффан, Крис Рено[стив карелл, кристен уиг, бенджамин брэтт, ми...В то время как Грю, бывший суперзлодей, приспо...[отношения родитель-ребенок, секретный агент, ...[мультфильм, приключения, фантастика, фэнтези,...
31111111131820.0354234filmРальф против ИнтернетаRalph Breaks the Internet2018.0мультфильм, приключения, фантастика, семейное,...СШАNaN6.0NaNРич Мур, Фил Джонстон[джон си райли, сара силверман, галь гадот, та...На этот раз Ральф и Ванилопа фон Кекс выйдут з...[видеоигра, мультфильм, продолжение, интернет,...[мультфильм, приключения, фантастика, семейное...
41111111144750.0344225filmТачкиCars2006.0спорт, мультфильм, комедииСШАNaN6.0NaNДжон Лассетер, Джо Рэнфт[оуэн уилсон, пол ньюман, бонни хант, ларри-ка...Неукротимый в своем желании всегда и во всем п...[автомобильная гонка, трасса 66, porsche, выхо...[спорт, мультфильм, комедии]
51111111277930.0356391filmРадиовспышкаRadioflash2019.0боевики, драмы, фантастика, триллерыСШАNaN16.0NaNБен Макферсон[брайтон шарбино, доминик монахэн, уилл пэттон...Риз с легкостью проходит виртуальные квесты, н...[2019, соединенные штаты, радиовспышка][боевики, драмы, фантастика, триллеры]
61111111247020.0351392filmХищникPredator1987.0боевики, фантастика, триллеры, приключенияСША, МексикаNaN16.0NaNДжон МакТирнан[арнольд шварценеггер, карл уэзерс, эльпидия к...Американский вертолет был сбит партизанами в Ю...[центральная и южная америка, хищник, иноплане...[боевики, фантастика, триллеры, приключения]
711111112163610.0348573filmDoom: АннигиляцияDoom: Annihilation2019.0боевики, ужасы, фантастика, триллерыСШАNaN18.0NaNТони Гиглио[эми мэнсон, доминик мафэм, люк аллен-гейл, дж...Отряд морпехов прилетает на марсианский спутни...[планета марс, ад, космос, демон, по мотивам в...[боевики, ужасы, фантастика, триллеры]
81111111212870.0343274filmТерминатор: Тёмные судьбыTerminator: Dark Fate2019.0боевики, фантастика, приключенияСША, КитайNaN16.0NaNТим Миллер[линда хэмилтон, арнольд шварценеггер, маккенз...Мексика. Милая девушка Даниэла Рамос, а для др...[искуственный интеллект, киборг, вертолет, мех...[боевики, фантастика, приключения]
911111112110180.0323495filmХищникиPredators2010.0боевики, фантастика, триллеры, приключенияСШАNaN16.0NaNНимрод Антал[эдриан броуди, тофер грейс, алиси брага, уолт...Наемник Ройс невольно вынужден возглавить груп...[охотник, хищник, якудза, охота на людей, иноп...[боевики, фантастика, триллеры, приключения]
101111111319160.2456551filmСекс и ничего лишнегоMy Awkward Sexual Adventure2012.0мелодрамыКанадаNaN18.0NaNШон Гэррити[джонас черник, эмили хэмпшир, сара мэннинен, ...Чтобы вернуть свою неудовлетворенную бывшую де...[нижнее белье, массажистка, секс втроем, фалло...[мелодрамы]
1111111113144700.2427862filmЛюбовьLove2015.0драмы, мелодрамыФранцияNaN18.0NaNГаспар Ноэ[аоми муйок, карл глусман, клара кристин, уго ...Любовь вне добра и зла. Любовь — это генетичес...[париж, франция, секс, сексуальность, галерея,...[драмы, мелодрамы]
12111111131010.2192313filmКуриосаCuriosa2019.0историческое, мелодрамыФранцияNaN18.0NaNЛу Жене[ноэми мерлан, нильс шнайдер, бенжамен лаверн,...Историческая драма про любовный треугольник, к...[, 1890-е, большой пенис, брак без секса, вдох...[историческое, мелодрамы]
1311111113124630.2066154filmСтудентка по вызовуMes chères études2010.0драмы, мелодрамыФранцияNaN18.0NaNЭмманюэль Берко[дебора франсуа, ален коши, матье деми, бенжам...Лаура — 19-летняя первокурсница французского у...[франция, гостиница, по роману или книге, гост...[драмы, мелодрамы]
141111111357320.1830125filmТайное влечениеAdore2013.0драмы, мелодрамыАвстралия, ФранцияNaN16.0NaNАнн Фонтен[наоми уоттс, робин райт, завьер сэмюэл, джейм...Главные героини картины – Лил и Роз — две давн...[пляж, нагота, любовники, месть, лучший друг, ...[драмы, мелодрамы]
\n
" }, - "execution_count": 84, + "execution_count": 269, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "if study.best_params['recomender'] == 'LightFM':\n", - " # Создание инстанса модели\n", - " model = LightFMWrapperModel(\n", - " LightFM(\n", - " k=study.best_params['k'],\n", - " learning_rate=study.best_params['learning_rate'],\n", - " loss=study.best_params['loss'],\n", - " no_components=study.best_params['no_components']\n", - " ),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS\n", - " )\n", - "else:\n", - " # Создание инстанса модели\n", - " model = ImplicitALSWrapperModel(\n", - " model=AlternatingLeastSquares(\n", - " factors=study.best_params['factors'],\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=study.best_params['regularization']\n", - " ),\n", - " fit_features_together=True\n", - " )\n", - "# Обучение модели и предикт для подсчета метрик\n", - "model.fit(dataset)\n", + "recos_with_avatars.merge(items, on='item_id', how='left')" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "markdown", + "source": [ + "В целом, все рекомендации к каждому аватару получились неплохие" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "markdown", + "id": "ab12c89f", + "metadata": {}, + "source": [ + " # Метод приближенного поиска соседей для выдачи рекомендаций.\n", "\n", - "recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True\n", - ")\n", - "metric = calc_metrics(metrics, recos, test, train)\n", - "metric" + "Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", + "Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д" ] }, { - "cell_type": "markdown", - "id": "43411998", + "cell_type": "code", + "execution_count": 67, + "id": "5d1161b4", "metadata": {}, + "outputs": [], "source": [ - " ## Метод приближенного поиска соседей." + "LEARNING_RATE = 0.08165160206425184\n", + "LOSS = 'warp'" ] }, { "cell_type": "code", - "execution_count": 85, - "id": "e0dfa8e8", + "execution_count": 68, + "id": "9f20ae6e", "metadata": {}, "outputs": [], "source": [ - "user_embeddings, item_embeddings = model.get_vectors(dataset)" + "# обучаем LightFM, чтобы достать из нее вектора пользователей и айтемов\n", + "model = LightFMWrapperModel(\n", + " LightFM(\n", + " k=K,\n", + " no_components=NO_COMPONENTS,\n", + " loss= LOSS,\n", + " random_state=RANDOM_STATE,\n", + " learning_rate=LEARNING_RATE,\n", + " user_alpha=USER_ALPHA,\n", + " item_alpha=ITEM_ALPHA\n", + " ),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS\n", + ")" ] }, { "cell_type": "code", - "execution_count": 86, - "id": "91a20b08", + "execution_count": 69, + "id": "9982d55c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "((756545, 59), (13963, 59))" + "" ] }, - "execution_count": 86, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "user_embeddings.shape, item_embeddings.shape" + "model.fit(dataset)" ] }, { "cell_type": "code", - "execution_count": 87, - "id": "3634fd78", + "execution_count": 72, + "id": "348b4fd6", "metadata": {}, "outputs": [], "source": [ - "def augment_inner_product(factors):\n", - " normed_factors = np.linalg.norm(factors, axis=1)\n", - " max_norm = normed_factors.max()\n", - "\n", - " extra_dim = np.sqrt(max_norm ** 2 - normed_factors ** 2).reshape(-1, 1)\n", - " augmented_factors = np.append(factors, extra_dim, axis=1)\n", - " return max_norm, augmented_factors" + "user_embeddings, item_embeddings = model.get_vectors(dataset)" ] }, { "cell_type": "code", - "execution_count": 88, - "id": "c2668a0d", + "execution_count": 73, + "id": "fd296cf4", "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "pre shape: (13963, 59)\n" - ] - }, { "data": { "text/plain": [ - "(13963, 60)" + "((756545, 34), (13963, 34))" ] }, - "execution_count": 88, + "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "print('pre shape: ', item_embeddings.shape)\n", - "max_norm, augmented_item_embeddings = augment_inner_product(item_embeddings)\n", - "augmented_item_embeddings.shape" + "user_embeddings.shape, item_embeddings.shape" ] }, { "cell_type": "code", - "execution_count": 89, - "id": "16fb4a95", + "execution_count": 74, + "id": "d75b4570", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(756545, 60)" + "array([-2.48910075e+02, 1.00000000e+00, -3.04745167e-01, 1.30259299e-01,\n", + " -1.25937782e-01, 1.32810516e-01, -3.98682870e-01, 2.12211904e-01,\n", + " 3.15063161e-01, 9.48599975e-03, 1.79876286e-01, -1.15210674e-01,\n", + " 3.13044085e-01, 5.25500635e-02, -8.94866249e-02, 6.32450803e-02,\n", + " 3.30464664e-01, -2.79290127e-01, 7.66675368e-02, 2.69704125e-01,\n", + " -2.02872234e-01, 3.65543869e-02, -2.08750917e-01, -7.48397237e-02,\n", + " 2.09714412e-01, 1.28161004e-01, -2.49842146e-01, 7.57336145e-02,\n", + " 6.74582969e-02, 2.03054725e-01, -4.46441335e-02, 1.00222239e-01,\n", + " 3.09746759e-01, 2.26963989e-01])" ] }, - "execution_count": 89, + "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "extra_zero = np.zeros((user_embeddings.shape[0], 1))\n", - "augmented_user_embeddings = np.append(user_embeddings, extra_zero, axis=1)\n", - "augmented_user_embeddings.shape" + "#пользователь со средним значением по каждому признаку\n", + "first_person = user_embeddings.mean(0)\n", + "first_person" ] }, { "cell_type": "code", - "execution_count": 90, - "id": "8d3d96d3", + "execution_count": 75, + "id": "88198015", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([-3.68946387e+03, 1.00000000e+00, 5.00279766e+04, 8.85783906e+04,\n", - " -1.05108094e+05, -3.06310918e+04, 1.96517285e+04, 6.73730078e+04,\n", - " 2.04599453e+05, 6.12343242e+04, 6.41995352e+04, -5.77218633e+04,\n", - " -7.05726250e+04, -1.61670656e+05, -5.52132148e+04, -1.30570914e+05,\n", - " -7.23810078e+04, 2.07963969e+05, 1.65819863e+04, -9.76921953e+04,\n", - " -3.12005684e+04, -7.85079531e+04, 5.45297734e+04, 1.34828297e+05,\n", - " 1.17192398e+05, 7.57457812e+04, -1.89341052e+03, 1.23631297e+05,\n", - " -1.10485789e+05, 2.78173301e+04, 1.66516035e+04, -6.22929336e+04,\n", - " 9.86834219e+04, -1.32930908e+04, 3.14460527e+04, 6.04318125e+04,\n", - " -8.20018047e+04, 6.20642812e+04, 4.66973711e+04, -1.44485000e+05,\n", - " 1.34138750e+05, 1.11652305e+05, -1.54659141e+05, -1.48082953e+05,\n", - " 3.26356621e+04, -2.69916387e+04, -1.60023016e+05, -7.10024922e+04,\n", - " -4.93529492e+04, -3.54507500e+04, 8.54245703e+04, -2.75770918e+04,\n", - " -1.25765594e+05, -1.01873039e+05, -3.04939473e+04, 9.42476641e+04,\n", - " 2.47347930e+04, 1.37679953e+05, 5.63563555e+04])" + "array([-364.41271973, 1. , -2.19337273, -2.05960441,\n", + " -3.03305483, -2.15237951, -3.10027146, -1.44008625,\n", + " -1.55592728, -1.69499218, -1.87335801, -3.19125104,\n", + " -1.8664068 , -2.62357092, -2.23808742, -1.78050435,\n", + " -1.67308342, -2.70261121, -1.94637215, -2.44766903,\n", + " -2.40233946, -1.93648934, -2.32535124, -2.73280096,\n", + " -2.20278382, -1.93085539, -2.29366779, -1.9847883 ,\n", + " -2.619452 , -1.8447926 , -2.03915739, -1.86472845,\n", + " -1.80441463, -1.98137343])" ] }, - "execution_count": 90, + "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "user_id = 30\n", - "user_embeddings[user_id]" + "#пользователь со минимальным значением по каждому признаку\n", + "second_person = user_embeddings.min(axis=0)\n", + "second_person" ] }, { "cell_type": "code", - "execution_count": 91, - "id": "a3abdc5a", + "execution_count": 76, + "id": "4e02dec3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([-3.68946387e+03, 1.00000000e+00, 5.00279766e+04, 8.85783906e+04,\n", - " -1.05108094e+05, -3.06310918e+04, 1.96517285e+04, 6.73730078e+04,\n", - " 2.04599453e+05, 6.12343242e+04, 6.41995352e+04, -5.77218633e+04,\n", - " -7.05726250e+04, -1.61670656e+05, -5.52132148e+04, -1.30570914e+05,\n", - " -7.23810078e+04, 2.07963969e+05, 1.65819863e+04, -9.76921953e+04,\n", - " -3.12005684e+04, -7.85079531e+04, 5.45297734e+04, 1.34828297e+05,\n", - " 1.17192398e+05, 7.57457812e+04, -1.89341052e+03, 1.23631297e+05,\n", - " -1.10485789e+05, 2.78173301e+04, 1.66516035e+04, -6.22929336e+04,\n", - " 9.86834219e+04, -1.32930908e+04, 3.14460527e+04, 6.04318125e+04,\n", - " -8.20018047e+04, 6.20642812e+04, 4.66973711e+04, -1.44485000e+05,\n", - " 1.34138750e+05, 1.11652305e+05, -1.54659141e+05, -1.48082953e+05,\n", - " 3.26356621e+04, -2.69916387e+04, -1.60023016e+05, -7.10024922e+04,\n", - " -4.93529492e+04, -3.54507500e+04, 8.54245703e+04, -2.75770918e+04,\n", - " -1.25765594e+05, -1.01873039e+05, -3.04939473e+04, 9.42476641e+04,\n", - " 2.47347930e+04, 1.37679953e+05, 5.63563555e+04, 0.00000000e+00])" + "array([0. , 1. , 1.80414879, 2.91568851, 2.57092023,\n", + " 2.49563074, 3.0165813 , 2.02071786, 2.10402703, 1.86775827,\n", + " 1.81193578, 2.3456769 , 2.37611055, 4.0926795 , 1.8776809 ,\n", + " 1.91333187, 2.16625547, 1.76979506, 1.87265527, 2.63360167,\n", + " 1.97114313, 1.88249838, 1.89424872, 2.15507913, 2.38049865,\n", + " 1.99921763, 1.80478072, 1.8311218 , 3.32906055, 2.25318193,\n", + " 2.0245254 , 2.37490654, 2.28989363, 1.97282732])" ] }, - "execution_count": 91, + "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "augmented_user_embeddings[user_id]" + "#пользователь со максимальным значением по каждому признаку\n", + "third_person = user_embeddings.max(axis=0)\n", + "third_person" ] }, { "cell_type": "code", - "execution_count": 92, - "id": "b4d804fe", + "execution_count": 77, + "id": "75a314ac", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([ 1.00000000e+00, 3.71805847e+02, 3.05234741e+03, 1.01628503e+03,\n", - " -2.01937231e+03, -7.06286914e+03, 2.08036670e+03, 1.44198691e+04,\n", - " 1.04459076e+02, 2.91055640e+03, 4.90286133e+03, -8.00846631e+03,\n", - " -3.74290078e+04, -5.34835303e+03, -5.73522314e+03, -1.32270422e+03,\n", - " -4.57180566e+03, 5.20245544e+02, 2.12270190e+03, -2.74671069e+03,\n", - " -3.97734521e+03, -5.76298193e+03, -9.74685645e+03, 1.00388757e+03,\n", - " 1.41514294e+03, 2.31493750e+04, 8.51632129e+03, 9.64525818e+02,\n", - " -1.17795410e+04, 5.20026611e+03, -1.86291174e+03, -3.32180225e+03,\n", - " 2.35795312e+03, -2.74500562e+03, 7.57092236e+03, 8.45529199e+03,\n", - " -4.04447168e+03, 3.18093457e+03, 1.06870723e+04, -1.86842322e+03,\n", - " 1.92173401e+03, 2.00068164e+03, -2.32481689e+03, -1.20484082e+03,\n", - " 8.42075134e+02, -2.14867944e+03, -8.79860291e+02, -7.14862646e+03,\n", - " -2.94369702e+03, -2.65627759e+03, 1.50566143e+04, -2.40812646e+03,\n", - " -8.63793823e+02, -1.57019958e+03, -2.04618115e+03, 1.11798945e+04,\n", - " 1.65814307e+03, 6.58971863e+02, 7.54287207e+03])" + "(756545, 34)" ] }, - "execution_count": 92, + "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "item_id = 0\n", - "item_embeddings[item_id]" + "user_embeddings.shape" ] }, { "cell_type": "code", - "execution_count": 93, - "id": "2e0030f1", + "execution_count": 78, + "id": "3cb72431", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([ 1.00000000e+00, 3.71805847e+02, 3.05234741e+03, 1.01628503e+03,\n", - " -2.01937231e+03, -7.06286914e+03, 2.08036670e+03, 1.44198691e+04,\n", - " 1.04459076e+02, 2.91055640e+03, 4.90286133e+03, -8.00846631e+03,\n", - " -3.74290078e+04, -5.34835303e+03, -5.73522314e+03, -1.32270422e+03,\n", - " -4.57180566e+03, 5.20245544e+02, 2.12270190e+03, -2.74671069e+03,\n", - " -3.97734521e+03, -5.76298193e+03, -9.74685645e+03, 1.00388757e+03,\n", - " 1.41514294e+03, 2.31493750e+04, 8.51632129e+03, 9.64525818e+02,\n", - " -1.17795410e+04, 5.20026611e+03, -1.86291174e+03, -3.32180225e+03,\n", - " 2.35795312e+03, -2.74500562e+03, 7.57092236e+03, 8.45529199e+03,\n", - " -4.04447168e+03, 3.18093457e+03, 1.06870723e+04, -1.86842322e+03,\n", - " 1.92173401e+03, 2.00068164e+03, -2.32481689e+03, -1.20484082e+03,\n", - " 8.42075134e+02, -2.14867944e+03, -8.79860291e+02, -7.14862646e+03,\n", - " -2.94369702e+03, -2.65627759e+03, 1.50566143e+04, -2.40812646e+03,\n", - " -8.63793823e+02, -1.57019958e+03, -2.04618115e+03, 1.11798945e+04,\n", - " 1.65814307e+03, 6.58971863e+02, 7.54287207e+03, 3.94554062e+09])" + "(756548, 34)" ] }, - "execution_count": 93, + "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "augmented_item_embeddings[item_id]" + "# добавим векотра 3х новых пользователей\n", + "user_embeddings = np.append(user_embeddings, np.array([first_person,\n", + " second_person, third_person]), axis=0)\n", + "user_embeddings.shape\n" ] }, { "cell_type": "code", - "execution_count": 94, - "id": "19104d9a", + "execution_count": 79, + "id": "db53d401", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Index-time parameters {'M': 48, 'indexThreadQty': 4, 'efConstruction': 100, 'post': 0}\n" + "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150, 'post': 0, 'chunkIndexSize': 10000}\n" ] } ], "source": [ - "M = 48\n", - "efC = 100\n", + "M = 50\n", + "efC = 150\n", + "\n", + "num_threads = 8\n", + "chunkIndexSize = 10000\n", "\n", - "num_threads = 4\n", - "index_time_params = {'M': M, 'indexThreadQty': num_threads, 'efConstruction': efC, 'post' : 0}\n", - "print('Index-time parameters', index_time_params)" + "index_time_params = {\n", + " 'M': M,\n", + " 'indexThreadQty': num_threads,\n", + " 'efConstruction': efC,\n", + " 'post': 0,\n", + " 'chunkIndexSize': chunkIndexSize,\n", + " }\n", + "print ('Index-time parameters', index_time_params)" ] }, { "cell_type": "code", - "execution_count": 95, - "id": "3634ebbb", + "execution_count": 80, + "id": "e09782e5", "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'nmslib' is not defined", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)", - "Cell \u001B[0;32mIn[95], line 3\u001B[0m\n\u001B[1;32m 1\u001B[0m K\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m10\u001B[39m\n\u001B[1;32m 2\u001B[0m space_name\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mnegdotprod\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[0;32m----> 3\u001B[0m index \u001B[38;5;241m=\u001B[39m \u001B[43mnmslib\u001B[49m\u001B[38;5;241m.\u001B[39minit(method\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mhnsw\u001B[39m\u001B[38;5;124m'\u001B[39m, space\u001B[38;5;241m=\u001B[39mspace_name, data_type\u001B[38;5;241m=\u001B[39mnmslib\u001B[38;5;241m.\u001B[39mDataType\u001B[38;5;241m.\u001B[39mDENSE_VECTOR)\n\u001B[1;32m 4\u001B[0m index\u001B[38;5;241m.\u001B[39maddDataPointBatch(augmented_item_embeddings)\n", - "\u001B[0;31mNameError\u001B[0m: name 'nmslib' is not defined" - ] + "data": { + "text/plain": [ + "13963" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "K=10\n", - "space_name='negdotprod'\n", - "index = nmslib.init(method='hnsw', space=space_name, data_type=nmslib.DataType.DENSE_VECTOR)\n", - "index.addDataPointBatch(augmented_item_embeddings)" + "K = 10\n", + "space_name = 'negdotprod'\n", + "index = nmslib.init(method='hnsw', space=space_name,\n", + " data_type=nmslib.DataType.DENSE_VECTOR)\n", + "index.addDataPointBatch(item_embeddings)" ] }, { "cell_type": "code", - "execution_count": 79, - "id": "6d423d8d", + "execution_count": 81, + "id": "209d778e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Index-time parameters {'M': 48, 'indexThreadQty': 4, 'efConstruction': 100}\n", - "Indexing time = 0.282692\n" + "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150}\n", + "Indexing time = 1.392440\n" ] } ], "source": [ "start = time.time()\n", - "index_time_params = {'M': M, 'indexThreadQty': num_threads, 'efConstruction': efC}\n", + "index_time_params = {'M': M, 'indexThreadQty': num_threads,\n", + " 'efConstruction': efC}\n", "index.createIndex(index_time_params)\n", "end = time.time()\n", "print('Index-time parameters', index_time_params)\n", - "print('Indexing time = %f' % (end-start))" + "print('Indexing time = %f' % (end - start))" ] }, { "cell_type": "code", - "execution_count": 80, - "id": "9dc1529f", + "execution_count": 82, + "id": "998dad8b", "metadata": {}, "outputs": [ { @@ -3541,343 +2140,247 @@ }, { "cell_type": "code", - "execution_count": 81, - "id": "0fff67a2", + "execution_count": 83, + "id": "6f5cd03c", "metadata": {}, "outputs": [], "source": [ - "query_matrix = augmented_user_embeddings[:1000, :]" + "query_matrix = user_embeddings" ] }, { "cell_type": "code", - "execution_count": 82, - "id": "1cdffc65", + "execution_count": 84, + "id": "77039943", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "kNN time total=0.023291 (sec), per query=0.000023 (sec), per query adjusted for thread number=0.000093 (sec)\n" + "kNN time total=3.962551 (sec), per query=0.000005 (sec), per query adjusted for thread number=0.000042 (sec)\n" ] } ], "source": [ "query_qty = query_matrix.shape[0]\n", "start = time.time()\n", - "nbrs = index.knnQueryBatch(query_matrix, k = K, num_threads = num_threads)\n", + "nbrs = index.knnQueryBatch(query_matrix, k=K, num_threads=num_threads)\n", "end = time.time()\n", "print(\n", - " 'kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' %\n", - " (end-start, float(end-start)/query_qty, num_threads*float(end-start)/query_qty)\n", + " 'kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' \\\n", + " % (end - start, float(end - start) / query_qty, num_threads * float(end - start) / query_qty)\n", ")" ] }, { "cell_type": "code", - "execution_count": 83, - "id": "d94de743", + "execution_count": 86, + "id": "cac18e0e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(array([ 43, 32, 19, 62, 31, 112, 305, 188, 268, 948], dtype=int32),\n", - " array([304.80273, 304.95447, 305.16202, 305.32443, 305.47067, 305.5135 ,\n", - " 305.6464 , 305.6903 , 305.73453, 305.78738], dtype=float32))" + "array([[ 32, 19, 43, ..., 31, 36, 69],\n", + " [ 31, 262, 62, ..., 32, 121, 735],\n", + " [ 19, 31, 121, ..., 29, 62, 105],\n", + " ...,\n", + " [ 31, 19, 43, ..., 268, 100, 86],\n", + " [ 19, 31, 32, ..., 268, 49, 173],\n", + " [ 19, 31, 32, ..., 100, 105, 268]])" ] }, - "execution_count": 83, + "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "nbrs[0]" + "# рекомендации для всех пользователей\n", + "recos_old_persons = np.array(nbrs, dtype=int)[:,0][:len(nbrs) - 3]\n", + "recos_old_persons" ] }, { "cell_type": "code", "execution_count": 87, - "id": "5be5c93c", - "metadata": {}, - "outputs": [], - "source": [ - "def recommend_all(query_factors, index_factors, topn=10):\n", - " output = query_factors.dot(index_factors.T)\n", - " argpartition_indices = np.argpartition(output, -topn)[:, -topn:]\n", - "\n", - " x_indices = np.repeat(np.arange(output.shape[0]), topn)\n", - " y_indices = argpartition_indices.flatten()\n", - " top_value = output[x_indices, y_indices].reshape(output.shape[0], topn)\n", - " top_indices = np.argsort(top_value)[:, ::-1]\n", - "\n", - " y_indices = top_indices.flatten()\n", - " top_indices = argpartition_indices[x_indices, y_indices]\n", - " labels = top_indices.reshape(-1, topn)\n", - " distances = output[x_indices, top_indices].reshape(-1, topn)\n", - " return labels, distances\n" - ] - }, - { - "cell_type": "code", - "execution_count": 108, - "id": "e9988091", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 19, 31, 121, 32, 43, 268, 120, 62, 103, 173]])" - ] - }, - "execution_count": 108, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "labels,_ = recommend_all(user_embeddings[[], :], item_embeddings)\n", - "labels" - ] - }, - { - "cell_type": "code", - "execution_count": 112, - "id": "3c722149", + "id": "918c6976", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([], shape=(0, 34), dtype=float64)" + "array([[ 31, 19, 32, 43, 62, 121, 173, 268, 100,\n", + " 86],\n", + " [12018, 10998, 7308, 12006, 10159, 10215, 3543, 8118, 8180,\n", + " 11511],\n", + " [ 8453, 6400, 3557, 3945, 6642, 4779, 3583, 2068, 8668,\n", + " 371]])" ] }, - "execution_count": 112, + "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "user_embeddings[[], :]" + "# рекомендации для добавленных пользователей\n", + "recos_new_persons = np.array(nbrs, dtype=int)[:,0][-3:]\n", + "recos_new_persons" ] }, { "cell_type": "code", - "execution_count": 113, - "id": "d300a815", + "execution_count": 88, + "id": "c78fbc6a", "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_id
0032
1019
2043
3062
40449
.........
756544575654443
756544675654429
7565447756544100
7565448756544105
7565449756544268
\n", + "

7565450 rows × 2 columns

\n", + "
" + ], "text/plain": [ - "array([[-3.24551971e+02, 1.00000000e+00, 8.73963833e-02, ...,\n", - " -1.30321786e-01, 1.82629615e-01, -3.07083875e-01],\n", - " [-3.24792297e+02, 1.00000000e+00, 3.87268960e-01, ...,\n", - " -4.32303697e-02, -4.72983688e-01, -1.79986209e-01],\n", - " [-3.01102661e+02, 1.00000000e+00, -1.63965374e-01, ...,\n", - " -1.01540364e-01, 1.10484377e-01, -2.40944147e-01],\n", - " ...,\n", - " [-3.58453766e+02, 1.00000000e+00, -1.08767882e-01, ...,\n", - " 2.43232936e-01, -1.24036551e-01, -4.88389194e-01],\n", - " [-2.99490662e+02, 1.00000000e+00, -3.04439873e-01, ...,\n", - " -2.42081508e-02, -3.93126070e-01, -2.91359007e-01],\n", - " [-3.10774689e+02, 1.00000000e+00, -2.57401466e-01, ...,\n", - " -3.03505287e-02, -4.26894128e-01, -3.11958164e-01]])" + " user_id item_id\n", + "0 0 32\n", + "1 0 19\n", + "2 0 43\n", + "3 0 62\n", + "4 0 449\n", + "... ... ...\n", + "7565445 756544 43\n", + "7565446 756544 29\n", + "7565447 756544 100\n", + "7565448 756544 105\n", + "7565449 756544 268\n", + "\n", + "[7565450 rows x 2 columns]" ] }, - "execution_count": 113, + "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "user_embeddings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "15d49fe7", - "metadata": {}, - "outputs": [], - "source": [ - "labels" + "df_r = \\\n", + " pd.DataFrame({'user_id': np.repeat(np.arange(len(recos_old_persons)),\n", + " 10), Columns.Item: recos_old_persons.ravel()})\n", + "df_r\n" ] }, { "cell_type": "code", "execution_count": 89, - "id": "d6c68dd7", + "id": "902cbca6", "metadata": {}, "outputs": [], "source": [ - "query_matrix_not_augmented = user_embeddings[:1000, :]" - ] - }, - { - "cell_type": "code", - "execution_count": 105, - "id": "b7d9dd1f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "207 ms ± 6.37 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "labels,_ = recommend_all(query_matrix_not_augmented, item_embeddings)\n", - "print(labels)" - ] - }, - { - "cell_type": "code", - "execution_count": 92, - "id": "904846a6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((1000, 34), (756545, 34))" - ] - }, - "execution_count": 92, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "item_embeddings[:1000, :].shape, user_embeddings.shape" + "df_r.to_csv('nmslib.csv.gz', index=False, compression='gzip')\n" ] }, { - "cell_type": "code", - "execution_count": 93, - "id": "d6027ae4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "7.88 ms ± 368 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" - ] - } - ], + "cell_type": "markdown", "source": [ - "%%timeit\n", - "index.knnQueryBatch(query_matrix, k = K, num_threads = num_threads)" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "id": "e6b0be91", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[ 43 32 19 ... 188 268 948]\n", - " [ 31 19 62 ... 450 49 268]\n", - " [ 19 31 121 ... 62 103 173]\n", - " ...\n", - " [ 31 62 358 ... 8 884 43]\n", - " [ 43 19 32 ... 8 121 164]\n", - " [3117 5859 776 ... 43 62 1132]]\n", - "[[-304.80272148 -304.95450166 -305.1620535 ... -305.69031591\n", - " -305.73454442 -305.7874324 ]\n", - " [-311.19933349 -311.44323422 -311.45526998 ... -312.0948194\n", - " -312.21820321 -312.23901463]\n", - " [-284.3956498 -284.45770448 -284.96237912 ... -285.29546382\n", - " -285.36598349 -285.41208658]\n", - " ...\n", - " [-332.37278335 -332.85525963 -332.98405066 ... -333.36833688\n", - " -333.44008879 -333.48889785]\n", - " [-302.10402324 -302.13324433 -302.3124104 ... -302.86405908\n", - " -302.88296188 -303.00234271]\n", - " [ 14.88806505 14.41715752 14.1114468 ... 13.71272978\n", - " 13.68271151 13.6242354 ]]\n" - ] - } + "# Холодные пользователи\n", + "Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", + "\n", + "В предыдущей домашке, мы выяснили, что на этом датасете лучше всего себя ведет топ за последний месяц. Поэтому каждую модель мы использовали с подобным методом добивки холодных пользователей\n" ], - "source": [ - "labels, distances = recommend_all(user_embeddings[:1000, :], item_embeddings)\n", - "print(labels)\n", - "print(distances)" - ] + "metadata": { + "collapsed": false + } }, { "cell_type": "code", "execution_count": null, - "id": "77fedf20", - "metadata": {}, "outputs": [], - "source": [] + "source": [], + "metadata": { + "collapsed": false + } } ], "metadata": { @@ -3896,7 +2399,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.7" + "version": "3.8.8" } }, "nbformat": 4, diff --git "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" "b/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" deleted file mode 100644 index 3f4c842e..00000000 --- "a/notebooks/\320\224\320\276\320\274\320\260\321\210\320\275\320\265\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265 \342\204\2264.ipynb" +++ /dev/null @@ -1,2406 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "source": [ - "# Домашнее задание\n", - "\n", - "Домашнее задание состоит из нескольких блоков.\n", - "\n", - "\n", - "## Эксперименты в ipynb ноутбуках (15 баллов)\n", - "- Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", - " - Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)\n", - "- Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", - " - Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д\n", - "- Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**\n", - "- Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", - "\n", - "Примечание: за невоспроизводимый код в ноутбуках (например, нарушен порядок выполнения ячеек, вызываются переменные, которые нигде не были объявлены ранее и.т.п) будут штрафы на усмотрение проверяющего.\n", - "\n", - "\n", - "## Реализация итоговой модели в сервисе (10 баллов)\n", - "- Пробитие бейзлайна $MAP@10 \\geq 0.074921$ **(6 баллов)**\n", - "- Код сервиса соответствует критериям читаемости и воспроизводимости **(4 балла)**" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 1, - "outputs": [], - "source": [ - "import warnings\n", - "warnings.filterwarnings('ignore')" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 246, - "id": "e42a5585", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import time\n", - "import random\n", - "from pathlib import Path\n", - "\n", - "import numpy as np\n", - "import optuna\n", - "import pandas as pd\n", - "\n", - "import nmslib\n", - "from implicit.als import AlternatingLeastSquares\n", - "from lightfm import LightFM\n", - "from rectools import Columns\n", - "from rectools.dataset import Dataset\n", - "from rectools.metrics import MAP, Precision, Recall, calc_metrics\n", - "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel" - ] - }, - { - "cell_type": "code", - "execution_count": 180, - "id": "8cd36e1a", - "metadata": {}, - "outputs": [], - "source": [ - "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"" - ] - }, - { - "cell_type": "code", - "execution_count": 185, - "id": "4cb722c3", - "metadata": {}, - "outputs": [], - "source": [ - "DATA_PATH = Path(\"../data/kion_train/\")" - ] - }, - { - "cell_type": "code", - "execution_count": 186, - "id": "8195e56b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 2.61 s, sys: 924 ms, total: 3.53 s\n", - "Wall time: 5.74 s\n" - ] - } - ], - "source": [ - "%%time\n", - "users = pd.read_csv(DATA_PATH / 'users.csv')\n", - "items = pd.read_csv(DATA_PATH / 'items.csv')\n", - "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 187, - "id": "01c2bdef", - "metadata": {}, - "outputs": [], - "source": [ - "Columns.Datetime = 'last_watch_dt'" - ] - }, - { - "cell_type": "markdown", - "id": "00b5584e", - "metadata": {}, - "source": [ - "# Preprocess Interactions" - ] - }, - { - "cell_type": "code", - "execution_count": 188, - "id": "0a3b4b12", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id last_watch_dt total_dur watched_pct\n0 176549 9506 2021-05-11 4250 72.0\n1 699317 1659 2021-05-29 8317 100.0\n2 656683 7107 2021-05-09 10 0.0\n3 864613 7638 2021-07-05 14483 100.0\n4 964868 9506 2021-04-30 6725 100.0", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
\n
" - }, - "execution_count": 188, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 189, - "id": "260b1c48", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "user_id int64\nitem_id int64\nlast_watch_dt object\ntotal_dur int64\nwatched_pct float64\ndtype: object" - }, - "execution_count": 189, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions.dtypes" - ] - }, - { - "cell_type": "code", - "execution_count": 190, - "id": "fe2dbc06", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "user_id 0\nitem_id 0\nlast_watch_dt 0\ntotal_dur 0\nwatched_pct 828\ndtype: int64" - }, - "execution_count": 190, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions.isna().sum()" - ] - }, - { - "cell_type": "code", - "execution_count": 191, - "id": "71f61e81", - "metadata": {}, - "outputs": [], - "source": [ - "interactions[Columns.Datetime] = \\\n", - " pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')" - ] - }, - { - "cell_type": "code", - "execution_count": 192, - "id": "39646cb5", - "metadata": {}, - "outputs": [], - "source": [ - "interactions.dropna(inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 193, - "id": "f98ae95d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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\n" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "interactions['watched_pct'].hist(bins=20);" - ] - }, - { - "cell_type": "markdown", - "id": "1a0ad9f8", - "metadata": {}, - "source": [ - "Делю график просмотра на 5 категорий, где:\n", - "от 0% до 20% = 1,\n", - "от 21% до 40% = 2,\n", - "... ,\n", - "от 80% до 100% = 5" - ] - }, - { - "cell_type": "code", - "execution_count": 194, - "id": "1424e744", - "metadata": {}, - "outputs": [], - "source": [ - "interactions[Columns.Weight] = pd.cut(\n", - " x=interactions['watched_pct'],\n", - " bins=5,\n", - " labels=[1, 2, 3, 4, 5]\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 196, - "id": "052d2fb0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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\n" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "interactions[Columns.Datetime].hist(bins=20);" - ] - }, - { - "cell_type": "markdown", - "id": "5adb80ee", - "metadata": {}, - "source": [ - "Вообще, видно, что кол-во пользователей растет" - ] - }, - { - "cell_type": "code", - "execution_count": 197, - "id": "0fbd2bbc", - "metadata": {}, - "outputs": [], - "source": [ - "cold_users = \\\n", - " interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts() == 1].index" - ] - }, - { - "cell_type": "code", - "execution_count": 198, - "id": "150e1593", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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\n" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'\n", - " ].hist(bins=20);" - ] - }, - { - "cell_type": "markdown", - "id": "b5fa83eb", - "metadata": {}, - "source": [ - "Для холодных пользователей, я бы рекомендовал айтемы с самый высоким просмотром в среднем по холодным пользователям" - ] - }, - { - "cell_type": "code", - "execution_count": 199, - "id": "cca06e3f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n10 791466 8199 2021-07-27 713 9.0 1\n26 181144 10440 2021-08-08 27408 40.0 2\n37 161176 10440 2021-07-29 22 0.0 1\n38 21723 1819 2021-04-11 8535 100.0 5\n60 77216 8143 2021-05-08 660 11.0 1\n... ... ... ... ... ... ...\n5476222 1007900 9728 2021-08-12 416 6.0 1\n5476225 882138 4716 2021-05-21 1594 2.0 1\n5476238 805174 13125 2021-06-27 1 0.0 1\n5476246 648596 12225 2021-08-13 76 0.0 1\n5476248 697262 15297 2021-08-20 18307 63.0 4\n\n[355162 rows x 6 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n

355162 rows × 6 columns

\n
" - }, - "execution_count": 199, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users = interactions[interactions[Columns.User].isin(cold_users)]\n", - "hot_users = interactions[~interactions[Columns.User].isin(cold_users)]\n", - "cold_users" - ] - }, - { - "cell_type": "code", - "execution_count": 200, - "id": "a691676f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n0 176549 9506 2021-05-11 4250 72.0 4\n1 699317 1659 2021-05-29 8317 100.0 5\n2 656683 7107 2021-05-09 10 0.0 1\n3 864613 7638 2021-07-05 14483 100.0 5\n4 964868 9506 2021-04-30 6725 100.0 5\n... ... ... ... ... ... ...\n5476246 648596 12225 2021-08-13 76 0.0 1\n5476247 546862 9673 2021-04-13 2308 49.0 3\n5476248 697262 15297 2021-08-20 18307 63.0 4\n5476249 384202 16197 2021-04-19 6203 100.0 5\n5476250 319709 4436 2021-08-15 3921 45.0 3\n\n[5475423 rows x 6 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n

5475423 rows × 6 columns

\n
" - }, - "execution_count": 200, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hot_users" - ] - }, - { - "cell_type": "code", - "execution_count": 201, - "id": "a64701c2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " item_id\n10440 45695\n15297 39309\n2657 20474\n9728 15140\n4740 11455\n... ...\n1946 1\n13886 1\n14090 1\n5730 1\n13125 1\n\n[6440 rows x 1 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n

6440 rows × 1 columns

\n
" - }, - "execution_count": 201, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users['item_id'].value_counts().to_frame()" - ] - }, - { - "cell_type": "code", - "execution_count": 202, - "id": "cef9cfa6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" - }, - "execution_count": 202, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users[['item_id', 'total_dur']].groupby('item_id').mean().sort_values(by='total_dur', ascending=False).head(10).index" - ] - }, - { - "cell_type": "markdown", - "id": "a52f311b", - "metadata": {}, - "source": [ - "# Делим на train и test" - ] - }, - { - "cell_type": "code", - "execution_count": 203, - "id": "bd68d3fe", - "metadata": {}, - "outputs": [], - "source": [ - "max_date = interactions[Columns.Datetime].max()" - ] - }, - { - "cell_type": "code", - "execution_count": 204, - "id": "3092fe4b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: (4984443, 6)\n", - "test: (490980, 6)\n" - ] - } - ], - "source": [ - "train = interactions[interactions[Columns.Datetime] < max_date\n", - " - pd.Timedelta(days=7)].copy()\n", - "test = interactions[interactions[Columns.Datetime] >= max_date\n", - " - pd.Timedelta(days=7)].copy()\n", - "\n", - "print(f\"train: {train.shape}\")\n", - "print(f\"test: {test.shape}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 205, - "id": "ec286bdc", - "metadata": {}, - "outputs": [], - "source": [ - "train.drop(train.query(\"total_dur < 300\").index, inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 206, - "id": "52241fed", - "metadata": {}, - "outputs": [], - "source": [ - "drop_user = set(test[Columns.User]) - set(train[Columns.User])\n", - "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" - ] - }, - { - "cell_type": "markdown", - "id": "b5eec6da", - "metadata": {}, - "source": [ - "# User preprocess" - ] - }, - { - "cell_type": "code", - "execution_count": 207, - "id": "c57e2b2f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id age income sex kids_flg\n0 973171 age_25_34 income_60_90 М 1\n1 962099 age_18_24 income_20_40 М 0\n2 1047345 age_45_54 income_40_60 Ж 0\n3 721985 age_45_54 income_20_40 Ж 0\n4 704055 age_35_44 income_60_90 Ж 0\n... ... ... ... ... ...\n840192 339025 age_65_inf income_0_20 Ж 0\n840193 983617 age_18_24 income_20_40 Ж 1\n840194 251008 NaN NaN NaN 0\n840195 590706 NaN NaN Ж 0\n840196 166555 age_65_inf income_20_40 Ж 0\n\n[840197 rows x 5 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n

840197 rows × 5 columns

\n
" - }, - "execution_count": 207, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "users" - ] - }, - { - "cell_type": "code", - "execution_count": 208, - "id": "24cc138a", - "metadata": {}, - "outputs": [], - "source": [ - "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 209, - "id": "6e5e2d92", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id age income sex kids_flg\n0 973171 age_25_34 income_60_90 М 1\n1 962099 age_18_24 income_20_40 М 0\n3 721985 age_45_54 income_20_40 Ж 0\n4 704055 age_35_44 income_60_90 Ж 0\n5 1037719 age_45_54 income_60_90 М 0\n... ... ... ... .. ...\n840184 529394 age_25_34 income_40_60 Ж 0\n840186 80113 age_25_34 income_40_60 Ж 0\n840188 312839 age_65_inf income_60_90 Ж 0\n840189 191349 age_45_54 income_40_60 М 1\n840190 393868 age_25_34 income_20_40 М 0\n\n[586653 rows x 5 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
..................
840184529394age_25_34income_40_60Ж0
84018680113age_25_34income_40_60Ж0
840188312839age_65_infincome_60_90Ж0
840189191349age_45_54income_40_60М1
840190393868age_25_34income_20_40М0
\n

586653 rows × 5 columns

\n
" - }, - "execution_count": 209, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "users" - ] - }, - { - "cell_type": "markdown", - "id": "c7f9a6e7", - "metadata": {}, - "source": [ - "Заменяю Nan'ы на Unknown" - ] - }, - { - "cell_type": "code", - "execution_count": 210, - "id": "1286eb60", - "metadata": {}, - "outputs": [], - "source": [ - "users.fillna('Unknown', inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 211, - "id": "1ccccf0f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 973171 М sex\n1 962099 М sex\n3 721985 Ж sex\n4 704055 Ж sex\n5 1037719 М sex", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n
" - }, - "execution_count": 211, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_features_frames = []\n", - "for feature in ['sex', 'age', 'income']:\n", - " feature_frame = users.reindex(columns=[Columns.User, feature])\n", - " feature_frame.columns = ['id', 'value']\n", - " feature_frame['feature'] = feature\n", - " user_features_frames.append(feature_frame)\n", - "user_features = pd.concat(user_features_frames)\n", - "user_features.head()" - ] - }, - { - "cell_type": "markdown", - "id": "b9220b0b", - "metadata": {}, - "source": [ - "# Item preprocess" - ] - }, - { - "cell_type": "code", - "execution_count": 213, - "id": "8bbe9ee4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " item_id content_type title title_orig release_year \\\n0 10711 film Поговори с ней Hable con ella 2002.0 \n1 2508 film Голые перцы Search Party 2014.0 \n2 10716 film Тактическая сила Tactical Force 2011.0 \n3 7868 film 45 лет 45 Years 2015.0 \n4 16268 film Все решает мгновение NaN 1978.0 \n\n genres countries for_kids \\\n0 драмы, зарубежные, детективы, мелодрамы Испания NaN \n1 зарубежные, приключения, комедии США NaN \n2 криминал, зарубежные, триллеры, боевики, комедии Канада NaN \n3 драмы, зарубежные, мелодрамы Великобритания NaN \n4 драмы, спорт, советские, мелодрамы СССР NaN \n\n age_rating studios directors \\\n0 16.0 NaN Педро Альмодовар \n1 16.0 NaN Скот Армстронг \n2 16.0 NaN Адам П. Калтраро \n3 16.0 NaN Эндрю Хэй \n4 12.0 Ленфильм Виктор Садовский \n\n actors \\\n0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n4 Александр Абдулов, Александр Демьяненко, Алекс... \n\n description \\\n0 Мелодрама легендарного Педро Альмодовара «Пого... \n1 Уморительная современная комедия на популярную... \n2 Профессиональный рестлер Стив Остин («Все или ... \n3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n4 Расчетливая чаровница из советского кинохита «... \n\n keywords \n0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n4 Все, решает, мгновение, 1978, СССР, сильные, ж... ", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
\n
" - }, - "execution_count": 213, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 214, - "id": "72fa86a0", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": "item_id 0\ncontent_type 0\ntitle 0\ntitle_orig 4745\nrelease_year 98\ngenres 0\ncountries 37\nfor_kids 15397\nage_rating 2\nstudios 14898\ndirectors 1509\nactors 2619\ndescription 2\nkeywords 423\ndtype: int64" - }, - "execution_count": 214, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items.isna().sum()" - ] - }, - { - "cell_type": "code", - "execution_count": 215, - "id": "50f0611f", - "metadata": {}, - "outputs": [], - "source": [ - "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 216, - "id": "280cf47d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "item_id 0\ncontent_type 0\ntitle 0\ntitle_orig 3775\nrelease_year 31\ngenres 0\ncountries 14\nfor_kids 13415\nage_rating 1\nstudios 13047\ndirectors 939\nactors 1858\ndescription 0\nkeywords 388\ndtype: int64" - }, - "execution_count": 216, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items.isna().sum()" - ] - }, - { - "cell_type": "markdown", - "id": "eddd93b5", - "metadata": {}, - "source": [ - "# Genre" - ] - }, - { - "cell_type": "code", - "execution_count": 217, - "id": "bf6da75c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n
" - }, - "execution_count": 217, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Explode genres to flatten table\n", - "items['genre'] = items['genres'].str.lower().str.replace(', ', ',',\n", - " regex=False).str.split(',')\n", - "genre_feature = items[['item_id', 'genre']].explode('genre')\n", - "genre_feature.columns = ['id', 'value']\n", - "genre_feature['feature'] = 'genre'\n", - "genre_feature.head()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 218, - "id": "913b9c27", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre\n... ... ... ...\n15960 10632 криминал genre\n15961 4538 драмы genre\n15961 4538 спорт genre\n15961 4538 криминал genre\n15962 3206 комедии genre\n\n[36128 rows x 3 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n

36128 rows × 3 columns

\n
" - }, - "execution_count": 218, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "genre_feature" - ] - }, - { - "cell_type": "markdown", - "id": "478bf1e3", - "metadata": {}, - "source": [ - "# Content" - ] - }, - { - "cell_type": "code", - "execution_count": 220, - "id": "65f8b5d9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 film content_type\n1 2508 film content_type\n2 10716 film content_type\n3 7868 film content_type\n4 16268 film content_type", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
\n
" - }, - "execution_count": 220, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", - "content_feature.columns = [\"id\", \"value\"]\n", - "content_feature[\"feature\"] = \"content_type\"\n", - "content_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "a62ebee4", - "metadata": {}, - "source": [ - "# Actors" - ] - }, - { - "cell_type": "code", - "execution_count": 221, - "id": "fdc43660", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 адольфо фернандес actors\n0 10711 ана фернандес actors\n0 10711 дарио грандинетти actors\n0 10711 джеральдин чаплин actors\n0 10711 елена анайя actors", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
\n
" - }, - "execution_count": 221, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items['actors'] = items['actors'].str.lower().str.replace(', ', ',',\n", - " regex=False).str.split(',')\n", - "actors_feature = items[['item_id', 'actors']].explode('actors')\n", - "actors_feature.columns = ['id', 'value']\n", - "actors_feature['feature'] = 'actors'\n", - "actors_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "73801647", - "metadata": {}, - "source": [ - "# Keywords" - ] - }, - { - "cell_type": "code", - "execution_count": 222, - "id": "594abe5c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 поговори keywords\n0 10711 ней keywords\n0 10711 2002 keywords\n0 10711 испания keywords\n0 10711 друзья keywords", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
\n
" - }, - "execution_count": 222, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items['keywords'] = items['keywords'].str.lower().str.replace(', ', ','\n", - " , regex=False).str.split(',')\n", - "keywords_feature = items[['item_id', 'keywords']].explode('keywords')\n", - "keywords_feature.columns = ['id', 'value']\n", - "keywords_feature['feature'] = 'keywords'\n", - "keywords_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "d3eb0a37", - "metadata": {}, - "source": [ - "# Countries" - ] - }, - { - "cell_type": "code", - "execution_count": 223, - "id": "8eb8a621", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 Испания countries\n1 2508 США countries\n2 10716 Канада countries\n3 7868 Великобритания countries\n4 16268 СССР countries", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
\n
" - }, - "execution_count": 223, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "country_feature = items.reindex(columns=[Columns.Item, 'countries'])\n", - "country_feature.columns = ['id', 'value']\n", - "country_feature['feature'] = 'countries'\n", - "country_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "5e477ee1", - "metadata": {}, - "source": [ - "# Age Rating" - ] - }, - { - "cell_type": "code", - "execution_count": 224, - "id": "0894154a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 16.0 age_feature\n1 2508 16.0 age_feature\n2 10716 16.0 age_feature\n3 7868 16.0 age_feature\n4 16268 12.0 age_feature", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
\n
" - }, - "execution_count": 224, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", - "age_feature.columns = [\"id\", \"value\"]\n", - "age_feature[\"feature\"] = \"age_feature\"\n", - "age_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "c09df1ec", - "metadata": {}, - "source": [ - "# Studios" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "ff937b4f", - "metadata": {}, - "outputs": [], - "source": [ - "items.fillna('Unknown', inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 225, - "id": "cee42708", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 NaN studios\n1 2508 NaN studios\n2 10716 NaN studios\n3 7868 NaN studios\n4 16268 Ленфильм studios", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711NaNstudios
12508NaNstudios
210716NaNstudios
37868NaNstudios
416268Ленфильмstudios
\n
" - }, - "execution_count": 225, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", - "studios_feature.columns = [\"id\", \"value\"]\n", - "studios_feature[\"feature\"] = \"studios\"\n", - "studios_feature.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 226, - "id": "7234f13b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n
" - }, - "execution_count": 226, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# studios_feature, age_feature, country_feature - фичи которые хотелось бы использовать,\n", - "# но длительность обучения \"OPTUNA\" увеличивается в разы\n", - "item_features = pd.concat((genre_feature, content_feature ))\n", - "item_features.head()" - ] - }, - { - "cell_type": "markdown", - "id": "09b8d756", - "metadata": {}, - "source": [ - "# Metrics" - ] - }, - { - "cell_type": "code", - "execution_count": 227, - "id": "b082e667", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "{'Precision@1': Precision(k=1),\n 'Precision@2': Precision(k=2),\n 'Precision@3': Precision(k=3),\n 'Precision@4': Precision(k=4),\n 'Precision@5': Precision(k=5),\n 'Precision@6': Precision(k=6),\n 'Precision@7': Precision(k=7),\n 'Precision@8': Precision(k=8),\n 'Precision@9': Precision(k=9),\n 'Precision@10': Precision(k=10),\n 'Recall@1': Recall(k=1),\n 'Recall@2': Recall(k=2),\n 'Recall@3': Recall(k=3),\n 'Recall@4': Recall(k=4),\n 'Recall@5': Recall(k=5),\n 'Recall@6': Recall(k=6),\n 'Recall@7': Recall(k=7),\n 'Recall@8': Recall(k=8),\n 'Recall@9': Recall(k=9),\n 'Recall@10': Recall(k=10),\n 'MAP@1': MAP(k=1, divide_by_k=False),\n 'MAP@2': MAP(k=2, divide_by_k=False),\n 'MAP@3': MAP(k=3, divide_by_k=False),\n 'MAP@4': MAP(k=4, divide_by_k=False),\n 'MAP@5': MAP(k=5, divide_by_k=False),\n 'MAP@6': MAP(k=6, divide_by_k=False),\n 'MAP@7': MAP(k=7, divide_by_k=False),\n 'MAP@8': MAP(k=8, divide_by_k=False),\n 'MAP@9': MAP(k=9, divide_by_k=False),\n 'MAP@10': MAP(k=10, divide_by_k=False)}" - }, - "execution_count": 227, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "metrics_name = {\n", - " 'Precision': Precision,\n", - " 'Recall': Recall,\n", - " 'MAP': MAP,\n", - "}\n", - "\n", - "metrics = {}\n", - "for metric_name, metric in metrics_name.items():\n", - " for k in range(1, 11):\n", - " metrics[f'{metric_name}@{k}'] = metric(k=k)\n", - "metrics" - ] - }, - { - "cell_type": "markdown", - "id": "2c603783", - "metadata": {}, - "source": [ - "# Optuna\n", - "\n", - "Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", - "Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)" - ] - }, - { - "cell_type": "code", - "execution_count": 229, - "id": "fb193c2f", - "metadata": {}, - "outputs": [], - "source": [ - "NUM_THREADS = 8\n", - "RANDOM_STATE = 42\n", - "K = 5\n", - "NO_COMPONENTS = 32\n", - "N_EPOCHS = 1" - ] - }, - { - "cell_type": "code", - "execution_count": 230, - "id": "3328645d", - "metadata": {}, - "outputs": [], - "source": [ - "USER_ALPHA = 0\n", - "ITEM_ALPHA = 0\n", - "K_RECOS = 10" - ] - }, - { - "cell_type": "code", - "execution_count": 231, - "outputs": [], - "source": [ - "dataset = Dataset.construct(interactions_df=train,\n", - " user_features_df=user_features,\n", - " cat_user_features=['sex', 'age', 'income'],\n", - " item_features_df=item_features,\n", - " cat_item_features=['content_type', 'genre'])\n", - "TEST_USERS = test[Columns.User].unique()" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "a17b8b66", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:32:01,241]\u001B[0m A new study created in memory with name: no-name-d2c12238-d18d-4c6f-bca4-840e7d3f29b0\u001B[0m\n", - "\u001B[32m[I 2022-12-12 18:41:40,178]\u001B[0m Trial 0 finished with value: 0.07156314077881751 and parameters: {'recomender': 'ALS', 'regularization': 0.0035671951579306937}. Best is trial 0 with value: 0.07156314077881751.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07156314077881751\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:51:48,671]\u001B[0m Trial 1 finished with value: 0.07241639094290958 and parameters: {'recomender': 'ALS', 'regularization': 0.006724126527816994}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07241639094290958\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:53:18,697]\u001B[0m Trial 2 finished with value: 1.4050149479540313e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8190152272980945, 'k': 6, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 1.4050149479540313e-07\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:54:36,340]\u001B[0m Trial 3 finished with value: 0.005366068762176463 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.18723291153626603, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.005366068762176463\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:56:21,781]\u001B[0m Trial 4 finished with value: 0.0002205827579874263 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.6560234930178588, 'k': 6, 'loss': 'logistic'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.0002205827579874263\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:05:46,138]\u001B[0m Trial 5 finished with value: 0.07173988822226253 and parameters: {'recomender': 'ALS', 'regularization': 0.009044651486228098}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07173988822226253\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:07:05,748]\u001B[0m Trial 6 finished with value: 3.943062688880311e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.44751878244334975, 'k': 7, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 3.943062688880311e-06\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:08:22,099]\u001B[0m Trial 7 finished with value: 0.06793721324055035 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.10438302844592218, 'k': 3, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.06793721324055035\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:17:32,898]\u001B[0m Trial 8 finished with value: 0.07184311920591484 and parameters: {'recomender': 'ALS', 'regularization': 0.0005806772800434514}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07184311920591484\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:18:59,268]\u001B[0m Trial 9 finished with value: 2.2409988419866796e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.805131840226543, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 2.2409988419866796e-06\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:28:09,202]\u001B[0m Trial 10 finished with value: 0.07180954187357708 and parameters: {'recomender': 'ALS', 'regularization': 0.008190821633209066}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07180954187357708\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:37:15,147]\u001B[0m Trial 11 finished with value: 0.07244222251339615 and parameters: {'recomender': 'ALS', 'regularization': 0.00026970098377155163}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07244222251339615\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:46:24,260]\u001B[0m Trial 12 finished with value: 0.07202031081710311 and parameters: {'recomender': 'ALS', 'regularization': 0.0066363513358619185}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07202031081710311\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:55:34,176]\u001B[0m Trial 13 finished with value: 0.07199398893026046 and parameters: {'recomender': 'ALS', 'regularization': 0.004156107607150058}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07199398893026046\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:04:42,589]\u001B[0m Trial 14 finished with value: 0.07167963259586223 and parameters: {'recomender': 'ALS', 'regularization': 0.0006228566403390988}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07167963259586223\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:13:49,348]\u001B[0m Trial 15 finished with value: 0.07202106855494453 and parameters: {'recomender': 'ALS', 'regularization': 0.00598705937836684}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07202106855494453\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:22:57,770]\u001B[0m Trial 16 finished with value: 0.07193963920172777 and parameters: {'recomender': 'ALS', 'regularization': 0.0028834604694796696}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07193963920172777\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:32:04,614]\u001B[0m Trial 17 finished with value: 0.07186249836889418 and parameters: {'recomender': 'ALS', 'regularization': 0.007249626991281137}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07186249836889418\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:41:24,258]\u001B[0m Trial 18 finished with value: 0.07164870366757094 and parameters: {'recomender': 'ALS', 'regularization': 0.005115162467576984}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07164870366757094\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:50:49,059]\u001B[0m Trial 19 finished with value: 0.07179004415938793 and parameters: {'recomender': 'ALS', 'regularization': 0.0018963762834092678}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07179004415938793\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 21:42:16,853]\u001B[0m Trial 20 finished with value: 0.07167129296212232 and parameters: {'recomender': 'ALS', 'regularization': 0.009804091535656343}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07167129296212232\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 21:52:20,413]\u001B[0m Trial 21 finished with value: 0.07191839766465505 and parameters: {'recomender': 'ALS', 'regularization': 0.005764203522687446}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07191839766465505\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:02:12,773]\u001B[0m Trial 22 finished with value: 0.07159025974450188 and parameters: {'recomender': 'ALS', 'regularization': 0.006209360331833826}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07159025974450188\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:12:55,936]\u001B[0m Trial 23 finished with value: 0.07167021208897958 and parameters: {'recomender': 'ALS', 'regularization': 0.007825089420401029}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07167021208897958\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:23:04,762]\u001B[0m Trial 24 finished with value: 0.07191850988173716 and parameters: {'recomender': 'ALS', 'regularization': 0.004979324924695012}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07191850988173716\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:34:38,654]\u001B[0m Trial 25 finished with value: 0.07178449755342503 and parameters: {'recomender': 'ALS', 'regularization': 0.002381286135370409}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07178449755342503\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:45:43,850]\u001B[0m Trial 26 finished with value: 0.07177449403191542 and parameters: {'recomender': 'ALS', 'regularization': 0.004677821831829}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07177449403191542\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:56:45,636]\u001B[0m Trial 27 finished with value: 0.07214439856613958 and parameters: {'recomender': 'ALS', 'regularization': 0.0069504676367203744}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07214439856613958\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 23:08:13,361]\u001B[0m Trial 28 finished with value: 0.07237690498752612 and parameters: {'recomender': 'ALS', 'regularization': 0.0074561399301387955}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07237690498752612\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 23:18:05,878]\u001B[0m Trial 29 finished with value: 0.07173589378156864 and parameters: {'recomender': 'ALS', 'regularization': 0.00848249465326267}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07173589378156864\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[33m[W 2022-12-12 23:27:26,180]\u001B[0m Trial 30 failed because of the following error: KeyboardInterrupt()\u001B[0m\n", - "Traceback (most recent call last):\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", - " value_or_values = func(trial)\n", - " File \"/tmp/ipykernel_5286/352742220.py\", line 40, in objective\n", - " recos = model.recommend(\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\", line 132, in recommend\n", - " reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 141, in _recommend_u2i\n", - " scores = scores_calculator.calc(target_id)\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 98, in calc\n", - " scores = self.objects_factors @ subject_factors\n", - "KeyboardInterrupt\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", - "\u001B[0;32m/tmp/ipykernel_5286/352742220.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 48\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 49\u001B[0m \u001B[0mstudy\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0moptuna\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcreate_study\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mdirection\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m'maximize'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 50\u001B[0;31m \u001B[0mstudy\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0moptimize\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mobjective\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mn_trials\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;36m100\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001B[0m in \u001B[0;36moptimize\u001B[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 417\u001B[0m \"\"\"\n\u001B[1;32m 418\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 419\u001B[0;31m _optimize(\n\u001B[0m\u001B[1;32m 420\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 421\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_optimize\u001B[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 64\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 65\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mn_jobs\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0;36m1\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 66\u001B[0;31m _optimize_sequential(\n\u001B[0m\u001B[1;32m 67\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 68\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_optimize_sequential\u001B[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001B[0m\n\u001B[1;32m 158\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 159\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 160\u001B[0;31m \u001B[0mfrozen_trial\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0m_run_trial\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mstudy\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcatch\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 161\u001B[0m \u001B[0;32mfinally\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 162\u001B[0m \u001B[0;31m# The following line mitigates memory problems that can be occurred in some\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 232\u001B[0m \u001B[0;32mand\u001B[0m \u001B[0;32mnot\u001B[0m \u001B[0misinstance\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mfunc_err\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcatch\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 233\u001B[0m ):\n\u001B[0;32m--> 234\u001B[0;31m \u001B[0;32mraise\u001B[0m \u001B[0mfunc_err\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 235\u001B[0m \u001B[0;32mreturn\u001B[0m \u001B[0mfrozen_trial\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 236\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 194\u001B[0m \u001B[0;32mwith\u001B[0m \u001B[0mget_heartbeat_thread\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtrial\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_trial_id\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_storage\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 195\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 196\u001B[0;31m \u001B[0mvalue_or_values\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtrial\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 197\u001B[0m \u001B[0;32mexcept\u001B[0m \u001B[0mexceptions\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mTrialPruned\u001B[0m \u001B[0;32mas\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 198\u001B[0m \u001B[0;31m# TODO(mamu): Handle multi-objective cases.\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m/tmp/ipykernel_5286/352742220.py\u001B[0m in \u001B[0;36mobjective\u001B[0;34m(trial)\u001B[0m\n\u001B[1;32m 38\u001B[0m fit_features_together=True)\n\u001B[1;32m 39\u001B[0m \u001B[0mmodel\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mfit\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mdataset\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 40\u001B[0;31m recos = model.recommend(\n\u001B[0m\u001B[1;32m 41\u001B[0m \u001B[0musers\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mTEST_USERS\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 42\u001B[0m \u001B[0mdataset\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mdataset\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001B[0m in \u001B[0;36mrecommend\u001B[0;34m(self, users, dataset, k, filter_viewed, items_to_recommend, add_rank_col)\u001B[0m\n\u001B[1;32m 130\u001B[0m \u001B[0msorted_item_ids_to_recommend\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;32mNone\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 131\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 132\u001B[0;31m reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n\u001B[0m\u001B[1;32m 133\u001B[0m \u001B[0muser_ids\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 134\u001B[0m \u001B[0mdataset\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001B[0m in \u001B[0;36m_recommend_u2i\u001B[0;34m(self, user_ids, dataset, k, filter_viewed, sorted_item_ids_to_recommend)\u001B[0m\n\u001B[1;32m 139\u001B[0m \u001B[0mall_scores\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0mtp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mList\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mndarray\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m[\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 140\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mtarget_id\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mtqdm\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0muser_ids\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mdisable\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mverbose\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0;36m0\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 141\u001B[0;31m \u001B[0mscores\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mscores_calculator\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcalc\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtarget_id\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 142\u001B[0m reco_ids, reco_scores = recommend_from_scores(\n\u001B[1;32m 143\u001B[0m \u001B[0mscores\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mscores\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001B[0m in \u001B[0;36mcalc\u001B[0;34m(self, subject_id)\u001B[0m\n\u001B[1;32m 96\u001B[0m \u001B[0msubject_factors\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msubjects_factors\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0msubject_id\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 97\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdistance\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0mDistance\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mDOT\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 98\u001B[0;31m \u001B[0mscores\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mobjects_factors\u001B[0m \u001B[0;34m@\u001B[0m \u001B[0msubject_factors\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 99\u001B[0m \u001B[0;32melif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdistance\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0mDistance\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mEUCLIDEAN\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 100\u001B[0m \u001B[0msubject_dot\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msubjects_dots\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0msubject_id\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;31mKeyboardInterrupt\u001B[0m: " - ] - } - ], - "source": [ - "def objective(trial):\n", - " model_name = trial.suggest_categorical('recomender', ['LightFM',\n", - " 'ALS'])\n", - " if model_name == 'LightFM':\n", - " learning_rate = trial.suggest_float('learning_rate', 1e-10, 1)\n", - " k = trial.suggest_int('k', 2, 10)\n", - " loss = trial.suggest_categorical('loss', ['logistic', 'bpr',\n", - " 'warp'])\n", - " model = LightFMWrapperModel(LightFM(k=k,\n", - " learning_rate=learning_rate,\n", - " loss=loss, no_components=10),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS)\n", - " else:\n", - " regularization = trial.suggest_float('regularization', 1e-4,\n", - " 1e-2)\n", - " model = \\\n", - " ImplicitALSWrapperModel(model=AlternatingLeastSquares(factors=10,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=regularization),\n", - " fit_features_together=True)\n", - " model.fit(dataset)\n", - " recos = model.recommend(users=TEST_USERS, dataset=dataset,\n", - " k=K_RECOS, filter_viewed=True)\n", - " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", - " print ('MAP@10', metric)\n", - " return metric\n", - "\n", - "\n", - "study = optuna.create_study(direction='maximize')\n", - "study.optimize(objective, n_trials=100)" - ] - }, - { - "cell_type": "markdown", - "id": "3989645b", - "metadata": {}, - "source": [ - "## Пришлось остановить обучение, тк эти 30 эпох обучались 6 часов" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "99aae61e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'recomender': 'ALS', 'regularization': 0.00026970098377155163}" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "study.best_params" - ] - }, - { - "cell_type": "code", - "execution_count": 233, - "outputs": [], - "source": [ - "REGULARIZATION = 0.00026970098377155163" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 234, - "id": "d1f6069a", - "metadata": {}, - "outputs": [], - "source": [ - "# обучаем best model после optuna\n", - "model = ImplicitALSWrapperModel(\n", - " model=AlternatingLeastSquares(\n", - " factors=32,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=REGULARIZATION\n", - " ),\n", - " fit_features_together=True\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 236, - "id": "d3907c1d", - "metadata": {}, - "outputs": [], - "source": [ - "model.fit(dataset)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2050a6e", - "metadata": {}, - "outputs": [], - "source": [ - "recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "6bbe3ff3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.07124010116092815" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "calc_metrics(metrics, recos, test, train)['MAP@10']" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "d3eead34", - "metadata": {}, - "outputs": [], - "source": [ - "recos = recos[['user_id', 'item_id']]\n", - "recos.to_csv('ALS_after_optuna.csv.gz', index=False, compression='gzip')" - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Добавление аватаров\n", - "Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 264, - "outputs": [], - "source": [ - "some_avatars = pd.DataFrame(\n", - " {\n", - " Columns.User: [11111111, 11111112, 11111113],\n", - " Columns.Item: [\n", - " [10732, 3369, 15885], # Аватар, который любит мультики [губка боб, кунг-фу панда, ]\n", - " [3506, 1107, 11235], # Аватар, который любит боевики [форсаж, обитель зла, плохие парни]\n", - " [931, 389, 8315] # Аватар, который любит драмы [после, хатико, сумерки]\n", - " ],\n", - " 'last_watch_dt': [\n", - " [random.choice(sorted(interactions.last_watch_dt.unique())[-10:]) for _ in range(3)] for i in range(3)\n", - " ],\n", - " \"total_dur\": [\n", - " [34343, 6000, 9000],\n", - " [5000, 45452, 9000],\n", - " [5000, 3200, 3232]\n", - " ],\n", - " \"watched_pct\": [\n", - " [100.0, 95.0, 99.0],\n", - " [67.0, 95.0, 99.0],\n", - " [100.0, 53.0, 99.0]\n", - " ],\n", - " Columns.Weight: [\n", - " [5, 5, 5],\n", - " [3, 5, 5],\n", - " [5, 2, 5]\n", - " ]\n", - " }\n", - ")\n", - "\n", - "some_avatars = some_avatars.explode(\n", - " [Columns.Item, Columns.Datetime, \"total_dur\", \"watched_pct\", Columns.Weight]\n", - ").reset_index(drop=True)" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 265, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n0 11111111 10732 2021-08-22 34343 100.0 5\n1 11111111 3369 2021-08-19 6000 95.0 5\n2 11111111 15885 2021-08-17 9000 99.0 5\n3 11111112 3506 2021-08-20 5000 67.0 3\n4 11111112 1107 2021-08-14 45452 95.0 5\n5 11111112 11235 2021-08-19 9000 99.0 5\n6 11111113 931 2021-08-14 5000 100.0 5\n7 11111113 389 2021-08-19 3200 53.0 2\n8 11111113 8315 2021-08-22 3232 99.0 5", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
011111111107322021-08-2234343100.05
11111111133692021-08-19600095.05
211111111158852021-08-17900099.05
31111111235062021-08-20500067.03
41111111211072021-08-144545295.05
511111112112352021-08-19900099.05
6111111139312021-08-145000100.05
7111111133892021-08-19320053.02
81111111383152021-08-22323299.05
\n
" - }, - "execution_count": 265, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "some_avatars" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 266, - "outputs": [], - "source": [ - "interactions_with_avatars = pd.concat([interactions, some_avatars])\n", - "\n", - "dataset_with_avatars = Dataset.construct(\n", - " interactions_df=interactions_with_avatars,\n", - ")\n", - "\n", - "# обучаем best model после optuna\n", - "model_with_avatars = ImplicitALSWrapperModel(\n", - " model=AlternatingLeastSquares(\n", - " factors=32,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=REGULARIZATION\n", - " ),\n", - " fit_features_together=True\n", - ")" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 267, - "outputs": [ - { - "data": { - "text/plain": "" - }, - "execution_count": 267, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model_with_avatars.fit(dataset_with_avatars)" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 268, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id score rank\n0 11111111 11985 0.040700 1\n1 11111111 2954 0.039466 2\n2 11111111 7310 0.036591 3\n3 11111111 3182 0.035423 4\n4 11111111 4475 0.034422 5\n5 11111112 7793 0.035639 1\n6 11111112 4702 0.035139 2\n7 11111112 16361 0.034857 3\n8 11111112 1287 0.034327 4\n9 11111112 11018 0.032349 5\n10 11111113 1916 0.245655 1\n11 11111113 14470 0.242786 2\n12 11111113 101 0.219231 3\n13 11111113 12463 0.206615 4\n14 11111113 5732 0.183012 5", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idscorerank
011111111119850.0407001
11111111129540.0394662
21111111173100.0365913
31111111131820.0354234
41111111144750.0344225
51111111277930.0356391
61111111247020.0351392
711111112163610.0348573
81111111212870.0343274
911111112110180.0323495
101111111319160.2456551
1111111113144700.2427862
12111111131010.2192313
1311111113124630.2066154
141111111357320.1830125
\n
" - }, - "execution_count": 268, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "recos_with_avatars = model_with_avatars.recommend(\n", - " users=[11111111, 11111112, 11111113],\n", - " dataset=dataset_with_avatars,\n", - " k=5,\n", - " filter_viewed=True\n", - ")\n", - "recos_with_avatars" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 269, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id score rank content_type title \\\n0 11111111 11985 0.040700 1 film История игрушек 4 \n1 11111111 2954 0.039466 2 film Миньоны \n2 11111111 7310 0.036591 3 film Гадкий я 2 \n3 11111111 3182 0.035423 4 film Ральф против Интернета \n4 11111111 4475 0.034422 5 film Тачки \n5 11111112 7793 0.035639 1 film Радиовспышка \n6 11111112 4702 0.035139 2 film Хищник \n7 11111112 16361 0.034857 3 film Doom: Аннигиляция \n8 11111112 1287 0.034327 4 film Терминатор: Тёмные судьбы \n9 11111112 11018 0.032349 5 film Хищники \n10 11111113 1916 0.245655 1 film Секс и ничего лишнего \n11 11111113 14470 0.242786 2 film Любовь \n12 11111113 101 0.219231 3 film Куриоса \n13 11111113 12463 0.206615 4 film Студентка по вызову \n14 11111113 5732 0.183012 5 film Тайное влечение \n\n title_orig release_year \\\n0 Toy Story 4 2019.0 \n1 Minions 2015.0 \n2 Despicable Me 2 2013.0 \n3 Ralph Breaks the Internet 2018.0 \n4 Cars 2006.0 \n5 Radioflash 2019.0 \n6 Predator 1987.0 \n7 Doom: Annihilation 2019.0 \n8 Terminator: Dark Fate 2019.0 \n9 Predators 2010.0 \n10 My Awkward Sexual Adventure 2012.0 \n11 Love 2015.0 \n12 Curiosa 2019.0 \n13 Mes chères études 2010.0 \n14 Adore 2013.0 \n\n genres countries \\\n0 мультфильм, фэнтези, комедии США \n1 фантастика, мультфильм, приключения, комедии США \n2 мультфильм, приключения, фантастика, фэнтези, ... США, Франция, Япония \n3 мультфильм, приключения, фантастика, семейное,... США \n4 спорт, мультфильм, комедии США \n5 боевики, драмы, фантастика, триллеры США \n6 боевики, фантастика, триллеры, приключения США, Мексика \n7 боевики, ужасы, фантастика, триллеры США \n8 боевики, фантастика, приключения США, Китай \n9 боевики, фантастика, триллеры, приключения США \n10 мелодрамы Канада \n11 драмы, мелодрамы Франция \n12 историческое, мелодрамы Франция \n13 драмы, мелодрамы Франция \n14 драмы, мелодрамы Австралия, Франция \n\n for_kids age_rating studios directors \\\n0 NaN 6.0 NaN Джош Кули \n1 NaN 6.0 NaN Кайл Балда, Пьер Коффан \n2 NaN 0.0 NaN Пьер Коффан, Крис Рено \n3 NaN 6.0 NaN Рич Мур, Фил Джонстон \n4 NaN 6.0 NaN Джон Лассетер, Джо Рэнфт \n5 NaN 16.0 NaN Бен Макферсон \n6 NaN 16.0 NaN Джон МакТирнан \n7 NaN 18.0 NaN Тони Гиглио \n8 NaN 16.0 NaN Тим Миллер \n9 NaN 16.0 NaN Нимрод Антал \n10 NaN 18.0 NaN Шон Гэррити \n11 NaN 18.0 NaN Гаспар Ноэ \n12 NaN 18.0 NaN Лу Жене \n13 NaN 18.0 NaN Эмманюэль Берко \n14 NaN 16.0 NaN Анн Фонтен \n\n actors \\\n0 [том хэнкс, тим аллен, энни поттс, тони хейл, ... \n1 [сандра буллок, джон хэмм, майкл китон, эллисо... \n2 [стив карелл, кристен уиг, бенджамин брэтт, ми... \n3 [джон си райли, сара силверман, галь гадот, та... \n4 [оуэн уилсон, пол ньюман, бонни хант, ларри-ка... \n5 [брайтон шарбино, доминик монахэн, уилл пэттон... \n6 [арнольд шварценеггер, карл уэзерс, эльпидия к... \n7 [эми мэнсон, доминик мафэм, люк аллен-гейл, дж... \n8 [линда хэмилтон, арнольд шварценеггер, маккенз... \n9 [эдриан броуди, тофер грейс, алиси брага, уолт... \n10 [джонас черник, эмили хэмпшир, сара мэннинен, ... \n11 [аоми муйок, карл глусман, клара кристин, уго ... \n12 [ноэми мерлан, нильс шнайдер, бенжамен лаверн,... \n13 [дебора франсуа, ален коши, матье деми, бенжам... \n14 [наоми уоттс, робин райт, завьер сэмюэл, джейм... \n\n description \\\n0 Космический рейнджер Баз Лайтер, ковбой Вуди, ... \n1 Миньоны живут на планете гораздо дольше нас. У... \n2 В то время как Грю, бывший суперзлодей, приспо... \n3 На этот раз Ральф и Ванилопа фон Кекс выйдут з... \n4 Неукротимый в своем желании всегда и во всем п... \n5 Риз с легкостью проходит виртуальные квесты, н... \n6 Американский вертолет был сбит партизанами в Ю... \n7 Отряд морпехов прилетает на марсианский спутни... \n8 Мексика. Милая девушка Даниэла Рамос, а для др... \n9 Наемник Ройс невольно вынужден возглавить груп... \n10 Чтобы вернуть свою неудовлетворенную бывшую де... \n11 Любовь вне добра и зла. Любовь — это генетичес... \n12 Историческая драма про любовный треугольник, к... \n13 Лаура — 19-летняя первокурсница французского у... \n14 Главные героини картины – Лил и Роз — две давн... \n\n keywords \\\n0 [игрушка, дружба, ковбой, история игрушек 4, ,... \n1 [помощник, сцена после титров, сцена во время ... \n2 [отношения родитель-ребенок, секретный агент, ... \n3 [видеоигра, мультфильм, продолжение, интернет,... \n4 [автомобильная гонка, трасса 66, porsche, выхо... \n5 [2019, соединенные штаты, радиовспышка] \n6 [центральная и южная америка, хищник, иноплане... \n7 [планета марс, ад, космос, демон, по мотивам в... \n8 [искуственный интеллект, киборг, вертолет, мех... \n9 [охотник, хищник, якудза, охота на людей, иноп... \n10 [нижнее белье, массажистка, секс втроем, фалло... \n11 [париж, франция, секс, сексуальность, галерея,... \n12 [, 1890-е, большой пенис, брак без секса, вдох... \n13 [франция, гостиница, по роману или книге, гост... \n14 [пляж, нагота, любовники, месть, лучший друг, ... \n\n genre \n0 [мультфильм, фэнтези, комедии] \n1 [фантастика, мультфильм, приключения, комедии] \n2 [мультфильм, приключения, фантастика, фэнтези,... \n3 [мультфильм, приключения, фантастика, семейное... \n4 [спорт, мультфильм, комедии] \n5 [боевики, драмы, фантастика, триллеры] \n6 [боевики, фантастика, триллеры, приключения] \n7 [боевики, ужасы, фантастика, триллеры] \n8 [боевики, фантастика, приключения] \n9 [боевики, фантастика, триллеры, приключения] \n10 [мелодрамы] \n11 [драмы, мелодрамы] \n12 [историческое, мелодрамы] \n13 [драмы, мелодрамы] \n14 [драмы, мелодрамы] ", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idscorerankcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywordsgenre
011111111119850.0407001filmИстория игрушек 4Toy Story 42019.0мультфильм, фэнтези, комедииСШАNaN6.0NaNДжош Кули[том хэнкс, тим аллен, энни поттс, тони хейл, ...Космический рейнджер Баз Лайтер, ковбой Вуди, ...[игрушка, дружба, ковбой, история игрушек 4, ,...[мультфильм, фэнтези, комедии]
11111111129540.0394662filmМиньоныMinions2015.0фантастика, мультфильм, приключения, комедииСШАNaN6.0NaNКайл Балда, Пьер Коффан[сандра буллок, джон хэмм, майкл китон, эллисо...Миньоны живут на планете гораздо дольше нас. У...[помощник, сцена после титров, сцена во время ...[фантастика, мультфильм, приключения, комедии]
21111111173100.0365913filmГадкий я 2Despicable Me 22013.0мультфильм, приключения, фантастика, фэнтези, ...США, Франция, ЯпонияNaN0.0NaNПьер Коффан, Крис Рено[стив карелл, кристен уиг, бенджамин брэтт, ми...В то время как Грю, бывший суперзлодей, приспо...[отношения родитель-ребенок, секретный агент, ...[мультфильм, приключения, фантастика, фэнтези,...
31111111131820.0354234filmРальф против ИнтернетаRalph Breaks the Internet2018.0мультфильм, приключения, фантастика, семейное,...СШАNaN6.0NaNРич Мур, Фил Джонстон[джон си райли, сара силверман, галь гадот, та...На этот раз Ральф и Ванилопа фон Кекс выйдут з...[видеоигра, мультфильм, продолжение, интернет,...[мультфильм, приключения, фантастика, семейное...
41111111144750.0344225filmТачкиCars2006.0спорт, мультфильм, комедииСШАNaN6.0NaNДжон Лассетер, Джо Рэнфт[оуэн уилсон, пол ньюман, бонни хант, ларри-ка...Неукротимый в своем желании всегда и во всем п...[автомобильная гонка, трасса 66, porsche, выхо...[спорт, мультфильм, комедии]
51111111277930.0356391filmРадиовспышкаRadioflash2019.0боевики, драмы, фантастика, триллерыСШАNaN16.0NaNБен Макферсон[брайтон шарбино, доминик монахэн, уилл пэттон...Риз с легкостью проходит виртуальные квесты, н...[2019, соединенные штаты, радиовспышка][боевики, драмы, фантастика, триллеры]
61111111247020.0351392filmХищникPredator1987.0боевики, фантастика, триллеры, приключенияСША, МексикаNaN16.0NaNДжон МакТирнан[арнольд шварценеггер, карл уэзерс, эльпидия к...Американский вертолет был сбит партизанами в Ю...[центральная и южная америка, хищник, иноплане...[боевики, фантастика, триллеры, приключения]
711111112163610.0348573filmDoom: АннигиляцияDoom: Annihilation2019.0боевики, ужасы, фантастика, триллерыСШАNaN18.0NaNТони Гиглио[эми мэнсон, доминик мафэм, люк аллен-гейл, дж...Отряд морпехов прилетает на марсианский спутни...[планета марс, ад, космос, демон, по мотивам в...[боевики, ужасы, фантастика, триллеры]
81111111212870.0343274filmТерминатор: Тёмные судьбыTerminator: Dark Fate2019.0боевики, фантастика, приключенияСША, КитайNaN16.0NaNТим Миллер[линда хэмилтон, арнольд шварценеггер, маккенз...Мексика. Милая девушка Даниэла Рамос, а для др...[искуственный интеллект, киборг, вертолет, мех...[боевики, фантастика, приключения]
911111112110180.0323495filmХищникиPredators2010.0боевики, фантастика, триллеры, приключенияСШАNaN16.0NaNНимрод Антал[эдриан броуди, тофер грейс, алиси брага, уолт...Наемник Ройс невольно вынужден возглавить груп...[охотник, хищник, якудза, охота на людей, иноп...[боевики, фантастика, триллеры, приключения]
101111111319160.2456551filmСекс и ничего лишнегоMy Awkward Sexual Adventure2012.0мелодрамыКанадаNaN18.0NaNШон Гэррити[джонас черник, эмили хэмпшир, сара мэннинен, ...Чтобы вернуть свою неудовлетворенную бывшую де...[нижнее белье, массажистка, секс втроем, фалло...[мелодрамы]
1111111113144700.2427862filmЛюбовьLove2015.0драмы, мелодрамыФранцияNaN18.0NaNГаспар Ноэ[аоми муйок, карл глусман, клара кристин, уго ...Любовь вне добра и зла. Любовь — это генетичес...[париж, франция, секс, сексуальность, галерея,...[драмы, мелодрамы]
12111111131010.2192313filmКуриосаCuriosa2019.0историческое, мелодрамыФранцияNaN18.0NaNЛу Жене[ноэми мерлан, нильс шнайдер, бенжамен лаверн,...Историческая драма про любовный треугольник, к...[, 1890-е, большой пенис, брак без секса, вдох...[историческое, мелодрамы]
1311111113124630.2066154filmСтудентка по вызовуMes chères études2010.0драмы, мелодрамыФранцияNaN18.0NaNЭмманюэль Берко[дебора франсуа, ален коши, матье деми, бенжам...Лаура — 19-летняя первокурсница французского у...[франция, гостиница, по роману или книге, гост...[драмы, мелодрамы]
141111111357320.1830125filmТайное влечениеAdore2013.0драмы, мелодрамыАвстралия, ФранцияNaN16.0NaNАнн Фонтен[наоми уоттс, робин райт, завьер сэмюэл, джейм...Главные героини картины – Лил и Роз — две давн...[пляж, нагота, любовники, месть, лучший друг, ...[драмы, мелодрамы]
\n
" - }, - "execution_count": 269, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "recos_with_avatars.merge(items, on='item_id', how='left')" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "markdown", - "source": [ - "В целом, все рекомендации к каждому аватару получились неплохие" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "markdown", - "id": "ab12c89f", - "metadata": {}, - "source": [ - " # Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций.\n", - "\n", - "Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", - "Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "5d1161b4", - "metadata": {}, - "outputs": [], - "source": [ - "LEARNING_RATE = 0.08165160206425184\n", - "LOSS = 'warp'" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "id": "9f20ae6e", - "metadata": {}, - "outputs": [], - "source": [ - "# обучаем LightFM, чтобы достать из нее вектора пользователей и айтемов\n", - "model = LightFMWrapperModel(\n", - " LightFM(\n", - " k=K,\n", - " no_components=NO_COMPONENTS,\n", - " loss= LOSS,\n", - " random_state=RANDOM_STATE,\n", - " learning_rate=LEARNING_RATE,\n", - " user_alpha=USER_ALPHA,\n", - " item_alpha=ITEM_ALPHA\n", - " ),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "9982d55c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model.fit(dataset)" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "348b4fd6", - "metadata": {}, - "outputs": [], - "source": [ - "user_embeddings, item_embeddings = model.get_vectors(dataset)" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "fd296cf4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((756545, 34), (13963, 34))" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_embeddings.shape, item_embeddings.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "d75b4570", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([-2.48910075e+02, 1.00000000e+00, -3.04745167e-01, 1.30259299e-01,\n", - " -1.25937782e-01, 1.32810516e-01, -3.98682870e-01, 2.12211904e-01,\n", - " 3.15063161e-01, 9.48599975e-03, 1.79876286e-01, -1.15210674e-01,\n", - " 3.13044085e-01, 5.25500635e-02, -8.94866249e-02, 6.32450803e-02,\n", - " 3.30464664e-01, -2.79290127e-01, 7.66675368e-02, 2.69704125e-01,\n", - " -2.02872234e-01, 3.65543869e-02, -2.08750917e-01, -7.48397237e-02,\n", - " 2.09714412e-01, 1.28161004e-01, -2.49842146e-01, 7.57336145e-02,\n", - " 6.74582969e-02, 2.03054725e-01, -4.46441335e-02, 1.00222239e-01,\n", - " 3.09746759e-01, 2.26963989e-01])" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#пользователь со средним значением по каждому признаку\n", - "first_person = user_embeddings.mean(0)\n", - "first_person" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "id": "88198015", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([-364.41271973, 1. , -2.19337273, -2.05960441,\n", - " -3.03305483, -2.15237951, -3.10027146, -1.44008625,\n", - " -1.55592728, -1.69499218, -1.87335801, -3.19125104,\n", - " -1.8664068 , -2.62357092, -2.23808742, -1.78050435,\n", - " -1.67308342, -2.70261121, -1.94637215, -2.44766903,\n", - " -2.40233946, -1.93648934, -2.32535124, -2.73280096,\n", - " -2.20278382, -1.93085539, -2.29366779, -1.9847883 ,\n", - " -2.619452 , -1.8447926 , -2.03915739, -1.86472845,\n", - " -1.80441463, -1.98137343])" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#пользователь со минимальным значением по каждому признаку\n", - "second_person = user_embeddings.min(axis=0)\n", - "second_person" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "id": "4e02dec3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([0. , 1. , 1.80414879, 2.91568851, 2.57092023,\n", - " 2.49563074, 3.0165813 , 2.02071786, 2.10402703, 1.86775827,\n", - " 1.81193578, 2.3456769 , 2.37611055, 4.0926795 , 1.8776809 ,\n", - " 1.91333187, 2.16625547, 1.76979506, 1.87265527, 2.63360167,\n", - " 1.97114313, 1.88249838, 1.89424872, 2.15507913, 2.38049865,\n", - " 1.99921763, 1.80478072, 1.8311218 , 3.32906055, 2.25318193,\n", - " 2.0245254 , 2.37490654, 2.28989363, 1.97282732])" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#пользователь со максимальным значением по каждому признаку\n", - "third_person = user_embeddings.max(axis=0)\n", - "third_person" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "id": "75a314ac", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(756545, 34)" - ] - }, - "execution_count": 77, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_embeddings.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "id": "3cb72431", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(756548, 34)" - ] - }, - "execution_count": 78, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# добавим векотра 3х новых пользователей\n", - "user_embeddings = np.append(user_embeddings, np.array([first_person,\n", - " second_person, third_person]), axis=0)\n", - "user_embeddings.shape\n" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "db53d401", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150, 'post': 0, 'chunkIndexSize': 10000}\n" - ] - } - ], - "source": [ - "M = 50\n", - "efC = 150\n", - "\n", - "num_threads = 8\n", - "chunkIndexSize = 10000\n", - "\n", - "index_time_params = {\n", - " 'M': M,\n", - " 'indexThreadQty': num_threads,\n", - " 'efConstruction': efC,\n", - " 'post': 0,\n", - " 'chunkIndexSize': chunkIndexSize,\n", - " }\n", - "print ('Index-time parameters', index_time_params)" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "e09782e5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "13963" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "K = 10\n", - "space_name = 'negdotprod'\n", - "index = nmslib.init(method='hnsw', space=space_name,\n", - " data_type=nmslib.DataType.DENSE_VECTOR)\n", - "index.addDataPointBatch(item_embeddings)" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "id": "209d778e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150}\n", - "Indexing time = 1.392440\n" - ] - } - ], - "source": [ - "start = time.time()\n", - "index_time_params = {'M': M, 'indexThreadQty': num_threads,\n", - " 'efConstruction': efC}\n", - "index.createIndex(index_time_params)\n", - "end = time.time()\n", - "print ('Index-time parameters', index_time_params)\n", - "print 'Indexing time = %f' % (end - start)" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "id": "998dad8b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Setting query-time parameters {'efSearch': 100}\n" - ] - } - ], - "source": [ - "efS = 100\n", - "query_time_params = {'efSearch': efS}\n", - "print('Setting query-time parameters', query_time_params)\n", - "index.setQueryTimeParams(query_time_params)" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "id": "6f5cd03c", - "metadata": {}, - "outputs": [], - "source": [ - "query_matrix = user_embeddings" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "77039943", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "kNN time total=3.962551 (sec), per query=0.000005 (sec), per query adjusted for thread number=0.000042 (sec)\n" - ] - } - ], - "source": [ - "query_qty = query_matrix.shape[0]\n", - "start = time.time()\n", - "nbrs = index.knnQueryBatch(query_matrix, k=K, num_threads=num_threads)\n", - "end = time.time()\n", - "print 'kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' \\\n", - " % (end - start, float(end - start) / query_qty, num_threads\n", - " * float(end - start) / query_qty)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "id": "cac18e0e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 32, 19, 43, ..., 31, 36, 69],\n", - " [ 31, 262, 62, ..., 32, 121, 735],\n", - " [ 19, 31, 121, ..., 29, 62, 105],\n", - " ...,\n", - " [ 31, 19, 43, ..., 268, 100, 86],\n", - " [ 19, 31, 32, ..., 268, 49, 173],\n", - " [ 19, 31, 32, ..., 100, 105, 268]])" - ] - }, - "execution_count": 86, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# рекомендации для всех пользователей\n", - "recos_old_persons = np.array(nbrs, dtype=int)[:,0][:len(nbrs) - 3]\n", - "recos_old_persons" - ] - }, - { - "cell_type": "code", - "execution_count": 87, - "id": "918c6976", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 31, 19, 32, 43, 62, 121, 173, 268, 100,\n", - " 86],\n", - " [12018, 10998, 7308, 12006, 10159, 10215, 3543, 8118, 8180,\n", - " 11511],\n", - " [ 8453, 6400, 3557, 3945, 6642, 4779, 3583, 2068, 8668,\n", - " 371]])" - ] - }, - "execution_count": 87, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# рекомендации для добавленных пользователей\n", - "recos_new_persons = np.array(nbrs, dtype=int)[:,0][-3:]\n", - "recos_new_persons" - ] - }, - { - "cell_type": "code", - "execution_count": 88, - "id": "c78fbc6a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_id
0032
1019
2043
3062
40449
.........
756544575654443
756544675654429
7565447756544100
7565448756544105
7565449756544268
\n", - "

7565450 rows × 2 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id\n", - "0 0 32\n", - "1 0 19\n", - "2 0 43\n", - "3 0 62\n", - "4 0 449\n", - "... ... ...\n", - "7565445 756544 43\n", - "7565446 756544 29\n", - "7565447 756544 100\n", - "7565448 756544 105\n", - "7565449 756544 268\n", - "\n", - "[7565450 rows x 2 columns]" - ] - }, - "execution_count": 88, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_r = \\\n", - " pd.DataFrame({'user_id': np.repeat(np.arange(len(recos_old_persons)),\n", - " 10), Columns.Item: recos_old_persons.ravel()})\n", - "df_r\n" - ] - }, - { - "cell_type": "code", - "execution_count": 89, - "id": "902cbca6", - "metadata": {}, - "outputs": [], - "source": [ - "df_r.to_csv('nmslib.csv.gz', index=False, compression='gzip')\n" - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Холодные пользователи\n", - "Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", - "\n", - "В предыдущей домашке, мы выяснили, что на этом датасете лучше всего себя ведет топ за последний месяц. Поэтому каждую модель мы использовали с подобным методом добивки холодных пользователей\n" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": null, - "outputs": [], - "source": [], - "metadata": { - "collapsed": false - } - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From b3ae70352a85a3bd3c1a5c7a85e182c876d2feff Mon Sep 17 00:00:00 2001 From: Shakirov Renat Date: Wed, 14 Dec 2022 01:29:04 +0300 Subject: [PATCH 10/12] add online model's inference class --- service/api/models_zoo.py | 2 +- service/api/views.py | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/service/api/models_zoo.py b/service/api/models_zoo.py index eede9a81..35aa87a9 100644 --- a/service/api/models_zoo.py +++ b/service/api/models_zoo.py @@ -147,7 +147,7 @@ def reco_predict( return reco -class KNNModelBM25(BaseModelZoo): +class OnlineModel(BaseModelZoo): def __init__( self, path_to_model: str = "data/knn_bm25.pickle", diff --git a/service/api/views.py b/service/api/views.py index 1124fe1a..9603b00d 100644 --- a/service/api/views.py +++ b/service/api/views.py @@ -11,7 +11,7 @@ from .config import config_env from .models import NotFoundError, RecoResponse, UnauthorizedError -from .models_zoo import DumpModel +from .models_zoo import DumpModel, OnlineModel router = APIRouter() @@ -19,7 +19,15 @@ api_header = APIKeyHeader(name=config_env["API_KEY_NAME"], auto_error=False) token_bearer = HTTPBearer(auto_error=False) -models_zoo = {"model_1": DumpModel()} +try: + models_zoo = { + "model_1": DumpModel(), + "LightFM": OnlineModel(path_to_model='./data/lightfm.pickle') + } +except FileNotFoundError: + models_zoo = { + "model_1": DumpModel(), + } async def get_api_key( From c4cc4441dfe7ef7518c9b726d0fa4cb3b3ae78b3 Mon Sep 17 00:00:00 2001 From: Vladislav Mostovik <56130198+Mostovik71@users.noreply.github.com> Date: Wed, 14 Dec 2022 12:27:34 +0300 Subject: [PATCH 11/12] Delete ALS_LightFM_MF.ipynb --- notebooks/ALS_LightFM_MF.ipynb | 2407 -------------------------------- 1 file changed, 2407 deletions(-) delete mode 100644 notebooks/ALS_LightFM_MF.ipynb diff --git a/notebooks/ALS_LightFM_MF.ipynb b/notebooks/ALS_LightFM_MF.ipynb deleted file mode 100644 index 921e134d..00000000 --- a/notebooks/ALS_LightFM_MF.ipynb +++ /dev/null @@ -1,2407 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "source": [ - "# Домашнее задание\n", - "\n", - "Домашнее задание состоит из нескольких блоков.\n", - "\n", - "\n", - "## Эксперименты в ipynb ноутбуках (15 баллов)\n", - "- Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", - " - Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)\n", - "- Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", - " - Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д\n", - "- Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**\n", - "- Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", - "\n", - "Примечание: за невоспроизводимый код в ноутбуках (например, нарушен порядок выполнения ячеек, вызываются переменные, которые нигде не были объявлены ранее и.т.п) будут штрафы на усмотрение проверяющего.\n", - "\n", - "\n", - "## Реализация итоговой модели в сервисе (10 баллов)\n", - "- Пробитие бейзлайна $MAP@10 \\geq 0.074921$ **(6 баллов)**\n", - "- Код сервиса соответствует критериям читаемости и воспроизводимости **(4 балла)**" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 1, - "outputs": [], - "source": [ - "import warnings\n", - "warnings.filterwarnings('ignore')" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 246, - "id": "e42a5585", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import time\n", - "import random\n", - "from pathlib import Path\n", - "\n", - "import numpy as np\n", - "import optuna\n", - "import pandas as pd\n", - "\n", - "import nmslib\n", - "from implicit.als import AlternatingLeastSquares\n", - "from lightfm import LightFM\n", - "from rectools import Columns\n", - "from rectools.dataset import Dataset\n", - "from rectools.metrics import MAP, Precision, Recall, calc_metrics\n", - "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel" - ] - }, - { - "cell_type": "code", - "execution_count": 180, - "id": "8cd36e1a", - "metadata": {}, - "outputs": [], - "source": [ - "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"" - ] - }, - { - "cell_type": "code", - "execution_count": 185, - "id": "4cb722c3", - "metadata": {}, - "outputs": [], - "source": [ - "DATA_PATH = Path(\"../data/kion_train/\")" - ] - }, - { - "cell_type": "code", - "execution_count": 186, - "id": "8195e56b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CPU times: user 2.61 s, sys: 924 ms, total: 3.53 s\n", - "Wall time: 5.74 s\n" - ] - } - ], - "source": [ - "%%time\n", - "users = pd.read_csv(DATA_PATH / 'users.csv')\n", - "items = pd.read_csv(DATA_PATH / 'items.csv')\n", - "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 187, - "id": "01c2bdef", - "metadata": {}, - "outputs": [], - "source": [ - "Columns.Datetime = 'last_watch_dt'" - ] - }, - { - "cell_type": "markdown", - "id": "00b5584e", - "metadata": {}, - "source": [ - "# Preprocess Interactions" - ] - }, - { - "cell_type": "code", - "execution_count": 188, - "id": "0a3b4b12", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id last_watch_dt total_dur watched_pct\n0 176549 9506 2021-05-11 4250 72.0\n1 699317 1659 2021-05-29 8317 100.0\n2 656683 7107 2021-05-09 10 0.0\n3 864613 7638 2021-07-05 14483 100.0\n4 964868 9506 2021-04-30 6725 100.0", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
\n
" - }, - "execution_count": 188, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 189, - "id": "260b1c48", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "user_id int64\nitem_id int64\nlast_watch_dt object\ntotal_dur int64\nwatched_pct float64\ndtype: object" - }, - "execution_count": 189, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions.dtypes" - ] - }, - { - "cell_type": "code", - "execution_count": 190, - "id": "fe2dbc06", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "user_id 0\nitem_id 0\nlast_watch_dt 0\ntotal_dur 0\nwatched_pct 828\ndtype: int64" - }, - "execution_count": 190, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "interactions.isna().sum()" - ] - }, - { - "cell_type": "code", - "execution_count": 191, - "id": "71f61e81", - "metadata": {}, - "outputs": [], - "source": [ - "interactions[Columns.Datetime] = \\\n", - " pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')" - ] - }, - { - "cell_type": "code", - "execution_count": 192, - "id": "39646cb5", - "metadata": {}, - "outputs": [], - "source": [ - "interactions.dropna(inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 193, - "id": "f98ae95d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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\n" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "interactions['watched_pct'].hist(bins=20);" - ] - }, - { - "cell_type": "markdown", - "id": "1a0ad9f8", - "metadata": {}, - "source": [ - "Делю график просмотра на 5 категорий, где:\n", - "от 0% до 20% = 1,\n", - "от 21% до 40% = 2,\n", - "... ,\n", - "от 80% до 100% = 5" - ] - }, - { - "cell_type": "code", - "execution_count": 194, - "id": "1424e744", - "metadata": {}, - "outputs": [], - "source": [ - "interactions[Columns.Weight] = pd.cut(\n", - " x=interactions['watched_pct'],\n", - " bins=5,\n", - " labels=[1, 2, 3, 4, 5]\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 196, - "id": "052d2fb0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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\n" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "interactions[Columns.Datetime].hist(bins=20);" - ] - }, - { - "cell_type": "markdown", - "id": "5adb80ee", - "metadata": {}, - "source": [ - "Вообще, видно, что кол-во пользователей растет" - ] - }, - { - "cell_type": "code", - "execution_count": 197, - "id": "0fbd2bbc", - "metadata": {}, - "outputs": [], - "source": [ - "cold_users = \\\n", - " interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts() == 1].index" - ] - }, - { - "cell_type": "code", - "execution_count": 198, - "id": "150e1593", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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\n" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'\n", - " ].hist(bins=20);" - ] - }, - { - "cell_type": "markdown", - "id": "b5fa83eb", - "metadata": {}, - "source": [ - "Для холодных пользователей, я бы рекомендовал айтемы с самый высоким просмотром в среднем по холодным пользователям" - ] - }, - { - "cell_type": "code", - "execution_count": 199, - "id": "cca06e3f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n10 791466 8199 2021-07-27 713 9.0 1\n26 181144 10440 2021-08-08 27408 40.0 2\n37 161176 10440 2021-07-29 22 0.0 1\n38 21723 1819 2021-04-11 8535 100.0 5\n60 77216 8143 2021-05-08 660 11.0 1\n... ... ... ... ... ... ...\n5476222 1007900 9728 2021-08-12 416 6.0 1\n5476225 882138 4716 2021-05-21 1594 2.0 1\n5476238 805174 13125 2021-06-27 1 0.0 1\n5476246 648596 12225 2021-08-13 76 0.0 1\n5476248 697262 15297 2021-08-20 18307 63.0 4\n\n[355162 rows x 6 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n

355162 rows × 6 columns

\n
" - }, - "execution_count": 199, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users = interactions[interactions[Columns.User].isin(cold_users)]\n", - "hot_users = interactions[~interactions[Columns.User].isin(cold_users)]\n", - "cold_users" - ] - }, - { - "cell_type": "code", - "execution_count": 200, - "id": "a691676f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n0 176549 9506 2021-05-11 4250 72.0 4\n1 699317 1659 2021-05-29 8317 100.0 5\n2 656683 7107 2021-05-09 10 0.0 1\n3 864613 7638 2021-07-05 14483 100.0 5\n4 964868 9506 2021-04-30 6725 100.0 5\n... ... ... ... ... ... ...\n5476246 648596 12225 2021-08-13 76 0.0 1\n5476247 546862 9673 2021-04-13 2308 49.0 3\n5476248 697262 15297 2021-08-20 18307 63.0 4\n5476249 384202 16197 2021-04-19 6203 100.0 5\n5476250 319709 4436 2021-08-15 3921 45.0 3\n\n[5475423 rows x 6 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n

5475423 rows × 6 columns

\n
" - }, - "execution_count": 200, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hot_users" - ] - }, - { - "cell_type": "code", - "execution_count": 201, - "id": "a64701c2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " item_id\n10440 45695\n15297 39309\n2657 20474\n9728 15140\n4740 11455\n... ...\n1946 1\n13886 1\n14090 1\n5730 1\n13125 1\n\n[6440 rows x 1 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n

6440 rows × 1 columns

\n
" - }, - "execution_count": 201, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users['item_id'].value_counts().to_frame()" - ] - }, - { - "cell_type": "code", - "execution_count": 202, - "id": "cef9cfa6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" - }, - "execution_count": 202, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cold_users[['item_id', 'total_dur']].groupby('item_id').mean().sort_values(by='total_dur', ascending=False).head(10).index" - ] - }, - { - "cell_type": "markdown", - "id": "a52f311b", - "metadata": {}, - "source": [ - "# Делим на train и test" - ] - }, - { - "cell_type": "code", - "execution_count": 203, - "id": "bd68d3fe", - "metadata": {}, - "outputs": [], - "source": [ - "max_date = interactions[Columns.Datetime].max()" - ] - }, - { - "cell_type": "code", - "execution_count": 204, - "id": "3092fe4b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "train: (4984443, 6)\n", - "test: (490980, 6)\n" - ] - } - ], - "source": [ - "train = interactions[interactions[Columns.Datetime] < max_date\n", - " - pd.Timedelta(days=7)].copy()\n", - "test = interactions[interactions[Columns.Datetime] >= max_date\n", - " - pd.Timedelta(days=7)].copy()\n", - "\n", - "print(f\"train: {train.shape}\")\n", - "print(f\"test: {test.shape}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 205, - "id": "ec286bdc", - "metadata": {}, - "outputs": [], - "source": [ - "train.drop(train.query(\"total_dur < 300\").index, inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 206, - "id": "52241fed", - "metadata": {}, - "outputs": [], - "source": [ - "drop_user = set(test[Columns.User]) - set(train[Columns.User])\n", - "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" - ] - }, - { - "cell_type": "markdown", - "id": "b5eec6da", - "metadata": {}, - "source": [ - "## User preprocess" - ] - }, - { - "cell_type": "code", - "execution_count": 207, - "id": "c57e2b2f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id age income sex kids_flg\n0 973171 age_25_34 income_60_90 М 1\n1 962099 age_18_24 income_20_40 М 0\n2 1047345 age_45_54 income_40_60 Ж 0\n3 721985 age_45_54 income_20_40 Ж 0\n4 704055 age_35_44 income_60_90 Ж 0\n... ... ... ... ... ...\n840192 339025 age_65_inf income_0_20 Ж 0\n840193 983617 age_18_24 income_20_40 Ж 1\n840194 251008 NaN NaN NaN 0\n840195 590706 NaN NaN Ж 0\n840196 166555 age_65_inf income_20_40 Ж 0\n\n[840197 rows x 5 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n

840197 rows × 5 columns

\n
" - }, - "execution_count": 207, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "users" - ] - }, - { - "cell_type": "code", - "execution_count": 208, - "id": "24cc138a", - "metadata": {}, - "outputs": [], - "source": [ - "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 209, - "id": "6e5e2d92", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " user_id age income sex kids_flg\n0 973171 age_25_34 income_60_90 М 1\n1 962099 age_18_24 income_20_40 М 0\n3 721985 age_45_54 income_20_40 Ж 0\n4 704055 age_35_44 income_60_90 Ж 0\n5 1037719 age_45_54 income_60_90 М 0\n... ... ... ... .. ...\n840184 529394 age_25_34 income_40_60 Ж 0\n840186 80113 age_25_34 income_40_60 Ж 0\n840188 312839 age_65_inf income_60_90 Ж 0\n840189 191349 age_45_54 income_40_60 М 1\n840190 393868 age_25_34 income_20_40 М 0\n\n[586653 rows x 5 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
..................
840184529394age_25_34income_40_60Ж0
84018680113age_25_34income_40_60Ж0
840188312839age_65_infincome_60_90Ж0
840189191349age_45_54income_40_60М1
840190393868age_25_34income_20_40М0
\n

586653 rows × 5 columns

\n
" - }, - "execution_count": 209, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "users" - ] - }, - { - "cell_type": "markdown", - "id": "c7f9a6e7", - "metadata": {}, - "source": [ - "Заменяю Nan'ы на Unknown" - ] - }, - { - "cell_type": "code", - "execution_count": 210, - "id": "1286eb60", - "metadata": {}, - "outputs": [], - "source": [ - "users.fillna('Unknown', inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 211, - "id": "1ccccf0f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 973171 М sex\n1 962099 М sex\n3 721985 Ж sex\n4 704055 Ж sex\n5 1037719 М sex", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n
" - }, - "execution_count": 211, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_features_frames = []\n", - "for feature in ['sex', 'age', 'income']:\n", - " feature_frame = users.reindex(columns=[Columns.User, feature])\n", - " feature_frame.columns = ['id', 'value']\n", - " feature_frame['feature'] = feature\n", - " user_features_frames.append(feature_frame)\n", - "user_features = pd.concat(user_features_frames)\n", - "user_features.head()" - ] - }, - { - "cell_type": "markdown", - "id": "b9220b0b", - "metadata": {}, - "source": [ - "## Item preprocess" - ] - }, - { - "cell_type": "code", - "execution_count": 213, - "id": "8bbe9ee4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " item_id content_type title title_orig release_year \\\n0 10711 film Поговори с ней Hable con ella 2002.0 \n1 2508 film Голые перцы Search Party 2014.0 \n2 10716 film Тактическая сила Tactical Force 2011.0 \n3 7868 film 45 лет 45 Years 2015.0 \n4 16268 film Все решает мгновение NaN 1978.0 \n\n genres countries for_kids \\\n0 драмы, зарубежные, детективы, мелодрамы Испания NaN \n1 зарубежные, приключения, комедии США NaN \n2 криминал, зарубежные, триллеры, боевики, комедии Канада NaN \n3 драмы, зарубежные, мелодрамы Великобритания NaN \n4 драмы, спорт, советские, мелодрамы СССР NaN \n\n age_rating studios directors \\\n0 16.0 NaN Педро Альмодовар \n1 16.0 NaN Скот Армстронг \n2 16.0 NaN Адам П. Калтраро \n3 16.0 NaN Эндрю Хэй \n4 12.0 Ленфильм Виктор Садовский \n\n actors \\\n0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n4 Александр Абдулов, Александр Демьяненко, Алекс... \n\n description \\\n0 Мелодрама легендарного Педро Альмодовара «Пого... \n1 Уморительная современная комедия на популярную... \n2 Профессиональный рестлер Стив Остин («Все или ... \n3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n4 Расчетливая чаровница из советского кинохита «... \n\n keywords \n0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n4 Все, решает, мгновение, 1978, СССР, сильные, ж... ", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
\n
" - }, - "execution_count": 213, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 214, - "id": "72fa86a0", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": "item_id 0\ncontent_type 0\ntitle 0\ntitle_orig 4745\nrelease_year 98\ngenres 0\ncountries 37\nfor_kids 15397\nage_rating 2\nstudios 14898\ndirectors 1509\nactors 2619\ndescription 2\nkeywords 423\ndtype: int64" - }, - "execution_count": 214, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items.isna().sum()" - ] - }, - { - "cell_type": "code", - "execution_count": 215, - "id": "50f0611f", - "metadata": {}, - "outputs": [], - "source": [ - "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 216, - "id": "280cf47d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "item_id 0\ncontent_type 0\ntitle 0\ntitle_orig 3775\nrelease_year 31\ngenres 0\ncountries 14\nfor_kids 13415\nage_rating 1\nstudios 13047\ndirectors 939\nactors 1858\ndescription 0\nkeywords 388\ndtype: int64" - }, - "execution_count": 216, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items.isna().sum()" - ] - }, - { - "cell_type": "markdown", - "id": "eddd93b5", - "metadata": {}, - "source": [ - "## Genre" - ] - }, - { - "cell_type": "code", - "execution_count": 217, - "id": "bf6da75c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n
" - }, - "execution_count": 217, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Explode genres to flatten table\n", - "items['genre'] = items['genres'].str.lower().str.replace(', ', ',',\n", - " regex=False).str.split(',')\n", - "genre_feature = items[['item_id', 'genre']].explode('genre')\n", - "genre_feature.columns = ['id', 'value']\n", - "genre_feature['feature'] = 'genre'\n", - "genre_feature.head()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 218, - "id": "913b9c27", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre\n... ... ... ...\n15960 10632 криминал genre\n15961 4538 драмы genre\n15961 4538 спорт genre\n15961 4538 криминал genre\n15962 3206 комедии genre\n\n[36128 rows x 3 columns]", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n

36128 rows × 3 columns

\n
" - }, - "execution_count": 218, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "genre_feature" - ] - }, - { - "cell_type": "markdown", - "id": "478bf1e3", - "metadata": {}, - "source": [ - "## Content" - ] - }, - { - "cell_type": "code", - "execution_count": 220, - "id": "65f8b5d9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 film content_type\n1 2508 film content_type\n2 10716 film content_type\n3 7868 film content_type\n4 16268 film content_type", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
\n
" - }, - "execution_count": 220, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", - "content_feature.columns = [\"id\", \"value\"]\n", - "content_feature[\"feature\"] = \"content_type\"\n", - "content_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "a62ebee4", - "metadata": {}, - "source": [ - "## Actors" - ] - }, - { - "cell_type": "code", - "execution_count": 221, - "id": "fdc43660", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 адольфо фернандес actors\n0 10711 ана фернандес actors\n0 10711 дарио грандинетти actors\n0 10711 джеральдин чаплин actors\n0 10711 елена анайя actors", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
\n
" - }, - "execution_count": 221, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items['actors'] = items['actors'].str.lower().str.replace(', ', ',',\n", - " regex=False).str.split(',')\n", - "actors_feature = items[['item_id', 'actors']].explode('actors')\n", - "actors_feature.columns = ['id', 'value']\n", - "actors_feature['feature'] = 'actors'\n", - "actors_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "73801647", - "metadata": {}, - "source": [ - "## Keywords" - ] - }, - { - "cell_type": "code", - "execution_count": 222, - "id": "594abe5c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 поговори keywords\n0 10711 ней keywords\n0 10711 2002 keywords\n0 10711 испания keywords\n0 10711 друзья keywords", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
\n
" - }, - "execution_count": 222, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "items['keywords'] = items['keywords'].str.lower().str.replace(', ', ','\n", - " , regex=False).str.split(',')\n", - "keywords_feature = items[['item_id', 'keywords']].explode('keywords')\n", - "keywords_feature.columns = ['id', 'value']\n", - "keywords_feature['feature'] = 'keywords'\n", - "keywords_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "d3eb0a37", - "metadata": {}, - "source": [ - "## Countries" - ] - }, - { - "cell_type": "code", - "execution_count": 223, - "id": "8eb8a621", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 Испания countries\n1 2508 США countries\n2 10716 Канада countries\n3 7868 Великобритания countries\n4 16268 СССР countries", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
\n
" - }, - "execution_count": 223, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "country_feature = items.reindex(columns=[Columns.Item, 'countries'])\n", - "country_feature.columns = ['id', 'value']\n", - "country_feature['feature'] = 'countries'\n", - "country_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "5e477ee1", - "metadata": {}, - "source": [ - "## Age Rating" - ] - }, - { - "cell_type": "code", - "execution_count": 224, - "id": "0894154a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 16.0 age_feature\n1 2508 16.0 age_feature\n2 10716 16.0 age_feature\n3 7868 16.0 age_feature\n4 16268 12.0 age_feature", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
\n
" - }, - "execution_count": 224, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", - "age_feature.columns = [\"id\", \"value\"]\n", - "age_feature[\"feature\"] = \"age_feature\"\n", - "age_feature.head()" - ] - }, - { - "cell_type": "markdown", - "id": "c09df1ec", - "metadata": {}, - "source": [ - "## Studios" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "ff937b4f", - "metadata": {}, - "outputs": [], - "source": [ - "items.fillna('Unknown', inplace=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 225, - "id": "cee42708", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 NaN studios\n1 2508 NaN studios\n2 10716 NaN studios\n3 7868 NaN studios\n4 16268 Ленфильм studios", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711NaNstudios
12508NaNstudios
210716NaNstudios
37868NaNstudios
416268Ленфильмstudios
\n
" - }, - "execution_count": 225, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", - "studios_feature.columns = [\"id\", \"value\"]\n", - "studios_feature[\"feature\"] = \"studios\"\n", - "studios_feature.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 226, - "id": "7234f13b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": " id value feature\n0 10711 драмы genre\n0 10711 зарубежные genre\n0 10711 детективы genre\n0 10711 мелодрамы genre\n1 2508 зарубежные genre", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n
" - }, - "execution_count": 226, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# studios_feature, age_feature, country_feature - фичи которые хотелось бы использовать,\n", - "# но длительность обучения \"OPTUNA\" увеличивается в разы\n", - "item_features = pd.concat((genre_feature, content_feature ))\n", - "item_features.head()" - ] - }, - { - "cell_type": "markdown", - "id": "09b8d756", - "metadata": {}, - "source": [ - "## Metrics" - ] - }, - { - "cell_type": "code", - "execution_count": 227, - "id": "b082e667", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": "{'Precision@1': Precision(k=1),\n 'Precision@2': Precision(k=2),\n 'Precision@3': Precision(k=3),\n 'Precision@4': Precision(k=4),\n 'Precision@5': Precision(k=5),\n 'Precision@6': Precision(k=6),\n 'Precision@7': Precision(k=7),\n 'Precision@8': Precision(k=8),\n 'Precision@9': Precision(k=9),\n 'Precision@10': Precision(k=10),\n 'Recall@1': Recall(k=1),\n 'Recall@2': Recall(k=2),\n 'Recall@3': Recall(k=3),\n 'Recall@4': Recall(k=4),\n 'Recall@5': Recall(k=5),\n 'Recall@6': Recall(k=6),\n 'Recall@7': Recall(k=7),\n 'Recall@8': Recall(k=8),\n 'Recall@9': Recall(k=9),\n 'Recall@10': Recall(k=10),\n 'MAP@1': MAP(k=1, divide_by_k=False),\n 'MAP@2': MAP(k=2, divide_by_k=False),\n 'MAP@3': MAP(k=3, divide_by_k=False),\n 'MAP@4': MAP(k=4, divide_by_k=False),\n 'MAP@5': MAP(k=5, divide_by_k=False),\n 'MAP@6': MAP(k=6, divide_by_k=False),\n 'MAP@7': MAP(k=7, divide_by_k=False),\n 'MAP@8': MAP(k=8, divide_by_k=False),\n 'MAP@9': MAP(k=9, divide_by_k=False),\n 'MAP@10': MAP(k=10, divide_by_k=False)}" - }, - "execution_count": 227, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "metrics_name = {\n", - " 'Precision': Precision,\n", - " 'Recall': Recall,\n", - " 'MAP': MAP,\n", - "}\n", - "\n", - "metrics = {}\n", - "for metric_name, metric in metrics_name.items():\n", - " for k in range(1, 11):\n", - " metrics[f'{metric_name}@{k}'] = metric(k=k)\n", - "metrics" - ] - }, - { - "cell_type": "markdown", - "id": "2c603783", - "metadata": {}, - "source": [ - "# Optuna\n", - "\n", - "Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", - "Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)" - ] - }, - { - "cell_type": "code", - "execution_count": 229, - "id": "fb193c2f", - "metadata": {}, - "outputs": [], - "source": [ - "NUM_THREADS = 8\n", - "RANDOM_STATE = 42\n", - "K = 5\n", - "NO_COMPONENTS = 32\n", - "N_EPOCHS = 1" - ] - }, - { - "cell_type": "code", - "execution_count": 230, - "id": "3328645d", - "metadata": {}, - "outputs": [], - "source": [ - "USER_ALPHA = 0\n", - "ITEM_ALPHA = 0\n", - "K_RECOS = 10" - ] - }, - { - "cell_type": "code", - "execution_count": 231, - "outputs": [], - "source": [ - "dataset = Dataset.construct(interactions_df=train,\n", - " user_features_df=user_features,\n", - " cat_user_features=['sex', 'age', 'income'],\n", - " item_features_df=item_features,\n", - " cat_item_features=['content_type', 'genre'])\n", - "TEST_USERS = test[Columns.User].unique()" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "a17b8b66", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:32:01,241]\u001B[0m A new study created in memory with name: no-name-d2c12238-d18d-4c6f-bca4-840e7d3f29b0\u001B[0m\n", - "\u001B[32m[I 2022-12-12 18:41:40,178]\u001B[0m Trial 0 finished with value: 0.07156314077881751 and parameters: {'recomender': 'ALS', 'regularization': 0.0035671951579306937}. Best is trial 0 with value: 0.07156314077881751.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07156314077881751\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:51:48,671]\u001B[0m Trial 1 finished with value: 0.07241639094290958 and parameters: {'recomender': 'ALS', 'regularization': 0.006724126527816994}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07241639094290958\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:53:18,697]\u001B[0m Trial 2 finished with value: 1.4050149479540313e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8190152272980945, 'k': 6, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 1.4050149479540313e-07\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:54:36,340]\u001B[0m Trial 3 finished with value: 0.005366068762176463 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.18723291153626603, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.005366068762176463\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 18:56:21,781]\u001B[0m Trial 4 finished with value: 0.0002205827579874263 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.6560234930178588, 'k': 6, 'loss': 'logistic'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.0002205827579874263\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:05:46,138]\u001B[0m Trial 5 finished with value: 0.07173988822226253 and parameters: {'recomender': 'ALS', 'regularization': 0.009044651486228098}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07173988822226253\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:07:05,748]\u001B[0m Trial 6 finished with value: 3.943062688880311e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.44751878244334975, 'k': 7, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 3.943062688880311e-06\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:08:22,099]\u001B[0m Trial 7 finished with value: 0.06793721324055035 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.10438302844592218, 'k': 3, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.06793721324055035\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:17:32,898]\u001B[0m Trial 8 finished with value: 0.07184311920591484 and parameters: {'recomender': 'ALS', 'regularization': 0.0005806772800434514}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07184311920591484\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:18:59,268]\u001B[0m Trial 9 finished with value: 2.2409988419866796e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.805131840226543, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 2.2409988419866796e-06\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:28:09,202]\u001B[0m Trial 10 finished with value: 0.07180954187357708 and parameters: {'recomender': 'ALS', 'regularization': 0.008190821633209066}. Best is trial 1 with value: 0.07241639094290958.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07180954187357708\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:37:15,147]\u001B[0m Trial 11 finished with value: 0.07244222251339615 and parameters: {'recomender': 'ALS', 'regularization': 0.00026970098377155163}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07244222251339615\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:46:24,260]\u001B[0m Trial 12 finished with value: 0.07202031081710311 and parameters: {'recomender': 'ALS', 'regularization': 0.0066363513358619185}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07202031081710311\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 19:55:34,176]\u001B[0m Trial 13 finished with value: 0.07199398893026046 and parameters: {'recomender': 'ALS', 'regularization': 0.004156107607150058}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07199398893026046\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:04:42,589]\u001B[0m Trial 14 finished with value: 0.07167963259586223 and parameters: {'recomender': 'ALS', 'regularization': 0.0006228566403390988}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07167963259586223\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:13:49,348]\u001B[0m Trial 15 finished with value: 0.07202106855494453 and parameters: {'recomender': 'ALS', 'regularization': 0.00598705937836684}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07202106855494453\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:22:57,770]\u001B[0m Trial 16 finished with value: 0.07193963920172777 and parameters: {'recomender': 'ALS', 'regularization': 0.0028834604694796696}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07193963920172777\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:32:04,614]\u001B[0m Trial 17 finished with value: 0.07186249836889418 and parameters: {'recomender': 'ALS', 'regularization': 0.007249626991281137}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07186249836889418\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:41:24,258]\u001B[0m Trial 18 finished with value: 0.07164870366757094 and parameters: {'recomender': 'ALS', 'regularization': 0.005115162467576984}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07164870366757094\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 20:50:49,059]\u001B[0m Trial 19 finished with value: 0.07179004415938793 and parameters: {'recomender': 'ALS', 'regularization': 0.0018963762834092678}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07179004415938793\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 21:42:16,853]\u001B[0m Trial 20 finished with value: 0.07167129296212232 and parameters: {'recomender': 'ALS', 'regularization': 0.009804091535656343}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07167129296212232\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 21:52:20,413]\u001B[0m Trial 21 finished with value: 0.07191839766465505 and parameters: {'recomender': 'ALS', 'regularization': 0.005764203522687446}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07191839766465505\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:02:12,773]\u001B[0m Trial 22 finished with value: 0.07159025974450188 and parameters: {'recomender': 'ALS', 'regularization': 0.006209360331833826}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07159025974450188\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:12:55,936]\u001B[0m Trial 23 finished with value: 0.07167021208897958 and parameters: {'recomender': 'ALS', 'regularization': 0.007825089420401029}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07167021208897958\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:23:04,762]\u001B[0m Trial 24 finished with value: 0.07191850988173716 and parameters: {'recomender': 'ALS', 'regularization': 0.004979324924695012}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07191850988173716\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:34:38,654]\u001B[0m Trial 25 finished with value: 0.07178449755342503 and parameters: {'recomender': 'ALS', 'regularization': 0.002381286135370409}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07178449755342503\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:45:43,850]\u001B[0m Trial 26 finished with value: 0.07177449403191542 and parameters: {'recomender': 'ALS', 'regularization': 0.004677821831829}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07177449403191542\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 22:56:45,636]\u001B[0m Trial 27 finished with value: 0.07214439856613958 and parameters: {'recomender': 'ALS', 'regularization': 0.0069504676367203744}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07214439856613958\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 23:08:13,361]\u001B[0m Trial 28 finished with value: 0.07237690498752612 and parameters: {'recomender': 'ALS', 'regularization': 0.0074561399301387955}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07237690498752612\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m[I 2022-12-12 23:18:05,878]\u001B[0m Trial 29 finished with value: 0.07173589378156864 and parameters: {'recomender': 'ALS', 'regularization': 0.00848249465326267}. Best is trial 11 with value: 0.07244222251339615.\u001B[0m\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MAP@10 0.07173589378156864\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[33m[W 2022-12-12 23:27:26,180]\u001B[0m Trial 30 failed because of the following error: KeyboardInterrupt()\u001B[0m\n", - "Traceback (most recent call last):\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", - " value_or_values = func(trial)\n", - " File \"/tmp/ipykernel_5286/352742220.py\", line 40, in objective\n", - " recos = model.recommend(\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\", line 132, in recommend\n", - " reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 141, in _recommend_u2i\n", - " scores = scores_calculator.calc(target_id)\n", - " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 98, in calc\n", - " scores = self.objects_factors @ subject_factors\n", - "KeyboardInterrupt\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", - "\u001B[0;32m/tmp/ipykernel_5286/352742220.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 48\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 49\u001B[0m \u001B[0mstudy\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0moptuna\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcreate_study\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mdirection\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m'maximize'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 50\u001B[0;31m \u001B[0mstudy\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0moptimize\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mobjective\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mn_trials\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;36m100\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001B[0m in \u001B[0;36moptimize\u001B[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 417\u001B[0m \"\"\"\n\u001B[1;32m 418\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 419\u001B[0;31m _optimize(\n\u001B[0m\u001B[1;32m 420\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 421\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_optimize\u001B[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001B[0m\n\u001B[1;32m 64\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 65\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mn_jobs\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0;36m1\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 66\u001B[0;31m _optimize_sequential(\n\u001B[0m\u001B[1;32m 67\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 68\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_optimize_sequential\u001B[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001B[0m\n\u001B[1;32m 158\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 159\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 160\u001B[0;31m \u001B[0mfrozen_trial\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0m_run_trial\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mstudy\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcatch\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 161\u001B[0m \u001B[0;32mfinally\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 162\u001B[0m \u001B[0;31m# The following line mitigates memory problems that can be occurred in some\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 232\u001B[0m \u001B[0;32mand\u001B[0m \u001B[0;32mnot\u001B[0m \u001B[0misinstance\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mfunc_err\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mcatch\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 233\u001B[0m ):\n\u001B[0;32m--> 234\u001B[0;31m \u001B[0;32mraise\u001B[0m \u001B[0mfunc_err\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 235\u001B[0m \u001B[0;32mreturn\u001B[0m \u001B[0mfrozen_trial\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 236\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001B[0m in \u001B[0;36m_run_trial\u001B[0;34m(study, func, catch)\u001B[0m\n\u001B[1;32m 194\u001B[0m \u001B[0;32mwith\u001B[0m \u001B[0mget_heartbeat_thread\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtrial\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_trial_id\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mstudy\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_storage\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 195\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 196\u001B[0;31m \u001B[0mvalue_or_values\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mfunc\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtrial\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 197\u001B[0m \u001B[0;32mexcept\u001B[0m \u001B[0mexceptions\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mTrialPruned\u001B[0m \u001B[0;32mas\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 198\u001B[0m \u001B[0;31m# TODO(mamu): Handle multi-objective cases.\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m/tmp/ipykernel_5286/352742220.py\u001B[0m in \u001B[0;36mobjective\u001B[0;34m(trial)\u001B[0m\n\u001B[1;32m 38\u001B[0m fit_features_together=True)\n\u001B[1;32m 39\u001B[0m \u001B[0mmodel\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mfit\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mdataset\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 40\u001B[0;31m recos = model.recommend(\n\u001B[0m\u001B[1;32m 41\u001B[0m \u001B[0musers\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mTEST_USERS\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 42\u001B[0m \u001B[0mdataset\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mdataset\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001B[0m in \u001B[0;36mrecommend\u001B[0;34m(self, users, dataset, k, filter_viewed, items_to_recommend, add_rank_col)\u001B[0m\n\u001B[1;32m 130\u001B[0m \u001B[0msorted_item_ids_to_recommend\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;32mNone\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 131\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 132\u001B[0;31m reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n\u001B[0m\u001B[1;32m 133\u001B[0m \u001B[0muser_ids\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 134\u001B[0m \u001B[0mdataset\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001B[0m in \u001B[0;36m_recommend_u2i\u001B[0;34m(self, user_ids, dataset, k, filter_viewed, sorted_item_ids_to_recommend)\u001B[0m\n\u001B[1;32m 139\u001B[0m \u001B[0mall_scores\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0mtp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mList\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mndarray\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m[\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 140\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mtarget_id\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mtqdm\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0muser_ids\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mdisable\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mverbose\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0;36m0\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 141\u001B[0;31m \u001B[0mscores\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mscores_calculator\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcalc\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtarget_id\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 142\u001B[0m reco_ids, reco_scores = recommend_from_scores(\n\u001B[1;32m 143\u001B[0m \u001B[0mscores\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mscores\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001B[0m in \u001B[0;36mcalc\u001B[0;34m(self, subject_id)\u001B[0m\n\u001B[1;32m 96\u001B[0m \u001B[0msubject_factors\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msubjects_factors\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0msubject_id\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 97\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdistance\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0mDistance\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mDOT\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 98\u001B[0;31m \u001B[0mscores\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mobjects_factors\u001B[0m \u001B[0;34m@\u001B[0m \u001B[0msubject_factors\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 99\u001B[0m \u001B[0;32melif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdistance\u001B[0m \u001B[0;34m==\u001B[0m \u001B[0mDistance\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mEUCLIDEAN\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 100\u001B[0m \u001B[0msubject_dot\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msubjects_dots\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0msubject_id\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;31mKeyboardInterrupt\u001B[0m: " - ] - } - ], - "source": [ - "def objective(trial):\n", - " model_name = trial.suggest_categorical('recomender', ['LightFM',\n", - " 'ALS'])\n", - " if model_name == 'LightFM':\n", - " learning_rate = trial.suggest_float('learning_rate', 1e-10, 1)\n", - " k = trial.suggest_int('k', 2, 10)\n", - " loss = trial.suggest_categorical('loss', ['logistic', 'bpr',\n", - " 'warp'])\n", - " model = LightFMWrapperModel(LightFM(k=k,\n", - " learning_rate=learning_rate,\n", - " loss=loss, no_components=10),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS)\n", - " else:\n", - " regularization = trial.suggest_float('regularization', 1e-4,\n", - " 1e-2)\n", - " model = \\\n", - " ImplicitALSWrapperModel(model=AlternatingLeastSquares(factors=10,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=regularization),\n", - " fit_features_together=True)\n", - " model.fit(dataset)\n", - " recos = model.recommend(users=TEST_USERS, dataset=dataset,\n", - " k=K_RECOS, filter_viewed=True)\n", - " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", - " print ('MAP@10', metric)\n", - " return metric\n", - "\n", - "\n", - "study = optuna.create_study(direction='maximize')\n", - "study.optimize(objective, n_trials=100)" - ] - }, - { - "cell_type": "markdown", - "id": "3989645b", - "metadata": {}, - "source": [ - "## Пришлось остановить обучение, тк эти 30 эпох обучались 6 часов" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "99aae61e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'recomender': 'ALS', 'regularization': 0.00026970098377155163}" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "study.best_params" - ] - }, - { - "cell_type": "code", - "execution_count": 233, - "outputs": [], - "source": [ - "REGULARIZATION = 0.00026970098377155163" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 234, - "id": "d1f6069a", - "metadata": {}, - "outputs": [], - "source": [ - "# обучаем best model после optuna\n", - "model = ImplicitALSWrapperModel(\n", - " model=AlternatingLeastSquares(\n", - " factors=32,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=REGULARIZATION\n", - " ),\n", - " fit_features_together=True\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 236, - "id": "d3907c1d", - "metadata": {}, - "outputs": [], - "source": [ - "model.fit(dataset)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b2050a6e", - "metadata": {}, - "outputs": [], - "source": [ - "recos = model.recommend(\n", - " users=TEST_USERS,\n", - " dataset=dataset,\n", - " k=K_RECOS,\n", - " filter_viewed=True\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "6bbe3ff3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.07124010116092815" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "calc_metrics(metrics, recos, test, train)['MAP@10']" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "d3eead34", - "metadata": {}, - "outputs": [], - "source": [ - "recos = recos[['user_id', 'item_id']]\n", - "recos.to_csv('ALS_after_optuna.csv.gz', index=False, compression='gzip')" - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Добавление аватаров\n", - "Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 264, - "outputs": [], - "source": [ - "some_avatars = pd.DataFrame(\n", - " {\n", - " Columns.User: [11111111, 11111112, 11111113],\n", - " Columns.Item: [\n", - " [10732, 3369, 15885], # Аватар, который любит мультики [губка боб, кунг-фу панда, ]\n", - " [3506, 1107, 11235], # Аватар, который любит боевики [форсаж, обитель зла, плохие парни]\n", - " [931, 389, 8315] # Аватар, который любит драмы [после, хатико, сумерки]\n", - " ],\n", - " 'last_watch_dt': [\n", - " [random.choice(sorted(interactions.last_watch_dt.unique())[-10:]) for _ in range(3)] for i in range(3)\n", - " ],\n", - " \"total_dur\": [\n", - " [34343, 6000, 9000],\n", - " [5000, 45452, 9000],\n", - " [5000, 3200, 3232]\n", - " ],\n", - " \"watched_pct\": [\n", - " [100.0, 95.0, 99.0],\n", - " [67.0, 95.0, 99.0],\n", - " [100.0, 53.0, 99.0]\n", - " ],\n", - " Columns.Weight: [\n", - " [5, 5, 5],\n", - " [3, 5, 5],\n", - " [5, 2, 5]\n", - " ]\n", - " }\n", - ")\n", - "\n", - "some_avatars = some_avatars.explode(\n", - " [Columns.Item, Columns.Datetime, \"total_dur\", \"watched_pct\", Columns.Weight]\n", - ").reset_index(drop=True)" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 265, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id last_watch_dt total_dur watched_pct weight\n0 11111111 10732 2021-08-22 34343 100.0 5\n1 11111111 3369 2021-08-19 6000 95.0 5\n2 11111111 15885 2021-08-17 9000 99.0 5\n3 11111112 3506 2021-08-20 5000 67.0 3\n4 11111112 1107 2021-08-14 45452 95.0 5\n5 11111112 11235 2021-08-19 9000 99.0 5\n6 11111113 931 2021-08-14 5000 100.0 5\n7 11111113 389 2021-08-19 3200 53.0 2\n8 11111113 8315 2021-08-22 3232 99.0 5", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idlast_watch_dttotal_durwatched_pctweight
011111111107322021-08-2234343100.05
11111111133692021-08-19600095.05
211111111158852021-08-17900099.05
31111111235062021-08-20500067.03
41111111211072021-08-144545295.05
511111112112352021-08-19900099.05
6111111139312021-08-145000100.05
7111111133892021-08-19320053.02
81111111383152021-08-22323299.05
\n
" - }, - "execution_count": 265, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "some_avatars" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 266, - "outputs": [], - "source": [ - "interactions_with_avatars = pd.concat([interactions, some_avatars])\n", - "\n", - "dataset_with_avatars = Dataset.construct(\n", - " interactions_df=interactions_with_avatars,\n", - ")\n", - "\n", - "# обучаем best model после optuna\n", - "model_with_avatars = ImplicitALSWrapperModel(\n", - " model=AlternatingLeastSquares(\n", - " factors=32,\n", - " random_state=RANDOM_STATE,\n", - " num_threads=NUM_THREADS,\n", - " regularization=REGULARIZATION\n", - " ),\n", - " fit_features_together=True\n", - ")" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 267, - "outputs": [ - { - "data": { - "text/plain": "" - }, - "execution_count": 267, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model_with_avatars.fit(dataset_with_avatars)" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 268, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id score rank\n0 11111111 11985 0.040700 1\n1 11111111 2954 0.039466 2\n2 11111111 7310 0.036591 3\n3 11111111 3182 0.035423 4\n4 11111111 4475 0.034422 5\n5 11111112 7793 0.035639 1\n6 11111112 4702 0.035139 2\n7 11111112 16361 0.034857 3\n8 11111112 1287 0.034327 4\n9 11111112 11018 0.032349 5\n10 11111113 1916 0.245655 1\n11 11111113 14470 0.242786 2\n12 11111113 101 0.219231 3\n13 11111113 12463 0.206615 4\n14 11111113 5732 0.183012 5", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idscorerank
011111111119850.0407001
11111111129540.0394662
21111111173100.0365913
31111111131820.0354234
41111111144750.0344225
51111111277930.0356391
61111111247020.0351392
711111112163610.0348573
81111111212870.0343274
911111112110180.0323495
101111111319160.2456551
1111111113144700.2427862
12111111131010.2192313
1311111113124630.2066154
141111111357320.1830125
\n
" - }, - "execution_count": 268, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "recos_with_avatars = model_with_avatars.recommend(\n", - " users=[11111111, 11111112, 11111113],\n", - " dataset=dataset_with_avatars,\n", - " k=5,\n", - " filter_viewed=True\n", - ")\n", - "recos_with_avatars" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": 269, - "outputs": [ - { - "data": { - "text/plain": " user_id item_id score rank content_type title \\\n0 11111111 11985 0.040700 1 film История игрушек 4 \n1 11111111 2954 0.039466 2 film Миньоны \n2 11111111 7310 0.036591 3 film Гадкий я 2 \n3 11111111 3182 0.035423 4 film Ральф против Интернета \n4 11111111 4475 0.034422 5 film Тачки \n5 11111112 7793 0.035639 1 film Радиовспышка \n6 11111112 4702 0.035139 2 film Хищник \n7 11111112 16361 0.034857 3 film Doom: Аннигиляция \n8 11111112 1287 0.034327 4 film Терминатор: Тёмные судьбы \n9 11111112 11018 0.032349 5 film Хищники \n10 11111113 1916 0.245655 1 film Секс и ничего лишнего \n11 11111113 14470 0.242786 2 film Любовь \n12 11111113 101 0.219231 3 film Куриоса \n13 11111113 12463 0.206615 4 film Студентка по вызову \n14 11111113 5732 0.183012 5 film Тайное влечение \n\n title_orig release_year \\\n0 Toy Story 4 2019.0 \n1 Minions 2015.0 \n2 Despicable Me 2 2013.0 \n3 Ralph Breaks the Internet 2018.0 \n4 Cars 2006.0 \n5 Radioflash 2019.0 \n6 Predator 1987.0 \n7 Doom: Annihilation 2019.0 \n8 Terminator: Dark Fate 2019.0 \n9 Predators 2010.0 \n10 My Awkward Sexual Adventure 2012.0 \n11 Love 2015.0 \n12 Curiosa 2019.0 \n13 Mes chères études 2010.0 \n14 Adore 2013.0 \n\n genres countries \\\n0 мультфильм, фэнтези, комедии США \n1 фантастика, мультфильм, приключения, комедии США \n2 мультфильм, приключения, фантастика, фэнтези, ... США, Франция, Япония \n3 мультфильм, приключения, фантастика, семейное,... США \n4 спорт, мультфильм, комедии США \n5 боевики, драмы, фантастика, триллеры США \n6 боевики, фантастика, триллеры, приключения США, Мексика \n7 боевики, ужасы, фантастика, триллеры США \n8 боевики, фантастика, приключения США, Китай \n9 боевики, фантастика, триллеры, приключения США \n10 мелодрамы Канада \n11 драмы, мелодрамы Франция \n12 историческое, мелодрамы Франция \n13 драмы, мелодрамы Франция \n14 драмы, мелодрамы Австралия, Франция \n\n for_kids age_rating studios directors \\\n0 NaN 6.0 NaN Джош Кули \n1 NaN 6.0 NaN Кайл Балда, Пьер Коффан \n2 NaN 0.0 NaN Пьер Коффан, Крис Рено \n3 NaN 6.0 NaN Рич Мур, Фил Джонстон \n4 NaN 6.0 NaN Джон Лассетер, Джо Рэнфт \n5 NaN 16.0 NaN Бен Макферсон \n6 NaN 16.0 NaN Джон МакТирнан \n7 NaN 18.0 NaN Тони Гиглио \n8 NaN 16.0 NaN Тим Миллер \n9 NaN 16.0 NaN Нимрод Антал \n10 NaN 18.0 NaN Шон Гэррити \n11 NaN 18.0 NaN Гаспар Ноэ \n12 NaN 18.0 NaN Лу Жене \n13 NaN 18.0 NaN Эмманюэль Берко \n14 NaN 16.0 NaN Анн Фонтен \n\n actors \\\n0 [том хэнкс, тим аллен, энни поттс, тони хейл, ... \n1 [сандра буллок, джон хэмм, майкл китон, эллисо... \n2 [стив карелл, кристен уиг, бенджамин брэтт, ми... \n3 [джон си райли, сара силверман, галь гадот, та... \n4 [оуэн уилсон, пол ньюман, бонни хант, ларри-ка... \n5 [брайтон шарбино, доминик монахэн, уилл пэттон... \n6 [арнольд шварценеггер, карл уэзерс, эльпидия к... \n7 [эми мэнсон, доминик мафэм, люк аллен-гейл, дж... \n8 [линда хэмилтон, арнольд шварценеггер, маккенз... \n9 [эдриан броуди, тофер грейс, алиси брага, уолт... \n10 [джонас черник, эмили хэмпшир, сара мэннинен, ... \n11 [аоми муйок, карл глусман, клара кристин, уго ... \n12 [ноэми мерлан, нильс шнайдер, бенжамен лаверн,... \n13 [дебора франсуа, ален коши, матье деми, бенжам... \n14 [наоми уоттс, робин райт, завьер сэмюэл, джейм... \n\n description \\\n0 Космический рейнджер Баз Лайтер, ковбой Вуди, ... \n1 Миньоны живут на планете гораздо дольше нас. У... \n2 В то время как Грю, бывший суперзлодей, приспо... \n3 На этот раз Ральф и Ванилопа фон Кекс выйдут з... \n4 Неукротимый в своем желании всегда и во всем п... \n5 Риз с легкостью проходит виртуальные квесты, н... \n6 Американский вертолет был сбит партизанами в Ю... \n7 Отряд морпехов прилетает на марсианский спутни... \n8 Мексика. Милая девушка Даниэла Рамос, а для др... \n9 Наемник Ройс невольно вынужден возглавить груп... \n10 Чтобы вернуть свою неудовлетворенную бывшую де... \n11 Любовь вне добра и зла. Любовь — это генетичес... \n12 Историческая драма про любовный треугольник, к... \n13 Лаура — 19-летняя первокурсница французского у... \n14 Главные героини картины – Лил и Роз — две давн... \n\n keywords \\\n0 [игрушка, дружба, ковбой, история игрушек 4, ,... \n1 [помощник, сцена после титров, сцена во время ... \n2 [отношения родитель-ребенок, секретный агент, ... \n3 [видеоигра, мультфильм, продолжение, интернет,... \n4 [автомобильная гонка, трасса 66, porsche, выхо... \n5 [2019, соединенные штаты, радиовспышка] \n6 [центральная и южная америка, хищник, иноплане... \n7 [планета марс, ад, космос, демон, по мотивам в... \n8 [искуственный интеллект, киборг, вертолет, мех... \n9 [охотник, хищник, якудза, охота на людей, иноп... \n10 [нижнее белье, массажистка, секс втроем, фалло... \n11 [париж, франция, секс, сексуальность, галерея,... \n12 [, 1890-е, большой пенис, брак без секса, вдох... \n13 [франция, гостиница, по роману или книге, гост... \n14 [пляж, нагота, любовники, месть, лучший друг, ... \n\n genre \n0 [мультфильм, фэнтези, комедии] \n1 [фантастика, мультфильм, приключения, комедии] \n2 [мультфильм, приключения, фантастика, фэнтези,... \n3 [мультфильм, приключения, фантастика, семейное... \n4 [спорт, мультфильм, комедии] \n5 [боевики, драмы, фантастика, триллеры] \n6 [боевики, фантастика, триллеры, приключения] \n7 [боевики, ужасы, фантастика, триллеры] \n8 [боевики, фантастика, приключения] \n9 [боевики, фантастика, триллеры, приключения] \n10 [мелодрамы] \n11 [драмы, мелодрамы] \n12 [историческое, мелодрамы] \n13 [драмы, мелодрамы] \n14 [драмы, мелодрамы] ", - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
user_iditem_idscorerankcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywordsgenre
011111111119850.0407001filmИстория игрушек 4Toy Story 42019.0мультфильм, фэнтези, комедииСШАNaN6.0NaNДжош Кули[том хэнкс, тим аллен, энни поттс, тони хейл, ...Космический рейнджер Баз Лайтер, ковбой Вуди, ...[игрушка, дружба, ковбой, история игрушек 4, ,...[мультфильм, фэнтези, комедии]
11111111129540.0394662filmМиньоныMinions2015.0фантастика, мультфильм, приключения, комедииСШАNaN6.0NaNКайл Балда, Пьер Коффан[сандра буллок, джон хэмм, майкл китон, эллисо...Миньоны живут на планете гораздо дольше нас. У...[помощник, сцена после титров, сцена во время ...[фантастика, мультфильм, приключения, комедии]
21111111173100.0365913filmГадкий я 2Despicable Me 22013.0мультфильм, приключения, фантастика, фэнтези, ...США, Франция, ЯпонияNaN0.0NaNПьер Коффан, Крис Рено[стив карелл, кристен уиг, бенджамин брэтт, ми...В то время как Грю, бывший суперзлодей, приспо...[отношения родитель-ребенок, секретный агент, ...[мультфильм, приключения, фантастика, фэнтези,...
31111111131820.0354234filmРальф против ИнтернетаRalph Breaks the Internet2018.0мультфильм, приключения, фантастика, семейное,...СШАNaN6.0NaNРич Мур, Фил Джонстон[джон си райли, сара силверман, галь гадот, та...На этот раз Ральф и Ванилопа фон Кекс выйдут з...[видеоигра, мультфильм, продолжение, интернет,...[мультфильм, приключения, фантастика, семейное...
41111111144750.0344225filmТачкиCars2006.0спорт, мультфильм, комедииСШАNaN6.0NaNДжон Лассетер, Джо Рэнфт[оуэн уилсон, пол ньюман, бонни хант, ларри-ка...Неукротимый в своем желании всегда и во всем п...[автомобильная гонка, трасса 66, porsche, выхо...[спорт, мультфильм, комедии]
51111111277930.0356391filmРадиовспышкаRadioflash2019.0боевики, драмы, фантастика, триллерыСШАNaN16.0NaNБен Макферсон[брайтон шарбино, доминик монахэн, уилл пэттон...Риз с легкостью проходит виртуальные квесты, н...[2019, соединенные штаты, радиовспышка][боевики, драмы, фантастика, триллеры]
61111111247020.0351392filmХищникPredator1987.0боевики, фантастика, триллеры, приключенияСША, МексикаNaN16.0NaNДжон МакТирнан[арнольд шварценеггер, карл уэзерс, эльпидия к...Американский вертолет был сбит партизанами в Ю...[центральная и южная америка, хищник, иноплане...[боевики, фантастика, триллеры, приключения]
711111112163610.0348573filmDoom: АннигиляцияDoom: Annihilation2019.0боевики, ужасы, фантастика, триллерыСШАNaN18.0NaNТони Гиглио[эми мэнсон, доминик мафэм, люк аллен-гейл, дж...Отряд морпехов прилетает на марсианский спутни...[планета марс, ад, космос, демон, по мотивам в...[боевики, ужасы, фантастика, триллеры]
81111111212870.0343274filmТерминатор: Тёмные судьбыTerminator: Dark Fate2019.0боевики, фантастика, приключенияСША, КитайNaN16.0NaNТим Миллер[линда хэмилтон, арнольд шварценеггер, маккенз...Мексика. Милая девушка Даниэла Рамос, а для др...[искуственный интеллект, киборг, вертолет, мех...[боевики, фантастика, приключения]
911111112110180.0323495filmХищникиPredators2010.0боевики, фантастика, триллеры, приключенияСШАNaN16.0NaNНимрод Антал[эдриан броуди, тофер грейс, алиси брага, уолт...Наемник Ройс невольно вынужден возглавить груп...[охотник, хищник, якудза, охота на людей, иноп...[боевики, фантастика, триллеры, приключения]
101111111319160.2456551filmСекс и ничего лишнегоMy Awkward Sexual Adventure2012.0мелодрамыКанадаNaN18.0NaNШон Гэррити[джонас черник, эмили хэмпшир, сара мэннинен, ...Чтобы вернуть свою неудовлетворенную бывшую де...[нижнее белье, массажистка, секс втроем, фалло...[мелодрамы]
1111111113144700.2427862filmЛюбовьLove2015.0драмы, мелодрамыФранцияNaN18.0NaNГаспар Ноэ[аоми муйок, карл глусман, клара кристин, уго ...Любовь вне добра и зла. Любовь — это генетичес...[париж, франция, секс, сексуальность, галерея,...[драмы, мелодрамы]
12111111131010.2192313filmКуриосаCuriosa2019.0историческое, мелодрамыФранцияNaN18.0NaNЛу Жене[ноэми мерлан, нильс шнайдер, бенжамен лаверн,...Историческая драма про любовный треугольник, к...[, 1890-е, большой пенис, брак без секса, вдох...[историческое, мелодрамы]
1311111113124630.2066154filmСтудентка по вызовуMes chères études2010.0драмы, мелодрамыФранцияNaN18.0NaNЭмманюэль Берко[дебора франсуа, ален коши, матье деми, бенжам...Лаура — 19-летняя первокурсница французского у...[франция, гостиница, по роману или книге, гост...[драмы, мелодрамы]
141111111357320.1830125filmТайное влечениеAdore2013.0драмы, мелодрамыАвстралия, ФранцияNaN16.0NaNАнн Фонтен[наоми уоттс, робин райт, завьер сэмюэл, джейм...Главные героини картины – Лил и Роз — две давн...[пляж, нагота, любовники, месть, лучший друг, ...[драмы, мелодрамы]
\n
" - }, - "execution_count": 269, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "recos_with_avatars.merge(items, on='item_id', how='left')" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "markdown", - "source": [ - "В целом, все рекомендации к каждому аватару получились неплохие" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "markdown", - "id": "ab12c89f", - "metadata": {}, - "source": [ - " # Метод приближенного поиска соседей для выдачи рекомендаций.\n", - "\n", - "Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", - "Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "5d1161b4", - "metadata": {}, - "outputs": [], - "source": [ - "LEARNING_RATE = 0.08165160206425184\n", - "LOSS = 'warp'" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "id": "9f20ae6e", - "metadata": {}, - "outputs": [], - "source": [ - "# обучаем LightFM, чтобы достать из нее вектора пользователей и айтемов\n", - "model = LightFMWrapperModel(\n", - " LightFM(\n", - " k=K,\n", - " no_components=NO_COMPONENTS,\n", - " loss= LOSS,\n", - " random_state=RANDOM_STATE,\n", - " learning_rate=LEARNING_RATE,\n", - " user_alpha=USER_ALPHA,\n", - " item_alpha=ITEM_ALPHA\n", - " ),\n", - " epochs=N_EPOCHS,\n", - " num_threads=NUM_THREADS\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "9982d55c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model.fit(dataset)" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "348b4fd6", - "metadata": {}, - "outputs": [], - "source": [ - "user_embeddings, item_embeddings = model.get_vectors(dataset)" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "fd296cf4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((756545, 34), (13963, 34))" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_embeddings.shape, item_embeddings.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "d75b4570", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([-2.48910075e+02, 1.00000000e+00, -3.04745167e-01, 1.30259299e-01,\n", - " -1.25937782e-01, 1.32810516e-01, -3.98682870e-01, 2.12211904e-01,\n", - " 3.15063161e-01, 9.48599975e-03, 1.79876286e-01, -1.15210674e-01,\n", - " 3.13044085e-01, 5.25500635e-02, -8.94866249e-02, 6.32450803e-02,\n", - " 3.30464664e-01, -2.79290127e-01, 7.66675368e-02, 2.69704125e-01,\n", - " -2.02872234e-01, 3.65543869e-02, -2.08750917e-01, -7.48397237e-02,\n", - " 2.09714412e-01, 1.28161004e-01, -2.49842146e-01, 7.57336145e-02,\n", - " 6.74582969e-02, 2.03054725e-01, -4.46441335e-02, 1.00222239e-01,\n", - " 3.09746759e-01, 2.26963989e-01])" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#пользователь со средним значением по каждому признаку\n", - "first_person = user_embeddings.mean(0)\n", - "first_person" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "id": "88198015", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([-364.41271973, 1. , -2.19337273, -2.05960441,\n", - " -3.03305483, -2.15237951, -3.10027146, -1.44008625,\n", - " -1.55592728, -1.69499218, -1.87335801, -3.19125104,\n", - " -1.8664068 , -2.62357092, -2.23808742, -1.78050435,\n", - " -1.67308342, -2.70261121, -1.94637215, -2.44766903,\n", - " -2.40233946, -1.93648934, -2.32535124, -2.73280096,\n", - " -2.20278382, -1.93085539, -2.29366779, -1.9847883 ,\n", - " -2.619452 , -1.8447926 , -2.03915739, -1.86472845,\n", - " -1.80441463, -1.98137343])" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#пользователь со минимальным значением по каждому признаку\n", - "second_person = user_embeddings.min(axis=0)\n", - "second_person" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "id": "4e02dec3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([0. , 1. , 1.80414879, 2.91568851, 2.57092023,\n", - " 2.49563074, 3.0165813 , 2.02071786, 2.10402703, 1.86775827,\n", - " 1.81193578, 2.3456769 , 2.37611055, 4.0926795 , 1.8776809 ,\n", - " 1.91333187, 2.16625547, 1.76979506, 1.87265527, 2.63360167,\n", - " 1.97114313, 1.88249838, 1.89424872, 2.15507913, 2.38049865,\n", - " 1.99921763, 1.80478072, 1.8311218 , 3.32906055, 2.25318193,\n", - " 2.0245254 , 2.37490654, 2.28989363, 1.97282732])" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#пользователь со максимальным значением по каждому признаку\n", - "third_person = user_embeddings.max(axis=0)\n", - "third_person" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "id": "75a314ac", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(756545, 34)" - ] - }, - "execution_count": 77, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "user_embeddings.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "id": "3cb72431", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(756548, 34)" - ] - }, - "execution_count": 78, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# добавим векотра 3х новых пользователей\n", - "user_embeddings = np.append(user_embeddings, np.array([first_person,\n", - " second_person, third_person]), axis=0)\n", - "user_embeddings.shape\n" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "db53d401", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150, 'post': 0, 'chunkIndexSize': 10000}\n" - ] - } - ], - "source": [ - "M = 50\n", - "efC = 150\n", - "\n", - "num_threads = 8\n", - "chunkIndexSize = 10000\n", - "\n", - "index_time_params = {\n", - " 'M': M,\n", - " 'indexThreadQty': num_threads,\n", - " 'efConstruction': efC,\n", - " 'post': 0,\n", - " 'chunkIndexSize': chunkIndexSize,\n", - " }\n", - "print ('Index-time parameters', index_time_params)" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "e09782e5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "13963" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "K = 10\n", - "space_name = 'negdotprod'\n", - "index = nmslib.init(method='hnsw', space=space_name,\n", - " data_type=nmslib.DataType.DENSE_VECTOR)\n", - "index.addDataPointBatch(item_embeddings)" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "id": "209d778e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150}\n", - "Indexing time = 1.392440\n" - ] - } - ], - "source": [ - "start = time.time()\n", - "index_time_params = {'M': M, 'indexThreadQty': num_threads,\n", - " 'efConstruction': efC}\n", - "index.createIndex(index_time_params)\n", - "end = time.time()\n", - "print('Index-time parameters', index_time_params)\n", - "print('Indexing time = %f' % (end - start))" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "id": "998dad8b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Setting query-time parameters {'efSearch': 100}\n" - ] - } - ], - "source": [ - "efS = 100\n", - "query_time_params = {'efSearch': efS}\n", - "print('Setting query-time parameters', query_time_params)\n", - "index.setQueryTimeParams(query_time_params)" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "id": "6f5cd03c", - "metadata": {}, - "outputs": [], - "source": [ - "query_matrix = user_embeddings" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "77039943", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "kNN time total=3.962551 (sec), per query=0.000005 (sec), per query adjusted for thread number=0.000042 (sec)\n" - ] - } - ], - "source": [ - "query_qty = query_matrix.shape[0]\n", - "start = time.time()\n", - "nbrs = index.knnQueryBatch(query_matrix, k=K, num_threads=num_threads)\n", - "end = time.time()\n", - "print(\n", - " 'kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' \\\n", - " % (end - start, float(end - start) / query_qty, num_threads * float(end - start) / query_qty)\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "id": "cac18e0e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 32, 19, 43, ..., 31, 36, 69],\n", - " [ 31, 262, 62, ..., 32, 121, 735],\n", - " [ 19, 31, 121, ..., 29, 62, 105],\n", - " ...,\n", - " [ 31, 19, 43, ..., 268, 100, 86],\n", - " [ 19, 31, 32, ..., 268, 49, 173],\n", - " [ 19, 31, 32, ..., 100, 105, 268]])" - ] - }, - "execution_count": 86, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# рекомендации для всех пользователей\n", - "recos_old_persons = np.array(nbrs, dtype=int)[:,0][:len(nbrs) - 3]\n", - "recos_old_persons" - ] - }, - { - "cell_type": "code", - "execution_count": 87, - "id": "918c6976", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 31, 19, 32, 43, 62, 121, 173, 268, 100,\n", - " 86],\n", - " [12018, 10998, 7308, 12006, 10159, 10215, 3543, 8118, 8180,\n", - " 11511],\n", - " [ 8453, 6400, 3557, 3945, 6642, 4779, 3583, 2068, 8668,\n", - " 371]])" - ] - }, - "execution_count": 87, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# рекомендации для добавленных пользователей\n", - "recos_new_persons = np.array(nbrs, dtype=int)[:,0][-3:]\n", - "recos_new_persons" - ] - }, - { - "cell_type": "code", - "execution_count": 88, - "id": "c78fbc6a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
user_iditem_id
0032
1019
2043
3062
40449
.........
756544575654443
756544675654429
7565447756544100
7565448756544105
7565449756544268
\n", - "

7565450 rows × 2 columns

\n", - "
" - ], - "text/plain": [ - " user_id item_id\n", - "0 0 32\n", - "1 0 19\n", - "2 0 43\n", - "3 0 62\n", - "4 0 449\n", - "... ... ...\n", - "7565445 756544 43\n", - "7565446 756544 29\n", - "7565447 756544 100\n", - "7565448 756544 105\n", - "7565449 756544 268\n", - "\n", - "[7565450 rows x 2 columns]" - ] - }, - "execution_count": 88, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_r = \\\n", - " pd.DataFrame({'user_id': np.repeat(np.arange(len(recos_old_persons)),\n", - " 10), Columns.Item: recos_old_persons.ravel()})\n", - "df_r\n" - ] - }, - { - "cell_type": "code", - "execution_count": 89, - "id": "902cbca6", - "metadata": {}, - "outputs": [], - "source": [ - "df_r.to_csv('nmslib.csv.gz', index=False, compression='gzip')\n" - ] - }, - { - "cell_type": "markdown", - "source": [ - "# Холодные пользователи\n", - "Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", - "\n", - "В предыдущей домашке, мы выяснили, что на этом датасете лучше всего себя ведет топ за последний месяц. Поэтому каждую модель мы использовали с подобным методом добивки холодных пользователей\n" - ], - "metadata": { - "collapsed": false - } - }, - { - "cell_type": "code", - "execution_count": null, - "outputs": [], - "source": [], - "metadata": { - "collapsed": false - } - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From e0ff6541b89177563a4b92740807d8d7cff2644c Mon Sep 17 00:00:00 2001 From: Vladislav Mostovik <56130198+Mostovik71@users.noreply.github.com> Date: Wed, 14 Dec 2022 12:27:46 +0300 Subject: [PATCH 12/12] Add files via upload --- notebooks/ALS_LightFM_MF.ipynb | 4890 ++++++++++++++++++++++++++++++++ 1 file changed, 4890 insertions(+) create mode 100644 notebooks/ALS_LightFM_MF.ipynb diff --git a/notebooks/ALS_LightFM_MF.ipynb b/notebooks/ALS_LightFM_MF.ipynb new file mode 100644 index 00000000..fdb48263 --- /dev/null +++ b/notebooks/ALS_LightFM_MF.ipynb @@ -0,0 +1,4890 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "# Домашнее задание\n", + "\n", + "Домашнее задание состоит из нескольких блоков.\n", + "\n", + "\n", + "## Эксперименты в ipynb ноутбуках (15 баллов)\n", + "- Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", + " - Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)\n", + "- Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", + " - Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д\n", + "- Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**\n", + "- Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", + "\n", + "Примечание: за невоспроизводимый код в ноутбуках (например, нарушен порядок выполнения ячеек, вызываются переменные, которые нигде не были объявлены ранее и.т.п) будут штрафы на усмотрение проверяющего.\n", + "\n", + "\n", + "## Реализация итоговой модели в сервисе (10 баллов)\n", + "- Пробитие бейзлайна $MAP@10 \\geq 0.074921$ **(6 баллов)**\n", + "- Код сервиса соответствует критериям читаемости и воспроизводимости **(4 балла)**" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings('ignore')" + ] + }, + { + "cell_type": "code", + "execution_count": 246, + "id": "e42a5585", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import time\n", + "import random\n", + "from pathlib import Path\n", + "\n", + "import numpy as np\n", + "import optuna\n", + "import pandas as pd\n", + "\n", + "import nmslib\n", + "from implicit.als import AlternatingLeastSquares\n", + "from lightfm import LightFM\n", + "from rectools import Columns\n", + "from rectools.dataset import Dataset\n", + "from rectools.metrics import MAP, Precision, Recall, calc_metrics\n", + "from rectools.models import ImplicitALSWrapperModel, LightFMWrapperModel" + ] + }, + { + "cell_type": "code", + "execution_count": 180, + "id": "8cd36e1a", + "metadata": {}, + "outputs": [], + "source": [ + "os.environ['OPENBLAS_NUM_THREADS'] = \"1\"" + ] + }, + { + "cell_type": "code", + "execution_count": 185, + "id": "4cb722c3", + "metadata": {}, + "outputs": [], + "source": [ + "DATA_PATH = Path(\"../data/kion_train/\")" + ] + }, + { + "cell_type": "code", + "execution_count": 186, + "id": "8195e56b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2.61 s, sys: 924 ms, total: 3.53 s\n", + "Wall time: 5.74 s\n" + ] + } + ], + "source": [ + "%%time\n", + "users = pd.read_csv(DATA_PATH / 'users.csv')\n", + "items = pd.read_csv(DATA_PATH / 'items.csv')\n", + "interactions = pd.read_csv(DATA_PATH / 'interactions.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 187, + "id": "01c2bdef", + "metadata": {}, + "outputs": [], + "source": [ + "Columns.Datetime = 'last_watch_dt'" + ] + }, + { + "cell_type": "markdown", + "id": "00b5584e", + "metadata": {}, + "source": [ + "# Preprocess Interactions" + ] + }, + { + "cell_type": "code", + "execution_count": 188, + "id": "0a3b4b12", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pct
017654995062021-05-11425072.0
169931716592021-05-298317100.0
265668371072021-05-09100.0
386461376382021-07-0514483100.0
496486895062021-04-306725100.0
\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct\n", + "0 176549 9506 2021-05-11 4250 72.0\n", + "1 699317 1659 2021-05-29 8317 100.0\n", + "2 656683 7107 2021-05-09 10 0.0\n", + "3 864613 7638 2021-07-05 14483 100.0\n", + "4 964868 9506 2021-04-30 6725 100.0" + ] + }, + "execution_count": 188, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 189, + "id": "260b1c48", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id int64\n", + "item_id int64\n", + "last_watch_dt object\n", + "total_dur int64\n", + "watched_pct float64\n", + "dtype: object" + ] + }, + "execution_count": 189, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 190, + "id": "fe2dbc06", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "user_id 0\n", + "item_id 0\n", + "last_watch_dt 0\n", + "total_dur 0\n", + "watched_pct 828\n", + "dtype: int64" + ] + }, + "execution_count": 190, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interactions.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 191, + "id": "71f61e81", + "metadata": {}, + "outputs": [], + "source": [ + "interactions[Columns.Datetime] = \\\n", + " pd.to_datetime(interactions[Columns.Datetime], format='%Y-%m-%d')" + ] + }, + { + "cell_type": "code", + "execution_count": 192, + "id": "39646cb5", + "metadata": {}, + "outputs": [], + "source": [ + "interactions.dropna(inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 193, + "id": "f98ae95d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "interactions['watched_pct'].hist(bins=20);" + ] + }, + { + "cell_type": "markdown", + "id": "1a0ad9f8", + "metadata": {}, + "source": [ + "Делю график просмотра на 5 категорий, где:\n", + "от 0% до 20% = 1,\n", + "от 21% до 40% = 2,\n", + "... ,\n", + "от 80% до 100% = 5" + ] + }, + { + "cell_type": "code", + "execution_count": 194, + "id": "1424e744", + "metadata": {}, + "outputs": [], + "source": [ + "interactions[Columns.Weight] = pd.cut(\n", + " x=interactions['watched_pct'],\n", + " bins=5,\n", + " labels=[1, 2, 3, 4, 5]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 196, + "id": "052d2fb0", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "interactions[Columns.Datetime].hist(bins=20);" + ] + }, + { + "cell_type": "markdown", + "id": "5adb80ee", + "metadata": {}, + "source": [ + "Вообще, видно, что кол-во пользователей растет" + ] + }, + { + "cell_type": "code", + "execution_count": 197, + "id": "0fbd2bbc", + "metadata": {}, + "outputs": [], + "source": [ + "cold_users = \\\n", + " interactions[Columns.User].value_counts()[interactions[Columns.User].value_counts() == 1].index" + ] + }, + { + "cell_type": "code", + "execution_count": 198, + "id": "150e1593", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "interactions[interactions[Columns.User].isin(cold_users)]['watched_pct'\n", + " ].hist(bins=20);" + ] + }, + { + "cell_type": "markdown", + "id": "b5fa83eb", + "metadata": {}, + "source": [ + "Для холодных пользователей, я бы рекомендовал айтемы с самый высоким просмотром в среднем по холодным пользователям" + ] + }, + { + "cell_type": "code", + "execution_count": 199, + "id": "cca06e3f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
1079146681992021-07-277139.01
26181144104402021-08-082740840.02
37161176104402021-07-29220.01
382172318192021-04-118535100.05
607721681432021-05-0866011.01
.....................
5476222100790097282021-08-124166.01
547622588213847162021-05-2115942.01
5476238805174131252021-06-2710.01
5476246648596122252021-08-13760.01
5476248697262152972021-08-201830763.04
\n", + "

355162 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "10 791466 8199 2021-07-27 713 9.0 1\n", + "26 181144 10440 2021-08-08 27408 40.0 2\n", + "37 161176 10440 2021-07-29 22 0.0 1\n", + "38 21723 1819 2021-04-11 8535 100.0 5\n", + "60 77216 8143 2021-05-08 660 11.0 1\n", + "... ... ... ... ... ... ...\n", + "5476222 1007900 9728 2021-08-12 416 6.0 1\n", + "5476225 882138 4716 2021-05-21 1594 2.0 1\n", + "5476238 805174 13125 2021-06-27 1 0.0 1\n", + "5476246 648596 12225 2021-08-13 76 0.0 1\n", + "5476248 697262 15297 2021-08-20 18307 63.0 4\n", + "\n", + "[355162 rows x 6 columns]" + ] + }, + "execution_count": 199, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users = interactions[interactions[Columns.User].isin(cold_users)]\n", + "hot_users = interactions[~interactions[Columns.User].isin(cold_users)]\n", + "cold_users" + ] + }, + { + "cell_type": "code", + "execution_count": 200, + "id": "a691676f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
017654995062021-05-11425072.04
169931716592021-05-298317100.05
265668371072021-05-09100.01
386461376382021-07-0514483100.05
496486895062021-04-306725100.05
.....................
5476246648596122252021-08-13760.01
547624754686296732021-04-13230849.03
5476248697262152972021-08-201830763.04
5476249384202161972021-04-196203100.05
547625031970944362021-08-15392145.03
\n", + "

5475423 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "0 176549 9506 2021-05-11 4250 72.0 4\n", + "1 699317 1659 2021-05-29 8317 100.0 5\n", + "2 656683 7107 2021-05-09 10 0.0 1\n", + "3 864613 7638 2021-07-05 14483 100.0 5\n", + "4 964868 9506 2021-04-30 6725 100.0 5\n", + "... ... ... ... ... ... ...\n", + "5476246 648596 12225 2021-08-13 76 0.0 1\n", + "5476247 546862 9673 2021-04-13 2308 49.0 3\n", + "5476248 697262 15297 2021-08-20 18307 63.0 4\n", + "5476249 384202 16197 2021-04-19 6203 100.0 5\n", + "5476250 319709 4436 2021-08-15 3921 45.0 3\n", + "\n", + "[5475423 rows x 6 columns]" + ] + }, + "execution_count": 200, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hot_users" + ] + }, + { + "cell_type": "code", + "execution_count": 201, + "id": "a64701c2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_id
1044045695
1529739309
265720474
972815140
474011455
......
19461
138861
140901
57301
131251
\n", + "

6440 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " item_id\n", + "10440 45695\n", + "15297 39309\n", + "2657 20474\n", + "9728 15140\n", + "4740 11455\n", + "... ...\n", + "1946 1\n", + "13886 1\n", + "14090 1\n", + "5730 1\n", + "13125 1\n", + "\n", + "[6440 rows x 1 columns]" + ] + }, + "execution_count": 201, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users['item_id'].value_counts().to_frame()" + ] + }, + { + "cell_type": "code", + "execution_count": 202, + "id": "cef9cfa6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Int64Index([609, 4895, 3825, 5069, 14092, 12593, 7142, 2271, 13673, 11566], dtype='int64', name='item_id')" + ] + }, + "execution_count": 202, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cold_users[['item_id', 'total_dur']].groupby('item_id').mean().sort_values(by='total_dur', ascending=False).head(10).index" + ] + }, + { + "cell_type": "markdown", + "id": "a52f311b", + "metadata": {}, + "source": [ + "# Делим на train и test" + ] + }, + { + "cell_type": "code", + "execution_count": 203, + "id": "bd68d3fe", + "metadata": {}, + "outputs": [], + "source": [ + "max_date = interactions[Columns.Datetime].max()" + ] + }, + { + "cell_type": "code", + "execution_count": 204, + "id": "3092fe4b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "train: (4984443, 6)\n", + "test: (490980, 6)\n" + ] + } + ], + "source": [ + "train = interactions[interactions[Columns.Datetime] < max_date\n", + " - pd.Timedelta(days=7)].copy()\n", + "test = interactions[interactions[Columns.Datetime] >= max_date\n", + " - pd.Timedelta(days=7)].copy()\n", + "\n", + "print(f\"train: {train.shape}\")\n", + "print(f\"test: {test.shape}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 205, + "id": "ec286bdc", + "metadata": {}, + "outputs": [], + "source": [ + "train.drop(train.query(\"total_dur < 300\").index, inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 206, + "id": "52241fed", + "metadata": {}, + "outputs": [], + "source": [ + "drop_user = set(test[Columns.User]) - set(train[Columns.User])\n", + "test.drop(test[test[Columns.User].isin(drop_user)].index, inplace=True)" + ] + }, + { + "cell_type": "markdown", + "id": "b5eec6da", + "metadata": {}, + "source": [ + "## User preprocess" + ] + }, + { + "cell_type": "code", + "execution_count": 207, + "id": "c57e2b2f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
21047345age_45_54income_40_60Ж0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
..................
840192339025age_65_infincome_0_20Ж0
840193983617age_18_24income_20_40Ж1
840194251008NaNNaNNaN0
840195590706NaNNaNЖ0
840196166555age_65_infincome_20_40Ж0
\n", + "

840197 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " user_id age income sex kids_flg\n", + "0 973171 age_25_34 income_60_90 М 1\n", + "1 962099 age_18_24 income_20_40 М 0\n", + "2 1047345 age_45_54 income_40_60 Ж 0\n", + "3 721985 age_45_54 income_20_40 Ж 0\n", + "4 704055 age_35_44 income_60_90 Ж 0\n", + "... ... ... ... ... ...\n", + "840192 339025 age_65_inf income_0_20 Ж 0\n", + "840193 983617 age_18_24 income_20_40 Ж 1\n", + "840194 251008 NaN NaN NaN 0\n", + "840195 590706 NaN NaN Ж 0\n", + "840196 166555 age_65_inf income_20_40 Ж 0\n", + "\n", + "[840197 rows x 5 columns]" + ] + }, + "execution_count": 207, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users" + ] + }, + { + "cell_type": "code", + "execution_count": 208, + "id": "24cc138a", + "metadata": {}, + "outputs": [], + "source": [ + "users = users.loc[users[Columns.User].isin(train[Columns.User])].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 209, + "id": "6e5e2d92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_idageincomesexkids_flg
0973171age_25_34income_60_90М1
1962099age_18_24income_20_40М0
3721985age_45_54income_20_40Ж0
4704055age_35_44income_60_90Ж0
51037719age_45_54income_60_90М0
..................
840184529394age_25_34income_40_60Ж0
84018680113age_25_34income_40_60Ж0
840188312839age_65_infincome_60_90Ж0
840189191349age_45_54income_40_60М1
840190393868age_25_34income_20_40М0
\n", + "

586653 rows × 5 columns

\n", + "
" + ], + "text/plain": [ + " user_id age income sex kids_flg\n", + "0 973171 age_25_34 income_60_90 М 1\n", + "1 962099 age_18_24 income_20_40 М 0\n", + "3 721985 age_45_54 income_20_40 Ж 0\n", + "4 704055 age_35_44 income_60_90 Ж 0\n", + "5 1037719 age_45_54 income_60_90 М 0\n", + "... ... ... ... .. ...\n", + "840184 529394 age_25_34 income_40_60 Ж 0\n", + "840186 80113 age_25_34 income_40_60 Ж 0\n", + "840188 312839 age_65_inf income_60_90 Ж 0\n", + "840189 191349 age_45_54 income_40_60 М 1\n", + "840190 393868 age_25_34 income_20_40 М 0\n", + "\n", + "[586653 rows x 5 columns]" + ] + }, + "execution_count": 209, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "users" + ] + }, + { + "cell_type": "markdown", + "id": "c7f9a6e7", + "metadata": {}, + "source": [ + "Заменяю Nan'ы на Unknown" + ] + }, + { + "cell_type": "code", + "execution_count": 210, + "id": "1286eb60", + "metadata": {}, + "outputs": [], + "source": [ + "users.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 211, + "id": "1ccccf0f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
0973171Мsex
1962099Мsex
3721985Жsex
4704055Жsex
51037719Мsex
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 973171 М sex\n", + "1 962099 М sex\n", + "3 721985 Ж sex\n", + "4 704055 Ж sex\n", + "5 1037719 М sex" + ] + }, + "execution_count": 211, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_features_frames = []\n", + "for feature in ['sex', 'age', 'income']:\n", + " feature_frame = users.reindex(columns=[Columns.User, feature])\n", + " feature_frame.columns = ['id', 'value']\n", + " feature_frame['feature'] = feature\n", + " user_features_frames.append(feature_frame)\n", + "user_features = pd.concat(user_features_frames)\n", + "user_features.head()" + ] + }, + { + "cell_type": "markdown", + "id": "b9220b0b", + "metadata": {}, + "source": [ + "## Item preprocess" + ] + }, + { + "cell_type": "code", + "execution_count": 213, + "id": "8bbe9ee4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
item_idcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywords
010711filmПоговори с нейHable con ella2002.0драмы, зарубежные, детективы, мелодрамыИспанияNaN16.0NaNПедро АльмодоварАдольфо Фернандес, Ана Фернандес, Дарио Гранди...Мелодрама легендарного Педро Альмодовара «Пого...Поговори, ней, 2002, Испания, друзья, любовь, ...
12508filmГолые перцыSearch Party2014.0зарубежные, приключения, комедииСШАNaN16.0NaNСкот АрмстронгАдам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ...Уморительная современная комедия на популярную...Голые, перцы, 2014, США, друзья, свадьбы, прео...
210716filmТактическая силаTactical Force2011.0криминал, зарубежные, триллеры, боевики, комедииКанадаNaN16.0NaNАдам П. КалтрароАдриан Холмс, Даррен Шалави, Джерри Вассерман,...Профессиональный рестлер Стив Остин («Все или ...Тактическая, сила, 2011, Канада, бандиты, ганг...
37868film45 лет45 Years2015.0драмы, зарубежные, мелодрамыВеликобританияNaN16.0NaNЭндрю ХэйАлександра Риддлстон-Барретт, Джеральдин Джейм...Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей...45, лет, 2015, Великобритания, брак, жизнь, лю...
416268filmВсе решает мгновениеNaN1978.0драмы, спорт, советские, мелодрамыСССРNaN12.0ЛенфильмВиктор СадовскийАлександр Абдулов, Александр Демьяненко, Алекс...Расчетливая чаровница из советского кинохита «...Все, решает, мгновение, 1978, СССР, сильные, ж...
\n", + "
" + ], + "text/plain": [ + " item_id content_type title title_orig release_year \\\n", + "0 10711 film Поговори с ней Hable con ella 2002.0 \n", + "1 2508 film Голые перцы Search Party 2014.0 \n", + "2 10716 film Тактическая сила Tactical Force 2011.0 \n", + "3 7868 film 45 лет 45 Years 2015.0 \n", + "4 16268 film Все решает мгновение NaN 1978.0 \n", + "\n", + " genres countries for_kids \\\n", + "0 драмы, зарубежные, детективы, мелодрамы Испания NaN \n", + "1 зарубежные, приключения, комедии США NaN \n", + "2 криминал, зарубежные, триллеры, боевики, комедии Канада NaN \n", + "3 драмы, зарубежные, мелодрамы Великобритания NaN \n", + "4 драмы, спорт, советские, мелодрамы СССР NaN \n", + "\n", + " age_rating studios directors \\\n", + "0 16.0 NaN Педро Альмодовар \n", + "1 16.0 NaN Скот Армстронг \n", + "2 16.0 NaN Адам П. Калтраро \n", + "3 16.0 NaN Эндрю Хэй \n", + "4 12.0 Ленфильм Виктор Садовский \n", + "\n", + " actors \\\n", + "0 Адольфо Фернандес, Ана Фернандес, Дарио Гранди... \n", + "1 Адам Палли, Брайан Хаски, Дж.Б. Смув, Джейсон ... \n", + "2 Адриан Холмс, Даррен Шалави, Джерри Вассерман,... \n", + "3 Александра Риддлстон-Барретт, Джеральдин Джейм... \n", + "4 Александр Абдулов, Александр Демьяненко, Алекс... \n", + "\n", + " description \\\n", + "0 Мелодрама легендарного Педро Альмодовара «Пого... \n", + "1 Уморительная современная комедия на популярную... \n", + "2 Профессиональный рестлер Стив Остин («Все или ... \n", + "3 Шарлотта Рэмплинг, Том Кортни, Джеральдин Джей... \n", + "4 Расчетливая чаровница из советского кинохита «... \n", + "\n", + " keywords \n", + "0 Поговори, ней, 2002, Испания, друзья, любовь, ... \n", + "1 Голые, перцы, 2014, США, друзья, свадьбы, прео... \n", + "2 Тактическая, сила, 2011, Канада, бандиты, ганг... \n", + "3 45, лет, 2015, Великобритания, брак, жизнь, лю... \n", + "4 Все, решает, мгновение, 1978, СССР, сильные, ж... " + ] + }, + "execution_count": 213, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 214, + "id": "72fa86a0", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "item_id 0\n", + "content_type 0\n", + "title 0\n", + "title_orig 4745\n", + "release_year 98\n", + "genres 0\n", + "countries 37\n", + "for_kids 15397\n", + "age_rating 2\n", + "studios 14898\n", + "directors 1509\n", + "actors 2619\n", + "description 2\n", + "keywords 423\n", + "dtype: int64" + ] + }, + "execution_count": 214, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 215, + "id": "50f0611f", + "metadata": {}, + "outputs": [], + "source": [ + "items = items.loc[items[Columns.Item].isin(train[Columns.Item])].copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 216, + "id": "280cf47d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "item_id 0\n", + "content_type 0\n", + "title 0\n", + "title_orig 3775\n", + "release_year 31\n", + "genres 0\n", + "countries 14\n", + "for_kids 13415\n", + "age_rating 1\n", + "studios 13047\n", + "directors 939\n", + "actors 1858\n", + "description 0\n", + "keywords 388\n", + "dtype: int64" + ] + }, + "execution_count": 216, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items.isna().sum()" + ] + }, + { + "cell_type": "markdown", + "id": "eddd93b5", + "metadata": {}, + "source": [ + "## Genre" + ] + }, + { + "cell_type": "code", + "execution_count": 217, + "id": "bf6da75c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre" + ] + }, + "execution_count": 217, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Explode genres to flatten table\n", + "items['genre'] = items['genres'].str.lower().str.replace(', ', ',',\n", + " regex=False).str.split(',')\n", + "genre_feature = items[['item_id', 'genre']].explode('genre')\n", + "genre_feature.columns = ['id', 'value']\n", + "genre_feature['feature'] = 'genre'\n", + "genre_feature.head()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 218, + "id": "913b9c27", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
............
1596010632криминалgenre
159614538драмыgenre
159614538спортgenre
159614538криминалgenre
159623206комедииgenre
\n", + "

36128 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre\n", + "... ... ... ...\n", + "15960 10632 криминал genre\n", + "15961 4538 драмы genre\n", + "15961 4538 спорт genre\n", + "15961 4538 криминал genre\n", + "15962 3206 комедии genre\n", + "\n", + "[36128 rows x 3 columns]" + ] + }, + "execution_count": 218, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "genre_feature" + ] + }, + { + "cell_type": "markdown", + "id": "478bf1e3", + "metadata": {}, + "source": [ + "## Content" + ] + }, + { + "cell_type": "code", + "execution_count": 220, + "id": "65f8b5d9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711filmcontent_type
12508filmcontent_type
210716filmcontent_type
37868filmcontent_type
416268filmcontent_type
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 film content_type\n", + "1 2508 film content_type\n", + "2 10716 film content_type\n", + "3 7868 film content_type\n", + "4 16268 film content_type" + ] + }, + "execution_count": 220, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "content_feature = items.reindex(columns=[Columns.Item, \"content_type\"])\n", + "content_feature.columns = [\"id\", \"value\"]\n", + "content_feature[\"feature\"] = \"content_type\"\n", + "content_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "a62ebee4", + "metadata": {}, + "source": [ + "## Actors" + ] + }, + { + "cell_type": "code", + "execution_count": 221, + "id": "fdc43660", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711адольфо фернандесactors
010711ана фернандесactors
010711дарио грандинеттиactors
010711джеральдин чаплинactors
010711елена анайяactors
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 адольфо фернандес actors\n", + "0 10711 ана фернандес actors\n", + "0 10711 дарио грандинетти actors\n", + "0 10711 джеральдин чаплин actors\n", + "0 10711 елена анайя actors" + ] + }, + "execution_count": 221, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items['actors'] = items['actors'].str.lower().str.replace(', ', ',',\n", + " regex=False).str.split(',')\n", + "actors_feature = items[['item_id', 'actors']].explode('actors')\n", + "actors_feature.columns = ['id', 'value']\n", + "actors_feature['feature'] = 'actors'\n", + "actors_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "73801647", + "metadata": {}, + "source": [ + "## Keywords" + ] + }, + { + "cell_type": "code", + "execution_count": 222, + "id": "594abe5c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711поговориkeywords
010711нейkeywords
0107112002keywords
010711испанияkeywords
010711друзьяkeywords
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 поговори keywords\n", + "0 10711 ней keywords\n", + "0 10711 2002 keywords\n", + "0 10711 испания keywords\n", + "0 10711 друзья keywords" + ] + }, + "execution_count": 222, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "items['keywords'] = items['keywords'].str.lower().str.replace(', ', ','\n", + " , regex=False).str.split(',')\n", + "keywords_feature = items[['item_id', 'keywords']].explode('keywords')\n", + "keywords_feature.columns = ['id', 'value']\n", + "keywords_feature['feature'] = 'keywords'\n", + "keywords_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "d3eb0a37", + "metadata": {}, + "source": [ + "## Countries" + ] + }, + { + "cell_type": "code", + "execution_count": 223, + "id": "8eb8a621", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711Испанияcountries
12508СШАcountries
210716Канадаcountries
37868Великобританияcountries
416268СССРcountries
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 Испания countries\n", + "1 2508 США countries\n", + "2 10716 Канада countries\n", + "3 7868 Великобритания countries\n", + "4 16268 СССР countries" + ] + }, + "execution_count": 223, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "country_feature = items.reindex(columns=[Columns.Item, 'countries'])\n", + "country_feature.columns = ['id', 'value']\n", + "country_feature['feature'] = 'countries'\n", + "country_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "5e477ee1", + "metadata": {}, + "source": [ + "## Age Rating" + ] + }, + { + "cell_type": "code", + "execution_count": 224, + "id": "0894154a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
01071116.0age_feature
1250816.0age_feature
21071616.0age_feature
3786816.0age_feature
41626812.0age_feature
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 16.0 age_feature\n", + "1 2508 16.0 age_feature\n", + "2 10716 16.0 age_feature\n", + "3 7868 16.0 age_feature\n", + "4 16268 12.0 age_feature" + ] + }, + "execution_count": 224, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "age_feature = items.reindex(columns=[Columns.Item, \"age_rating\"])\n", + "age_feature.columns = [\"id\", \"value\"]\n", + "age_feature[\"feature\"] = \"age_feature\"\n", + "age_feature.head()" + ] + }, + { + "cell_type": "markdown", + "id": "c09df1ec", + "metadata": {}, + "source": [ + "## Studios" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "ff937b4f", + "metadata": {}, + "outputs": [], + "source": [ + "items.fillna('Unknown', inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 225, + "id": "cee42708", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711NaNstudios
12508NaNstudios
210716NaNstudios
37868NaNstudios
416268Ленфильмstudios
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 NaN studios\n", + "1 2508 NaN studios\n", + "2 10716 NaN studios\n", + "3 7868 NaN studios\n", + "4 16268 Ленфильм studios" + ] + }, + "execution_count": 225, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "studios_feature = items.reindex(columns=[Columns.Item, \"studios\"])\n", + "studios_feature.columns = [\"id\", \"value\"]\n", + "studios_feature[\"feature\"] = \"studios\"\n", + "studios_feature.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 226, + "id": "7234f13b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idvaluefeature
010711драмыgenre
010711зарубежныеgenre
010711детективыgenre
010711мелодрамыgenre
12508зарубежныеgenre
\n", + "
" + ], + "text/plain": [ + " id value feature\n", + "0 10711 драмы genre\n", + "0 10711 зарубежные genre\n", + "0 10711 детективы genre\n", + "0 10711 мелодрамы genre\n", + "1 2508 зарубежные genre" + ] + }, + "execution_count": 226, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# studios_feature, age_feature, country_feature - фичи которые хотелось бы использовать,\n", + "# но длительность обучения \"OPTUNA\" увеличивается в разы\n", + "item_features = pd.concat((genre_feature, content_feature ))\n", + "item_features.head()" + ] + }, + { + "cell_type": "markdown", + "id": "09b8d756", + "metadata": {}, + "source": [ + "## Metrics" + ] + }, + { + "cell_type": "code", + "execution_count": 227, + "id": "b082e667", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Precision@1': Precision(k=1),\n", + " 'Precision@2': Precision(k=2),\n", + " 'Precision@3': Precision(k=3),\n", + " 'Precision@4': Precision(k=4),\n", + " 'Precision@5': Precision(k=5),\n", + " 'Precision@6': Precision(k=6),\n", + " 'Precision@7': Precision(k=7),\n", + " 'Precision@8': Precision(k=8),\n", + " 'Precision@9': Precision(k=9),\n", + " 'Precision@10': Precision(k=10),\n", + " 'Recall@1': Recall(k=1),\n", + " 'Recall@2': Recall(k=2),\n", + " 'Recall@3': Recall(k=3),\n", + " 'Recall@4': Recall(k=4),\n", + " 'Recall@5': Recall(k=5),\n", + " 'Recall@6': Recall(k=6),\n", + " 'Recall@7': Recall(k=7),\n", + " 'Recall@8': Recall(k=8),\n", + " 'Recall@9': Recall(k=9),\n", + " 'Recall@10': Recall(k=10),\n", + " 'MAP@1': MAP(k=1, divide_by_k=False),\n", + " 'MAP@2': MAP(k=2, divide_by_k=False),\n", + " 'MAP@3': MAP(k=3, divide_by_k=False),\n", + " 'MAP@4': MAP(k=4, divide_by_k=False),\n", + " 'MAP@5': MAP(k=5, divide_by_k=False),\n", + " 'MAP@6': MAP(k=6, divide_by_k=False),\n", + " 'MAP@7': MAP(k=7, divide_by_k=False),\n", + " 'MAP@8': MAP(k=8, divide_by_k=False),\n", + " 'MAP@9': MAP(k=9, divide_by_k=False),\n", + " 'MAP@10': MAP(k=10, divide_by_k=False)}" + ] + }, + "execution_count": 227, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "metrics_name = {\n", + " 'Precision': Precision,\n", + " 'Recall': Recall,\n", + " 'MAP': MAP,\n", + "}\n", + "\n", + "metrics = {}\n", + "for metric_name, metric in metrics_name.items():\n", + " for k in range(1, 11):\n", + " metrics[f'{metric_name}@{k}'] = metric(k=k)\n", + "metrics" + ] + }, + { + "cell_type": "markdown", + "id": "2c603783", + "metadata": {}, + "source": [ + "# Optuna\n", + "\n", + "Необходимо будет перебрать $N$ моделей $(N \\geq 2)$ матричной факторизации и перебрать у них $K$ гиперпараметров $(K \\geq 2)$ **(6 баллов)**\n", + "Для перебора гиперпараметров можно использовать [`Optuna`](https://github.com/optuna/optuna), [`Hyperopt`](https://github.com/hyperopt/hyperopt)" + ] + }, + { + "cell_type": "code", + "execution_count": 229, + "id": "fb193c2f", + "metadata": {}, + "outputs": [], + "source": [ + "NUM_THREADS = 8\n", + "RANDOM_STATE = 42\n", + "K = 5\n", + "NO_COMPONENTS = 32\n", + "N_EPOCHS = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 230, + "id": "3328645d", + "metadata": {}, + "outputs": [], + "source": [ + "USER_ALPHA = 0\n", + "ITEM_ALPHA = 0\n", + "K_RECOS = 10" + ] + }, + { + "cell_type": "code", + "execution_count": 231, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "dataset = Dataset.construct(interactions_df=train,\n", + " user_features_df=user_features,\n", + " cat_user_features=['sex', 'age', 'income'],\n", + " item_features_df=item_features,\n", + " cat_item_features=['content_type', 'genre'])\n", + "TEST_USERS = test[Columns.User].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "a17b8b66", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:32:01,241]\u001b[0m A new study created in memory with name: no-name-d2c12238-d18d-4c6f-bca4-840e7d3f29b0\u001b[0m\n", + "\u001b[32m[I 2022-12-12 18:41:40,178]\u001b[0m Trial 0 finished with value: 0.07156314077881751 and parameters: {'recomender': 'ALS', 'regularization': 0.0035671951579306937}. Best is trial 0 with value: 0.07156314077881751.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07156314077881751\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:51:48,671]\u001b[0m Trial 1 finished with value: 0.07241639094290958 and parameters: {'recomender': 'ALS', 'regularization': 0.006724126527816994}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07241639094290958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:53:18,697]\u001b[0m Trial 2 finished with value: 1.4050149479540313e-07 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.8190152272980945, 'k': 6, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 1.4050149479540313e-07\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:54:36,340]\u001b[0m Trial 3 finished with value: 0.005366068762176463 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.18723291153626603, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.005366068762176463\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 18:56:21,781]\u001b[0m Trial 4 finished with value: 0.0002205827579874263 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.6560234930178588, 'k': 6, 'loss': 'logistic'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.0002205827579874263\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:05:46,138]\u001b[0m Trial 5 finished with value: 0.07173988822226253 and parameters: {'recomender': 'ALS', 'regularization': 0.009044651486228098}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07173988822226253\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:07:05,748]\u001b[0m Trial 6 finished with value: 3.943062688880311e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.44751878244334975, 'k': 7, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 3.943062688880311e-06\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:08:22,099]\u001b[0m Trial 7 finished with value: 0.06793721324055035 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.10438302844592218, 'k': 3, 'loss': 'warp'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.06793721324055035\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:17:32,898]\u001b[0m Trial 8 finished with value: 0.07184311920591484 and parameters: {'recomender': 'ALS', 'regularization': 0.0005806772800434514}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07184311920591484\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:18:59,268]\u001b[0m Trial 9 finished with value: 2.2409988419866796e-06 and parameters: {'recomender': 'LightFM', 'learning_rate': 0.805131840226543, 'k': 7, 'loss': 'bpr'}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 2.2409988419866796e-06\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:28:09,202]\u001b[0m Trial 10 finished with value: 0.07180954187357708 and parameters: {'recomender': 'ALS', 'regularization': 0.008190821633209066}. Best is trial 1 with value: 0.07241639094290958.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07180954187357708\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:37:15,147]\u001b[0m Trial 11 finished with value: 0.07244222251339615 and parameters: {'recomender': 'ALS', 'regularization': 0.00026970098377155163}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07244222251339615\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:46:24,260]\u001b[0m Trial 12 finished with value: 0.07202031081710311 and parameters: {'recomender': 'ALS', 'regularization': 0.0066363513358619185}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07202031081710311\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 19:55:34,176]\u001b[0m Trial 13 finished with value: 0.07199398893026046 and parameters: {'recomender': 'ALS', 'regularization': 0.004156107607150058}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07199398893026046\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:04:42,589]\u001b[0m Trial 14 finished with value: 0.07167963259586223 and parameters: {'recomender': 'ALS', 'regularization': 0.0006228566403390988}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167963259586223\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:13:49,348]\u001b[0m Trial 15 finished with value: 0.07202106855494453 and parameters: {'recomender': 'ALS', 'regularization': 0.00598705937836684}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07202106855494453\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:22:57,770]\u001b[0m Trial 16 finished with value: 0.07193963920172777 and parameters: {'recomender': 'ALS', 'regularization': 0.0028834604694796696}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07193963920172777\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:32:04,614]\u001b[0m Trial 17 finished with value: 0.07186249836889418 and parameters: {'recomender': 'ALS', 'regularization': 0.007249626991281137}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07186249836889418\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:41:24,258]\u001b[0m Trial 18 finished with value: 0.07164870366757094 and parameters: {'recomender': 'ALS', 'regularization': 0.005115162467576984}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07164870366757094\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 20:50:49,059]\u001b[0m Trial 19 finished with value: 0.07179004415938793 and parameters: {'recomender': 'ALS', 'regularization': 0.0018963762834092678}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07179004415938793\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 21:42:16,853]\u001b[0m Trial 20 finished with value: 0.07167129296212232 and parameters: {'recomender': 'ALS', 'regularization': 0.009804091535656343}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167129296212232\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 21:52:20,413]\u001b[0m Trial 21 finished with value: 0.07191839766465505 and parameters: {'recomender': 'ALS', 'regularization': 0.005764203522687446}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07191839766465505\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:02:12,773]\u001b[0m Trial 22 finished with value: 0.07159025974450188 and parameters: {'recomender': 'ALS', 'regularization': 0.006209360331833826}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07159025974450188\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:12:55,936]\u001b[0m Trial 23 finished with value: 0.07167021208897958 and parameters: {'recomender': 'ALS', 'regularization': 0.007825089420401029}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07167021208897958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:23:04,762]\u001b[0m Trial 24 finished with value: 0.07191850988173716 and parameters: {'recomender': 'ALS', 'regularization': 0.004979324924695012}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07191850988173716\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:34:38,654]\u001b[0m Trial 25 finished with value: 0.07178449755342503 and parameters: {'recomender': 'ALS', 'regularization': 0.002381286135370409}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07178449755342503\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:45:43,850]\u001b[0m Trial 26 finished with value: 0.07177449403191542 and parameters: {'recomender': 'ALS', 'regularization': 0.004677821831829}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07177449403191542\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 22:56:45,636]\u001b[0m Trial 27 finished with value: 0.07214439856613958 and parameters: {'recomender': 'ALS', 'regularization': 0.0069504676367203744}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07214439856613958\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 23:08:13,361]\u001b[0m Trial 28 finished with value: 0.07237690498752612 and parameters: {'recomender': 'ALS', 'regularization': 0.0074561399301387955}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07237690498752612\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2022-12-12 23:18:05,878]\u001b[0m Trial 29 finished with value: 0.07173589378156864 and parameters: {'recomender': 'ALS', 'regularization': 0.00848249465326267}. Best is trial 11 with value: 0.07244222251339615.\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MAP@10 0.07173589378156864\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[33m[W 2022-12-12 23:27:26,180]\u001b[0m Trial 30 failed because of the following error: KeyboardInterrupt()\u001b[0m\n", + "Traceback (most recent call last):\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\", line 196, in _run_trial\n", + " value_or_values = func(trial)\n", + " File \"/tmp/ipykernel_5286/352742220.py\", line 40, in objective\n", + " recos = model.recommend(\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\", line 132, in recommend\n", + " reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 141, in _recommend_u2i\n", + " scores = scores_calculator.calc(target_id)\n", + " File \"/home/rezarayev/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\", line 98, in calc\n", + " scores = self.objects_factors @ subject_factors\n", + "KeyboardInterrupt\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_5286/352742220.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[0mstudy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moptuna\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_study\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdirection\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'maximize'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 50\u001b[0;31m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobjective\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_trials\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/study.py\u001b[0m in \u001b[0;36moptimize\u001b[0;34m(self, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 417\u001b[0m \"\"\"\n\u001b[1;32m 418\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 419\u001b[0;31m _optimize(\n\u001b[0m\u001b[1;32m 420\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 421\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize\u001b[0;34m(study, func, n_trials, timeout, n_jobs, catch, callbacks, gc_after_trial, show_progress_bar)\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 65\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn_jobs\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 66\u001b[0;31m _optimize_sequential(\n\u001b[0m\u001b[1;32m 67\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_optimize_sequential\u001b[0;34m(study, func, n_trials, timeout, catch, callbacks, gc_after_trial, reseed_sampler_rng, time_start, progress_bar)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 159\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 160\u001b[0;31m \u001b[0mfrozen_trial\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_run_trial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstudy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 161\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[0;31m# The following line mitigates memory problems that can be occurred in some\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 232\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc_err\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 233\u001b[0m ):\n\u001b[0;32m--> 234\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mfunc_err\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 235\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfrozen_trial\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 236\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/optuna/study/_optimize.py\u001b[0m in \u001b[0;36m_run_trial\u001b[0;34m(study, func, catch)\u001b[0m\n\u001b[1;32m 194\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mget_heartbeat_thread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_trial_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstudy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_storage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 195\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 196\u001b[0;31m \u001b[0mvalue_or_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 197\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTrialPruned\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[0;31m# TODO(mamu): Handle multi-objective cases.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/tmp/ipykernel_5286/352742220.py\u001b[0m in \u001b[0;36mobjective\u001b[0;34m(trial)\u001b[0m\n\u001b[1;32m 38\u001b[0m fit_features_together=True)\n\u001b[1;32m 39\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m recos = model.recommend(\n\u001b[0m\u001b[1;32m 41\u001b[0m \u001b[0musers\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTEST_USERS\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0mdataset\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/base.py\u001b[0m in \u001b[0;36mrecommend\u001b[0;34m(self, users, dataset, k, filter_viewed, items_to_recommend, add_rank_col)\u001b[0m\n\u001b[1;32m 130\u001b[0m \u001b[0msorted_item_ids_to_recommend\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 131\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 132\u001b[0;31m reco_user_ids, reco_item_ids, reco_scores = self._recommend_u2i(\n\u001b[0m\u001b[1;32m 133\u001b[0m \u001b[0muser_ids\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 134\u001b[0m \u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001b[0m in \u001b[0;36m_recommend_u2i\u001b[0;34m(self, user_ids, dataset, k, filter_viewed, sorted_item_ids_to_recommend)\u001b[0m\n\u001b[1;32m 139\u001b[0m \u001b[0mall_scores\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mtp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mList\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mtarget_id\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0muser_ids\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mverbose\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 141\u001b[0;31m \u001b[0mscores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mscores_calculator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcalc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtarget_id\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 142\u001b[0m reco_ids, reco_scores = recommend_from_scores(\n\u001b[1;32m 143\u001b[0m \u001b[0mscores\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mscores\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/rectools/models/vector.py\u001b[0m in \u001b[0;36mcalc\u001b[0;34m(self, subject_id)\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0msubject_factors\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubjects_factors\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msubject_id\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdistance\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mDistance\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDOT\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 98\u001b[0;31m \u001b[0mscores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobjects_factors\u001b[0m \u001b[0;34m@\u001b[0m \u001b[0msubject_factors\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 99\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdistance\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mDistance\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mEUCLIDEAN\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0msubject_dot\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubjects_dots\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msubject_id\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "def objective(trial):\n", + " model_name = trial.suggest_categorical('recomender', ['LightFM',\n", + " 'ALS'])\n", + " if model_name == 'LightFM':\n", + " learning_rate = trial.suggest_float('learning_rate', 1e-10, 1)\n", + " k = trial.suggest_int('k', 2, 10)\n", + " loss = trial.suggest_categorical('loss', ['logistic', 'bpr',\n", + " 'warp'])\n", + " model = LightFMWrapperModel(LightFM(k=k,\n", + " learning_rate=learning_rate,\n", + " loss=loss, no_components=10),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS)\n", + " else:\n", + " regularization = trial.suggest_float('regularization', 1e-4,\n", + " 1e-2)\n", + " model = \\\n", + " ImplicitALSWrapperModel(model=AlternatingLeastSquares(factors=10,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=regularization),\n", + " fit_features_together=True)\n", + " model.fit(dataset)\n", + " recos = model.recommend(users=TEST_USERS, dataset=dataset,\n", + " k=K_RECOS, filter_viewed=True)\n", + " metric = calc_metrics(metrics, recos, test, train)['MAP@10']\n", + " print ('MAP@10', metric)\n", + " return metric\n", + "\n", + "\n", + "study = optuna.create_study(direction='maximize')\n", + "study.optimize(objective, n_trials=100)" + ] + }, + { + "cell_type": "markdown", + "id": "3989645b", + "metadata": {}, + "source": [ + "## Пришлось остановить обучение, тк эти 30 эпох обучались 6 часов" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "99aae61e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'recomender': 'ALS', 'regularization': 0.00026970098377155163}" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "study.best_params" + ] + }, + { + "cell_type": "code", + "execution_count": 233, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "REGULARIZATION = 0.00026970098377155163" + ] + }, + { + "cell_type": "code", + "execution_count": 234, + "id": "d1f6069a", + "metadata": {}, + "outputs": [], + "source": [ + "# обучаем best model после optuna\n", + "model = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=32,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=REGULARIZATION\n", + " ),\n", + " fit_features_together=True\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 236, + "id": "d3907c1d", + "metadata": {}, + "outputs": [], + "source": [ + "model.fit(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2050a6e", + "metadata": {}, + "outputs": [], + "source": [ + "recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=dataset,\n", + " k=K_RECOS,\n", + " filter_viewed=True\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "6bbe3ff3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.07124010116092815" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "calc_metrics(metrics, recos, test, train)['MAP@10']" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "d3eead34", + "metadata": {}, + "outputs": [], + "source": [ + "recos = recos[['user_id', 'item_id']]\n", + "recos.to_csv('ALS_after_optuna.csv.gz', index=False, compression='gzip')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "# Добавление аватаров\n", + "Добавить 3 \"аватаров\" (искусственных пользователей) и посмотреть рекомендации итоговой модели на них. Объяснить почему добавили именно таких пользователей. **(3 балла)**" + ] + }, + { + "cell_type": "code", + "execution_count": 264, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "some_avatars = pd.DataFrame(\n", + " {\n", + " Columns.User: [11111111, 11111112, 11111113],\n", + " Columns.Item: [\n", + " [10732, 3369, 15885], # Аватар, который любит мультики [губка боб, кунг-фу панда, ]\n", + " [3506, 1107, 11235], # Аватар, который любит боевики [форсаж, обитель зла, плохие парни]\n", + " [931, 389, 8315] # Аватар, который любит драмы [после, хатико, сумерки]\n", + " ],\n", + " 'last_watch_dt': [\n", + " [random.choice(sorted(interactions.last_watch_dt.unique())[-10:]) for _ in range(3)] for i in range(3)\n", + " ],\n", + " \"total_dur\": [\n", + " [34343, 6000, 9000],\n", + " [5000, 45452, 9000],\n", + " [5000, 3200, 3232]\n", + " ],\n", + " \"watched_pct\": [\n", + " [100.0, 95.0, 99.0],\n", + " [67.0, 95.0, 99.0],\n", + " [100.0, 53.0, 99.0]\n", + " ],\n", + " Columns.Weight: [\n", + " [5, 5, 5],\n", + " [3, 5, 5],\n", + " [5, 2, 5]\n", + " ]\n", + " }\n", + ")\n", + "\n", + "some_avatars = some_avatars.explode(\n", + " [Columns.Item, Columns.Datetime, \"total_dur\", \"watched_pct\", Columns.Weight]\n", + ").reset_index(drop=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 265, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idlast_watch_dttotal_durwatched_pctweight
011111111107322021-08-2234343100.05
11111111133692021-08-19600095.05
211111111158852021-08-17900099.05
31111111235062021-08-20500067.03
41111111211072021-08-144545295.05
511111112112352021-08-19900099.05
6111111139312021-08-145000100.05
7111111133892021-08-19320053.02
81111111383152021-08-22323299.05
\n", + "
" + ], + "text/plain": [ + " user_id item_id last_watch_dt total_dur watched_pct weight\n", + "0 11111111 10732 2021-08-22 34343 100.0 5\n", + "1 11111111 3369 2021-08-19 6000 95.0 5\n", + "2 11111111 15885 2021-08-17 9000 99.0 5\n", + "3 11111112 3506 2021-08-20 5000 67.0 3\n", + "4 11111112 1107 2021-08-14 45452 95.0 5\n", + "5 11111112 11235 2021-08-19 9000 99.0 5\n", + "6 11111113 931 2021-08-14 5000 100.0 5\n", + "7 11111113 389 2021-08-19 3200 53.0 2\n", + "8 11111113 8315 2021-08-22 3232 99.0 5" + ] + }, + "execution_count": 265, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "some_avatars" + ] + }, + { + "cell_type": "code", + "execution_count": 266, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "interactions_with_avatars = pd.concat([interactions, some_avatars])\n", + "\n", + "dataset_with_avatars = Dataset.construct(\n", + " interactions_df=interactions_with_avatars,\n", + ")\n", + "\n", + "# обучаем best model после optuna\n", + "model_with_avatars = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=32,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=REGULARIZATION\n", + " ),\n", + " fit_features_together=True\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 267, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 267, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_with_avatars.fit(dataset_with_avatars)" + ] + }, + { + "cell_type": "code", + "execution_count": 268, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idscorerank
011111111119850.0407001
11111111129540.0394662
21111111173100.0365913
31111111131820.0354234
41111111144750.0344225
51111111277930.0356391
61111111247020.0351392
711111112163610.0348573
81111111212870.0343274
911111112110180.0323495
101111111319160.2456551
1111111113144700.2427862
12111111131010.2192313
1311111113124630.2066154
141111111357320.1830125
\n", + "
" + ], + "text/plain": [ + " user_id item_id score rank\n", + "0 11111111 11985 0.040700 1\n", + "1 11111111 2954 0.039466 2\n", + "2 11111111 7310 0.036591 3\n", + "3 11111111 3182 0.035423 4\n", + "4 11111111 4475 0.034422 5\n", + "5 11111112 7793 0.035639 1\n", + "6 11111112 4702 0.035139 2\n", + "7 11111112 16361 0.034857 3\n", + "8 11111112 1287 0.034327 4\n", + "9 11111112 11018 0.032349 5\n", + "10 11111113 1916 0.245655 1\n", + "11 11111113 14470 0.242786 2\n", + "12 11111113 101 0.219231 3\n", + "13 11111113 12463 0.206615 4\n", + "14 11111113 5732 0.183012 5" + ] + }, + "execution_count": 268, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recos_with_avatars = model_with_avatars.recommend(\n", + " users=[11111111, 11111112, 11111113],\n", + " dataset=dataset_with_avatars,\n", + " k=5,\n", + " filter_viewed=True\n", + ")\n", + "recos_with_avatars" + ] + }, + { + "cell_type": "code", + "execution_count": 269, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_idscorerankcontent_typetitletitle_origrelease_yeargenrescountriesfor_kidsage_ratingstudiosdirectorsactorsdescriptionkeywordsgenre
011111111119850.0407001filmИстория игрушек 4Toy Story 42019.0мультфильм, фэнтези, комедииСШАNaN6.0NaNДжош Кули[том хэнкс, тим аллен, энни поттс, тони хейл, ...Космический рейнджер Баз Лайтер, ковбой Вуди, ...[игрушка, дружба, ковбой, история игрушек 4, ,...[мультфильм, фэнтези, комедии]
11111111129540.0394662filmМиньоныMinions2015.0фантастика, мультфильм, приключения, комедииСШАNaN6.0NaNКайл Балда, Пьер Коффан[сандра буллок, джон хэмм, майкл китон, эллисо...Миньоны живут на планете гораздо дольше нас. У...[помощник, сцена после титров, сцена во время ...[фантастика, мультфильм, приключения, комедии]
21111111173100.0365913filmГадкий я 2Despicable Me 22013.0мультфильм, приключения, фантастика, фэнтези, ...США, Франция, ЯпонияNaN0.0NaNПьер Коффан, Крис Рено[стив карелл, кристен уиг, бенджамин брэтт, ми...В то время как Грю, бывший суперзлодей, приспо...[отношения родитель-ребенок, секретный агент, ...[мультфильм, приключения, фантастика, фэнтези,...
31111111131820.0354234filmРальф против ИнтернетаRalph Breaks the Internet2018.0мультфильм, приключения, фантастика, семейное,...СШАNaN6.0NaNРич Мур, Фил Джонстон[джон си райли, сара силверман, галь гадот, та...На этот раз Ральф и Ванилопа фон Кекс выйдут з...[видеоигра, мультфильм, продолжение, интернет,...[мультфильм, приключения, фантастика, семейное...
41111111144750.0344225filmТачкиCars2006.0спорт, мультфильм, комедииСШАNaN6.0NaNДжон Лассетер, Джо Рэнфт[оуэн уилсон, пол ньюман, бонни хант, ларри-ка...Неукротимый в своем желании всегда и во всем п...[автомобильная гонка, трасса 66, porsche, выхо...[спорт, мультфильм, комедии]
51111111277930.0356391filmРадиовспышкаRadioflash2019.0боевики, драмы, фантастика, триллерыСШАNaN16.0NaNБен Макферсон[брайтон шарбино, доминик монахэн, уилл пэттон...Риз с легкостью проходит виртуальные квесты, н...[2019, соединенные штаты, радиовспышка][боевики, драмы, фантастика, триллеры]
61111111247020.0351392filmХищникPredator1987.0боевики, фантастика, триллеры, приключенияСША, МексикаNaN16.0NaNДжон МакТирнан[арнольд шварценеггер, карл уэзерс, эльпидия к...Американский вертолет был сбит партизанами в Ю...[центральная и южная америка, хищник, иноплане...[боевики, фантастика, триллеры, приключения]
711111112163610.0348573filmDoom: АннигиляцияDoom: Annihilation2019.0боевики, ужасы, фантастика, триллерыСШАNaN18.0NaNТони Гиглио[эми мэнсон, доминик мафэм, люк аллен-гейл, дж...Отряд морпехов прилетает на марсианский спутни...[планета марс, ад, космос, демон, по мотивам в...[боевики, ужасы, фантастика, триллеры]
81111111212870.0343274filmТерминатор: Тёмные судьбыTerminator: Dark Fate2019.0боевики, фантастика, приключенияСША, КитайNaN16.0NaNТим Миллер[линда хэмилтон, арнольд шварценеггер, маккенз...Мексика. Милая девушка Даниэла Рамос, а для др...[искуственный интеллект, киборг, вертолет, мех...[боевики, фантастика, приключения]
911111112110180.0323495filmХищникиPredators2010.0боевики, фантастика, триллеры, приключенияСШАNaN16.0NaNНимрод Антал[эдриан броуди, тофер грейс, алиси брага, уолт...Наемник Ройс невольно вынужден возглавить груп...[охотник, хищник, якудза, охота на людей, иноп...[боевики, фантастика, триллеры, приключения]
101111111319160.2456551filmСекс и ничего лишнегоMy Awkward Sexual Adventure2012.0мелодрамыКанадаNaN18.0NaNШон Гэррити[джонас черник, эмили хэмпшир, сара мэннинен, ...Чтобы вернуть свою неудовлетворенную бывшую де...[нижнее белье, массажистка, секс втроем, фалло...[мелодрамы]
1111111113144700.2427862filmЛюбовьLove2015.0драмы, мелодрамыФранцияNaN18.0NaNГаспар Ноэ[аоми муйок, карл глусман, клара кристин, уго ...Любовь вне добра и зла. Любовь — это генетичес...[париж, франция, секс, сексуальность, галерея,...[драмы, мелодрамы]
12111111131010.2192313filmКуриосаCuriosa2019.0историческое, мелодрамыФранцияNaN18.0NaNЛу Жене[ноэми мерлан, нильс шнайдер, бенжамен лаверн,...Историческая драма про любовный треугольник, к...[, 1890-е, большой пенис, брак без секса, вдох...[историческое, мелодрамы]
1311111113124630.2066154filmСтудентка по вызовуMes chères études2010.0драмы, мелодрамыФранцияNaN18.0NaNЭмманюэль Берко[дебора франсуа, ален коши, матье деми, бенжам...Лаура — 19-летняя первокурсница французского у...[франция, гостиница, по роману или книге, гост...[драмы, мелодрамы]
141111111357320.1830125filmТайное влечениеAdore2013.0драмы, мелодрамыАвстралия, ФранцияNaN16.0NaNАнн Фонтен[наоми уоттс, робин райт, завьер сэмюэл, джейм...Главные героини картины – Лил и Роз — две давн...[пляж, нагота, любовники, месть, лучший друг, ...[драмы, мелодрамы]
\n", + "
" + ], + "text/plain": [ + " user_id item_id score rank content_type title \\\n", + "0 11111111 11985 0.040700 1 film История игрушек 4 \n", + "1 11111111 2954 0.039466 2 film Миньоны \n", + "2 11111111 7310 0.036591 3 film Гадкий я 2 \n", + "3 11111111 3182 0.035423 4 film Ральф против Интернета \n", + "4 11111111 4475 0.034422 5 film Тачки \n", + "5 11111112 7793 0.035639 1 film Радиовспышка \n", + "6 11111112 4702 0.035139 2 film Хищник \n", + "7 11111112 16361 0.034857 3 film Doom: Аннигиляция \n", + "8 11111112 1287 0.034327 4 film Терминатор: Тёмные судьбы \n", + "9 11111112 11018 0.032349 5 film Хищники \n", + "10 11111113 1916 0.245655 1 film Секс и ничего лишнего \n", + "11 11111113 14470 0.242786 2 film Любовь \n", + "12 11111113 101 0.219231 3 film Куриоса \n", + "13 11111113 12463 0.206615 4 film Студентка по вызову \n", + "14 11111113 5732 0.183012 5 film Тайное влечение \n", + "\n", + " title_orig release_year \\\n", + "0 Toy Story 4 2019.0 \n", + "1 Minions 2015.0 \n", + "2 Despicable Me 2 2013.0 \n", + "3 Ralph Breaks the Internet 2018.0 \n", + "4 Cars 2006.0 \n", + "5 Radioflash 2019.0 \n", + "6 Predator 1987.0 \n", + "7 Doom: Annihilation 2019.0 \n", + "8 Terminator: Dark Fate 2019.0 \n", + "9 Predators 2010.0 \n", + "10 My Awkward Sexual Adventure 2012.0 \n", + "11 Love 2015.0 \n", + "12 Curiosa 2019.0 \n", + "13 Mes chères études 2010.0 \n", + "14 Adore 2013.0 \n", + "\n", + " genres countries \\\n", + "0 мультфильм, фэнтези, комедии США \n", + "1 фантастика, мультфильм, приключения, комедии США \n", + "2 мультфильм, приключения, фантастика, фэнтези, ... США, Франция, Япония \n", + "3 мультфильм, приключения, фантастика, семейное,... США \n", + "4 спорт, мультфильм, комедии США \n", + "5 боевики, драмы, фантастика, триллеры США \n", + "6 боевики, фантастика, триллеры, приключения США, Мексика \n", + "7 боевики, ужасы, фантастика, триллеры США \n", + "8 боевики, фантастика, приключения США, Китай \n", + "9 боевики, фантастика, триллеры, приключения США \n", + "10 мелодрамы Канада \n", + "11 драмы, мелодрамы Франция \n", + "12 историческое, мелодрамы Франция \n", + "13 драмы, мелодрамы Франция \n", + "14 драмы, мелодрамы Австралия, Франция \n", + "\n", + " for_kids age_rating studios directors \\\n", + "0 NaN 6.0 NaN Джош Кули \n", + "1 NaN 6.0 NaN Кайл Балда, Пьер Коффан \n", + "2 NaN 0.0 NaN Пьер Коффан, Крис Рено \n", + "3 NaN 6.0 NaN Рич Мур, Фил Джонстон \n", + "4 NaN 6.0 NaN Джон Лассетер, Джо Рэнфт \n", + "5 NaN 16.0 NaN Бен Макферсон \n", + "6 NaN 16.0 NaN Джон МакТирнан \n", + "7 NaN 18.0 NaN Тони Гиглио \n", + "8 NaN 16.0 NaN Тим Миллер \n", + "9 NaN 16.0 NaN Нимрод Антал \n", + "10 NaN 18.0 NaN Шон Гэррити \n", + "11 NaN 18.0 NaN Гаспар Ноэ \n", + "12 NaN 18.0 NaN Лу Жене \n", + "13 NaN 18.0 NaN Эмманюэль Берко \n", + "14 NaN 16.0 NaN Анн Фонтен \n", + "\n", + " actors \\\n", + "0 [том хэнкс, тим аллен, энни поттс, тони хейл, ... \n", + "1 [сандра буллок, джон хэмм, майкл китон, эллисо... \n", + "2 [стив карелл, кристен уиг, бенджамин брэтт, ми... \n", + "3 [джон си райли, сара силверман, галь гадот, та... \n", + "4 [оуэн уилсон, пол ньюман, бонни хант, ларри-ка... \n", + "5 [брайтон шарбино, доминик монахэн, уилл пэттон... \n", + "6 [арнольд шварценеггер, карл уэзерс, эльпидия к... \n", + "7 [эми мэнсон, доминик мафэм, люк аллен-гейл, дж... \n", + "8 [линда хэмилтон, арнольд шварценеггер, маккенз... \n", + "9 [эдриан броуди, тофер грейс, алиси брага, уолт... \n", + "10 [джонас черник, эмили хэмпшир, сара мэннинен, ... \n", + "11 [аоми муйок, карл глусман, клара кристин, уго ... \n", + "12 [ноэми мерлан, нильс шнайдер, бенжамен лаверн,... \n", + "13 [дебора франсуа, ален коши, матье деми, бенжам... \n", + "14 [наоми уоттс, робин райт, завьер сэмюэл, джейм... \n", + "\n", + " description \\\n", + "0 Космический рейнджер Баз Лайтер, ковбой Вуди, ... \n", + "1 Миньоны живут на планете гораздо дольше нас. У... \n", + "2 В то время как Грю, бывший суперзлодей, приспо... \n", + "3 На этот раз Ральф и Ванилопа фон Кекс выйдут з... \n", + "4 Неукротимый в своем желании всегда и во всем п... \n", + "5 Риз с легкостью проходит виртуальные квесты, н... \n", + "6 Американский вертолет был сбит партизанами в Ю... \n", + "7 Отряд морпехов прилетает на марсианский спутни... \n", + "8 Мексика. Милая девушка Даниэла Рамос, а для др... \n", + "9 Наемник Ройс невольно вынужден возглавить груп... \n", + "10 Чтобы вернуть свою неудовлетворенную бывшую де... \n", + "11 Любовь вне добра и зла. Любовь — это генетичес... \n", + "12 Историческая драма про любовный треугольник, к... \n", + "13 Лаура — 19-летняя первокурсница французского у... \n", + "14 Главные героини картины – Лил и Роз — две давн... \n", + "\n", + " keywords \\\n", + "0 [игрушка, дружба, ковбой, история игрушек 4, ,... \n", + "1 [помощник, сцена после титров, сцена во время ... \n", + "2 [отношения родитель-ребенок, секретный агент, ... \n", + "3 [видеоигра, мультфильм, продолжение, интернет,... \n", + "4 [автомобильная гонка, трасса 66, porsche, выхо... \n", + "5 [2019, соединенные штаты, радиовспышка] \n", + "6 [центральная и южная америка, хищник, иноплане... \n", + "7 [планета марс, ад, космос, демон, по мотивам в... \n", + "8 [искуственный интеллект, киборг, вертолет, мех... \n", + "9 [охотник, хищник, якудза, охота на людей, иноп... \n", + "10 [нижнее белье, массажистка, секс втроем, фалло... \n", + "11 [париж, франция, секс, сексуальность, галерея,... \n", + "12 [, 1890-е, большой пенис, брак без секса, вдох... \n", + "13 [франция, гостиница, по роману или книге, гост... \n", + "14 [пляж, нагота, любовники, месть, лучший друг, ... \n", + "\n", + " genre \n", + "0 [мультфильм, фэнтези, комедии] \n", + "1 [фантастика, мультфильм, приключения, комедии] \n", + "2 [мультфильм, приключения, фантастика, фэнтези,... \n", + "3 [мультфильм, приключения, фантастика, семейное... \n", + "4 [спорт, мультфильм, комедии] \n", + "5 [боевики, драмы, фантастика, триллеры] \n", + "6 [боевики, фантастика, триллеры, приключения] \n", + "7 [боевики, ужасы, фантастика, триллеры] \n", + "8 [боевики, фантастика, приключения] \n", + "9 [боевики, фантастика, триллеры, приключения] \n", + "10 [мелодрамы] \n", + "11 [драмы, мелодрамы] \n", + "12 [историческое, мелодрамы] \n", + "13 [драмы, мелодрамы] \n", + "14 [драмы, мелодрамы] " + ] + }, + "execution_count": 269, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recos_with_avatars.merge(items, on='item_id', how='left')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "В целом, все рекомендации к каждому аватару получились неплохие" + ] + }, + { + "cell_type": "markdown", + "id": "ab12c89f", + "metadata": {}, + "source": [ + " # Метод приближенного поиска соседей для выдачи рекомендаций.\n", + "\n", + "Воспользоваться методом приближенного поиска соседей для выдачи рекомендаций. **(3 балла)**\n", + "Можно использовать любые удобные: [`Annoy`](https://github.com/spotify/annoy), [`nmslib`](https://github.com/nmslib/nmslib) и.т.д" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "5d1161b4", + "metadata": {}, + "outputs": [], + "source": [ + "LEARNING_RATE = 0.08165160206425184\n", + "LOSS = 'warp'" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "9f20ae6e", + "metadata": {}, + "outputs": [], + "source": [ + "# обучаем LightFM, чтобы достать из нее вектора пользователей и айтемов\n", + "model = LightFMWrapperModel(\n", + " LightFM(\n", + " k=K,\n", + " no_components=NO_COMPONENTS,\n", + " loss= LOSS,\n", + " random_state=RANDOM_STATE,\n", + " learning_rate=LEARNING_RATE,\n", + " user_alpha=USER_ALPHA,\n", + " item_alpha=ITEM_ALPHA\n", + " ),\n", + " epochs=N_EPOCHS,\n", + " num_threads=NUM_THREADS\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "9982d55c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.fit(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "348b4fd6", + "metadata": {}, + "outputs": [], + "source": [ + "user_embeddings, item_embeddings = model.get_vectors(dataset)" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "fd296cf4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "((756545, 34), (13963, 34))" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings.shape, item_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "d75b4570", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-2.48910075e+02, 1.00000000e+00, -3.04745167e-01, 1.30259299e-01,\n", + " -1.25937782e-01, 1.32810516e-01, -3.98682870e-01, 2.12211904e-01,\n", + " 3.15063161e-01, 9.48599975e-03, 1.79876286e-01, -1.15210674e-01,\n", + " 3.13044085e-01, 5.25500635e-02, -8.94866249e-02, 6.32450803e-02,\n", + " 3.30464664e-01, -2.79290127e-01, 7.66675368e-02, 2.69704125e-01,\n", + " -2.02872234e-01, 3.65543869e-02, -2.08750917e-01, -7.48397237e-02,\n", + " 2.09714412e-01, 1.28161004e-01, -2.49842146e-01, 7.57336145e-02,\n", + " 6.74582969e-02, 2.03054725e-01, -4.46441335e-02, 1.00222239e-01,\n", + " 3.09746759e-01, 2.26963989e-01])" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#пользователь со средним значением по каждому признаку\n", + "first_person = user_embeddings.mean(0)\n", + "first_person" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "88198015", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-364.41271973, 1. , -2.19337273, -2.05960441,\n", + " -3.03305483, -2.15237951, -3.10027146, -1.44008625,\n", + " -1.55592728, -1.69499218, -1.87335801, -3.19125104,\n", + " -1.8664068 , -2.62357092, -2.23808742, -1.78050435,\n", + " -1.67308342, -2.70261121, -1.94637215, -2.44766903,\n", + " -2.40233946, -1.93648934, -2.32535124, -2.73280096,\n", + " -2.20278382, -1.93085539, -2.29366779, -1.9847883 ,\n", + " -2.619452 , -1.8447926 , -2.03915739, -1.86472845,\n", + " -1.80441463, -1.98137343])" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#пользователь со минимальным значением по каждому признаку\n", + "second_person = user_embeddings.min(axis=0)\n", + "second_person" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "4e02dec3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([0. , 1. , 1.80414879, 2.91568851, 2.57092023,\n", + " 2.49563074, 3.0165813 , 2.02071786, 2.10402703, 1.86775827,\n", + " 1.81193578, 2.3456769 , 2.37611055, 4.0926795 , 1.8776809 ,\n", + " 1.91333187, 2.16625547, 1.76979506, 1.87265527, 2.63360167,\n", + " 1.97114313, 1.88249838, 1.89424872, 2.15507913, 2.38049865,\n", + " 1.99921763, 1.80478072, 1.8311218 , 3.32906055, 2.25318193,\n", + " 2.0245254 , 2.37490654, 2.28989363, 1.97282732])" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#пользователь со максимальным значением по каждому признаку\n", + "third_person = user_embeddings.max(axis=0)\n", + "third_person" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "75a314ac", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(756545, 34)" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_embeddings.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "3cb72431", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(756548, 34)" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# добавим векотра 3х новых пользователей\n", + "user_embeddings = np.append(user_embeddings, np.array([first_person,\n", + " second_person, third_person]), axis=0)\n", + "user_embeddings.shape\n" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "db53d401", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150, 'post': 0, 'chunkIndexSize': 10000}\n" + ] + } + ], + "source": [ + "M = 50\n", + "efC = 150\n", + "\n", + "num_threads = 8\n", + "chunkIndexSize = 10000\n", + "\n", + "index_time_params = {\n", + " 'M': M,\n", + " 'indexThreadQty': num_threads,\n", + " 'efConstruction': efC,\n", + " 'post': 0,\n", + " 'chunkIndexSize': chunkIndexSize,\n", + " }\n", + "print ('Index-time parameters', index_time_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "e09782e5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13963" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "K = 10\n", + "space_name = 'negdotprod'\n", + "index = nmslib.init(method='hnsw', space=space_name,\n", + " data_type=nmslib.DataType.DENSE_VECTOR)\n", + "index.addDataPointBatch(item_embeddings)" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "209d778e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index-time parameters {'M': 50, 'indexThreadQty': 8, 'efConstruction': 150}\n", + "Indexing time = 1.392440\n" + ] + } + ], + "source": [ + "start = time.time()\n", + "index_time_params = {'M': M, 'indexThreadQty': num_threads,\n", + " 'efConstruction': efC}\n", + "index.createIndex(index_time_params)\n", + "end = time.time()\n", + "print('Index-time parameters', index_time_params)\n", + "print('Indexing time = %f' % (end - start))" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "998dad8b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setting query-time parameters {'efSearch': 100}\n" + ] + } + ], + "source": [ + "efS = 100\n", + "query_time_params = {'efSearch': efS}\n", + "print('Setting query-time parameters', query_time_params)\n", + "index.setQueryTimeParams(query_time_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "6f5cd03c", + "metadata": {}, + "outputs": [], + "source": [ + "query_matrix = user_embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "77039943", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "kNN time total=3.962551 (sec), per query=0.000005 (sec), per query adjusted for thread number=0.000042 (sec)\n" + ] + } + ], + "source": [ + "query_qty = query_matrix.shape[0]\n", + "start = time.time()\n", + "nbrs = index.knnQueryBatch(query_matrix, k=K, num_threads=num_threads)\n", + "end = time.time()\n", + "print(\n", + " 'kNN time total=%f (sec), per query=%f (sec), per query adjusted for thread number=%f (sec)' \\\n", + " % (end - start, float(end - start) / query_qty, num_threads * float(end - start) / query_qty)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "id": "cac18e0e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 32, 19, 43, ..., 31, 36, 69],\n", + " [ 31, 262, 62, ..., 32, 121, 735],\n", + " [ 19, 31, 121, ..., 29, 62, 105],\n", + " ...,\n", + " [ 31, 19, 43, ..., 268, 100, 86],\n", + " [ 19, 31, 32, ..., 268, 49, 173],\n", + " [ 19, 31, 32, ..., 100, 105, 268]])" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# рекомендации для всех пользователей\n", + "recos_old_persons = np.array(nbrs, dtype=int)[:,0][:len(nbrs) - 3]\n", + "recos_old_persons" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "918c6976", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 31, 19, 32, 43, 62, 121, 173, 268, 100,\n", + " 86],\n", + " [12018, 10998, 7308, 12006, 10159, 10215, 3543, 8118, 8180,\n", + " 11511],\n", + " [ 8453, 6400, 3557, 3945, 6642, 4779, 3583, 2068, 8668,\n", + " 371]])" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# рекомендации для добавленных пользователей\n", + "recos_new_persons = np.array(nbrs, dtype=int)[:,0][-3:]\n", + "recos_new_persons" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "id": "c78fbc6a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
user_iditem_id
0032
1019
2043
3062
40449
.........
756544575654443
756544675654429
7565447756544100
7565448756544105
7565449756544268
\n", + "

7565450 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " user_id item_id\n", + "0 0 32\n", + "1 0 19\n", + "2 0 43\n", + "3 0 62\n", + "4 0 449\n", + "... ... ...\n", + "7565445 756544 43\n", + "7565446 756544 29\n", + "7565447 756544 100\n", + "7565448 756544 105\n", + "7565449 756544 268\n", + "\n", + "[7565450 rows x 2 columns]" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_r = \\\n", + " pd.DataFrame({'user_id': np.repeat(np.arange(len(recos_old_persons)),\n", + " 10), Columns.Item: recos_old_persons.ravel()})\n", + "df_r\n" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "902cbca6", + "metadata": {}, + "outputs": [], + "source": [ + "df_r.to_csv('nmslib.csv.gz', index=False, compression='gzip')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "# Холодные пользователи\n", + "Придумать как можно обработать рекомендации для холодных пользователей. **(3 балла)**\n", + "\n", + "В предыдущей домашке, мы выяснили, что на этом датасете лучше всего себя ведет топ за последний месяц. Поэтому каждую модель мы использовали с подобным методом добивки холодных пользователей\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "39d02966", + "metadata": {}, + "source": [ + "# For baseline\n", + "Пробитие бейзлайна MAP@10 >= 0.074921 (6 баллов).\n", + "Чтобы пробить бейзлайн, было принято решение обучиться на всем датасете" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8f6d0f92", + "metadata": {}, + "outputs": [], + "source": [ + "data = Dataset.construct(\n", + " interactions,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "model = ImplicitALSWrapperModel(\n", + " model=AlternatingLeastSquares(\n", + " factors=32,\n", + " random_state=RANDOM_STATE,\n", + " num_threads=NUM_THREADS,\n", + " regularization=REGULARIZATION\n", + " ),\n", + " fit_features_together=True\n", + ")\n", + "\n", + "model.fit(data)\n", + "recos = model.recommend(\n", + " users=TEST_USERS,\n", + " dataset=data,\n", + " k=10,\n", + " filter_viewed=True\n", + ")\n", + "\n", + "recos = recos[['user_id', 'item_id']]\n", + "recos.to_csv('ALSnew.csv.gz', index=False, compression='gzip')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}