1,159

2、linUCB代码实战

设定超参数和矩阵

``````self.alpha = 0.25
self.r1 = 0.6
self.r0 = -16
self.d = 6  # dimension of user features
``````

``````self.Aa = {} # Aa : collection of matrix to compute disjoint part for each article a, d*d
self.AaI = {}  # AaI : store the inverse of all Aa matrix

self.ba = {}  # ba : collection of vectors to compute disjoin part, d*1
self.theta = {}
``````

初始化矩阵

``````def set_articles(self,art):
for key in art:
self.Aa[key] = np.identity(self.d) # 创建单位矩阵
self.ba[key] = np.zeros((self.d,1))

self.AaI[key] = np.identity(self.d)
self.theta[key] = np.zeros((self.d,1))
``````

计算推荐结果

``````def recommend(self,timestamp,user_features,articles):
xaT = np.array([user_features]) # d * 1
xa = np.transpose(xaT)

AaI_tmp = np.array([self.AaI[article] for article in articles])
theta_tmp = np.array([self.theta[article] for article in articles])
art_max = articles[np.argmax(np.dot(xaT,theta_tmp) + self.alpha * np.sqrt(np.dot(np.dot(xaT,AaI_tmp),xa)))]

self.x = xa
self.xT = xaT

self.a_max = art_max
return self.a_max
``````

更新矩阵信息

``````def update(self,reward):
if reward == -1:
pass
elif reward == 1 or reward == 0:
if reward == 1:
r = self.r1
else:
r = self.r0

self.Aa[self.a_max] += np.dot(self.x,self.xT)
self.ba[self.a_max] += r * self.x
self.AaI[self.a_max] = np.linalg.inv(self.Aa[self.a_max])
self.theta[self.a_max] = np.dot(self.AaI[self.a_max],self.ba[self.a_max])

else:
# error
``````

结语

1）由于加入了特征，所以收敛比UCB更快（论文有证明）；
2）特征构建是效果的关键，也是工程上最麻烦和值的发挥的地方；
3）由于参与计算的是特征，所以可以处理动态的推荐候选池，编辑可以增删文章；
4）特征降维很有必要，关系到计算效率。
5）是一种在线学习算法。