Введение
Одним из самых больших прорывов, необходимых для достижения любой степени или уровня искусственного интеллекта, является наличие машин, которые могут обрабатывать текстовые данные. К счастью, объем текстовых данных во всем мире за последние годы вырос в геометрической прогрессии. Это также требует от людей срочного извлечения новых знаний и новых точек зрения из текстовых данных. От анализа социальных сетей до управления рисками и защиты от киберпреступлений обработка текстовых данных никогда не была так важна.
image
В этой статье мы обсудим различные методы извлечения признаков, начиная с некоторых основных методов и постепенно погружаясь в продвинутые методы обработки естественного языка. Мы также узнаем, как предварительно обрабатывать текстовые данные, чтобы можно было извлечь лучшие функции из «чистых» данных.
содержание
- Базовое извлечение знаков из текстовых данных
- число слов
- количество символов
- средняя длина слова
- количество стоп-слов
- количество специальных символов
- Количество номеров
- количество заглавных букв
- Базовая предварительная обработка текстовых данных
- преобразование нижнего регистра
- убрать знаки препинания
- удалить стоп-слова
- удалить частые слова
- удалить разреженные слова
- исправление орфографии
- токенизация
- Стемминг
- лемматизация
- Расширенная обработка текста
- Языковая модель N-грамм
- частота слов
- Частота обратного документа
- TF-IDF
- мешок слов
- анализ эмоций
- вложение слов
1. Извлечение основных признаков
Даже если у нас нет достаточных знаний об NLP, мы можем использовать python для извлечения нескольких основных функций текстовых данных. Прежде чем мы начнем, мы используем pandas для загрузки набора данных для последующего использования в других задачах.Набор данных представляет собой текстовый набор данных о настроениях в Твиттере.
import pandas as pd
train=pd.read_csv("files/data/python46-data/train_E6oV3lV.csv")
print(train.head(10))
id label tweet
0 1 0 @user when a father is dysfunctional and is s...
1 2 0 @user @user thanks for #lyft credit i can't us...
2 3 0 bihday your majesty
3 4 0 #model i love u take with u all the time in ...
4 5 0 factsguide: society now #motivation
5 6 0 [2/2] huge fan fare and big talking before the...
6 7 0 @user camping tomorrow @user @user @user @use...
7 8 0 the next school year is the year for exams.ð��...
8 9 0 we won!!! love the land!!! #allin #cavs #champ...
9 10 0 @user @user welcome here ! i'm it's so #gr...
1.1 Количество словарного запаса
Для каждого твита одной из основных характеристик, которую мы можем извлечь, является количество слов. Первоначальная цель этого состоит в том, что обычно негативные комментарии содержат больше слов, чем позитивные комментарии.
Мы можем просто вызвать функцию split, чтобы разделить предложение:
train['word_count']=train['tweet'].apply(lambda x:len(str(x).split(" ")))
train[['tweet','word_count']].head()
1.2 Количество символов
Причина выбора количества символов в качестве признака такая же, как и для предыдущего признака. Здесь мы подсчитываем количество символов в твите непосредственно из длины строки.
train['char_count']=train['tweet'].str.len()
train[['tweet','char_count']].head()
УведомлениеКоличество строк здесь включает в себя количество пробелов в твите, мы удалим их по мере необходимости
1.3 Средняя длина словарного запаса
Затем мы вычисляем среднюю длину словарного запаса каждого твита в качестве еще одной функции, которая может помочь нам улучшить модель. Средняя длина словарного запаса рассчитывается путем деления длины всех слов в каждом твите на количество слов в каждом твите.
def avg_word(sentence):
words=sentence.split()
return (sum(len(word) for word in words)/len(words))
train['avg_word']=train['tweet'].apply(lambda x:avg_word(x))
train[['tweet','avg_word']].head()
1.4 Количество стоп-слов
Обычно при решении задач НЛП первоочередной задачей является удаление стоп-слов. Но иногда подсчет количества стоп-слов может дать дополнительную информацию, которую мы потеряли ранее. Вот объяснение стоп-слов:
Для экономии места на диске и повышения эффективности поиска поисковые системы автоматически игнорируют определенные слова или слова при индексации страниц или обработке поисковых запросов, которые называются стоп-словами. Вообще говоря, стоп-слова можно условно разделить на следующие две категории:
- Эти слова широко используются и их можно увидеть повсюду в Интернете. Например, слово "Web" встречается почти на каждом веб-сайте. Для таких слов поисковые системы не могут гарантировать, что они могут давать действительно релевантные результаты поиска, и их трудно помогают сузить область поиска, но и снижают эффективность поиска;
- Этих типов больше, включая модальные частицы, наречия, предлоги, союзы и т. д., которые обычно сами по себе не имеют ясного значения и имеют определенный эффект только тогда, когда они помещены в законченное предложение, например, обычное «de». ", "в" и т.
Здесь мы импортируем модуль стопворс из библиотеки NLTK.
from nltk.corpus import stopwords
stop=stopwords.words('english')
train['stopwords']=train['tweet'].apply(lambda sen:len([x for x in sen.split() if x in stop]))
train[['tweet','stopwords']].head()
1.5 Количество специальных символов
Интересной особенностью является количество символов «#» и «@», которые мы можем извлечь из каждого твита. Это также помогает нам извлекать больше информации из текстовых данных.
Здесь мы используемstartswith
функция для обработки
train['hashtags']=train['tweet'].apply(lambda sen:len([x for x in sen.split() if x.startswith("#")]))
train[['tweet','hashtags']].head()
1.6 Количество номеров
Эта функция обычно не используется, но количество цифр является полезной функцией при выполнении аналогичных задач.
train['numerics']=train['tweet'].apply(lambda sen:len([x for x in sen.split() if x.isdigit()]))
train[['tweet','numerics']].head()
1.7 Количество слов с заглавной буквы
«Гнев» или «Ярость» обычно пишутся прописными буквами, поэтому необходимо идентифицировать эти слова.
train['upper']=train['tweet'].apply(lambda sen:len([x for x in sen.split() if x.isupper()]))
train[['tweet','upper']].head()
2 Предварительная обработка текстовых данных
До сих пор мы научились извлекать основные функции из текстовых данных. Прежде чем погрузиться в извлечение текста и функций, нашим первым шагом должна быть очистка данных для улучшения функций.
Мы добьемся этого, выполнив некоторые основные шаги предварительной обработки обучающих данных.
2.1 Преобразование нижнего регистра
Первый шаг в предварительной обработке, который мы собираемся сделать, это перевести наши твиты в нижний регистр. Это позволяет избежать создания нескольких копий одного и того же. Например, когда мы подсчитываем словарь слов, «аналитика» и «аналитика» будут рассматриваться как разные слова.
train['tweet']=train['tweet'].apply(lambda sen:" ".join(x.lower() for x in sen.split()))
train['tweet'].head()
0 @user when a father is dysfunctional and is so...
1 @user @user thanks for #lyft credit i can't us...
2 bihday your majesty
3 #model i love u take with u all the time in ur...
4 factsguide: society now #motivation
Name: tweet, dtype: object
2.2 Удалить знаки препинания
Следующим шагом является удаление знаков препинания, так как они не добавляют никакой дополнительной информации к текстовым данным. Таким образом, удаление всех символов поможет нам уменьшить размер обучающих данных.
train['tweet'] = train['tweet'].str.replace('[^\w\s]','')
train['tweet'].head()
0 user when a father is dysfunctional and is so ...
1 user user thanks for lyft credit i cant use ca...
2 bihday your majesty
3 model i love u take with u all the time in urð...
4 factsguide society now motivation
Name: tweet, dtype: object
Как видно из приведенного выше вывода, все знаки препинания, включая «#» и «@», были удалены из обучающих данных.
2.3 Удаление стоп-слов
Как мы обсуждали ранее, стоп-слова (или общеупотребительные слова) должны быть удалены из текстовых данных. Для этой цели мы можем создать список стоп-слов в виде нашей собственной библиотеки стоп-слов или использовать предопределенную библиотеку.
from nltk.corpus import stopwords
stop=stopwords.words('english')
train['tweet']=train['tweet'].apply(lambda sen:" ".join(x for x in sen.split() if x not in stop))
train['tweet'].head()
0 user father dysfunctional selfish drags kids d...
1 user user thanks lyft credit cant use cause do...
2 bihday majesty
3 model love u take u time urð ðððð ððð
4 factsguide society motivation
Name: tweet, dtype: object
2.4 Удаление общих слов
Сначала мы можем удалить общие слова из текстовых данных, давайте проверим 10 наиболее часто встречающихся слов в текстовых данных, а затем вызовем удаление или сохранение.
freq=pd.Series(' '.join(train['tweet']).split()).value_counts()[:10]
freq
user 17473
love 2647
ð 2511
day 2199
â 1797
happy 1663
amp 1582
im 1139
u 1136
time 1110
dtype: int64
Теперь давайте избавимся от этих слов, потому что они не влияют на нашу классификацию текстовых данных.
freq=list(freq.index)
freq
['user', 'love', 'ð', 'day', 'â', 'happy', 'amp', 'im', 'u', 'time']
train['tweet']=train['tweet'].apply(lambda sen:' '.join(x for x in sen.split() if x not in freq))
train['tweet'].head()
0 father dysfunctional selfish drags kids dysfun...
1 thanks lyft credit cant use cause dont offer w...
2 bihday majesty
3 model take urð ðððð ððð
4 factsguide society motivation
Name: tweet, dtype: object
2.5 Удаление редких слов
Опять же, поскольку мы удаляем самые распространенные слова, на этот раз давайте удалим из текста редко встречающиеся слова. Поскольку они встречаются редко, связь между ними и другими словами в основном шумовая. Редкие слова можно заменить более общими формами, которые в этом случае будут иметь большее значение.
freq = pd.Series(' '.join(train['tweet']).split()).value_counts()[-10:]
freq
happenedâ 1
britmumspics 1
laterr 1
2230 1
dkweddking 1
ampsize 1
moviescenes 1
kaderimsin 1
nfinity 1
babynash 1
dtype: int64
freq = list(freq.index)
train['tweet'] = train['tweet'].apply(lambda x: " ".join(x for x in x.split() if x not in freq))
train['tweet'].head()
0 father dysfunctional selfish drags kids dysfun...
1 thanks lyft credit cant use cause dont offer w...
2 bihday majesty
3 model take urð ðððð ððð
4 factsguide society motivation
Name: tweet, dtype: object
Все эти шаги предварительной обработки необходимы, чтобы помочь нам уменьшить словарный шум, что в конечном итоге дает более эффективные функции.
2.6 Проверка орфографии
Мы все видели твиты с множеством орфографических ошибок. Трудно обнаружить эти ошибки за самое короткое время, когда мы в спешке рассылаем твиты. Орфографическая коррекция является полезным шагом предварительной обработки в этом отношении, так как она также помогает нам уменьшить количество копий слов. Например, "аналитика" и "аналитика" будут считаться разными словами, даже если они используются в одном и том же смысле.
Для этого воспользуемся библиотекой textblob.
TextBlob — это библиотека обработки текста с открытым исходным кодом, написанная на Python. Его можно использовать для выполнения многих задач обработки естественного языка, таких как тегирование частей речи, извлечение компонентов существительных, анализ настроений, перевод текста и т. д. ты сможешьофициальная документацияОзнакомьтесь со всеми функциями TextBlog.
from textblob import TextBlob
train['tweet'][:5].apply(lambda x: str(TextBlob(x).correct()))
0 father dysfunctional selfish drags kiss dysfun...
1 thanks left credit can use cause dont offer wh...
2 midday majesty
3 model take or ðððð ððð
4 factsguide society motivation
Name: tweet, dtype: object
Обратите внимание, что для внесения этих исправлений потребуется много времени. Поэтому в учебных целях я показываю действие этой техники только на первые 5 рядов.
Также будьте осторожны перед использованием этого приема, потому что если в твите много аббревиатур, например, «твой» сокращен до «ур», он будет исправлен на «или».
2.7 Причастие
Токенизация относится к разделению текста на ряд слов или слов. В нашем примере мы использовали библиотеку textblob
TextBlob(train['tweet'][1]).words
WordList(['thanks', 'lyft', 'credit', 'cant', 'use', 'cause', 'dont', 'offer', 'wheelchair', 'vans', 'pdx', 'disapointed', 'getthanked'])
2.8 Стемминг
Лемматизация - это восстановление языкового словаря любой формы до общей формы (которая может выражать полную семантику) и извлечение основы.
(stemming) - это основа или корень извлеченного слова (не обязательно способная выразить полную семантику). Лемматизация и стемминг — два важных способа морфологической нормализации, оба из которых могут достичь цели эффективного слияния морфем, и между ними есть как связи, так и различия. Для получения подробной информации см.Стемминг и лемматизация
Stemming относится к удалению суффиксов слов, таких как «ing», «ly», «s» и т. д., с помощью метода, основанного на правилах.
from nltk.stem import PorterStemmer
st=PorterStemmer()
train['tweet'][:5].apply(lambda x:" ".join([st.stem(word) for word in x.split()]))
0 father dysfunct selfish drag kid dysfunct run
1 thank lyft credit cant use caus dont offer whe...
2 bihday majesti
3 model take urð ðððð ððð
4 factsguid societi motiv
Name: tweet, dtype: object
В приведенном выше выводе «нефункциональный» стал «нефункционирующим».
2.9 Частичное восстановление речи
Результат, полученный после процесса лемматизации, представляет собой полное слово с определенным значением, которое обычно является допустимым словом в словаре.
from textblob import Word
train['tweet']=train['tweet'].apply(lambda x:" ".join([Word(word).lemmatize() for word in x.split()]))
train['tweet'].head()
0 father dysfunctional selfish drag kid dysfunct...
1 thanks lyft credit cant use cause dont offer w...
2 bihday majesty
3 model take urð ðððð ððð
4 factsguide society motivation
Name: tweet, dtype: object
3 Расширенная обработка текста
На данный момент мы выполнили все основные шаги предварительной обработки, которые могут очистить наши данные. Теперь мы можем приступить к извлечению признаков с использованием методов НЛП.
3.1 N-grams
N-граммы, называемые языковыми моделями N-грамм, представляют собой комбинации нескольких слов и представляют собой статистическую языковую модель, используемую для прогнозирования n-го элемента на основе первых (n-1) элементов. Распространенными моделями являются униграммы, биграммы и триграммы.
Униграммы обычно содержат меньше информации, чем биграммы и триграммы, и языковые модели необходимо выбирать в соответствии с конкретным приложением, потому что, если n-граммы слишком короткие, важная информация не может быть получена в это время. С другой стороны, если n-граммы слишком длинные, захваченная информация будет в основном такой же, без каких-либо различий.
TextBlob(train['tweet'][0]).ngrams(2)
[WordList(['father', 'dysfunctional']),
WordList(['dysfunctional', 'selfish']),
WordList(['selfish', 'drag']),
WordList(['drag', 'kid']),
WordList(['kid', 'dysfunction']),
WordList(['dysfunction', 'run'])]
3.2 Частота слов
Частота употребления термина — это отношение количества раз, которое слово встречается в предложении, к количеству слов в предложении.
** TF = (Number of times term T appears in the particular row) / (number of terms in that row)**
tf1 = (train['tweet'][1:2]).apply(lambda x: pd.value_counts(x.split(" "))).sum(axis = 0).reset_index()
tf1.columns = ['words','tf']
tf1
3.3 Инвертировать частоту документа
Inverse Document Frequency (IDF), принцип работы которого можно понять просто: если слово встречается во всех документах, то это слово может быть не так важно для нас.
IDF слова — это отношение количества всех строк к количеству строк, в которых встречается это слово, и, наконец, логарифм.
IDF = log(N/n)
import numpy as np
for i,word in enumerate(tf1['words']):
tf1.loc[i, 'idf'] =np.log(train.shape[0]/(len(train[train['tweet'].str.contains(word)])))
tf1
3.4 Термин Частота документа с инвертированной частотой (TF-IDF)
TF-IDF=TF*
IDF
tf1['tfidf']=tf1['tf']*tf1['idf']
tf1
Мы видим, что TF-IDF «наказал» «не», «не могу» и «использовать», потому что они являются общими словами, а значения tf-idf ниже.
Кроме того, значение tf-idf можно рассчитать напрямую через sksklearn.
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(max_features=1000, lowercase=True, analyzer='word',
stop_words= 'english',ngram_range=(1,1))
train_vect = tfidf.fit_transform(train['tweet'])
train_vect
<31962x1000 sparse matrix of type '<class 'numpy.float64'>'
with 114055 stored elements in Compressed Sparse Row format>
3.5 Сумка слов
BOW заключается в том, чтобы рассматривать текст/запрос как набор слов. Так как слов много, складываем их в мешочки, которые для краткости называются мешочками слов. Что касается того, почему мы используем мешки вместо корзин или ведер, мы не знаем. Например:
文本1:苏宁易购/是/国内/著名/的/B2C/电商/之一
Это короткий текст. "/" как разделение между словами. Из этого мы видим, что этот текст содержит такие слова, как «Suning Tesco», «B2C», «Электронная коммерция» и так далее. Другими словами, набор слов текста состоит из таких слов, как «Suning Tesco» и «Электронная коммерция».
Для получения подробной информации см.Сумка слов и векторных моделей слов
from sklearn.feature_extraction.text import CountVectorizer
bow = CountVectorizer(max_features=1000, lowercase=True, ngram_range=(1,1),analyzer = "word")
train_bow = bow.fit_transform(train['tweet'])
train_bow
<31962x1000 sparse matrix of type '<class 'numpy.int64'>'
with 128402 stored elements in Compressed Sparse Row format>
3.6 Анализ настроений
Последняя задача, которую нам нужно решить, — это как выполнить анализ тональности твитов.Прежде чем использовать модель ML/DL, мы можем использовать библиотеку textblob для оценки тональности.
train['tweet'][:5].apply(lambda x:TextBlob(x).sentiment)
0 (-0.3, 0.5354166666666667)
1 (0.2, 0.2)
2 (0.0, 0.0)
3 (0.0, 0.0)
4 (0.0, 0.0)
Name: tweet, dtype: object
Используйте результат анализа тональности TextBlob, чтобы вернуть его в виде кортежа в форме (полярность, субъективность). Показатель полярности — это число с плавающей запятой в диапазоне [-1,0 , 1,0 ], где положительные числа указывают положительность, а отрицательные числа указывают негатив. субъективность — это число с плавающей запятой в диапазоне [0,0, 1,0], где 0,0 — объективно, а 1,0 — субъективно.
Ниже приведен простой пример
from textblob import TextBlob
testimonial = TextBlob("Textblob is amazingly simple to use. What great fun!")
print(testimonial.sentiment)
Sentiment(polarity=0.39166666666666666, subjectivity=0.4357142857142857)
train['sentiment'] = train['tweet'].apply(lambda x: TextBlob(x).sentiment[0] )
train[['id','tweet','sentiment']].head()
4.7 Вложения слов
Встраивание слов — это векторизованное представление текста, и основная идея заключается в том, что расстояние между векторами похожих слов относительно короткое.
from gensim.scripts.glove2word2vec import glove2word2vec
glove_input_file = 'glove.6B.100d.txt'
word2vec_output_file = 'glove.6B.100d.txt.word2vec'
glove2word2vec(glove_input_file, word2vec_output_file)
Суммировать
Благодаря этой статье я надеюсь, что вы получили общее представление об этапах обработки текстовых данных и выборе функций.Рекомендуется использовать методы машинного обучения или глубокого обучения для прогнозирования настроений на основе этих основ.
Статья изWoohoo.аналитика vi.com/blog/2017/0…