Использование машинного обучения для решения инцидентов

Публикация № 1197027

Разработка - Практика программирования

Машинное обучение Python HelpDesk

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

Я не люблю, когда к месту и не к месту употребляют термин «Искусственный интеллект». «Искусственный интеллект отделяет котиков от собачек», «искусственный интеллект помогает ловить преступников», «абонентам помогут сократить расходы с помощью искусственного интеллекта». Чувствуется в этом какая-то попытка выдать желаемое за действительное. Я предпочитаю термин «Машинное обучение». По крайней мере именно про него я буду рассказывать дальше.

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

Обращаю внимание, что несмотря на ресурс, где статья опубликована – непосредственно к 1С она практически не имеет отношения. Только математика и Python.

 

Постановка задачи:

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

Было решено реализовать две функции:

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

Реализовать удалось обе функции, о первой я расскажу в этой статье, а про вторую – в следующей.

 

Немного теории.

В 2013 году в компании Google был разработан инструмент для анализа семантики естественных языков word2vec. Идея инструмента – подать на вход текстовый корпус, затем внутри происходит компьютерная магия и на выходе мы получаем матрицу, в которой каждое из слов нашего корпуса представлено как вектор, причем чем более сонаправлены вектора (чем больше косинусное произведение между ними), тем они более похожи.

На картинке я попытался изобразить ТОП-5 векторов, наиболее близких слову «Собака». Обучение матрицы происходило на википедии и на национальном корпусе русского языка. Самостоятельно поиграться можно например тут https://rusvectores.org/ Естественно на рисунке лишь схема, на самом деле матрица является не двумерной, то есть каждое слово задается не двумя координатами, а сотней и более.

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

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

Вся разработка велась на Python в среде Anaconda. При установке Анаконды часть необходимых библиотек устанавливается сразу, часть необходимо будет доустановить. Так как статья не ставит своей целью обучить программированию на Python, я не буду углубляться в вопросы «как поставить библиотеку», «а почему написано именно так», однако готов при необходимости обсудить это в комментариях. Так же обязательно выслушаю советы опытных питонистов, потому что уверен, мой код далек от оптимального.

Объявим нужные нам библиотеки:

import warnings

warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')

#Подавляем лишние оповещения

import pyodbc

#Все инциденты считываются из базы данных, библиотека для доступа к SQL

import pandas as pd

#Про pandas написано куча книг. Кратко - pandas это высокоуровневая Python библиотека для анализа данных.

import re

#Ммм, регулярки (картинка с Гомером)

import pymorphy2

morph = pymorphy2.MorphAnalyzer()

#Морфологический анализатор.

import logging

logging.root.handlers = []

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

#Библиотека для логирования

from smart_open import smart_open

#Библиотека для работы с большими удаленными файлами

import numpy as np

#Библиотека для работы с большими многомерными массивами

from numpy import random

import genism

# Библиотека обработки естественного языка

import nltk

#пакет библиотек и программ для символьной и статистической обработки естественного языка

from sklearn.model_selection import train_test_split

from sklearn import linear_model

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer

from sklearn.metrics import accuracy_score, confusion_matrix, recall_score

# sklearn - бесплатная библиотека машинного обучения для языка программирования Python

import matplotlib.pyplot as plt

#Необходимо для рисования графиков

from gensim.models import Word2Vec

#А вот и сам Word2Vec

from sklearn.neighbors import KNeighborsClassifier

from sklearn import linear_model

from nltk.corpus import stopwords

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

 

%matplotlib inline

 

Загрузим стоп слова

stop_words = stopwords.words('russian')

 

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

 

connection_string_remedy = 'DRIVER={ODBC Driver 17 for SQL Server};SERVER=MyServer;DATABASE=MyBase;UID=user;PWD=password'

 

Объявим функцию, которая приведет текст инцидента к машиннообрабатываемому виду. Для этого мы сделаем следующее:

 

1. Удаляем всё лишнее (цифры, подписи, телефоны)

2. Приводим к нижнему регистру.

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

