Как стать автором
Поиск
Написать публикацию
Обновить

Как расслабиться инженеру на работе при помощи Python?

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров12K

Всем привет! Меня зовут Владимир Ганзюк

Работаю инженером НСИ и изучаю для себя C#, но не сталкиваясь с Python, наткнулся я как-то случайно на одну очень интересную библиотеку Pymorhp.

Pymorph – морфологический анализатор для русского языка, использует словари из OpenCorpora. Исходный код можно получить на github. Документация к библиотеке написана достаточно хорошо.

Предыстория:

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

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

Суть:

В выгрузке из нашей системы имеется рабочая среда, естественно, таких сред может быть несколько. Перечисление сред изначально было через «;», через какое-то время кто-то подумал, что неплохо будет всё-таки использовать «,». Это исправить можно и в Excel, но наименование рабочей среды должно начинаться с существительного + прилагательного. Вот несколько примеров:

  • Топливо дизельное;

  • Газ углеводородный, фракция пропан-пропиленовая, газ природный;

  • Фракция бутан-бутиленовая.

В системе рабочие среды были внесены некорректно, к примеру: «Бутан бутиленовая фракция», «Бензин; вода», «Газ углеводородный, сухой газ».

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

За вечер написал костыль (функцию) sorting_dictionary:

def sorting_dictionary(dictionary):
    sorted_dic, dic, result_words = [], [], []

    for index in dictionary.keys():
        sentence_in_cell = dictionary[index].split(", ")
        for words in sentence_in_cell:
            words = words.split()
            for word in words:
                p = morph.parse(word)[0]
                if p.tag.POS == "NOUN":
                    sorted_dic.append(word)
                    for word in words:
                        p = morph.parse(word)[0]
                        if p.tag.POS == "PRED":
                            sorted_dic.append(word)
                elif p.tag.POS == "PREP":
                    sorted_dic.append(word)
            for word in words:
                p = morph.parse(word)[0]
                if p.tag.POS == "ADJF":
                    sorted_dic.append(word.lower())
            for word in words:
                p = morph.parse(word)[0]
                item_list = ['CONJ', 'PRTF']
                for item in item_list:
                    if item == p.tag.POS:
                        sorted_dic.append(word)
            for word in words:
                p = morph.parse(word)[0]
                item_list = ["VERB", "INFN"]
                for item in item_list:
                    if item == p.tag.POS:
                        sorted_dic.append(word)
            for word in words:
                p = morph.parse(word)[0]
                if p.tag.POS == None:
                    sorted_dic.append(word)
            words2 = " ".join(sorted_dic)
            result_words.append(words2)
            words2 = " "
            sorted_dic.clear()
        res_join = ", ".join(result_words)

        dic.append(upcase_first_letter(res_join))
        result_words.clear()
    return dic

Вкратце, функция принимает на вход словарь, в который уже заранее были внесены все значения из файла Excel с использованием библиотеки openpyxl и «;» была заменена на «,».

Часть речи слова получаем через атрибут POS: p.tag.POS. Если запрашиваемая характеристика для данного тега не определена, то возвращается None. Обозначения для граммем, можно получить тут:

Эта функция возвращает уже отсортированный вариант словаря.

Результаты:

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

Функция изменила 565 позиций, а это значит, что 1628 позиций уже отсеялись как правильные. В основном это легкие по типу: «Азот», «Бензин нестабильный», которая Pymorph определяет без проблем.

Из 565 измененных позиций 121 оказалась некорректной, например: «Раствор свежий щелочи», хотя правильный вариант - «Раствор щелочи свежий». Также есть проблема со скобками, к примеру: «Смесь газопродуктовая (бензин, ВСГ)», функция возвращает, как «Смесь (бензин газопродуктовая, ВСГ)».

Скорость работы алгоритма составила 29 секунд. Неплохо, да? Но у данной библиотеки иногда возникают сложности с определением части речи.

К примеру, если отойти от сред и разобрать предложение по словам «Мама мыла раму», то именно слово «мыла» оно определит, как существительное единственного числа с более высокой вероятностью, чем глагол. Да, у данной библиотеки ещё есть score – оценка вероятности того, что данный разбор правильный. Цитата из документации к библиотеке «то, как нужно разбирать слово, зависит от соседних слов; pymorphy2 работает только на уровне отдельных слов»

Также очень много позиций «Вакуумный газойль; Дизельное топливо», где «газойль» и «топливо» должны стоять на первом месте, функция вернула, как «Газойль вакуумный, топливо дизельное». Даже на удивление нашел такую среду из выгрузки: «27% водный раствор амина, Н2S – до 10% масс., азот», функция вернула абсолютно правильный вариант «Раствор амина водный 27%, Н2S – до 10% масс., азот»

Данная библиотека также в состоянии изменять падеж слова. Например, в библиотеке Natasha, которую я тоже пробовал, определить падеж можно, а вот изменить его, к сожалению, не получилось. Да и в отличие от Pymorph, Natasha очень медленная, т.к. Yargy реализует алгоритм Early parser, а его сложность О(n^3), код написан больше на читаемость, а не оптимизацию. 1000 позиций Natasha обрабатывала около 1 минуты, в то время как Pymorph справился с объемом в два раза больше за двое меньшее время. Это так, небольшое отступление, если кто столкнется с подобной ситуацией с выбором библиотеки.

Изменение падежа слова, например, может понадобиться для переноса транспортируемой среды в формат «Транспортировка» + среда для другого атрибута.

Вывод:

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


Ганзюк Владимир, инженер нормативно-справочной информации (НСИ)

Теги:
Хабы:
Всего голосов 8: ↑6 и ↓2+4
Комментарии17

Публикации

Ближайшие события