我必须创建一个用户和电视节目的邻接表,其中行是用户,电视节目是列。如果用户关注该电视节目,那么矩阵中将有一个 1,否则为 0。我已经从推特上收集了这些信息。总共有 140 个电视节目和大约 530000 个独立用户。我正在使用以下代码生成矩阵,使用 python:
- NoTvShows:电视节目总数(ID)
- unique_user:所有唯一用户
- collected_users:这是一个列表列表。子列表对应电视节目并列出关注者的 ID。
for i in range(0,NoTvShows):
for every_user in unique_users:
if every_user in collected_users[i]:
matrix.append(1)
else:
matrix.append(0)
main_matrix.append(matrix)
matrix = []
the_matrix = zip(*main_matrix)
simplejson.dump(the_matrix,fwrite)
fwrite.close()
当我尝试在服务器上执行我的程序时,它崩溃了,因为它占用了大量时间和内存。我知道我可以使用 numpy 来减小矩阵的大小,然后使用它来计算用户之间的相似性。但是,我不确定如何在此代码中对 numpy 进行编码并生成缩减矩阵。
我希望有人能在这方面指导我
谢谢
理查
请您参考如下方法:
稀疏矩阵(如 suggested by @phg )很好,因为矩阵中的大部分条目可能为 0(假设大多数用户只关注少数电视节目)。
不过,可能更重要的是,您正在以一种非常低效的方式构建矩阵(制作大量 python 列表列表并将它们复制过来),而不是首先将它们放在一个漂亮的紧凑型 numpy 数组中。此外,您将花费大量时间搜索列表(使用 in 语句),而这对于您的循环来说根本不是必需的。
此代码遍历关注者列表,并在 user_ids 字典中为每个 ID 查找用户 #。您可以非常简单地使其适应稀疏矩阵类(我认为只需将 np.zeros 切换为 scipy.sparse.coo_matrix)。
user_ids = dict((user, i) for i, user in enumerate(unique_users))
follower_matrix = np.zeros(NoTvShows, len(unique_users), dtype=bool)
for show_idx, followers in enumerate(collected_users):
for user in followers:
follower_matrix[show_idx, user_ids[user]] = 1
一旦你有了矩阵,你真的,真的不想将它保存为 JSON,除非你必须这样做:这对于数字矩阵来说是一种非常浪费的格式。如果你只是在 numpy 中再次使用数据矩阵,numpy.save 是最好的。 numpy.savetxt 也有效,至少消除了括号和逗号,并且在写入时可能会减少内存开销。但是当你有一个 0-1 矩阵并且它是 bool 数据类型时,numpy.save 每个矩阵元素只需要一位,而 numpy.savetxt 需要两个字节 = 16位(一个ascii '0' or '1' 加一个空格或换行符),而json至少使用三个字节,我认为(逗号,空格,加上一些括号在每一行)。
您可能还在谈论降维技术。这也是很有可能的;有很多技术可以通过某种 PCA 类型的技术、主题模型,或者基于聚类的方法,将 140 维的向量(接下来是电视节目)减少到更低的维度……如果你唯一担心的是构建矩阵需要很长时间,但这根本没有帮助(因为这些技术通常需要完整的原始矩阵,然后给你一个低维版本)。在这里试试我的建议,如果它不够好,试试稀疏矩阵,然后考虑减少数据的奇特方法(可能通过学习数据子集的降维,然后构建其余数据)。