4. лемматизируем и добавляем часть речи (ну кстати тестирование показало, что добавление части речи не улучшает результат, поэтому ниже этот функционал закомментирован.

 

def lemmatization(text,morphing = True):

    stop_words = stopwords.words('russian')

    border = text.find('Для решения инцидента заявитель должен предоставить')

#После этого текста в инциденте у нас идет служебная информация, ФИО сотрудника,

#магазин, с которого он обратился, номер телефона, IP адрес компьютера и прочее

#то, что для наших целей явно мешает. Удаляем.

    if border > 0:

        text = text[0:border]

    text = text.lower()

    text = re.sub(r"\d+", "", text, flags=re.UNICODE)

    text = re.sub('\W', ' ', text).split()

    if morphing == False:

        return text

    text_new = ''

    x = 0

    previous_word_ne = False

    for item in text:    

        if item == 'не':

            previous_word_ne = True

#это важная часть. Так как машина превращает слова в вектора – для нее «работает» и «не работает» не антонимы,

# а просто -в первом случае один вектор, а во втором случае два и они между собой не связаны.

#Поэтому превратим два слова «не работает» в одно «не_работает»

 

       

        if len(item) > 2:

            if not (item in stop_words):

                if previous_word_ne:

                    text_new = text_new+'не_'+morph.parse(item)[0].normal_form+' '#'_'+str(morph.parse(item)[0].tag.POS)+' '

# morph.parse(item)[0].normal_form – приведение к нормальной форме: «Побежали» -> «бежать», «компьютеров» -> «компьютер» и т.д.

                    previous_word_ne = False

                else:

                    text_new = text_new+morph.parse(item)[0].normal_form+' '#'_'+str(morph.parse(item)[0].tag.POS)+' '

                   

    return text_new

 

Результат работы функции:

lemmatization ("Для решения первой задачи сделаем следующее предположение – у нас есть инцидент и его решение, которое придумано человеком")

 

'решение один задача сделать следующий предположение инцидент решение который придумать человек '

 

Загрузим данные в DataFrame:

 

%%time

cnxn = pyodbc.connect(connection_string_remedy)

cursor = cnxn.cursor()

 

sql = '''

    SELECT Number, Description, ShortDescription

    FROM [MyBase].[dbo].[MyTable] (nolock)

    where cast(DateCreate as date) > '2018-01-01'

    and '''

#Здесь Description – текст инцидента, а ShortDescription его классификатор

 

#Кладем результат запроса в DataFrame и лемматизируем текст инцидента

 

df_result = pd.read_sql_query (sql, cnxn)

for index, row in df_result.iterrows():

    text = row['Description']

    text_new = lemmatization(text)

    df_result.iat[index,1]=text_new

 

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

 

my_tags = (df_result['ShortDescription'].value_counts()>1000)

my_tags = my_tags[my_tags == True].index.tolist()

len(my_tags)

 

У меня получилось 57 самых частых классификаторов. Данный параметр нужно подбирать на основании ваших данных.

 

Копируем DataFrame, чтобы заново не готовить исходный DataFrame. Дальше работаем только с отфильтрованным DataFrame. Сравниваем количество в отфильтрованном и полном DataFrame

 

df_result_filter = df_result[df_result['ShortDescription'].isin(my_tags)]

print(df_result.count())

print(df_result_filter.count())

df_result_filter.to_csv('Data/df_result_filter.csv', encoding = "utf-8")

 

У меня получилось 553551 инцидент в неотфильтрованном и 509497 инцидентов в отфильтрованном датафреймах.

 

Теперь давайте посмотрим на распределение инцидентов по классификаторам:

 

df_result_filter.ShortDescription.value_counts().plot(kind="bar", rot=90)

plt.rcParams['figure.figsize'] = [30, 5]

plt.show()

 

 

Разбиваем наш датафрейм на тренировочную и тестовую части. Как понятно из названия – на тренировочной мы будем обучать нашу модель, а на тестовой – проверять результат обучения.

 

train_data, test_data = train_test_split(df_result_filter, test_size=0.1, random_state=42)

 

Далее создадим вспомогательные функции:

 

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

 

def plot_confusion_matrix(cm, title='Confusion matrix', cmap=plt.cm.Blues):

    plt.imshow(cm, interpolation='nearest', cmap=cmap)

    plt.title(title)

    plt.colorbar()

    tick_marks = np.arange(len(my_tags))

    target_names = my_tags

    plt.xticks(tick_marks, target_names, rotation=90)

    plt.yticks(tick_marks, target_names

    plt.ylabel('True label')

    plt.xlabel('Predicted label')

    fig = plt.gcf()

    fig.set_size_inches(18.5, 10.5)

    fig.savefig('test2png.png', dpi=100)

   

Функция, непосредственно вычисляющая матрицу ошибок.  

 

def evaluate_prediction(predictions, target, title="Confusion matrix"):

    print('accuracy %s' % accuracy_score(target, predictions))

    print('recall %s' % recall_score(target,predictions, average='micro'))

    cm = confusion_matrix(target, predictions)

    cm_normalized = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]

    plot_confusion_matrix(cm_normalized, title + ' Normalized')

 

 

Функция, превращающая текст инцидента в вектор   

def word_averaging(wv, words):

    all_words, mean = set(), []

   

    for word in words:

        if isinstance(word, np.ndarray):

            mean.append(word)

        elif word in wv.vocab:

            mean.append(wv.syn0norm[wv.vocab[word].index])

            all_words.add(wv.vocab[word].index)

 

    if not mean:

        logging.warning("cannot compute similarity with no input %s", words)

        # FIXME: remove these examples in pre-processing

#        return np.zeros(wv.layer1_size,)

        return np.zeros(wv.vector_size,)

 

    mean = gensim.matutils.unitvec(np.array(mean).mean(axis=0)).astype(np.float32)

    return mean

 

def  word_averaging_list(wv, text_list):

    return np.vstack([word_averaging(wv, review) for review in text_list])

 

#Разобьем полученные данные на массив (ndarray), строками в котором будут списки (list), где каждый элемент списка – отдельное слово.

def w2v_tokenize_text(text):

    tokens = []

    for sent in nltk.sent_tokenize(text, language='english'):

        for word in nltk.word_tokenize(sent, language='english'):

            if len(word) < 3:

                continue

            tokens.append(word)

    return tokens

 

Приступаем непосредственно к тренировке.

#Используя вышеобъявленную функцию превратим наш Датафрейм в массив с инцидентами (каждый инцидент это список, в котором отдельный элемент списка – слово)

 

inc_tokenized = df_result.apply(lambda r: w2v_tokenize_text(r['Description']), axis=1).values

 

Посмотрим, что у нас получилось, возьмем 50-ый элемент массива:

inc_tokenized[50]

 

['добрый',

 'день',

 'ошибочно',

 'отгрузить',

 'телефон',

 'просить',

 'отменить',

 'отрузка',

 'поставить',

 'остаток',

 'телефон',

 'мочь',

 'вернуть',

 'клиент',

 'номер',

 'сейф',

 'пакет',

 'номер',

 'отгрузка',

 'заранее',

 'спасибо',

 'табельный',

 'номер']

 

Обучим нашу модель

%%time

model = Word2Vec(inc_tokenized,

size=200,

window=5,

min_count=3,

workers=8)

wv = model.wv

 

Создадим L2-нормированные вектора и сохраним результат, он нам потребуется в дальнейшем

wv.init_sims(replace=True)

wv.save_word2vec_format('data/key_vectors_inc.bin')

 

Ну теперь давайте немного поиграем в ассоциации. Попросим показать нашу модель наиболее близкие по смыслу слова к тому, которое мы укажем. Обратите внимание, база для обучения – это инциденты от сотрудников магазинов сотовой связи (телефоны, аксессуары, сим-карты и т.п.)

 

wv.most_similar(positive=['ошибка'])

 

[('сообщение', 0.653794527053833),
 ('ощибка', 0.5926002264022827),
 ('табличка', 0.552541196346283),
 ('ошбка', 0.525760293006897),
 ('надпись', 0.5208160281181335),
 ('окошко', 0.5118091106414795),
 ('попытка', 0.49567654728889465),
 ('сбой', 0.48171132802963257),
 ('окно', 0.4712887406349182),
 ('уведомление', 0.46060070395469666)]

 

 

wv.most_similar(positive=['сим'])

 

[('симкарта', 0.801783561706543),
 ('симка', 0.7723581790924072),
 ('sim', 0.7251297235488892),
 ('болванка', 0.6134322881698608),
 ('бронзовый', 0.5933068990707397),
 ('сикарта', 0.592644989490509),
 ('icc', 0.582025408744812),
 ('ctn', 0.581929087638855),
 ('не_сим', 0.5614026188850403),
 ('бронза', 0.5609164237976074)]

 

wv.most_similar(positive=['телефон'])

 

[('смартфон', 0.8400038480758667),
 ('айфон', 0.7854971885681152),
 ('планшет', 0.7388856410980225),
 ('lite', 0.6476684212684631),
 ('iphone', 0.613440990447998),
 ('vita', 0.610135018825531),
 ('nokia', 0.6086500287055969),
 ('апп', 0.6069196462631226),
 ('товар', 0.6057144403457642),
 ('prime', 0.6033762693405151)]

 

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

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

 

%%time

full_tokenized = df_result.apply(lambda r: w2v_tokenize_text(r['Description']), axis=1).values

X_full_word_average = word_averaging_list(wv,full_tokenized)

df_result['X_full_word_average'] = list(X_full_word_average)

 

Это позволит нам искать не похожие слова, а похожие инциденты. Давайте проверим, работает ли наше предположение.

 

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

def find_similar_index(a, A):

    subs = (a[:,None] - A)

    sq_dist = np.einsum('ij,ij->j',subs, subs)

    return sq_dist

 

Преобразуем наш инцидент в вектор и найдем вектора, которые наиболее близки нашему. Выберем только те, расстояние до которых меньше 0.3. Чем меньше расстояние – тем ближе наш инцидент к полученному.

 

df_result_copy = df_result_filter

inc_text = '''

Добрый день. Не получается распечатать ценники по акции Самсунг

с услугами связи и акссесуарами. Ценник должен быть акционный. Название

акции в 1С - Акция «Samsung 3-я цена». Данную акцию не находит. И

выдает ошибку. Скрин приложен.

'''

inc_lemmatization = (lemmatization(inc_text))

inc_tokenize = w2v_tokenize_text(inc_lemmatization)

inc_average_list = word_averaging(wv,inc_tokenize)

 

df_result_copy['similar_index'] = find_similar_index(inc_average_list,X_full_word_average.T)

df_result_copy = df_result_copy.sort_values('similar_index')

df_order = df_result_copy[df_result_copy['similar_index']<0.3].head(1000)

df_order.head(10)

 

 

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

 

Инцидент с номером 20862395 это исходный инцидент, посмотрим следующие:

Номер инцидента

Текст

20868378

'Добрый день, по акции Смартфоны Samsung Galaxy с услугами связи и

аксессуарами невозможно напечатать акционный ценник, нет данной акции.

Когда набираешь артикул выдает ошибку

18399650

Добрый день! При печати ценника на Самсунг по акции А30 всего за 99

руб/мес не дает выбрать акцию. Нет возможности напечатать акционный

ценник

18047257

Добрый день, по акции HUAWEI P30 lite ценник должен печататься с суммой

16590р цена по акции, полная цена смартфона 21990р, ценник не

корректный,Ю скрины во вложении

21026274

Добрый день.

Не печатаются ценники по акции скидка на смартфон apple при покупке доп

товаров и услуг

 

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

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

Когда сотрудник ввел текст инцидента первым делом мы отправляем его (текст, а не сотрудника) на поиск похожих инцидентов. В случае если среди похожих есть инцидент с готовым решением – покажем его сотруднику и спрашиваем подошло ли решение. Если решение подходит – мы не создаем инцидент, считая что проблема решена.

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Diversus 2108 18.02.20 15:38 Сейчас в теме
Отличная статья! Спасибо за подробное описание. Если позволите замечание:
В случае если среди похожих есть инцидент с готовым решением – покажем его сотруднику и спрашиваем подошло ли решение. Если решение подходит – мы не создаем инцидент, считая что проблема решена.
На мой взгляд было бы лучше все таки создавать инцидент, сразу устанавливая статус, что он решен и способ его решения - машинное обучение с указанием на способ решения. Тогда можно было бы видеть тут же в help desk/service desk сколько таких инцидентов было решено с использованием машинного обучения. Иначе не совсем понятен порядок цифр и сколько в процентном отношении все таки по факту решается автоматически.
PS: Но это больше придирки конечно :)
romankoav; +1 Ответить
3. Repich 507 18.02.20 16:11 Сейчас в теме
(1) Эта информация фиксируется в отдельной базе. Точнее фиксируется сам факт что пользователю предложено решение и его ответ "подошло/не подошло". Но идея - создавать инцидент и сразу закрывать его - интересная, это действительно дополнительная информация для аналитики, спасибо, обдумаю.
2. akim2040 20 18.02.20 15:43 Сейчас в теме
Можно спросить, у Вас тоже есть такие нерадивые пользователи, которые считают что на сервис-деск достаточно кинуть один скриншот без всякого описания?
Если да, как такие обрабатываете?
4. Repich 507 18.02.20 16:14 Сейчас в теме
(2) К сожалению только вручную. Первая линия возвращает их на инициатора с требованием описать проблему.
5. TODD22 19 18.02.20 16:19 Сейчас в теме
(4)
К сожалению только вручную. Первая линия возвращает их на инициатора с требованием описать проблему.

