摘要:原來為了簡單方便,自己小網站上的文章頁的相關內容推薦就是從數據庫里隨機抽取數據來填充一個列表,所以一點相關性都沒有,更本沒有辦法引導用戶去訪問推薦內容。
原來為了簡單方便,自己小網站上的文章頁的相關內容推薦就是從數據庫里隨機抽取數據來填充一個列表,所以一點相關性都沒有,更本沒有辦法引導用戶去訪問推薦內容。
算法選擇如何能做到相似內容的推薦呢,礙于小網站還跑在虛擬主機上(對的,連一個自己完整可控的服務器都沒有),所以可以想的辦法不多,條件限制在 只能用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的名稱
+-------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------------+------+-----+---------+-------+ | tag | text | YES | | NULL | | | count | bigint(20) | YES | | NULL | | | tagid | int(11) | NO | PRI | 0 | | +-------+------------+------+-----+---------+-------+
tag_map 建立tag和文章的映身關系。
+-----------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------+------+-----+---------+-------+ | id | bigint(20) | NO | PRI | 0 | | | articleid | bigint(20) | YES | | NULL | | | tagid | int(11) | YES | | NULL | | +-----------+------------+------+-----+---------+-------+
tag_map存的數據類似如下:
+----+-----------+-------+ | 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.獲取所有文章對應的TAGIDmysql> 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變成數組。
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){ //用articleid 做key ,值是該id下的所有tagID數組。 $result[$value["articleid"]] = explode(",",$value["tags"]); } CacheHelper::setCache($result, 86400); return $result; }
有了這個的返回結果,就比較好辦了,接下去的工作就是去應用jaccard相似度這個算法了,具體就看代碼吧。
/** * [更據指定文章返回相似的文章推薦] * @param $articleid 指定的文章ID * @param $top 要返回的推薦條數 * @return Array 推薦條目數組 */ function getArticleRecommend($articleid, $top = 5){ if($cache = CacheHelper::getCache()){ return $cache; } try{ $articleid = intval($articleid); $m = new TagMapModel(); $all_tags = $m->getAllGroupByArticleId();//調用上面的函數返回所有文章的tags $finded = $all_tags[$articleid];//因為上面是包含所有文章了,所以肯定包含了當前文章。 unset($all_tags[$articleid]);//把當前文章從數組中刪除,不然自己和自己肯定是相似度最高了。 $jaccard_arr = []; //用于存相似度 foreach ($all_tags as $key => $value) { $intersect =array_intersect($finded, $value); //計算交集 $union = array_unique(array_merge($finded, $value)); //計算并集 $jaccard_arr[$key] = (float)(count($intersect) / count($union)); } arsort($jaccard_arr); //按相似度排序,最相似的排最前面 $jaccard_keys = array_keys($jaccard_arr);//由于數組的key就是文章id,所以這里把key取出來就可以了 array_splice($jaccard_keys, $top);//獲取前N條推薦 //到這里我們就已經得到了,最相似N篇文章的ID了,接下去的工作就是通過這幾個ID,從數據庫里把相關信息,查詢出來就可以了 $articleModels = new ApiModelArticleModel(); $recommendArticles = $articleModels->getRecommendByTag($jaccard_keys); CacheHelper::setCache($recommendArticles, 604800); //緩存7天 return $recommendArticles; } catch (Exception $e) { throw new Exception("獲取推薦文章錯誤"); } }
雖然簡單,短短幾條代碼,但是效果還是可以的,推薦的文章有了一定的相似度,肯定可以帶來更好的用戶體驗,實例 ,你們可以看看 https://www.wx2share.com/Arti...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30866.html
摘要:原來為了簡單方便,自己小網站上的文章頁的相關內容推薦就是從數據庫里隨機抽取數據來填充一個列表,所以一點相關性都沒有,更本沒有辦法引導用戶去訪問推薦內容。 原來為了簡單方便,自己小網站上的文章頁的相關內容推薦就是從數據庫里隨機抽取數據來填充一個列表,所以一點相關性都沒有,更本沒有辦法引導用戶去訪問推薦內容。 算法選擇 如何能做到相似內容的推薦呢,礙于小網站還跑在虛擬主機上(對的,連一個自...
摘要:所以我們選一個倉庫倉庫比較多,我這里選用,都行,根據需求自行選擇訪問端口,然后就沒有然后了功能沒有那么強大,不過占用資源少,速度快,我們穩定運行了幾年了。 kubernetes集群三步安裝 CI 概述 用一個可描述的配置定義整個工作流 程序員是很懶的動物,所以想各種辦法解決重復勞動的問題,如果你的工作流中還在重復一些事,那么可能就得想想如何優化了 持續集成就是可以幫助我們解決重復的代碼...
摘要:只要的項目有提交,相關就根據來決定是否跑自動部署的命令。項目的自動部署添加執行的注冊命令,按照說明進行參數配置。至此,和服務都已經自動部署完成。 準備工作 說明 公司最近準備了一臺新的開發服務器,正好用以實踐docker的基本應用。docker的好處不再贅述,詳情可參考阮一峰的這篇入門。(關于Docker最好的中文介紹,沒有之一)。 公司目前主要使用了EggJs + ReactJS的技...
摘要:如果實在不會安裝可以去網上找教程。打開,跳轉到剛剛創建的文件夾位置,運行命令然后會在你的文件夾中搭建好了環境配置配置修改一些你的博客名字描述作者等。基于我的個人經驗,建議都開啟開啟標簽頁命令,在博客目錄添加元數據開啟分類頁命令,在博 Windows環境下Git安裝、配置SSH key、安裝node.js npm、安裝Hexo及配置、發布博客 前言 使用github pages服務搭建博客的...
閱讀 2976·2023-04-25 19:45
閱讀 2694·2021-11-19 09:40
閱讀 697·2021-10-14 09:49
閱讀 2692·2021-09-30 09:47
閱讀 2221·2021-09-26 09:55
閱讀 1230·2021-09-22 16:01
閱讀 2814·2019-08-30 14:19
閱讀 710·2019-08-29 16:44