【问题标题】:How to create a sparse binary matrix from a dictionary in python如何从python中的字典创建稀疏二进制矩阵
【发布时间】:2022-11-02 02:18:37
【问题描述】:

我有一个.tsv我从中创建了一个文件蟒蛇字典在哪里钥匙都是电影编号价值观特征(每部电影都有不同数量的功能)。

这是我的字典的一个例子:

要达到的目标:

从这本字典我想创建一个项目特征稀疏矩阵用于推荐系统项目。 最后我想拥有一个二元稀疏矩阵当电影具有特定特征时为 1。 像这样的东西:

我的代码:

创建字典:

def Dictionary():
    d={}
    l=[]
    with open(filepath_mapping) as f:
        for line in f.readlines():
            line = line.split()
            key = int(line[0])
            value = [int(el) for el in line[1:]]
            d[key] = value
    return(d)

movie_features_dict = Dictionary()

从字典创建项目特征矩阵:

n = len(movie_features_dict)
value_lengths = [len(v) for v in movie_features_dict.values()]
d = max(value_lengths)
print(f"ITEM*FEATURES matrix shape: {n,d}\n")

item_feature_matrix = sp.dok_matrix((n,d), dtype=np.int8)

for movie_ids, features in movie_features_dict.items():
    item_feature_matrix[movie_ids, features] = 1

item_feature_matrix = item_feature_matrix.tocsr()
print(item_feature_matrix.shape)

问题:

我有 22069 部电影,而特征数量最多的电影应该有 885 个特征,所以理论上我应该有22069*885矩阵,但是使用我编写的代码,我继续遇到此错误:

raise IndexError('index (%d) out of range' % max_indx)
IndexError: index (614734) out of range

【问题讨论】:

  • 如果没有数据,要完全重现您遇到的错误有点困难,第一个打印语句指示`nd 的值的结果是什么?我认为错误是由于您使用特征值(features)对矩阵进行索引,该特征值可能高于特征总数,因为某些特征值不存在(即数字 2 到 4 中你的例子)。
  • @Oxbowerce 第一个打印语句的结果是“ITEM*FEATURES 矩阵形状:(22069, 885)”,所以正如我在问题“n”(电影数量)的“问题”段落中所写的那样,应该是 22069 ,而“d”(至少一部电影具有的特征的最大值)应该是 885。我认为问题在于每部电影都没有固定数量的特征,但它是可变的,我不知道如何创建稀疏矩阵。

标签: python dictionary scipy sparse-matrix key-value


【解决方案1】:

根据this 的回答,您可以用几行代码执行以下操作:

import pandas as pd

id_to_features = {
    880: [18, 23, 854, 98475, 20],
    152: [1, 578, 18, 654, 23, 5, 11],
    6654: [2088]
}

df = pd.DataFrame({"features": list(id_to_features.values())})
matrix = df['features'].apply(pd.value_counts).fillna(0).astype(int)
ids = list(id_to_features.keys())
matrix.index = ids
matrix = matrix.reindex(sorted(matrix.columns), axis=1)

编辑

出于好奇,我创建了一个假数据集,上面的代码在普通笔记本电脑上运行(使用perf_counter)需要 7 秒。

下面是生成数据集的代码:

id_to_features = {
    i: [randint(1, 886) for _ in range(randint(1, 10))] for i in range(1, 22070)
}

【讨论】:

  • 问题是我不能(或不想)创建数据框,因为文件非常大并且需要很多时间。我将 .tsv 文件作为字典阅读只是因为该文件非常大,而且每部电影都有不同数量的特征这一事实并不能帮助我创建稀疏矩阵。
  • 你好!感谢您的澄清。出于好奇,我创建了一个具有您指定维度的数据集。花了7s。我的假数据集可信吗?谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-01-10
  • 2017-03-31
  • 1970-01-01
  • 2016-07-29
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
相关资源
最近更新 更多