А автоматически это нельзя сделать? Если нет текстового описания то нужно ответить на ряд наводящих вопросов и отправить повторно. Можно сразу сделать форму в которую нельзя отправить без текстового описания.
6. Repich 507 18.02.20 16:23 Сейчас в теме
(5)
А автоматически это нельзя сделать? Если нет текстового описания то нужно ответить на ряд наводящих вопросов и отправить повторно. Можно сразу сделать форму в которую нельзя отправить без текстового описания.


Можно конечно. Но так как жалоб от первой линии нет - значит проблема не сильно им мешает.
7. TODD22 19 18.02.20 16:26 Сейчас в теме
(6)У нас заявка без описания не создаётся.
8. akim2040 20 18.02.20 17:00 Сейчас в теме
(7) ну ведь ничего не мешает написать в описании "не работает", и это будет не очень информативно. Думаю и правда, такое только под ручную обработку
Fox-trot; +1 Ответить
9. TODD22 19 18.02.20 17:10 Сейчас в теме
(8)
ну ведь ничего не мешает написать в описании "не работает", и это будет не очень информативно.

Конечно ничего не мешает. Но наличие этого поля уже дисциплинирует. К тому же можно там же делать подсказки как надо описывать ошибки, пожелания по доработке и тд.
Меньше "холостой" работы для ТП им не надо отправлять пользователю его ошибку что бы дополнял. Обычно описание есть. Не всегда внятное, но всё же есть.
10. pm74 177 18.02.20 18:33 Сейчас в теме
(0) супер , прочитал пока бегло но впечатляет
11. lunjio 64 18.02.20 20:37 Сейчас в теме
(0)
Спасибо за статью, очень интересное решение.
У вас это в виде внешней компоненты/сервиса, как организовано на уровне архитектуры ? Погрузите пожалуйста в непосредственную реализацию, тоесть вы разбираете текущее обращение, получаете схожие слова, запросом отбираете инциденты где есть эти слова, потом их так же к векторам преобразуете и т.д? Либо внешний сервис напрямую к скулю обращается и сам уже получает список инцидентов с похожими словами и их преобразует к векторам и выдает упорядоченными по схожести ?
Как с производительностью дела обстоят ? За какой промежуток времени обработка и выдача результата происходит ? Спасибо
12. Repich 507 18.02.20 21:18 Сейчас в теме
(11) Наверное отвечу отдельной статьей.
17. Repich 507 25.02.20 18:27 Сейчас в теме
13. oleganatolievich 146 20.02.20 11:28 Сейчас в теме
прочел бегло, статья крутая. вот это я понимаю автоматизация автоматизации.
juliia1992; +1 Ответить
14. kalyaka 603 21.02.20 09:26 Сейчас в теме
А есть какие-нибудь решения, которые бы могли проводить смысловой лингвистический анализ и на основе смысловых фреймов определять о чем идет речь в тексте? А то так получается, что анализа никакого нет, есть чисто статистическая выборка и оценка вероятности, что на основе такого набора слов скорее всего речь идет об этом.

