[英]Recommend based on search key word
我在下面有一個input query
表:
query
0 orange
1 apple
2 meat
我想針對user query
表進行如下操作
user query
0 a1 orange
1 a1 strawberry
2 a1 pear
3 a2 orange
4 a2 strawberry
5 a2 lemon
6 a3 orange
7 a3 banana
8 a6 meat
9 a7 beer
10 a8 juice
在input query
中給定一個查詢,我想將其與user query
表中其他用戶的查詢相匹配,並返回按計數總數排名前 3 位。
例如, input query
中的orange
匹配用戶user query
中的用戶a1
、 a2
、 a3
都查詢過orange
,他們查詢的其他項目是strawberry
(count of 2), pear
, lemon
, banana
(count of 1)。
答案將是strawberry
(因為它有最大數量)、 pear
、 lemon
(因為我們只返回前 3 名)。
apple
的類似推理(沒有用戶查詢因此 output 'nothing')和meat
查詢。
所以最終的output table
是
query recommend
0 orange strawberry
1 orange pear
2 orange lemon
3 apple nothing
4 meat nothing
給定user query
有 100 萬行的有效方法是什么?
這是input query
、 user query
和output table
的代碼
df_input = pd.DataFrame( {'query': {0: 'orange', 1: 'apple', 2: 'meat'}} )
df_user = pd.DataFrame( {'user': {0: 'a1', 1: 'a1', 2: 'a1', 3: 'a2', 4: 'a2', 5: 'a2', 6: 'a3', 7: 'a3', 8: 'a6', 9: 'a7', 10: 'a8'}, 'query': {0: 'orange', 1: 'strawberry', 2: 'pear', 3: 'orange', 4: 'strawberry', 5: 'lemon', 6: 'orange', 7: 'banana', 8: 'meat', 9: 'beer', 10: 'juice'}} )
df_output = pd.DataFrame( {'query': {0: 'orange', 1: 'orange', 2: 'orange', 3: 'apple', 4: 'meat'}, 'recommend': {0: 'strawberry', 1: 'pear', 2: 'lemon', 3: 'nothing', 4: 'nothing'}} )
根據您擁有的 memory 資源,選擇以下任一解決方案。
import pandas as pd
# Create sample dataframes
df_input = pd.DataFrame({'query': {0: 'orange', 1: 'apple', 2: 'meat'}})
df_user = pd.DataFrame({'user': {0: 'a1', 1: 'a1', 2: 'a1', 3: 'a2', 4: 'a2', 5: 'a2', 6: 'a3', 7: 'a3', 8: 'a6', 9: 'a7', 10: 'a8'}, 'query': {0: 'orange', 1: 'strawberry', 2: 'pear', 3: 'orange', 4: 'strawberry', 5: 'lemon', 6: 'orange', 7: 'banana', 8: 'meat', 9: 'beer', 10: 'juice'}})
# Define how many recommended items you need for each query
n_top = 3
# Exclude unnecessary rows for caluculation
dfu = df_user.drop_duplicates()
queries = df_input['query']
users = dfu.loc[dfu['query'].isin(queries), 'user'].drop_duplicates()
mask_q = dfu['query'].isin(queries)
mask_u = dfu['user'].isin(users)
df1 = dfu[mask_u&mask_q].set_index('user')
df2 = dfu[mask_u].set_index('user')
如果你有一個大的 memory 資源,試試下面的代碼。
# Carry out the basket analysis
df = df1.join(df2, lsuffix='_x', rsuffix='_y')
df = df[df.query_x!=df.query_y].reset_index()
df = df.groupby(['query_x', 'query_y'], as_index=False).count()
df = df.sort_values('user', ascending=False).groupby('query_x').head(n_top)
df = df.drop('user', axis=1).rename(columns={'query_x': 'query', 'query_y': 'recommend'})
df = df_input.merge(df, how='left', on='query').fillna('nothing')
如果您有 memory 資源的限制,請嘗試以下代碼。 它比解決方案 1 花費的時間長得多,但您幾乎可以肯定地完成計算。
# Carry out the basket analysis
df = pd.DataFrame()
for _, df_q1 in df1.groupby('query'):
_df = pd.DataFrame()
for _, df_q2 in df2.groupby('query'):
df_q1q2 = df_q1.join(df_q2, lsuffix='_x', rsuffix='_y')
df_q1q2 = df_q1q2.reset_index().groupby(['query_x', 'query_y'], as_index=False).count()
_df = _df.append(df_q1q2)
_df = _df[_df.query_x!=_df.query_y]
_df = _df.sort_values('user', ascending=False).groupby('query_x').head(n_top)
df = df.append(_df)
df = df.drop('user', axis=1).rename(columns={'query_x': 'query', 'query_y': 'recommend'})
df = df_input.merge(df, how='left', on='query').fillna('nothing')
詢問 | 推薦 | |
---|---|---|
0 | 橘子 | 草莓 |
1個 | 橘子 | 香蕉 |
2個 | 橘子 | 檸檬 |
3個 | 蘋果 | 沒有 |
4個 | 肉 | 沒有 |
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.