推薦-基於bandit的主題冷啓動在線學習策略

                  推薦-基於bandit的主題冷啓動在線學習策略

推薦系統裏面有兩個經典問題:EE問題和冷啓動問題。

什麼是EE問題?又叫exploit-explore問題。exploit就是:對用戶比較確定的興趣,當然要利用開採迎合,好比說已經掙到的錢,當然要花;explore就是:光對着用戶已知的興趣使用,用戶很快會膩,所以要不斷探索用戶新的興趣纔行,這就好比雖然有一點錢可以花了,但是還得繼續搬磚掙錢,不然花完了就得喝西北風。

除了bandit算法之外,還有一些其他的explore的辦法,比如:在推薦時,隨機地去掉一些用戶歷史行爲(特徵)。

0 Beta分佈

但是我發現Beta分佈就很少會用這樣可以憑直覺感知的方法來解釋它的用處在哪裏,而且Beta分佈經常會和一些複雜的概念一起出現,比如“共軛先驗”和“順序統計量”。

我們預期這個運動員一個賽季的擊球率大約是0.27,但在0.21到0.35之間都是合理的。這種情況可以用一個參數α=81和 β=219的Beta分佈來表示:

這裏寫圖片描述

x軸代表的是他的擊球率。因此請注意在這個實例當中,不僅y軸是概率(或者更準確地說是概率密度),x軸也是(擊球率就是一次擊球擊中的概率)。這個Beta分佈表示了一個概率的概率分佈。

  • 平均數(期望)是α/(α+β)=81/(81+219)=0.270
  • 這個分佈幾乎全部分佈在(0.2,0.35)這個範圍之間,也就是擊球率的合理範圍。

β分佈的形狀取決於α和β的值。貝葉斯分析中大量使用了β分佈。

當你將參數α和β都設置爲1時,該分佈又被稱爲均勻分佈(uniform distribution)。嘗試不同的α和β取值,看看分佈的形狀是如何變化的。
當然,從該分佈來看,beta.pdf(x,a,b)中除了a,b兩個數字參數之外,還有x表徵的概率因素在其中。這裏x,相當於模擬了不同概率條件下,概率密度的走勢,所以橫軸是可以代表概率值,概率函數最大值(y的最大值)也代表概率最大值(x最大值)。
 

參考:
直觀理解Beta分佈
如何在Python中實現這五類強大的概率分佈

 

1 bandit介紹

主要來源:《Bandit算法與推薦系統》,首發於《程序員》雜誌

1.1 bandit簡介

bandit算法是一種簡單的在線學習算法,常常用於嘗試解決這兩個問題。
bandit算法來源於歷史悠久的賭博學,它要解決的問題是這樣的:
一個賭徒,要去搖老虎機,走進賭場一看,一排老虎機,外表一模一樣,但是每個老虎機吐錢的概率可不一樣,他不知道每個老虎機吐錢的概率分佈是什麼,那麼每次該選擇哪個老虎機可以做到最大化收益呢?這就是多臂賭博機問題(Multi-armed bandit problem, K-armed bandit problem, MAB)。
這裏寫圖片描述

衡量不同bandit算法在解決多臂問題上的效果?首先介紹一個概念,叫做累積遺憾(regret):這裏我們討論的每個臂的收益非0即1,也就是伯努利收益。定義累積遺憾(regret) :

這裏寫圖片描述

然後,每次選擇後,計算和最佳的選擇差了多少,然後把差距累加起來就是總的遺憾。

1.2 常用的bandit算法——Thompson sampling算法

Thompson sampling算法:假設每個臂是否產生收益,其背後有一個概率分佈,產生收益的概率爲p。每次選擇臂的方式是:用每個臂現有的beta分佈產生一個隨機數b,選擇所有臂產生的隨機數中最大的那個臂去搖。

1.3 常用的bandit算法——UCB算法

這個公式反映一個特點:均值越大,標準差越小,被選中的概率會越來越大,同時哪些被選次數較少的臂也會得到試驗機會。

1.4 常用的bandit算法——Epsilon-Greedy算法

有點類似模擬退火的思想:

選一個(0,1)之間較小的數作爲epsilon
每次以概率epsilon做一件事:所有臂中隨機選一個
每次以概率1-epsilon 選擇截止到當前,平均收益最大的那個臂。
是不是簡單粗暴?epsilon的值可以控制對Exploit和Explore的偏好程度。越接近0,越保守,只想花錢不想掙錢。

1.5 常用的bandit算法——樸素bandit算法

最樸素的bandit算法就是:先隨機試若干次,計算每個臂的平均收益,一直選均值最大那個臂。這個算法是人類在實際中最常採用的,不可否認,它還是比隨機亂猜要好。

把幾個模型的結果,進行10000次模型。可得以下的圖:

這裏寫圖片描述

2 bandit的延伸應用與模型

2.1 bandit算法與線性迴歸

**UCB解決Multi-armed bandit問題的思路是:用置信區間。**置信區間可以簡單地理解爲不確定性的程度,區間越寬,越不確定,反之亦反之。UCB算法加入特徵信息,單純的老虎機回報情況就是老虎機自己內部決定的,而在廣告推薦領域,一個選擇的回報,是由User和Item一起決定的,如果我們能用feature來刻畫User和Item這一對CP,在每次選擇item之前,通過feature預估每一個arm(item)的期望回報及置信區間,選擇的收益就可以通過feature泛化到不同的item上。
LinUCB算法有一個很重要的步驟,就是給User和Item構建特徵:

原始用戶特徵

  • 人口統計學:性別特徵(2類),年齡特徵(離散成10個區間)
  • 地域信息:遍佈全球的大都市,美國各個州
  • 行爲類別:代表用戶歷史行爲的1000個類別取值

原始文章特徵

  • URL類別:根據文章來源分成了幾十個類別
  • 編輯打標籤:編輯人工給內容從幾十個話題標籤中挑選出來的
     

2.2 bandit算法與協同過濾

每一個推薦候選item,都可以根據用戶對其偏好不同(payoff不同)將用戶聚類成不同的羣體,一個羣體來集體預測這個item的可能的收益,這就有了協同的效果,然後再實時觀察真實反饋回來更新用戶的個人參數,這就有了bandit的思想在裏面。
另外,如果要推薦的候選item較多,還需要對item進行聚類,這樣就不用按照每一個item對user聚類,而是按照每一個item的類簇對user聚類,如此以來,item的類簇數相對於item數要大大減少。

COFIBA算法
基於這些思想,有人提出了算法COFIBA(讀作coffee bar)13,簡要描述如下:
在時刻t,用戶來訪問推薦系統,推薦系統需要從已有的候選池子中挑一個最佳的物品推薦給他,然後觀察他的反饋,用觀察到的反饋來更新挑選策略。 這裏的每個物品都有一個特徵向量,所以這裏的bandit算法是context相關的。 這裏依然是用嶺迴歸去擬合用戶的權重向量,用於預測用戶對每個物品的可能反饋(payoff),這一點和linUCB算法是一樣的。
對比LinUCB算法,COFIBA算法的不同有兩個:

  • 基於用戶聚類挑選最佳的item(相似用戶集體決策的bandit)
  • 基於用戶的反饋情況調整user和item的聚類(協同過濾部分)

也就是user(人羣聚類)、item(主題聚類)雙料聚類。

3 python實現bandit在線學習策略

之前提到的幾個code可在github之中看到:

筆者簡單的基於常規bandit算法進行了一些嘗試。

3.1 幾款bandit常規模型的評估

code可見:anonymous/bandit_simulations.py

之前code主要是,輸入了5個主題(K)下的10000個樣本(num_samples ),迭代了100次(number_experiments )。

true_rewards抽取了單個樣本來看,就是五個主題裏面,第1,4個被提及了,其餘的沒有被提及。

array([[ True, False, False,  True, False]])

CTRs_that_generated_data 點擊可能性是用來評估regretrun_bandit_dynamic_alg函數輸出的是,該模型下,該次迭代的regret值。

'''
main code
'''
# define number of samples and number of choices
num_samples = 10000
K = 5 # number of arms
number_experiments = 100