Это чем-то мне напоминает изучение иностранного языка в школе, когда учитель не особо заморачивается над передачей понимания, делает упор на зубрежке иностранных слов. После такого обучения на основе данных о контексте переводимого текста и знания отдельных слов можно ловко "фантазировать" близкий (иногда не очень) по смыслу перевод.
15. Repich 507 21.02.20 16:08 Сейчас в теме
(14) То, о чем вы пишите работает точно так же как и описанный выше механизм. Берется выборка для обучения, на основе которой строится модель, которая в свою очередь выдает коэффициент сходства исследуемого текста и тех классификаторов, которые есть в модели.
Машинное обучение и модные сейчас нейронные сети оперируют ТОЛЬКО числами.
Если вы обучили модель на журнальных статьях - она сможет отличить статью про спорт от статьи про автомобили, но рассказ Куприна от повести Чехова она отличить не сможет.
16. kalyaka 603 21.02.20 17:13 Сейчас в теме
(15) Я имел в виду использование лингвистического анализа: типа кто-то или что-то совершает такое то действие. Выделить объект и субъект и возможные отношения между ними. Т.е. это получается экспертная система с возможностью накопления связанной информации для поиска путей решения.

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

См. также

Использование программных перечислений, ч.1: строковые константы Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Часто ли у вас возникает необходимость в коде выполнять сравнение на строку?

