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

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

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

Хотя предварительно обученные встраивания слов, такие как Word2Vec или GloVe, доступны в Интернете и могут быть легко использованы для различных задач NLP, они обычно обучаются на общих текстовых данных и могут не учитывать нюансы, специфичные для предметной области или задачи. В таких случаях может быть полезным обучение встраиванию конкретных слов в специализированные наборы данных. Индивидуальные встраивания, обученные для конкретных областей или вариантов использования, могут лучше отражать тонкости и контекст целевых данных, что приводит к повышению производительности в последующих задачах НЛП.

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

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

Встраивание слов в зависимости от регистра

!wget -nc https://lazyprogrammer.me/course_files/nlp/bbc_text_cls.csv

from keras.models import Sequential
from keras.layers import Embedding, Dense, Input
from keras.models import Model
from keras.preprocessing.text import Tokenizer
from keras.utils import pad_sequences
import numpy as np

bbc_text = pd.read_csv('bbc_text_cls.csv')

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

##### selecting only sport news since we want topic specific suggestions #####

sport_df = bbc_text[bbc_text['labels'] == 'sport']

corpus = sport_df['text']
corpus = corpus[0:100] ### selecting first 100 sentences for faster training ######

Определение словаря и токенизация корпуса:

# Define the vocabulary
vocab = set()
for sentence in corpus:
    for word in sentence.split():
        vocab.add(word)
vocab_size = len(vocab)

# Tokenize the corpus

tokenizer = Tokenizer()
tokenizer.fit_on_texts(corpus)
sequences = tokenizer.texts_to_sequences(corpus)

# Set hyperparameters

embedding_dim = 100
window_size = 2
num_epochs = 100

Генерация пар слов в качестве входных и выходных пар для скип-грамм:

# Generate word pairs as input-output pairs for skip-gram
word_pairs = []
for sequence in sequences:
    for i in range(len(sequence)):
        for j in range(max(0, i - window_size), min(i + window_size + 1, len(sequence))):
            if i != j:
                word_pairs.append((sequence[i], sequence[j]))

# Prepare input and output data

input_data, output_data = zip(*word_pairs)
input_data = np.array(input_data)
output_data = np.array(output_data)

# Define the model architecture
input_layer = Input(shape=(1,))
embedding_layer = Embedding(vocab_size, embedding_dim)(input_layer)
output_layer = Dense(vocab_size, activation='softmax')(embedding_layer)

### using softmax as it is the standard algorithm to convert a input of K numbers into a probability distribution of K possible outcomes, which is what we need for this exercise ####

## Define the model ##

model = Model(inputs=input_layer, outputs=output_layer)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')

# Train the model
model.fit(input_data, output_data, epochs=num_epochs)
# Get the learned word embeddings

weights = model.layers[1].get_weights()[0]
# creating the embedding matrix

word_index = tokenizer.word_index
embedding_matrix = np.zeros((vocab_size, embedding_dim))
for word, i in word_index.items():
    if i < vocab_size:
        embedding_matrix[i] = weights[i]

Теперь мы собираемся использовать приведенную выше матрицу встраивания, чтобы вычислить слова, наиболее близкие к «разрывам», а затем сравнить результаты с тем, что мы получаем от встраивания предварительно обученных слов.

# Define a function to find the nearest words to a given word
def find_nearest_words(word, embeddings, vocab, n=5):
    # Get the index of the word in the vocabulary
    word_index = vocab.index(word)
    # Get the word embedding
    word_embedding = embeddings[word_index]
    # Compute the cosine similarity between the word embedding and all other word embeddings
    cosine_similarities = np.dot(embeddings, word_embedding) / (np.linalg.norm(embeddings, axis=1) * np.linalg.norm(word_embedding))
    # Get the indices of the most similar words
    nearest_indices = cosine_similarities.argsort()[-n-1:-1][::-1]
    # Get the most similar words
    nearest_words = [vocab[i] for i in nearest_indices]
    return nearest_words

# Find the nearest words to the word 'sentence'
nearest_words = find_nearest_words('breaks', embedding_matrix, list(vocab))
print("Nearest words to 'sentence':", nearest_words)
Nearest words to 'breaks': ['19-year-old.', 'passing', 'predict', '3:49.78.', 'who']

Предварительно обученные встраивания

Мы будем использовать эмбеддинг Glove, созданный Стэнфордским университетом.

import gensim.downloader as api

# Load pre-trained word embeddings
embedding_model = api.load("glove-wiki-gigaword-100")
word = "breaks"
nearest_words = embedding_model.most_similar(word)

# Print the nearest words
print("Nearest words to '{}':".format(word))
for word, similarity in nearest_words:
    print(word, similarity)
Nearest words to 'breaks': ['break', 'gets', 'breaking', 'goes', 'cut']

Результаты

Как видно из предыдущего примера, модель, обученная для конкретного варианта использования, даже с небольшим набором данных, состоящим всего из 100 предложений, дает более релевантные с точки зрения контекста результаты по сравнению с использованием предварительно обученной модели, полученной из Интернета. Например, когда мы вводим слово «перерывы» в нашу специально обученную модель, она точно связывает его с такими понятиями, как «рекорд» и «19 лет». менее конкретные словесные ассоциации. Это подчеркивает преимущество обучающих вложений, адаптированных к конкретной области или задаче, поскольку они могут фиксировать семантику, специфичную для предметной области, и давать более значимые результаты.

Подпишитесь на меня в LinkedIn:

https://www.linkedin.com/in/harshharsh/