paint-brush
Takviyeli Öğrenmede Bağlamsal Çok Silahlı Haydut Sorunlarıile@teenl0ve
8,942 okumalar
8,942 okumalar

Takviyeli Öğrenmede Bağlamsal Çok Silahlı Haydut Sorunları

ile Valentine Shkulov13m2023/07/29
Read on Terminal Reader
Read this story w/o Javascript

Çok uzun; Okumak

Bu makale, ödülün bağlama bağlı olduğu, takviyeli öğrenmede bağlam temelli çok kollu eşkıya sorunlarına dalmaktadır. Bu sorunları çözmek için üç farklı algoritmayı tartıştık ve uyguladık: LinUCB, Karar Ağaçları ve Sinir Ağları, bunların benzersiz güçlü yönlerini ve dikkate alınması gereken noktaları vurguladık. Performanslarını açıkça karşılaştırmamış olsak da, elimizdeki problemin özelliklerine göre doğru yaklaşımı seçmenin önemini vurguladık.
featured image - Takviyeli Öğrenmede Bağlamsal Çok Silahlı Haydut Sorunları
Valentine Shkulov HackerNoon profile picture
0-item
1-item
2-item
3-item

Bağlamsal haydutlar, öğrencinin en fazla ödülle sonuçlanan eylemleri seçmesi gereken karar verme modellerinde kullanılan bir takviyeli öğrenme algoritmaları sınıfıdır. Adlarını, oyuncunun hangi slot makinelerinde oynayacağına, her makineyi kaç kez oynayacağına ve bunları hangi sırayla oynayacağına karar vermesi gereken klasik "tek kollu haydut" kumar probleminden almıştır.

https://towardsdatascience.com/contextual-bandits-and-reinforcement-learning-6bdfeaece72a


Bağlamsal haydutları diğerlerinden ayıran şey, karar verme sürecinin bağlam tarafından bilgilendirilmesidir. Bu durumda bağlam, eylemin sonucunu etkileyebilecek bir dizi gözlemlenebilir değişkeni ifade eder. Bu ekleme, haydut sorununu, kararın belirli koşullara bağlı olduğu kişiselleştirilmiş öneriler, klinik araştırmalar veya reklam yerleştirme gibi gerçek dünya uygulamalarına yaklaştırıyor.

Bağlamsal Eşkıya Sorunlarının Formülasyonu

Bağlamsal haydut problemi çeşitli algoritmalar kullanılarak uygulanabilir. Aşağıda, bağlamsal haydut sorunlarına yönelik algoritmik yapının üst düzey genel bir özetini sunuyorum:

Ve aşağıdaki algoritma, bağlamsal haydut sorununun altında yatan matematiği gösteriyor:

Yukarıdakilerin hepsini özetlemek gerekirse, genel anlamda algoritmanın amacı, belirli bir zaman diliminde kümülatif ödülü en üst düzeye çıkarmaktır. Her turda yalnızca seçilen eylemin ödülünün gözlemlendiğini unutmayın. Bu, haydut sorunlarını denetimli öğrenmeden ayıran kısmi geri bildirim olarak bilinir.


Bağlamsal bir haydut sorununu çözmek için en yaygın yaklaşım, keşif ve sömürünün dengelenmesini içerir. Kullanım, en iyi kararı vermek için mevcut bilgiyi kullanmak anlamına gelirken keşif, daha fazla bilgi toplamak için daha az kesin eylemde bulunmayı içerir.


Keşif ve kullanım arasındaki denge, Bağlamsal Haydut sorununu çözmek için tasarlanan LinUCB, Neural Bandit veya Decision Tree Bandit gibi çeşitli algoritmalarda kendini gösterir. Bu algoritmaların tümü, bu ödünleşimi ele almak için kendi benzersiz stratejilerini kullanır.


