Keras / TensorFlow - высокая точность, плохой прогноз

Я новичок в машинном обучении, и я пытаюсь обучить модель, которая обнаруживает город Prague в предложении. Это может быть множество словоформ.

Prague, PRAHA, Z Prahy etc...

Итак, у меня есть набор данных поезда, который состоит из title и result, где result двоичный - 1 или 0 (около 5000 примеров)

Вы можете увидеть образец в комментариях к коду.

Мои мысли:

  1. загрузить набор данных поезда (заголовок, результат) и тестовый набор данных (заголовок)
  2. установить X_train, y_train
  3. преобразовать столбец заголовка из X_train в последовательности чисел
  4. создать модель и установить слои (я здесь не уверен, правильно ли я все сделаю)
  5. тренироваться
  6. контрольная работа

Поезд печатает это:

Epoch 15/20
 - 0s - loss: 0.0303 - acc: 0.9924
Epoch 16/20
 - 0s - loss: 0.0304 - acc: 0.9922
Epoch 17/20
 - 0s - loss: 0.0648 - acc: 0.9779
Epoch 18/20
 - 0s - loss: 0.0589 - acc: 0.9816
Epoch 19/20
 - 0s - loss: 0.0494 - acc: 0.9844
Epoch 20/20

Но тест возвращает эти значения:

[0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0]

Это означает, что он обнаружил слово Prague в этих двух предложениях из тестового csv:

  1. Сильвестр - Дублин-з-Праги
  2. Прогулка до BRUSELU z PRAHY от 518 Kč

Первое предложение - это подстрока из одного предложения из X_train, а второе предложение равно одному из предложений X_train.

Я безуспешно пытался увеличить число epochs и число batch_size ...

Другие тестовые предложения были созданы случайным образом или путем модификации предложений X_test.

def train():
    # load train dataset

    #  "TIP! Ukraine Airlines - Thajsko - levné letenky Bangkok z Prahy (a zpět) 9.790,- kč",1
    # Predvianočná MALAGA s odletom z Viedne už za 18€,0
    # S 5* Singapore Airlines z Prahy do Singapuru a pak na Maledivy za 15.940 Kč,1
    # Athény z Katowic či Blavy,0
    # Z Prahy na kanárský ostrov Tenerife vč. zavazadla. Letenky od 1 990 Kč,1
    # Hotel v Praze i na víkend za 172Kč! (i jednolůžkové pokoje),1
    dataframe = pandas.read_csv("prague_train_set.csv")
    dataframe['title'] = dataframe['title'].str.lower()
    dataset = dataframe.values

    # load test dataset

    # v Praze je super # Should be 1, predicts 0
    # Silvestr v Dublinu z Prahy # Should be 1, predicts 1
    # do Prahy zavita peter # Should be 1, predicts 0
    # toto nie # Should be 0, predicts 0
    # xxx # Should be 0, predicts 0
    # Praha **** # Should be 1, predicts 0
    # z Prahy Přímo # Should be 1, predicts 0
    # Tip na dárek: Řím z Prahy za 778Kč (letfdenky tam i zpět) # Should be 1, predicts 0
    # lety do BRUSELU z PRAHY od 518 K # Should be 1, predicts 0
    # Přímé lety do BRUSELU z PRAHY od 518 Kč # Should be 1, predicts 1
    # Gelachovský stit # Should be 0, predicts 0

    tdataframe = pandas.read_csv("prague_test_set.csv")
    tdataframe['title'] = tdataframe['title'].str.lower()
    tdataset = tdataframe.values

    # Preprocess dataset
    X_train = dataset[:,0]
    X_test = tdataset[:,0]
    y_train = dataset[:,1]

    tokenizer = Tokenizer(char_level=True)
    tokenizer.fit_on_texts(X_train)

    X_train = tokenizer.texts_to_sequences(X_train)
    SEQ_MAX_LEN = 200
    X_train = sequence.pad_sequences(X_train, maxlen=SEQ_MAX_LEN)

    X_test = tokenizer.texts_to_sequences(X_test)
    X_test = sequence.pad_sequences(X_test, maxlen=SEQ_MAX_LEN)



    # create model
    model = Sequential()
    # model.add(Embedding(tokenizer.word_index.__len__(), 32, input_length=100))
    model.add(Dense(SEQ_MAX_LEN, input_dim=SEQ_MAX_LEN, init='uniform', activation='relu'))
    model.add(Dense(10, init='uniform', activation='relu'))
    model.add(Dense(1, init='uniform', activation='sigmoid'))
    # Compile model
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    # Fit the model
    model.fit(X_train, y_train, epochs=20, batch_size=32, verbose=2)
    # model.save("trainmodel.h5")
    # model = load_model("trainmodel.h5")
    # calculate predictions
    predictions = model.predict(X_test)
    # round predictions
    rounded = [round(x[0]) for x in predictions]
    print(rounded)

Вы знаете, что мне делать, чтобы он работал правильно?

Это кажется просто несбалансированным набором данных со слишком большим количеством нулей (или слишком большим количеством). Ваша модель имеет тенденцию выдавать все нули или все единицы, и точность для этого велика. Вы можете попробовать использовать веса классов, как описано в fit: keras.io/models/sequential/#fit

Daniel Möller 09.12.2018 16:03

Там примерно 25% единиц, а остальное - нули. У меня была проблема с постоянной точностью около 0,7, которая, вероятно, была этой проблемой. Я проверю вес.

Milano 09.12.2018 16:07
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
385
1

Ответы 1

С этим могут возникнуть две проблемы. 1. Асимметрия данных 2. Переоснащение

  1. Асимметрия данных: данные вашего набора данных могут быть искажены, например, он имеет только 1% положительных результатов, тогда простой алгоритм, который предсказывает 0, будет иметь точность 99%. Здесь вам нужно использовать следующие метрики для количественной оценки «добродетели»

    • точность и отзыв
    • f1-счет
  2. Переобучение: также называется проблемой обобщения, теоретически, если параметры обучения больше (ваши веса и смещения нейронной сети), тогда она может соответствовать этим параметрам, чтобы добиться хороших результатов при обучении, но не может их обобщить. Теоретически VC-размерность - это предел, который зависит от вашего обучающего примера (m), поэтому вы можете попробовать

    • увеличение размера обучающих данных (за счет увеличения)
    • Добавление регуляризации
    • Использование отсева
    • вы можете посмотреть в, чтобы понять, сколько узлов должно быть в нейронной сети

Другие вопросы по теме