閒魚搜尋召回升級:向量召回&個性化召回
在搜尋系統中,召回環節位於排序漏斗的最底層,決定了下游排序的空間大小,其重要程度毋庸置疑,在閒魚搜尋場景亦是如此。然而由於機器和人力資源的限制,長期以來閒魚搜尋的召回都是使用最簡單的基於文字的召回方式,其優化迭代方式也只是在基礎商品欄位(標題、描述)之上,增加擴充套件欄位。基於此,季度優化前,閒魚主搜的召回整體方案如下:
-
Query側:通過Query改寫,擴充套件Query語義,緩解使用者側搜尋詞表達不充分的問題,間接實現擴召回;
-
Item側:通過增加擴充套件欄位,強化商品側的表徵,具體的拓展欄位包括:
-
結構化資訊,如類目、演算法識別的CPV(屬性值,如商品品牌、型號、顏色等);
-
商品影象識別的標籤,如OCR識別出的商品圖片中的描述欄位;
-
I2I商品資訊遷移:通過swing等I2I技術,引入與trigger商品相似商品的基礎資訊作為文字召回欄位;
-
同款、一鍵轉賣商品資訊遷移,同I2I,只不過擴充套件資訊通過確定的關聯商品得到;
-
其他商品預測Tag拓展;
雖然通過如上擴充索引欄位的方式,有效提升了搜尋的召回能力。但資料分析發現,召回不足的情況仍有較大的搜尋PV佔比,說明召回側還有比較大的空間可挖(具體資料這裡不做詳細羅列)。而優化召回不足大體可以從兩個方向發力:1)演算法策略層面進行優化,提升召回能力;2)供給層面優化,引導增加商品供給,或使賣家優化商品供給描述。這裡則討論前者,首先是當前系統主要有以下不足之處:
-
Query召回商品仍然使用純文字方式召回,Term命中規則嚴格,缺少語義匹配能力。
-
當前召回個性化能力不足,或者說沒有兼顧效率特徵,召回截斷後可能損失更具個性化的相關商品。
對於1,本季度我們增加基於語義的向量召回,緩解召回語義能力不足的問題;對於2則有很多思路,如考慮成交效率的向量召回、u2i、u2i2i等,這裡做了一些嘗試,發現有時常規的方案無法直接照搬到閒魚場景,而最終本次優化我們優先採用了基於行為的I2I(準確說是Q2I2I),同時為了彌補長尾query召回仍然不足的問題,我們補充了基於多模態內容的I2I,從文字和視覺維度召回相關商品。
對於上述擴召回的候選,我們使用類目、核心詞、語義相關性等維度保證相關性,召回升級後整體模組構成如下:
後面的章節,將依次分模組進行詳細方案的介紹。
語義向量召回
建模目標
搜尋向量召回的最理想結果是儘可能檢索出“相關且高成交效率”的商品。由於閒魚搜尋之前沒有向量召回鏈路,因此一期我們決定先從“相關性”目標出發,設計基於純語義的向量召回,目的是彌補文字召回語義泛化能力弱的問題。其難點主要為閒魚場景特色下Query和商品的語義表徵建模,以及線上機制策略的相容;而對於“成交效率”目標的兼顧,本季度也做了相應的實驗,但是由於閒魚場景的特殊性,暫時無法直接照搬常規方法,需要進一步探索,這點在本章結尾進行討論。
模型設計
閒魚搜尋的語義向量模型同大多數的場景一樣,使用DSSM架構,Baseline Encoder為預訓練的Electra-Small模型(相對於Bert-base效果微跌,但模型大小由300M+縮小到47M,提升了執行效率)。為了豐富Query語義,彌補Query表達不充分的問題,我們增加了臨近Query表徵(基於行為的Q2Q),與集團ICBU、淘寶主搜通過多工方式引入不同,這裡直接增加Query和臨近Query的self-attention模組,通過更為直接的融入資訊,避免了多工調餐的工作量及其不確定性。
對於無臨近Query的Key Query,進行置空操作,此外對於有臨近Query的Sample也會以一定機率置空,以適應新Query與超長尾Query缺少Q2Q的問題。
模型架構如下:
實現細 節
-
資料構造
搜尋語義召回向量的核心目標為相關性,因此其樣本構造也是圍繞此設計,這裡方案參考 閒魚搜尋相關性——體驗與效率平衡的背後 :
-
正樣本:充足曝光下高點選ctr樣本(如:ctr大於同query下商品點選率平均值)
-
負樣本:
-
Baseline隨機構造負樣本:為增加隨機性,該部分實現可在訓練時使用同Batch中其他樣本做負樣本,同時也可以引入經典的Batch Level Hard Sample機制。
-
同父類目的鄰居子類目負取樣。
-
高曝光低點選類目樣本:同一個Query搜尋下,根據全域性點選商品的類目分佈,取相對超低頻類目樣本作為負樣本。
-
充足曝光情況下,低於相應Query平均曝光點選率一定百分比的樣本做負樣本。
-
基於Query核心Term替換構造負樣本:如,對於“品牌A+品類”結構的Query,使用“品牌B+品類”結構的Query做其負樣本。
-
Graph Query Attention
Query Graph即上文提到的行為Q2Q,這裡參考Swing I2I演算法,構造Swing Q2Q結果。詳細地。取Top 3 Query拼接後作為Key Query的補充資訊,而後Key Query與Graph Querys通過[SEP]拼接作為模型Query塔的輸入。為了使模型能夠區分Key Query和Graph Querys的差異,不同的Query型別使用不同的Segment_id作為標識。對於Item-Title塔,其Segment_id與Key Query一致。
直接拼接的方式融合Graph Query資訊可以從模型底層就與key Query進行相互的Attention互動,以Query-Title的匹配為目標優化可以更直接的引入臨近Query的有用資訊,缺點則是一定程度上損失了模型預測階段對於無Graph Query的樣本精度。這點則是通過隨機丟棄Graph Query的方式緩解,實驗證明該方法行之有效。
-
Batch-Level Triple loss vs InfoNCE loss
早些時候,語義向量召回的優化目標loss為經典的Triple loss:
其中 d(a,p)表示向量a和p的距離,a和p表示query和doc的正樣本對,a和n表示負樣本對。Triple loss訓練的另一個標配是Online hard negative mining,即在mini-batch內,每個正樣本對之間互為負樣本,選擇其中最難的樣本作為負樣本(相似度打分最高的樣本對)。
除了經典的Triple loss外,我們也借鑑了對比學習框架(如MOCO、SimCLR等)下常用的InfoNCE Loss,:,這裡增加溫度引數,進一步提升模型的泛化能力。
其中q為query向量,k+為商品正樣本對,k-為負樣本對,τ為temperature超引數。InfoNCE在自監督對比學習中十分有效,同樣在有監督的對比學習框架下,也被驗證效果。上式從程式碼實現來看更加直觀,也比較巧妙:
loss_fun = torch.nn.CrossEntropyLoss()
# query_vecs : [batch, feat_dim]
# item_vecs : [batch, feat_dim]
# sim eg: cosine similarity,return dim: [batch, batch]
scores = sim(query_vecs, item_vecs) / temp
labels = torch.arange(scores.size(0)).long() # scores矩陣對角線為正樣本
loss = loss_func(scores, labels)
-
商品側引入其常搜query資訊
該部分策略出發點,閒魚搜尋場景中很多標題也存在資訊量不足的情況,如“便宜賣”,容易使模型學偏,這裡使用商品歷史有點選的Top3 Query作為商品的補充資訊,與Query Graph一樣的方式融合進網路(使用不同的Segment_id),但實驗發現效果不盡如人意,原因分析可能是閒魚商品在預測過程中,有不小佔比的商品集合為新品,該部分商品往往補充資訊不足。商品側引入其高點選Query,根據模型《Shortcut Learning in Deep Neural Networks》的論述,這裡模型容易走捷徑,過分關注 補充的Query資訊,對於缺失補充特徵的商品預測效果有偏。因此在離線HitRate指標表 現不好,線上也存在類似分佈不一致的問題。而換個思路補充相似商品資訊,也會存在類似 問題,因此該路徑未繼續深挖。
-
上述關鍵離線實驗對比
策略 |
AUC(相關性) |
[email protected]、5、10 |
online baseline model+dim=128 |
0.780 |
51.0、73.3、80.7 |
query+難樣本構造+dim=64 |
0.805 |
52.6、 76.8、 84.4 |
query+graph query+dim=64 |
0.790 |
50.5、 76.3、 84.4 |
query+graph query+難樣本構造+dim=64 |
0.804 |
55.2、 79.6、 86.6 |
query+graph query+難樣本構造+infonce loss+batch size=64 |
0.822 |
61.2、 83.9、 89.6 |
aph query+難樣本構造+infonce loss+batchsize=128 |
0.824 |
62.6、 84.7、90.1 |
線上工程方案
-
向量引擎
得益於強大的 Ha3 引擎,使得向量引擎的搭建變得容易了許多。在構建向量索引和使用向量引擎對外提供服務的過程中,需要注意以下的問題:
-
商品狀態的維護,包括商品的下線以及新商品的釋出。閒魚場景中的商品屬於孤品,通常商品被賣出或者下架後,將不能再被展示出來,這就要求商品在下架的同時能夠及時從索引中刪除;同樣,在閒魚平臺上,新商品的成交要比舊商品高,因此,新入庫商品需要能夠及時進入向量索引。
-
召回結果的過濾、統計、排序等操作。為了能提高向量召回結果的效率,需要將這些操作封裝到引擎中,使得召回的結果符合相關性等要求。
為了能夠同時滿足如上的需求,我們設計瞭如下的向量召回索引流程:
-
索引構建階段,分別搭建資料的批量和增量流程,並通過SARO(集團PB級資料處理能力以及秒級實時效能的大資料ETL平臺)統一管理
-
每天例行通過ODPS構建T+1全量的索引,使得每天的線上資料能夠及時同步;
-
每天的增量資料,如商品狀態的改變(如商品下線,價格更改等),新增商品,都會通過訊息流的形式傳遞給SARO,通過SARO對資料統一管理。
-
引擎查詢階段,得益於Ha3引擎的強大功能,通過scorer外掛、function外掛等對召回結果過濾、統計和排序
-
多路召回
在閒魚搜尋業務中,存在多個索引引擎,主要包括倒排引擎,即主引擎和優品引擎,在增加了向量引擎以及I2I引擎後,如何以最小的代價對鏈路改造多鏈路召回使其滿足整體RT的要求,我們設計瞭如下的多路召回流程:
在實現的過程中,採用的是如上的併發多路召回的方式,目前索引引擎的種類分為兩種,分別為Ha3引擎和KV引擎引擎。當前對於每一路引擎都是獨立的召回,通過設定不同的召回量控制每一路引擎的召回結果。
問題討論與優化方向
在上述基礎的語義向量召回基礎上,本季度我們也做了一些其他的嘗試,下面主要簡單描述嘗試的方案,以及階段性的結論分析:
-
增加個性化向量召回
向量召回的理想目標是檢索出“相關且高成交效率”的商品,而基於語義的向量召回更多的是考慮“相關”目標,“高成交效率”的目標則是在粗排/精排階段實現。如果能在召回階段就考慮成交效率,一步到位,應該是更加理想的狀態。
因此,我們也嘗試了主流的個性化向量的建模方案:
-
模型側:仍為DSSM架構,升級query tower變為user&query tower,item tower不變;
-
資料側:使用點選/成交user&query-item對為正樣本,曝光為點選/點選未成交的樣本為負樣本,同時增加隨機取樣負樣本;
-
特徵側:增加個性化特徵,如使用者畫像和行為特徵、商品和賣家維度的統計特徵等。
如上的改造期望使向量模型學習到個性化特徵,但結果是模型失去了“相關性”的度量能力(原因也容易想到,在正負樣本的構造過程中,“曝光未點選”的負樣本極大的可能是“相關”樣本),其實上述方案被叫做“雙塔粗排模型”更加貼切。
基於這個結論有兩條優化路徑:
-
在個性化向量召回過程中或過程後增加相關性策略(如類目、核心詞匹配),方案看上去可行,但回過頭來想,其實和使用“類目/核心詞召回,個性化向量粗排”差別不大,已經失去了向量召回的初衷,因此廢棄。
-
融合個性化和相關性向量,在召回階段兼顧二者目標,比較有代表性的工作如百度的《Mobius: Towards the next generation of query-ad matching in Baidu's sponsored search.》等,該部分方案是相對合理的解決方向,同樣也是後續的探索方向。
-
引入多模態
上述語義向量召回方案,並未考慮多模態資訊,集團也有很多工作,這裡也嘗試了類似方案,使用多模態bert強化item側的特徵,事實上離線指標也能得到一定程度提升,但相對地,其鏈路的也變得更重,對資源的消耗也急劇增加。綜合考慮下,當前線上主要還是使用文字模態。該方向仍需繼續探索,以兼顧鏈路的時效性以及資源的ROI。
-
關於相關性控制
閒魚搜尋滿意度和badcase率是一個比較嚴格的監測指標,而擴大召回勢必會增加badcase透出風險,依賴語義的向量召回更是如此,由於沒有嚴格的Term命中限制,不可避免地對一些query存在語義漂移現象,對於少見的長尾query更甚。
事實即是如此,在實踐過程中,僅使用語義向量召回,雖然成交效率可以取得可觀的提升,但badcase率也相應的急劇提升,這裡我們的解決方案也相對常規:
-
考慮到語義向量匹配分可以度量query-item相關性,但一刀切的方式卡匹配分閾值會收窄成交效率的收益,因此我們使用動態閾值方法對候選進行召回截斷,動態閾值通過離線query歷史行為統計得到;
-
增加query-item類目匹配限制;
-
增加核心term匹配限制,同時相容同義詞。
-
其他體感問題:不合理價格、虛標價格、站外引流等商品的過濾
如此經過一系列的調餐,達到了搜尋滿意度和badcase率指標的可接受程度的微跌,但卻損失2個點左右的人均買賣家效率指標(相對不做滿意度優化)。這個方向上,仍然有一部分優化空間,如更柔型的相關性控制(當前版本核心term匹配這裡限制的比較嚴格),更準確的語義向量表達等。相應的後續會從向量表徵和機制策略兩方面進行優化。
基於行為的I2I召回
當前召回個性化能力不足,對於不同使用者的相同query,召回相同的候選,召回截斷後可能損失更具個性化的相關商品。
建模目標
分析發現,使用者通過搜尋到詳情頁猜你喜歡,通過猜你喜歡場景成交的商品佔比可觀,通過case分析發現,該部分diff商品,靠常規的文字召回方法難以成功檢索到。一個參考統計資料,搜尋導流到猜你喜歡的點選PV裡 ,僅有約25%在當前query的召回集合中,也就是說有75%沒有被召回。如一個例子:搜尋引擎中檢索“迪卡儂優惠券”,返回結果量不足,而點選相關商品進入詳情頁猜你喜歡卻可以關聯處滿足需求的商品。
因此考慮直接通過I2I方法召回檢索池中的商品也會有一定的搜尋效率提升空間。
方案設計
而在搜尋場景下I2I實際上需要轉化為Q2I2I,因此該部分實驗可以分為兩個階段:
-
Q2I:通過使用者搜尋query,得到trigger item,該部分有兩種方式:1)直接通過當前query實時線上曝光的top item作為trigger商品;2)離線統計該query下歷史成交、點選、加購、詢單的item集合,線上請求query2trigger表。
-
I2I:trigger item到擴召回item的對映,這部分同樣有多種選擇:1)使用閒魚推薦或搜尋場景的i2i召回表;2)直接使用詳情頁猜你喜歡的曝光點選日誌表,構造I2I對映表,trigger為詳情頁主商品id。
通過以上兩個階段可以組合出Q2I2I的候選方案,最終通過AB test擇優選擇。使用上述方案,最優核心七日人均買賣家提升可以達到+4%的人均買賣家提升,人均成單相應漲幅有+5%。但相應的也伴隨著嚴重的相關性指標下跌的情況。如比較典型的,對於優惠券/會員充之類的query,個性化召回往往會出現比較明顯的發散性召回:
對此,我們將相關性的優化也分成了兩個階段,Query2trigger item的相關性,保證trigger item和query的相關性;I2I後,通過query與候選item的類目、核心詞以及語義匹配分過濾相關性。在維持相關性波動不大的情況下,最終實現七日+1.8%人均買賣家,人均成單+2.65%。可以看到嚴格的相關性限制,也縮小了成交效率的空間,也是後續的優化方向,如使用更加soft的相關性限制。
各AB收益對比
經過本季度搜索召回優化,核心指標上有了明顯的提升,推全時人均買賣家:近3日人均買賣家相對提升+4.66%;近7日人均買賣家相對提升+3.31%,人均成單:近3日人均成單+5.3%;近7日人均成單+4.02%;
其中,階段性的參考切割實驗對比:
-
向量召回:七日人均買賣家+2.25%,人均成單+2.69%;
-
行為I2I召回:七日人均買賣家+1.8%,人均成單+2.65%;
PS:參考主引擎等數量擴召回,七日人均買賣家+2.3%(未扣除相關性折損,即成交效率收益,損失相關性指標較嚴重。)相比之下,排除精排候選增多引入的不公平對比,擴召回優化的收益仍然可觀。
總結與展望
閒魚搜尋場景相對常規的電商場景有不小的差異,如商品上下架頻繁、整體庫存不足,各型別商品庫存分佈差異大、使用者query發散、商品型別發散等,賣家側也是盤踞著各種型別的使用者,自由閒置賣家、小專業賣家、黃牛賣家、“投機倒把”的中間商等,因此在演算法策略優化中需要考慮的細節較多,召回優化過程中也是如此。
而對於後續優化方向上,在上面的討論中其實也比較明確,總結一點即是召回效率與搜尋體感指標的trade off,如何在保證相關的前提下儘可能召回高成交效率的商品,將是一個長期探索的方向。
參考資源
2、Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A.N., Kaiser, L., Polosukhin, I.: Attention is all you need. In: NeurIPS (2017)
3、Mobius: Towards the next generation of query-ad matching in Baidu's sponsored search
4、Shortcut Learning in Deep Neural Networks
- Flutter富文字編輯器系列文章3——互動篇
- Flutter富文字編輯器系列文章3——互動篇
- 打造Flutter高效能富文字編輯器——渲染篇
- 節日獻禮:Flutter圖片庫重磅開源!
- 節日獻禮:Flutter圖片庫重磅開源!
- 關於閒魚測試資料構造,我有幾條心得
- 關於閒魚測試資料構造,我有幾條心得
- 打造Flutter高效能富文字編輯器——協議篇
- 打造Flutter高效能富文字編輯器——協議篇
- 閒魚前端技術體系的背後——魔魚(良心推薦,從思路到實踐)
- 閒魚如何保障交易鏈路質量
- Flutter 音影片開發的新思路
- 實效性與準確性的背後:多系統資料聚合展示
- Flutter滑動體驗對齊原生-滑動曲線篇
- 閒魚搜尋-成交寬度優化實踐
- 閒魚策略中樞業務擴充套件模組實現
- 閒魚互動玩法標準化建設
- 一條慢SQL引發的改造
- Flutter切面的應用與擴充套件
- 程式設計師如何保持學習成長?