使用PHP?MySQL實現(xiàn)數(shù)據(jù)量小的內(nèi)容推薦方法
前言
當下,只要是一個初具規(guī)模的內(nèi)容應用都具備個性化推薦系統(tǒng)。比如購物類的會有推薦商品模塊,搜索條下有個性化的搜索關鍵詞或詞條補全詞,社交類的有博主推薦,視頻或文章推薦等等。這些功能除了要有龐大的數(shù)據(jù)量,還要有健全的數(shù)據(jù)存儲倉庫建設方案,以及后面對數(shù)據(jù)的清洗,排序,訓練后的推薦模型算法?! ?/p>
但是,對于小公司或者說是小項目,在想法還未真正落地就設計大數(shù)據(jù)存儲,推薦算法和一系列大型架構的方案,顯然是不符合業(yè)務型產(chǎn)品開展的正常規(guī)律的。我想那些大廠早期開發(fā)應該也沒有這么成熟的技術結構,都是不斷迭代或者推倒重來一步步走過來的?! ?/p>
那么,在小項目早期安排了有關于推薦功能的那要如何解決呢? 如何做到下一次迭代在不重構的基礎上添加協(xié)同過濾推薦? 下面就從視頻推薦和用戶推薦兩個功能展開,用PHP和MySQL進行代碼實現(xiàn)。
視頻推薦
這里主要通過一個內(nèi)容熱度值進行排序推薦,熱度由內(nèi)容質(zhì)量和發(fā)布時間差決定,時差越長,熱度越低,內(nèi)容質(zhì)量越高熱度越高。而內(nèi)容質(zhì)量由視頻點贊數(shù),收藏數(shù)和評論數(shù)外帶權重決定,總體就是單位時間內(nèi)點贊,收藏,評論越高,熱度提升,視頻就越往前靠。相對的就是發(fā)布時間越久,熱度就會逐步降低,視頻越往后靠。
另外我們還要設計兩個參數(shù)用于手動調(diào)節(jié)視頻的熱度,提高就只需要增加內(nèi)容質(zhì)量,所以額外加一個數(shù)可以說是初始值。降低可以對時間差添加一個指數(shù),也就是時間差的次方,可以理解是重力,也就是隨著時間拉長,重力增加則熱度成倍降低。
1. 公式

