#python #machine-learning
Вопрос:
Попробуйте этот простой код игрового автомата.
import numpy as np
slotConRates = [.02, .013, .013, .015, .018]
# Number of Tries
N = 10000
# Number of Machines
d = len(slotConRates)
# Add 1 if you get a Win in the Array X
X = np.zeros((N,d))
for i in range(N):
for j in range(d):
if np.random.rand() < slotConRates[j]:
X[i][j] = 1
win_reward = np.zeros(d)
loss_reward = np.zeros(d)
# Taking our best Slot Machine through beta distribution and updating it's loss and wins
for i in range(N):
selected = 0
MaxRandom = 0
for j in range(d):
randomBeta = np.random.beta(win_reward[j] 1, loss_reward[j] 1)
if randomBeta > MaxRandom:
MaxRandom = randomBeta
selected = j
if X[i][selected] == 1:
win_reward[selected] = 1
else:
loss_reward[selected] = 1
# Showing which slot machine is considered the best
nSelected = win_reward loss_reward
for i in range(d):
print('Machine number ' str(i 1) ' was selected ' str(nSelected[i]) ' times')
print('Conclusion: Best machine is machine number ' str(np.argmax(nSelected) 1))
Тем не менее, он всегда выбирает 1-ю машину для каждой итерации.
Machine number 1 was selected 10000.0 times
Machine number 2 was selected 1181.0 times
Machine number 3 was selected 1108.0 times
Machine number 4 was selected 640.0 times
Machine number 5 was selected 1314.0 times
Conclusion: Best machine is machine number 1
Как мне это исправить? Проблема заключается во втором for
цикле. Есть какие-нибудь идеи о том, почему это происходит?
Комментарии:
1. Вы начинаете каждый
j
цикл сMaxRandom = 0
и, следовательноrandomBeta > MaxRandom
, всегдаTrue
дляj == 0
?
Ответ №1:
Я действительно не понимаю, что вы делаете, но я почему-то думаю, что эта небольшая модификация (изменение отступа последнего if
else
блока) может быть тем, что вы ищете:
...
for i in range(N):
selected = 0
MaxRandom = 0
for j in range(d):
randomBeta = np.random.beta(win_reward[j] 1, loss_reward[j] 1)
if randomBeta > MaxRandom:
MaxRandom = randomBeta
selected = j
if X[i][selected] == 1:
win_reward[selected] = 1
else:
loss_reward[selected] = 1
...
Редактировать:
Типичный результат после корректировки:
win_reward = array([ 34., 7., 3., 20., 124.])
loss_reward = array([1733., 656., 431., 1271., 5721.])
nSelected = array([1767., 663., 434., 1291., 5845.])
Machine number 1 was selected 1767.0 times
Machine number 2 was selected 663.0 times
Machine number 3 was selected 434.0 times
Machine number 4 was selected 1291.0 times
Machine number 5 was selected 5845.0 times
Conclusion: Best machine is machine number 5
(Test sum over selections: 10000.0)
Полный список, который я использовал:
import numpy as np
slotConRates = [.02, .013, .013, .015, .018]
N = 10000
d = len(slotConRates)
X = np.zeros((N,d))
for i in range(N):
for j in range(d):
if np.random.rand() < slotConRates[j]:
X[i][j] = 1
win_reward = np.zeros(d)
loss_reward = np.zeros(d)
for i in range(N):
selected = 0
MaxRandom = 0
for j in range(d):
randomBeta = np.random.beta(win_reward[j] 1, loss_reward[j] 1)
if randomBeta > MaxRandom:
MaxRandom = randomBeta
selected = j
if X[i][selected] == 1:
win_reward[selected] = 1
else:
loss_reward[selected] = 1
nSelected = win_reward loss_reward
print(f'{win_reward = }')
print(f'{loss_reward = }')
print(f'{nSelected = }')
for i in range(d):
print(f'Machine number {i 1} was selected {nSelected[i]} times')
print(f'Conclusion: Best machine is machine number {np.argmax(nSelected) 1}')
print(f'(Test sum over selections: {nSelected.sum()})')
Комментарии:
1. Нет. Это не то. Это простая демонстрация для выборки Томпсона, используемая в искусственном интеллекте. Вопрос в целой программе. Вы можете просто скопировать его и запустить, чтобы проверить.
2. @AbhishekRai Хорошо, тогда смотрите мой комментарий выше:
10000
неизбежно дляnSelected[0]
.3. @AbhishekRai Кроме того: Если отступ в
if
else
блоке —правильный, то почему строкаselected = j
, а не просто использовать простоj
?4. @AbhishekRai Последний комментарий: Если вы посмотрите здесь , где-то после середины, вы найдете код, который очень похож на ваш (начинается с
# Implementing Thompson Sampling
). И отступ вif
else
блоке—, который подсчитывает награды, в значительной степени соответствует моему предложению.5. Вот и все…Не знаю, почему это не сработало вчера.