Bu fikrin Bandit için kod temsili şöyledir:

 class Bandit: def __init__(self, n_actions, n_features): self.n_actions = n_actions self.n_features = n_features self.theta = np.random.randn(n_actions, n_features) def get_reward(self, action, x): return x @ self.theta[action] + np.random.normal() def get_optimal_reward(self, x): return np.max(x @ self.theta.T) # Usage example # Define the bandit environment n_actions = 10 n_features = 5 bandit = Bandit(n_actions, n_features) # Define the model agent model_agent = model(n_features, *args) # Define the context (features) x = np.random.randn(n_features) # The agent makes a prediction pred_rewards = np.array([model_agent.predict(x) for _ in range(n_actions)]) # The agent chooses an action action = np.argmax(pred_rewards) # The agent gets a reward reward = bandit.get_reward(action, x) # The agent updates its parameters model_agent.update(x, reward)

LinUCB Algoritması

LinUCB algoritması, bir bağlam verilen bir eylemin beklenen ödülünü doğrusal bir işlev olarak modelleyen bağlamsal bir haydut algoritmasıdır ve keşif ve kullanım arasında denge kurmak için Üst Güven Sınırı (UCB) ilkesine dayalı eylemleri seçer. Mevcut modele göre (doğrusal bir model olan) mevcut en iyi seçeneği kullanır, ancak aynı zamanda modelin tahminlerindeki belirsizliği göz önünde bulundurarak potansiyel olarak daha yüksek ödüller sağlayabilecek seçenekleri de araştırır. Matematiksel olarak şu şekilde sunulabilir:

Bu yaklaşım, algoritmanın yüksek belirsizliğe sahip olduğu eylemleri keşfetmesini sağlar.


Bir eylem seçtikten ve bir ödül aldıktan sonra LinUCB, parametreleri aşağıdaki gibi günceller:

Ve işte Python'daki kod uygulaması:

 import numpy as np class LinUCB: def __init__(self, n_actions, n_features, alpha=1.0): self.n_actions = n_actions self.n_features = n_features self.alpha = alpha # Initialize parameters self.A = np.array( [np.identity(n_features) for _ in range(n_actions)] ) # action covariance matrix self.b = np.array( [np.zeros(n_features) for _ in range(n_actions)] ) # action reward vector self.theta = np.array( [np.zeros(n_features) for _ in range(n_actions)] ) # action parameter vector def predict(self, context): context = np.array(context) # Convert list to ndarray context = context.reshape( -1, 1 ) # reshape the context to a single-column matrix p = np.zeros(self.n_actions) for a in range(self.n_actions): theta = np.dot( np.linalg.inv(self.A[a]), self.b[a] ) # theta_a = A_a^-1 * b_a theta = theta.reshape(-1, 1) # Explicitly reshape theta p[a] = np.dot(theta.T, context) + self.alpha * np.sqrt( np.dot(context.T, np.dot(np.linalg.inv(self.A[a]), context)) ) # p_t(a|x_t) = theta_a^T * x_t + alpha * sqrt(x_t^T * A_a^-1 * x_t) return p def update(self, action, context, reward): self.A[action] += np.outer(context, context) # A_a = A_a + x_t * x_t^T self.b[action] += reward * context # b_a = b_a + r_t * x_tx

Karar Ağacı Algoritması

Karar Ağacı Bandit, ödül fonksiyonunu bir karar ağacı olarak modeller; burada her yaprak düğümü bir eyleme karşılık gelir ve kökten yaprak düğüme giden her yol, bağlama dayalı bir karar kuralını temsil eder. İstatistiksel bir çerçeve aracılığıyla keşif ve kullanım gerçekleştirir, istatistiksel anlamlılık testlerine dayalı olarak karar ağacında bölmeler ve birleştirmeler yapar.

Amaç, beklenen kümülatif ödülü maksimuma çıkaran en iyi karar ağacını öğrenmektir:

Karar ağacı öğrenimi genellikle iki adımdan oluşur:

  1. Ağaç Büyütme : Tek bir düğümle (kök) başlayarak, her düğümü, beklenen ödülü en üst düzeye çıkaran bir özelliğe ve eşiğe göre yinelemeli olarak bölün. Bu işlem, maksimum derinliğe veya yaprak başına minimum numune sayısına ulaşmak gibi bir durdurma koşulu karşılanıncaya kadar devam eder.
  2. Ağaç Budama : Tamamen büyümüş ağaçtan başlayarak, beklenen ödülü önemli ölçüde artırıyor veya azaltmıyorsa, her düğümün çocuklarını yinelemeli olarak birleştirin. Bu işlem daha fazla birleştirme yapılamayana kadar devam eder.


