Рубрики
Без рубрики

Классификация документа: 7 прагматических подходов для небольших наборов данных

Эта статья была первоначально опубликована Shahul ES на Neptune.ml/blog, где вы можете найти более подробную … Теги с обучением машины, наукой данных, Python.

Эта статья была первоначально размещена Shahul ES на neptune.ml/blog Где вы можете найти более глубокие статьи для машинного обучения практикующих.

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

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

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

Текстовый классификационный рабочий процесс начинается с очистки и подготовки корпуса из набора данных. Затем этот корпус представлен любым из различных методов представления текста, которые затем следует моделирование.

В этой статье Мы сосредоточимся на «текстовом представлении» Шаг этого трубопровода.

Мы будем использовать данные из Реальный или нет? NLP с стихийными твитами Конкурс Kaggle. Здесь Задача – предсказать, какие твиты о реальных бедствиях, а какие нет.

Если вы хотите следовать по шагам статьи, вы можете установить все библиотеки, которые я использовал для анализа.

Давайте посмотрим на наши данные,

import pandas as pd

tweet= pd.read_csv('../input/nlp-getting-started/train.csv')
test=pd.read_csv('../input/nlp-getting-started/test.csv')

tweet.head(3)

Данные содержит идентификатор, ключевое слово, местоположение, текст и цель, которая является двоичным. Мы будем рассматривать только твиты, чтобы предсказать цель.

print('There are {} rows and {} columns in train'.format(tweet.shape[0],tweet.shape[1]))
print('There are {} rows and {} columns in test'.format(test.shape[0],test.shape[1]))

Учебный набор данных имеет менее 8000 твитов. Что, в сочетании с тем фактом, что твиты 280 топов символов делают его сложным, маленьким (ish) набором данных.

Прежде чем мы попадем в любую задачу NLP, нам нужно сделать некоторые данные для предварительной обработки данных и основной очистки. Это не фокус этой статьи, но если вы хотите прочитать больше об этом шаге, ознакомьтесь с этим статья .

Короче говоря, мы будем:

  • Токенизировать : процесс, по которому предложения преобразуются в список токенов или слов.
  • Удалить стоп-слова : опустите слова, такие как «а» или «
  • Лемматизируйте : Уменьшите инфицированные формы каждого слова в общее основание или рут («исследования», «изучение» -> «исследование»).
def preprocess_news(df):
    '''Function to preprocess and create corpus'''
    new_corpus=[]

    lem=WordNetLemmatizer()
    for text in df["question_text"]:
        words=[w for w in word_tokenize(text) if (w not in stop)]

        words=[lem.lemmatize(w) for w in words]

        new_corpus.append(words)
    return new_corpus

corpus=preprocess_news(df)

Теперь давайте посмотрим, как представлять этот корпус, чтобы мы могли пилить это в любой алгоритм обучения машины.

Текст не может быть использован непосредственно в качестве входа в модель обучения машины, но сначала необходимо представить в числовом формате. Это известно как текстовое представление.

CountVectorizer.

CountVectorizer предоставляет простым способом для вектора и представляют собой коллекцию текстовых документов. Он токенизует входной текст и создает словарный запас известных слов, а затем представляет документы, использующие этот словарный запас.

Давайте понять это, используя пример,

text = ["She sells seashells in the seashore"]
# create the transform
vectorizer = CountVectorizer()
# tokenize and build vocab
vectorizer.fit(text)
# summarize
print(vectorizer.vocabulary_)
# encode document
vector = vectorizer.transform(text)
# summarize encoded vector
print(vector.shape)
print(type(vector))
print(vector.toarray())

Вы можете видеть, что Coutvectorizer построил словарный запас из данного текста, а затем представлял слова, используя Numpy Redry Matrix. Мы можем попытаться передать другой текст, используя этот словарный запас и соблюдайте вывод, чтобы получить лучшее понимание.

vector=vectorizer.transform(["I sell seashells in the seashore"])
vector.toarray()

Ты это видишь:

  • Индексные позиции 3 и 4 имеют Zeroes, означающие, что эти два слова нет в нашем словаре, и все остальные позиции имеют 1, что означает, что эти слова присутствуют в нашем словаре. Соответствующие слова, отсутствующие из словаря, «продают» и «она». Теперь, когда вы понимаете, как работает Coutvectorizer, мы можем соответствовать и преобразовать наш корпус, используя его.
