客串:屌絲的坑人表單神器php
走過的那些事兒:數據庫那點事兒html
探討:探討負載均衡算法
面向對象的認識:面向對象的認識----新生的初識、面向對象的番外----思想的夢遊篇(1)sql
起點:手把手教你作關鍵詞匹配項目(搜索引擎)---- 第一天數據庫
回顧:手把手教你作關鍵詞匹配項目(搜索引擎)---- 第十八天負載均衡
第十九天post
上回咱們一直提到字典的構建,以及寶貝屬性的特殊處理,提得太多,致使如今整個系統還不能徹底的運行起來。搜索引擎
小帥帥要多在這方面下功夫了。spa
就算上次咱們提到的用SQL語句裏面的對屬性LIKE,對黑名單NOT LIKE也沒法解決全部的問題,咱們只是把須要匹配的關鍵詞縮小了範圍。code
咱們拿一個實例來講明下:
有個寶貝是雪紡連衣裙,那麼雪紡連衣裙a 、新潮雪紡連衣裙a、韓版雪紡女裙a、高仿雪紡女裙、正品女裙等這些詞能用嗎?
小帥帥、於老大、小樂樂、小歡歡以及小哼哼一致認爲須要爲每一個關鍵詞跟寶貝屬性(字典)作匹配,當匹配度處於某個值,好比>=80%的時候可用。
小帥帥又納悶了,怎麼作到爲每一個關鍵詞跟寶貝屬性(字典)作匹配呢?
當時於老大就提到用關鍵詞拆分算法,這個算法其實很簡單,原理以下:
把關鍵詞按業務詞彙拆成詞組或者單詞,對每一個單詞或者詞組算出在整個關鍵詞所佔的比例,好比:雪紡連衣裙a 那麼會被拆分紅雪紡、連衣裙和a,那麼相應的比例爲33%、50%和17%。
而後再根據所拆成的詞組或者單詞同寶貝屬性(字典)作對比,那麼算出匹配成功的總比例來決定是否可用。好比寶貝是雪紡連衣裙,那麼雪紡連衣裙a,所獲得的匹配度爲33%+50%=83%。
當這個算法一講解完畢,小帥帥就迫不急待的寫了代碼,代碼以下:
<?php class Splitter { /** * 獲取類目下分詞的詞組數據,按字符串長度比較排序 * @param $cid * @return array */ public static function getWordSegmentation($cid){ $ret = array(); $sql = "select word from category_linklist where cid='$cid'"; $words = DB::makeArray($sql); foreach($words as $strWords){ $words = explode(",",$strWords); foreach($words as $word){ if(self::isPhrase($word)){ $ret[] = $word; } } } usort($ret,function($a,$b){ return (strlen($a)<strlen($b))?1:-1; }); return $ret; } /** * 檢測是否爲詞組 * @param $word * @return bool */ public static function isPhrase($word){ if(preg_match('/^[\x{4E00}-\x{9FA5}]+$/u', $word) && strlen($word) <= 3){ return false; } if(strlen($word)<=1){ return false; } return true; } /** * 把關鍵詞拆分紅詞組或者單詞 * @param $keyword * @param $cid * @return array */ public static function split($keyword,$cid){ $splitWords = array(); $splitSegmentation = self::getWordSegmentation($cid); $remainKeyword = $keyword; foreach($splitSegmentation as $phrase){ if(count(explode($phrase,$remainKeyword))>1){ $splitWords[] = $phrase; $remainKeyword = str_replace($phrase,"::",$remainKeyword); } } $remainKeywords = explode("::",$remainKeyword); $splitWords = array_merge($splitWords,$remainKeywords); $keywordScores = array(); foreach($splitWords as $splitWord){ $keywordScore = new KeywordScore(); $keywordScore->splitWord = $splitWord; $keywordScore->weight = self::calculateWeight($splitWord,$keyword); $keywordScores[] = $keywordScore; } return $keywordScores; } /** * @desc 計算UTF8字符串權重 * @param string $splitWord * @param string $word * @return float */ public static function calculateWeight($splitWord, $word) { return ROUND(strlen($splitWord) / strlen($word), 3); } } class KeywordScore { public $splitWord; public $weight; }
小帥帥寫這個也是一點一點通過屢次重構而得來的結果,他不想讓於老大失望,因此一再精益求精。
小帥帥把代碼拿給於老大看的時候,於老大會有什麼反應呢,請看下回分解.