10.12.2016    37241    unichkin    74    

«Варп-двигатель» для «среза последних»

Практика программирования Бесплатно (free)

Решение, позволяющее получить данные, аналогичные "срезу последних" на два порядка быстрее.

10.08.2020    2709    hobi    45    

Не спеша, эффективно и правильно – путь разработки. Часть 3. Практика

Практика программирования Бесплатно (free)

Черновой вариант книги Никиты Зайцева, a.k.a.WildHare. Разработкой на платформе 1С автор занимается с 1996-го года, специализация — большие и по-хорошему страшные системы. Квалификация “Эксперт”, несколько успешных проектов класса “сверхтяжелая”. Успешные проекты ЦКТП. Четыре года работал в самой “1С”, из них два с половиной архитектором и ведущим разработчиком облачной Технологии 1cFresh. Ну — и так далее. Не хвастовства ради, а понимания для. Текст написан не фантазером-теоретиком, а экспертом, у которого за плечами почти двадцать три года инженерной практики на больших проектах.

29.06.2020    8270    WildHare    33    

Не спеша, эффективно и правильно – путь разработки. Часть 2. Теория

Практика программирования Бесплатно (free)

Черновой вариант книги Никиты Зайцева, a.k.a.WildHare. Разработкой на платформе 1С автор занимается с 1996-го года, специализация — большие и по-хорошему страшные системы. Квалификация “Эксперт”, несколько успешных проектов класса “сверхтяжелая”. Успешные проекты ЦКТП. Четыре года работал в самой “1С”, из них два с половиной архитектором и ведущим разработчиком облачной Технологии 1cFresh. Ну — и так далее. Не хвастовства ради, а понимания для. Текст написан не фантазером-теоретиком, а экспертом, у которого за плечами почти двадцать три года инженерной практики на больших проектах.

