智能图书推荐系统
所需运行环境
使用python3.6作为编程语言。使用mysql作为数据库存储.
需要安装pandas,flask,pymysql.
安装方式:
cmd下
pip install pandas
pip install flask
pip install pymysql
项目源码介绍:
20180712
|
-|-----data >这个文件夹中存放数据集,数据集比较杂乱。
| |
| |-BX-Books.csv >关于27万条的数据信息,涉及书籍编号,书籍名,书籍作者....
| |-BX-Users.csv >关于27万条的用户信息,涉及用户ID,用户区县,用户省份,用户年龄。
| |-Rating1M.csv >关于100万条的用户对数据的评分数据。涉及用户ID,书籍ID,评分。(评分1-10为标准)|
|
|
|
-|------CkeanData >这个文件夹中存放清洗好的数据集,将上面数据清理出需要的数据。
| |
| |-book.csv >关于27万条的数据信息,保留书籍编号,书籍名,书籍作者,出版年份。
| |-user.csv >关于27万条的用户信息,保留了用户ID,用户区县,用户省份,用户年龄。
| 并且将用户ID,和用户区县作为账号密码用于网站登录。
| |-bookrating.csv >关于100万条的用户对数据的评分数据。保留用户ID,书籍ID,评分。(评分1-10为标准)
| |-booktuijian.csv >关于10个测试用户和对其推荐书籍的信息。涉及用户ID,书籍ID,推荐指数。(评分1-10为标准)
|
-|------BookWebAPI.py >启动这个文件开启服务器。启动方式:在更目录下进入cmd输入 python BookWebAPI.py
-|------CleanCSV.py >清洗原先杂乱的csv文件,保存到cleanData文件夹下面。
-|------CSVToMysql.py >将清洗好的文件,即CleanData里面的文件,导入到mysql中。
|
-|------CF >协同过滤1:CF 算法
-|------slope one >协同过滤2:slope one 算法
|
-|-----其他文件夹 >提供给前端页面和前端页面的依赖
项目思路:
本项目实现了3个图书推荐功能:
1 基于书籍的推荐,将书籍按评论平均值排序,将前10个推送给用户。
2 基于CF(协同过滤)算法的推荐,从登录用户阅读的书籍,寻找具有相同兴趣的用户,并将这些用户阅读的书籍计算求得匹配度。
按匹配度将前十个推送给用户。
3 基于slope one 的推荐。slope one讲解:
用户\商品 商品1 商品2
用户 1 3 4
用户 2 4 ?
从上表中预测用户2对商品2的评分时采用SlopeOne算法计算方式为:R(用户2,商品2) = 4 +(4-3)= 5
这就是 SlopeOne 推荐的基本原理,它将用户的评分之间的关系看作简单的线性关系:Y = X + b
项目地址:
gethub: https://github.com/lsq960124/Flask-BookRecommend-Mysql
百度云 : 链接:https://pan.baidu.com/s/15OCv3j_A570sGt0w5vCYzw 密码:r67w
CF.py 协同过滤算法的解析:
计算相似用户:
def _cosine_sim(target_books, books):
'''
simple method for calculate cosine distance.
e.g: x = [1 0 1 1 0], y = [0 1 1 0 1](x1^2+x2^2+...)+sqrt(y1^2+y2^2+...)]
cosine = (x1*y1+x2*y2+...) / [sqrt
that means union_len(movies1, movies2) / sqrt(len(movies1)*len(movies2))
上面是算法的公式,关于基于用户协调过滤算法的理解你可以看你的论文。
我讲的可能没论文写得到位
return的值cosine就是相似度。用到的知识是线性代数求cos角度数。举个列子 空间上面有 2个点A,B。与
坐标原点(0,0)组成AOB三角形,角AOB的度数越小,那么表示两个坐标点越相近。代入这个书籍推荐上面
我们这样理解:
用户A=[‘书1’,‘书2’,‘书3’]=['1','2','3'] ID代表书籍的编号
用户B=[‘书4’,‘书2’,‘书6’]=['4','2','6'] ID代表书籍的编号
用户C=[‘书7’,‘书8’,‘书9’]=['21','2','6'] ID代表书籍的编号
如果用户A登录网址 思考一个问题 我们推荐用户B的书籍,还是用户C的给A?
求cosAOB = x cosAOC = y
很明显 X< Y 那么 证明用户B距离用户A更近,即B的阅读兴趣与A跟相似,于是
我们可以把B阅读的书籍推荐给A
我们用这个方法可以得到最相似的用户,但是还得不到最适合推荐的书籍。这个可以在
get_topn_items这个方法中解决。
'''
union_len = len(set(target_books) & set(books))
if union_len == 0: return 0.0
product = len(target_books) * len(books)
cosine = union_len / math.sqrt(product)
return cosine
计算推荐书籍:
def _get_top_n_items(self, top_n_users, candidates_books, top_n):
"""
calculate interest of candidates movies and return top n movies.
e.g. interest = sum(sim * normalize_rating)
上面2个方法,依靠上面的注释的内容,我们得到了最相似的用户,那么用户中我们需要怎么推荐书籍?
原理其实很容易理解:
首先我们有全部用户对于不同书籍的评分,那么我们可以计算出每个书籍的平均得分。这个作为一个权重
再去乘以之前用户的相似度。那么这个值以上面的例子来说
用户A=[‘书1’,‘书2’,‘书3’]=['1','2','3'] ID代表书籍的编号
用户B=[‘书4’,‘书2’,‘书6’]=['4','2','6'] ID代表书籍的编号
用户C=[‘书7’,‘书8’,‘书9’]=['21','2','6'] ID代表书籍的编号
用户A登录, 他阅读了‘书1’,‘书2’,‘书3’,假设数据库只有用户A,用户B,用户C
发现B,C都与A有共同兴趣,即看过书2,那么我们需要推送4,6,21,我们需要计算4,6,21的
推荐度,并排序返回给A。
那么怎么计算呢?
首先,我们前面求出了A与B,C的相似度。这个值乘以每本书在书籍评分数据的平均值。这样4,21的是可以直接
得到的,而关于6,我们需要将B的匹配度加上C匹配度。
最后我们得到的一个表格为
【 书本ID,匹配度 】
【 xxxxx 1.223】
【 xxxxx 1.223】
【 xxxxx 0.423】
【 xxxxx 1.323】
【 xxxxx 0.023】
【 xxxxx 0.000】
我们再对这个表格排序 将前TOPN推荐给用户A。
"""
top_n_user_data = [self.frame[self.frame['UserID'] == k] for k, _ in top_n_users]
interest_list = []
for book_id in candidates_books:
tmp = []
for user_data in top_n_user_data:
if book_id in user_data['BookID'].values:
readdf = user_data[user_data['BookID'] == book_id]
tmp.append(round(readdf['Rating'].mean(),2))
else:
tmp.append(0)
interest = sum([top_n_users[i][1] * tmp[i] for i in range(len(top_n_users))])
interest_list.append((book_id, interest))
interest_list = sorted(interest_list, key=lambda x: x[1], reverse=True)
return interest_list[:top_n]