Продолжая предыдущую историю, в этом посте мы рассмотрим пример подготовки текста для анализа настроений набора данных обзора фильмов. Этот образец набора данных можно найти по адресу: http://www.cs.cornell.edu/people/pabo/movie-review-data/review_polarity.tar.gz.
Набор данных подразделяется на положительные отзывы и отрицательные отзывы; все положительные отзывы хранятся в каталоге pos, а все отрицательные — в каталоге neg. Каждый отзыв находится в отдельном файле.
Во-первых, нам нужно разделить данные на данные обучения и данные тестирования до какой-либо подготовки данных. Это означает, что любые знания в тестовом наборе, которые могли бы помочь нам лучше подготовить данные, недоступны во время подготовки данных и обучения модели. В этом примере мы будем использовать 10% данных для тестирования и 90% для обучения.
Следовательно, нам нужно выполнить следующие шаги:
В качестве первого шага нам нужно загрузить все обзоры в память. Следующий код отвечает за загрузку всех обучающих файлов, которые хранятся в указанной директории, в нашем случае это означает, что будет загружено 90% файлов:
from os import listdir # load training documents only in a directory def process_documents_for_vocabulary(directory, vocabulary): # walk through all files and folders i = 0 print("Total number of file = %s" % len(listdir(directory))) for fileName in listdir(directory): # only training files if fileName.startswith('cv9') or not fileName.endswith('.txt'): continue # create the full path of the file to open path = directory + '/' + fileName i += 1 print("File number = ", i, " - ", path) # add to vocabulary add_document_to_vocabulary(path, vocabulary)
Мы не загружаем файлы, начинающиеся с cv9 или не имеющие расширения .txt. Все файлы загружаются в словарь.
# load documents into memory def load_document(fileName): # open the file as read only file = open(fileName, 'r') # read all text text = file.read() # close the file file.close() return text # add document to vocabulary def add_document_to_vocabulary(fileName, vocabulary): # load document document = load_document(fileName) # clean document tokens = clean_tokens(document) # update counts vocabulary.update(tokens)
Следующим шагом будет очистка данных. Будут выполнены следующие этапы очистки:
- Удалите все знаки препинания из слов
- Удалить токены, которые являются просто знаками препинания
- Удалить жетоны, содержащие числа
- Удалите токены, которые имеют только один символ
- Удалите токены, которые не имеют большого значения, такие как «или» или «и».
И вот пример кода, который делает именно это:
# clean and tokenize def clean_tokens(document): # split document into tokens by white space tokens = document.split() # punctuation removal remove_punctuation = re.compile('[%s]' % re.escape(string.punctuation)) tokens = [remove_punctuation.sub('', w) for w in tokens] # remove remaining tokens that are not alphabetic tokens = [word for word in tokens if word.isalpha()] # filter out stop words stop_words = set(stopwords.words('english')) tokens = [w for w in tokens if not w in stop_words] # filter out short tokens tokens = [word for word in tokens if len(word) > 1] return tokens
Словарный запас может стать огромным. Частью подготовки анализа тональности является определение и адаптация словаря слов, поддерживаемых моделью. Можно принять решение о поддержке всех слов, встречающихся в тексте, или отбросить некоторые из них в зависимости от количества вхождений. Окончательный набор можно в конце сохранить в файл для дальнейшего использования.
# constants minimumOccurence = 2 # keep only tokens that occure at least 5 times tokens = [i for i,j in vocabulary.items() if j >= minimumOccurence]
После создания словаря данные сохраняются в файловой системе.
# save list to file def save_list(lines, filename): data = '\n'.join(lines) file = open(filename, 'w') file.write(data) file.close()
Это все, что нужно сделать для того, чтобы создать наш словарный запас. Обратите внимание, что мы не использовали тестовые данные для нашего словаря. Вот полный код для создания словаря.
from os import listdir from nltk.corpus import stopwords from collections import Counter import re import string # constants vocabularyFileName = 'vocabulary.txt' negativeDirectory = 'review_polarity/txt_sentoken/neg' positiveDirectory = 'review_polarity/txt_sentoken/pos' minimumOccurence = 2 # initiate vocabulary = Counter() # save list to file def save_list(lines, filename): data = '\n'.join(lines) file = open(filename, 'w') file.write(data) file.close() # load documents into memory def load_document(fileName): # open the file as read only file = open(fileName, 'r') # read all text text = file.read() # close the file file.close() return text # clean and tokenize def clean_tokens(document): # split document into tokens by white space tokens = document.split() # punctuation removal remove_punctuation = re.compile('[%s]' % re.escape(string.punctuation)) tokens = [remove_punctuation.sub('', w) for w in tokens] # remove remaining tokens that are not alphabetic tokens = [word for word in tokens if word.isalpha()] # filter out stop words stop_words = set(stopwords.words('english')) tokens = [w for w in tokens if not w in stop_words] # filter out short tokens tokens = [word for word in tokens if len(word) > 1] return tokens # add document to vocabulary def add_document_to_vocabulary(fileName, vocabulary): # load document document = load_document(fileName) # clean document tokens = clean_tokens(document) # update counts vocabulary.update(tokens) # load training documents only in a directory def process_documents_for_vocabulary(directory, vocabulary): # walk through all files and folders i = 0 print("Total number of file = %s" % len(listdir(directory))) for fileName in listdir(directory): # only training files if fileName.startswith('cv9') or not fileName.endswith('.txt'): continue # create the full path of the file to open path = directory + '/' + fileName i += 1 print("File number = ", i, " - ", path) # add to vocabulary add_document_to_vocabulary(path, vocabulary) # define vocabulary vocabulary = Counter() # add all documents to vocabulary process_documents_for_vocabulary(negativeDirectory, vocabulary) process_documents_for_vocabulary(positiveDirectory, vocabulary) # Vocabulary size print("Vocabulary size: ", len(vocabulary)) # keep only tokens that occure at least 5 times tokens = [i for i,j in vocabulary.items() if j >= minimumOccurence] # save vocabulary to the file for later use save_list(tokens, vocabularyFileName) ### End of first step #### ### Report ### print('*********************************************') print ('Report') print('---------------------------------------------') # print the size of vocabulary print("Vocabulary size: ", len(vocabulary)) # how many tokens do we have now print("Reduced vocabulary size: ", len(tokens))
И в итоге получаем следующее:
Отчет
— — — — — — — — — — — — — — — — — — — — — -
Размер словарного запаса: 44276
Сокращенный размер словаря: 25767
Файл «vocabulary.txt» сохранен в файловой системе.
Резюме
Надеюсь, вам понравилось это чтение. Теперь, когда у нас есть подготовленный словарь, нашим следующим шагом будет токенизация словаря и построение модели глубокого обучения для анализа настроений. Мы рассмотрим эти темы в нашем следующем рассказе.
использованная литература
- Глубокое обучение с помощью Python, Франсуа Шолле, ISBN 9781617294433
- Искусственный интеллект для людей, том 1: основные алгоритмы, Джефф Хитон, ISBN978–1493682225
- Искусственный интеллект для людей, том 3: глубокое обучение и нейронные сети, Джефф Хитон, ISBN978–1505714340
- Разработка моделей глубокого обучения на Theano и TensorFlow с использованием Keras, Джейсон Браунли
- Глубокое обучение, Ян Гудфеллоу, Йошуа Бенджио и Аарон Курвиль, ISBN 9780262035613
- Нейронные сети и обучающие машины, Саймон Хейкин, ISBN 9780131471399
- Dropout: простой способ предотвратить переобучение нейронных сетей, Нитиш Сривастава, Джеффри Хинтон, Алекс Крижевский, Илья Суцкевер и Руслан Салахутдинов