regret_accumulator = np.zeros((num_samples,5))
for i in range(number_experiments):
	# 五套算法各自迭代100次的累加regret
    print ("Running experiment:", i+1)
    true_rewards,CTRs_that_generated_data = generate_bernoulli_bandit_data(num_samples,K)
    regret_accumulator[:,0] += run_bandit_dynamic_alg(true_rewards,CTRs_that_generated_data,random)# (10000,)
    regret_accumulator[:,1] += run_bandit_dynamic_alg(true_rewards,CTRs_that_generated_data,naive)
    regret_accumulator[:,2] += run_bandit_dynamic_alg(true_rewards,CTRs_that_generated_data,epsilon_greedy)
    regret_accumulator[:,3] += run_bandit_dynamic_alg(true_rewards,CTRs_that_generated_data,UCB)
    regret_accumulator[:,4] += run_bandit_dynamic_alg(true_rewards,CTRs_that_generated_data,UCB_bernoulli)
    
plt.semilogy(regret_accumulator/number_experiments)  # (10000, 5) / 100
plt.title('Simulated Bandit Performance for K = 5')
plt.ylabel('Cumulative Expected Regret')
plt.xlabel('Round Index')
plt.legend(('Random','Naive','Epsilon-Greedy','(1 - 1/t) UCB','95% UCB'),loc='lower right')
plt.show()

輸出的結果即爲:

這裏寫圖片描述

regret最大代表誤差越大,這邊筆者的實驗室UCB優先級高一些。

3.2 基於bandit的主題冷啓動強化策略

首輪純冷啓動,會主動推給用戶隨機的10個主題樣例,獲得前期樣本; 後進行迭代操作。
這邊筆者在模擬實際情況,譬如在做一個新聞推薦的內容,需要冷啓動。
假設該新聞平臺主要有五個主題['news','sports','entertainment','edu','tech'],需要以主題推送給不同的用戶。

3.2.1 第一輪冷啓動

那麼,假設筆者自己去看,一開始系統先隨機推送10次內容於首頁,看這些文章內容哪些被點擊了,然後整理成變量top10 。那麼,這裏的意思就是,筆者打開APP的頭10次,都是隨機推送了,然後第一次,我點擊了‘sports’,'edu'兩個主題的內容,即被記錄下來,這麼模擬操作了10次。
 

topics = ['news','sports','entertainment','edu','tech']
top10 = [['sports','edu'],['tech','sports'],['tech','entertainment','edu'],['entertainment'],['sports','tech','sports']
         ,['edu'],['tech','news'],['tech','entertainment'],['tech'],['tech','edu']]

以上的內容進入bandit進行策略優化:

# generator data
true_rewards = generate_bandit_data(top10,topics)
# bandit model
estimated_beta_params = mBandit(true_rewards,UCB)
print('Cold boot ...')
prob1 = BanditProbs(estimated_beta_params,topics,printf = True,plotf = True)

其中的主題概率得分爲:

【news】 topic prob is : 0.01
【sports】 topic prob is : 0.5
【entertainment】 topic prob is : 0.5
【edu】 topic prob is : 0.5
【tech】 topic prob is : 0.99

結果顯示,進行了10次初始嘗試,筆者對tech科技主題的偏好非常高,遠遠高於其他主題。

這裏寫圖片描述

3.2.2 第二輪迭代

那麼有了第一輪10次的基本經驗,在這上面繼續迭代。迭代的邏輯是:筆者接下來看一條,就會記錄一條,導入模型進行迭代計算。

topic_POI = [['edu','news']]

true_rewards = generate_bandit_data(topic_POI,topics)
estimated_beta_params = mBandit(true_rewards,UCB,beta_params = estimated_beta_params)  # 加載之前的內容
print(estimated_beta_params)
print(' second start. ...')
prob2 = BanditProbs(estimated_beta_params,topics,printf = True,plotf = True)

來看一張胡亂迭代了很多輪之後的圖:

這裏寫圖片描述

可以看到有兩個高峯,是sports主題以及edu主題。

【news】 topic prob is : 0.01
【sports】 topic prob is : 0.8300000000000001
【entertainment】 topic prob is : 0.33
【edu】 topic prob is : 0.89
【tech】 topic prob is : 0.6

【參考】:
Bandit算法與推薦系統
bandit算法原理及Python實現
推薦系統的EE問題及Bandit算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章