Machine Learning, Text mining

Мониторинг технического состояния сети

Время прочтения: 6 мин.

Для решения задачи будем использовать инструменты text-mining, в том числе, нормализуем текст, избавимся от стоп-слов, преобразуем слова в tf-idf векторы, применим обучение с учителем, выберем критерии критичности текстов и рассчитаем результирующие показатели. Код (пример данных) модели векторизатора и классификации можно посмотреть по ссылке

Цель нашего исследования — выявление «проблемных филиалов», уровень и частота поломок эксплуатационного характера в которых приводит к фактическому простою работы подразделения или негативно влияет на качество обслуживания клиентов.

  1. Система регистрации обращений

Изначально нам необходимо понять, как работает система регистрации обращений. Создавая заявку, сотрудник выбирает категорию поломки/аварии и описывает проблему. Затем она поступает в обслуживающую компанию и специалист, в течение определённого времени, выезжает на место поломки. Если поломку удаётся устранить, специалист закрывает заявку. Если требуется провести сложные работы или закупить детали, он может продлить срок выполнения.

  1. Нормализация слов Pymorphy2

Инициатор заявки не всегда правильно указывает категорию, поскольку может не разбираться в предмете поломки. Поэтому разметим правильные классы обращений в обучающей выборке и, при помощи интеллектуального анализа текста, будем классифицировать все обращения.

Для нормализации слов русского языка применим pymorphy2 – удобную и быструю библиотеку, использующую, в качестве исходного, словарь «Открытого корпуса».

Импортируем библиотеку через JupyterNotebook:

!pip install --index-url=http://mirror.ca.sbrf.ru/pypi/simple/ --trusted-host mirror.ca.sbrf.ru --user pymorphy2

В качестве стартового словаря стоп-слов используем достаточно полный словарь библиотеки stopwords, дополнив его словами со слишком низкой и слишком высокой встречаемостью.

Импортируем библиотеку через JupyterNotebook:

!pip install --index-url=http://mirror.ca.sbrf.ru/pypi/simple/ --trusted-host mirror.ca.sbrf.ru --user stop_words

Векторизатор и классификаторы сохраним и будем считывать из файлов .pkl с применением модуля pickle, способного преобразовывать объекты python в поток байтов и обратно.

Import pickle
#ПРИМЕНЕНИЕ МОДЕЛИ
with open (‘vectf_23867.pkl’,’ rb’) as v1:
	vec = pickle.load(v1)
x_test = vec.transform(q4.komment)