Bölme kriteri ve birleştirme kriteri genellikle iyileştirmenin istatistiksel anlamlılığını sağlamak için istatistiksel testlere dayalı olarak tanımlanır.

 from sklearn.tree import DecisionTreeRegressor class DecisionTreeBandit: def __init__(self, n_actions, n_features, max_depth=5): self.n_actions = n_actions self.n_features = n_features self.max_depth = max_depth # Initialize the decision tree model for each action self.models = [ DecisionTreeRegressor(max_depth=self.max_depth) for _ in range(n_actions) ] self.data = [[] for _ in range(n_actions)] def predict(self, context): return np.array( [self._predict_for_action(a, context) for a in range(self.n_actions)] ) def _predict_for_action(self, action, context): if not self.data[action]: return 0.0 X, y = zip(*self.data[action]) self.models[action].fit(np.array(X), np.array(y)) context_np = np.array(context).reshape( 1, -1 ) # convert list to NumPy array and reshape return self.models[action].predict(context_np)[0] def update(self, action, context, reward): self.data[action].append((context, reward))

DecisionTreeBandit için predict yöntemi, belirli bir bağlamda her eylem için beklenen ödülü tahmin etmek amacıyla mevcut model parametrelerini kullanır. update yöntemi, seçilen eylemden gözlemlenen ödüle dayalı olarak model parametrelerini günceller. Bu uygulama DecisionTreeBandit için scikit-learn kullanıyor.

Sinir Ağlarıyla Bağlamsal Haydutlar

Yüksek boyutlu veya doğrusal olmayan durumlarda ödül fonksiyonuna yaklaşmak için derin öğrenme modelleri kullanılabilir. Politika tipik olarak bağlamı ve mevcut eylemleri girdi olarak alan ve her eylemin gerçekleştirilme olasılığının çıktısını veren bir sinir ağıdır.


Popüler bir derin öğrenme yaklaşımı, bir ağın (aktör) hangi eylemin gerçekleştirileceğine karar verdiği ve diğer ağın (eleştirmen) aktör tarafından gerçekleştirilen eylemi değerlendirdiği aktör-eleştirmen mimarisini kullanmaktır.


Bağlam ile ödül arasındaki ilişkinin doğrusal olmadığı daha karmaşık senaryolarda ödül fonksiyonunu modellemek için bir sinir ağı kullanabiliriz. Popüler yöntemlerden biri, REINFORCE veya aktör eleştirmeni gibi bir politika gradyanı yöntemi kullanmaktır.


Aşağıdaki özetlemek gerekirse Neural Bandit, sinir ağının parametrelerindeki belirsizliği hesaba katarak ödül fonksiyonunu modellemek için sinir ağlarını kullanır. Ayrıca, politikayı daha yüksek ödüller yönünde güncellediği politika değişimleri aracılığıyla keşif sunar. Bu tür bir keşif daha yönlendirilmiş olup, geniş eylem alanlarında faydalı olabilir.


En basit kod uygulaması şudur:

 import torch import torch.nn as nn import torch.optim as optim class NeuralNetwork(nn.Module): def __init__(self, n_features): super(NeuralNetwork, self).__init__() self.layer = nn.Sequential( nn.Linear(n_features, 32), nn.ReLU(), nn.Linear(32, 1) ) def forward(self, x): return self.layer(x) class NeuralBandit: def __init__(self, n_actions, n_features, learning_rate=0.01): self.n_actions = n_actions self.n_features = n_features self.learning_rate = learning_rate # Initialize the neural network model for each action self.models = [NeuralNetwork(n_features) for _ in range(n_actions)] self.optimizers = [ optim.Adam(model.parameters(), lr=self.learning_rate) for model in self.models ] self.criterion = nn.MSELoss() def predict(self, context): context_tensor = torch.tensor(context, dtype=torch.float32) # Convert to tensor with torch.no_grad(): return torch.cat( [model(context_tensor).reshape(1) for model in self.models] ) def update(self, action, context, reward): self.optimizers[action].zero_grad() context_tensor = torch.tensor(context, dtype=torch.float32) # Convert to tensor reward_tensor = torch.tensor(reward, dtype=torch.float32) # Convert to tensor pred_reward = self.models[action](context_tensor) loss = self.criterion(pred_reward, reward_tensor) loss.backward() self.optimizers[action].step()

