本文摘自PHP中文网,作者不言,侵删。
本篇文章给大家带来的内容是关于基于Tags实现内容推荐的方法(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。原来为了简单方便,自己小网站上的文章页的相关内容推荐就是从数据库里随机抽取数据来填充一个列表,所以一点相关性都没有,更本没有办法引导用户去访问推荐内容。
算法选择
如何能做到相似内容的推荐呢,碍于小网站还跑在虚拟主机上(对的,连一个自己完整可控的服务器都没有),所以可以想的办法不多,条件限制在 只能用PHP+MySql。所以我想到的办法就是通过Tags来匹配相似文章进行推荐。如果两篇文章的TAGS 比较相似
比如:文章A 的TAGS为: [A,B,C,D,E]
文章B 的 TAGS 为:[A,D,E,F,G]
文章C 的 TAGS 为:[C,H,I,J,K]通过眼睛我们能很方便的发现,文章B和文章A更为相似,因为它们有三个关键字相同分别为:[A,D,E],哪如何用计算机来判断它们的相似度呢,这里我们用jaccard相似度的最基本应用来计算它们的相似度
jaccard相似度
给定两个集合A,B,Jaccard 系数定义为A与B交集的大小与A与B并集的大小的比值,定义如下:
文章A和文章B的交集为 [A,D,E],大小为3,并集为[A,B,C,D,E,F,G],大小为7,3/7=0.4285...
而文章A和文章C交集为 [C],大小为1,并集为[A,B,C,D,E,H,I,J,K],大小为9, 1/9=0.11111...
这样就可以得出文章A,B比文章A,C更为相似,有了这个算法,计算机就可以来判断两篇文章的相似度了。
具体的推荐思想
给定一篇文章,获取该文章的关键字TAGS,然后通过以上算法去数据库比对所有文章的相似度,获取最相似的N篇文章进行推荐。
实现过程
第一 TAGS的获取
文章的TAGS是通过TF-IDF算法,提取文章中的高频词,选取N个作为TAGS,对于中文的文章来说还涉及到一个中文分词的问题,因为是虚拟主机的关系,这步的工作我用python(为什么用Python ,jieba分词,真香)在本地写了一个程序,完成所有文章的分词,词频统计,生成TAGS,并写回服务器的数据库。由于本文是写推荐的算法,所以分词和建立TAGS的部分就不具体展开了,而且不同的系统有不同的TAGS建立方式。
第二 TAGS的存储
建立两张表,用于存储TAGS
tags,用于存所有tag的名称
1 2 3 4 5 6 7 | +-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| tag | text | YES | | NULL | |
| count | bigint(20) | YES | | NULL | |
| tagid | int(11) | NO | PRI | 0 | |
+-------+------------+------+-----+---------+-------+
|
tag_map 建立tag和文章的映身关系。
1 2 3 4 5 6 7 | +-----------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | 0 | |
| articleid | bigint(20) | YES | | NULL | |
| tagid | int(11) | YES | | NULL | |
+-----------+------------+------+-----+---------+-------+
|
tag_map存的数据类似如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | +----+-----------+-------+
| id | articleid | tagid |
+----+-----------+-------+
| 1 | 776 | 589 |
| 2 | 776 | 471 |
| 3 | 776 | 1455 |
| 4 | 776 | 1287 |
| 5 | 776 | 52 |
| 6 | 777 | 1386 |
| 7 | 777 | 588 |
| 8 | 777 | 109 |
| 9 | 777 | 603 |
| 10 | 777 | 1299 |
+----+-----------+-------+
|
其实做相似推荐的时候,只需要用到tag_map表就可以了,因为tagid和tag name 是一一对应的。
具体编码
1.获取所有文章对应的TAGID
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | mysql> select articleid, GROUP_CONCAT(tagid) as tags from tag_map GROUP BY articleid;
+-----------+--------------------------+
| articleid | tags |
+-----------+--------------------------+
| 12 | 1178,1067,49,693,1227 |
| 13 | 196,2004,2071,927,131 |
| 14 | 1945,713,1711,2024,49 |
| 15 | 35,119,9,1,1180 |
| 16 | 1182,1924,2200,181,1938 |
| 17 | 46,492,414,424,620 |
| 18 | 415,499,153,567,674 |
| 19 | 1602,805,691,1613,194 |
| 20 | 2070,1994,886,575,1149 |
| 21 | 1953,1961,1534,2038,1393 |
+-----------+--------------------------+
|
通过以上SQL,可以一次性查询所用文章,极其对应的所有tag
在PHP,我们可以把tags变成数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public function getAllGroupByArticleId(){
if ( $cache = CacheHelper::getCache()){
return $cache ;
}
$query_result = $this ->query( 'select articleid, GROUP_CONCAT(tagid) as tags from tag_map GROUP BY articleid' );
$result = [];
foreach ( $query_result as $key => $value ){
$result [ $value [ 'articleid' ]] = explode ( "," , $value [ 'tags' ]);
}
CacheHelper::setCache( $result , 86400);
return $result ;
}
|
有了这个的返回结果,就比较好办了,接下去的工作就是去应用jaccard相似度这个算法了,具体就看代码吧。
阅读剩余部分
相关阅读 >>
mysql索引类型介绍
如何进入mysql数据库
oracle和mysql的高可用方案对比分析
mysql搜索引擎及其区别
mysql如何批量修改字符集
浅谈mysql的整体架构
mysql8.0绿色版安装教程详解
mysql分页性能探索
navicat连接mysql出现1045错误的解决方法是什么
mysql到底支不支持事务嵌套?
更多相关阅读请进入《算法》频道 >>
机械工业出版社
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。
转载请注明出处:木庄网络博客 » 基于Tags实现内容推荐的方法(代码)