微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Dask优化中的ALS算法

如何解决Dask优化中的ALS算法

我正在尝试在 dask 中实现 ALS 算法,但我无法弄清楚如何一步计算潜在特征。我遵循 this stackoverflow thread 上的公式并得出以下代码

    Items = da.linalg.lstsq(da.add(da.dot(Users,Users.T),lambda_ * da.eye(n_factors)),da.dot(Users,X))[0].T.compute()
    Items = np.where(Items < 0,Items)

    Users = da.linalg.lstsq(da.add(da.dot(Items.T,Items),da.dot(Items.T,X.T))[0].compute()
    Users = np.where(Users < 0,Users)

但我认为这不正确,因为 MSE 并没有减少。

示例输入:

n_factors = 2
lambda_ = 0.1
# We have 6 users and 4 items

矩阵 X_train(6x4)、R(4x6)、Users(2x6) 和 Items(4x2) 看起来像:

1  0  0  0  5  2        1 0 0 0    0.8  1.3     1.1  0.2  4.1  1.6
0  0  0  0  4  0        0 0 1 1    3.9  4.3     3.5  2.7  4.3  0.5
0  3  0  0  4  0        0 0 0 0    2.9  1.5
0  3  0  0  0  0        0 0 0 0    0.2  4.7
                        1 1 1 0    0.9  1.1
                        1 0 0 0    4.8  3.0

编辑:我发现了问题,但我不知道如何解决。在迭代开始之前,我将 X_train 矩阵中没有评分的所有值设置为 0。

X_train = da.nan_to_num(X_train)

这是因为点积仅适用于数值。但是因为矩阵非常稀疏,它的 90% 现在由零组成。并在矩阵中拟合真实评分后,它会拟合这个零点。

任何帮助将不胜感激。

解决方法

处理数据集中的空白或缺失值的一种方法是使用 masked arrays。截至 2017 年 5 月,Dask 也支持它们。

在 Dask 中定义掩码数组相当简单,与 numpy 相似。 docs 中列出了所有支持的函数,这里只是一些最常用的方法:

data_set = da.array([[1,2],[3,4]])

masked_data_set_1 = da.ma.masked_array(data_set,mask=[[False,True],[True,False]])
# returns [[1,--],[--,4]]

masked_data_set_2 = da.ma.masked_equal(data_set,4)
# returns [[1,--]]

masked_data_set_3 = da.ma.masked_where(data_set < 3,data_set)
# returns [[--,4]]

就您而言,您正在尝试执行 da.dot(Users,X)) 的点积。您可以将掩码数组用作:

,而不是将所有 NaN 值设置为 0
masked_X = da.ma.masked_where(X != X,X)

现在您可以轻松执行点积,例如:

da.ma.getdata(da.dot(Users,masked_X))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。