基于nlp_gte_sentence-embedding_chinese-large的智能新闻推荐系统

📅 发布时间:2026/7/9 20:30:01 👁️ 浏览次数:
基于nlp_gte_sentence-embedding_chinese-large的智能新闻推荐系统
基于nlp_gte_sentence-embedding_chinese-large的智能新闻推荐系统每天打开新闻App是不是感觉推荐给你的内容越来越“懂你”了你可能刚搜过“新能源汽车”首页就出现了相关评测你昨晚看了几篇科技新闻今天推送里就多了不少AI动态。这背后就是推荐系统在默默工作。传统的推荐系统比如基于“你看了A别人也看了A和B所以给你推荐B”的协同过滤或者基于“文章里有‘科技’标签你爱看科技所以推荐给你”的内容过滤已经有些力不从心了。它们很难理解“新能源汽车”和“自动驾驶”之间的深层语义关联也搞不清一篇关于“大模型技术突破”的文章到底是偏技术原理还是商业应用。今天我们就来聊聊如何用一个新的“武器”——nlp_gte_sentence-embedding_chinese-large模型来构建一个更智能、更懂你的新闻推荐系统。这个模型就像一个超级翻译官能把任何一段中文文本无论是新闻标题还是长篇报道都转换成一个高维度的“向量”你可以理解为一串有意义的数字。神奇的是语义相近的文本它们的向量在数学空间里也会靠得很近。这就为我们做精准的“语义匹配”推荐打下了基础。1. 为什么是GTE模型它强在哪在开始动手之前我们得先搞清楚手里的工具。nlp_gte_sentence-embedding_chinese-large后面我们简称GTE-large是阿里云达摩院开源的一个中文文本表示模型。简单说它的核心任务就是把文字变成数字向量并且让相似含义的文字变成的数字也相似。它有几个特点特别适合做新闻推荐首先它“理解”能力很强。传统的词袋模型可能只认识“苹果”这个词但分不清指的是水果还是公司。GTE-large这类基于Transformer的预训练模型能根据上下文准确理解语义。比如“苹果发布新款手机”和“今天吃了一个红苹果”它生成的向量会截然不同。其次它是为句子和段落级任务优化的。新闻的标题和摘要通常就是一个或几个句子GTE-large正好擅长处理这个长度的文本捕捉整体语义而不是纠结于单个词。最后它的“大型”large版本拥有更多的参数和更强的表示能力。在中文通用领域的文本相似度、检索等任务上它的表现通常比“base”或“small”版本更出色能捕捉更细微的语义差别。对于新闻推荐这种对准确性要求较高的场景用“大杯”往往更稳妥。你可以把它想象成一个经验老道的编辑不仅能快速读完一篇文章还能精准地提炼出它的核心思想和情感倾向然后打上一个独一无二、内涵丰富的“语义指纹”。我们接下来的所有工作都将围绕这个“语义指纹”展开。2. 系统核心设计从“标签”到“语义”的升级一个智能新闻推荐系统核心无外乎三件事理解内容、理解用户、进行匹配。基于GTE-large我们可以对这三个环节进行一次全面的升级。2.1 内容理解给每篇新闻装上“语义芯片”过去我们理解一篇文章可能靠的是编辑打上的几个关键词标签比如“科技、人工智能”。这种方式粗糙、费力且无法穷尽所有角度。现在我们可以让GTE-large来干这件事。对于入库的每一篇新闻我们提取它的标题和核心摘要如果没有摘要可以截取文章开头部分然后送入GTE-large模型。from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks # 初始化GTE-large嵌入模型管道 # 首次运行会自动从ModelScope下载模型需要一点时间 embedding_pipeline pipeline(Tasks.sentence_embedding, modeldamo/nlp_gte_sentence-embedding_chinese-large) def get_article_embedding(title, summary): 获取新闻文章的语义向量 Args: title: 新闻标题 summary: 新闻摘要 Returns: numpy.ndarray: 文章的768维语义向量 # 将标题和摘要组合成一个文本作为文章的整体语义表示 # 你也可以选择分别处理然后融合这里用简单拼接 combined_text f{title}。{summary} # 模型输入需要是列表形式 inputs {source_sentence: [combined_text]} # 进行推理得到向量 result embedding_pipeline(inputinputs) # 返回第一个也是唯一一个句子的向量 article_vector result[text_embedding][0] return article_vector # 示例处理一篇科技新闻 news_title 深度解析大模型技术如何重塑内容创作行业 news_summary 本文探讨了大型语言模型在文案生成、视频脚本创作、个性化营销等领域的应用现状与未来挑战。 article_vector get_article_embedding(news_title, news_summary) print(f文章向量维度{article_vector.shape}) # 输出(768,) print(f向量样例前5维{article_vector[:5]})这段代码运行后一篇冗长的新闻就被压缩成了一个768维的向量。这个向量就是文章的“语义芯片”它包含了文章主题、情感、风格等丰富信息。我们将这个向量和文章的元数据ID、发布时间等一起存入向量数据库比如Milvus、Qdrant或DashVector中。这就完成了新闻素材库的“向量化”改造。2.2 用户画像动态的“兴趣图谱”而非静态标签传统的用户画像是“你喜欢科技、体育、财经”是几个孤立的标签。而基于语义向量的用户画像是一个动态的、多维的“兴趣点云”。具体怎么做呢我们记录用户的所有交互行为点击、阅读时长、点赞、收藏。每一个行为对应的新闻我们都有其语义向量。用户的兴趣画像就是他近期交互过的所有新闻向量的一个“聚合”。一种简单有效的方法是计算加权平均向量。给最近的行为更高的权重给阅读时间长的文章更高的权重。import numpy as np from collections import deque import time class SemanticUserProfile: def __init__(self, user_id, recent_items_max50): self.user_id user_id # 使用一个双端队列来保存近期的交互记录文章向量 权重 时间戳 self.recent_interactions deque(maxlenrecent_items_max) def add_interaction(self, article_vector, weight1.0): 添加一次用户交互 Args: article_vector: 文章的语义向量 weight: 交互权重例如点击1.0阅读超过1分钟1.5收藏2.0 timestamp time.time() self.recent_interactions.append({ vector: article_vector, weight: weight, time: timestamp }) def get_current_profile_vector(self, time_decay_factor0.1): 计算用户当前的语义兴趣向量 采用时间衰减的加权平均 Args: time_decay_factor: 时间衰减系数越大则近期行为越重要 Returns: numpy.ndarray: 用户当前兴趣向量 if not self.recent_interactions: return None current_time time.time() total_weight 0.0 weighted_vector_sum np.zeros_like(self.recent_interactions[0][vector]) for interaction in self.recent_interactions: vector interaction[vector] base_weight interaction[weight] # 计算时间衰减越近的行为权重越高 time_diff_hours (current_time - interaction[time]) / 3600 time_decay np.exp(-time_decay_factor * time_diff_hours) final_weight base_weight * time_decay weighted_vector_sum vector * final_weight total_weight final_weight # 返回加权平均向量即用户的“兴趣中心点” if total_weight 0: user_vector weighted_vector_sum / total_weight # 归一化方便后续计算余弦相似度 user_vector user_vector / np.linalg.norm(user_vector) return user_vector else: return None # 示例模拟用户行为更新画像 user_profile SemanticUserProfile(user_iduser_123) # 假设用户阅读了三篇文章我们已有它们的向量 news_vectors [ np.random.randn(768), # 文章1向量科技类 np.random.randn(768), # 文章2向量体育类 np.random.randn(768), # 文章3向量科技类 ] # 用户点击了文章1和3并收藏了文章3 user_profile.add_interaction(news_vectors[0], weight1.0) # 点击 user_profile.add_interaction(news_vectors[2], weight1.0) # 点击 user_profile.add_interaction(news_vectors[2], weight2.0) # 收藏更高权重 # 获取用户当前的兴趣向量 current_interest user_profile.get_current_profile_vector() if current_interest is not None: print(f用户兴趣向量维度{current_interest.shape}) # 这个向量会偏向于科技类内容因为科技类文章尤其是被收藏的权重更高这样用户的画像不再是一组离散的标签而是一个在高维空间中的“点”。这个点会随着用户的最新行为而平滑移动真实反映其当前兴趣。2.3 推荐匹配在语义空间里“寻找邻居”当我们要给用户推荐新闻时事情就变得直观而高效了。我们不需要复杂的规则引擎只需要在向量数据库里做一次“最近邻搜索”。第一步获取用户当前的兴趣向量上文计算出的current_interest。第二步将这个向量作为查询输入向量数据库。第三步数据库会返回与这个查询向量余弦相似度最高的K篇文章。# 假设我们已经有一个向量数据库客户端这里用伪代码示意核心逻辑 def recommend_articles(user_interest_vector, vector_db_collection, top_k10, exclude_read_ids[]): 基于语义相似度进行新闻推荐 Args: user_interest_vector: 用户兴趣向量 vector_db_collection: 向量数据库集合已存储所有文章向量 top_k: 返回推荐数量 exclude_read_ids: 需要排除的已读文章ID列表 Returns: list: 推荐的文章ID和相似度分数 # 在向量数据库中搜索最相似的向量 # 这里以伪代码表示不同向量数据库如Milvus, Qdrant, DashVector的API略有不同 search_results vector_db_collection.search( query_vectoruser_interest_vector.tolist(), # 转换为列表 top_ktop_k len(exclude_read_ids), # 多查一些用于过滤已读 filter_conditionNone # 可以加入过滤条件如时间、类别等 ) # 过滤掉用户已经读过的文章 recommendations [] for article_id, similarity_score in search_results: if article_id not in exclude_read_ids: recommendations.append((article_id, similarity_score)) if len(recommendations) top_k: break return recommendations # 示例为用户进行推荐 # user_vector 来自上一步的 user_profile.get_current_profile_vector() # article_collection 是连接到的向量数据库集合 recommended_news recommend_articles(user_vector, article_collection, top_k5, exclude_read_ids[news_456]) for news_id, score in recommended_news: print(f推荐文章ID: {news_id}, 语义相似度: {score:.4f})这个过程就像在语义宇宙中以用户的兴趣点为圆心画一个圈把圈内最邻近、最相关的文章找出来推荐给他。匹配的精度直接从“关键词匹配”提升到了“语义理解”的层面。3. 让推荐更智能几个实战进阶技巧基础的语义匹配搭好了但一个优秀的推荐系统还需要解决一些常见问题如何推荐新颖的内容解决信息茧房如何考虑文章的时效性如何做冷启动3.1 多样性探索跳出“兴趣泡泡”如果只推荐最相似的用户可能会陷入“信息茧房”。我们需要主动推荐一些略有不同的内容探索用户的潜在兴趣。一个常见方法是“最大边界相关性MMR”重排序。它的思想是在保证与用户兴趣相关性的基础上尽可能让推荐结果之间的内容差异大一些。def diversify_recommendations(user_vector, candidate_articles, top_k10, lambda_param0.7): 使用MMR算法对候选推荐结果进行多样化重排序 Args: user_vector: 用户兴趣向量 candidate_articles: 列表元素为(article_id, article_vector, similarity_score) top_k: 最终返回数量 lambda_param: 权衡参数0-1越大越看重相关性越小越看重多样性 Returns: list: 重排序后的文章ID列表 selected [] remaining candidate_articles.copy() # 第一步先选择与用户最相关的一篇 first_article max(remaining, keylambda x: x[2]) # x[2]是相似度分数 selected.append(first_article[0]) # 加入ID remaining.remove(first_article) while len(selected) top_k and remaining: mmr_scores [] for article_id, article_vec, rel_score in remaining: # 计算该文章与已选文章的最大相似度衡量冗余度 max_sim_to_selected 0 for sel_id in selected: # 这里需要能根据sel_id找到已选文章的向量简化处理 # 假设我们有一个字典 article_vector_map sel_vec article_vector_map[sel_id] sim np.dot(article_vec, sel_vec) / (np.linalg.norm(article_vec) * np.linalg.norm(sel_vec)) max_sim_to_selected max(max_sim_to_selected, sim) # 计算MMR分数 mmr_score lambda_param * rel_score - (1 - lambda_param) * max_sim_to_selected mmr_scores.append((article_id, mmr_score, article_vec, rel_score)) # 选择MMR分数最高的文章 best_article max(mmr_scores, keylambda x: x[1]) selected.append(best_article[0]) # 从剩余列表中移除需要根据ID找到对应项 remaining [item for item in remaining if item[0] ! best_article[0]] return selected3.2 融合时效性给新鲜事加点“热度分”新闻具有很强的时效性。我们可以将语义相似度与文章的“新鲜度”结合起来。一个简单的办法是将时间衰减因子融入最终的推荐分数。def score_with_recency(semantic_score, publish_time, half_life_hours24): 结合语义分数和文章时效性计算最终推荐分数 Args: semantic_score: 语义相似度 (0-1) publish_time: 文章发布时间戳 half_life_hours: 半衰期24小时后热度减半 Returns: float: 最终得分 current_time time.time() age_hours (current_time - publish_time) / 3600 # 指数衰减越新分数加成越高 recency_factor np.exp(-np.log(2) * age_hours / half_life_hours) # 加权融合这里给语义相似度更高权重0.7时效性权重0.3 final_score 0.7 * semantic_score 0.3 * recency_factor return final_score3.3 解决冷启动当新用户或新文章到来时新用户冷启动当新用户没有任何行为时我们可以热门推荐推荐当前最热门的文章。多兴趣试探同时推荐几个主流大类科技、体育、财经、娱乐的热门文章根据其首次点击行为快速初始化兴趣向量。利用注册信息如果用户注册时选择了兴趣标签可以用这些标签的预定义向量来初始化用户画像。新文章冷启动一篇新文章发布还没有任何交互数据。我们的语义模型正好派上用场直接用GTE-large计算其语义向量。在推荐时除了考虑用户兴趣向量还可以考虑该文章与当前热点话题向量的相似度或者将其推荐给喜欢相关领域通过计算与领域基准向量的相似度的用户。4. 搭建一个简单的原型系统理论说了这么多我们来串一个简单的、可运行的流程看看。假设我们用内存字典模拟向量数据库。import numpy as np import time from typing import Dict, List, Tuple # 模拟一个简单的“向量数据库” class SimpleVectorDB: def __init__(self): self.data: Dict[str, Dict] {} # key: article_id, value: {vector: ..., meta: ...} def insert(self, article_id: str, vector: np.ndarray, meta: dict): self.data[article_id] {vector: vector, meta: meta} def search(self, query_vector: np.ndarray, top_k: int 5) - List[Tuple[str, float]]: 暴力搜索计算余弦相似度 results [] query_norm np.linalg.norm(query_vector) for aid, item in self.data.items(): vec item[vector] dot_product np.dot(query_vector, vec) norm np.linalg.norm(vec) if norm 0 and query_norm 0: similarity dot_product / (query_norm * norm) results.append((aid, similarity)) # 按相似度降序排序 results.sort(keylambda x: x[1], reverseTrue) return results[:top_k] # ---------- 1. 初始化 ---------- print(1. 初始化模型和数据库...) # 注意这里为了演示用随机向量代替实际模型调用。实际使用时替换为真实的embedding_pipeline。 def mock_get_embedding(text): 模拟GTE-large生成向量实际使用时替换 np.random.seed(hash(text) % 10000) vec np.random.randn(768) return vec / np.linalg.norm(vec) # 归一化 db SimpleVectorDB() user_profiles: Dict[str, SemanticUserProfile] {} # ---------- 2. 模拟新闻入库 ---------- print(\n2. 模拟新闻入库并向量化...) news_articles [ {id: news_001, title: 人工智能助力天气预报精度大幅提升, category: 科技}, {id: news_002, title: 欧冠半决赛上演惊天逆转, category: 体育}, {id: news_003, title: 央行发布最新货币政策报告, category: 财经}, {id: news_004, title: 深度学习框架迎来重大更新, category: 科技}, {id: news_005, title: 新能源汽车销量季度环比增长50%, category: 财经}, ] for article in news_articles: vector mock_get_embedding(article[title]) db.insert(article[id], vector, article) print(f 已入库: {article[title]}) # ---------- 3. 模拟用户行为并推荐 ---------- print(\n3. 模拟用户阅读行为并生成推荐...) user_id test_user if user_id not in user_profiles: user_profiles[user_id] SemanticUserProfile(user_id) # 用户阅读了第一篇科技新闻 read_article_id news_001 read_vector db.data[read_article_id][vector] user_profiles[user_id].add_interaction(read_vector, weight1.5) # 假设阅读时长较长 print(f 用户阅读了: {db.data[read_article_id][meta][title]}) # 获取用户当前兴趣向量 user_vector user_profiles[user_id].get_current_profile_vector() if user_vector is not None: print(f 用户兴趣向量已更新。) # 进行推荐排除已读 recommendations db.search(user_vector, top_k3) recommendations [r for r in recommendations if r[0] ! read_article_id][:2] # 取前2个未读的 print(f\n 为您推荐) for aid, score in recommendations: article_meta db.data[aid][meta] print(f - {article_meta[title]} [{article_meta[category]}] (相似度: {score:.3f}))运行这段代码你会看到一个极简的推荐流程新闻被向量化存储用户行为被记录并形成兴趣向量系统基于该向量寻找最相似的新闻进行推荐。虽然用了随机向量模拟但完整展示了从内容理解、用户画像到语义匹配的闭环。5. 总结回过头看基于nlp_gte_sentence-embedding_chinese-large这类强大的语义表示模型来构建推荐系统核心优势在于它实现了从“表面匹配”到“深度理解”的跨越。我们不再需要依赖人工标注的海量标签也不用担心“苹果”一词的多义性。系统通过向量这个桥梁在语义的层面上将内容和用户连接了起来。实际部署时你还需要考虑更多工程细节如何搭建高效的向量数据库集群来应对海量新闻和实时查询如何设计更复杂的用户兴趣模型如多兴趣向量如何在线更新用户画像以保证低延迟以及如何设计A/B测试框架来持续优化推荐策略。但无论如何语义理解都是现代推荐系统不可或缺的基石。用上GTE-large这样的工具就像是给推荐引擎装上了“理解中文的智能大脑”。它也许不能解决所有问题但无疑能让你的推荐系统在智能化道路上迈出坚实的一大步。如果你正在为你的新闻应用寻找提升推荐效果的方案不妨从搭建一个这样的语义原型系统开始试试。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。