旅游推荐数据分析可视化系统算法
本文档详细介绍了旅游推荐数据分析可视化系统中使用的各种算法,包括推荐算法、数据分析算法和可视化算法。
目录
推荐算法
基于用户的协同过滤推荐
协同过滤是一种常用的推荐算法,通过分析用户之间的相似性,为目标用户推荐与其相似的用户喜欢的项目。本系统实现了基于用户的协同过滤算法。
算法步骤:
- 获取所有用户的评分数据,数据结构为
{用户ID: {景点标题: 评分}, ...}
- 计算目标用户与其他用户之间的相似度(使用余弦相似度)
- 根据相似度对其他用户进行降序排序
- 选择与目标用户最相似的N个用户喜欢的景点
- 过滤掉目标用户已经评分过的景点,生成最终推荐列表
核心代码:
def user_bases_collaborative_filtering(user_id, user_ratings, top_n=3):
# 获取目标用户的评分数据
target_user_ratings = user_ratings[user_id]
# 初始化一个字段,用于保存其他用户与目标用户的相似度得分
user_similarity_scores = {}
# 将目标用户的评分转化为numpy数组
target_user_ratings_list = np.array([
rating for _ , rating in target_user_ratings.items()
])
# 计算目标用户与其他用户之间的相似度得分
for user, ratings in user_ratings.items():
if user == user_id:
continue
# 将其他用户的评分转化为numpy数组
user_ratings_list = np.array([ratings.get(item,0) for item in target_user_ratings])
# 计算余弦相似度
similarity_score = cosine_similarity([user_ratings_list],[target_user_ratings_list])[0][0]
user_similarity_scores[user] = similarity_score
# 对用户相似度得分进行降序排序
sorted_similar_user = sorted(user_similarity_scores.items(), key=lambda x:x[1], reverse=True)
# 选择 TOP N 个相似用户喜欢的景点 作为推荐结果
recommended_items = set()
for similar_user, _ in sorted_similar_user[:top_n]:
recommended_items.update(user_ratings[similar_user].keys())
# 过滤掉目标用户已经评分过的景点
recommended_items = [item for item in recommended_items if item not in target_user_ratings]
return recommended_items
优点:
- 不需要了解项目的具体特征,只需要用户的历史行为数据
- 可以发现用户潜在的兴趣点,提供个性化推荐
- 随着系统使用量增加,推荐效果会逐渐提升
缺点:
- 冷启动问题:新用户或新项目缺乏足够的评分数据
- 数据稀疏性:用户通常只评价少量项目,导致用户-项目矩阵稀疏
- 计算复杂度随用户和项目数量增加而增加
基于浏览历史的推荐
基于用户浏览历史的推荐算法通过分析用户历史浏览过的景点,识别用户偏好的省份和评分阈值,推荐符合用户口味的景点。
算法步骤:
- 获取用户浏览过的景点信息
- 统计用户偏好的省份,找出用户最常浏览的前3个省份
- 计算用户浏览过的景点的平均评分
- 根据用户偏好的省份筛选景点,过滤掉用户已浏览过的景点
- 筛选评分高于用户浏览景点平均评分的景点作为推荐结果
- 如果推荐结果不足,补充随机推荐
核心代码:
def getBrowseBasedRecommendation(user_id, limit=10):
from app.models import UserBrowseHistory, TravelInfo
try:
# 获取用户浏览过的景点ID列表
browsed_travels = UserBrowseHistory.objects.filter(user_id=user_id)
if not browsed_travels.exists():
# 如果用户没有浏览记录,返回随机推荐
return getRandomTravel()
# 获取浏览过的景点ID列表
browsed_travel_ids = [bt.travel_id for bt in browsed_travels]
# 获取用户浏览过的景点信息
browsed_travels_info = TravelInfo.objects.filter(id__in=browsed_travel_ids)
# 统计用户偏好的省份
province_count = {}
for travel in browsed_travels_info:
if travel.province not in province_count:
province_count[travel.province] = 0
province_count[travel.province] += 1
# 获取前3个最受欢迎的省份
favorite_provinces = []
if province_count:
sorted_provinces = sorted(province_count.items(), key=lambda x: x[1], reverse=True)
favorite_provinces = [p[0] for p in sorted_provinces[:3]]
# 计算平均评分
avg_score = 0
valid_scores = 0
for travel in browsed_travels_info:
try:
score = float(travel.score)
avg_score += score
valid_scores += 1
except ValueError:
continue
if valid_scores > 0:
avg_score = avg_score / valid_scores
else:
avg_score = 4.0 # 默认平均分
# 根据用户喜欢的省份筛选景点
if favorite_provinces:
all_travels = TravelInfo.objects.filter(province__in=favorite_provinces)
else:
# 如果没有偏好省份,获取所有景点
all_travels = TravelInfo.objects.all()
# 过滤出未浏览过且评分高于平均分的景点
result_list = []
for travel in all_travels:
if travel.id not in browsed_travel_ids:
try:
travel_score = float(travel.score)
if travel_score >= avg_score:
result_list.append(travel)
except ValueError:
continue
# 如果推荐结果不足,补充随机推荐
if len(result_list) < limit:
# 获取所有景点ID
all_travel_ids = set(TravelInfo.objects.values_list('id', flat=True))
# 排除已浏览和已推荐的ID
excluded_ids = set(browsed_travel_ids + [t.id for t in result_list])
remaining_ids = list(all_travel_ids - excluded_ids)
# 随机选择景点补充
if remaining_ids:
remaining_count = limit - len(result_list)
sample_size = min(remaining_count, len(remaining_ids))
random_ids = random.sample(remaining_ids, sample_size)
random_travels = TravelInfo.objects.filter(id__in=random_ids)
result_list.extend(random_travels)
# 限制返回数量
return result_list[:limit]
except Exception as e:
print(f"浏览历史推荐出错: {e}")
# 出错时返回随机推荐
return getRandomTravel()
优点:
- 不依赖用户评分数据,只需要浏览历史,适合解决冷启动问题
- 能够快速捕捉用户地理偏好,推荐相似区域的景点
- 实现简单,计算效率高
缺点:
- 可能过于强调地理位置,忽略其他特征
- 如果用户浏览历史不丰富,推荐效果可能不理想
- 不能很好地发现用户潜在的新兴趣
主题推荐算法
系统实现了三种主题推荐算法,分别针对亲子游、文化游和自然风光游,通过关键词匹配为用户提供特定主题的景点推荐。
亲子游推荐算法
算法步骤:
- 定义亲子游相关的关键词列表
- 遍历所有景点,检查景点介绍中是否包含亲子游关键词
- 如果找到的景点少于10个,则从评分较高的景点中补充
- 返回最终的推荐列表(不超过10个景点)
核心代码:
def getFamilyFriendlyTravel():
travelList = getAllTravelInfoMapData()
familyFriendlyList = []
# 亲子游关键词
keywords = ["亲子", "家庭", "儿童", "孩子", "小朋友", "游乐", "互动", "体验", "教育", "学习", "动物园", "植物园", "博物馆", "科技馆", "游乐园"]
for travel in travelList:
# 检查详情介绍中是否包含亲子游关键词
if any(keyword in travel.detailIntro for keyword in keywords) or any(keyword in travel.shortIntro for keyword in keywords):
familyFriendlyList.append(travel)
# 如果找到的景点少于10个,则从评分较高的景点中补充
if len(familyFriendlyList) < 10:
remainingCount = 10 - len(familyFriendlyList)
# 按评分排序(从高到低)
sortedTravelList = sorted(travelList, key=lambda x: float(x.score) if x.score.replace('.', '', 1).isdigit() else 0, reverse=True)
# 从排序后的列表中添加未包含在familyFriendlyList中的景点
added = 0
for travel in sortedTravelList:
if travel not in familyFriendlyList:
familyFriendlyList.append(travel)
added += 1
if added >= remainingCount:
break
# 如果找到的景点超过10个,只返回前10个
return familyFriendlyList[:10]
文化游推荐算法
算法步骤:
- 定义文化游相关的关键词列表
- 遍历所有景点,检查景点介绍中是否包含文化游关键词
- 如果找到的景点少于10个,则从评分较高的景点中补充
- 返回最终的推荐列表(不超过10个景点)
核心代码:
def getCulturalTravel():
travelList = getAllTravelInfoMapData()
culturalList = []
# 文化游关键词
keywords = ["文化", "历史", "博物馆", "古迹", "古城", "名胜", "传统", "遗址", "遗产", "文物", "寺庙", "宫殿", "纪念馆", "民俗", "古建筑"]
for travel in travelList:
# 检查详情介绍中是否包含文化游关键词
if any(keyword in travel.detailIntro for keyword in keywords) or any(keyword in travel.shortIntro for keyword in keywords):
culturalList.append(travel)
# 如果找到的景点少于10个,则从评分较高的景点中补充
if len(culturalList) < 10:
remainingCount = 10 - len(culturalList)
# 按评分排序(从高到低)
sortedTravelList = sorted(travelList, key=lambda x: float(x.score) if x.score.replace('.', '', 1).isdigit() else 0, reverse=True)
# 从排序后的列表中添加未包含在culturalList中的景点
added = 0
for travel in sortedTravelList:
if travel not in culturalList:
culturalList.append(travel)
added += 1
if added >= remainingCount:
break
# 如果找到的景点超过10个,只返回前10个
return culturalList[:10]
自然风光推荐算法
算法步骤:
- 定义自然风光相关的关键词列表
- 遍历所有景点,检查景点介绍中是否包含自然风光关键词
- 如果找到的景点少于10个,则从评分较高的景点中补充
- 返回最终的推荐列表(不超过10个景点)
核心代码:
def getNatureTravel():
travelList = getAllTravelInfoMapData()
natureList = []
# 自然风光关键词
keywords = ["自然", "风景", "山", "海", "湖", "森林", "湿地", "峡谷", "瀑布", "草原", "沙漠", "岛屿", "海滩", "国家公园", "保护区", "地质公园"]
for travel in travelList:
# 检查详情介绍中是否包含自然风光关键词
if any(keyword in travel.detailIntro for keyword in keywords) or any(keyword in travel.shortIntro for keyword in keywords):
natureList.append(travel)
# 如果找到的景点少于10个,则从评分较高的景点中补充
if len(natureList) < 10:
remainingCount = 10 - len(natureList)
# 按评分排序(从高到低)
sortedTravelList = sorted(travelList, key=lambda x: float(x.score) if x.score.replace('.', '', 1).isdigit() else 0, reverse=True)
# 从排序后的列表中添加未包含在natureList中的景点
added = 0
for travel in sortedTravelList:
if travel not in natureList:
natureList.append(travel)
added += 1
if added >= remainingCount:
break
# 如果找到的景点超过10个,只返回前10个
return natureList[:10]
主题推荐算法的优点:
- 通过关键词匹配可以快速筛选特定主题的景点
- 不依赖用户历史数据,适用于所有用户
- 实现简单,易于扩展新的主题
主题推荐算法的缺点:
- 依赖景点描述的质量和关键词的准确性
- 不考虑用户个人偏好
- 简单的关键词匹配可能忽略语义层面的相关性
随机推荐算法
当无法进行个性化推荐时(例如新用户、推荐结果不足等情况),系统会使用随机推荐算法提供备选推荐。
算法步骤:
- 获取所有景点列表
- 随机选择10个景点作为推荐结果
核心代码:
def getRandomTravel():
travelList = getAllTravelInfoMapData()
maxLen = len(travelList)
resultList = []
for i in range(10):
randomNum = random.randint(0,maxLen-1)
resultList.append(travelList[randomNum])
return resultList
优点:
- 简单实用,可以作为推荐算法的兜底方案
- 提供多样性,帮助用户发现意想不到的景点
- 不受冷启动问题影响
缺点:
- 不考虑用户个人喜好
- 推荐可能不相关,用户满意度可能较低
数据分析与可视化算法
词云生成算法
系统使用jieba分词和WordCloud库生成两种词云:景点介绍词云和用户评论词云。
算法步骤:
- 收集所有景点的详细介绍文本(或用户评论文本)
- 使用jieba进行中文分词
- 去除停用词(常见无意义词汇)
- 使用WordCloud生成词云图像
核心代码:
def getIntroCloudImg(targetImgSrc, resImgSrc):
travelList = TravelInfo.objects.all()
text = ''
stopwords = ['的', '是', '在', '这', '那', '他', '她', '它', '我', '你','和','等','为','有','与']
for travel in travelList:
text += travel.detailIntro
cut = jieba.cut(text)
newCut = []
for tex in cut:
if tex not in stopwords:
newCut.append(tex)
string = ' '.join(newCut)
img = Image.open(targetImgSrc)
img_arr = np.array(img)
wc = WordCloud(
background_color='white',
mask=img_arr,
font_path='/System/Library/Fonts/STHeiti Light.ttc'
)
wc.generate_from_text(string)
# 绘制图片
fig = plt.figure(1)
plt.imshow(wc)
plt.axis('off') # 不显示坐标轴
plt.savefig(resImgSrc, dpi=500)
评论词云生成的代码类似,区别在于数据源是用户评论内容。
优点:
- 直观展示文本中的高频词汇
- 有助于快速把握景点特点或用户评价重点
- 视觉效果好,便于用户理解
缺点:
- 只关注词频,忽略词之间的语义关系
- 需要合理的停用词表以避免无意义高频词汇影响结果
- 对长尾词汇(低频但可能重要的词)展示不足
地理分布可视化
系统利用ECharts库实现了景点地理分布的热力图可视化,直观展示全国各地区景点的密集程度。
算法步骤:
- 收集所有景点的地理位置数据
- 统计各省份的景点数量
- 使用ECharts的地图组件生成热力图
核心代码:
def getGeoData():
travelList = TravelInfo.objects.all()
provinceDic = {}
for travel in travelList:
if travel.province not in provinceDic:
provinceDic[travel.province] = 0
provinceDic[travel.province] += 1
geoData = []
for name,value in provinceDic.items():
geoData.append({
'name': name,
'value': value
})
return geoData
用户活跃度分析
系统通过分析用户注册时间的分布,生成用户活跃度时间分布图,展示平台用户增长情况。
算法步骤:
- 获取所有用户的创建时间
- 按月统计用户数量
- 使用ECharts生成柱状图或折线图
核心代码:
def getUserCreateTimeData():
userList = User.objects.all().order_by('createTime')
timeDic = {}
for user in userList:
createTime = user.createTime.strftime('%Y-%m')
if createTime not in timeDic:
timeDic[createTime] = 0
timeDic[createTime] += 1
resultList = []
for name,value in timeDic.items():
resultList.append({
'name': name,
'value': value
})
return resultList
评分与销量分析
系统通过分析景点的评分和销量数据,生成排行榜和图表,帮助用户识别高品质景点。
算法步骤:
- 获取所有景点的评分和销量数据
- 按评分或销量排序
- 生成Top10榜单或分布图表
核心代码:
def getAnthorData():
travelList = TravelInfo.objects.all()
# 按评分排序
scoreTop10 = sorted(travelList, key=lambda x: float(x.score) if x.score.replace('.', '', 1).isdigit() else 0, reverse=True)[:10]
# 按销量排序
saleCountTop10 = sorted(travelList, key=lambda x: int(x.saleCount) if x.saleCount.isdigit() else 0, reverse=True)[:10]
# 准备数据以适应前端展示
scoreTop10Data = []
for travel in scoreTop10:
scoreTop10Data.append({
'title': travel.title,
'detailUrl': travel.detailUrl,
'cover': travel.cover,
'detailAddress': travel.detailAddress,
'score': travel.score
})
return scoreTop10Data, saleCountTop10
价格分布分析
系统分析景点价格的分布情况,帮助用户了解旅游市场价格行情。
算法步骤:
- 获取所有景点的价格数据
- 对价格进行区间划分
- 统计各区间的景点数量
- 生成价格分布图表
核心代码:
@csrf_exempt
def priceChar(request):
travelList = TravelInfo.objects.all()
# 价格区间划分
priceRanges = {
"0-100": 0,
"101-200": 0,
"201-300": 0,
"301-400": 0,
"401-500": 0,
"501以上": 0
}
# 统计各区间景点数量
for travel in travelList:
try:
price = int(float(travel.price))
if price <= 100:
priceRanges["0-100"] += 1
elif price <= 200:
priceRanges["101-200"] += 1
elif price <= 300:
priceRanges["201-300"] += 1
elif price <= 400:
priceRanges["301-400"] += 1
elif price <= 500:
priceRanges["401-500"] += 1
else:
priceRanges["501以上"] += 1
except ValueError:
continue
# 准备数据以适应前端展示
labels = list(priceRanges.keys())
data = list(priceRanges.values())
return JsonResponse({
'labels': labels,
'data': data
})
关于旅游推荐系统情感分析算法
本文档详细介绍了旅游推荐数据分析可视化系统中使用的情感分析算法,该算法主要用于分析用户对景点的评论情感倾向,帮助系统更好地理解用户体验和景点质量。
目录
情感分析概述
情感分析(Sentiment Analysis),也称为意见挖掘(Opinion Mining),是一种通过计算机技术分析文本中情感倾向的方法。在旅游推荐系统中,情感分析主要用于识别用户对景点的评价是正面、负面还是中性的,从而帮助系统生成更符合用户偏好的推荐结果。
本系统使用了两种主要的情感分析方法:基于词典的情感分析和基于机器学习的情感分析。这两种方法各有优缺点,在实际应用中相互补充,以提高情感分析的准确性。
基于词典的情感分析
基于词典的情感分析是一种依赖预定义情感词典的方法,通过匹配文本中的情感词并计算其情感得分来确定整体情感倾向。
算法步骤:
- 对用户评论进行中文分词,去除停用词
- 使用情感词典(如知网HowNet情感词典、大连理工大学情感词典等)匹配分词结果
- 识别否定词、程度副词等修饰词,调整情感词的权重
- 计算整体情感得分,得出情感倾向判断
核心代码:
def analyze_sentiment_with_dictionary(comment):
# 分词
seg_list = jieba.cut(comment)
words = [word for word in seg_list if word not in stopwords]
# 情感得分计算
sentiment_score = 0
negative_modifier = False
degree_modifier = 1.0
for i, word in enumerate(words):
# 检查是否是情感词
if word in sentiment_dict:
word_score = sentiment_dict[word]
# 考虑否定词的影响
if negative_modifier:
word_score = -word_score
negative_modifier = False
# 考虑程度副词的影响
word_score = word_score * degree_modifier
degree_modifier = 1.0
sentiment_score += word_score
# 检查否定词
elif word in negation_words:
negative_modifier = True
# 检查程度副词
elif word in degree_words:
degree_modifier = degree_dict.get(word, 1.0)
# 情感分类
if sentiment_score > threshold_positive:
return "positive", sentiment_score
elif sentiment_score < threshold_negative:
return "negative", sentiment_score
else:
return "neutral", sentiment_score
优点:
- 实现简单,计算效率高
- 不需要大量标注数据
- 对特定领域词汇的情感能有比较准确的判断
缺点:
- 严重依赖词典质量和覆盖面
- 难以处理复杂句式和隐含情感
- 对新词和网络用语适应性差
基于机器学习的情感分析
基于机器学习的情感分析通过训练模型来学习文本与情感标签之间的映射关系,能够更好地处理复杂的语义情况。本系统使用了CNN和LSTM模型进行情感分析。
算法步骤:
- 数据预处理:对评论文本进行分词、去停用词等处理
- 特征提取:将文本转换为词向量表示(如Word2Vec, GloVe等)
- 模型训练:使用标注好的数据集训练深度学习模型
- 情感分类:使用训练好的模型对新评论进行情感分类
核心代码:
def build_sentiment_model():
# 构建模型
model = Sequential()
model.add(Embedding(max_features, embedding_dim, input_length=maxlen))
model.add(Bidirectional(LSTM(lstm_units, dropout=0.2, recurrent_dropout=0.2)))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation='softmax')) # 3类:正面、负面、中性
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model
def train_sentiment_model(model, X_train, y_train, X_val, y_val):
# 训练模型
early_stopping = EarlyStopping(monitor='val_loss', patience=3)
history = model.fit(X_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_data=(X_val, y_val),
callbacks=[early_stopping])
return model, history
def predict_sentiment(model, text):
# 预处理文本
processed_text = preprocess_text(text)
# 转换为向量
sequence = tokenizer.texts_to_sequences([processed_text])
padded_sequence = pad_sequences(sequence, maxlen=maxlen)
# 预测
prediction = model.predict(padded_sequence)[0]
sentiment_class = np.argmax(prediction)
confidence = prediction[sentiment_class]
# 映射到情感类别
sentiment_map = {0: "negative", 1: "neutral", 2: "positive"}
return sentiment_map[sentiment_class], confidence
优点:
- 能处理复杂的语义关系
- 自动学习特征,不需要人工构建特征
- 适应能力强,能处理新词和变化的语言表达
缺点:
- 需要大量标注数据进行训练
- 模型训练和预测的计算成本高
- 可解释性差,难以理解模型的决策过程
评论情感分布可视化
系统利用情感分析结果生成景点评论情感分布图表,以便直观展示用户对景点的整体评价倾向。
可视化算法步骤:
- 对景点的所有评论进行情感分析,获取情感分类结果
- 统计不同情感类别(正面、负面、中性)的数量
- 使用饼图或柱状图展示情感分布情况
核心代码:
@csrf_exempt
def sentiment_distribution(request):
if request.method == 'POST':
travel_id = request.POST.get('travel_id')
try:
travel = TravelInfo.objects.get(id=travel_id)
comments = json.loads(travel.comments) if travel.comments else []
# 情感分析结果统计
sentiment_counts = {
"positive": 0,
"neutral": 0,
"negative": 0
}
for comment in comments:
content = comment.get('content', '')
if content:
# 对评论进行情感分析
sentiment, _ = analyze_sentiment(content)
sentiment_counts[sentiment] += 1
# 准备饼图数据
labels = list(sentiment_counts.keys())
data = list(sentiment_counts.values())
return JsonResponse({
'labels': labels,
'data': data,
'title': f"{travel.title}评论情感分布"
})
except Exception as e:
return JsonResponse({'error': str(e)}, status=400)
return JsonResponse({'error': 'Invalid request'}, status=400)
情感分析的综合算法:
系统在实际应用中,会结合词典方法和机器学习方法的优势,采用集成策略进行情感分析:
def analyze_sentiment(text):
# 使用词典方法分析
dict_sentiment, dict_score = analyze_sentiment_with_dictionary(text)
# 使用机器学习模型分析
ml_sentiment, ml_confidence = predict_sentiment(model, text)
# 加权融合两种结果
if ml_confidence > high_confidence_threshold:
# 如果机器学习模型置信度高,优先采用其结果
final_sentiment = ml_sentiment
elif abs(dict_score) > strong_opinion_threshold:
# 如果词典方法发现强烈情感倾向,优先采用其结果
final_sentiment = dict_sentiment
else:
# 否则加权融合两种结果
# 这里可以实现更复杂的融合逻辑
if dict_sentiment == ml_sentiment:
final_sentiment = dict_sentiment
else:
# 冲突时的处理策略
if ml_confidence > dict_confidence_equivalent:
final_sentiment = ml_sentiment
else:
final_sentiment = dict_sentiment
return final_sentiment, max(ml_confidence, abs(dict_score)/max_dict_score)
情感分析对推荐系统的影响
情感分析结果在推荐系统中发挥着重要作用,主要体现在以下几个方面:
1. 推荐权重调整
系统会根据景点评论的情感分布情况调整该景点在推荐算法中的权重。评论情感越正面的景点会获得更高的推荐权重,从而更容易被推荐给用户。
算法示例:
def adjust_recommendation_weight(travel, sentiment_stats):
# 计算情感分数(-1到1之间)
total_comments = sum(sentiment_stats.values())
if total_comments == 0:
return default_weight
sentiment_score = (sentiment_stats["positive"] - sentiment_stats["negative"]) / total_comments
# 基础权重(可以是评分或其他因素)
base_weight = float(travel.score) if travel.score.replace('.', '', 1).isdigit() else 3.0
# 调整后的权重
adjusted_weight = base_weight * (1 + sentiment_score * sentiment_weight_factor)
return adjusted_weight
2. 个性化推荐优化
系统会分析用户历史浏览和评价过的景点的评论情感分布,了解用户偏好的评价类型,进一步优化个性化推荐效果。
算法示例:
def optimize_personalized_recommendation(user_id, candidate_travels):
# 获取用户历史浏览的景点
user_browsed_travels = UserBrowseHistory.objects.filter(user_id=user_id)
# 分析用户偏好的评论情感分布
user_sentiment_preference = analyze_user_sentiment_preference(user_browsed_travels)
# 为候选景点评分
scored_candidates = []
for travel in candidate_travels:
# 获取景点的评论情感分布
travel_sentiment_stats = get_travel_sentiment_stats(travel)
# 计算用户偏好与景点评论情感分布的匹配度
sentiment_match_score = calculate_sentiment_match(
user_sentiment_preference,
travel_sentiment_stats
)
# 结合基础分数和情感匹配分数
final_score = calculate_final_score(
base_score=float(travel.score),
sentiment_score=sentiment_match_score
)
scored_candidates.append((travel, final_score))
# 排序并返回结果
sorted_candidates = sorted(scored_candidates, key=lambda x: x[1], reverse=True)
return [travel for travel, _ in sorted_candidates]
3. 情感趋势分析
系统会分析景点评论的情感变化趋势,识别用户情感的波动,从而预测景点质量的变化,及时调整推荐策略。
算法示例:
def analyze_sentiment_trends(travel_id, time_window=30):
# 获取景点的所有评论
travel = TravelInfo.objects.get(id=travel_id)
comments = json.loads(travel.comments) if travel.comments else []
# 按时间排序评论
sorted_comments = sorted(comments, key=lambda x: x.get('date', ''))
# 按时间窗口分组并分析情感趋势
time_windows = []
sentiment_scores = []
current_window = []
current_window_end = None
for comment in sorted_comments:
comment_date = parse_date(comment.get('date', ''))
if not comment_date:
continue
if current_window_end is None:
# 初始化第一个时间窗口
current_window_end = comment_date + datetime.timedelta(days=time_window)
current_window.append(comment)
elif comment_date <= current_window_end:
# 评论属于当前时间窗口
current_window.append(comment)
else:
# 处理当前窗口并创建新窗口
if current_window:
window_sentiment = calculate_window_sentiment(current_window)
time_windows.append(current_window_end - datetime.timedelta(days=time_window))
sentiment_scores.append(window_sentiment)
# 创建新窗口
current_window = [comment]
current_window_end = comment_date + datetime.timedelta(days=time_window)
# 处理最后一个窗口
if current_window:
window_sentiment = calculate_window_sentiment(current_window)
time_windows.append(current_window_end - datetime.timedelta(days=time_window))
sentiment_scores.append(window_sentiment)
# 分析趋势
trend = analyze_trend(sentiment_scores)
return {
'time_windows': [tw.strftime('%Y-%m-%d') for tw in time_windows],
'sentiment_scores': sentiment_scores,
'trend': trend
}
通过以上三种方式,情感分析算法不仅能够帮助系统更准确地了解用户对景点的真实评价,还能动态调整推荐策略,提高推荐系统的性能和用户满意度。