vec=CountVectorizer(max_df=10,max_features=10000)
vec.fit(df.question_text.values)
vector=vec.transform(df.question_text.values)

Вы должны знать, что CountVectorizer имеет несколько важных параметров, которые вы должны приспособиться к вашей проблеме:

  • max_features : Создайте словарь, который рассматривает только топ-н-токены, заказываемые терминой частотой через корпус.
  • min_df : При создании словарного словаря игнорировать термины, которые имеют частоту токена строго ниже данного порога
  • max_df : При построении словарного словари игнорировать термины, которые имеют частоту токена строго выше данного порога.

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

Одной из проблем с COMPVEXTERIZER заключается в том, что общие слова, такие как «The», появятся много раз (если вы не удалите их на стадии предварительной обработки), и эти слова на самом деле не важны. Одна популярная альтернатива – Tfidfvectorizer. Это аббревиатура для Термин частотно-обратная частота документа.

  • Термин частота : Это суммирует, как часто данное слово появляется в документе.
  • Обратная частота документа : Это нисходящие слова, которые много появляются через документы.

Давайте посмотрим на пример:

from sklearn.feature_extraction.text import TfidfVectorizer
# list of text documents
text = ["She sells seashells by the seashore","The sea.","The seashore"]
# create the transform
vectorizer = TfidfVectorizer()
# tokenize and build vocab
vectorizer.fit(text)
# summarize
print(vectorizer.vocabulary_)
print(vectorizer.idf_)
# encode document
vector = vectorizer.transform([text[0]])
# summarize encoded vector
print(vector.shape)
print(vector.toarray())

Словочный словарь состоит из 6 слов, а частота обратного документа рассчитывается для каждого слова, присваивая наименьшему баллу на «The», произошедшее 4 раза.

Затем оценки нормализуются между 0 и 1, и это представление текста может использоваться в качестве ввода в любую модель обучения машины.

Большая проблема с приведенными выше подходами состоит в том, что контекст слова теряется при его предложении. Встроенные вложения слова обеспечивают гораздо лучшее представление слов в NLP, кодируя некоторую контекстную информацию. Это обеспечивает сопоставление от слова до соответствующего n-мерного вектора.

Word2Vec был разработан в Google от Tomas Mikolov et al. и использует Неглубокая нейронная сеть изучать слов вложения. Векторы изучены путем понимания контекста, в котором происходит слово. В частности, он смотрит на сопряженные слова.

Ниже приведена матрица соэлемента для предложения «Кошка сидела на коврике».

Word2Vec состоит из двух разных моделей:

  • Непрерывная сумка слов (Глобина) Модель можно подумать о том, как изучать сложные вложения, обучая модель прогнозировать слово, учитывая его контекст .
  • Skip-Gram Модель является противоположным, изученным словом вложения, обучение модели для Предсказать контекст с учетом слова Отказ Основная идея вложения слова – это слова, которые происходят в аналогичном контексте, как правило, ближе друг к другу в векторном пространстве. Давайте проверим, как реализовать Word2Vec в Python.
import gensim
from gensim.models import Word2Vec

model = gensim.models.Word2Vec(corpus, 
                               min_count = 1, size = 100, window = 5)

Теперь вы создали свою модель Word2Vec, некоторые из важных параметров, которые вы можете на самом деле изменить и наблюдать, как различия,

  • Размер : Это указывает размер вложения результирующего вектора для каждого слова.
  • min_count : При создании словарного словаря игнорировать термины, которые имеют частоту документа строго ниже данного порога
  • окно : Количество слов, окружающих слово, считается при построении представления. Также известен как размер окна. В этой статье мы ориентируемся на прагматические подходы для небольших наборов данных, и мы будем использовать предварительно обученные векторы Word Word вместо учебных векторов из нашего корпуса. Этот метод гарантированно дает лучшую производительность.

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

from  gensim.models.KeyedVectors import load_word2vec_format

def load_word2vec():
    word2vecDict = load_word2vec_format(
        '../input/word2vec-google/GoogleNews-vectors-negative300.bin',
        binary=True, unicode_errors='ignore')
    embeddings_index = dict()
    for word in word2vecDict.wv.vocab:
        embeddings_index[word] = word2vecDict.word_vec(word)

    return embeddings_index

