До моего первого контакта с Sage мне пришлось гуглить название, чтобы узнать, чем они занимаются. Когда я услышал, что она занимается разработкой программного обеспечения для планирования и учета ресурсов предприятия, я признаю, что первым впечатлением было то, что это звучит немного скучно. Я представил себе стол с кучей бумаг и кого-то, кто вбивает числа в один из этих огромных калькуляторов 80-х годов.

Но я не мог ошибиться больше.

Вскоре я обнаружил, что Sage уже много лет автоматизирует учетные процессы. И сегодня это включает в себя использование ИИ и машинного обучения. Оказывается, они создали Sage AI, чтобы превратить Sage в технологический бизнес с поддержкой AI. Звучит интереснее, не так ли?

В этом посте я поделюсь примером типичной проблемы, которую мы решаем в Sage AI: автоматизация счетов. Этот случай не только является отличной историей успеха, но также показывает, сколько обсуждений, размышлений и стратегии необходимо для достижения некоторых из наших результатов.

Автоматическая идентификация поставщиков

Почему важно определить поставщика

Обработка счетов имеет решающее значение в бухгалтерии, особенно для отдела Кредиторская задолженность (AP). AP — это платежи, причитающиеся поставщикам за товары или услуги, полученные компанией. Определить, какому поставщику клиент должен деньги, обычно несложно.

Но если счетов много, выполнение этого вручную может стать повторяющимся и привести к ошибкам, таким как оплата не тому поставщику или потеря/дублирование платежа. Автоматизация процесса значительно повышает его надежность, и мы можем сделать это еще лучше с помощью машинного обучения.

Проблемы с определением поставщика в счетах-фактурах

Давайте представим, что поставщик (Carles Panades Guinart Analytics) проделал замечательную работу, создал счет и отправил его клиенту (Sage UK Limited).

Сначала заказчик зафиксирует данные в учетной системе, в том числе реквизиты продавца. Понятно, что имя поставщика, указанное в счете, — «Carles Panades Guinart Analytics».

Однако клиенты часто присваивают поставщикам разные имена, такие как частичные (CPG Analytics) или полные аббревиатуры (CPGA), имя контактного лица (Carles), содержат опечатки (Charles Panacea Gurnard Analytics) или даже используют расплывчатое имя, связанное с отрасли (Компания Data Science). В этом случае имя в документе может не совпадать с назначенным именем поставщика в системе.

Кроме того, одним из наиболее распространенных решений этой проблемы для автоматизации точек доступа является оптическое распознавание символов (OCR), но оно может привести к некоторым ошибкам. Например, буква «А» может быть преобразована в «4» при обработке OCR. В этом случае «Аналитика» станет «4nalytics», что неверно и усложняет сопоставление.

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

Предлагаемый подход

Сходство счетов-фактур

Для того же примера счета предположим, что «CPG Analytics» было назначено в качестве имени поставщика в системе учета клиента. В будущем может быть больше счетов-фактур, таких как этот:

Это, очевидно, очень похоже на первый счет, и это то, чем мы можем воспользоваться. Мы можем сопоставить новый счет с поставщиком с наиболее похожим счетом из прошлого. Хотя это простая идея, очень сложно измерить сходство и точно выполнить сопоставление.

Измерение сходства: задокументируйте сходство с помощью tf-idf

Чтобы измерить сходство, мы используем нечто, называемое сходством документов, которое просматривает определенные части текста, чтобы идентифицировать поставщика. Это глубоко изученная тема в области обработки естественного языка, которая предлагает огромное количество методов для вычисления сходства текста, например:

  • Сходство Жаккара и связанные методы, например хэширование с учетом местоположения (LSH)
  • Частота термина, обратная частоте документа (tf-idf)
  • Doc2vec
  • Представления двунаправленного энкодера от трансформаторов (BERT)

Для этого решения мы используем tf-idf из-за его точности, проверенного опыта в битвах по науке о данных и относительной простоты реализации. Мы не будем углубляться в детали tf-idf, так как это отдельная тема. Вместо этого мы рассмотрим, как мы использовали его для решения нашей проблемы.

Реализация tf-idf

Первым шагом, который мы предприняли, было использование счета-фактуры на рис. 1 для обучения нашей модели машинного обучения. Это включало извлечение следующего текста из этого счета и его использование для создания списка счетов в качестве входных данных модели:

invoice_1 = 'Carles Panades Guinart Analytics 221B Baker Street, London NW1 6XE United Kingdom Phone +44 21 7737 0934 INVOICE NO. 001984 2022-07-21 BILL TO SHIP TO INSTRUCTIONS Sage (UK) Limited C23 5 & 6 Cobalt Park Way Wallsend NE28 9EJ United Kingdom Same as recipient None QUANTITY DESCRIPTION UNIT PRICE TOTAL 1 Data Science Mumbo Jumbo 10000.00 10000.00 SUBTOTAL 10000.00 SALES TAX 21% SHIPPING & HANDLING TOTAL DUE BY DATE 12100.00 GBP Thank you for your business!'
invoices_train = [invoice_1]

Обратите внимание, что поставщик известен, поэтому у нас также есть соответствующий список поставщиков:

vendors_train = ['CPG Analytics']

Затем мы построили наш векторизатор tf-idf и использовали его для подбора алгоритма ближайшего соседа, который предоставляет наиболее похожий документ с помощью нескольких строк кода:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.neighbors import NearestNeighbors
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(invoices_train)
nn = NearestNeighbors(n_neighbors=1, metric='cosine')
nn.fit(X)

Наконец, мы можем предсказать поставщика по второму счету (рисунок 2) после его обработки аналогичным образом:

invoice_2 = 'Carles Panades Guinart Analytics 221B Baker Street, London NW1 6XE United Kingdom Phone +44 21 7737 0934 INVOICE NO. 001999 2022-07-25 BILL TO SHIP TO INSTRUCTIONS Sage (UK) Limited C23 5 & 6 Cobalt Park Way Wallsend NE28 9EJ United Kingdom Same as recipient None QUANTITY DESCRIPTION UNIT PRICE TOTAL 1 More Data Science Mumbo Jumbo 5000.00 5000.00 1 Machine Learning Gobbledygook 10000.00 10000.00 SUBTOTAL 15000.00 SALES TAX 21% SHIPPING & HANDLING TOTAL DUE BY DATE 18150.00 GBP Thank you for your business!'
invoices_test = [invoice_2]
invoices_test_tfidf_matrix = vectorizer.transform(invoices_test)
nn.kneighbors( invoices_test_tfidf_matrix )

Это приводит к:

(array([[0.03479332]]), array([[0]]))

Первый элемент кортежа — это косинусные расстояния, а второй — индексы ближайшего соседа. В этом сценарии ближайшим ко второму счету документу является документ с индексом 0 (соответствующий первому счету в цепочке счетов, что приводит к «аналитике CPG» от vendors_train[0]). Оценка представляет собой косинусное расстояние (0 — лучшая оценка и 1 — худшая), что указывает на то, что результат 0,034793332 является довольно хорошим. Обратите внимание, что в этом примере каждый из элементов кортежа представляет собой матрицу размерности 1 x 1, потому что нужно было спрогнозировать только один счет, и он дал наиболее похожую рекомендацию (мы учитывали только одного ближайшего соседа).

Проблемы в производстве

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

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

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

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