import numpy as npfrom scipy.spatial.distance import cosinefrom models import UserScore, Collegedef collaborative_filtering_recommend(user_id, top_n=10): # 获取所有用户评分数据 all_scores = UserScore.objects.all() user_ids = list(set([score.user_id for score in all_scores])) college_ids = list(set([score.college_id for score in all_scores])) # 构建用户-院校评分矩阵 rating_matrix = np.zeros((len(user_ids), len(college_ids))) user_index_map = {uid: idx for idx, uid in enumerate(user_ids)} college_index_map = {cid: idx for idx, cid in enumerate(college_ids)} for score in all_scores: user_idx = user_index_map[score.user_id] college_idx = college_index_map[score.college_id] rating_matrix[user_idx][college_idx] = score.score # 计算用户相似度 target_user_idx = user_index_map.get(user_id) if target_user_idx is None: return [] similarities = [] for idx, uid in enumerate(user_ids): if idx != target_user_idx: sim = 1 - cosine(rating_matrix[target_user_idx], rating_matrix[idx]) similarities.append((uid, sim)) # 选取最相似的K个用户 similarities.sort(key=lambda x: x[1], reverse=True) similar_users = [uid for uid, sim in similarities[:5]] # 生成推荐列表 recommend_scores = {} for college_idx, cid in enumerate(college_ids): if rating_matrix[target_user_idx][college_idx] == 0: weighted_sum = sum(rating_matrix[user_index_map[uid]][college_idx] * similarities[idx][1] for idx, uid in enumerate(similar_users)) recommend_scores[cid] = weighted_sum # 排序并返回Top-N推荐 sorted_colleges = sorted(recommend_scores.items(), key=lambda x: x[1], reverse=True)[:top_n] recommend_list = [College.objects.get(id=cid) for cid, score in sorted_colleges] return recommend_list