22.06.2020    9374    WildHare    23    

Вспомогательные инструкции в коде 1С Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Помогаем редактору кода 1С помогать нам писать и анализировать код.

15.10.2018    30099    tormozit    100    

Не спеша, эффективно и правильно – путь разработки. Часть 1. Парадигма

Практика программирования Бесплатно (free)

Черновой вариант книги Никиты Зайцева, a.k.a.WildHare. Разработкой на платформе 1С автор занимается с 1996-го года, специализация — большие и по-хорошему страшные системы. Квалификация “Эксперт”, несколько успешных проектов класса “сверхтяжелая”. Успешные проекты ЦКТП. Четыре года работал в самой “1С”, из них два с половиной архитектором и ведущим разработчиком облачной Технологии 1cFresh. Ну — и так далее. Не хвастовства ради, а понимания для. Текст написан не фантазером-теоретиком, а экспертом, у которого за плечами почти двадцать три года инженерной практики на больших проектах.

15.06.2020    13422    WildHare    34    

JSON в запросах DaJet QL

Практика программирования Бесплатно (free)

Практические примеры работы с JSON непосредственно в языке запросов. Перенос курсов валют между УТ и БП. Требуется SQL Server 2016 и выше.

24.04.2020    3768    zhichkin    6    

Визионное программирование

Практика программирования Бесплатно (free)

Новый способ программирования и его практическая демонстрация.

22.04.2020    4451    mkalimulin    111    

Оформление и рефакторинг сложных логических выражений Промо

Практика программирования v8 Россия Бесплатно (free)

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

20.09.2012    77861    tormozit    131    

Использование машинного обучения для решения инцидентов. Практическое применение

Практика программирования Бесплатно (free)

Продолжаю (и заканчиваю) тему с автоматическим решением инцидентов. Перейдем от теории к практике.

25.02.2020    4148    Repich    9    

Часовой на страже логов

Практика программирования Инструментарий разработчика Бесплатно (free)

При поддержке решений, которые установлены у большого количества пользователей на различных системах, очень важно вовремя получать подробную информацию о возникших проблемах. О том, как собирать логи и анализировать полученные данные в трекере ошибок Sentry на конференции Infostart Event 2019 Inception рассказал Андрей Крапивин.

