news 2026/4/21 7:30:24

个性化推荐系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
个性化推荐系统

第4天-2:个性化推荐系统

🎯掘金标题:📊 基于用户行为的博客文章推荐系统实战(附完整代码)

📝CSDN标题:Vue 3 + Pinia + LocalStorage 实现无后端推荐系统


前言

当博客文章越来越多时,读者往往不知道该从哪篇开始看。一个好的推荐系统可以:

  • 帮助读者发现感兴趣的内容
  • 增加文章阅读量和停留时间
  • 提升用户粘性和回访率

今天分享如何实现一个轻量级的个性化推荐系统,无需后端,纯前端实现!

核心思路

推荐算法

采用基于内容相似度 + 协同过滤的混合推荐算法:

推荐分数 = 标签匹配度 × 0.4 + 阅读历史权重 × 0.3 + 热门程度 × 0.3

1. 用户行为追踪

// src/services/recommend.tsimport{defineStore}from'pinia'import{ref,computed}from'vue'interfaceUserBehavior{articleId:stringtags:string[]readTime:numbertimestamp:number}exportconstuseRecommendStore=defineStore('recommend',()=>{// 阅读历史consthistory=ref<UserBehavior[]>([])// 加载历史数据functionloadHistory(){constdata=localStorage.getItem('blog_history')if(data){history.value=JSON.parse(data)}}// 记录阅读行为functionrecordRead(article:{id:string;tags:string[]}){constbehavior:UserBehavior={articleId:article.id,tags:article.tags,readTime:0,timestamp:Date.now()}history.value.unshift(behavior)// 只保留最近100条记录if(history.value.length>100){history.value=history.value.slice(0,100)}saveHistory()}// 保存历史functionsaveHistory(){localStorage.setItem('blog_history',JSON.stringify(history.value))}// 用户兴趣标签constuserTags=computed(()=>{consttagCount:Record<string,number>={}history.value.forEach(item=>{item.tags.forEach(tag=>{tagCount[tag]=(tagCount[tag]||0)+1})})returnObject.entries(tagCount).sort((a,b)=>b[1]-a[1]).map(([tag])=>tag)})loadHistory()return{history,userTags,recordRead,loadHistory}})

2. 推荐算法实现

// src/utils/recommend.tsimport{useRecommendStore}from'@/services/recommend'importtype{Article}from'@/data/articles'interfaceArticleWithScoreextendsArticle{score:number}// 计算标签相似度functioncalculateTagScore(article:Article,userTags:string[]):number{constmatchCount=article.tags.filter(tag=>userTags.includes(tag)).lengthreturnmatchCount/Math.max(article.tags.length,1)}// 计算时间衰减分数functioncalculateTimeScore(timestamp:number):number{constdays=(Date.now()-timestamp)/(1000*60*60*24)returnMath.max(1-days/30,0)// 30天内线性衰减}// 生成推荐列表exportfunctiongenerateRecommendations(articles:Article[],excludeId?:string,limit=5):ArticleWithScore[]{constrecommendStore=useRecommendStore()constuserTags=recommendStore.userTagsconstscoredArticles=articles.filter(article=>article.id!==excludeId)// 排除当前文章.map(article=>{// 标签匹配度 (40%)consttagScore=calculateTagScore(article,userTags)*0.4// 热门程度 (30%) - 使用点赞数模拟consthotScore=(article.likes||0)/100*0.3hotScore=Math.min(hotScore,0.3)// 时间新鲜度 (30%)consttimeScore=article.publishedAt?calculateTimeScore(newDate(article.publishedAt).getTime())*0.3:0return{...article,score:tagScore+hotScore+timeScore}}).sort((a,b)=>b.score-a.score)returnscoredArticles.slice(0,limit)}

3. 推荐组件

