sklearn использует функцию compute_class_weight для большого набора данных - PullRequest
3 голосов
/ 26 февраля 2020

Я обучаю последовательную модель tenorsflow keras примерно на 20+ ГБ текстовых категориальных данных в postgres дБ , и мне нужно дать весовые коэффициенты модели. Вот что я делаю.

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

Поскольку я не могу загрузить все это в память, я подумал, что могу использовать метод fit_generator в модели keras.

Однако как я могу рассчитать веса классов на этих данных? sklearn не предоставляет никакой специальной функции для этого, это правильный инструмент для этого ?

Я думал сделать это на нескольких случайных выборках но есть ли лучший подход, где можно использовать целые данные ?

1 Ответ

1 голос
/ 26 февраля 2020

Вы можете использовать генераторы, а также вы можете вычислить вес классов.

Допустим, у вас есть такой генератор, как этот

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], так как Вы упомянули о postgres sql в комментариях, я добавляю ответ прототипа здесь.

сначала выберите счетчик для каждого класса, используя отдельный запрос из postgres sql, и используйте его для вычисления весов классов. Вы можете вычислить это вручную. Основой c logi c является то, что счетчик наименее взвешенного класса получает значение 1, а остальные классы получают <1 на основе относительного количества наименее взвешенного класса. </p>

например, у вас есть 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()

Приведенный выше запрос вернет строки с кортежами (имя класса, количество для каждого класса), упорядоченные от минимального к максимальному.

Затем в приведенной ниже строке будет создан словарь весов классов

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
...