Представьте, что кто-то посылает вам такую почту каждый день:
Пример 1:
"Мой расход топлива вчера составлял XXX литров, мое дистанционное движение - YYY километров/мили, средняя скорость вчера ZZZ километров/мили в час"
Пример 2:
"Вчера двигатель использовал XXX литров топлива. Вчера автомобиль проехал YYY километры (+3 километров после 12 часов, но это было технически сегодня), средняя скорость автомобиля - это ZZZ километров в час",
В почте может быть больше значений, до 5 значений (в этом примере - 3).
Задача состоит в том, чтобы получить значения XXX,YYY and ZZZ
(и больше, когда есть), из почты. Конечно, почта печатается вручную, поэтому каждая почта имеет другой вид.
Вопрос в том, как это сделать? Всякая (серьезная) идея приветствуется, я расскажу об этом ниже:
Я думал, что Keras (или любая другая) нейронная сеть может выполнить эту работу. Я попытался предоставить каждому почтовому keras.preprocessing.text.one_hot()
вектор с keras.preprocessing.text.one_hot()
используя keras.preprocessing.text.one_hot()
и обучить keras.preprocessing.text.one_hot()
сеть следующим образом:
- EmbeddingLayer
- 1DConvLayer с активацией Relu
- MaxpoolLayer
- DropoutLayer
- FlattenLayer
- DenseLayer с активацией Relu
- DropoutLayer
- Плотный слой с линейной активацией
Для приведенных выше примеров было бы 3 выходных нейрона, где каждый нейрон должен был предсказать значение, например, первый выходной нейрон должен выводить XXX, второй нейрон YYY и т.д.
Используя оптимизатор Адама и MSE как потерю, это делает плохую работу. Кажется, что MSE сходится к довольно большому значению, и предсказания уходят.
Должен ли я использовать другую структуру? Какая структура имеет наилучшее изменение успеха?
Должен ли я использовать совершенно другой выход? например, выходы нейронной сети: "шестое слово - расход топлива".
Должен ли я использовать радикально иной подход без нейронной сети? Что тогда будет работать?
Пример сообщения с выходом нейронной сети. Почтовое сообщение:
- Cargo quantity, B/L mt: 0
- ME Fuel consumption mt: 8,9
- Total fuel consumption mt: 15
- Draught m: 6,65
- Date: 2018-07-04 07:00
- Timezone: 2018-07-04 07:00 W. Europe Standard Time
- ROB MGO: 510,3
- Distance, 127
Нейронная сеть Выход:
- Дата: 2018-09-12T15: 02: 28
- Часовой пояс: 545.405
- ROB MGO: -1876.67
- Груз: 23714,6
- Черновик: 0.394458
- Разгрузка груза: 9.97439e + 06
- Грузовая нагрузка: 9.87113e + 06
Желаемый результат:
- Дата: 2018-04-07T07: 00: 00
- Часовой пояс: +1
- ROB MGO: 510,3
- Грузы: 0
- Черновик: 6,65
- Разгрузка груза: 99999999
- Грузовая нагрузка: 99999999
Часовой пояс представляет собой разницу в отношении UTC, в этом случае +1, загрузка груза и грузовая нагрузка отсутствуют в почте, поэтому они должны вывести 99999999, что означает "нет". Даты сначала преобразуются в метки времени, поэтому нейронная сеть выводит временную метку.
Это можно сделать следующим образом:
Создайте файл excel с двумя столбцами с именем " Имя " и " Шаблон ". Там, где "Имя" является группой захвата (выгрузка черновика/груза), а для шаблона требуется "регулярное выражение", для его захвата.
Прочтите это excel в python с помощью команды:
import pandas as pd df = pd.read_excel('\\Regex.xlsx', sheet_name=0)
df
ниже функций, которые помогут вам проанализировать excel регулярных выражений, а затем проанализировать его:def parse_patterns_regex(df): pattern = df['pattern'].tolist() pattern_name = df['name'].tolist() pattern_dict = dict(zip(pattern_name, pattern)) return pattern_dict
pattern dict
и text
(ваши электронные письма) ниже функций, чтобы получить желаемый результатdef find_patterns_regex(text, pattern_dict,sep = ' ;; '): NLU_Dict=collections.defaultdict() for pn, p in pattern_dict.items(): val = sep.join([sep.join(filter(lambda x: len(str(x).strip()) >0,map(str, v))) for v in re.findall(p, text,re.I)]) NLU_Dict[pn] = val return NLU_Dict
NLU_Dict
будет словарем группы захвата и соответствующими значениями. Значения, отсутствующие в почте, будут просто пустыми. Вы можете просто написать простую логику, чтобы преобразовать blank to 999999
и т.д.
Capturing Group: Fuel Consumption ## This is "name" column of the above excel Regex:(\d+)\s?(?i)liters?|(\d+)\s?(?i)litters? ##This is "pattern" column of the above excel
См. Ссылку ниже, чтобы увидеть работу регулярного выражения: https://regex101.com/r/IppEq0/1