Press "Enter" to skip to content

推荐系统:实现文章相似推荐的简单实例

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

看了一篇文章实现了文章的内容相似度计算实现相似推荐,算法比较简单,非常适合我这种初学入门的人。

 

来自一篇英文文章: 地址

 

文章标题为:How to build a content-based movie recommender system with Natural Language Processing

 

文章的代码在: 地址

 

该文章实现相似推荐的步骤:

 

1、将CSV加载到pandas.pd

 

2、提取其中的标题、题材分类、导演、演员、情节描述4个字段;

 

3、将单词都变小写,人名中的空格合并(英文才需要这样);

 

4、题材分类、导演、演员这几个特征都是结构化的不需要处理;而标题、情节描述这类字段是长段文本,使用nltk库做关键词提取(如果是中文可以用jieba分词库也有关键词提取功能)

 

5、将第四步骤的分类、导演、演员、关键词列表,合并到一个词列表(这一处理其实暗含了分类、导演、演员三个特征和关键词一样重要,没有做加权处理)

 

6、使用CountVectorizer做每个词语的计数,得到了每个文章的向量;

 

7、使用sklearn的cosin做笛卡尔积的相似度计算;

 

8、计算结果是一个二维矩阵,按行查询某一个文章的推荐结果,按相似度值排序得到最相似的文章

 

从里面能学到不少知识的运用:

 

1、全流程用pandas运行,尤其是for each row,做单个列的各种map计算;

 

2、计算相似度时使用了多个特征,包括Title,Genre,Director,Actors,Plot,统一成一个bag of words参与计算

 

3、使用from sklearn.metrics.pairwise import cosine_similarity用于相似度计算;

 

4、使用from sklearn.feature_extraction.text import CountVectorizer用于单词计数;

 

5、使用from rake_nltk import Rake用于关键词提取;

 

代码实现关键部分:

 

作者用到的一些库:

 

import pandas as pd
from rake_nltk import Rake
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import CountVectorizer

 

pandas的dataframe中,直接替换一列的语法:

 

df['Director'] = df['Director'].map(lambda x: x.split(' '))

 

pd按行以此处理某个列的方法:

 

for index, row in df.iterrows():
    row['Actors'] = [x.lower().replace(' ','') for x in row['Actors']]
    row['Director'] = ''.join(row['Director']).lower()

 

pd.df删除某一列的方法:

 

df.(columns = ['Plot'], inplace = True)

 

pd.df从columns中提取一列作为index的方法:

 

df.set_index('Title', inplace = True)

 

作者将能使用的所有列,都放在了一个词包中用于相似度计算,按我的想法,这些特征列其实应该有不同的权重?

 

df['bag_of_words'] = ''
columns = df.columns
for index, row in df.iterrows():
    words = ''
    for col in columns:
        if col != 'Director':
            words = words + ' '.join(row[col])+ ' '
        else:
            words = words + row[col]+ ' '
    row['bag_of_words'] = words
    
df.drop(columns = [col for col in df.columns if col!= 'bag_of_words'], inplace = True)

 

sklearn使用词计数的调用:

 

count = CountVectorizer()
count_matrix = count.fit_transform(df['bag_of_words'])

 

sklearn实现矩阵相似度计算的方法:

 

# generating the cosine similarity matrix
cosine_sim = cosine_similarity(count_matrix, count_matrix)

 

怎样实现不同特征列的融合相似度计算?

 

这个问题纠结我很久,查询了一些文章,大都是人工指定加权权重,或者使用模型拟合权重值,没有多幺简单的方法,而作者使用的其实是直接把分类、演员等字段,和关键词直接融合的方法

 

作者在文章中提到一句话:

 

I decided to use CountVectorizer
rather than  TfIdfVectorizer
for one simple reason: I need a simple frequency counter for each word in my  bag_of_words
column. Tf-Idf tends to give less importance to the words that are more present in the entire corpus (our whole column, in this ) which is not what we want for this application,
because every word is important to detect similarity

!

 

对于标题、介绍这种纯文本内容,我们可以用TF/IDF提取关键词,物理含义就是降低全局出现的词频很多的词语;但是其实对于作者、演员、题材这类特征列,他们并不需要降低全局词频,使用词频计数即可。

 

有哪些可以提升的地方

 

作者的方法确实可以实现相似推荐,不过我感觉有一些可以提升的地方:

 

1、标题、简介,提取关键词后,可以查询业界的word2vec做向量扩展,这样能实现恰恰和伦巴舞这类词语的相似度度量,直接的关键词查询是得不到这样的信息;

 

2、分类、导演、演员这三个特征,需要和描述得到的关键词区分开,可以用加权的方法进行,按照产品的需求,加重分类、导演的相似度权重,降低演员、关键词的权重等,如果需要可以从点击率等出发,用模型计算这些权重;

Be First to Comment

发表评论

邮箱地址不会被公开。 必填项已用*标注