1.1. ”H“:視頻熱度值
1.2. ”W“:視頻質(zhì)量,質(zhì)量值自定(點贊數(shù)權重,收藏數(shù)權重之和,或者點贊率(點贊量/閱讀量),收藏率(收藏量/閱讀量)之和)等。
1.3. ”I“:初始值,可以手動調(diào)節(jié)熱度或者用于后期用戶賬號的權重。比如系統(tǒng)已經(jīng)有了成長體系,賬號發(fā)育規(guī)則基本完善了,用于實時計算賬號的權重分配的流量池,權重提升,則后面發(fā)布的視頻推薦力度大。
1.4. ”T“:時間差,由當前時間 - 發(fā)布時間產(chǎn)生,加一的原因是防止時間差為0(分母為零),不過有審核機制下,這種情況并不存在。
1.5. ”G":熱度衰減重力,這個也是用于手動調(diào)節(jié)熱度設置的控制參數(shù)。不過后期如果添加了舉報或者智能復審等環(huán)節(jié),再隨著諸如點贊和賬戶權重評估失控熱度飆升的情況下,對視頻違規(guī)或不良表現(xiàn)或臨時情況進行減小推薦。默認值最好是1,這種情況就是在同等質(zhì)量下新發(fā)布的越往前。
2. 表結構
CREATE TABLE `hhyp_short_video` ( `id` int(11) NOT NULL AUTO_INCREMENT, `hsvn` varchar(255) DEFAULT '' COMMENT '短視頻編號', `type` tinyint(1) DEFAULT '0' COMMENT '類型:1. 視頻 2.圖文', `user_id` int(11) DEFAULT '0', `video_url` varchar(255) DEFAULT '', `img_url` json DEFAULT NULL, `content` text COMMENT '內(nèi)容', `market_goods_id` int(11) DEFAULT '0', `address_id` int(11) DEFAULT '0' COMMENT '地址ID', `lat` decimal(4,0) DEFAULT '0' COMMENT '緯度', `lng` decimal(4,0) DEFAULT '0' COMMENT '經(jīng)度', `ip` varchar(100) CHARACTER SET utf8 DEFAULT '' COMMENT 'IP', `channel` tinyint(1) DEFAULT '0' COMMENT '渠道', `read_count` int(11) DEFAULT '0' COMMENT '瀏覽數(shù)', `like_count` int(11) DEFAULT '0' COMMENT '點贊數(shù)', `collect_count` int(11) DEFAULT '0' COMMENT '收藏數(shù)', `comment_count` int(11) DEFAULT '0' COMMENT '評論數(shù)', `share_count` int(11) DEFAULT '0' COMMENT '分享數(shù)', `is_top` tinyint(1) DEFAULT '0' COMMENT '是否置頂:0.否 1.是', `status` int(11) DEFAULT '0' COMMENT '0. 審核中 10. 推薦 20. 下架', `hot_int` int(11) DEFAULT '1' COMMENT '熱度初始值', `gravity` int(11) DEFAULT '1' COMMENT '熱度重力衰減值', `audit_time` int(11) DEFAULT '0' COMMENT '審核時間', `remark` text, `create_time` int(11) DEFAULT '0' COMMENT '創(chuàng)建時間', `delete_time` int(11) DEFAULT '0', `update_time` int(11) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=107 DEFAULT CHARSET=utf8mb4;
3. 代碼
public static function getList($map, $page = 1, $size = 20)
{
// 數(shù)據(jù)指標權重配置
$wcfg = [
'like_weight' => 4,
'collect_weight' => 3,
'comment_weight' => 1
];
$timeUnit = 3600; // 單位小時
$where[] = ['delete_time', '=', 0];
$map = array_merge($where, $map);
// 單位小時內(nèi),點贊/收藏/評論越多熱度越高,發(fā)布越久熱度越低
$alog = "(like_count*%s+collect_count*%s+comment_count*%s+hot_int)/pow((UNIX_TIMESTAMP(NOW())-create_time)/%s, gravity)";
$hotIndex = sprintf($alog, $wcfg['like_weight'], $wcfg['collect_weight'], $wcfg['comment_weight'], $timeUnit);
$field = ["id, hsvn,type,user_id,video_url,img_url,content,market_goods_id,
like_count,collect_count,address_id,comment_count,share_count,create_time, $hotIndex as hot_index"];
$list = self::field($field)
->json(['img_url'], true)
->with([
'user' => function ($query) {
$query->withField('id, nickname, mobile, avatar');
},
'marketGoods' => function ($query) {
$query->withField('id, content,freight,user_id');
},
'address' => function ($query) {
$query->withField('id, mername');
}
])
->where($map)
->page($page, $size)
->order("hot_index desc")
->select();
return $list;
}用戶推薦
推薦用戶,大部分是放在App里的個人中心感興趣用戶模塊。有的是給用戶推薦授權的通訊錄好友,有的是根據(jù)行為數(shù)據(jù),通過給用戶打標簽,再推薦與自己標簽相似的用戶等等方式。而我這里的用戶推薦是放在發(fā)布視頻的用戶面板里,本來我想通過協(xié)同過濾的相似用戶來做,由于數(shù)據(jù)太有限,加之我們業(yè)務本身就不能查看用戶關注列表和粉絲列表,所以就暫時用了一個折中的方法,給用戶推薦創(chuàng)作者關注的關注?! ?/p>
根據(jù)當前面板用戶關注的用戶里挑出粉絲數(shù)最多的前十個,然后再從這十個里分別挑出他們關注用戶里粉絲最多的前十,最后合并去重,也就是給自己推薦打開用戶關注的關注里粉絲最多的那批人。
1. 表結構
CREATE TABLE `hhyp_user_attention` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用戶id', `comcemed_user_id` int(11) NOT NULL DEFAULT '0' COMMENT '關注的用戶id', `create_time` int(11) DEFAULT '0' COMMENT '創(chuàng)建時間', `status` smallint(3) NOT NULL DEFAULT '0' COMMENT '關注狀態(tài) 0未關注 1已關注', `update_time` int(11) DEFAULT '0' COMMENT '更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=352 DEFAULT CHARSET=utf8mb4;
2. 代碼
通過查詢子查詢里指定用戶里粉絲最多的前十人(分組排序),然后遞歸往前查詢就形成關注鏈條,最后再合并查詢結果。其實這個也很看數(shù)據(jù)的,當我真正把這個方法放上去的時候,會發(fā)現(xiàn)很多面板里沒有用戶推薦的數(shù)據(jù),因為很多用戶根據(jù)就沒關注幾個人。
所以通過深度學習或者協(xié)同過濾做用戶推薦可能要等待一段時間,等用戶行為數(shù)據(jù)產(chǎn)生差不多的時候,我再出一下協(xié)同過濾的用戶相似度推薦吧。
// 關注鏈列表
public static function grandadList($userIds = [], &$allList = [], &$level = 1)
{
$field = ["comcemed_user_id, count(*) as fans_count, {$level} as level"];
$list = self::field($field)
->where('comcemed_user_id', 'in', function ($query) use ($userIds) {
$query->table('hhyp_user_attention')
->where('user_id', 'in', $userIds)
->where('status', '=', 1)
->field('comcemed_user_id');
})
->where('status', '=', 1)
->group('comcemed_user_id')
->order('fans_count desc')
->limit(10)
->select()
->toArray();
if ($list && $level < 4) {
$level++;
$comcemedUserIds = array_column($list, 'comcemed_user_id');
$list = self::grandadList($comcemedUserIds, $list, $level);
}
$list = array_merge($allList, $list);
return $list;
}以上就是使用PHP MySQL實現(xiàn)數(shù)據(jù)量小的內(nèi)容推薦方法的詳細內(nèi)容,更多關于PHP MySQL內(nèi)容推薦的資料請關注腳本之家其它相關文章!
相關文章
php curl模擬post請求和提交多維數(shù)組的示例代碼
這篇文章主要介紹了php curl模擬post請求和提交多維數(shù)組的示例代碼,需要的朋友可以參考下2015-11-11
linux mint下安裝phpstorm2020包括JDK部分的教程詳解
這篇文章主要介紹了linux mint下安裝phpstorm2020包括JDK部分的教程詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
基于ThinkPHP5框架使用QueryList爬取并存入mysql數(shù)據(jù)庫操作示例
這篇文章主要介紹了基于ThinkPHP5框架使用QueryList爬取并存入mysql數(shù)據(jù)庫操作,結合實例形式分析了thinkPHP5框架整合QueryList爬取數(shù)據(jù)存入mysql相關操作技巧及注意事項,需要的朋友可以參考下2019-05-05
php截取字符串之截取utf8或gbk編碼的中英文字符串示例
php中自帶strlen是返回的字節(jié)數(shù),對于utf8編碼的中文返回時3個,不滿足需求,下面給大家提供一個方法來完成這樣的功能2014-03-03
PHP url的pathinfo模式加載不同控制器的簡單實現(xiàn)
下面小編就為大家?guī)硪黄狿HP url的pathinfo模式加載不同控制器的簡單實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08

