根据搜索关键词推荐

Recommend based on search key word

我有一个 input query table 在下面:

    query
0  orange
1   apple
2    meat

我想针对 user query table 做如下

   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 table 中其他用户的查询进行匹配,并且 return 总排名前 3计数。

例如, orange in input query,匹配a1,a2,a3 in user query where all have queried orange, other items他们有查询 strawberry(2 个计数)、pearlemonbanana(1 个计数)。

答案将是strawberry(因为它有最大计数),pearlemon(因为我们只return前3)。

apple 的类似推理(没有用户查询因此输出 '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 queryuser queryoutput 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'}} )

根据您拥有的内存资源,选择以下任一解决方案。

代码:

#准备工作:

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')

#解决方案一:

如果您有大量内存资源,请尝试以下代码。

# 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')

# 方案二:

如果您的内存资源有限,请尝试以下代码。比解法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')

解决方案 1 和 2 的输出:

query recommend
0 orange strawberry
1 orange banana
2 orange lemon
3 apple nothing
4 meat nothing