赞
踩
本科生毕业设计选题大全——计算机类(Python/Java)
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人 。
(1)技术栈:
Python语言 MySQL数据库 Django框架 协同过滤推荐算法 requests网络爬虫 pyecharts数据可视化 html页面
爬取院校信息:https://yz.chsi.com.cn/sch/(研招网)
考研院校推荐系统 爬虫+混合推荐+协同过滤推荐算法+Echarts可视化
基于Python考研院校推荐系统 爬虫+混合推荐+协同过滤推荐算法+Echarts可视化 考研推荐 专业推荐 计算机毕业设计
(1)数据可视化分析
(2)系统首页—高校信息
(3)高校信息排行榜可视化分析
(4)院校推荐模块
(5)高校院校页面
(6)高校分数线页面
(7)查高校录取比页面
(8)查高校专业页面
(9)我的评分页面
(10)我的收藏页面
(11)后台数据管理页面
(12)数据采集爬虫页面
基于Python的考研院校推荐系统是一款利用Python语言和相关技术,为考生提供个性化院校推荐服务的应用系统。以下是该系统的主要介绍:
数据收集:系统采集了全国各地公布的考研数据,包括历年各省份考研报名人数、报考人数、录取分数线等信息,以及各高校的专业、科研情况、学术声誉等数据。通过对这些数据进行整合处理,系统建立了一个完整的数据仓库。
数据挖掘:系统利用机器学习和数据挖掘技术,对用户输入的专业、成绩、地区等信息进行分析,确定用户的兴趣和需求,以此为基础,利用协同过滤算法、基于内容的推荐算法等多种算法方法,实现个性化的院校推荐。
推荐算法:系统根据用户的输入信息,利用机器学习算法对已有的数据进行模型训练和预测,计算出与用户最匹配的院校推荐结果。
用户界面和交互设计:系统提供友好的用户界面和交互设计,用户可以根据自己的需求输入专业、成绩、地区等信息,同时还可以根据自己的偏好进行院校筛选和优化。
可视化展示:系统采用图表和图形等方式,直观地呈现推荐结果,使用户能够更加清晰明了地理解推荐结果,并进一步提高决策效率。
综上所述,基于Python的考研院校推荐系统是一款利用Python技术进行开发的应用系统,旨在为考生提供个性化的院校推荐服务。通过数据挖掘和机器学习技术,系统可以根据用户的兴趣和需求,给出符合用户背景和选校要求的院校推荐,提高用户决策效率,帮助他们实现顺利升学。
import random from django.shortcuts import render import math from app01 import models from app01.models import School, UserScore, User, UserCollection from app01.utils.pagination import Pagination def jaccard_similarity(a, b): 计算杰卡德相似度 将布尔向量转换为集合 set_a = set(i for i, x in enumerate(a) if x) print("set_a:", set_a) set_b = set(i for i, x in enumerate(b) if x) print("set_b:", set_b) 计算交集和并集的大小 intersection = len(set_a.intersection(set_b)) print("a和b交集:", set_a.intersection(set_b)) union = len(set_a.union(set_b)) print("a和b并集:", set_a.union(set_b)) 计算相似度 similarity = intersection / union if union else 0 return similarity 重载字典计算方法 class MyDict(dict): def __add__(self, other): res = MyDict(self) for key, val in other.items(): if key in res: res[key] += val else: res[key] = val return res def __mul__(self, factor): res = MyDict() for key, val in self.items(): res[key] = val * factor return res def __rmul__(self, factor): return self.__mul__(factor) def cosine_similarity(v1, v2): 计算余弦相似度 numerator = sum([a * b for a, b in zip(v1, v2)]) 两向量的内积作为分子 denominator = math.sqrt(sum([a ** 2 for a in v1])) * math.sqrt(sum([b ** 2 for b in v2])) 两向量模长的乘积作为分母 if denominator > 0: return numerator / denominator else: return 0 基于用户收藏计算当前用户与其他用户的杰卡德相似度 def user_jaccard_similarity_collections(user_id, default_similarity_jaccard=0): 获取当前用户的收藏数据 user_collections = UserCollection.objects.filter(user_id=user_id).values('school_id', 'collection') 获取当前用户收藏的学校id user_collections_school_id = [user_collection['school_id'] for user_collection in user_collections] print("当前用户收藏情况:") print(user_collections_school_id) print("基于用户收藏的邻居用户收藏情况:") 构造当前用户收藏向量 user_collection_vector = [0 for i in range(999)] for school_id in user_collections_school_id: user_collection_vector[school_id] = 1 similarities_jaccard = {} 定义字典来存放与当前用户相似用户的id和相似度 for user in User.objects.exclude(id=user_id): 获取当前用户与其他用户共同收藏的物品的id collections = user.usercollections.filter(school_id__in=user_collections_school_id).values('school_id') if collections: 如果当前用户与该用户有共同收藏的学校,则计算当前用户与该用户的相似度,这里使用杰卡德 获取该用户所有的收藏情况:(school_id) collections = user.usercollections.filter().values('school_id') collections_school_id = [(collection['school_id']) for collection in collections] print(collections_school_id) 构造该用户收藏向量:collection_vector collection_vector = [0 for i in range(999)] for school_id in collections_school_id: collection_vector[school_id] = 1 collection_vector[0] = user.id print(collection_vector) 计算两用户之间的杰卡德相似度 similarity_jaccard = jaccard_similarity(user_collection_vector, collection_vector) if similarity_jaccard > default_similarity_jaccard: similarities_jaccard[user.id] = similarity_jaccard return similarities_jaccard 基于用户收藏计算当前用户对邻居收藏院校的jaccard兴趣度 def user_recommendations_jaccard_collections(user_id, similarities, similarities_jaccard): 获取当前用户的收藏数据 user_collections = UserCollection.objects.filter(user_id=user_id).values('school_id', 'collection') 获取当前用户收藏的学校id user_collections_school_id = [user_collection['school_id'] for user_collection in user_collections] recommendations_jaccard = {} print("邻居用户已收藏的学校中目标用户未收藏的学校:", UserCollection.objects.filter(user_id__in=similarities).exclude( school_id__in=user_collections_school_id).values_list('school_id', flat=True).distinct()) 邻居用户已收藏的学校中目标用户未收藏的学校 for school_id in UserCollection.objects.filter(user_id__in=similarities).exclude( school_id__in=user_collections_school_id).values_list('school_id', flat=True).distinct(): 获取收藏了当前物品的用户:用户id和收藏情况(collection = 1) item_collections = UserCollection.objects.filter(school_id=school_id).values('user_id', 'collection') 初始化一个空列表 weighted_scores = [] 遍历 item_ratings 中的每一条记录 for collection in item_collections: 如果该收藏记录对应的用户在 similarities_jaccard 字典中,则计算该收藏记录对该物品的权重得分 if collection['user_id'] in similarities_jaccard: 获取该收藏记录对应用户与目标用户的相似度 similarity = similarities_jaccard[collection['user_id']] 计算该收藏记录对该物品的权重得分 weighted_score = similarity * collection['collection'] 将该权重得分添加到列表中 weighted_scores.append(weighted_score) numerator = sum(weighted_scores) denominator = sum(similarities_jaccard.values()) if denominator > 0: recommendations_jaccard[school_id] = round(numerator / denominator, 2) print("邻居用户已收藏的学校中目标用户未收藏的学校:", UserCollection.objects.filter(user_id__in=similarities).exclude( school_id__in=user_collections_school_id).values_list('school_id', flat=True).distinct()) print("基于用户收藏的兴趣度得分情况:",recommendations_jaccard) return recommendations_jaccard 基于用户评分计算当前用户和其他用户的余弦相似度 def user_cosine_similarity_ratings(user_id, default_similarity_cosine=0): 获取当前用户评分数据 user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score') user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings] 获取当前用户评分学校的评分情况:(school_id,score) user_ratings_school = [(user_rating['school_id'], user_rating['score']) for user_rating in user_ratings] print("当前用户评分情况:") print(user_ratings_school) print("基于用户评分的邻居用户评分情况:") 构造当前用户评分向量:user_rating_vector user_rating_vector = [0 for i in range(999)] for school_id, score in user_ratings_school: user_rating_vector[school_id] = score 根据评分情况计算所有用户的相似度:如果两用户之间没有共同评分的学校,则相似度为0 similarities_cosine = {} for user in User.objects.exclude(id=user_id): 获取当前用户与其他用户共同评价的物品的评分数据 ratings = user.userscores.filter(school_id__in=user_ratings_school_id).values('school_id', 'score') if ratings: 如果当前用户与该用户有共同评分的学校,则计算当前用户与该用户的相似度,这里使用余弦相似度 获取该用户所有的评分学校的评分情况:(school_id,score) ratings = user.userscores.filter().values('school_id', 'score') ratings_school = [(rating['school_id'], rating['score']) for rating in ratings] print(ratings_school) 构造该用户评分向量:rating_vector rating_vector = [0 for i in range(999)] for school_id, score in ratings_school: rating_vector[school_id] = score print(rating_vector) 计算两用户之间的余弦相似度 similarity_cosine = cosine_similarity(user_rating_vector, rating_vector) if similarity_cosine > default_similarity_cosine: similarities_cosine[user.id] = similarity_cosine return similarities_cosine 基于用户评分计算当前用户对邻居评分院校的cosine兴趣度 def user_recommendations_cosine_ratings(user_id, similarities, similarities_cosine): 获取当前用户评分数据 user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score') user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings] 根据相似度值为用户推荐物品 recommendations_cosine = {} 定义字典存放物品id和物品相似度 邻居用户已评分的学校中目标用户未评分的学校 for school_id in UserScore.objects.filter(user_id__in=similarities).exclude( school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct(): 获取评价了当前物品的用户和评分数据 item_ratings = UserScore.objects.filter(school_id=school_id).values('user_id', 'score') print("item_ratings:", item_ratings) 初始化一个空列表 weighted_scores = [] 遍历 item_ratings 中的每一条记录 for rating in item_ratings: 如果该评分记录对应的用户在 similarities 字典中,则计算该评分记录对该物品的权重得分 if rating['user_id'] in similarities_cosine: 获取该评分记录对应用户与目标用户的相似度 similarity = similarities_cosine[rating['user_id']] 计算该评分记录对该物品的权重得分 weighted_score = similarity * rating['score'] 将该权重得分添加到列表中 weighted_scores.append(weighted_score) numerator = sum(weighted_scores) denominator = sum(similarities_cosine.values()) if denominator > 0: recommendations_cosine[school_id] = round(numerator / denominator, 2) print("邻居用户已评分的学校中目标用户未评分的学校:", UserScore.objects.filter(user_id__in=similarities).exclude( school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct()) print("基于用户评分的兴趣度得分情况:", recommendations_cosine) return recommendations_cosine 补充推荐结果 def recommendations_supply(user_id, top_items: [tuple], top_n): print("top_items:", top_items) user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score') user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings] 获取当前用户的收藏数据 user_collections = UserCollection.objects.filter(user_id=user_id).values('school_id', 'collection') 获取当前用户收藏的学校id user_collections_school_id = [user_collection['school_id'] for user_collection in user_collections] if len(top_items) < top_n: rest = top_n - len(top_items) exists_school_id = list( [top_item[0] for top_item in top_items]) + user_ratings_school_id + user_collections_school_id rest_id = set() while len(rest_id) < rest: random_id = random.randint(1, 855) if random_id not in exists_school_id: rest_id.add(random_id) recommendations_id = [item[0] for item in top_items] + list(rest_id) else: recommendations_id = [item[0] for item in top_items][:top_n] return recommendations_id def user_based_recommend(request, default_similarity_jaccard=0, default_similarity_cosine=0, alpha=10): alpha_user = request.GET.get('alpha_user', '') if alpha_user != '': alpha_user = int(float(alpha_user)) if 0 <= alpha_user <= 10: alpha = alpha_user elif alpha_user < 0: alpha_user = 0 elif alpha_user > 10: alpha_user = 10 alpha = alpha / 10 print("推荐依据:评分情况:{0},收藏情况:{1}".format(alpha, 1 - alpha)) top_n = 12 获取当前用户id user_id = list(request.session.values())[0].get('id') similarities_cosine = user_cosine_similarity_ratings(user_id, default_similarity_cosine=default_similarity_cosine) similarities_jaccard = user_jaccard_similarity_collections(user_id, default_similarity_jaccard=default_similarity_jaccard) print("similarities_cosine:", similarities_cosine) print("similarity_jaccard:", similarities_jaccard) similarities = alpha * MyDict(similarities_cosine) + (1 - alpha) * MyDict(similarities_jaccard) print("similarities:", similarities) 测试:打印基于用户评分的用户相似度矩阵: print("基于用户评分的用户相似度矩阵:") print("user_id:", [i for i in similarities_cosine]) print("similarity:", [round(i, 2) for i in similarities_cosine.values()]) 测试:打印基于用户收藏的用户相似度矩阵: print("基于用户收藏的用户相似度矩阵:") print("user_id:", [i for i in similarities_jaccard]) print("similarity:", [round(i, 2) for i in similarities_jaccard.values()]) 根据相似度值为用户推荐物品 打印推荐字典 recommendations_cosine = user_recommendations_cosine_ratings(user_id=user_id, similarities=similarities, similarities_cosine=similarities_cosine) recommendations_jaccard = user_recommendations_jaccard_collections(user_id=user_id, similarities=similarities, similarities_jaccard=similarities_jaccard) print("当alpha=0.5时基于评分的兴趣度得分情况:\n", recommendations_cosine) print("当alpha=0.5时基于收藏的兴趣度得分情况:\n", recommendations_jaccard) 测试:打印目标用户对于邻居用户中未评分学校的兴趣度得分 recommendations = alpha * MyDict(recommendations_cosine) + (1 - alpha) * MyDict(recommendations_jaccard) recommendations = dict(filter(lambda item: item[1] > 0, recommendations.items())) print("当alpha=0.5时的加权兴趣度得分情况:\n", recommendations) 返回前 top_n 个物品 top_items = sorted(recommendations.items(), key=lambda x: x[1], reverse=True) print("Top items:", top_items) 如果返回的数量不够top_n,就去随机补充一些没有被推荐和没有被当前用户评分过的学校id,补充至top_n个,返回top_n个被推荐学校的id 如果够,直接返回top_n个被推荐学校的id recommendations_id = recommendations_supply(user_id=user_id, top_items=top_items, top_n=top_n) 从数据库中根据id找到被推荐的学校,打乱顺序返回 recommended_schools = models.School.objects.filter(id__in=recommendations_id).order_by('?') 不打乱顺序,得分较高的排在前面 recommended_schools = models.School.objects.filter(id__in=[item[0] for item in top_items]) 2.实例化分页对象 page_object = Pagination(request, recommended_schools, page_size=12) context = { "alpha": alpha_user, "a5": "active", "title": "基于用户推荐", "link": "https://yz.chsi.com.cn/", "recommended_schools": page_object.page_queryset, "page_string": page_object.html() 生成页码 } return render(request, 'recommend_base.html', context) def user_based_recommend_ratings(request, default_similarity=0): top_n = 12 获取当前用户id user_id = list(request.session.values())[0].get('id') 获取当前用户评分数据 user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score') 获取当前用户评分的学校id user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings] 获取当前用户评分学校的评分情况:(school_id,score) user_ratings_school = [(user_rating['school_id'], user_rating['score']) for user_rating in user_ratings] print("目标用户评分情况:") print(user_ratings_school) 测试:打印所有用户评分信息 print("所有用户评分信息:") all_user_score = UserScore.objects.filter().order_by('user_id') print("user_id"+'\t\t'+"school_id"+"\t\t\t\t"+"score") for user in all_user_score: print(str(user.user_id) + "\t\t\t" + str(user.school)+"\t\t\t\t" + str(user.score)) 测试:构造用户评分矩阵 print("用户评分矩阵:") print("user_id" + "\t" + "score_list") 构造当前用户评分向量:user_rating_vector user_rating_vector = [0 for i in range(999)] for school_id, score in user_ratings_school: user_rating_vector[school_id] = score user_rating_vector[0] = user_id print(user_rating_vector) 计算所有用户的相似度:如果两用户之间没有共同评分的学校,则相似度为0 similarities = {} 定义字典来存放与当前用户相似用户的id和相似度 print("邻居用户评分情况:") for user in User.objects.exclude(id=user_id): 获取当前用户与其他用户共同评价的物品的评分数据 ratings = user.userscores.filter(school_id__in=user_ratings_school_id).values('school_id', 'score') if ratings: 如果当前用户与该用户有共同评分的学校,则计算当前用户与该用户的相似度,这里使用余弦相似度 获取该用户所有的评分学校的评分情况:(school_id,score) ratings = user.userscores.filter().values('school_id', 'score') ratings_school = [(rating['school_id'], rating['score']) for rating in ratings] print(ratings_school) 构造该用户评分向量:rating_vector rating_vector = [0 for i in range(999)] for school_id, score in ratings_school: rating_vector[school_id] = score rating_vector[0] = user.id print(rating_vector) 计算两用户之间的余弦相似度 similarity = cosine_similarity(user_rating_vector, rating_vector) if similarity > default_similarity: similarities[user.id] = similarity 打印相似度字典 print("Similarities:", similarities) 测试:打印用户相似度矩阵 print("用户相似度矩阵:") print("用户id:", [round(i,2) for i in similarities]) print("相似度:",[round(i,2) for i in similarities.values()]) 根据相似度值为用户推荐物品 recommendations = {} 定义字典存放物品id和物品相似度 print("邻居用户中目标用户未评分的学校:",UserScore.objects.filter(user_id__in=similarities).exclude( school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct()) for school_id in UserScore.objects.filter(user_id__in=similarities).exclude( school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct(): 获取当前物品被评价的用户和评分数据 item_ratings = UserScore.objects.filter(school_id=school_id).values('user_id', 'score') print("item_ratings:", item_ratings) 初始化一个空列表 weighted_scores = [] 遍历 item_ratings 中的每一条记录 for rating in item_ratings: 如果该评分记录对应的用户在 similarities 字典中,则计算该评分记录对该物品的权重得分 if rating['user_id'] in similarities: 获取该评分记录对应用户与目标用户的相似度 similarity = similarities[rating['user_id']] 计算该评分记录对该物品的权重得分 weighted_score = similarity * rating['score'] 将该权重得分添加到列表中 weighted_scores.append(weighted_score) numerator = sum(weighted_scores) denominator = sum(similarities.values()) if denominator > 0: recommendations[school_id] = round(numerator / denominator, 2) 打印推荐字典 print("Recommendations:", recommendations) 测试:打印目标用户对于邻居用户中未评分学校的兴趣度得分 print("兴趣度得分情况:",recommendations) 返回前 top_n 个物品 top_items = sorted(recommendations.items(), key=lambda x: x[1], reverse=True) print("Top items:", top_items) 如果返回的数量不够top_n,就去随机补充一些没有被推荐和没有被当前用户评分过的学校id,补充至top_n个 if len(top_items) < top_n: rest = top_n - len(top_items) exists_school_id = list(recommendations.keys()) + user_ratings_school_id rest_id = set() while len(rest_id) < rest: random_id = random.randint(1, 855) if random_id not in exists_school_id: rest_id.add(random_id) recommendations_id = [item[0] for item in top_items] + list(rest_id) else: recommendations_id = [item[0] for item in top_items][:12] 从数据库中根据id找到被推荐的学校 recommended_schools = models.School.objects.filter(id__in=recommendations_id).order_by('?') 2.实例化分页对象 page_object = Pagination(request, recommended_schools, page_size=12) context = { "a5": "active", "title": "基于用户推荐", "link": "https://yz.chsi.com.cn/", "recommended_schools": page_object.page_queryset, "page_string": page_object.html() 生成页码 } return render(request, 'recommend_base.html', context) def user_based_recommend(request): top_n = 12 获取当前用户id user_id = list(request.session.values())[0].get('id') 获取当前用户评分数据 user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score') 获取当前用户评分的学校id user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings] user_ratings_school = [(user_rating['school_id'],user_rating['score']) for user_rating in user_ratings] print(user_ratings_school) 获取当前用户评分的学校分数 构造当前用户评分向量: user_rating_vector = [ 0 for i in range(1000)] for school_id,score in user_ratings_school: user_rating_vector[school_id] = score 计算所有用户的相似度:如果两用户之间没有共同评分的学校,则相似度为0 similarities = {} for user in User.objects.exclude(id=user_id): 获取当前用户与其他用户共同评价的物品的评分数据 ratings = user.userscores.filter(school_id__in=user_ratings_school_id).values('school_id','score') print("{0}:{1}".format(user, ratings)) if ratings:如果当前用户与该用户有共同评分的学校,则计算当前用户与该用户的相似度,这里使用余弦相似度 构造该用户评分向量: ratings_school = [(rating['school_id'], rating['score']) for rating in ratings] rating_vector = [0 for i in range(1000)] for school_id, score in ratings_school: rating_vector[school_id] = score print("当前用户:",user_rating_vector) print("该用户:",rating_vector) similarity = cosine_similarity(user_rating_vector, rating_vector) similarities[user.id] = similarity 打印相似度字典 print("Similarities:", similarities) 根据相似度值为用户推荐物品 recommendations = {} for school_id in UserScore.objects.filter(user_id__in=similarities.keys()).exclude( school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct(): 获取当前物品被评价的用户和评分数据 print(school_id) item_ratings = UserScore.objects.filter(school_id=school_id).values('user_id', 'score') print("item_ratings:", item_ratings) 初始化一个空列表 weighted_scores = [] 遍历 item_ratings 中的每一条记录 for rating in item_ratings: 如果该评分记录对应的用户在 similarities 字典中,则计算该评分记录对该物品的权重得分 if rating['user_id'] in similarities: 获取该评分记录对应用户与目标用户的相似度 similarity = similarities[rating['user_id']] 计算该评分记录对该物品的权重得分 weighted_score = similarity * rating['score'] 将该权重得分添加到列表中 weighted_scores.append(weighted_score) numerator = sum([similarities[user_id] * score for user_id, score in item_ratings if user_id in similarities]) numerator = sum(weighted_scores) print("numerator:", numerator) denominator = sum([similarities[user_id] for user_id in similarities]) denominator = sum(similarities.values()) print("denominator:", denominator) if denominator > 0: recommendations[school_id] = numerator / denominator 打印推荐字典 print("Recommendations:", recommendations) 返回前 top_n 个物品 top_items = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)[:top_n] top_items = sorted(recommendations.items(), key=lambda x: x[1], reverse=True) print("top_items", top_items) recommended_schools = models.School.objects.filter(id__in=[item[0] for item in top_items]).order_by("?")[:top_n] recommended_schools = models.School.objects.filter(id__in=[item[0] for item in top_items]) print(recommended_schools) 2.实例化分页对象 page_object = Pagination(request, recommended_schools, page_size=12) context = { "title": "基于用户推荐", "link": "https://yz.chsi.com.cn/", "recommended_schools": page_object.page_queryset, "page_string": page_object.html() 生成页码 } return render(request, 'recommend_base.html', context) 注释调试版 def user_based_recommend(request, default_similarity_jaccard=0, default_similarity_cosine=0, alpha=1): top_n = 12 获取当前用户id user_id = list(request.session.values())[0].get('id') 获取当前用户评分数据 user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score') 获取当前用户收藏数据 user_collections = UserCollection.objects.filter(user_id=user_id).values('school_id', 'collection') 获取当前用户评分的学校id user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings] 获取当前用户收藏的学校id user_collections_school_id = [user_collection['school_id'] for user_collection in user_collections] 获取当前用户评分学校的评分情况:(school_id,score) user_ratings_school = [(user_rating['school_id'], user_rating['score']) for user_rating in user_ratings] 获取当前用户的收藏情况:(school_id,1) user_collections_school = [(user_collection['school_id'], user_collection['collection']) for user_collection in user_collections] print("目标用户评分情况:") print(user_ratings_school) 测试:打印所有用户评分信息 print("所有用户评分信息:") all_user_score = UserScore.objects.filter().order_by('user_id') print("user_id"+'\t\t'+"school_id"+"\t\t\t\t"+"score") for user in all_user_score: print(str(user.user_id) + "\t\t\t" + str(user.school)+"\t\t\t\t" + str(user.score)) 测试:构造用户评分矩阵 print("用户评分矩阵:") print("user_id" + "\t" + "score_list") 构造当前用户评分向量:user_rating_vector user_rating_vector = [0 for i in range(999)] for school_id, score in user_ratings_school: user_rating_vector[school_id] = score 构造当前用户收藏向量 user_collection_vector = [0 for i in range(999)] for school_id in user_collections_school_id: user_collection_vector[school_id] = 1 user_rating_vector[0] = user_id print(user_rating_vector) 计算所有用户的相似度:如果两用户之间没有共同评分的学校,则相似度为0 similarities_jaccard = {} 定义字典来存放与当前用户相似用户的id和相似度 print("邻居用户评分情况:") for user in User.objects.exclude(id=user_id): 获取当前用户与其他用户共同收藏的物品的id collections = user.usercollections.filter(school_id__in=user_ratings_school_id).values('school_id') if collections: 如果当前用户与该用户有共同收藏的学校,则计算当前用户与该用户的相似度,这里使用杰卡德 获取该用户所有的收藏情况:(school_id,score) collections = user.usercollections.filter().values('school_id') collections_school_id = [(collection['school_id']) for collection in collections] print(ratings_school) 构造该用户收藏向量:collection_vector collection_vector = [0 for i in range(999)] for school_id in collections_school_id: collection_vector[school_id] = 1 rating_vector[0] = user.id print(rating_vector) 计算两用户之间的杰卡德相似度 similarity_jaccard = jaccard_similarity(user_rating_vector, collection_vector) if similarity_jaccard > default_similarity_jaccard: similarities_jaccard[user.id] = similarity_jaccard similarities_cosine = {} for user in User.objects.exclude(id=user_id): 获取当前用户与其他用户共同评价的物品的评分数据 ratings = user.userscores.filter(school_id__in=user_ratings_school_id).values('school_id', 'score') if ratings: 如果当前用户与该用户有共同评分的学校,则计算当前用户与该用户的相似度,这里使用余弦相似度 获取该用户所有的评分学校的评分情况:(school_id,score) ratings = user.userscores.filter().values('school_id', 'score') ratings_school = [(rating['school_id'], rating['score']) for rating in ratings] print(ratings_school) 构造该用户评分向量:rating_vector rating_vector = [0 for i in range(999)] for school_id, score in ratings_school: rating_vector[school_id] = score rating_vector[0] = user.id print(rating_vector) 计算两用户之间的余弦相似度 similarity_cosine = cosine_similarity(user_rating_vector, rating_vector) if similarity_cosine > default_similarity_cosine: similarities_cosine[user.id] = similarity_cosine 打印相似度字典 print("Similarities:", similarities) 测试:打印用户相似度矩阵 print("用户相似度矩阵:") print("用户id:", [round(i,2) for i in similarities]) print("相似度:",[round(i,2) for i in similarities.values()]) print("similarities_cosine:", similarities_cosine) print("similarity_jaccard:", similarities_jaccard) similarities = alpha * MyDict(similarities_cosine) + (1 - alpha) * MyDict(similarities_jaccard) print("similarities:", similarities) 根据相似度值为用户推荐物品 recommendations_cosine = {} 定义字典存放物品id和物品相似度 print("邻居用户已评分的学校中目标用户未评分的学校:", UserScore.objects.filter(user_id__in=similarities).exclude( school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct()) 邻居用户已评分的学校中目标用户未评分的学校 for school_id in UserScore.objects.filter(user_id__in=similarities).exclude( school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct(): 获取评价了当前物品的用户和评分数据 item_ratings = UserScore.objects.filter(school_id=school_id).values('user_id', 'score') print("item_ratings:", item_ratings) 初始化一个空列表 weighted_scores = [] 遍历 item_ratings 中的每一条记录 for rating in item_ratings: 如果该评分记录对应的用户在 similarities 字典中,则计算该评分记录对该物品的权重得分 if rating['user_id'] in similarities_cosine: 获取该评分记录对应用户与目标用户的相似度 similarity = similarities_cosine[rating['user_id']] 计算该评分记录对该物品的权重得分 weighted_score = similarity * rating['score'] 将该权重得分添加到列表中 weighted_scores.append(weighted_score) numerator = sum(weighted_scores) denominator = sum(similarities_cosine.values()) if denominator > 0: recommendations_cosine[school_id] = round(numerator / denominator, 2) recommendations_jaccard = {} print("邻居用户已收藏的学校中目标用户未收藏的学校:", UserCollection.objects.filter(user_id__in=similarities).exclude( school_id__in=user_collections_school_id).values_list('school_id', flat=True).distinct()) 邻居用户已收藏的学校中目标用户未收藏的学校 for school_id in UserCollection.objects.filter(user_id__in=similarities).exclude( school_id__in=user_collections_school_id).values_list('school_id', flat=True).distinct(): 获取收藏了当前物品的用户:用户id和收藏情况(collection = 1) item_collections = UserCollection.objects.filter(school_id=school_id).values('user_id', 'collection') print("item_ratings:", item_ratings) 初始化一个空列表 weighted_scores = [] 遍历 item_ratings 中的每一条记录 for collection in item_collections: 如果该收藏记录对应的用户在 similarities_jaccard 字典中,则计算该收藏记录对该物品的权重得分 if collection['user_id'] in similarities_jaccard: 获取该评分记录对应用户与目标用户的相似度 similarity = similarities_jaccard[collection['user_id']] 计算该评分记录对该物品的权重得分 weighted_score = similarity * collection['collection'] 将该权重得分添加到列表中 weighted_scores.append(weighted_score) numerator = sum(weighted_scores) denominator = sum(similarities_jaccard.values()) if denominator > 0: recommendations_jaccard[school_id] = round(numerator / denominator, 2) 打印推荐字典 print("Recommendations_cosine:", recommendations_cosine) print("Recommendations_jaccard:", recommendations_jaccard) 测试:打印目标用户对于邻居用户中未评分学校的兴趣度得分 recommendations = alpha * MyDict(recommendations_cosine) + (1 - alpha) * MyDict(recommendations_jaccard) recommendations = dict(filter(lambda item: item[1] > 0, recommendations.items())) print("兴趣度得分情况:", recommendations) 返回前 top_n 个物品 top_items = sorted(recommendations.items(), key=lambda x: x[1], reverse=True) print("Top items:", top_items) 如果返回的数量不够top_n,就去随机补充一些没有被推荐和没有被当前用户评分过的学校id,补充至top_n个 if len(top_items) < top_n: rest = top_n - len(top_items) exists_school_id = list(recommendations.keys()) + user_ratings_school_id rest_id = set() while len(rest_id) < rest: random_id = random.randint(1, 855) if random_id not in exists_school_id: rest_id.add(random_id) recommendations_id = [item[0] for item in top_items] + list(rest_id) else: recommendations_id = [item[0] for item in top_items][:12] 从数据库中根据id找到被推荐的学校 recommended_schools = models.School.objects.filter(id__in=recommendations_id).order_by('?') 2.实例化分页对象 page_object = Pagination(request, recommended_schools, page_size=12) context = { "a5": "active", "title": "基于用户推荐", "link": "https://yz.chsi.com.cn/", "recommended_schools": page_object.page_queryset, "page_string": page_object.html() 生成页码 } return render(request, 'recommend_base.html', context)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/123610?site
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。