В Интернете есть множество источников, которые предоставляют огромное количество ежедневных новостей. Кроме того, спрос на информацию со стороны пользователей постоянно растет, поэтому важно классифицировать новости таким образом, чтобы пользователи могли быстро и эффективно получать доступ к интересующей их информации. Используя эту модель, пользователи смогут определять темы новостей, которые не отслеживаются, и/или давать рекомендации, основанные на их прежних интересах. Таким образом, мы стремимся создавать модели, которые используют заголовки новостей и краткие описания в качестве входных данных и создают категории новостей в качестве выходных данных.

Проблема, которую мы будем решать, — это классификация статей BBC News и их категорий. Используя текст в качестве входных данных, мы предскажем, какой будет категория. Существует пять типов категорий: бизнес, развлечения, политика, спорт и технологии.

Схема учебника выглядит следующим образом:

  1. Предварительные условия и настройка среды
  2. Обзор набора данных
  3. Импорт необходимых библиотек
  4. Загрузка набора данных
  5. Очистка данных и предварительная обработка
  6. Создание и обучение модели машинного обучения
  7. Заключение

1. Предварительные условия и настройка среды

Это руководство выполняется в Anaconda Navigator (версия Python — 3.8.3) в операционной системе Windows. Следующие пакеты должны быть установлены, прежде чем вы продолжите работу с учебным пособием:

Вы можете установить эти пакеты в виртуальной среде Conda, используя conda install package-name. Если вы используете Python напрямую через терминал/командную строку, pip install package-name выполнит всю работу.

Установка GridDB

При загрузке набора данных в этом руководстве будут рассмотрены два метода: использование GridDB и использование Pandas. Чтобы получить доступ к GridDB с помощью Python, также необходимо заранее установить следующие пакеты:

  1. C-клиент GridDB
  2. SWIG (упрощенная оболочка и генератор интерфейсов)
  3. Клиент GridDB Python

2. Обзор набора данных

Текстовые документы являются одним из самых богатых источников данных для бизнеса.

Мы будем использовать общедоступный набор данных BBC, состоящий из 2225 статей, каждая из которых помечена в одной из 5 категорий: бизнес, развлечения, политика, спорт или технологии.

