Вложения слов — это числовые представления слов или фраз в многомерном векторном пространстве, где геометрические отношения между векторами фиксируют семантическое и синтаксическое сходство между соответствующими словами. Эти представления позволяют моделям машинного обучения понимать и обрабатывать естественный язык более осмысленным образом.
В традиционных подходах НЛП слова представлялись с помощью разреженных векторов с горячим кодированием, где каждое слово имело уникальный индекс в большом словаре. Однако этому представлению не хватает способности фиксировать отношения и контекстуальное значение между словами. Вложения слов устраняют это ограничение, назначая словам плотные, непрерывные векторные представления, что позволяет использовать более тонкие и контекстуальные представления слов.
Встраивания слов обычно изучаются путем обучения моделей на больших текстовых корпусах с использованием таких методов, как 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: