当我第一次看到"Ted Talk"数据集的时候,脑子里立刻冒出一些有意思的想法。首先,既然Ted Talk数据集包含了许多Ted演讲的演讲词文本,那么我们自然而然的就拥有了一个非常丰富且规范的预料库。第二,既然这个语料库有非常好的语言学属性,那么它可能是一个类似于Reuters 20 News Group这种非常优秀的数据集。所以,我们能不能利用这些演讲文本,利用它们之间的相关性,搭建一个像Ted官方网站一样的内容推荐系统呢?
当然,Ted官网用的推荐引擎,可定比本文采用的算法更加复杂,因为它会利用用户的历史交互信息。而本文则提出了一种仅利用演讲的台词内容,就可以进行内容推荐的方法,这一方法在你没有用户交互数据,但仍希望能推荐给用户一些相关联的内容时非常有用。
接下来,我们介绍具体的方法。
步骤1:审查数据
所有的Ted Talk数据存储在一个Excel表中,每个演讲的台词文本存储在一列名为transcript的单元格内,就像下面的样子。
代码语言:javascript复制import pandas as pd
transcripts=pd.read_csv("E:\Kaggle\ted-data\transcripts.csv")
transcripts.head()
检查完数据,我们发现可以从url一列中提取出演讲的名称。而我们的最终目标是利用transcript列的内容来获得演讲之间的相似度,然后推荐4个与给定演讲最相似的视频。
利用以下代码可以轻松的提取演讲名称(title)。
代码语言:javascript复制 transcripts['title']=transcripts['url'].map(lambda x:x.split("/")[-1])
transcripts.head()
要想创建推荐系统,接下来需要完成以下几个步骤。
(1)创建一个代表演讲文本的向量空间模型
(2)建立向量空间模型的相似度矩阵
(3)基于相似度方法,为每一个演讲选择4个相似的演讲。
步骤2:利用Tf-Idf创建文本向量
因为我们是基于演讲内容进行推荐,所以首先要做的是建立一个便于比较的文本内容标识方法。一种可行的方法是创建文本的Tf-Idf向量。
语料集、文档和向量空间
为了表示文本,我们可以将每个演讲看做一个文档(Document),将所有的文档的词语构成一个语料集(Corpus)。然后用一个布尔型的向量描述每个文档,其中1表示这个词出现在文档中,0则表示该词没有出现。所以,每个文档都可以看做向量空间(语料集)中的一个向量。
但这个简单的方法存在的问题很明显。首先,该方法中每个词在文档中的重要程度相同,但直观来说,出现次数多的词更适合描述一篇文档。此外,当文档比较长时,其与指定文档的重叠的积累更大,从而导致推荐算法更倾向于推荐长文档。
为了解决简单布尔算法的缺陷,文档可以通过Tf-Idf转换成欧几里得空间中的向量。空间的维度构成对应文档中出现的关键词(Term),每个文档在向量空间中的位置由两个子量的乘积得到:词频(Term Frequency)和反文档频率(Inverse document frequency)。
Tf-Idf(Term Frequency -Inverse Document Frequency)方法
可以通过考虑以下三个问题来确定一个单词在文档中的重要性。
(1)该词是否在文档中经常出现?
(2)该词是否在语料集中很少出现 ?
(3)同时满足(1)和(2)?
如果一个单词在文档中出现次数很多,但在其他文档中很少出现,则该单词在文档中无疑是重要的。词频描述某个词在文档中出现的频繁程度;而反文档频率是组合了词频后的第二个指标,旨在降低所有文档中几乎都会出现的关键词的权重。二者的乘积即是Tf-Idf。
利用机器学习框架(比如scikit-learn)计算Tf-Idf并创建文本的向量空间非常简单。
代码语言:javascript复制 from sklearn.feature_extraction import text
Text=transcripts['transcript'].tolist()
tfidf=text.TfidfVectorizer(input=Text,stop_words="english")
matrix=tfidf.fit_transform(Text)
#print(matrix.shape)
利用Tf-Idf方法,我们解决了演讲内容的向量表示问题,接下来我们研究如何找到与指定内容相似的演讲。
步骤3:找到相似的演讲
为了度量两个不同演讲的相似性,需要计算二者的相似度。通常,利用余弦相似度(Cosine Similarity)来处理Tf-Idf向量。我们可以建立一个余弦相似度矩阵来表示各个演讲之间的相似性。
代码语言:javascript复制 ### Get Similarity Scores using cosine similarity
from sklearn.metrics.pairwise import cosine_similarity
sim_unigram=cosine_similarity(matrix)
最后,我们基于余弦相似度矩阵来实现为选定内容推荐4个相似的演讲这一目标。也就是说,从上面的相似度矩阵中,在指定的行中,找出5个相似度最大的列来,代码如下。
代码语言:javascript复制def get_similar_articles(x):
return ",".join(transcripts['title'].loc[x.argsort()[-5:-1]])
transcripts['similar_articles_unigram']=[get_similar_articles(x) for x in sim_unigram]
接下来,让我们验证下本文算法的可行性。从Ted演讲集中选择 一个演讲:
代码语言:javascript复制transcripts['title'].str.replace("_"," ").str.upper().str.strip()[1]
代码语言:javascript复制'AL GORE ON AVERTING CLIMATE CRISIS'
然后,运转算法,找到的最相似的演讲如下:
代码语言:javascript复制transcripts['similar_articles_unigram'].str.replace("_"," ").str.upper().str.strip().str.split("n")[1]
代码语言:javascript复制['RORY BREMNER S ONE MAN WORLD SUMMIT',
',ALICE BOWS LARKIN WE RE TOO LATE TO PREVENT CLIMATE CHANGE HERE S HOW WE ADAPT',
',TED HALSTEAD A CLIMATE SOLUTION WHERE ALL SIDES CAN WIN',
',AL GORE S NEW THINKING ON THE CLIMATE CRISIS']
可以看到,利用Tf-Idf向量及余弦相似度,我们成功的建立了基于演讲内容的推荐算法。