劉 勇,劉 菲,蒙 杰
(甘肅省科學技術情報研究所∕甘肅省科技評價監(jiān)測重點實驗室,甘肅 蘭州 730000)
隨著更多的社會資源進行網絡化和數據化,大數據所能承載的價值不斷提升,應用邊界不斷擴大,使用戶獲取各方面的信息更加便捷,幫助用戶在繁復的信息中能夠精準快速的篩選出自己所需的信息至關重要。推薦引擎技術已經滲入生活之中,如淘寶的猜你喜歡、QQ 的好友推薦、今日頭條的文章推薦、網易云音樂的曲目推薦、Gmail 的廣告推送等。用戶看似使用的是同一款軟件,但呈現的頁面結果卻是千人千面,這都與基于大數據不同維度的個性化推薦有關[1]。對于用戶而言,提高單位時間的信息價值,減少噪聲干擾的同時得到更好的信息體驗;從應用角度來說,可以精準地定位到不同的用戶,提高推廣效果,減少用戶流失的可能性。推薦系統(tǒng)已成為互聯(lián)網公司營銷體系中非常重要的一環(huán)并有實際的收益[2]。
推薦是各大互聯(lián)網公司十分重要的營收手段,一直備受工業(yè)界與學術界的關注。過去幾年,推薦系統(tǒng)由早期的協(xié)同過濾算法[3]發(fā)展到MF模型、再到之后的Wide&Deep,以及基于Network Embedding的方法,可以明顯地看到基于神經網絡的方法正在逐漸占據主要位置,而GNN的出現又一次加速了技術趨勢[4]。由于機器學習、深度學習技術的成熟,以及對各種復雜特征的應用方法逐步穩(wěn)定。
在工業(yè)界,國內科技公司如京東、淘寶等都在普遍利用機器學習來構建推薦系統(tǒng),推薦系統(tǒng)普遍應用于生活中并且取得了明顯進步,但也面臨著數據稀少、用戶行為的復雜性、業(yè)務的多樣性、冷啟動、精確性的兩難窘境。
在學術界,中國學者在推薦系統(tǒng)中廣泛應用深度學習技術,如卷積神經網絡(CNN)和循環(huán)神經網絡(RNN)等,以提高推薦性能[5]。一些研究關注將社交網絡信息整合到推薦系統(tǒng)中,以提高個性化推薦的準確性。針對多種類型的數據(文本、圖像、音頻等)進行推薦的研究逐漸增多,這有助于更全面地了解用戶興趣。針對實時性要求較高的應用,研究者致力于設計能夠快速適應用戶興趣變化的實時推薦系統(tǒng)。
(1)系統(tǒng)采用ElasticSearch 搜索引擎,相較于關系型數據庫,檢索速度更快。
(2)系統(tǒng)采用ElasticSearch 搜索引擎,引用第三方插件IKAnanlyzer分詞器,增加自定義詞庫對數據進行分詞處理,讓搜索引擎更加高效和準確。
(3)系統(tǒng)有效的解決了冷啟動問題。對于用戶冷啟動問題,解決辦法是將所有用戶近幾天查看的相關產品推薦給新用戶。對于物品冷啟動問題,文章的解決辦法是增加資源最近上新時間權重,將新增的物品推薦給可能會感興趣的用戶。
(4)對于開發(fā)者而言,無需了解太多復雜算法,大大減少了學習成本,極大地提高了開發(fā)效率。
該系統(tǒng)以科技創(chuàng)新公共服務平臺積累的大量科技服務、科研店鋪、科學儀器、技術轉移、專家信息等數據為支撐,依托ElasticSearch 大數據分析挖掘技術,采用TF-IDF、LUCentere、熱詞統(tǒng)計發(fā)現算法等算法,計算每個文檔的相關性得分,對其進行推薦排序。系統(tǒng)功能結構如圖1所示。
圖1 系統(tǒng)功能結構圖
(1)數據導入
將科技資源、科研服務等數據信息從SQLServer關系型數據庫中采用Python 程序異步批量導入ElasticSearch 中,其中數據字段包含主要介紹內容、時間、名稱、所屬科學領域、收藏數、收藏區(qū)間上升數、點擊量、點擊區(qū)間上升數、點贊數、點贊區(qū)間上升數,每12 h 運行一次Python 程序進行一次定時數據更新。
(2)用戶行為存儲
在ElasticSearch 中創(chuàng)建一個用于存儲用戶搜索、瀏覽、購買、評論等信息的索引,將用戶的id、所查看服務的分類、服務名稱、服務內容、服務所屬店鋪等信息存入該索引中。數據類型見表1。
表1 數據存儲類型
其中用戶點擊時間存儲為日期類型,便于后續(xù)進行時間區(qū)間檢索;服務名稱與服務內容存儲為全文本(text)類型,便于日后進行排序聚合,其他存儲均為關鍵字(keyword)類型。
ElasticSearch 中字符類型包括text 類型與keyword類型,text類型的數據被用來索引長文本,在建立索引文檔之前會被分詞器進行分詞,轉化為詞組。經過分詞機制之后ES 允許檢索到該文本切分而成的詞語,但是text類型的數據不能用來過濾、排序和聚合等操作。keyword 類型不支持文本分詞但可以進行過濾、排序和聚合。
text 類型的字段若想進行排序和聚合,則需要在設置字段時設置fielddata為“true”。fielddata的結構與正排索引非常相像,構建和管理都在內存中并常駐于JVM內存堆,加載太多的數據到內存會導致垃圾回收(gc)緩慢,甚至可能導致OutOfMemory 異常,一般不推薦使用[6]。為了限制fielddata使用大量的內存,則需要設置indices.fielddata.cache.size 參數,該參數控制fielddata 堆內存分配。當執(zhí)行一個查詢需要訪問新的字段值的時候,將會把值加載到內存,然后試著把它們加入到fielddata。如果fielddata大小超過指定的大小,為了騰出空間,別的值就會被驅逐出去。默認情況下,這個參數設置的是無限制,即Elasticsearch 將永遠不會把數據從fielddata里替換出去,這個設置是一個保護措施,而不是一個內存不足的解決方案。使用默認的設置,來自老索引的fielddata不會被清除出去,fielddata會一直增長直到阻止你繼續(xù)加載fielddata,在那時程序將會被卡住。為了避免這類情形產生,需在config∕elasticsearch.yml 文件里加上indices.fielddata.cache.size的值為20%的配置給fielddata 設置一個上限,最久未使用(LRU)的fielddata 將會被回收,給新加載的數據騰出空間。
(3)文本分詞
由于ElasticSearch 的內置分詞器對中文有一定的局限性,本系統(tǒng)引用第三方插件IKAnanlyzer分詞器,IK分詞器包含ik_max_word和ik_smart兩種分詞模式[7]。ik_max_word 為最大限度分詞,而ik_smart盡量以詞語的形式分詞。IK分詞器雖然優(yōu)于ES提供的默認分詞器,但是仍存在一個弊端,即不能識別網絡中的熱詞或者一些小區(qū)名等,故需自定義一些詞匯用于分詞處理。首先定義擴展字典,如“蘭州大學”“科學技術”“高新技術企業(yè)”等的專有名詞,可在分詞時不拆分;再定義擴展停止詞字典,如“①”“&”“雖說”等一些無關緊要的語氣助詞、動詞、形容詞等,可在分詞時對停用詞進行屏蔽與過濾處理[8]。
(1)過濾與聚合
根據用戶ID 對近1 個月到近7 d、近7 d 兩個時間段的行為進行聚類統(tǒng)計,再對所有用戶近1 個月到近7 d、近7 d兩個時間段的行為進行聚類。
采用熱詞統(tǒng)計發(fā)現算法中的加權變化率對熱詞進行計算。首先對近7 d聚類的采錄訪問主題詞進行循環(huán),當其中元素的字符長度小于2,跳出本次循環(huán)執(zhí)行下一次循環(huán)。否則,判斷其中元素是否存在于近1 月至7 d 聚類出現結果全集中。若匹配到之前存在這個詞,則令匹配到之前的次數為近1 月至7 d聚類出現結果全集中該元素出現的總次數,否則令匹配到之前的次數為0。該元素加權變化率:
其中:CZ為近7 d 搜索次數,Cqq為匹配到之前的次數。若加權變化率小于0,則將該元素放入停用詞數組中,否則判斷停用詞數組中是否包含該元素。若停用詞數組包含該元素則跳出此次循環(huán)進入下一循環(huán),若不包含該元素則令該元素權重為1.1×該元素加權變化率,將該元素和權重放入熱詞數組中,具體流程如圖2所示。
圖2 熱詞加權流程圖
其中WQ為近1月至7 d聚類出現結果全集,CQ為近1月至近7 d聚類檢索總次數,WZ為近7 d搜索詞全集,CZ為近7 d搜索總次數,Cqq為匹配到為近1 月至近7 天的搜索次數,stopWord 為停用詞,topicWord為熱詞,RateWithWeight為加權變化率。
(2)相似度計算
采用TF-IDF、LUCentere相關性等算法,將熱詞集合與庫中數據進行相似度計算排序。
首先提取熱詞,通過標題、內容、單位等字段進行匹配,將最小匹配度設置為80%,按照相關度進行排序顯示。其中在標題字段上加權重,使得詞干出現在標題字段上比出現在其他字段上的文檔匹配分值高。
其次,按受歡迎度提升權重,將收藏數、收藏區(qū)間上升數、點擊量、點擊區(qū)間上升數、點贊數、點贊區(qū)間上升數、產品上新時間作為考慮因素分別設置權重進行分值處理計算。公式為:
其中:old_score 為之前分數值;new_score 為現在分數值;number_of_votes表示收藏數;收藏區(qū)間上升數等考慮因素的值,factor 值大于1 會提升效果,factor值小于1會降低效果。
然后,對文檔中的發(fā)布時間字段設置一個理想的值,如果實際的值越偏離這個理想值(無論是增大還是減?。驮讲环掀谕?,分數就越低。系統(tǒng)采用高斯衰減函數,若將當前日期設的為原點,所有距原點前7 d 范圍內的位置的評分是1.0,距原點30 d的位置評分是0.5。
最后,將各個部分分值相加合并成一個綜合的分值,然后再將綜合的分值與查詢分數相乘,見表2。
表2 文檔得分表
經過數據采集、清洗、導入、用戶行為存儲、文本分析、過濾、聚合、相似度計算、倒排索引等操作,采用Bootstrap 框架進行前端頁面的顯示,利用Ajax技術實現前后端交互,采用HTTP 協(xié)議與數據庫通信,網絡采用FTTX+LAN 光纖線路實現訪問ChinaNET和CerNET自動分流。
系統(tǒng)測試數據主要源于科技創(chuàng)新公共服務平臺經過特殊處理后的歷史數據,數據量約有1萬條,搜索性能見表3。
表3 搜索測試結果
從表3 分析可知,對于大量的數據檢索,ES 檢索所花費的時間遠低于傳統(tǒng)的數據庫檢索。
求熱詞時,單純比較每天詞條的出現次數是不行的,主要是需要比較多天之間的出現次數。具體有以下算法。
(1)排位差
算法的核心思想是根據詞語每天出現次數求出其排在第幾,之后計算2 d的排位差,根據排位差求熱度。
首先,統(tǒng)計每一個詞在昨天和前天出現的次數,并找出排位前N 的詞語集合。其次,計算每個詞兩天的排位差。最后,根據詞語的排位差進行排序,其中排位變化最大的就是最熱的詞。
如果昨天出現的詞前天也同樣存在則排位差的公式為:
式中:Position(w,昨日)表示詞條昨日排位,Position(w,前日)表示詞條前日排位。若昨天出現的詞前天并未出現則排位差的公式為:
式中:N為詞條前日全部排位數。詞條這兩天的排位差PositionChange越小,表示其越火。雖然此算法比較笨,必須作三次排序,但是挑選出的詞語效果還是比較好的。
(2)變化率
算法核心思想是根據詞語2 d的出現次數求出其出現次數的比值,根據比值求出其熱度。
首先,統(tǒng)計每一個詞在昨天和前天出現的次數,并找出排位前N 的詞語集合。其次,計算每個詞這兩天的變化率,即今日次數∕昨日次數。最后,根據詞語的變化率進行排序,其中變化率最大的就是最熱的詞。公式如下:
式中:Cz為某詞昨日訪問頻次,Cq為某詞前日訪問頻次。該算法雖然簡單,但是對于訪問次數少但變化率大的詞語會占便宜。
(3)加權變化率
加權變化率是對于算法2 的修正,考慮搜索量因素,根據詞語2 d 的出現次數和其在總搜索次數的站的份額求出比值,根據比值求出其熱度。
首先,統(tǒng)計每一個詞在昨天和前天出現的次數,并找出排位前N 的詞語集合。
其次,對每一個詞,計算每個詞這2 d的加權變化率。
式中,CZ為昨日搜索總頻次,CQ為前日搜索總頻次。最后,根據詞語的加權變化率進行排序,其中加權變化率最大的就是最熱的詞。
Lucene[9]的評分是叫做TF∕IDF 算法,根據分詞詞庫,所有文檔在建立索引的時候進行分詞劃分。進行搜索的時候,也對搜索的短語進行分詞劃分。lucene的算法簡單來說就是將搜索的短語進行分詞得出分詞項,每個分詞項和每個索引中的文檔根據TF∕IDF進行詞頻出現的評分計算[10]。然后每個分詞項的得分相加,就是這個搜索對應的文檔得分,公式為:
式中:score(q,d)是文檔d與查詢q的相關度評分。
queryNorm(q)為查詢歸一因子,查詢歸一因子將查詢歸一化,使最終的得分不至于太大,從而具有一定的可比性。
coord(q,d)是協(xié)調因子表示輸入的Token 被文檔匹配到的比例,可以為那些查詢詞包含度高的文檔提供獎勵,文檔里出現的查詢詞越多,它越有機會成為好的匹配結果。如果檢索“你好朋友”,設每一個詞的權重為1.2,若沒用協(xié)調因子,最終評分會是文檔里所有詞權重的總和。比如文檔里有“你好”這一詞則評分為1.2;文檔里有“你好朋友”則評分為2.4。協(xié)調因子將評分與文檔里匹配詞的數量相乘,然后除以查詢里所有詞的數量,如果使用協(xié)調因子,文檔里有“你好”評分會變成1.1×1∕2=0.6,文檔里有“你好朋友”評分會變成2.4×2∕2=2.4。
tf(tind)是詞t 在文檔d 中的詞頻,頻率越高,得分越高。
idf(t)指的是詞在集合所有文檔里出現的頻率越高,權重越低,可以快速縮小范圍找到感興趣的文檔。
t.getBoost()是查詢中使用的權重。
norm(t,d)為長度的加權因子,主要是為了在文檔都匹配的情況下將較短的文檔增加權重排在前面。
∑(tinq)是查詢q中每個詞t對于文檔d的權重和。
聚合分析運算是數據庫中重要的特性,對于數據分析場景尤為重要。類似于關系型數據庫中的SUM、AVG、GROUP BY 等,ElasticSearch 也提供了豐富的聚合運算方式,可以滿足大部分分析和查詢場景。桶的叫法和SQL 里面分組的概念是類似的,一個桶就類似SQL 里面的一個group,多級嵌套的aggregation,類似SQL 里面的多字段分組?;诜治鲆?guī)則的不同,ES 將聚合分析主要劃分為Metric、Bucket、Pipeline及Matrix[11]。
(1)Metric
Metric 是指標分析聚合,其主要分為單值分析和多值分析這兩類。
單值分析可以同時使用多個單值分析關鍵詞返回多個結果。主要包括以下:
min:返回數值類型字段的最小值。
max:返回數值類型字段的最大值。
avg:返回數值類型字段的平均值。
sum:返回數值類型字段值的總和。
cardinality:返回不重復的總個數。
weight avg:在計算平均數時會使用另外一個字段作為每個文檔的權重。
value count:統(tǒng)計某字段所有有值的文檔數。
多值分析可以輸出多個結果。主要包括以下:
stats:一次性返回所有單值結果。
extended_stats:對stats進行擴展,包含更多,如:方差,標準差,標準差范圍等。
percentile:百分位數統(tǒng)計,比如用于統(tǒng)計95%的員工工資都小于某個值或者大于某個值。
percentile rank:和percentile 統(tǒng)計方向相反,比如用于統(tǒng)計工資小于2 萬的員工落在哪個百分比上。
top hits:一般用于在查詢結果中返回每個桶(bucket)中的頂部N 個文檔,使用時一般需要帶上排序信息。
(2)Bucket
分桶聚合,將滿足同一種條件的數據放在一個桶中,類似于關系型數據庫中的group by 語法,根據一定規(guī)則按照維度進行劃分成不同的桶。與指標聚合不同的是,桶聚合可以進行嵌套,大桶里面可以套小桶,對大桶的數據再次篩選并且可以嵌套多層。常見的有以下5類:
Terms:直接按照term 進行分桶,類似數據庫group by 以后求和,如果是text 類型,按分詞后的結果分桶。
Range:按指定數值范圍進行分桶。
Date Range:按指定日期范圍進行分桶。
Histogram:直方圖,按固定數值間隔策略進行數據分割。
Date Histogram:日期直方圖,按固定時間間隔進行數據分割。
(3)Pipeline
管道分析類型,支持對聚合分析的結果再次進行聚合分析,且支持鏈式調用。pipeline的分析結果會輸出到原結果中,因輸出位置不同,分為:Parent和Sibling。Sibling 是同級聚合,對當前同一級的聚合數據進行處理,操作后的數據不會影響其他聚合的輸出,會生成新的桶,使用兄弟管道聚合同級必須有兩個或以上的聚合。Parent是對父聚合處理后的數據進行處理,返回值不會生成新桶,而是在原有桶內。
(4)Matrix
矩陣聚合,類似于分別使用Metric 的多值聚合對數據進行聚合,并且不支持腳本。
文章依托ElasticSearch 大數據分析挖掘技術,通過熱詞統(tǒng)計算法挑選出個人用戶和全部用戶的前100的熱詞,再將其與庫中文檔進行相似度計算,對科技服務的喜愛度、點擊率權重提升,最后進行綜合評分。結合個人用戶與全部用戶喜愛度,通過設置不同權重來推薦商品,不僅滿足用戶個性化推薦,而且使推薦商品更加多樣。使用ElasticSearch提高了推薦速度、簡化開發(fā)步驟,采用文章推薦方法提高了推薦的準確性,并且有效的解決了“冷啟動”問題。但還存在不足,之后將深度挖掘數據,發(fā)現更多符合用戶感興趣的信息,進一步提高推薦的多樣性。