使用numpy来减小矩阵的大小

Ric*_*dev 1 python numpy matrix

我必须创建一个用户和电视节目的邻接列表,其中行是用户,电视节目是列.如果用户跟随该电视节目,则矩阵中将有1为零.我已经从twitter上收集了这些信息.总共有140个电视节目和大约530000个独立用户.我使用以下代码生成矩阵,使用python:

  • NoTvShows:电视节目总数(ID)
  • unique_user:所有唯一用户
  • gather_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()
Run Code Online (Sandbox Code Playgroud)

当我尝试在服务器上执行我的程序时,它崩溃了,因为它占用了大量的时间和内存.我知道我可以使用numpy来减小矩阵的大小,然后用它来计算用户之间的相似性.但是,我不确定如何在此代码中编码numpy并生成简化矩阵.

我希望有人可以在这方面指导我

谢谢

Richa

Dou*_*gal 6

稀疏矩阵(由@phg建议)很好,因为矩阵中的大多数条目可能都是0(假设大多数用户只关注几个电视节目).

可能更重要的是,你正在以非常低效的方式构建矩阵(制作大量的python列表并将它们复制),而不是仅仅将它们放在一个非常紧凑的numpy数组中.此外,您花了大量时间搜索列表(使用in语句),这时您的循环根本不需要.

此代码循环遍历关注者列表,并为user_ids字典中的每个id查找用户#.您可以非常简单地将它调整为稀疏矩阵类(我认为只需切换np.zerosscipy.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
Run Code Online (Sandbox Code Playgroud)

一旦你有了矩阵,你真的,真的不想把它保存为JSON,除非你必须:它是一个非常浪费的数字矩阵格式.numpy.save如果你只是在numpy中再次使用数据矩阵,那是最好的.numpy.savetxt也可以工作,至少可以删除括号和逗号,并且在写入时可能会减少内存开销.但是当你有一个0-1矩阵并且它是布尔数据类型时,numpy.save每个矩阵元素只需要一个位,而numpy.savetxt需要两个字节= 16位(一个ascii '0''1'加一个空格或换行符),而json至少使用三个字节,我想(逗号,空格,每行加上一些括号).


您可能还在谈论降维技术.这也很有可能; 有很多技术可以减少140维度的矢量(遵循电视节目)以降低维度,可以通过某种PCA类型技术,主题模型,也许是基于聚类的东西....如果你的唯一值得关注的是,它需要很长时间来构建矩阵,但这根本不会有所帮助(因为这些技术通常需要完整的原始矩阵然后给你一个低维版本).在这里尝试我的建议,如果它不够好尝试稀疏矩阵,然后担心减少数据的奇特方法(可能通过学习数据子集的维数减少然后构建其余部分).