{"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":"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"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-06T11:41:27.171716Z","iopub.execute_input":"2024-06-06T11:41:27.172167Z","iopub.status.idle":"2024-06-06T11:41:28.906652Z","shell.execute_reply.started":"2024-06-06T11:41:27.172133Z","shell.execute_reply":"2024-06-06T11:41:28.905195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"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-06T11:41:28.909631Z","iopub.execute_input":"2024-06-06T11:41:28.910149Z","iopub.status.idle":"2024-06-06T11:41:28.920153Z","shell.execute_reply.started":"2024-06-06T11:41:28.910117Z","shell.execute_reply":"2024-06-06T11:41:28.918002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = load('train')","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:41:28.929978Z","iopub.execute_input":"2024-06-06T11:41:28.930429Z","iopub.status.idle":"2024-06-06T11:42:39.920418Z","shell.execute_reply.started":"2024-06-06T11:41:28.930395Z","shell.execute_reply":"2024-06-06T11:42:39.919201Z"},"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-06T11:42:39.923918Z","iopub.execute_input":"2024-06-06T11:42:39.924421Z","iopub.status.idle":"2024-06-06T11:42:41.90829Z","shell.execute_reply.started":"2024-06-06T11:42:39.924379Z","shell.execute_reply":"2024-06-06T11:42:41.906234Z"},"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-06T11:42:41.909863Z","iopub.execute_input":"2024-06-06T11:42:41.91035Z","iopub.status.idle":"2024-06-06T11:43:57.672647Z","shell.execute_reply.started":"2024-06-06T11:42:41.91031Z","shell.execute_reply":"2024-06-06T11:43:57.67122Z"},"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-06T11:43:57.674814Z","iopub.execute_input":"2024-06-06T11:43:57.675325Z","iopub.status.idle":"2024-06-06T11:43:58.597225Z","shell.execute_reply.started":"2024-06-06T11:43:57.675282Z","shell.execute_reply":"2024-06-06T11:43:58.595561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"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']<28].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:43:58.598935Z","iopub.execute_input":"2024-06-06T11:43:58.599398Z","iopub.status.idle":"2024-06-06T11:44:00.791075Z","shell.execute_reply.started":"2024-06-06T11:43:58.599318Z","shell.execute_reply":"2024-06-06T11:44:00.789771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_val_offline","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:00.793287Z","iopub.execute_input":"2024-06-06T11:44:00.793804Z","iopub.status.idle":"2024-06-06T11:44:00.819544Z","shell.execute_reply.started":"2024-06-06T11:44:00.793763Z","shell.execute_reply":"2024-06-06T11:44:00.817804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_offline","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:00.821764Z","iopub.execute_input":"2024-06-06T11:44:00.822218Z","iopub.status.idle":"2024-06-06T11:44:00.840937Z","shell.execute_reply.started":"2024-06-06T11:44:00.822187Z","shell.execute_reply":"2024-06-06T11:44:00.838658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#只加载前1000用户数据\ndf_train_offline = df_train_offline[df_train_offline['session'].isin(df_train_offline['session'].unique()[:1000])].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:00.842771Z","iopub.execute_input":"2024-06-06T11:44:00.843362Z","iopub.status.idle":"2024-06-06T11:44:01.528789Z","shell.execute_reply.started":"2024-06-06T11:44:00.843304Z","shell.execute_reply":"2024-06-06T11:44:01.527072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_offline","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.530627Z","iopub.execute_input":"2024-06-06T11:44:01.531007Z","iopub.status.idle":"2024-06-06T11:44:01.549522Z","shell.execute_reply.started":"2024-06-06T11:44:01.530977Z","shell.execute_reply":"2024-06-06T11:44:01.546958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"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-06T11:44:01.551907Z","iopub.execute_input":"2024-06-06T11:44:01.553165Z","iopub.status.idle":"2024-06-06T11:44:01.565906Z","shell.execute_reply.started":"2024-06-06T11:44:01.553113Z","shell.execute_reply":"2024-06-06T11:44:01.564311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_offline","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.574032Z","iopub.execute_input":"2024-06-06T11:44:01.574482Z","iopub.status.idle":"2024-06-06T11:44:01.59586Z","shell.execute_reply.started":"2024-06-06T11:44:01.574449Z","shell.execute_reply":"2024-06-06T11:44:01.594056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nsession_aids_df = df_train_offline[['session','aid']].groupby('session',as_index=False).agg(list)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.597882Z","iopub.execute_input":"2024-06-06T11:44:01.598293Z","iopub.status.idle":"2024-06-06T11:44:01.652133Z","shell.execute_reply.started":"2024-06-06T11:44:01.598246Z","shell.execute_reply":"2024-06-06T11:44:01.6509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"session_aids_df","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.6537Z","iopub.execute_input":"2024-06-06T11:44:01.65405Z","iopub.status.idle":"2024-06-06T11:44:01.677019Z","shell.execute_reply.started":"2024-06-06T11:44:01.654021Z","shell.execute_reply":"2024-06-06T11:44:01.67523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#df_val_offline","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.678933Z","iopub.execute_input":"2024-06-06T11:44:01.67937Z","iopub.status.idle":"2024-06-06T11:44:01.68772Z","shell.execute_reply.started":"2024-06-06T11:44:01.679336Z","shell.execute_reply":"2024-06-06T11:44:01.68652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#df_val_offline = df_val_offline.sort_values('ts',ascending=True).reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.689412Z","iopub.execute_input":"2024-06-06T11:44:01.690256Z","iopub.status.idle":"2024-06-06T11:44:01.702578Z","shell.execute_reply.started":"2024-06-06T11:44:01.690211Z","shell.execute_reply":"2024-06-06T11:44:01.701164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#session_items_val = df_val_offline.groupby(['session'], as_index=False)['aid'].agg(set)\n#print(session_items_val)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.704846Z","iopub.execute_input":"2024-06-06T11:44:01.705288Z","iopub.status.idle":"2024-06-06T11:44:01.719148Z","shell.execute_reply.started":"2024-06-06T11:44:01.70525Z","shell.execute_reply":"2024-06-06T11:44:01.717045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#session_items_val","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.721327Z","iopub.execute_input":"2024-06-06T11:44:01.721781Z","iopub.status.idle":"2024-06-06T11:44:01.734569Z","shell.execute_reply.started":"2024-06-06T11:44:01.721748Z","shell.execute_reply":"2024-06-06T11:44:01.732811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## 仅选择前1000个用户的数据\nsession_aids_df = session_aids_df[session_aids_df['session'].isin(session_aids_df['session'].unique()[:1000])].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.737133Z","iopub.execute_input":"2024-06-06T11:44:01.738953Z","iopub.status.idle":"2024-06-06T11:44:01.753865Z","shell.execute_reply.started":"2024-06-06T11:44:01.738905Z","shell.execute_reply":"2024-06-06T11:44:01.752471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"session_aids_df","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.755465Z","iopub.execute_input":"2024-06-06T11:44:01.755878Z","iopub.status.idle":"2024-06-06T11:44:01.781179Z","shell.execute_reply.started":"2024-06-06T11:44:01.755847Z","shell.execute_reply":"2024-06-06T11:44:01.779325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import defaultdict","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.783225Z","iopub.execute_input":"2024-06-06T11:44:01.783649Z","iopub.status.idle":"2024-06-06T11:44:01.795183Z","shell.execute_reply.started":"2024-06-06T11:44:01.783618Z","shell.execute_reply":"2024-06-06T11:44:01.793077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#drop_duplicated(keep='last')\nsession_aids_df['session_activity'] = session_aids_df['aid'].apply(lambda x: len(x))","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.797228Z","iopub.execute_input":"2024-06-06T11:44:01.797673Z","iopub.status.idle":"2024-06-06T11:44:01.81456Z","shell.execute_reply.started":"2024-06-06T11:44:01.797635Z","shell.execute_reply":"2024-06-06T11:44:01.813014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"session_aids_df","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.816711Z","iopub.execute_input":"2024-06-06T11:44:01.817193Z","iopub.status.idle":"2024-06-06T11:44:01.849534Z","shell.execute_reply.started":"2024-06-06T11:44:01.817158Z","shell.execute_reply":"2024-06-06T11:44:01.848057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"session_dict = dict(zip(session_aids_df['session'],session_aids_df['session_activity']))","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.851825Z","iopub.execute_input":"2024-06-06T11:44:01.852259Z","iopub.status.idle":"2024-06-06T11:44:01.862563Z","shell.execute_reply.started":"2024-06-06T11:44:01.852227Z","shell.execute_reply":"2024-06-06T11:44:01.860619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#session_dict","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.864665Z","iopub.execute_input":"2024-06-06T11:44:01.86513Z","iopub.status.idle":"2024-06-06T11:44:01.876019Z","shell.execute_reply.started":"2024-06-06T11:44:01.865072Z","shell.execute_reply":"2024-06-06T11:44:01.874714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import math","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.878373Z","iopub.execute_input":"2024-06-06T11:44:01.8788Z","iopub.status.idle":"2024-06-06T11:44:01.893048Z","shell.execute_reply.started":"2024-06-06T11:44:01.878768Z","shell.execute_reply":"2024-06-06T11:44:01.89172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.89431Z","iopub.execute_input":"2024-06-06T11:44:01.894739Z","iopub.status.idle":"2024-06-06T11:44:01.908885Z","shell.execute_reply.started":"2024-06-06T11:44:01.894707Z","shell.execute_reply":"2024-06-06T11:44:01.907636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def bpr_loss(pos_score, neg_score):#定义实用函数以计算每个样本的BPR损失\n    return -np.log(1.0 / (1.0 + np.exp(-(pos_score - neg_score))))","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.911385Z","iopub.execute_input":"2024-06-06T11:44:01.91202Z","iopub.status.idle":"2024-06-06T11:44:01.925249Z","shell.execute_reply.started":"2024-06-06T11:44:01.911967Z","shell.execute_reply":"2024-06-06T11:44:01.923854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 初始化item_Sim字典\nitem_Sim = defaultdict(dict)\nfor i, row in tqdm(session_aids_df.iterrows(), total=len(session_aids_df)):\n    aid_list = row['aid']\n    \n    for loc1, item in enumerate(aid_list):\n        item_Sim[item][item] = 0  # 添加项以正确处理自己与自己的情况\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                # BPR损失的正样本得分计算\n                pos_score = item_Sim[item][related_item]\n                \n                # 从所有item中随机选择一个负样本\n                negative_item = random.choice(list(item_Sim[item].keys()))\n                \n                # BPR损失的负样本得分计算\n                neg_score = item_Sim[item][negative_item]\n                \n                # BPR损失计算和更新\n                loss = bpr_loss(pos_score, neg_score)\n                item_Sim[item][related_item] -= loss * 0.7 ** (loc2 - loc1 - 1) * 1 / math.log(session_dict[row['session']] + 1)\n            else:\n                # BPR损失的正样本得分计算\n                pos_score = item_Sim[item][related_item]\n                \n                # 从所有item中随机选择一个负样本\n                negative_item = random.choice(list(item_Sim[item].keys()))\n                \n                # BPR损失的负样本得分计算\n                neg_score = item_Sim[item][negative_item]\n                \n                # BPR损失计算和更新\n                loss = bpr_loss(pos_score, neg_score)\n                item_Sim[item][related_item] += loss * 0.7 * 0.7 ** (loc1 - loc2 - 1) * 1 / math.log(session_dict[row['session']] + 1)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:01.927524Z","iopub.execute_input":"2024-06-06T11:44:01.928027Z","iopub.status.idle":"2024-06-06T11:44:05.476261Z","shell.execute_reply.started":"2024-06-06T11:44:01.927979Z","shell.execute_reply":"2024-06-06T11:44:05.475211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"aid_list","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:05.478165Z","iopub.execute_input":"2024-06-06T11:44:05.478562Z","iopub.status.idle":"2024-06-06T11:44:05.486416Z","shell.execute_reply.started":"2024-06-06T11:44:05.478523Z","shell.execute_reply":"2024-06-06T11:44:05.484936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#item_Sim","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:05.488324Z","iopub.execute_input":"2024-06-06T11:44:05.48871Z","iopub.status.idle":"2024-06-06T11:44:05.502648Z","shell.execute_reply.started":"2024-06-06T11:44:05.488673Z","shell.execute_reply":"2024-06-06T11:44:05.500854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"to be continue","metadata":{}},{"cell_type":"code","source":"# 创建一个新的字典，用于存储会话ID到推荐列表的映射\nres_dict = {}\n\n# 遍历session_aids_df的每一行\nfor _, row in session_aids_df.iterrows():\n    session_id = str(row['session'])  # 确保会话ID是字符串\n    aid_list = row['aid']\n    \n    #选择前20的物品\n    top_similar_items = sorted(item_Sim[aid_list[0]].items(), key=lambda x: x[1], reverse=True)[:20]\n    recommended_items = [item[0] for item in top_similar_items]\n\n    # 将推荐列表转换为字符串格式，并存储在res_dict中\n    res_dict[session_id] = ' '.join(map(str, recommended_items))  # 使用字符串会话ID作为键\n\n# 此时，res_dict包含了会话ID和对应推荐列表的字符串表示\n","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:05.504558Z","iopub.execute_input":"2024-06-06T11:44:05.505253Z","iopub.status.idle":"2024-06-06T11:44:05.608965Z","shell.execute_reply.started":"2024-06-06T11:44:05.505204Z","shell.execute_reply":"2024-06-06T11:44:05.606802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res_dict","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:05.610393Z","iopub.execute_input":"2024-06-06T11:44:05.610885Z","iopub.status.idle":"2024-06-06T11:44:05.661998Z","shell.execute_reply.started":"2024-06-06T11:44:05.610844Z","shell.execute_reply":"2024-06-06T11:44:05.66038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 统计验证集中每个session对应的商品集合\nsession_items_val = df_val_offline.groupby(['session'], as_index=False)['aid'].agg(set)\nprint(session_items_val)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:05.664206Z","iopub.execute_input":"2024-06-06T11:44:05.664937Z","iopub.status.idle":"2024-06-06T11:44:53.636294Z","shell.execute_reply.started":"2024-06-06T11:44:05.664881Z","shell.execute_reply":"2024-06-06T11:44:53.634978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 统计验证集中session的数量\nsession_count_val = session_items_val['session'].nunique()\nprint(session_count_val)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:53.637691Z","iopub.execute_input":"2024-06-06T11:44:53.638038Z","iopub.status.idle":"2024-06-06T11:44:53.740299Z","shell.execute_reply.started":"2024-06-06T11:44:53.638009Z","shell.execute_reply":"2024-06-06T11:44:53.739041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#计算得分函数\ndef getScore(df):\n    # 初始化分子和分母\n    score_Numerator = 0  # 推荐列表和实际列表交集的大小\n    score_Denominator = 0  # 分母，取20和实际列表长度的较小值\n\n    # 使用tqdm进度条迭代df的每一行，并显示进度\n    for i, row in tqdm(enumerate(df.iterrows()), total=len(df)):\n        # 根据当前行的session从res_dict中获取推荐列表\n        recom_tmp = [int(x) for x in res_dict[str(row['session'])].split(' ')]\n        # 计算推荐列表和实际列表的交集大小\n        score_Numerator += len(row['aid'] & set(recom_tmp))\n        # 分母是20和实际列表长度的较小值\n        score_Denominator += min(20, len(row['aid']))\n\n    # 返回得分\n    return score_Numerator / score_Denominator\n","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:53.741693Z","iopub.execute_input":"2024-06-06T11:44:53.742021Z","iopub.status.idle":"2024-06-06T11:44:53.750458Z","shell.execute_reply.started":"2024-06-06T11:44:53.741993Z","shell.execute_reply":"2024-06-06T11:44:53.749171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"score=getScore(session_items_val)\nscore","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:53.75213Z","iopub.execute_input":"2024-06-06T11:44:53.752584Z","iopub.status.idle":"2024-06-06T11:44:54.412048Z","shell.execute_reply.started":"2024-06-06T11:44:53.752541Z","shell.execute_reply":"2024-06-06T11:44:54.408136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nrecommendations = []\nfor session, aids in tqdm(session_aids_df[['session', 'aid']].values, total=len(session_aids_df)):\n    session_recs = []\n    \n    for aid in aids:\n        if aid in item_Sim:\n            sim_items = item_Sim[aid]\n            sorted_sim_items = sorted(sim_items, key=sim_items.get, reverse=True)\n            session_recs.extend(sorted_sim_items)\n    \n    session_recs = list(set(session_recs))[:20]  # 获取前20个推荐商品\n    \n    recommendations.append({'session': session, 'recs': session_recs})\ndf_recommendations = pd.DataFrame(recommendations)\nprint(df_recommendations)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.413901Z","iopub.status.idle":"2024-06-06T11:44:54.414553Z","shell.execute_reply.started":"2024-06-06T11:44:54.414238Z","shell.execute_reply":"2024-06-06T11:44:54.414263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_recommendations","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.417376Z","iopub.status.idle":"2024-06-06T11:44:54.417968Z","shell.execute_reply.started":"2024-06-06T11:44:54.41769Z","shell.execute_reply":"2024-06-06T11:44:54.417717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_recommendations_dict = {row['session']: row['recs'] for _, row in df_recommendations.iterrows()}\nprint(df_recommendations_dict)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.419998Z","iopub.status.idle":"2024-06-06T11:44:54.420641Z","shell.execute_reply.started":"2024-06-06T11:44:54.42033Z","shell.execute_reply":"2024-06-06T11:44:54.420355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 创建一个字典，键为会话ID，值为推荐商品列表\nres_dict = {}\nfor session_id in df_val_offline['session'].unique():\n    res_dict[str(session_id)] = generate_recommendations(session_id, item_Sim, session_dict)","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.422226Z","iopub.status.idle":"2024-06-06T11:44:54.422689Z","shell.execute_reply.started":"2024-06-06T11:44:54.422478Z","shell.execute_reply":"2024-06-06T11:44:54.422497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 计算得分\ndef getScore(df, res_dict):\n    # 初始化分子和分母\n    score_Numerator = 0  \n    score_Denominator = 0  \n\n    # 使用tqdm进度条迭代df的每一行，并显示进度\n    for i, row in tqdm(enumerate(df.iterrows()), total=len(df)):\n        # 根据当前行的session从res_dict中获取推荐列表\n        recom_tmp = res_dict[str(row['session'])].split(' ')\n        # 计算推荐列表和实际列表的交集大小\n        score_Numerator += len(set(row['aid']) & set(recom_tmp))\n        # 分母是20和实际列表长度的较小值\n        score_Denominator += min(20, len(row['aid']))\n\n    # 返回精确率，即分子除以分母\n    return score_Numerator / score_Denominator\n\n# 计算验证集上的精确率\nscore = getScore(df_val_offline, res_dict)\nscore\n","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.424408Z","iopub.status.idle":"2024-06-06T11:44:54.424852Z","shell.execute_reply.started":"2024-06-06T11:44:54.424653Z","shell.execute_reply":"2024-06-06T11:44:54.424671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_recommendations(session_id, item_Sim, session_dict):\n    # 获取会话中商品的列表\n    aids = set(session_aids_df.loc[session_aids_df['session'] == session_id, 'aid'].values[0])\n    # 初始化用户商品相似度列表\n    user_item_sim = [(item, item_Sim[item]) for item in item_Sim if item not in aids]\n    \n    # 按照相似度排序，取前20个\n    user_item_sim.sort(key=lambda x: x[1], reverse=True)\n    recommended_items = [item for item, _ in user_item_sim[:20]]\n    \n    return ' '.join(map(str, recommended_items))","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.427417Z","iopub.status.idle":"2024-06-06T11:44:54.428203Z","shell.execute_reply.started":"2024-06-06T11:44:54.427839Z","shell.execute_reply":"2024-06-06T11:44:54.427869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## 创建一个字典，键为会话ID，值为推荐商品列表\nres_dict = {}\n\n# 遍历验证集中的每个唯一会话ID\nfor session_id in df_val_offline['session'].unique():\n    # 检查是否在session_aids_df中有对应的会话ID\n    if session_id in session_aids_df['session'].values:\n        res_dict[str(session_id)] = generate_recommendations(session_id, item_Sim, session_dict)\n","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.431287Z","iopub.status.idle":"2024-06-06T11:44:54.432002Z","shell.execute_reply.started":"2024-06-06T11:44:54.431689Z","shell.execute_reply":"2024-06-06T11:44:54.431716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def getScore(df, res_dict):\n    # 初始化分子和分母\n    score_Numerator = 0  \n    score_Denominator = 0  \n\n    # 使用tqdm进度条迭代df的每一行，并显示进度\n    for i, row in tqdm(enumerate(df.iterrows()), total=len(df)):\n        # 根据当前行的session从res_dict中获取推荐列表\n        recom_tmp = res_dict.get(row['session'], '').split(' ')\n        # 计算推荐列表和实际列表的交集大小\n        score_Numerator += len(set(row['aid']).intersection(set(recom_tmp)))\n        # 分母是20和实际列表长度的较小值\n        score_Denominator += min(20, len(row['aid']))\n\n    # 返回精确率，即分子除以分母\n    return score_Numerator / score_Denominator","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.433604Z","iopub.status.idle":"2024-06-06T11:44:54.434202Z","shell.execute_reply.started":"2024-06-06T11:44:54.433895Z","shell.execute_reply":"2024-06-06T11:44:54.433918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"score = getScore(df_val_offline, res_dict)\nscore","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.438343Z","iopub.status.idle":"2024-06-06T11:44:54.439014Z","shell.execute_reply.started":"2024-06-06T11:44:54.438767Z","shell.execute_reply":"2024-06-06T11:44:54.43879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def getScore(df):#计算得分\n    \n    score_Numerator = 0\n    score_Denominator = 0\n    \n    for i, row in tqdm(df.iterrows(), total=len(df)):\n        \n            recom_tmp = [int(x) for x in df_recommendations_dict[str(row['recs'])]]\n            score_Numerator += len(row['aid'] & set(recom_tmp))\n            score_Denominator += min(20, len(row['aid']))\n    \n    return score_Numerator / score_Denominator","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.441378Z","iopub.status.idle":"2024-06-06T11:44:54.441888Z","shell.execute_reply.started":"2024-06-06T11:44:54.441669Z","shell.execute_reply":"2024-06-06T11:44:54.441688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"score=getScore(session_items_val)\nscore","metadata":{"execution":{"iopub.status.busy":"2024-06-06T11:44:54.444821Z","iopub.status.idle":"2024-06-06T11:44:54.446813Z","shell.execute_reply.started":"2024-06-06T11:44:54.446226Z","shell.execute_reply":"2024-06-06T11:44:54.44634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"raw","source":"","metadata":{}}]}