如何构建一个简单的图书推荐系统

原作者:venkat-raman

出处:https://www.linkedin.com/pulse/content-based-recommender-engine-under-hood-venkat-raman

 

    在我们的日常生活中,遇到过各种各样的推荐系统,比如说电子商务网站或社交媒体网站上的。有些推荐看起来是相关的,但是有时候真是匪夷所思、让人来气。

 

    推荐系统一般有两种:基于内容的和基于协同过滤的。根据我们具体的使用场景,这两种方法有各自的优势和劣势。

 

基于内容的推荐:

    在基于内容的推荐中,会根据项目(items)的关键词或属性向用户推荐内容。或者说,它倾向于推荐近似的项目。想象一下,你正在读数据可视化的书,并且想寻找一本同一个话题的书,在这种场景下,就适合用基于内容的推荐系统。

 

基于协同过滤的推荐:

    下面这张图可以帮你更直观的理解。消费者A已经买了图书x、y、z,并且消费者B已经买了图书y、z。现在协同过滤算法会推荐x给消费者B。这种方式有它的优点和缺点。消费者B爱看的是小说,但是这种算法并不关心图书x是不是一个小说类的书。这种相关推荐可能正确也可能错误。但是它的优点是很多公司可以用这种方法进行跨品类的商品推荐。

 

开发一个基于内容的推荐系统—理论篇

 

    想象一下你拥有一个图书馆,里面有很多关于科学的书籍。你的朋友读过一本关于神经网络的书,并且想继续读一些相关的书来建立他在这个领域的知识体系。最好的方法就是实现一个简单的基于内容的推荐系统,

 

在做推荐系统的时候,我们会接触到三个重要的概念:

  • 向量(Vectors)

  • 词频-逆文档频率(TF-IDF)

  • 余弦相似性(Cosine Similarity)

 

向量(Vectors):

 

    基本原理就是将文章或词组转换为向量,并且在向量空间中表示。这种想法是如此的聪明,本质上,这种想法让机器学习和人工智能成为可能。事实上,Geoffrey Hinton(深度学习之父)在一篇“MIT技术评论”文章中将位于多伦多的人工智能研究所(AI institute)称为向量研究所(Vector Institute),因为向量优异的特性已经在深度学习和其他神经网络中发挥巨大作用。

 

词频-逆文档频率(TF-IDF):

    TF-IDF表示的是词的频率和逆向的文档频率。TF-IDF帮助评估一个词在文档中的重要性。

 

TF-词频

    为了确定文档中单词的出现频率,以及将文档转化为向量的形式,让我们进行以下的步骤:

第一步:创建一个单词词典(也称为词袋模型),代表全部的文档空间。我们忽略一些常用词(也称为停顿词),比如“个”、“的”、“是”。因为这些词特别常见并且和我们的目标不一致,我们是要选择那些重要的词。

 

    在现在的这个例子中,我用到了test1.csv文件,它包含了50本书的标题。但是为了直观表示,先仅仅考虑三个图书标题作为整个的‘文档空间’。所以B1是一个文档,B2、B3是剩下的。B1, B2, B3一起构成了文档空间。

 

B1 - 推荐系统 

B2 - 统计学习的原理

B3 - 高级的推荐系统

 

现在创建一个单词索引(忽略掉停顿词)

 

1推荐

2系统

3原理

4统计

5学习

6高级

 

第二步:组织向量

 

    词频(TF)帮助我们识别单词在文档中出现的次数,但是有一个固有的问题,词频给了那些频繁出现的词更高的重要性,而忽略了那些很少出现但是同样重要的词。如果罕见词包含了非常重要的信息,那这种情况是很不理想的。这个问题被‘逆文档频率(IDF)’解决了。

有时候,一个单词可能在篇幅较长的文章中出现次数更多。因此,“词频标准化”(TermFrequency normalization)就派上用场了。

TFn = (单词t在一个文档中出现的次数) / (这个文档中单词的总数),n代表了已经标准化。

 

 