NeuralBandit için, bir bağlam verilen her eylem için beklenen ödülü tahmin etmek üzere mevcut model parametrelerini kullanan ve seçilen eylemden gözlemlenen ödüle dayalı olarak model parametrelerini güncelleyen, predict yöntemi ve update yöntemiyle aynı resim. Bu uygulama NeuralBandit için PyTorch'u kullanıyor.

Modellerin karşılaştırmalı performansı

Her modelin kendine özgü avantajları ve dezavantajları vardır ve model seçimi, eldeki problemin özel gereksinimlerine bağlıdır. Bu modellerden bazılarının özelliklerine bakalım ve ardından performanslarını karşılaştıralım.

LinUCB

Doğrusal Üst Güven Sınırı (LinUCB) modeli, belirli bir bağlamda her eylem için beklenen ödülü tahmin etmek amacıyla doğrusal regresyon kullanır. Ayrıca bu tahminlerin belirsizliğini de takip ediyor ve bunu araştırmayı teşvik etmek için kullanıyor.


Avantajları:

  • Basit ve hesaplama açısından verimlidir.

  • Pişmanlık sınırına teorik garantiler sağlar.


Dezavantajları:

  • Ödül fonksiyonunun, daha karmaşık problemler için geçerli olmayabilecek bağlam ve eylemin doğrusal bir fonksiyonu olduğunu varsayar.

Karar Ağacı Haydutu

Karar Ağacı Haydut modeli, ödül fonksiyonunu bir karar ağacı olarak temsil eder. Her yaprak düğüm bir eyleme karşılık gelir ve kökten yaprak düğüme giden her yol, bağlama dayalı bir karar kuralını temsil eder.


Avantajları:

  • Yorumlanabilir karar kuralları sağlar.

  • Karmaşık ödül işlevlerini yerine getirebilir.


Dezavantajları:

  • Özellikle büyük ağaçlarda aşırı uyum sorunu yaşanabilir.
  • Ağacın maksimum derinliği gibi hiperparametrelerin ayarlanmasını gerektirir.

Sinirsel Haydut

Sinir Haydut modeli, belirli bir bağlamda her eylem için beklenen ödülü tahmin etmek için bir sinir ağı kullanır. Keşfi teşvik etmek için politika eğimi yöntemlerini kullanır.


Avantajları:

  • Karmaşık, doğrusal olmayan ödül fonksiyonlarını yönetebilir.

  • Geniş aksiyon alanlarında faydalı olan yönlendirilmiş keşif gerçekleştirebilir.


Dezavantajları:

  • Sinir ağının mimarisi ve öğrenme hızı gibi hiperparametrelerin ayarlanmasını gerektirir.
  • Özellikle büyük ağlar ve geniş eylem alanları için hesaplama açısından pahalı olabilir.

Kod karşılaştırması ve genel çalışma örneği:

İşte, daha önce bahsedilen ve tanımlanan tüm bu modellerin haydutlarının performanslarını, her model için bir simülasyon çalıştırarak karşılaştırmak için Python kodu.

 import matplotlib.pyplot as plt # Define the bandit environment n_actions = 10 n_features = 5 bandit = Bandit(n_actions, n_features) # Define the agents linucb_agent = LinUCB(n_actions, n_features, alpha=0.1) neural_agent = NeuralBandit(n_actions, n_features, learning_rate=0.01) tree_agent = DecisionTreeBandit(n_actions, n_features, max_depth=5) # Run the simulation for each agent n_steps = 1000 agents = [linucb_agent, tree_agent, neural_agent] cumulative_rewards = {agent.__class__.__name__: np.zeros(n_steps) for agent in agents} cumulative_regrets = {agent.__class__.__name__: np.zeros(n_steps) for agent in agents} for agent in agents: print(agent) for t in range(n_steps): x = np.random.randn(n_features) pred_rewards = agent.predict([x]) action = np.argmax(pred_rewards) reward = bandit.get_reward(action, x) optimal_reward = bandit.get_optimal_reward(x) agent.update(action, x, reward) cumulative_rewards[agent.__class__.__name__][t] = ( reward if t == 0 else cumulative_rewards[agent.__class__.__name__][t - 1] + reward ) cumulative_regrets[agent.__class__.__name__][t] = ( optimal_reward - reward if t == 0 else cumulative_regrets[agent.__class__.__name__][t - 1] + optimal_reward - reward ) # Plot the results plt.figure(figsize=(12, 6)) plt.subplot(121) for agent_name, rewards in cumulative_rewards.items(): plt.plot(rewards, label=agent_name) plt.xlabel("Steps") plt.ylabel("Cumulative Rewards") plt.legend() plt.subplot(122) for agent_name, regrets in cumulative_regrets.items(): plt.plot(regrets, label=agent_name) plt.xlabel("Steps") plt.ylabel("Cumulative Regrets") plt.legend() plt.show() 