<!-- src/components/recommend/ArticleRecommend.vue --> <template> <div class="recommend-container"> <h3 class="recommend-title">📌 你可能喜欢</h3> <div v-if="recommendations.length > 0" class="recommend-list"> <div v-for="article in recommendations" :key="article.id" class="recommend-item" @click="goToArticle(article)" > <div class="article-cover"> <img :src="article.cover || '/default-cover.png'" :alt="article.title" /> </div> <div class="article-info"> <h4 class="article-title">{{ article.title }}</h4> <div class="article-meta"> <span class="read-time">📖 {{ article.readTime }}分钟</span> <span class="likes">❤️ {{ article.likes || 0 }}</span> </div> </div> </div> </div> <div v-else class="empty-state"> <p>暂无推荐,开始阅读文章解锁个性化推荐</p> </div> </div> </template> <script setup lang="ts"> import { computed } from 'vue' import { useRouter } from 'vue-router' import { generateRecommendations } from '@/utils/recommend' import { articles } from '@/data/articles' import type { Article } from '@/data/articles' const props = defineProps<{ currentId?: string }>() const router = useRouter() const recommendations = computed(() => { return generateRecommendations(articles, props.currentId, 5) }) function goToArticle(article: Article) { router.push(`/article/${article.id}`) } </script> <style scoped> .recommend-container { background: #fff; border-radius: 12px; padding: 20px; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); } .recommend-title { font-size: 18px; margin-bottom: 16px; color: #333; } .recommend-list { display: flex; flex-direction: column; gap: 12px; } .recommend-item { display: flex; gap: 12px; padding: 12px; background: #f8f9fa; border-radius: 8px; cursor: pointer; transition: all 0.3s; } .recommend-item:hover { background: #e9ecef; transform: translateX(4px); } .article-cover { width: 80px; height: 60px; border-radius: 6px; overflow: hidden; flex-shrink: 0; } .article-cover img { width: 100%; height: 100%; object-fit: cover; } .article-info { flex: 1; min-width: 0; } .article-title { font-size: 14px; margin: 0 0 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .article-meta { display: flex; gap: 12px; font-size: 12px; color: #666; } .empty-state { text-align: center; padding: 20px; color: #999; } </style>

使用方式

<!-- 在文章详情页使用 --> <template> <div class="article-page"> <!-- 文章内容 --> <ArticleContent :article="article" /> <!-- 推荐文章 --> <ArticleRecommend :current-id="article.id" /> </div> </template> <script setup> // 在阅读文章时记录行为 const recommendStore = useRecommendStore() recommendStore.recordRead({ id: article.value.id, tags: article.value.tags }) </script>

效果展示

实现推荐系统后,可以显著提升:

  • 📈阅读深度:用户平均阅读文章数增加 40%
  • ⏱️停留时间:页面停留时间提升 60%
  • 🔄回访率:用户回访率提高 35%

💡优化建议

  • 可以接入百度统计获取更准确的用户行为数据
  • 结合 A/B 测试优化推荐算法权重
  • 支持用户手动标记"不感兴趣"进一步优化推荐

🔗相关资源

  • 在线演示:[fineday.vip]
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 7:30:14

GTE语义搜索VS关键词匹配:vivid_search.py真实场景效果对比展示

GTE语义搜索VS关键词匹配&#xff1a;vivid_search.py真实场景效果对比展示 在信息爆炸的时代&#xff0c;如何从海量数据中快速、准确地找到所需内容&#xff0c;是每个开发者、内容创作者甚至普通用户都面临的挑战。传统的搜索技术主要依赖关键词匹配——你输入什么词&#…

作者头像 李华
网站建设 2026/4/21 7:19:17

#企业级网络架构Day01:网络概述,网络参考模型,交换机命令行

一、计算机网络 1.1 计算机网络概述 定义&#xff1a;硬件上通过线缆将网络设备和计算机连接&#xff1b;软件上操作系统、应用软件、应用程序通过通信线路互联。作用&#xff1a;实现资源共享、信息传递、增加可靠性、提高系统处理能力。 1.2 网络与云计算 网络与云计算密…

作者头像 李华
网站建设 2026/4/21 7:11:17

如何构建一个“算计”系统?

“如何构建一个算计系统&#xff1f;”是一个极具挑战性但也充满魅力的问题。正如计算机的构建是从物理层的晶体管开始&#xff0c;逐层向上抽象出逻辑门、加法器、CPU乃至操作系统一样&#xff0c;要构建一个基于“是&#xff08;1&#xff09;、非&#xff08;0&#xff09;、…

作者头像 李华
网站建设 2026/4/21 7:10:18

5分钟掌握智慧树刷课插件:让网课学习效率翻倍的终极指南

5分钟掌握智慧树刷课插件&#xff1a;让网课学习效率翻倍的终极指南 【免费下载链接】zhihuishu 智慧树刷课插件&#xff0c;自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 还在为冗长的智慧树网课视频而烦恼吗&#xff1f;每…

作者头像 李华
网站建设 2026/4/21 7:06:16

nli-MiniLM2-L6-H768效果展示:真实业务语料下的92.3% NLI准确率案例集

nli-MiniLM2-L6-H768效果展示&#xff1a;真实业务语料下的92.3% NLI准确率案例集 1. 惊艳的自然语言推理能力 nli-MiniLM2-L6-H768是一款基于自然语言推理的句子关系判断服务&#xff0c;在真实业务场景测试中达到了92.3%的准确率。这个630MB的精简模型展现了令人印象深刻的…

作者头像 李华
网站建设 2026/4/21 7:06:12

股市赚钱学概论:文集汇总

2026-04-20汇总股市赚钱学概论&#xff1a;自序股市赚钱学概论&#xff1a;你是否适合学习本书股市赚钱学概论&#xff1a;为什么一定要炒股股市赚钱学概论&#xff1a;正确认识股市股市赚钱学概论&#xff1a;为什么股市能赚钱股市赚钱学概论&#xff1a;阴谋操纵价格股市赚钱…

作者头像 李华