逆文档频率(IDF,Inverse Document Frequency

 

逆文档频率的定义:

n代表了总文档数。

 

 

    在有些不同的IDF的定义中,为了避免分母为0,分母上会加1。

基本上,一个简单的定义就是:

IDF= ln(文档总数/包含单词t在内的文档数量)

 

现在让我们从我们的单词词典中找出一些词计算IDF。

我们有6个单词:

1推荐

2系统

3原理

4统计

5学习

6高级

我们的文档是:

B1 - 推荐系统 

B2 - 统计学习的原理

B3 - 高级的推荐系统

现在:

IDF:IDF (w1) = log 3/2; IDF(w2) = log 3/2; IDF (w3) = log 3/1; IDF (W4) = log 3/1; IDF(W5) = log 3/1; IDF(w6) = log 3/1

我们就可以得到一批向量:

 = (0.4054, 0.4054, 1.0986, 1.0986, 1.0986, 1.0986)

TF-IDF 权重:

现在最后一步就是得到TF-IDF 权重。TF向量和IDF向量被转化为一个矩阵。

TF-IDF 权重用以下的公式表示:

TF-IDF Weight = TF (t,d) * IDF(t,D)

我们也可以用python代码得到同样的矩阵:

tfidf_matrix = tf.fit_transform(ds['Book Title'])

余弦相似性:

 

    余弦相似性可以用来度量两个非零向量的相似程度。有意思的是,我们可以用两个向量代表两个句子,通过看两个向量的角度有多么接近,来判断两个句子多么相似。

余弦值的取值范围是-1到1.

所以如果两个向量的角度是0,那么余弦值是1,这就代表着这两个句子是彼此非常相似。

如果两个向量是垂直相交的,比如cos 90。那么意思就是两个句子是无关的,

 

 

如何实现

    下面我写了一些python代码,来实现一个简单的推荐系统。为了能清晰的看到每一行代码的作用,我已经添加了注释。

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
ds = pd.read_csv("test1.csv") #you can plug in your own list of products or movies or books here as csv file
tf = TfidfVectorizer(analyzer='word', ngram_range=(1, 3), min_df=0, stop_words='english')
######ngram (1,3) can be explained as follows#####
#ngram(1,3) encompasses uni gram, bi gram and tri gram
#consider the sentence "The ball fell"
#ngram (1,3) would be the, ball, fell, the ball, ball fell, the ball fell

tfidf_matrix = tf.fit_transform(ds['Book Title'])
cosine_similarities = cosine_similarity(tfidf_matrix,tfidf_matrix)

results = {} # dictionary created to store the result in a dictionary format (ID : (Score,item_id))

for idx, row in ds.iterrows(): #iterates through all the rows
    # the below code 'similar_indice' stores similar ids based on cosine similarity. sorts them in ascending order. [:-5:-1] is then used so that the indices with most similarity are got. 0 means no similarity and 1 means perfect similarity
    similar_indices = cosine_similarities[idx].argsort()[:-5:-1] #stores 5 most similar books, you can change it as per your needs
    similar_items = [(cosine_similarities[idx][i], ds['ID'][i]) for i in similar_indices]
    results[row['ID']] = similar_items[1:]
    
#below code 'function item(id)' returns a row matching the id along with Book Title. Initially it is a dataframe, then we convert it to a list
def item(id):
    return ds.loc[ds['ID'] == id]['Book Title'].tolist()[0]
def recommend(id, num):
    if (num == 0):
        print("Unable to recommend any book as you have not chosen the number of book to be recommended")
    elif (num==1):
        print("Recommending " + str(num) + " book similar to " + item(id))
        
    else :
        print("Recommending " + str(num) + " books similar to " + item(id))
    print("----------------------------------------------------------")
    recs = results[id][:num]
    for rec in recs:
        print("You may also like to read: " + item(rec[1]) + " (score:" + str(rec[0]) + ")")

#the first argument in the below function to be passed is the id of the book, second argument is the number of books you want to be recommended
recommend(5,2)

输出的结果:

Recommending 2 books similar to The Elements of Statistical Learning ----------------------------------------------------------You may also like to read: An introduction to Statistical Learning  (score:0.389869522721)You may also like to read: Statistical Distributions (score:0.13171009673)

test1.csv文件中的图书id和标题

ID,Book Title1,Probabilistic Graphical Models2,Bayesian Data Analysis 3,Doing data science 4,Pattern Recognition and Machine Learning 5,The Elements of Statistical Learning 6,An introduction to Statistical Learning 7,Python Machine Learning 8,Natural Langauage Processing with Python9,Statistical Distributions10,Monte Carlo Statistical Methods11,Machine Learning :A Probablisitic Perspective12,Neural Network Design 13,Matrix methods in Data Mining and Pattern recognition 14,Statistical Power Analysis15,Probability Theory The Logic of Science16,Introduction to Probability 17,Statistical methods for recommender systems18,Entropy and Information theory19,Clever Algorithms: Nature-Inspired Programming Recipes20,"Precision: Principles, Practices and Solutions for the Internet of Things"

 

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用tkinter这个GUI库来构建一个简单图书信息系统是很容易的。我们可以通过设计一个简单易用的界面来让用户方便地操作这个系统,以实现对图书的管理、查询和借阅等功能。 该系统的使用者可以是一个图书馆管理员,也可以是个人用户。管理员可以用此系统来管理图书的信息、借阅信息等,个人用户可以通过该系统查询图书的信息以及进行借阅操作。 我们可以将该系统分为三个主要的部分:查询、图书管理和借阅管理。在查询部分,可以提供各种查询方式,例如根据作者、书名、出版社等查询图书信息。在图书管理部分,管理员可以管理图书的信息,包括添加图书、删除图书、修改图书信息等。在借阅管理部分,管理员和用户都可以进行借阅、归还操作等。 针对这些功能,可以设计一个基于tkinter的图形界面,使用标签、文本框、按钮以及菜单等组件实现各个功能模块。我们可以将各个模块的功能放置在不同的tab标签页中,以便用户方便地切换功能模块。在实现这些功能时,我们可以为每个数据模型创建相应的数据表,并使用SQL语句完成各种数据库操作。 总之,使用tkinter或其他GUI库构建一个简单图书信息系统并不难,只需要设计简单易用的UI界面,合理的功能划分以及对各种数据模型的合理设计,就可以实现一个功能完善、易用的图书信息系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值