{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":38760,"databundleVersionId":4493939,"sourceType":"competition"},{"sourceId":4436180,"sourceType":"datasetVersion","datasetId":2597726}],"dockerImageVersionId":30684,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd, numpy as np\n\nimport glob\n\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nfrom datetime import datetime\n\nfrom tqdm import tqdm\n\ntype_labels = {'clicks':1, 'carts':2, 'orders':3}","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:52:20.225078Z","iopub.execute_input":"2024-06-09T05:52:20.226789Z","iopub.status.idle":"2024-06-09T05:52:20.234990Z","shell.execute_reply.started":"2024-06-09T05:52:20.226722Z","shell.execute_reply":"2024-06-09T05:52:20.233619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load(which):    \n    dfs = []\n\n    test_files = glob.glob('/kaggle/input/otto-chunk-data-inparquet-format/'+which+'_parquet/*')\n    \n    for e, chunk_file in enumerate(test_files):\n        chunk = pd.read_parquet(chunk_file)\n        chunk.ts = (chunk.ts/1000).astype('int32')\n        chunk['type'] = chunk['type'].map(type_labels).astype('int8')\n        dfs.append(chunk)\n        \n    return pd.concat(dfs).reset_index(drop=True) #.astype({\"ts\": \"datetime64[ms]\"})","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:52:20.237310Z","iopub.execute_input":"2024-06-09T05:52:20.237647Z","iopub.status.idle":"2024-06-09T05:52:20.247878Z","shell.execute_reply.started":"2024-06-09T05:52:20.237619Z","shell.execute_reply":"2024-06-09T05:52:20.246750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = load('train')","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:52:20.249142Z","iopub.execute_input":"2024-06-09T05:52:20.249473Z","iopub.status.idle":"2024-06-09T05:53:14.368965Z","shell.execute_reply.started":"2024-06-09T05:52:20.249434Z","shell.execute_reply":"2024-06-09T05:53:14.368045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = load('test')","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:53:14.370476Z","iopub.execute_input":"2024-06-09T05:53:14.370895Z","iopub.status.idle":"2024-06-09T05:53:16.248994Z","shell.execute_reply.started":"2024-06-09T05:53:14.370856Z","shell.execute_reply":"2024-06-09T05:53:16.247803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = train_df[train_df['ts']>=1661385600].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:53:16.252216Z","iopub.execute_input":"2024-06-09T05:53:16.252581Z","iopub.status.idle":"2024-06-09T05:53:18.181338Z","shell.execute_reply.started":"2024-06-09T05:53:16.252550Z","shell.execute_reply":"2024-06-09T05:53:18.178763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['datetime'] = train_df['ts'].apply(lambda x: datetime.fromtimestamp(x))","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:53:18.183826Z","iopub.execute_input":"2024-06-09T05:53:18.184276Z","iopub.status.idle":"2024-06-09T05:54:30.266957Z","shell.execute_reply.started":"2024-06-09T05:53:18.184233Z","shell.execute_reply":"2024-06-09T05:54:30.265578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['day'] = train_df['datetime'].dt.day","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:30.268539Z","iopub.execute_input":"2024-06-09T05:54:30.268882Z","iopub.status.idle":"2024-06-09T05:54:31.113524Z","shell.execute_reply.started":"2024-06-09T05:54:30.268852Z","shell.execute_reply":"2024-06-09T05:54:31.112361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_val_offline = train_df[train_df['day']==28].reset_index(drop=True)\ndf_train_offline = train_df[train_df['day']==27].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:31.114976Z","iopub.execute_input":"2024-06-09T05:54:31.115288Z","iopub.status.idle":"2024-06-09T05:54:32.216612Z","shell.execute_reply.started":"2024-06-09T05:54:31.115261Z","shell.execute_reply":"2024-06-09T05:54:32.215618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_offline=df_train_offline.iloc[:10000]\ndf_val_offline=df_val_offline.iloc[:10000]","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.217865Z","iopub.execute_input":"2024-06-09T05:54:32.218204Z","iopub.status.idle":"2024-06-09T05:54:32.223861Z","shell.execute_reply.started":"2024-06-09T05:54:32.218177Z","shell.execute_reply":"2024-06-09T05:54:32.222797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_offline['user_label'], user_idx = pd.factorize(df_train_offline[\"session\"])# factorize函数是为了将用户和商品转化为连续的整数，更直观的展示矩阵\ndf_train_offline['item_label'], item_idx = pd.factorize(df_train_offline[\"aid\"])","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.225152Z","iopub.execute_input":"2024-06-09T05:54:32.225465Z","iopub.status.idle":"2024-06-09T05:54:32.238246Z","shell.execute_reply.started":"2024-06-09T05:54:32.225439Z","shell.execute_reply":"2024-06-09T05:54:32.237217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_offline['user_label'].max()","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.239578Z","iopub.execute_input":"2024-06-09T05:54:32.239978Z","iopub.status.idle":"2024-06-09T05:54:32.247403Z","shell.execute_reply.started":"2024-06-09T05:54:32.239941Z","shell.execute_reply":"2024-06-09T05:54:32.246443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_offline['item_label'].max()","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.248660Z","iopub.execute_input":"2024-06-09T05:54:32.249065Z","iopub.status.idle":"2024-06-09T05:54:32.259593Z","shell.execute_reply.started":"2024-06-09T05:54:32.249034Z","shell.execute_reply":"2024-06-09T05:54:32.258553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_val_offline['user_label'], user_idx = pd.factorize(df_val_offline[\"session\"])# factorize函数是为了将用户和商品转化为连续的整数，更直观的展示矩阵\ndf_val_offline['item_label'], item_idx = pd.factorize(df_val_offline[\"aid\"])","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.260737Z","iopub.execute_input":"2024-06-09T05:54:32.261082Z","iopub.status.idle":"2024-06-09T05:54:32.270723Z","shell.execute_reply.started":"2024-06-09T05:54:32.261055Z","shell.execute_reply":"2024-06-09T05:54:32.269670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_val_offline['user_label'].max()","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.276073Z","iopub.execute_input":"2024-06-09T05:54:32.276370Z","iopub.status.idle":"2024-06-09T05:54:32.283769Z","shell.execute_reply.started":"2024-06-09T05:54:32.276344Z","shell.execute_reply":"2024-06-09T05:54:32.282777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_val_offline['item_label'].max()","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.284965Z","iopub.execute_input":"2024-06-09T05:54:32.285281Z","iopub.status.idle":"2024-06-09T05:54:32.294463Z","shell.execute_reply.started":"2024-06-09T05:54:32.285256Z","shell.execute_reply":"2024-06-09T05:54:32.293452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_offline = df_train_offline.sort_values('ts',ascending=True).reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.295671Z","iopub.execute_input":"2024-06-09T05:54:32.296038Z","iopub.status.idle":"2024-06-09T05:54:32.309340Z","shell.execute_reply.started":"2024-06-09T05:54:32.296009Z","shell.execute_reply":"2024-06-09T05:54:32.308230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"session_aids_df = df_train_offline[['user_label','item_label']].groupby('user_label',as_index=False).agg(list)","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.310703Z","iopub.execute_input":"2024-06-09T05:54:32.311088Z","iopub.status.idle":"2024-06-09T05:54:32.380337Z","shell.execute_reply.started":"2024-06-09T05:54:32.311051Z","shell.execute_reply":"2024-06-09T05:54:32.379336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import defaultdict","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.381676Z","iopub.execute_input":"2024-06-09T05:54:32.382029Z","iopub.status.idle":"2024-06-09T05:54:32.386572Z","shell.execute_reply.started":"2024-06-09T05:54:32.382000Z","shell.execute_reply":"2024-06-09T05:54:32.385574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#drop_duplicated(keep='last')\nsession_aids_df['session_activity'] = session_aids_df['item_label'].apply(lambda x: len(x))","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.387887Z","iopub.execute_input":"2024-06-09T05:54:32.388257Z","iopub.status.idle":"2024-06-09T05:54:32.402232Z","shell.execute_reply.started":"2024-06-09T05:54:32.388222Z","shell.execute_reply":"2024-06-09T05:54:32.401251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"session_dict = dict(zip(session_aids_df['user_label'],session_aids_df['session_activity']))","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.403402Z","iopub.execute_input":"2024-06-09T05:54:32.403722Z","iopub.status.idle":"2024-06-09T05:54:32.413681Z","shell.execute_reply.started":"2024-06-09T05:54:32.403687Z","shell.execute_reply":"2024-06-09T05:54:32.412566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import math","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.415294Z","iopub.execute_input":"2024-06-09T05:54:32.415600Z","iopub.status.idle":"2024-06-09T05:54:32.424318Z","shell.execute_reply.started":"2024-06-09T05:54:32.415565Z","shell.execute_reply":"2024-06-09T05:54:32.423318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"item_Sim = defaultdict()\n\nfor i,row in tqdm( session_aids_df.iterrows(), total=len(session_aids_df) ):\n    \n    aid_list = row['item_label']\n    \n    for loc1, item in enumerate(aid_list):\n        \n        item_Sim.setdefault(item,dict())\n        \n        for loc2, related_item in enumerate(aid_list):\n            if item == related_item:\n                continue\n        \n            item_Sim[item].setdefault(related_item,0)\n            \n            if loc1 < loc2:\n                item_Sim[item][related_item] += 1 * 0.7 ** (loc2-loc1-1) * 1/math.log(session_dict[row['user_label']]+1)\n            else:\n                item_Sim[item][related_item] += 0.7 * 0.7 ** (loc1-loc2-1) * 1/math.log(session_dict[row['user_label']]+1)","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:32.425528Z","iopub.execute_input":"2024-06-09T05:54:32.425832Z","iopub.status.idle":"2024-06-09T05:54:34.121237Z","shell.execute_reply.started":"2024-06-09T05:54:32.425805Z","shell.execute_reply":"2024-06-09T05:54:34.120372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"session_items_val = df_val_offline.groupby(['user_label'],as_index=False)['item_label'].agg(set)","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:34.122821Z","iopub.execute_input":"2024-06-09T05:54:34.123164Z","iopub.status.idle":"2024-06-09T05:54:34.170008Z","shell.execute_reply.started":"2024-06-09T05:54:34.123135Z","shell.execute_reply":"2024-06-09T05:54:34.168865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"session_items_val","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:34.171340Z","iopub.execute_input":"2024-06-09T05:54:34.171640Z","iopub.status.idle":"2024-06-09T05:54:34.186885Z","shell.execute_reply.started":"2024-06-09T05:54:34.171613Z","shell.execute_reply":"2024-06-09T05:54:34.185829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# to be continue","metadata":{}},{"cell_type":"code","source":"aid = df_train_offline[df_train_offline['type'] == 1]\naid_count = aid.groupby('aid').size().reset_index(name = 'counts')","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:35.094884Z","iopub.execute_input":"2024-06-09T05:54:35.095334Z","iopub.status.idle":"2024-06-09T05:54:35.106855Z","shell.execute_reply.started":"2024-06-09T05:54:35.095293Z","shell.execute_reply":"2024-06-09T05:54:35.105892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install implicit \nimport scipy.sparse as sparse# 处理稀疏矩阵\nimport implicit# 处理隐式数据\nUSER_ID = 'session'\nITEM_ID = 'aid'\nSEED = 0\nuser_item_matrix = sparse.csr_matrix((np.ones(len(df_train_offline)),# 创建一个df行数的数组，指定用户和有交互的商品之间值为1\n                                     (df_train_offline['user_label'], df_train_offline['item_label'])))#可以用recommodation 函数：第一个是用户编码，第二个是\nepoch, emb_size = 100, 64# 迭代次数和隐式因子个数\n# 用隐式反馈推荐\nmodel = implicit.bpr.BayesianPersonalizedRanking(factors = emb_size, # 隐式因子的个数\n                                                 regularization=0.001, # 正则化参数：防止过拟合\n                                                 iterations=epoch,# 迭代次数\n                                                 random_state=SEED)# 随机种子\nmodel.fit(user_item_matrix)# 模型学习过程","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:35.108231Z","iopub.execute_input":"2024-06-09T05:54:35.108596Z","iopub.status.idle":"2024-06-09T05:54:48.925403Z","shell.execute_reply.started":"2024-06-09T05:54:35.108550Z","shell.execute_reply":"2024-06-09T05:54:48.924257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\n\nnum_users = user_item_matrix.shape[0]\ntop_num = 20\nrecommendation_all = {}\n\n# 使用 tqdm(range(num_users)) 替代原本的 range(num_users)\nfor user_id in tqdm(range(num_users)):\n    top_bpr = model.recommend(user_id, user_item_matrix[user_id], N=top_num)# 给出模型认为该用户最可能喜欢的N个物品。\n    recommendation_all[user_id] = top_bpr\n    ","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:48.927338Z","iopub.execute_input":"2024-06-09T05:54:48.928168Z","iopub.status.idle":"2024-06-09T05:54:51.751231Z","shell.execute_reply.started":"2024-06-09T05:54:48.928123Z","shell.execute_reply":"2024-06-09T05:54:51.749993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 获取用户嵌入向量\nuser_embeddings = model.user_factors\n\n# 获取商品嵌入向量\nitem_embeddings = model.item_factors","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:51.752934Z","iopub.execute_input":"2024-06-09T05:54:51.753237Z","iopub.status.idle":"2024-06-09T05:54:51.764082Z","shell.execute_reply.started":"2024-06-09T05:54:51.753210Z","shell.execute_reply":"2024-06-09T05:54:51.762752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 打印用户和商品嵌入向量的维度\nprint(\"User Embeddings Shape:\", user_embeddings.shape)\nprint(\"Item Embeddings Shape:\", item_embeddings.shape)","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:51.765783Z","iopub.execute_input":"2024-06-09T05:54:51.766182Z","iopub.status.idle":"2024-06-09T05:54:51.780546Z","shell.execute_reply.started":"2024-06-09T05:54:51.766145Z","shell.execute_reply":"2024-06-09T05:54:51.779455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cosine_similarity = np.dot(user_embeddings, item_embeddings.T) / (np.linalg.norm(user_embeddings) * np.linalg.norm(item_embeddings.T))\n\n# 计算点积相似度\ndot_product_similarity = np.dot(user_embeddings, item_embeddings.T)","metadata":{"execution":{"iopub.status.busy":"2024-06-09T05:54:51.782545Z","iopub.execute_input":"2024-06-09T05:54:51.786051Z","iopub.status.idle":"2024-06-09T05:54:51.969880Z","shell.execute_reply.started":"2024-06-09T05:54:51.786023Z","shell.execute_reply":"2024-06-09T05:54:51.968212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_users = dot_product_similarity.shape[0]\nn_items = dot_product_similarity.shape[1]\n\nresult_dict = {}\nfor i in range(n_users):\n    user_dict = {}\n    for j in range(n_items):\n        user_dict[j] = dot_product_similarity[i][j]\n    result_dict[i] = user_dict","metadata":{"execution":{"iopub.status.busy":"2024-06-09T07:04:28.206502Z","iopub.execute_input":"2024-06-09T07:04:28.207057Z","iopub.status.idle":"2024-06-09T07:04:38.574218Z","shell.execute_reply.started":"2024-06-09T07:04:28.207014Z","shell.execute_reply":"2024-06-09T07:04:38.573088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"weight_item_Sim = 0.6  # 假设 item_Sim 的权重\nweight_result_dict = 0.4  # 假设 result_dict 的权重\n\ncombined_dict = {}\n\nfor i in tqdm(range(n_users)):\n    combined_user_dict = {}\n    for j in range(n_items):\n        # 获取 item_Sim 中的值\n        item_Sim_value = item_Sim.get(i, {}).get(j, 0)\n        # 获取 result_dict 中的值\n        result_dict_value = result_dict.get(i, {}).get(j, 0)\n\n        # 按照权重计算并合并\n        combined_value = weight_item_Sim * item_Sim_value + weight_result_dict * result_dict_value\n\n        combined_user_dict[j] = combined_value\n    combined_dict[i] = combined_user_dict\n","metadata":{"execution":{"iopub.status.busy":"2024-06-09T07:20:16.806843Z","iopub.execute_input":"2024-06-09T07:20:16.807595Z","iopub.status.idle":"2024-06-09T07:21:19.719317Z","shell.execute_reply.started":"2024-06-09T07:20:16.807558Z","shell.execute_reply":"2024-06-09T07:21:19.718067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import defaultdict\n\n# 假设 item_Sim 已经根据之前的代码段构建好了\n\ndef predict_for_session(session_aids, item_sim, top_n=20):\n\n    session_set = set(session_aids)\n    recommendations = defaultdict(int)\n    \n    for item in session_set:\n        # 检查 item 是否在 item_sim 字典中\n        if item in item_sim:\n            # 检查 item_sim[item] 是否是一个字典\n            if isinstance(item_sim[item], dict):\n                # 安全地迭代 item_sim[item] 的项\n                for related_item, count in item_sim[item].items():\n                    if related_item not in session_set:\n                        recommendations[related_item] += count\n    # 按分数降序排序推荐物品\n    sorted_recommendations = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)\n    \n    # 返回 top_n 推荐\n    return sorted_recommendations[:top_n]","metadata":{"execution":{"iopub.status.busy":"2024-06-09T07:24:11.615521Z","iopub.execute_input":"2024-06-09T07:24:11.616041Z","iopub.status.idle":"2024-06-09T07:24:11.626117Z","shell.execute_reply.started":"2024-06-09T07:24:11.615990Z","shell.execute_reply":"2024-06-09T07:24:11.624649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def evaluate_sessions(df_val, item_sim, top_n=5):\n    actual_items = defaultdict(set)\n    predicted_items = defaultdict(set)\n    \n    # 使用 tqdm 包装迭代器以显示进度条\n    for index, row in tqdm(df_val.iterrows(), total=df_val.shape[0]):\n        session = row['user_label']\n        # 确保 aids 是一个列表\n        aids = [row['item_label']]\n        \n        # 将实际的物品添加到集合中\n        actual_items[session].update(aids)\n        \n        top_items = predict_for_session(aids, item_sim, top_n=top_n)\n        for item, _ in top_items:\n            predicted_items[session].add(item)\n\n    precision_at_k = {}\n    \n    for session, actual_set in actual_items.items():\n        predicted_set = predicted_items[session]\n        common = actual_set.intersection(predicted_set)\n        precision_at_k[session] = len(common) / top_n\n    \n    overall_precision = np.mean(list(precision_at_k.values()))\n\n    return overall_precision","metadata":{"execution":{"iopub.status.busy":"2024-06-09T07:24:15.535893Z","iopub.execute_input":"2024-06-09T07:24:15.536417Z","iopub.status.idle":"2024-06-09T07:24:15.550805Z","shell.execute_reply.started":"2024-06-09T07:24:15.536379Z","shell.execute_reply":"2024-06-09T07:24:15.549408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 使用验证集进行评估\ntop_n = 20  # 假设我们想要 top 20 的推荐\nprecision = evaluate_sessions(df_val_offline,combined_dict, top_n=top_n)\nprint(f\"Precision@{top_n}: {precision:.6f}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-09T07:27:31.001846Z","iopub.execute_input":"2024-06-09T07:27:31.002729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}