廣告索引(定向)的布爾表達式
在搜索領域,索引是一項非常重要的技術,直接影響到查詢的效率,其基本的流程是:文章先進行分詞、計算權重,然后利用詞和文檔的信息建立倒排索引,在查詢的時候,得到符合條件的文檔的id集合,然后利用正排索引返回文檔的詳細信息。
在計算廣告中,廣告主通常會定義廣告投放的條件,例如下面有3個廣告,每個廣告都有自己的定向條件
如果此時有一個用戶來訪問(后面稱為query ),該用戶的畫像如上面藍色部分。那么這3個 ad 應該給她返回哪個更合理呢?
我們可以把這個用戶每個維度的特征去與每個 ad 進行匹配,會發現只有 ad3 的定向投放條件都符合。
實際的廣告平台可能有幾十萬條廣告,就需要一個方案來高效檢索符合給當前請求的用戶投放的廣告。
布爾表達式檢索
基本概念
- Conjunction,表示一個廣告的定向條件;
- Assignment,表示定向條件中的一個維度;
- sizeof(Conjunction),Conjunction 中包含的 Assignment 數量;
用 Conjunction 表示某條廣告的廣告主的要求的一類人群。
例如上面的 ad1 的 Conjunction:
age ∈ { 18-29 } ∧ region ∈ { BJ } ∧ network ∈ { WIFI }
這里符號 ∈ 是屬於,∉ 是不屬於,∧ 是交, ∨ 是並;
用 Assignment 表示一個維度,例如上面 ad1 的 Conjunction包括如下Assignment
-
age ∈ { 18-29 }
-
region ∈ { BJ }
-
network ∈ { WIFI }
最后,說下 sizeof(Conjunction) 是指 conjunction 中包含非∉ 的Assignment的個數。
兩層倒排
廣告的倒排索引包括兩層:
- 第一層索引:ConjunctionId -> AdIds,不同的廣告可能有相同的 ConjunctionId;
- 第二層索引:Assignment -> ConjunctionIds,不同的 ConjunctionId 可能包含相同的 Assignment;
當一個用戶的請求(query)來之后,我們需要把query的所有維度去 第一層索引 找出所有符合的 ConjunctionIds(這里求交),然后再去 第二層索引 召回廣告(這里求並);
這里可以利用 Assignment 約束: 如果 sizeof(query) < sizeof(Conjunction) , 則檢索時可以跳過該Conjunction(因為該query肯定不滿足該廣告的所有定向條件)。
回到前面的例子,ad1 - ad3 的第一層索引:
第二層索引:
可以看到,這里年齡可以切成多個key。
另外,利用上面說的 Assignment 約束規則,第二層索引還可以按照 sizeof(Conjunction) 分成若干部分,提高檢索效率。如下圖:
此時,如果請求的 sizeof(query) = 2,那么 sizeof(Conjunction) > 2 的 Key(Assignment) 可以直接跳過不用檢索。
再來看請求側:
檢索過程:
這里,query中的“網絡”這個維度沒有結果,但沒關系,其它 Assignment 都有結果,接下來就是看如何匹配了。
為了提高檢索效率,在第二層索引,一般遵守如下規則:
- 每個key對應的倒排鏈表(Posting list)內部 entry 按升序排列;
- 具有相同 sizeof(Conjunction) 的 Posting list 之間,按照Posting list 中第一個 Entry 按升序排列;
我們看下上面檢索的結果, 按上面的規則排序后:
先將每個 Posting list 內部entry排序,然后不停 Posting list 按其第一個 entry (即 Conjunction=1 )排序,可以得到:
這里我們看下 1 這個 entry,只出現了一次,顯然不匹配(需要出現在3個key 中才滿足所有定向條件);
接下來,每個Posting list 按第2個 entry(即 Conjunction=2 )排序:
第2個 entry出現了2次,也不滿足sizeof(Conjunction)=3 的條件;
繼續對 第3個 entry(即 Conjunction=3 ) 排序,
第3個entry出現了3次,條件匹配,可以作為定向結果返回。
如上檢索過程,對於 sizeof 為 k 的 Conjunction,需要出現在 k 個Posting list中。
反向定向
假如有一個廣告的定向條件是:
性別 ∉ { 女 } ∧ 年齡 ∈ { 26-29 } ∧ 興趣 ∈ { 時尚 }
這個Conjunction的第二層索引結構如下,
這里把它放到 size=2 的部分,前面提到 ∉ 的 Assignment 不算到 sizeof(Conjunction) 中。
另外,這里用 -4 來表示這個是負定向,在檢索的時候,除了滿足對於 sizeof 為 k 的 Conjunction,需要出現在 k 個Posting list中,還要滿足 conjunction id 不能出現在排除屬性對應的 posting list 中。
把 conjunction id = 4 與前面3個廣告一起看下索引結構:
時間復雜度
O(log(|S|)×|C|×Pavg)
其中:
- S,請求中 Assignment 個數,即 sizeof(query);
- C,Conjunctions 個數;
- Pavg,Conjunctions 中∈ 和 ∉ 的語句的平均數;