Uygulama Senaryoları

  1. Kişiselleştirilmiş Öneri : Bu senaryoda bağlam, kullanıcı bilgileri (yaş, cinsiyet, geçmiş satın alma işlemleri gibi) ve ürün bilgileri (ürün kategorisi, fiyat gibi) olabilir. Eylemler tavsiye edilecek öğelerdir ve ödül, kullanıcının öğeyi tıklayıp tıklamadığı veya satın alıp almadığıdır. Tıklama oranını veya geliri en üst düzeye çıkaran kişiselleştirilmiş bir öneri politikasını öğrenmek için bağlamsal bir haydut algoritması kullanılabilir.
  2. Klinik Araştırmalar : Klinik araştırmalarda bağlam hasta bilgileri (yaş, cinsiyet, tıbbi geçmiş gibi) olabilir, eylemler farklı tedavilerdir ve ödül de sağlık sonuçlarıdır. Bağlamsal bir haydut algoritması, tedavinin etkisini ve yan etkilerini dengeleyerek hastanın sağlık sonucunu en üst düzeye çıkaran bir tedavi politikasını öğrenebilir.
  3. Çevrimiçi Reklamcılık : Çevrimiçi reklamcılıkta bağlam, kullanıcı bilgileri ve reklam bilgileri olabilir, eylemler görüntülenecek reklamlardır ve ödül, kullanıcının reklamı tıklayıp tıklamadığıdır. Bağlamsal bir haydut algoritması, reklam alaka düzeyini ve kullanıcı tercihlerini göz önünde bulundurarak tıklama oranını veya geliri en üst düzeye çıkaran bir politika öğrenebilir.


Bu uygulamaların her birinde, keşif ve kullanım arasında denge kurmak çok önemlidir. Kullanım, mevcut bilgiye dayanarak en iyi eylemi seçmektir, keşif ise daha fazla bilgi edinmek için farklı eylemleri denemektir. Bağlamsal haydut algoritmaları, bu keşif-sömürü değiş tokuşunu resmileştirmek ve çözmek için bir çerçeve sağlar.

Çözüm

Bağlamsal haydutlar, geri bildirimin sınırlı olduğu ortamlarda karar vermede güçlü bir araçtır. Karar vermede bağlamı kullanma yeteneği, geleneksel haydut algoritmalarından daha karmaşık ve incelikli kararlara olanak tanır.


Performansı açık bir şekilde karşılaştırmasak da algoritma seçiminin problem özelliklerinden etkilenmesi gerektiğini belirttik. Daha basit ilişkiler için LinUCB ve Karar Ağaçları üstün olabilirken Sinir Ağları karmaşık senaryolarda daha iyi performans gösterebilir. Her yöntem benzersiz güçlü yönler sunuyordu: Matematiksel basitliği nedeniyle LinUCB, yorumlanabilirliği nedeniyle Karar Ağaçları ve karmaşık ilişkileri ele alma becerileri nedeniyle Sinir Ağları. Doğru yaklaşımı seçmek, bu heyecan verici alanda etkili problem çözmenin anahtarıdır.


Genel olarak, bağlama dayalı haydut sorunları, takviyeli öğrenme kapsamında ilgi çekici bir alan sunar; bunların üstesinden gelmek için çeşitli algoritmalar mevcuttur ve bu güçlü modellerin daha da yenilikçi kullanımlarını görmeyi bekleyebiliriz.