sklearn工具包中针对大型数据集的compute_class_weight函数

10

我正在训练一个tensorflow keras顺序模型,使用一个大小约为20GB的基于文本分类的PostgreSQL数据库中的数据,并且需要为模型提供类权重。 以下是我的操作步骤:

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])

由于我无法将整个东西加载到内存中,所以我想在Keras模型中使用fit_generator方法。

然而,我该如何计算这些数据的类别权重sklearn没有提供任何特殊的函数来处理这个问题,它是否是处理这个问题的正确工具

我考虑对多个随机样本进行操作,但是否有更好的方法可以使用全部数据

2个回答

5
你可以使用生成器,也可以计算类别权重。
假设你的生成器如下:
train_generator = train_datagen.flow_from_directory(
        'train_directory',
        target_size=(224, 224),
        batch_size=32,
        class_mode = "categorical"
        )

计算训练集的类别权重可以按照以下方式进行

class_weights = class_weight.compute_class_weight(
           'balanced',
            np.unique(train_generator.classes), 
            train_generator.classes)

[编辑1] 由于您在评论中提到了PostgreSQL,因此我在此添加原型答案。
首先,使用来自PostgreSQL的单独查询获取每个类别的计数,并用它来计算类别权重。您可以手动计算它。基本逻辑是最低权重类别的计数获得值1,其余类别根据相对于最低权重类别的计数而获得小于1的值。
例如,您有3个A、B、C类别,分别为100、200、150,则类别权重变为{A:1,B:0.5,C:0.66}。
从PostgreSQL检索值后,请手动计算它。
[查询]
cur.execute("SELECT class, count(*) FROM table group by classes order by 1")
rows = cur.fetchall()

以上查询将返回按数量从少到多排序的元组(类名,每个类的计数)。

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

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

2
这个方法似乎从目录名中获取类名。我正在处理文本数据。如果我编写自己的生成器来产生从Postgres数据库连接读取的值,我需要迭代它们,但是compute_class_weight期望整个训练标签列表。有没有什么办法来处理这个问题? - Vibhor
1
你在问题中应该提到了Postgres。如何编写一个查询来获取每个类的计数?(select count(*) from table group by classes)并获取结果并使用它来计算类权重? - venkata krishnan

1
Sklearn不适用于这样的大规模处理。理想情况下,我们应该自己实现,特别是当它是你定期运行的流程的一部分时。

你的回答可以通过提供更多支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接