sklearn utils compute_class_weight 函数用于大型数据集

Vib*_*hor 6 python machine-learning scikit-learn data-science tensorflow

我正在postgres db 中基于大约 20+ GB 的基于文本的分类数据训练 tensorflow keras 顺序模型,我需要为模型提供类权重。这是我在做什么。

class_weights = sklearn.utils.class_weight.compute_class_weight('balanced', classes, y)

model.fit(x, y, epochs=100, batch_size=32, class_weight=class_weights, validation_split=0.2, callbacks=[early_stopping])
Run Code Online (Sandbox Code Playgroud)

由于我无法将整个内容加载到内存中,我想我可以在 keras 模型中使用fit_generator方法。

但是,如何计算此数据的类权重sklearn没有为此提供任何特殊功能,它是正确的工具吗?

我想在多个随机样本上做这件事,但有没有更好的方法可以使用整个数据

ven*_*nan 5

您可以使用生成器,也可以计算类别权重。

假设你有这样的发电机

train_generator = train_datagen.flow_from_directory(
        'train_directory',
        target_size=(224, 224),
        batch_size=32,
        class_mode = "categorical"
        )
Run Code Online (Sandbox Code Playgroud)

训练集的类别权重可以这样计算

class_weights = class_weight.compute_class_weight(
           'balanced',
            np.unique(train_generator.classes), 
            train_generator.classes)
Run Code Online (Sandbox Code Playgroud)

[编辑1] 既然你在评论中提到了postgres sql,我在这里添加原型答案。

首先使用 postgres sql 中的单独查询获取每个类的计数,并用它来计算类权重。你可以手动计算它。基本逻辑是权重最小的类的计数值为 1,其余类根据权重最小的类的相对计数得到 <1。

例如,您有 3 个类别 A、B、C,值为 100,200,150,则类别权重变为 {A:1,B:0.5,C:0.66}

从 postgres sql 获取值后手动计算它。

[询问]

cur.execute("SELECT class, count(*) FROM table group by classes order by 1")
rows = cur.fetchall()
Run Code Online (Sandbox Code Playgroud)

上面的查询将返回包含从最小到最高排序的元组(类名称、每个类的计数)的行。

然后下面的代码将创建类权重字典

class_weights = {}
for row in rows:
    class_weights[row[0]]=rows[0][1]/row[1] 
    #dividing the least value the current value to get the weight, 
    # so that the least value becomes 1, 
    # and other values becomes < 1
Run Code Online (Sandbox Code Playgroud)

  • 此方法似乎从目录名称中获取类名称。我正在处理文本数据。如果我编写自己的生成器来生成从 postgres 数据库连接读取的值,我需要迭代它们,但是compute_class_weight需要整个训练标签列表。有什么办法可以解决这个问题吗? (2认同)