Давайте проверим встраивание,

w2v_model=load_word2vec()
w2v_model['London'].shape

Вы можете видеть, что слово представлено с использованием 300-мерного вектора. Таким образом, каждое слово в вашем корпусе может быть представлено так, как это, и эта матрица встраивания используется для обучения вашей модели.

Теперь давайте узнаем о FastText, который является чрезвычайно полезным модулем, доступным в Генсим . FastText был разработан Facebook и дает отличную производительность и скорость в задачах текстовых классификаций.

Он поддерживает как непрерывную сумку слов, так и модели Skip-Gram. Основное отличие предыдущих моделей и FastText – это то, что он нарушает слово в нескольких н-граммах Отказ

Давайте возьмем слово апельсин, например.

Трешивания слов апельсина, org, Ran, ang, zge (игнорирование начальных и окончательных границ слова).

Слово Встраивание вектор (текстовое представление) для апельсина будет суммой этих N-граммов Отказ Редкие слова или опечатки теперь могут быть правильно представлены, поскольку весьма вероятно, что некоторые их N-граммы также появляются другими словами.

Например, для слова, такого как пастуофантантичноfantastic, который, возможно, никогда не был в каком-либо корпусе, Gensim может вернуть любые два из следующих решений: нулевой вектор или случайный вектор с низкой величиной.

FastText Однако, однако, может производить лучшие векторы, нарушая слово в куски и использование векторов для тех кусков для создания конечного вектора для слова. В этом конкретном случае последний вектор может быть ближе к векторами фантастической и фантастической.

Опять же, мы будем использовать предварительно обученную модель, а не обучение нашим собственным встраиванию слов.

Для этого вы можете скачать предварительно обученные векторы отсюда.

Каждая строка этого файла содержит слово, и это соответствующий N-мерный вектор. Мы создадим словарь, используя этот файл для сопоставления каждого слова в его векторное представление.

from gensim.models import FastText 

def load_fasttext():

    print('loading word embeddings...')
    embeddings_index = {}
    f = open('../input/fasttext/wiki.simple.vec',encoding='utf-8')
    for line in tqdm(f):
        values = line.strip().rsplit(' ')
        word = values[0]
        coefs = np.asarray(values[1:], dtype='float32')
        embeddings_index[word] = coefs
    f.close()
    print('found %s word vectors' % len(embeddings_index))

    return embeddings_index

embeddings_index=load_fastext()

Давайте проверим встраиваемое для слова,

embeddings_index['london'].shape

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

Для этого мы будем использовать предварительно обученные векторы перчатки, которые обучены крупным корпорацией. Это гарантированно выполнять лучше практически в любой ситуации. Вы можете скачать его отсюда.

После загрузки мы можем загрузить нашу предварительно обученную модель слов. До этого вы должны понимать формат, в котором он доступен. Каждая строка содержит слово и его соответствующее N-мерное векторное представление. Так,

Итак, чтобы использовать это, вы должны сначала приготовить словарь, который содержит сопоставление между Word и соответствующим вектором. Это можно назвать встроенным словаре.

Давайте создадим один для нашей цели.

def load_glove():
    embedding_dict = {}
    path = '../input/glove-global-vectors-for-word-representation/glove.6B.100d.txt'
    with open(path, 'r') as f:
        for line in f:
            values = line.split()
            word = values[0]
            vectors = np.asarray(values[1:], 'float32')
            embedding_dict[word] = vectors
    f.close()

    return embedding_dict


embeddings_index = load_glove()

Теперь у нас есть словарь, содержащий каждое слово в перчатке предварительно обученные векторы и их соответствующий вектор в словаре. Давайте проверим вложение для слова.

embeddings_index['london'].shape

Универсальное кодирование предложения

До сих пор мы имели дело с представлением слов, и эти методы наиболее полезны для операций уровня слов. Иногда нам нужно исследовать операции уровня наказания. Эти энкодеры называются рекодерами предложения.

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

Например,

  • Сегодня солнечно
  • Сегодня дождливо
  • Это облачно сегодня. Эти предложения будут кодированы и представлены так, чтобы они были близки друг к другу в векторном пространстве.

