Время прочтения: 3 мин.
Для анализа были получены отзывы о трудоустройстве с популярных сайтов.
Исходные данные представляют собой примерно 31000 отзывов о трудоустройстве и процессе работы в компании, начиная с 2006 года. Большая часть отзывов – развернутый, эмоциональный текст, занимающий минимум половину листа А4. Для сокращения объема анализируемой информации, было принято решение реализовать суммаризацию текстов.
Подготовим данные для анализа: удалим стоп-слова и короткие слова, не несущие смысловой нагрузки, переведем текст в нижний регистр, удалим знаки препинания и цифры. Для предобработки отзывов и генерации резюме используем две различные функции, так как обработка текста и резюме немного различаются.
# предобработка отзывов
def preprocessing_reviews(text):
stop_words=set(stopwords.words('russian'))
new_text=new_text.lower()
new_text=re.sub(r'[^\w\s]+|[\d]',' ', new_text)
token=[t from t in new_text.split() if not t in stop_words]
word=[]
for i in token:
if len(i)>2:
word.append(i)
return(" ".join(word)).strip()
treated=[]
for x in review['Text']:
treated.append(preprocessing_reviews(x))
# предобработка резюме
def preprocessing_digest(text):
new_text=re.sub('""','',text)
new_text=new_text.lower()
new_text=re.sub(r'[^\w\s]+|[\d]',' ', new_text)
token=new_text.split()
new_text=''
for i in token:
if len(i)>1:
new_text=new_text+i+' '
return new_text
treated_digest=[]
for x in review['Digest']:
treated_digest.append(preprocessing_digest(x))
review[' treated_text']= treated
review[' treated_digest']= treated_digest
review[' treated_digest']=review[' treated_digest'].apply(lambda x: '_START_'+x+'_END_')
Превратим тексты в числовые последовательности. Для этого воспользуемся Keras. Прежде всего, создадим единый словарь. Разделим текст на слова с помощью функции text_to_sequences(). Воспользуемся функцией pad_sequences() для того, чтобы все последовательности имели одинаковую длину. Урезать или дополнять последовательность будем с конца.
x_tokenizer=Tokenizer()
x_tokenizer.fit_on_text(list(x_tr))
x_tr =x_tokenizer.text_to_sequences(x_tr)
x_var=x_tokenizer.text_to_sequences(x_var)
x_tr =pad_sequences(x_tr,maxlen=max_len_text,padding='post')
x_var=pad_sequences(x_var,maxlen=max_len_text,padding='post')
Приступим к построению модели. Ключевыми компонентами модели будут являться:
- Кодер – позволяет кодировать слова в числовые данные для последующей работы LSTM;
- Уровни LSTM – количество уровней можно варьировать для достижения большей точности;
- Декодер – преобразует числовые данные в понятный форма.
В качестве функции потерь использована разреженная категориальная перекрестная энтропия (SCCE). Для остановки обучения в нужный момент времени был использован метод ранней остановки (модель прекратит обучение, когда увеличится потеря валидации), если необходимо отобразить номер эпохи, в которой обучение было остановлено, необходимо установить аргумент verbose=1 :
encoder_input=Input(shape=(max_len_text,))
enc_emb=Embedding(input_dim=1000, output_dim=64)(encoder_input)
encoder_lstm=LSTM(64,return_sequences=True)
encoder_output, state_h, state_c = encoder_lstm(enc_emb)
decoder_input= Input(shape=(None,))
dec_layer = Embedding(y_size, 64)
dec_emb= dec _layer(decoder_input)
decoder_lstm= LSTM(64, return_sequences = True, return_state=True)
decoder_output, decoder_fwd_state, decoder_back_state = decoder_lstm(dec_emb, initial_state=[state_h, state_c])
decoder_dense = TimeDistributed(Dense(y_size, activation='softmax'))
decoder_output=decoder_dense(decoder_output)
model= Model([encoder_input, decoder_input],decoder_output)
model.compile(optimizer='rmsprop', loss= tf.keras.losses.SparseCategoricalCrossentrop)
early_stop= EarlyStopping(monitor='val_loss', mode='auto')
Теперь расшифруем последовательность для генерации текста и преобразуем числовую последовательность слов в краткое резюме.
Несколько резюме, сгенерированных моделью:
По результатам работы модели можно сделать вывод о том, что автореферирование является эффективным способом анализа большого объема информации. Применения этого метода поможет значительно сократить время на изучение отзывов, а также упростить выделение тематик текстов.