13.01.2020    6485    Scorpion4eg    8    

Приватный блокчейн и 1С популярно

Практика программирования Блокчейн Бесплатно (free)

Две предыдущие публикации на эту тему были сфокусированы преимущественно на технической стороне вопроса. Кроме того, их содержание оказалось понятным не каждому специалисту. В этой статье я постараюсь обяснить для всех и, что говорится, «на пальцах»: что такое приватный блокчейн, когда и зачем его следует применять и на что обратить внимание при использовании этой технологии в 1С.

02.09.2019    6053    mkalimulin    140    

Запись значения в поле ввода/формы со срабатыванием события ПриИзменении Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Иногда возникает необходимость после записи значения в какое либо поле ввода/формы вызвать для него обработчик события ПриИзменении, а о вызове самого события приходится только мечтать. В этой статье приводится программный способ вызова этого события.

11.07.2007    48205    tormozit    41    

Кодогенерация и метагенерация в 1С

Практика программирования Инструментарий разработчика Бесплатно (free)

В своем докладе на конференции INFOSTART EVENT 2018 EDUCATION Дмитрий Белозеров рассказал о разработке инструмента, позволяющего программно работать с метаданными 1С и писать скрипты для выполнения тех же действий, которые выполняет разработчик в конфигураторе –  с какими сложностями и нюансами пришлось столкнуться, и что получилось в итоге.

26.08.2019    8999    kirovsbis    28    

Интеграция сценарного тестирования в процесс разработки

Практика программирования Инструментарий разработчика Бесплатно (free)

Разработчик системы «Тестер» Дмитрий Решитко в своем докладе на конференции INFOSTART EVENT 2018 EDUCATION показывает, что процесс тестирования можно очень плотно интегрировать в процесс разработки, что внедрение тестирования – это возможность развития программиста как такового, позволяющая ему упорядочивать ход мыслей и оставаться «в фокусе». Навыки построения процесса кодирования на стыке с тестированием сокращают время на концентрацию, освобождают от страха перед изменениями и улучшают память разработчика.

08.07.2019    9146    grumagargler    7    

Управляй качеством кода 1С с помощью SonarQube

Практика программирования Россия Бесплатно (free)

Управляй техническом долгом проектов 1С с помощью SonarQube. В статье рассматривается пример применения SonarQube при разработке.

07.07.2019    39204    olegtymko    231    

Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Как сделать метод формы, доступный на клиенте и на сервере одновременно, и сохранить при этом удобство разработки

10.09.2017    44639    tormozit    74    

Выгрузка документа по условию

Практика программирования Разработка v8 Бесплатно (free)

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    16013    m-rv    2    

Как прикрутить ГУИД к регистру сведений

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 Бесплатно (free)

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

16.04.2019    20143    m-rv    17    

О времени и 1С

Практика программирования Разработка Бесплатно (free)

Основы и особенности работы со временем в 1С. Как избавиться от боли при работе в разных часовых поясах. Что такое момент времени. И другое.

01.04.2019    34686    YPermitin    61    

Развитие 1С программиста Промо

Практика программирования Личная эффективность Бесплатно (free)

Делюсь своим опытом и видением развития 1С программиста.

17.10.2018    20685    pashamak    62    

Пример создания bridge (http api - tcp) для ККТ "Касса №1" ("К1-Ф")

Практика программирования ККМ Кассовые операции Кассовые операции Разработка Россия Бесплатно (free)

Пример создания bridge (http api - tcp) для ККТ "Касса №1" ("К1-Ф"). Данная статья будет полезна интеграторам, программистам, тем кто работает (интегрирует, разрабатывает) различное ТО либо железки. Версия и релиз технологической платформы не имеет значения.

17.03.2019    6552    dmarenin    1    

Быстрее чем INSERT! BULK-операции и примеры использования

Производительность и оптимизация (HighLoad) Практика программирования Внешние источники данных Перенос данных из 1C8 в 1C8 Разработка Бесплатно (free)

Microsoft SQL Server поддерживает так называемые BULK-операции, используемые для быстрого изменения больших объемов данных в базе. В статье пойдет речь о практических примерах их использования. Все примеры сделаны в контексте платформы 1С (а как иначе).

09.03.2019    24030    YPermitin    40    

Как сделать запрос на изменение данных Промо

Практика программирования v8 v8::Запросы 1cv8.cf Бесплатно (free)

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    30488    m-rv    21    