Набор данных, используемый в этом проекте, представляет собой необработанный набор данных BBC News. Его можно скачать отсюда (http://mlg.ucd.ie/datasets/bbc.html).

3. Импорт необходимых библиотек

import griddb_python as griddb
import csv
import tensorflow as tf
import numpy as np
import pandas as pd
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, LSTM, Dropout, Activation, Embedding, Bidirectional
import nltk
from nltk.corpus import stopwords
import matplotlib.pyplot as plt

4. Загрузка набора данных

Давайте продолжим и загрузим набор данных в нашу записную книжку.

4.a Использование GridDB

Toshiba GridDB™ — это хорошо масштабируемая база данных NoSQL, которая лучше всего подходит для Интернета вещей и больших данных. В основе принципов GridDB лежит предложение универсального хранилища данных, оптимизированного для Интернета вещей, обеспечивающего высокую масштабируемость, высокую производительность и высокую надежность.

Для хранения больших объемов данных файл CSV может быть громоздким. GridDB служит идеальной альтернативой, поскольку она имеет открытый исходный код и хорошо масштабируемую базу данных. GridDB — это масштабируемая база данных в памяти без SQL, которая упрощает хранение больших объемов данных. Если вы новичок в GridDB, может быть полезен учебник по чтению и записи в GridDB.

Предполагая, что вы уже настроили свою базу данных, теперь мы напишем SQL-запрос на python для загрузки нашего набора данных.

sql_statement = ('SELECT * FROM bbc-text')
dataset = pd.read_sql_query(sql_statement, cont)

Обратите внимание, что переменная cont содержит информацию о контейнере, в котором хранятся наши данные. Замените bbc-text именем вашего контейнера. Дополнительную информацию можно найти в этом руководстве Чтение и запись в GridDB.

Когда дело доходит до вариантов использования IoT и больших данных, GridDB явно выделяется среди других баз данных в пространстве реляционных и NoSQL. В целом GridDB предлагает несколько функций обеспечения надежности для критически важных приложений, которым требуется высокая доступность и сохранение данных.

4.b Использование оператора With

В Python вам нужно предоставить доступ к файлу, открыв его. Вы можете сделать это с помощью функции open(). Open возвращает файловый объект, который имеет методы и атрибуты для получения информации об открытом файле и управления им. Оба вышеперечисленных метода приведут к одному и тому же результату, поскольку данные загружаются в виде фрейма данных pandas с использованием любого из методов.

Мы импортируем библиотеку ntlk и импортируем функцию стоп-слов. Мы установим стоп-слова для английского языка. Это образцы английских стоп-слов: has, hasn’t, and, not are, потому что, each, во время.

Процесс преобразования данных во что-то, понятное компьютеру, называется предварительной обработкой. Одной из основных форм предварительной обработки является отфильтровывание бесполезных данных. При обработке естественного языка бесполезные слова (данные) называются стоп-словами.

Стоп-слово — это часто используемое слово (например, «the», «a», «an», «in»), которое поисковая система запрограммировала игнорировать как при индексировании записей для поиска, так и при извлечении их в качестве результата. поискового запроса. Мы бы не хотели, чтобы эти слова занимали место в нашей базе данных или занимали ценное время обработки. Для этого мы можем легко удалить их, сохранив список слов, которые вы считаете стоп-словами.

nltk.download('stopwords')
STOPWORDS = set(stopwords.words('english'))
#We populate the list of articles and labels from the data and also remove the stopwords.
articles = []
labels = []
with open("bbc-text.csv", 'r') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    next(reader)
    for row in reader:
        labels.append(row[0])
        article = row[1]
        for word in STOPWORDS:
            token = ' ' + word + ' '
            article = article.replace(token, ' ')
            article = article.replace(' ', ' ')
        articles.append(article)

Мы устанавливаем гиперпараметры, необходимые для построения и обучения модели.

vocab_size = 5000 
embedding_dim = 64
max_length = 200
trunc_type = 'post'
padding_type = 'post'
oov_tok = '<oov>' # OOV = Out of Vocabulary
training_portion = 0.8</oov>

После загрузки набора данных давайте теперь исследуем набор данных. Мы напечатаем первые 10 строк этого набора данных, используя функцию head().

5. Очистка данных и предварительная обработка

articles[:1]
['tv future hands viewers home theatre systems plasma high-definition tvs digital video recorders moving living room way people watch tv radically different five years time. according expert panel gathered annual consumer electronics show las vegas discuss new technologies impact one favourite pastimes. us leading trend programmes content delivered viewers via home networks cable satellite telecoms companies broadband service providers front rooms portable devices. one talked-about technologies ces digital personal video recorders (dvr pvr). set-top boxes like us tivo uk sky+ system allow people record store play pause forward wind tv programmes want. essentially technology allows much personalised tv. also built-in high-definition tv sets big business japan us slower take europe lack high-definition programming. people forward wind adverts also forget abiding network channel schedules putting together a-la-carte entertainment. us networks cable satellite companies worried means terms advertising revenues well brand identity viewer loyalty channels. although us leads technology moment also concern raised europe particularly growing uptake services like sky+. happens today see nine months years time uk adam hume bbc broadcast futurologist told bbc news website. likes bbc issues lost advertising revenue yet. pressing issue moment commercial uk broadcasters brand loyalty important everyone. talking content brands rather network brands said tim hanlon brand communications firm starcom mediavest. reality broadband connections anybody producer content. added: challenge hard promote programme much choice. means said stacey jolna senior vice president tv guide tv group way people find content want watch simplified tv viewers. means networks us terms channels could take leaf google book search engine future instead scheduler help people find want watch. kind channel model might work younger ipod generation used taking control gadgets play them. might suit everyone panel recognised. older generations comfortable familiar schedules channel brands know getting. perhaps want much choice put hands mr hanlon suggested. end kids diapers pushing buttons already - everything possible available said mr hanlon. ultimately consumer tell market want. 50 000 new gadgets technologies showcased ces many enhancing tv-watching experience. high-definition tv sets everywhere many new models lcd (liquid crystal display) tvs launched dvr capability built instead external boxes. one example launched show humax 26-inch lcd tv 80-hour tivo dvr dvd recorder. one us biggest satellite tv companies directtv even launched branded dvr show 100-hours recording capability instant replay search function. set pause rewind tv 90 hours. microsoft chief bill gates announced pre-show keynote speech partnership tivo called tivotogo means people play recorded programmes windows pcs mobile devices. reflect increasing trend freeing multimedia people watch want want.']
labels[:1]
    ['tech']

Теперь давайте приступим к созданию и оценке моделей машинного обучения в нашем наборе данных кредитных карт. Сначала мы создадим features и labels для нашей модели и разделим их на обучающую и тестовую выборки. Размер теста был сохранен на уровне 20% от общего размера набора данных.

Нам нужно разделить их на набор для обучения и набор для проверки. Мы устанавливаем 80% (training_portion = 0,8) для обучения и еще 20% для проверки.

train_size = int(len(articles) * training_portion)
train_articles = articles[0: train_size]
train_labels = labels[0: train_size]
validation_articles = articles[train_size:]
validation_labels = labels[train_size:]

5.a Токенизация

Токенизация устанавливается с num_words равным vocab_size (5000) и oov_token равным ‘ ‘. Метод fits_on_texts вызывается для train_articles. Используя частоту слов, этот метод создает индекс словарного запаса. В приведенном примере «Кошка села на коврик. «, он создаст словарь [‘’: 1, ‘кот’: 3, ‘мат’: 6, ‘он’: 5, ‘сб’: 4, ‘эт’: 2}.

tokenizer = Tokenizer(num_words = vocab_size, oov_token=oov_tok)
tokenizer.fit_on_texts(train_articles)
word_index = tokenizer.word_index

oov_token — это значение ‘ ‘, которое мы ставим, если слово отсутствует в словаре.

5.b Преобразование в последовательности

За токенизацией следует метод text_to_sequences. Он преобразует каждый текст в текстах в целочисленную последовательность. Метод в основном берет каждое слово в тексте и заменяет его соответствующим целым числом из словаря tokenizer.word_index. Если слова нет в словаре, ему будет присвоено значение 1.

train_sequences = tokenizer.texts_to_sequences(train_articles)

5.c Усечение последовательности и заполнение

Когда мы обучаем их НЛП, нам нужно сделать эти последовательности одного размера (конкретной формы). Чтобы убедиться, что все последовательности имеют одинаковый размер, мы будем использовать отступы и обрезать их.

train_padded = pad_sequences(train_sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)

Мы будем применять токенизацию, конвертировать в последовательности и заполнять/усекать для train_articles и validation_articles.

tokenizer = Tokenizer(num_words = vocab_size, oov_token=oov_tok)
tokenizer.fit_on_texts(train_articles)
word_index = tokenizer.word_index
train_sequences = tokenizer.texts_to_sequences(train_articles)
train_padded = pad_sequences(train_sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)
validation_sequences = tokenizer.texts_to_sequences(validation_articles)
validation_padded = pad_sequences(validation_sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)

Как и прежде, нам нужно сделать здесь то же самое, что и с функциями и статьями. Модель не понимает слов, поэтому нам нужно преобразовать метку в числа. Мы размечаем и конвертируем в последовательность так же, как и раньше. При токенизации мы не указываем размер словаря и oov_token.

label_tokenizer = Tokenizer()
label_tokenizer.fit_on_texts(labels)
training_label_seq = np.array(label_tokenizer.texts_to_sequences(train_labels))
validation_label_seq = np.array(label_tokenizer.texts_to_sequences(validation_labels))

6. Построение модели машинного обучения

Теперь мы готовы создать модель нейронной сети. Архитектура модели состоит из следующих слоев:

model = Sequential()
model.add(Embedding(vocab_size, embedding_dim))
model.add(Dropout(0.5))
model.add(Bidirectional(LSTM(embedding_dim)))
model.add(Dense(6, activation='softmax'))
model.summary()
Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    embedding (Embedding)        (None, None, 64)          320000    
    _________________________________________________________________
    dropout (Dropout)            (None, None, 64)          0         
    _________________________________________________________________
    bidirectional (Bidirectional (None, 128)               66048     
    _________________________________________________________________
    dense (Dense)                (None, 6)                 774       
    =================================================================
    Total params: 386,822
    Trainable params: 386,822
    Non-trainable params: 0
    _________________________________________________________________

Затем мы компилируем модель для настройки процесса обучения с потерей sparse_categorical_crossentropy, поскольку мы не кодировали метки сразу. Мы используем оптимизатор Adam.

opt = tf.keras.optimizers.Adam(learning_rate=0.001, decay=1e-6)
model.compile(loss='sparse_categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
num_epochs = 12
history = model.fit(train_padded, training_label_seq, epochs=num_epochs, validation_data=(validation_padded, validation_label_seq), verbose=2)
Epoch 1/12
    56/56 - 8s - loss: 1.6055 - accuracy: 0.2949 - val_loss: 1.4597 - val_accuracy: 0.3191
    Epoch 2/12
    56/56 - 5s - loss: 1.0623 - accuracy: 0.5854 - val_loss: 0.7767 - val_accuracy: 0.8000
    Epoch 3/12
    56/56 - 5s - loss: 0.6153 - accuracy: 0.7989 - val_loss: 0.7209 - val_accuracy: 0.7910
    Epoch 4/12
    56/56 - 5s - loss: 0.3402 - accuracy: 0.9101 - val_loss: 0.5048 - val_accuracy: 0.8135
    Epoch 5/12
    56/56 - 6s - loss: 0.1731 - accuracy: 0.9685 - val_loss: 0.1699 - val_accuracy: 0.9618
    Epoch 6/12
    56/56 - 6s - loss: 0.0448 - accuracy: 0.9955 - val_loss: 0.1592 - val_accuracy: 0.9663
    Epoch 7/12
    56/56 - 6s - loss: 0.0333 - accuracy: 0.9966 - val_loss: 0.1428 - val_accuracy: 0.9663
    Epoch 8/12
    56/56 - 5s - loss: 0.0400 - accuracy: 0.9927 - val_loss: 0.1245 - val_accuracy: 0.9685
    Epoch 9/12
    56/56 - 6s - loss: 0.0178 - accuracy: 0.9972 - val_loss: 0.1179 - val_accuracy: 0.9685
    Epoch 10/12
    56/56 - 5s - loss: 0.0135 - accuracy: 0.9972 - val_loss: 0.1557 - val_accuracy: 0.9573
    Epoch 11/12
    56/56 - 5s - loss: 0.0264 - accuracy: 0.9983 - val_loss: 0.1193 - val_accuracy: 0.9685
    Epoch 12/12
    56/56 - 6s - loss: 0.0102 - accuracy: 0.9994 - val_loss: 0.1306 - val_accuracy: 0.9663

Мы строим историю точности и потерь и смотрим, есть ли переоснащение.

def plot_graphs(history, string):
  plt.plot(history.history[string])
  plt.plot(history.history['val_'+string])
  plt.xlabel("Epoch Count")
  plt.ylabel(string)
  plt.legend([string, 'val_'+string])
  plt.show()
  
plot_graphs(history, "accuracy")
plot_graphs(history, "loss")

Наконец, мы вызываем метод predict() для выполнения предсказания образца текста.

txt = ["Only bonds issued by the Russian government can be traded as part of a phased re-opening of the market. The exchange closed hours after Russian President Vladimir Putin sent thousands of troops into Ukraine on 24 February.Andrei Braginsky, a spokesman for the Moscow Exchange, said he hoped that trading in stocks would be able to start again soon. Technically everything is ready, and we are hoping this will resume in the near future, he said."]
seq = tokenizer.texts_to_sequences(txt)
padded = pad_sequences(seq, maxlen=max_length)
pred = model.predict(padded)
labels = ['sport', 'bussiness', 'politics', 'tech', 'entertainment']
print(pred)
print(np.argmax(pred))
print(labels[np.argmax(pred)-1])
[[2.6411068e-04 2.1545513e-02 9.6170175e-01 7.2104726e-03 1.0733245e-03
      8.2047796e-03]]
    2
    bussiness

7. Заключение

В этом руководстве мы создали модель классификации текста с помощью LSTM, чтобы предсказать категорию статей BBC News. Мы рассмотрели два способа импорта наших данных, используя (1) GridDB и (2) With Statement. Для больших наборов данных GridDB предоставляет прекрасную альтернативу импорту данных в ваш блокнот, поскольку он имеет открытый исходный код и легко масштабируется. Скачай GridDB сегодня!

Первоначально опубликовано на https://griddb.net 1 апреля 2022 г.