图书推荐系统(一)之数据准备
📖对豆瓣图书的数据集进行分析,方案一根据图书分析用户数,方案二根据用户分析图书数
1 数据准备
来自 豆瓣图书数据集,表结构是用户id-图书id-评分。
2 数据分析
2.1 根据图书分析用户数
思路:分析用户评分最多的和最小的N本图书对应的评分用户数。
(1)加载数据集,放入字典结构
def _load_data(file_path):
book_rate_map = dict()
for line in open(file_path,"r",encoding="utf-8").readlines():
user,bookid,rate = line.strip().split("::")
#book_rate_map={bookid:{user:score}}
book_rate_map.setfault(bookid,{})
book_rate_map[bookid][user] = score
return book_rate_map
(2)获取评分最多的和最少的N本图书
def _most_rate_books(k):
book_rate_score = _load_data("./data/douban.dat")
#图书id-评分人数数据集
book_rate_num = dict()
#用户名数据集,set()函数创建一个无序不重复元素集
users = set()
#计算每本图书下的用户数,以及展示用户
for key in book_rate_score.keys():
book_rate_num[key] =len(book_rate_score[key])
for user in book_rate_score[key].keys():
users.add(user)
#按照评分人数,从大到小排序
new_book_rate_num = sorted(book_rate_num.items(),key = lambda k:k[1],reverse = True)
print("总有图书数目:{}".format(new_book_rate_num.__len__()))
print("总有用户数目:{}".format(users.__len__()))
#按照评分人数,从小到大排序
new_1_book_rate_num = sorted(book_rate_num.items(),key = lambda k:k[1],reverse = False)
#返回评分最多的和最少的N本图书id列表+原数据集
return list(dict(new_book_rate_num[:k]).keys())+list(dict(new_1_book_rate_num[:k]).keys()),book_rate_score
(3)获取用户评分最多的和最小的N本图书对应的评分用户
def _topk_book_to_user():
user = set()
books,book_rate_score = _most_rate_books(30):
for book in books:
for user in book_rate_score[book].keys():
users.add(user)
print(users.__user__)
完整代码如下: analysis_topK_book_to_users.py
# -*- coding: utf-8 -*-
"""
Author:JinHelen
Date:2019-04-16
Desc:分析豆瓣数据集中评分最多的N本图书和最少的N本图书涉及的用户数
思路:
1、加载数据,返回字典结构,数据集形式为:{bookid:{user:score}}
2、要获取用户评分最多的和最小的N本图书对应的评分用户数
(1)计算每本图书下的用户数,得到图书id-用户数数据表,记录下用户名
(2)按照评分人数,采用倒排和正排,分别取前N本图书
(3)返回2N本图书id和原数据集
(4)遍历得到的2N本图书id,获取每本图书下的用户名,计算用户数
"""
#加载数据集,返回字典结构
def _load_data(file_path):
book_rate_map = dict()
for line in open(file_path,"r",encoding="utf-8").readlines():
user, bookid, score = line.strip().split("::")
#book_rate_map={bookid:{user:score}}
book_rate_map.setdefault(bookid,{})
book_rate_map[bookid][user]=score
return book_rate_map
#获取用户评分最多的和最少的N本图书,以及图书评分字典
def _most_rate_books(k):
#图书id-用户-评分数据集
book_rate_score = _load_data("./data/douban.dat")
#图书id-用户数数据集
book_rate_num = dict()
#用户名数据集,set()函数创建一个无序不重复元素集
users = set()
#这里的keys是指bookid
for key in book_rate_score.keys():
#计算bookid下的用户数
book_rate_num[key] = len(book_rate_score[key])
#这里的keys指user
for user in book_rate_score[key].keys():
#存下用户名
users.add(user)
#按照评分人数倒排,revers=True 表示从大到小排序
# 图书id-用户数数据集 从大到小
new_book_rate_num = sorted(book_rate_num.items(),key= lambda k:k[1],reverse=True)
#__len__返回元素的个数
print("总有图书数目:{}".format(new_book_rate_num.__len__()))
print("总有用户数据:{}".format(users.__len__()))
# print(dict(new_book_rate_num[:k]))
# 按照评分人数正排,revers=False 表示从小到大排序
# 图书id-用户数数据集 从小到大
new_1_book_rate_num = sorted(book_rate_num.items(), key=lambda k: k[1], reverse=False)
#返回评分最多的和最少的N本图书id+原数据集
return list(dict(new_book_rate_num[:k]).keys())+list(dict(new_1_book_rate_num[:k]).keys()),book_rate_score
# 获取用户评分最多的和最小的N本图书对应的评分用户
def _topk_book_to_user():
users = set()
books, book_rate_score = _most_rate_books(30)
for book in books:
for user in book_rate_score[book].keys():
users.add(user)
print(users.__len__())
_topk_book_to_user()
运行结果部分内容:
总有图书数目:80008
总有用户数据:383033
2071
2200
4107
4248
4457
...
19153
19154
19155
19156
19156
注意:数字代表每本图书下的用户数
2.2 根据用户分析图书数
思路:分析豆瓣数据集中评分行为最多的和最少的用户涉及的图书数
(1)加载数据
def _load_data(file_path):
user_rate_map = dict()
for line in open(file_path,"r",encoding="utf-8").readlines():
user, bookid, score = line.strip().split("::")
#user_rate_map = {user:{bookid:score}}
user_rate_map.setdefault(user,{})
user_rate_map[user][bookid] = score
return user_rate_map
(2)获取评分行为最多的M个用户和最少的N个用户
def _most_rate_users(most,small):
user_rate_score = _load_data("./data/douban.dat")
#用户-图书数数据集
user_rate_num = dict()
#图书id数据集
books = set()
for user in user_rate_score.keys():
user_rate_num[user] = len(user_rate_score[user])
for book in user_rate_score[user].keys():
books.add(book)
#按照图书书倒排,从大到小排序
new_user_rate_num = sorted(user_rate_num.items(),key=lambda k:k[1],reverse=True)
print("总有用户数目:{}".format(new_user_rate_num.__len__()))
print("总有图书数目:{}".format(books.__len__()))
#按照图书书正排,从小到大排序
new_1_user_rate_num = sorted(user_rate_num.items(),key=lambda k:k[1],reverse=False)
return list(dict(new_user_rate_num[:most]).keys())+list(dict(new_1_user_rate_num[:small]).keys()),user_rate_score
(3)将对应的用户和图书id写入文件
def _write_users_and_books(users,books):
fw = open("data/select_users.txt","w")
fw.write("\n".join(users))
fw.close()
fw = open("data/select_books.txt","w")
fw.write("\n".join(books))
fw.close()
(4)获取用户和对应的图书数
def _top_user_to_book():
book = set()
users,user_rate_score = _most_rate_users(50,50)
for user in users:
for book in user_rate_score[user].keys():
books.add(book)
print(books.__len__())
_write_users_and_books(users,list(books))
完整代码如下: analysis_topK_users_to_books.py
"""
Author:JinHelen
Date:2019-04-16
Desc:分析豆瓣数据集中评分行为最多的和最少的用户涉及的图书数
思路:
1、加载数据,返回字典结构,数据集形式为:{user:{bookid:score}}
2、要获取评分行为最多的M个和最少的N个用户
(1)计算每名用户下的图书数,得到用户-图书数数据集,记录下图书id
(2)按照图书数,采用倒排和正排,分别取前M个用户和前N个用户
(3)返回M+N个用户和原数据集
(4)遍历得到的M+N个用户,获取每个用户下的图书id,计算图书数
3、将得到的M+N个用户存到txt中,得到的这些用户评价过的图书存到text中
"""
# 加载数据
def _load_data(file_path):
user_rate_map = dict()
for line in open(file_path,"r",encoding="utf-8").readlines():
user, bookid, score = line.strip().split("::")
#user_rate_map = {user:{bookid:score}}
user_rate_map.setdefault(user,{})
user_rate_map[user][bookid] = score
return user_rate_map
#获取评分行为最多的M个用户和最少的N个用户
def _most_rate_users(most,small):
#用户-图书id-评分数据集
user_rate_score = _load_data("./data/douban.dat")
#用户-图书数数据集
user_rate_num = dict()
#图书id数据集
books = set()
for user in user_rate_score.keys():
user_rate_num[user] = len(user_rate_score[user])
for book in user_rate_score[user].keys():
books.add(book)
# 按照图书数倒排,revers=True 表示从大到小排序
new_user_rate_num = sorted(user_rate_num.items(),key=lambda k:k[1],reverse=True)
print("总有用户数目:{}".format(new_user_rate_num.__len__()))
print("总有图书数目:{}".format(books.__len__()))
# print(dict(new_user_rate_num[:most]))
# 按照图书数正排,revers=False 表示从小到大排序
new_1_user_rate_num = sorted(user_rate_num.items(), key=lambda k: k[1], reverse=False)
# print(dict(new_1_user_rate_num[:small]))
return list(dict(new_user_rate_num[:most]).keys()) + list(dict(new_1_user_rate_num[:small]).keys()),user_rate_score
#将对应的用户和图书id写入文件
def _write_users_and_books(users,books):
fw = open("data/select_users.txt","w")
fw.write("\n".join(users))
fw.close()
fw = open("data/select_books.txt", "w")
fw.write("\n".join(books))
fw.close()
#获取用户和对应的图书数
def _top_user_to_book():
books = set()
users,user_rate_score = _most_rate_users(50,50)
for user in users:
for book in user_rate_score[user].keys():
books.add(book)
#每个用户下的图书数
print(books.__len__())
_write_users_and_books(users, list(books))
_top_user_to_book()
运行结果部分内容:
总有用户数目:383033
总有图书数目:80008
4110
5747
6765
7768
8330
...
24043
24043
24044
24046
注:数字分别代表每位用户下的图书数