Как писать понятные коммиты

Практика программирования Разработка Россия Бесплатно (free)

Как писать сообщения коммитов так, чтобы потом не было мучительно больно.

06.03.2019    12645    Scorpion4eg    35    

Подготовка ребёнка к ЕГЭ по информатике. Часть шестнадцатая

Практика программирования Разработка Бесплатно (free)

Поиск выигрышной стратегии, завершающая статья.

22.02.2019    5689    vasilev2015    0    

Метод формирования движений в типовых регистрах нетиповыми регистраторами Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Вариант решения задач с проведением по типовым регистрам нетиповыми регистраторами. Зачем - чтобы при сравнении конфигурации не обращать внимание на свойства регистров и исключить вероятность допущения горькой оплошности при обновлении информационных баз, заменив типы регистраторов основной конфигурации типами конфигурации поставщика. Для программных продуктов, имеющих в своем составе метаданных документ "Корректировка регистров"("Корректировка записей регистров").

05.12.2017    28205    itriot11    34    

Подготовка ребёнка к ЕГЭ по информатике. Часть тринадцатая

Практика программирования Разработка Бесплатно (free)

Исправление ошибок в программе, часть вторая.

20.02.2019    5750    vasilev2015    3    

Использование классов .Net в 1С для новичков Промо

Практика программирования Разработка внешних компонент Универсальные функции v7.7 v8 Бесплатно (free)

Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

27.01.2016    76210    Serginio    108    

Автоматические и управляемые блокировки применительно к типовым конфигурациям 1С Промо

Математика и алгоритмы Практика программирования v8 v8::blocking 1cv8.cf Бесплатно (free)

Основные принципы работы с режимами автоматических и управляемых блокировок в 1С Предприятие 8. Теория и применение в типовых конфигурациях: БП, УТ, ЕРП

10.11.2018    34532    ids79    40    

Подготовка ребёнка к ЕГЭ по информатике. Часть восьмая

Практика программирования Разработка Бесплатно (free)

Шифрование и дешифрование информации. Закон Фано

05.02.2019    5613    vasilev2015    1    

Тестер: частые вопросы Промо

Практика программирования v8 Бесплатно (free)

Ошибкам бой - тесты норма жизни!

25.07.2018    29175    grumagargler    28    

Расширяем свой багаж

Практика программирования Разработка Бесплатно (free)

Алгоритм решения возможной нетиповой задачи на собеседовании.

29.01.2019    6358    scientes    15    

Подготовка ребёнка* к ЕГЭ по информатике. Часть четвертая

Практика программирования Разработка Бесплатно (free)

Решение систем логических уравнений повышенного уровня сложности.

25.01.2019    6191    vasilev2015    0    

Подготовка ребенка* к ЕГЭ по информатике. Часть третья

Практика программирования Разработка Бесплатно (free)

Алгоритмы рекурсии, логические задачи. Подготовка к ЕГЭ.

22.01.2019    7519    vasilev2015    0    

Разработка и сценарное тестирование с Vanessa-ADD. Установка инструментов. Запись действий пользователя и выполнение сценариев

Практика программирования Vanessa Automation Бесплатно (free)

Вторая часть цикла публикаций, посвященных Vanessa-ADD и автоматизации тестирования.

21.01.2019    34259    Vladimir Litvinenko    96    

Подготовка ребенка* к ЕГЭ по информатике. Часть вторая

Практика программирования Бесплатно (free)

Примеры на Паскале. Если сам родитель* - поддержи ! Если сам водила - посигналь !

19.01.2019    5867    vasilev2015    0    

Подготовка к ЕГЭ сына - школьника (по информатике)

Практика программирования Бесплатно (free)

Примеры на Паскале. Если сам отец - поддержи ! Если сам водила - посигналь !

17.01.2019    6638    vasilev2015    50    

Быстрая отладка экранных форм документов и справочников

Практика программирования Бесплатно (free)

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

18.12.2018    7065    milkers    19    

1С + asterisk (автоматический обзвон) часть 1

WEB Практика программирования Телефония, SIP Россия Бесплатно (free)

Пример реализации автообзвона (с обработкой ответа на отвечающей стороне) с использованием ami asterisk. Данная статья может быть полезна программистам, интеграторам, администраторам. Версия и релиз технологической платформы не имеет значения.

29.11.2018    11785    dmarenin    9