Анализ тональности текста или сентимент анализ - это метод классификации текста. Самый популярный пример из курсов по машинному обучению - прогноз оценки, которую поставит посетитель ресторана заведению на основе его отзыва. Или, по другому, можем ли мы спрогнозировать на основе отзыва посетителя, будет ли он рекомендовать этот ресторан или нет.
В HR сама собой напрашивается аналогичная задача: можем ли мы спрогнозировать на основе отзыва увольняющегося работника в exit интервью спрогнозировать, будет ли он рекомендовать нашу компанию коллегам / будет ли он отзываться о компании позитивно или негативно. Хотя, безусловно, класс решаемых задач значительно шире. Я бы отослал здесь к статье Raja Sengupta Как NLP может в корне изменить HR. NLP - это Natural language processing или проще - анализ текстов. Моя задача проще - я хочу показать код для решения одной задачи в Python.
Этот подход интуитивно понятен, но он имеет ряд недостатков (что делать с "не"? и т.п...), но главное: в этом подходе не отражается смысл слов, фраз.
word2vec
Преодолением такого подхода является метод word2vec (буквально 'word' to 'vector'), который превращает весь текст в N-мерное пространство, и каждое слово это вектор со своими координатами, т.е. буквально можно записать так:
'опрос': array([ 0.05069825, -0.01941545, 0.00567565, -0.0276236 , 0.01180002,
....... 0.00385726])
Не показываю весь вектор, потому что он имеет 100 значений. И эти 100 значений - это переменные в нашем уравнении.
"Плюс" этого метода в том, что близкие по значению слова имеют близкие координаты векторов. Например, когда я делал модель для функционала HR, то для слова "компенсации" самые близкие координаты вектора имело слово "c&b". И это замечательно, потому что в подходе "bag of words" слова "c&b" и "компенсации" это разные слова, а в подходе word2vec эти слова хоть и не идентичны, но очень близки.
Я свои данные взял из нашего исследования факторов текучести персонала (участвуем в исследовании) . Помимо всего прочего, в нашем опросе есть две переменные:
"Отзыв о компании";
"Готовы ли Вы рекомендовать эту компанию в качестве работодателя своим знакомым, коллегам?"
Итак, начинаем с загрузки данных
Да, у нас очень небольшой датасет, лучше иметь несколько тысяч, даже несколько десятков тысяч строк данных. Но моя задача скромнее - показать алгоритм. Выборка у нас достаточно сбалансированная - соотношение тех, кто готов рекомендовать компанию, и тех, кто не готов - почти 50/50.
Первая задача, которую нам надо решить - создать словарь слов. Т.е. присвоить каждому слову координаты вектора. Для этого нам необходимо взять весь текст и обучить его. Но прежде нам необходимо преобразовать наши отзывы из формата pandas в формат, годный для преобразований word2vec.
Преобразуем таким образом
В HR сама собой напрашивается аналогичная задача: можем ли мы спрогнозировать на основе отзыва увольняющегося работника в exit интервью спрогнозировать, будет ли он рекомендовать нашу компанию коллегам / будет ли он отзываться о компании позитивно или негативно. Хотя, безусловно, класс решаемых задач значительно шире. Я бы отослал здесь к статье Raja Sengupta Как NLP может в корне изменить HR. NLP - это Natural language processing или проще - анализ текстов. Моя задача проще - я хочу показать код для решения одной задачи в Python.
word2vec vs "bag of words"
Одним из самых популярных методов анализа текстов (а точнее, этот метод просто хронологически более ранний - и, может быть, более интуитивно понятный) является метод "мешок слов "bag of words". Мы просто получаем столько переменных, сколько у нас слов в тексте (исключая "мусорные" или редкие слова). Т.е. если в отзывах у нас используется 1 485 слов, то у нас будет 1485 новых переменных / колонок. И если в отзыве содержится слово - оно же название переменной - то переменная принимает значение "1", в противном случае "0". Т.е. если респондент написал отзыв "хорошая компания", то из 1485 ячеек напротив данного респондента будет только две "1" - в колонках "хорошая" и "компания".Этот подход интуитивно понятен, но он имеет ряд недостатков (что делать с "не"? и т.п...), но главное: в этом подходе не отражается смысл слов, фраз.
word2vec
Преодолением такого подхода является метод word2vec (буквально 'word' to 'vector'), который превращает весь текст в N-мерное пространство, и каждое слово это вектор со своими координатами, т.е. буквально можно записать так:
'опрос': array([ 0.05069825, -0.01941545, 0.00567565, -0.0276236 , 0.01180002,
....... 0.00385726])
Не показываю весь вектор, потому что он имеет 100 значений. И эти 100 значений - это переменные в нашем уравнении.
"Плюс" этого метода в том, что близкие по значению слова имеют близкие координаты векторов. Например, когда я делал модель для функционала HR, то для слова "компенсации" самые близкие координаты вектора имело слово "c&b". И это замечательно, потому что в подходе "bag of words" слова "c&b" и "компенсации" это разные слова, а в подходе word2vec эти слова хоть и не идентичны, но очень близки.
Данные
У меня свой датасет, которым я с вами не поделюсь, но вы можете опробовать этот код на своих данных. Структура данных достаточно проста:- переменная "текст";
- бинарная переменная 1/ 0, +1 / -1 и т.п..
Я свои данные взял из нашего исследования факторов текучести персонала (участвуем в исследовании) . Помимо всего прочего, в нашем опросе есть две переменные:
"Отзыв о компании";
"Готовы ли Вы рекомендовать эту компанию в качестве работодателя своим знакомым, коллегам?"
Реализация в Python
Итак, начинаем с загрузки данных
import pandas as pd import numpy as np df = pd.read_csv('data.csv', sep=',', encoding = 'cp1251') df.info() Data columns (total 2 columns): y 792 non-null int64 Отзыв о компании 792 non-null object dtypes: int64(1), object(1)
df['y'].value_counts() 1 404 0 388 Name: y, dtype: int64
Да, у нас очень небольшой датасет, лучше иметь несколько тысяч, даже несколько десятков тысяч строк данных. Но моя задача скромнее - показать алгоритм. Выборка у нас достаточно сбалансированная - соотношение тех, кто готов рекомендовать компанию, и тех, кто не готов - почти 50/50.
Первая задача, которую нам надо решить - создать словарь слов. Т.е. присвоить каждому слову координаты вектора. Для этого нам необходимо взять весь текст и обучить его. Но прежде нам необходимо преобразовать наши отзывы из формата pandas в формат, годный для преобразований word2vec.
Преобразуем таким образом
import nltk import nltk.data tokenizer = nltk.data.load('tokenizers/punkt/english.pickle') from nltk.tokenize import sent_tokenize, word_tokenize import re
def preproc(sentence): sent_text = re.sub(r'[^\w\s]','', sentence) words = sent_text.lower().split() return(words)
def senttxt(sent, tokenizer, remove_stopwords=False ): raw_sentences = tokenizer.tokenize(oped.strip()) sentences = [] for raw_sentence in raw_sentences: sentences.append(preproc(raw_sentence)) len(sentences) return sentences
txt_snt = df['Отзыв о компании'].tolist() sentences = [] for i in range(0,len(nyt_opeds)): sent = txt_snt[i].replace("/.", '') sentences += senttxt(sent, tokenizer)В итоге мы получаем объект вот такого формата
sentences[0] ['классическая', 'российская', 'компания', 'с', 'назначениями', 'не', 'по', 'знаниям', 'а', 'по', 'личной', 'приверженности', 'не', 'соблюдающая', 'свои', 'же', 'правила', 'делающая', 'глупость', 'за', 'глупостью', 'и', 'оправдывающая', 'их', 'еще', 'большими', 'глупостями']Этот формат уже можно использовать для создания словаря. Что мы и делаем.