旅游推荐数据分析可视化系统算法
旅游推荐数据分析可视化系统算法
本文档详细介绍了旅游推荐数据分析可视化系统中使用的各种算法,包括推荐算法、数据分析算法和可视化算法。
目录
- 推荐算法
- 基于用户的协同过滤推荐
- 基于浏览历史的推荐
- 主题推荐算法
- 亲子游推荐算法
- 文化游推荐算法
- 自然风光推荐算法
- 随机推荐算法
- 数据分析与可视化算法
- 词云生成算法
- 地理分布可视化
- 用户活跃度分析
- 评分与销量分析
- 价格分布分析
推荐算法
基于用户的协同过滤推荐
协同过滤是一种常用的推荐算法,通过分析用户之间的相似性,为目标用户推荐与其相似的用户喜欢的项目。本系统实现了基于用户的协同过滤算法。
算法步骤:
- 获取所有用户的评分数据,数据结构为
{用户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, TravelInfotry:# 获取用户浏览过的景点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] = 0province_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 = 0valid_scores = 0for travel in browsed_travels_info:try:score = float(travel.score)avg_score += scorevalid_scores += 1except ValueError:continueif valid_scores > 0:avg_score = avg_score / valid_scoreselse: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:# 获取所有景点IDall_travel_ids = set(TravelInfo.objects.values_list('id', flat=True))# 排除已浏览和已推荐的IDexcluded_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 = 0for travel in sortedTravelList:if travel not in familyFriendlyList:familyFriendlyList.append(travel)added += 1if 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 = 0for travel in sortedTravelList:if travel not in culturalList:culturalList.append(travel)added += 1if 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 = 0for travel in sortedTravelList:if travel not in natureList:natureList.append(travel)added += 1if 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.detailIntrocut = 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] = 0provinceDic[travel.province] += 1geoData = []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] = 0timeDic[createTime] += 1resultList = []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"] += 1elif price <= 200:priceRanges["101-200"] += 1elif price <= 300:priceRanges["201-300"] += 1elif price <= 400:priceRanges["301-400"] += 1elif price <= 500:priceRanges["401-500"] += 1else:priceRanges["501以上"] += 1except 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 = 0negative_modifier = Falsedegree_modifier = 1.0for i, word in enumerate(words):# 检查是否是情感词if word in sentiment_dict:word_score = sentiment_dict[word]# 考虑否定词的影响if negative_modifier:word_score = -word_scorenegative_modifier = False# 考虑程度副词的影响word_score = word_score * degree_modifierdegree_modifier = 1.0sentiment_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_scoreelif sentiment_score < threshold_negative:return "negative", sentiment_scoreelse: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 modeldef 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, historydef 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_sentimentelif abs(dict_score) > strong_opinion_threshold:# 如果词典方法发现强烈情感倾向,优先采用其结果final_sentiment = dict_sentimentelse:# 否则加权融合两种结果# 这里可以实现更复杂的融合逻辑if dict_sentiment == ml_sentiment:final_sentiment = dict_sentimentelse:# 冲突时的处理策略if ml_confidence > dict_confidence_equivalent:final_sentiment = ml_sentimentelse:final_sentiment = dict_sentimentreturn 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_weightsentiment_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 = Nonefor comment in sorted_comments:comment_date = parse_date(comment.get('date', ''))if not comment_date:continueif 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}
通过以上三种方式,情感分析算法不仅能够帮助系统更准确地了解用户对景点的真实评价,还能动态调整推荐策略,提高推荐系统的性能和用户满意度。
相关文章:
旅游推荐数据分析可视化系统算法
旅游推荐数据分析可视化系统算法 本文档详细介绍了旅游推荐数据分析可视化系统中使用的各种算法,包括推荐算法、数据分析算法和可视化算法。 目录 推荐算法 基于用户的协同过滤推荐基于浏览历史的推荐主题推荐算法 亲子游推荐算法文化游推荐算法自然风光推荐算法…...
Pandas:数据处理与分析
目录 一、Pandas 简介 二、Pandas 的安装与导入 三、Pandas 的核心数据结构 (一)Series (二)DataFrame 四、Pandas 数据读取与写入 (一)读取数据 (二)写入数据 五、数据清洗…...
非阻塞式IO-Java NIO
一、NIO简介 Java NIO是Java1.4引入的一种新的IO API,它提供了非阻塞式IO,选择器、通道、缓冲区等新的概念和机制。相比传统的IO,多出的N不单纯是新的,更表现在Non-blocking非阻塞,NIO具有更高的并发性、可扩展性以及…...
tryhackme——Enumerating Active Directory
文章目录 一、凭据注入1.1 RUNAS1.2 SYSVOL1.3 IP和主机名 二、通过Microsoft Management Console枚举AD三、通过命令行net命令枚举四、通过powershell枚举 一、凭据注入 1.1 RUNAS 当获得AD凭证<用户名>:<密码>但无法登录域内机器时,runas.exe可帮助…...
(二)Linux下基本指令 2
【知识预告】 16. date 指令 17. cal 指令 18. find 指令 19. which指令 20. whereis 指令 21. alias 指令 22. grep 指令 23. zip/unzip 指令 24. tar 指令 25. bc 指令 26. uname ‒r 指令 27. 重要的⼏个热键 28. 关机 16 date 指令 指定格式显⽰时间:date %Y-…...
[ctfshow web入门] web70
信息收集 使用cinclude("php://filter/convert.base64-encode/resourceindex.php");读取的index.php error_reporting和ini_set被禁用了,不必管他 error_reporting(0); ini_set(display_errors, 0); // 你们在炫技吗? if(isset($_POST[c])){…...
第三章 Freertos智能小车遥控控制
本文基于小车APP,通过与蓝牙模块进行连接,发送特定信号给小车主控,实现对小车的模式切换、灯光控制、前进、后退、左右控制。目前还未加入电机控制,具体的电机控制效果还不能实现,但是可以进行模式切换与灯光控制。 …...
Spring 6.x 详解介绍
Spring 6.x 是 Spring Framework 的最新主版本,于2022年11月正式发布,标志着对 Java 17 和 Jakarta EE 9 的全面支持,同时引入了多项革新性特性,旨在优化性能、简化开发并拥抱现代技术趋势。 一、核心特性与架构调整 Java 17 与 J…...
阿里云OSS+CDN自动添加文章图片水印配置指南
文章目录 一、环境准备二、OSS水印样式配置三、CDN关键配置四、Handsome主题自动化配置五、水印效果验证六、常见问题排查 一、环境准备 资源清单 阿里云OSS Bucket(绑定自定义域名 static.example.com)阿里云CDN加速域名,回源为Bucket的域名…...
hot100-子串-JS
一、560.和为k的子串 560. 和为 K 的子数组 提示 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1: 输入:nums [1,1,1], k 2 输出:2示例 2…...
LeetCode 270:在二叉搜索树中寻找最接近的值(Swift 实战解析)
文章目录 摘要描述题解答案题解代码分析示例测试及结果时间复杂度空间复杂度总结 摘要 在日常开发中,我们经常需要在一组有序的数据中快速找到最接近某个目标值的元素。LeetCode 第 270 题“Closest Binary Search Tree Value”正是这样一个问题。本文将深入解析该…...
《操作系统真象还原》第十三章——编写硬盘驱动程序
文章目录 前言硬盘及分区表创建从盘及获取安装的磁盘数创建磁盘分区表硬盘分区表浅析 编写硬盘驱动程序硬盘初始化修改interrupt.c编写ide.h编写ide.c 实现thread_yield和idle线程修改thread.c 实现简单的休眠函数修改timer.c 完善硬盘驱动程序继续编写ide.c 获取硬盘信息&…...
DNS服务实验
该文章将介绍DNS服务的正向和反向解析实验、主从实验、转发服务器实验以及Web解析实验 正向解析实验:将域名解析为对应的IP地址 反向解析实验:将IP地址解析为对应的域名 主从实验:主服务器区域数据文件发送给从服务器,从服务器…...
SierraNet M1288网络损伤功能显著助力GPU互联网络的测试验证,包含包喷洒,LLR等复杂特性的验证测试
SierraNet M1288 以太网协议分析仪 产品概述 SierraNet M1288 是一款兼具高性价比与全面功能的以太网和光纤通道数据捕获及协议验证系统。它能够以全线路速率 100% 记录所有流量,并借助 InFusion™ 工具实现高级错误注入和流量破坏功能,为开发人员和协议…...
HunyuanCustom:文生视频框架论文速读
《HunyuanCustom: A Multimodal-Driven Architecture for Customized Video Generation》论文讲解 一、引言 本文提出了 HunyuanCustom,这是一个基于多模态驱动的定制化视频生成框架。该框架旨在解决现有视频生成模型在身份一致性(identity consistenc…...
HTTP、HTTPS、SSH区别以及如何使用ssh-keygen生成密钥对
HTTP、HTTPS、SSH区别以及如何使用ssh-keygen生成密钥对 HTTP (HyperText Transfer Protocol) 定义:应用层协议,用于通过Web传输数据(如网页、文件)默认端口:80机制:客户端发送Get请求,服务器…...
如何启动vue项目及vue语法组件化不同标签应对的作用说明
如何启动vue项目及vue语法组件化不同标签应对的作用说明 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是node.js和vue的使用。前后每一小节的内容是存在的有:学习and理解的关联性。【帮帮志系列文章】&…...
Ubuntu22.04安装显卡驱动/卸载显卡驱动
报错 今日输入nvidia-smi报错,在安装了535和550,包括560都没办法解决,但是又怕乱搞导致环境损坏,打算把显卡卸载然后重新安装系统默认推荐版本的显卡驱动 qinqin:~$ nvidia-smi Failed to initialize NVML: Driver/library version mismatch NVML library version: 560.35卸载…...
【桌面】【输入法】常见问题汇总
目录 一、麒麟桌面系统输入法概述 1、输入法介绍 2、输入法相关组件与服务 3、输入法调试相关命令 3.1、输入法诊断命令 3.2、输入法配置重新加载命令 3.3、启动fcitx输入法 3.4、查看输入法有哪些版本,并安装指定版本 3.5、重启输入法 3.6、查看fcitx进程…...
Web3 初学者学习路线图
目录 🌟 Web3 初学者学习路线图 🧩 第一步:搞懂 Web3 是什么 ✅ 学什么? 🔧 推荐工具: 🎥 推荐学习: 🛠️ 第二步:了解智能合约和 Solidity(核心技能) ✅ 学什么? 🔧 工具: 📘 推荐课程: 🌐 第三步:连接前端和区块链,创建简单 DApp ✅ 学…...
python打卡day21
常见的降维算法 知识点回顾: LDA线性判别PCA主成分分析t-sne降维 之前学了特征降维的两个思路,特征筛选(如树模型重要性、方差筛选)和特征组合(如SVD/PCA)。 现在引入特征降维的另一种分类:无/有…...
KNOWLEDGE-BASED SYSTEMS(KBS期刊)投稿经验分享
期刊介绍: KBS是计算机一区,CCF-c期刊,(只看大类分区,小类不用看,速度很快,桌拒比较多,能送审就机会很大!) 具体时间流程: 7月初投稿…...
vue使用rules实现表单校验——校验用户名和密码
编写校验规则 常规校验 const rules {username: [{ required: true, message: 请输入用户名, trigger: blur },{ min: 5, max: 16, message: 长度在 5 到 16 个字符, trigger: blur }],password: [{ required: true, message: 请输入密码, trigger: blur },{ min: 5, max: 1…...
[CANN] 安装软件依赖
环境 昊算平台910b NPUdocker容器 安装步骤 安装依赖-安装CANN(物理机场景)-软件安装-开发文档-昇腾社区 apt安装miniconda安装 Apt 首先进行换源,参考昇腾NPU容器内 apt 换源 Miniconda 安装miniconda mkdir -p ~/miniconda3 wget …...
代码随想录算法训练营第三十七天
LeetCode题目: 300. 最长递增子序列674. 最长连续递增序列718. 最长重复子数组2918. 数组的最小相等和(每日一题) 其他: 今日总结 往期打卡 300. 最长递增子序列 跳转: 300. 最长递增子序列 学习: 代码随想录公开讲解 问题: 给你一个整数数组 nums ,找到其中最长…...
Qt开发经验 --- 避坑指南(11)
文章目录 [toc]1 QtCreator同时运行多个程序2 刚安装的Qt编译报错cannot find -lGL: No such file or directory3 ubuntu下Qt无法输入中文4 Qt版本发行说明5 Qt6.6 VS2022报cdb.exe无法定位dbghelp.dll输入点6 Qt Creator13.0对msvc-qmake-jom.exe支持有问题7 银河麒麟系统中ud…...
vue 组件函数式调用实战:以身份验证弹窗为例
通常我们在 Vue 中使用组件,是像这样在模板中写标签: <MyComponent :prop"value" event"handleEvent" />而函数式调用,则是让我们像调用一个普通 JavaScript 函数一样来使用这个组件,例如:…...
青藏高原东北部祁连山地区250m分辨率多年冻土空间分带指数图(2023)
时间分辨率:10年 < x < 100年空间分辨率:100m - 1km共享方式:开放获取数据大小:24.38 MB数据时间范围:近50年来元数据更新时间:2023-10-08 数据集摘要 多年冻土目前正在经历大规模的退化,…...
[6-2] 定时器定时中断定时器外部时钟 江协科技学习笔记(41个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 V 30 31 32 33 34 35 36 37 38 39 40 41...
抖音视频去水印怎么操作
在抖音上保存或分享视频时,水印通常会自动添加。如果想去除水印,可以尝试以下方法,但请注意尊重原创作者的版权,仅限个人合理使用。 方法 1:使用第三方去水印工具(手机/电脑均可) 复制视频链接 …...
Java并发编程
Java并发编程的核心挑战 线程安全与数据竞争 线程安全的概念及其重要性数据竞争的产生原因及常见场景如何通过同步机制(如锁、原子类)避免数据竞争 // 示例:使用synchronized关键字实现线程安全 public class Counter {private int count …...
【ospf综合实验】
拓扑图:...
NVMe控制器之仿真平台搭建
本设计采用Verilog HDL语言进行实现并编写测试激励,仿真工具使用Mentor公司的QuestaSim 10.6c软件完成对关键模块的仿真验证工作,由于是基于Xilinx公司的Kintex UltraScale系列FPGA器件实现的,因此使用Xilinx公司的Vivado2019.1设计套件工具进…...
深入探究 InnoDB 的写失效问题
在 MySQL 数据库的世界中,InnoDB 存储引擎凭借其卓越的性能和可靠性,成为众多应用的首选。然而,如同任何复杂的系统一样,InnoDB 也面临着一些挑战,其中写失效问题便是一个值得深入探讨的关键议题。本文将带您全面了解 …...
边缘计算从专家到小白
“云-边-端”架构 “云” :传统云计算的中心节点,是边缘计算的管控端。汇集所有边缘的感知数据、业务数据以及互联网数据,完成对行业以及跨行业的态势感知和分析。 “边” :云计算的边缘侧,分为基础设施边缘和设备边缘…...
智能商品推荐系统技术路线图
智能商品推荐系统技术路线图 系统架构图 --------------------------------------------------------------------------------------------------------------- | 用户交互层 (Presentation Layer) …...
SpringMVC面试内容
SpringMVC运行流程 SpringMVC的运行流程SpringBoot Vue交互流程HTTP 的 GET 和 POST 区别跨域请求是什么?有什么问题?怎么解决?浏览器访问资源没有响应,怎么排查Cookie的理解Session的理解 Cookie和Session的区别 SpringMVC的运行流程 1、域名解析…...
Python 核心概念速查清单
本文大纲 1. 变量与字符串 (Variables and Strings) 变量 (Variables): 用于存储值。字符串 (String): 由单引号或双引号包围的字符序列。 示例:打印 “Hello world!” print("Hello world!")使用变量打印: msg = "Hello world!" print(msg)字符串拼接…...
Unity.UGUI DrawCall合批笔记
前言 昨天在通过FrameDebug查看DrawCall时,发现批次结果与理解中的不一致,又去补充了一下这方面知识,笔记记录下,只关乎UGUI。 基础场景 首先列一下无法合批的一些基础场景 1.图片无图集或图集不同,图片是运行时生成的…...
高精度加减
1、高精度加法 主要有以下几步: 输入处理:使用字符串来存储大整数,避免数值范围限制。对齐数字:确保两个数字的数位对齐(前面补零)。逐位相加:从最低位开始,逐位相加并处理进位。最…...
day21python打卡
知识点回顾: LDA线性判别PCA主成分分析t-sne降维 还有一些其他的降维方式,也就是最重要的词向量的加工,我们未来再说 作业: 自由作业:探索下什么时候用到降维?降维的主要应用?或者让ai给你出题&…...
DataBinding与Kotlin优化视图绑定
在 Android 开发中,DataBinding 与 Kotlin 的结合可以显著提升代码的简洁性和可维护性,彻底摆脱传统 findViewById 的繁琐操作。以下是如何通过 DataBinding 优化视图绑定的完整指南: 一、为何要告别 findViewById? 模板代码冗余…...
CDGP主观题题库与范例解答
本文共8400字,涉及数据建模、数据安全、主数据、数据架构等主观题解答范例 数据建模题目 初次访问网购网站的访客,如试图在网站上购物,则需要申请会员。申请会员时需要填写会员姓名、性别、身份证号码、联系电话、会员ID、密码等信息。会员申请成功后,通过会员ID和密码便…...
2.商户查询缓存
2.0 问题记录 2.0.1 为什么要给缓存 TTL 1. 防止内存泄漏:如果不设置过期时间,缓存数据会永久存在于 Redis 中,随着时间推移可能导致 Redis 内存耗尽。2. 数据一致性:设置合理的过期时间可以确保缓存不会长期存储过时数据&#…...
vs python“““标记注释报错,vs使用自带环境安装 python第三方库
文章目录 vs python"""标记注释报错vs使用自带环境安装 python第三方库 vs python"""标记注释报错 解决方法: 切换编码 文件-高级保存选项-编码处选择下拉菜单中的“Unicode(UTF-8带签名)-代码页65001”-确定 这里更详细:…...
区块链技术中的Java SE实战:从企业级应用到5大核心问题解析
区块链技术中的Java SE实战:从企业级应用到5大核心问题解析 问题1:如何在Java SE中实现区块链的基本数据结构? 回答1: 区块链的核心数据结构是链式区块,每个区块包含数据、哈希值以及前一个区块的哈希值。以下是一个…...
数据结构—(概述)
目录 一 数据结构,相关概念 1. 数据结构: 2. 数据(Data): 3. 数据元素(Data Element): 4. 数据项: 5. 数据对象(Data Object): 6. 容器(container): 7. 结点(Node)ÿ…...
UE5 PCG学习笔记
https://www.bilibili.com/video/BV1onUdY2Ei3/?spm_id_from333.337.search-card.all.click&vd_source707ec8983cc32e6e065d5496a7f79ee6 一、安装PCG 插件里选择以下进行安装 移动目录后,可以使用 Update Redirector References,更新下࿰…...
Harness: 全流程 DevOps 解决方案,让持续集成如吃饭般简单
引言 在当今快速发展的软件开发世界中,高效的 DevOps 工具变得越来越重要。Harness 作为一个开源的运维平台,为开发和运维团队提供了从代码托管到 CI/CD 的全流程解决方案,同时实现自动化的开发环境和制品管理。这种集中化的工具可以显著减少运维难度,提高团队效率,真正解…...
Windows:Powershell的使用
文章目录 零、格式化输出命令1、Format-List(别名:fl) 一、服务管理SC命令二、软件管理命令三、权限管理命令1、Get-Acl2、Set-Acl 总结 零、格式化输出命令 1、Format-List(别名:fl) 可通过管道符传递对象…...