Давайте перейдем и проверьте, как реализовать Enternal Encoder предложений и найти аналогичные предложения, используя его.

Вы можете скачать оригинальные векторы отсюда.

Мы загрузим модуль, используя концентратор Tensorflow.

module_url = "../input/universalsentenceencoderlarge4"
# Import the Universal Sentence Encoder's TF Hub module
embed = hub.load(module_url)

Далее мы создадим встраивание для каждого предложения в нашем списке.

sentence_list=df.question_text.values.tolist()
sentence_emb=embed(sentence_list)['outputs'].numpy()

Вот статья на Узнайте больше о Universal Encoder предложений.

При использовании любого из вышеперечисленных методов вложения ОДИН ОДИН ЗАКЛЮЧИТЕ о том, является контекст, в котором использовался слово. Это Один из главных недостатков таких моделей представления слов.

Например, слово слово «палочка» будет представлено с использованием того же вектора, независимо от контекста, в котором он использовался, который не имеет большого смысла. С недавним событиями в области NLP и моделей, таких как Bert (однонаправленное представление энкодера от трансформаторов), это было сделано возможным. Вот статья для Подробнее.

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

Давайте создадим index index и исправить максимальное длину предложения, поступайте каждое предложение в нашем корпусе, используя Keras Tokenizer и Pad_sewends.

MAX_LEN=50
tokenizer_obj=Tokenizer()
tokenizer_obj.fit_on_texts(corpus)
sequences=tokenizer_obj.texts_to_sequences(corpus)

tweet_pad=pad_sequences(sequences,
                        maxlen=MAX_LEN,
                        truncating='post',
                        padding='post')

Давайте проверим количество уникальных слов в нашем корпусе,

word_index=tokenizer_obj.word_index
print('Number of unique words:',len(word_index))

Использование этого словаря и встраиваемого словаря INDEXARE и встраивании вы можете создать Встраивание матрицы для нашего корпуса. Эта матрица вложения передается на Слой встраивания из нейронной сети для изучения слов представлений.

def prepare_matrix(embedding_dict, emb_size=300):
    num_words = len(word_index)
    embedding_matrix = np.zeros((num_words, emb_size))

    for word, i in tqdm(word_index.items()):
        if i > num_words:
            continue

    emb_vec = embedding_dict.get(word)
    if emb_vec is not None:
        embedding_matrix[i] = emb_vec

    return embedding_matrix

Мы можем определить нашу нейронную сеть и передавать этот индекс вложения на слой встраивания сети. Мы пропускаем векторы на слой встраивания и установить тренируемый = Ложь Для предотвращения обновления весов.

def new_model(embedding_matrix):
    inp = Input(shape=(MAX_LEN,))

    x = Embedding(num_words, embedding_matrix.shape[1], weights=[embedding_matrix],
                  trainable=False)(inp)

    x = Bidirectional(
        LSTM(60, return_sequences=True, name='lstm_layer', 
             dropout=0.1, recurrent_dropout=0.1))(x)

    x = GlobalAveragePool1D()(x)
    x = Dense(1, activation="sigmoid")(x)
    model = Model(inputs=inp, outputs=x)

    model.compile(loss='binary_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])

    return model

Например, для запуска модели с помощью вложений Word2Vec,

embeddings_index=load_word2vec()
embedding_matrix=prepare_matrix(embeddings_index)
model=new_model(embedding_matrix)

history=model.fit(X_train,y_train,
                  batch_size=8,
                  epochs=5,
                  validation_data=(X_test,y_test),
                  verbose=2)

Вы можете вызвать нужный тип вложений и выполнить те же шаги для реализации любого из них.

Итак, какой метод текстовых классификаций работал лучше всего в нашей примерной проблеме?

Вы можете использовать Neptune для сравнения производительности нашей модели, используя различные вложения, просто настроив эксперимент.

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

Вы можете Исследуйте эксперименты Здесь, если вы хотите.

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

Надеюсь, вы найдете их полезными в ваших проектах.

Эта статья была изначально Опубликовано на neptune.ml/blog Где вы можете найти более глубокие статьи для машинного обучения практикующих.

Оригинал: “https://dev.to/jakubczakon/document-classification-7-pragmatic-approaches-for-small-datasets-5ej7”