with open (‘modelRF_23867.pkl’, ‘rb’) as m1:
	model = pickle.load(m1
y_pred = model.predict(x_test)

В качестве исходных данных, берем столбец комментария из исходного DataFrame:

import pandas as pd
df=pd.read_excel('statya.xlsx')
df=df[['Коммент']]
df
Коммент
0 в помещение до в связи с работами на линии бу…
1 в всп выбивает свет\nнагрев проводов искрение …
2 оборвало пружину на воротах…
3 ремонт розеток светильников замена ламп…
4 кабинет зона обслуживания юридических лиц выд…
22340 регулировка приточной вентиляции настройка те…
22341 искрит провод на рабочем месте окно номер \nна…
22342 с г по г с до будет отключена электроэнергия…
22343 плановое отключение электроэнергии с до \nна…
22344 прошу посмотреть почему в кассу через вентиляц…

22345 rows × 1 columns

Перевод слов в нормальную форму представлен ниже:

import pymorphy2
morph = pymorphy2.MorphAnalyzer()
def converter (sentence):
    list1 = []
    words = sentence.split()
    for item in words:
        list1.append(morph.parse(item)[0].normal_form)
    return ' '.join(list1)
df['Коммент']= df['Коммент'].astype(str)
df['Коммент1']=df['Коммент'].apply(converter)
df
  Коммент Коммент1
0 в помещение до в связи с работами на линии бу… в помещение до в связь с работа на линия быть …
1 в всп выбивает свет\nнагрев проводов искрение … в всп выбивать свет нагрев проводы искрение в …
2 оборвало пружину на воротах… оборвать пружина на ворот не …
3 ремонт розеток светильников замена ламп радиоз… ремонт розетка светильник замена лампа радиозв…
4 кабинет зона обслуживания юридических лиц выд… кабинет зона обслуживание юридический лицо выд…
22340 регулировка приточной вентиляции настройка те… регулировка приточный вентиляция настройка тем…
22341 искрит провод на рабочем месте окно номер \nна… искрить провод на рабочий место окно номер наг…
22342 с г по г с до будет отключена электроэнергия… с год по год с до быть отключить электроэнерги…
22343 плановое отключение электроэнергии с до \nна… плановый отключение электроэнергия с до нагрев…
22344 прошу посмотреть почему в кассу через вентиляц… просить посмотреть почему в касса через вентил…

22345 rows × 2 columns

Удаляем стоп-слова:

from stop_words import get_stop_words
#Создаем словать стоп слов
rr = get_stop_words('ru')
#Разделяем на слова и считаем количество повторений
wo = pd.Series(' '.join(df['Коммент1']).lower().split()).value_counts().reset_index()
#Записываем все редко встречающиеся слова в новый лист, считаем его длину
lst1 = wo[wo[0]<3]['index'].tolist()
lst2 = wo[wo[0]>5000]['index'].tolist()

dop = ['просить', 'уважение', 'требоваться', 'необходимый', 'добрый', 'день', 'здравствуйте', 'нужный']
#Объединяем
R = rr+lst1+lst2+dop
#В столбце Коммент1 из всех строк убираем ранее полученные стоп-слова
df['Коммент1'] =df['Коммент1'].apply(lambda x: ' '.join([word for word in x.split() if word not in (R)]))
df
Коммент Коммент1
0 в помещение до в связи с работами на линии бу… помещение связь работа линия отсутствовать све…
1 в всп выбивает свет\nнагрев проводов искрение … всп выбивать свет нагрев проводы искрение зады…
2 оборвало пружину на воротах… ворот подниматься автоматичес…
3 ремонт розеток светильников замена ламп радиоз… зона потолок
4 кабинет зона обслуживания юридических лиц выд… кабинет зона обслуживание юридический лицо оши…
22340 регулировка приточной вентиляции настройка те… регулировка приточный вентиляция настройка тем…
22341 искрит провод на рабочем месте окно номер \nна… искрить провод рабочий место окно номер нагрев…
22342 с г по г с до будет отключена электроэнергия… отключить электроэнергия письмо вложение нагре…
22343 плановое отключение электроэнергии с до \nна… плановый отключение электроэнергия нагрев пров…
22344 прошу посмотреть почему в кассу через вентиляц… посмотреть касса вентиляция заходить запах ули…

22345 rows × 2 columns

Таким образом мы привели все предложения в комментариях к нормальной форме, что необходимо для последующей классификации обращений.

Итак, нам нужно определить филиалы, в которых ситуация с поломками достигает критического уровня. Используем для этого text-mining.

Определимся с критериями оценки критичности поломок в филиале. Будем считать количество заявок из одного филиала по поводу одной и той же поломки, чтобы выявить проблемы, возникающие неоднократно.

Также обратим внимание на выразительные заявки, в которых негативная тональность текста выше, чем в остальных. Как правило, такие заявки пишут тогда, когда проблема критична для работы филиала или проблема не решается в течение длительного времени.

  1. Применение ML

Импортируем все необходимые библиотеки/модули:

import sklearn
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.decomposition import TruncatedSVD
from sklearn.linear_model import LogisticRegression, SGDClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.multiclass import OneVsRestClassifier
from sklearn.metrics import f1_score
from sklearn.ensemble import RandomForestClassifier

Для анализа тональности применялся классификатор RandomForest из библиотеки sklearn. Помимо этих критериев, использовались данные о том, как много заявок из этого филиала не закрыли в срок, часто ли и как долго продлевался срок исполнения заявок.

Для большей гибкости анализа составляем матрицу весов отобранных показателей.

Варьируя элементы матрицы можно повысить значимость того или иного компонента, основываясь на сравнении ожидаемого и получаемого результата. Показатели, умноженные на их веса, просуммируем для каждого обращения.

Теперь у нас есть возможность подсчитать суммарную критичность обращений по филиалам, категориям работ и по тому и другому одновременно. Такой анализ позволяет увидеть поломки какого вида характерны для данного филиала и рассмотреть возможные причины.

Также мы можем оценить качество работы подрядных организаций, сравнивая показатель критичности в филиалах в зоне их ответственности с критичностью в других филиалах. 

Таким образом, с применением интеллектуального анализа текста, удалось выявить точки концентрации поломок, определить западающие категории поломок, проанализировать возможную причину и эффективность деятельности подрядных организаций.

Советуем почитать