РезультатАнализаДанныхДеревоРешений

Типы · DataAnalysisDecisionTreeResult

Содержит информацию о результате анализа дерева решений.

Полное описание, параметры и ограничения

РезультатАнализаДанныхДеревоРешений (DataAnalysisDecisionTreeResult)

РезультатАнализаДанныхДеревоРешений (DataAnalysisDecisionTreeResult)

Доступен, начиная с версии 8.0.

Свойства:
Глубина (Depth)
Классификации (Classifications)
КоличествоКлассов (ClassCount)
КоличествоЛистьев (LeafCount)
КоличествоОбъектов (ObjectCount)
КоличествоУзлов (NodeCount)
КорневыеУзлы (RootNodes)
НастройкаКолонок (ColumnsSetting)
Ошибка (Error)
Параметры (Parameters)

Методы:
СоздатьМодельПрогноза (CreatePredictionModel)

Описание:

Содержит информацию о результате анализа дерева решений.

Доступность:

Сервер, толстый клиент, внешнее соединение.
Сериализуется.

Использование в версии:

Доступен, начиная с версии 8.0.

Методическая информация

Практические примеры

Обучить свое дерево на32 случаях и разобрать реальные классы, узлы и созданную модель

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

Где и как запускать

Полный серверный общий модуль УчебноеДеревоРешений85 собственной пустой конфигурации; отдельная управляемая форма получает только текст. В1С не выполнялся.

Подготовка

  1. НОВАЯ отдельная пустая файловая база точно8.5.1.1343. Имя конфигурации УчебноеДеревоРешений85, совместимость Не использовать, Русский. Нет прикладных объектов, общих реквизитов, расширений, подписок, заданий или рабочих данных; модули конфигурации вручную пустые. Не использовать БП/КА2/УТ/УНФ.

  2. Общие → Общие модули → УчебноеДеревоРешений85. Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставить весь основной модуль, включая функции подготовки, проверки, обхода и защиты стенда. Будущая ручная подготовка: сохранить и обновить только собственную базу F7.

  3. Собственная внешняя обработка УчебныйРасчетДерева85 → управляемая Форма → команда/кнопка Выполнить, действие Выполнить. Полный отдельный модуль формы ниже вызывает только собственный серверный общий модуль и получает текст отчета. Таблицы, алгоритм, узлы и модель на клиент не передаются.

  4. Код в памяти создает32 строки: восемь повторений остатков0,1,10,11 с уникальными own-case-кодами. РешениеПоПравилу=Нужно для остатка<5, иначе Достаточно. Это вымышленные метки, иллюстрирующие уже заданное учебное правило, а не данные реальных продаж/заказов.

  5. Код — НеИспользуемая колонка, Остаток — Входная с видом Непрерывные, РешениеПоПравилу — Прогнозируемая с видом Дискретные. МинимальноеКоличествоСлучаев1, МаксимальнаяГлубина4, ТипУпрощенияНеУпрощать. Имена параметров сверены с installed-справкой; их реально ищет созданный анализатор.

  6. Никакие строки1С, модели в базе, файлы, печатные документы или сетевые сервисы не подготавливать. Нет рабочего источника, обучения нейросети, отправки данных наружу или автоматической закупки. Вывод основан только на текущем маленьком объекте памяти.

Функция ВыполнитьПример() Экспорт
    ПроверитьСвойПустойСтенд();
    Таблица = СоздатьСвоиСлучаи();
    Анализатор = Новый АнализДанных;
    Анализатор.ТипАнализа = Тип("АнализДанныхДеревоРешений");
    Анализатор.ИсточникДанных = Таблица;
    НастроитьСвоиКолонки(Анализатор.НастройкаКолонок);
    НастроитьСвойПараметр(Анализатор.Параметры, "МинимальноеКоличествоСлучаев", 1);
    НастроитьСвойПараметр(Анализатор.Параметры, "МаксимальнаяГлубина", 4);
    НастроитьСвойПараметр(Анализатор.Параметры, "ТипУпрощения", ТипУпрощенияДереваРешений.НеУпрощать);
    Результат = Анализатор.Выполнить();
    Если ТипЗнч(Результат) <> Тип("РезультатАнализаДанныхДеревоРешений") Тогда
        ВызватьИсключение "Не получен настоящий результат своего дерева решений";
    КонецЕсли;
    Если Результат.КоличествоОбъектов <> Таблица.Количество() Или Результат.КоличествоКлассов <> 2
        Или Результат.КоличествоЛистьев < 1 Или Результат.КоличествоУзлов < Результат.КоличествоЛистьев
        Или Результат.Глубина < 0 Или Результат.Ошибка < 0 Или Результат.Ошибка > 100 Тогда
        ВызватьИсключение "Результат не согласован с собственными32 случаями и двумя метками";
    КонецЕсли;
    ПроверитьСвоиКолонкиРезультата(Результат.НастройкаКолонок);
    ПроверитьСвойПараметр(Результат.Параметры, "МинимальноеКоличествоСлучаев", 1);
    ПроверитьСвойПараметр(Результат.Параметры, "МаксимальнаяГлубина", 4);
    ПроверитьСвойПараметр(Результат.Параметры, "ТипУпрощения", ТипУпрощенияДереваРешений.НеУпрощать);
    Отчет = "СВОЙ УЧЕБНЫЙ РАСЧЕТ, НЕ ПРОГНОЗ РЕАЛЬНЫХ ЗАКУПОК" + Символы.ПС;
    Отчет = Отчет + "Объектов: " + Строка(Результат.КоличествоОбъектов) + "; классов: " + Строка(Результат.КоличествоКлассов) + Символы.ПС;
    Отчет = Отчет + "Узлов: " + Строка(Результат.КоличествоУзлов) + "; листьев: " + Строка(Результат.КоличествоЛистьев) + Символы.ПС;
    Отчет = Отчет + "Глубина по платформе: " + Строка(Результат.Глубина) + "; ошибка дерева в процентах: " + Строка(Результат.Ошибка) + Символы.ПС;
    Классификации = Результат.Классификации;
    Если ТипЗнч(Классификации) <> Тип("ФиксированныйМассив") Или Классификации.Количество() = 0 Тогда
        ВызватьИсключение "Нужен реальный непустой массив сгруппированных классификаций";
    КонецЕсли;
    ВсегоСлучаев = 0;
    Для Каждого Классификация Из Классификации Цикл
        Если ТипЗнч(Классификация) <> Тип("КлассификацияОбъектаАнализаДанных") Или Классификация.Количество < 0 Тогда
            ВызватьИсключение "Не получена настоящая классификация собственных случаев";
        КонецЕсли;
        Факт = ОписатьСвойКласс(Классификация.Факт);
        Прогноз = ОписатьСвойКласс(Классификация.Прогноз);
        ВсегоСлучаев = ВсегоСлучаев + Классификация.Количество;
        Отчет = Отчет + "Случаев: " + Строка(Классификация.Количество) + "; факт: " + Факт + "; прогноз: " + Прогноз + Символы.ПС;
    КонецЦикла;
    Если ВсегоСлучаев <> Таблица.Количество() Тогда
        ВызватьИсключение "Сумма количества случаев классификаций не равна32";
    КонецЕсли;
    Корни = Результат.КорневыеУзлы;
    СтатистикаУзлов = ОбойтиСвоиУзлы(Корни);
    Если СтатистикаУзлов.Узлов <> Результат.КоличествоУзлов Или СтатистикаУзлов.Листьев <> Результат.КоличествоЛистьев Тогда
        ВызватьИсключение "Независимый обход не совпал с числами узлов и листьев результата";
    КонецЕсли;
    Отчет = Отчет + СтатистикаУзлов.Отчет + Символы.ПС;
    Модель = Результат.СоздатьМодельПрогноза();
    Если ТипЗнч(Модель) <> Тип("МодельПрогнозаДеревоРешений") Тогда
        ВызватьИсключение "Результат не создал настоящий объект модели прогноза";
    КонецЕсли;
    КорниМодели = Модель.КорневыеУзлы;
    СтатистикаМодели = ОбойтиСвоиУзлы(КорниМодели);
    Если СтатистикаМодели.Узлов <> СтатистикаУзлов.Узлов Или СтатистикаМодели.Листьев <> СтатистикаУзлов.Листьев Тогда
        ВызватьИсключение "Модель и результат не согласованы по своей структуре дерева";
    КонецЕсли;
    Отчет = Отчет + "Модель действительно создана из собственного результата; ее корни обходятся. Прогноз на новых данных в этом уроке не выполнялся";
    Возврат Отчет;
КонецФункции

Функция СоздатьСвоиСлучаи()
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
    Таблица.Колонки.Добавить("Остаток", Новый ОписаниеТипов("Число"));
    Таблица.Колонки.Добавить("РешениеПоПравилу", Новый ОписаниеТипов("Строка"));
    Остатки = Новый Массив;
    Остатки.Добавить(0);
    Остатки.Добавить(1);
    Остатки.Добавить(10);
    Остатки.Добавить(11);
    Для Повтор = 1 По 8 Цикл
        Для Каждого Остаток Из Остатки Цикл
            СтрокаСлучая = Таблица.Добавить();
            СтрокаСлучая.Код = "own-case-" + Строка(Повтор) + "-" + Строка(Остаток);
            СтрокаСлучая.Остаток = Остаток;
            СтрокаСлучая.РешениеПоПравилу = ?(Остаток < 5, "Нужно", "Достаточно");
        КонецЦикла;
    КонецЦикла;
    Если Таблица.Количество() <> 32 Тогда
        ВызватьИсключение "Нужны ровно32 собственных учебных случая";
    КонецЕсли;
    Возврат Таблица;
КонецФункции

Процедура НастроитьСвоиКолонки(Настройки)
    Код = Настройки.Найти("Код");
    Остаток = Настройки.Найти("Остаток");
    КолонкаРешения = Настройки.Найти("РешениеПоПравилу");
    Если Код = Неопределено Или Остаток = Неопределено Или КолонкаРешения = Неопределено Или Настройки.Количество() <> 3 Тогда
        ВызватьИсключение "Анализатор должен создать настройки трех собственных колонок";
    КонецЕсли;
    Код.ТипКолонки = ТипКолонкиАнализаДанныхДеревоРешений.НеИспользуемая;
    Остаток.ТипКолонки = ТипКолонкиАнализаДанныхДеревоРешений.Входная;
    Остаток.ВидДанных = ВидДанныхАнализа.Непрерывные;
    КолонкаРешения.ТипКолонки = ТипКолонкиАнализаДанныхДеревоРешений.Прогнозируемая;
    КолонкаРешения.ВидДанных = ВидДанныхАнализа.Дискретные;
    ПроверитьСвоиКолонкиРезультата(Настройки);
КонецПроцедуры

Процедура ПроверитьСвоиКолонкиРезультата(Настройки)
    Если ТипЗнч(Настройки) <> Тип("КолонкиАнализаДанных") Или Настройки.Количество() <> 3 Тогда
        ВызватьИсключение "Нужны настоящие три настройки колонок анализа";
    КонецЕсли;
    Код = Настройки.Найти("Код");
    Остаток = Настройки.Найти("Остаток");
    КолонкаРешения = Настройки.Найти("РешениеПоПравилу");
    Если Код = Неопределено Или Остаток = Неопределено Или КолонкаРешения = Неопределено Тогда
        ВызватьИсключение "Исчезла собственная колонка";
    КонецЕсли;
    Если Код.ТипКолонки <> ТипКолонкиАнализаДанныхДеревоРешений.НеИспользуемая
        Или Остаток.ТипКолонки <> ТипКолонкиАнализаДанныхДеревоРешений.Входная
        Или Остаток.ВидДанных <> ВидДанныхАнализа.Непрерывные
        Или КолонкаРешения.ТипКолонки <> ТипКолонкиАнализаДанныхДеревоРешений.Прогнозируемая
        Или КолонкаРешения.ВидДанных <> ВидДанныхАнализа.Дискретные Тогда
        ВызватьИсключение "Перепутаны ключ, числовой вход или собственная метка класса";
    КонецЕсли;
КонецПроцедуры

Функция НайтиСвойПараметр(Параметры, Имя)
    Параметр = Параметры.Найти(Имя);
    Если Параметр = Неопределено Или ТипЗнч(Параметр) <> Тип("ПараметрАнализаДанных") Тогда
        ВызватьИсключение "Не найден собственный параметр алгоритма " + Имя;
    КонецЕсли;
    Индекс = Параметры.Индекс(Параметр);
    Если Индекс < 0 Или Индекс >= Параметры.Количество() Тогда
        ВызватьИсключение "Индекс настоящего параметра выходит за границы";
    КонецЕсли;
    ПоИндексу = Параметры.Получить(Индекс);
    Если ПоИндексу.Имя <> Параметр.Имя Или ПоИндексу.Имя <> Имя Тогда
        ВызватьИсключение "Найти и Получить не вернули один собственный параметр";
    КонецЕсли;
    Возврат Параметр;
КонецФункции

Процедура НастроитьСвойПараметр(Параметры, Имя, Значение)
    Параметр = НайтиСвойПараметр(Параметры, Имя);
    Если Не Параметр.ТипЗначения.СодержитТип(ТипЗнч(Значение)) Тогда
        ВызватьИсключение "Тип значения не разрешен реальным параметром " + Имя;
    КонецЕсли;
    Параметр.Значение = Значение;
    ПроверитьСвойПараметр(Параметры, Имя, Значение);
КонецПроцедуры

Процедура ПроверитьСвойПараметр(Параметры, Имя, Эталон)
    Параметр = НайтиСвойПараметр(Параметры, Имя);
    Если ТипЗнч(Параметр.Значение) <> ТипЗнч(Эталон) Или Параметр.Значение <> Эталон Тогда
        ВызватьИсключение "Не совпал собственный параметр результата " + Имя;
    КонецЕсли;
КонецПроцедуры

Функция ОписатьСвоеСвойство(Описание)
    Если ТипЗнч(Описание) <> Тип("СвойствоОбъектаАнализаДанных") Тогда
        ВызватьИсключение "Нужно реальное описание значения или условия собственного анализа";
    КонецЕсли;
    Возврат Описание.Имя + "; сравнение=" + Строка(Описание.ВидСравнения)
        + "; значение=" + Строка(Описание.Значение) + "; с=" + Строка(Описание.ЗначениеС) + "; по=" + Строка(Описание.ЗначениеПо);
КонецФункции

Функция ОписатьСвойКласс(Класс)
    Если ТипЗнч(Класс) <> Тип("ОбъектАнализаДанных") Тогда
        ВызватьИсключение "Нужен реальный объект факта, прогноза или решения";
    КонецЕсли;
    Свойства = Новый Структура("РешениеПоПравилу", Неопределено);
    ЗаполнитьЗначенияСвойств(Свойства, Класс);
    Описание = Свойства.РешениеПоПравилу;
    Если Описание = Неопределено Тогда
        ВызватьИсключение "У собственного класса отсутствует единственная прогнозируемая колонка";
    КонецЕсли;
    Если ТипЗнч(Описание) <> Тип("СвойствоОбъектаАнализаДанных") Или Описание.Имя <> "РешениеПоПравилу"
        Или Описание.ВидСравнения <> ВидСравнения.Равно
        Или ТипЗнч(Описание.Значение) <> Тип("Строка")
        Или (Описание.Значение <> "Нужно" И Описание.Значение <> "Достаточно") Тогда
        ВызватьИсключение "Факт или прогноз не описывает собственную метку класса";
    КонецЕсли;
    Возврат ОписатьСвоеСвойство(Описание);
КонецФункции

Функция ОписатьСвоеРешение(Решение)
    Если ТипЗнч(Решение) <> Тип("РешениеАнализаДанных") Или Решение.КоличествоСлучаев < 0 Тогда
        ВызватьИсключение "Нужно настоящее возможное решение собственного узла";
    КонецЕсли;
    Возврат ОписатьСвойКласс(Решение.Решение) + "; правильных случаев=" + Строка(Решение.КоличествоСлучаев)
        + "; вероятность как вернула платформа=" + Строка(Решение.Вероятность);
КонецФункции

Функция ОбойтиСвоиУзлы(Корни)
    Если ТипЗнч(Корни) <> Тип("ФиксированныйМассив") Или Корни.Количество() = 0 Тогда
        ВызватьИсключение "Нужны настоящие непустые корни собственного результата или модели";
    КонецЕсли;
    Стек = Новый Массив;
    Для Каждого Корень Из Корни Цикл
        Стек.Добавить(Новый Структура("Узел,Уровень", Корень, 0));
    КонецЦикла;
    КоличествоУзлов = 0;
    КоличествоЛистьев = 0;
    Отчет = "ОБХОД СОБСТВЕННЫХ УЗЛОВ" + Символы.ПС;
    Пока Стек.Количество() > 0 Цикл
        Индекс = Стек.Количество() - 1;
        Кадр = Стек[Индекс];
        Стек.Удалить(Индекс);
        Узел = Кадр.Узел;
        Если ТипЗнч(Узел) <> Тип("УзелДереваРешений") Или Кадр.Уровень > 64 Или КоличествоУзлов >= 128 Тогда
            ВызватьИсключение "Свой маленький обход вышел за допустимые учебные границы";
        КонецЕсли;
        КоличествоУзлов = КоличествоУзлов + 1;
        Отчет = Отчет + "Узел=" + Строка(КоличествоУзлов) + "; уровень обхода=" + Строка(Кадр.Уровень)
            + "; попало случаев=" + Строка(Узел.КоличествоСлучаев) + Символы.ПС;
        Условие = Узел.Условие;
        Если Условие <> Неопределено Тогда
            Если ТипЗнч(Условие) <> Тип("ОбъектАнализаДанных") Тогда
                ВызватьИсключение "Узел не вернул документированный объект условия";
            КонецЕсли;
            Свойства = Новый Структура("Остаток", Неопределено);
            ЗаполнитьЗначенияСвойств(Свойства, Условие);
            Если Свойства.Остаток <> Неопределено Тогда
                Отчет = Отчет + "Условие своего числового входа: " + ОписатьСвоеСвойство(Свойства.Остаток) + Символы.ПС;
            Иначе
                Отчет = Отчет + "У этого узла нет описания условия по Остаток; выдуманная граница не подставлялась" + Символы.ПС;
            КонецЕсли;
        КонецЕсли;
        Отчет = Отчет + "Лучшее решение: " + ОписатьСвоеРешение(Узел.Решение) + Символы.ПС;
        ВсеРешения = Узел.ВсеРешения;
        Если ТипЗнч(ВсеРешения) <> Тип("ФиксированныйМассив") Тогда
            ВызватьИсключение "Нужен настоящий массив возможных решений узла";
        КонецЕсли;
        Для Каждого Возможное Из ВсеРешения Цикл
            Отчет = Отчет + "Возможное решение: " + ОписатьСвоеРешение(Возможное) + Символы.ПС;
        КонецЦикла;
        Дети = Узел.Узлы;
        Если ТипЗнч(Дети) <> Тип("ФиксированныйМассив") Тогда
            ВызватьИсключение "Нужен настоящий массив вложенных узлов";
        КонецЕсли;
        Если Дети.Количество() = 0 Тогда
            КоличествоЛистьев = КоличествоЛистьев + 1;
        Иначе
            Для Каждого Дочерний Из Дети Цикл
                Стек.Добавить(Новый Структура("Узел,Уровень", Дочерний, Кадр.Уровень + 1));
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
    Возврат Новый Структура("Узлов,Листьев,Отчет", КоличествоУзлов, КоличествоЛистьев, Отчет);
КонецФункции

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры
УчебныйРасчетДерева85.Форма

Собственная внешняя обработка → управляемая Форма → Модуль

Полный клиент-серверный модуль формы, не клиентский расчет анализа данных.

&НаКлиенте
Процедура Выполнить(Команда)
    Отчет = ВыполнитьНаСервере();
    Сообщить(Отчет);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ВыполнитьНаСервере()
    Возврат УчебноеДеревоРешений85.ВыполнитьПример();
КонецФункции

Разбор по шагам

  1. Серверный guard проверяет отсутствие прикладных объектов, расширений и активной транзакции. СоздатьСвоиСлучаи возвращает реальную ТаблицаЗначений с32 явно размеченными строками, а не неизвестный Источник.

  2. ТипАнализа — значение Тип("АнализДанныхДеревоРешений"), не строка или выдуманное перечисление. После назначения источника появляются реальные настройки колонок. Каждое Найти проверяется, три роли и два вида данных задаются и перечитываются.

  3. Параметры создаются самим алгоритмом. НайтиСвойПараметр подтверждает настоящий ПараметрАнализаДанных, получает Индекс, проверяет границы и перечитывает его через Получить. ТипЗначения.СодержитТип проверяется до присваивания Значение; после расчета те же значения и типы сверяются через Результат.Параметры.

  4. Выполнить возвращает настоящий РезультатАнализаДанныхДеревоРешений. КоличествоОбъектов сопоставляется с32 строками, КоличествоКлассов с двумя собственными метками; глубина, узлы, листья и ошибка выводятся фактически. Не обещается конкретная граница разделения, размер дерева или нулевая ошибка.

  5. Классификации — ФиксированныйМассив сгруппированных пар Факт/Прогноз. Количество каждого элемента — вес случаев этой классификации. Складываем веса и сверяем с32, а не требуем32 элементов массива. Факт и Прогноз имеют тип ОбъектАнализаДанных, их динамическое свойство РешениеПоПравилу содержит отдельное СвойствоОбъектаАнализаДанных, не голую строку.

  6. В собственную Структура копируется только совпадающее имя свойства без явного СписокСвойств. Поэтому у корневого условия без Остаток структура остается с Неопределено, а отсутствие не скрывается универсальным Попытка. Классовая метка обязательна; имя, сравнениеРавно, строковый тип и два допустимых значения проверяются.

  7. ОписатьСвоеСвойство показывает настоящее Имя, ВидСравнения, Значение, ЗначениеС и ЗначениеПо. У равенства границы не выдаются за смысл сравнения; у числового условия диагностируются фактические значения интервала без выдуманного правила включения/исключения концов.

  8. КорневыеУзлы обходятся собственным стеком Массив, без рекурсивного роста стека вызовов. Для каждого настоящего УзелДереваРешений используются количество случаев, условие, лучшее и все решения, дочерние узлы. Лист определяется отсутствием детей. Учебные ограничения128 узлов/64 уровня предотвращают неограниченный диагностический обход.

  9. РешениеАнализаДанных содержит число верных случаев, вероятность и отдельный ОбъектАнализаДанных класса. Вероятность выводится как вернула платформа: без неподтвержденного умножения на100. Только Результат.Ошибка прямо объявлена в справке процентами.

  10. Числа узлов и листьев вычисляются независимо обходом и сверяются с результатом. Уровень собственного обхода начинается с0; его нельзя автоматически приравнивать к Глубина по платформе без знания соглашения о нумерации.

  11. СоздатьМодельПрогноза вызывается именно у собственного результата. Реальная МодельПрогнозаДеревоРешений используется: ее КорневыеУзлы также обходятся и сопоставляются с результатом. Это создание и проверка структуры, не уже выполненный прогноз на новых данных.

Как проверить результат

  1. Будущий результат:32 объектов и2 класса, действительные параметры1/4/НеУпрощать, отчет по сгруппированным факт/прогноз и реальным узлам. Сумма весов классификаций32; независимые числа узлов/листьев совпадают с результатом и созданной моделью. Значения глубины, ошибки и вероятностей не подставляются вручную.

  2. Будущий отрицательный контроль данных: в СоздатьСвоиСлучаи заменить число повторений8 на7. Проверка собственного источника должна отклонить28 вместо32 до выполнения алгоритма. Вернуть8 после опыта.

  3. Будущий отрицательный контроль ролей: только в НастроитьСвоиКолонки заменить роль Остаток сВходная наНеИспользуемая. ПроверитьСвоиКолонкиРезультата должен отвергнуть схему до расчета. Эталон проверяющей процедуры не изменять, затем вернуть исходную роль.

  4. Будущий отрицательный контроль результата: только сразу после Результат = Анализатор.Выполнить() присвоить Результат = Неопределено. Проверка точного native-типа должна остановиться до readonly-чтений. Затем вернуть полный исходный код.

  5. runtimeVerifiedScenarios=0: алгоритм, модель, BSL, форма и база1С здесь не запускались. Статические проверки не являются доказательством построенного дерева, качества прогноза или успешного обучения. Описан будущий опыт только собственной пустой базы.

Ожидаемый результат

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

На что обратить внимание

  1. У результатов, классификаций, узлов, решений и описаний свойств нет используемых здесь конструкторов. Они получены из настоящего анализа; readonly-свойствам ничего не присваивается. Не подменять их фиктивными Структура с похожими именами.

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

  3. Количество элементов Классификации не равно автоматически КоличествоОбъектов. У одного элемента может быть несколько случаев; код проверяет сумму именно весов.

  4. Корень может не иметь свойства условия по Остаток; это не разрешение придумать границу. ЗаполнитьЗначенияСвойств без явного списка копирует пересечение имен только в собственную структуру памяти. readonly-объект источника не меняется.

  5. ЗначениеС/ЗначениеПо относятся к описанию интервала; не использовать их как готовое число класса и не угадывать включенность концов. Вероятность решения и процентная Ошибка результата — разные показатели; формат не меняет их математический смысл.

  6. МаксимальнаяГлубина4 — настройка алгоритма, Уровень0 собственного обхода — счетчик программы. Точная структура дерева и соглашение о глубине требуют будущего реального исполнения, не обещаются по статическим тестам.

  7. В этом уроке модель не получает новый ИсточникДанных и не выполняет прогноз. Ее тип и КорневыеУзлы привязаны к реальному созданию/обходу; остальные API модели должны изучаться отдельным полным прогнозным сценарием, а не чужими формальными target-привязками.

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

Получить прогноз для четырех своих новых кодов: входные соответствия, схема выхода и настоящий расчет

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

Где и как запускать

Полный серверный общий модуль УчебныйПрогнозДерева85 собственной пустой базы; все помощники включены, отдельная управляемая форма получает только текст. В 1С не выполнялся.

Подготовка

  1. НОВАЯ отдельная пустая файловая база платформы точно 8.5.1.1343: имя конфигурации УчебныйПрогнозДерева85, совместимость Не использовать, Русский. Без прикладных объектов, расширений, подписок, заданий и рабочих данных; модули конфигурации вручную пустые. Не использовать БП/КА2/УТ/УНФ.

  2. Общие → Общие модули → УчебныйПрогнозДерева85: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Основной блок ниже — весь модуль, включая подготовку собственных таблиц, проверку стенда и разбор решений; никаких отсутствующих помощников подключать не нужно. Будущая ручная подготовка: сохранить и обновить только свою базу F7.

  3. Своя внешняя обработка УчебныеНовыеСлучаи85 → управляемая Форма → команда и кнопка Выполнить с действием Выполнить. Полный отдельный модуль формы приведен ниже. На сервер уходят только вызовы собственного общего модуля; на клиент возвращается текст, а не таблицы, модель или ее колонки.

  4. Обучающая таблица создается в памяти: 32 случая, остатки 0/1/10/11 и две вымышленные метки Нужно/Достаточно по собственному правилу. Код не используется в обучении, Остаток — непрерывный вход, РешениеПоПравилу — дискретный прогноз. Подготовка полностью включена, предыдущий урок запускать не нужно.

  5. Второй объект ТаблицаЗначений содержит четыре новых кода own-predict-1…4 и только Код/ВходнойОстаток. Колонки РешениеПоПравилу и готового ответа в источнике прогноза нет. Числа знакомы обучению: это новый набор объектов для проверки сопоставления, не независимая контрольная выборка качества.

  6. Для опыта не нужны файлы данных, сеть, БСП, рабочие товары, расписание или сохраненные модели. Обучение, соответствия, вывод и временное удаление колонок происходят только в собственных объектах памяти. Код здесь не исполняется в 1С.

Функция ВыполнитьПример() Экспорт
    ПроверитьСвойПустойСтенд();
    Обучение = СоздатьСвоиСлучаи();
    Анализатор = Новый АнализДанных;
    Анализатор.ТипАнализа = Тип("АнализДанныхДеревоРешений");
    Анализатор.ИсточникДанных = Обучение;
    НастроитьСвоиКолонки(Анализатор.НастройкаКолонок);
    НастроитьСвойПараметр(Анализатор.Параметры, "МинимальноеКоличествоСлучаев", 1);
    НастроитьСвойПараметр(Анализатор.Параметры, "МаксимальнаяГлубина", 4);
    НастроитьСвойПараметр(Анализатор.Параметры, "ТипУпрощения", ТипУпрощенияДереваРешений.НеУпрощать);
    РезультатОбучения = Анализатор.Выполнить();
    Если ТипЗнч(РезультатОбучения) <> Тип("РезультатАнализаДанныхДеревоРешений") Тогда
        ВызватьИсключение "Нужен реальный результат обучения на своей таблице";
    КонецЕсли;
    Модель = РезультатОбучения.СоздатьМодельПрогноза();
    Если ТипЗнч(Модель) <> Тип("МодельПрогнозаДеревоРешений") Тогда
        ВызватьИсключение "Не создана настоящая собственная модель";
    КонецЕсли;
    НовыеСлучаи = СоздатьСвоиНовыеСлучаи();
    Модель.ИсточникДанных = НовыеСлучаи;
    Если ТипЗнч(Модель.ИсточникДанных) <> Тип("ТаблицаЗначений") Или Модель.ИсточникДанных.Количество() <> 4 Тогда
        ВызватьИсключение "Источник прогноза должен быть отдельной собственной таблицей из четырех строк";
    КонецЕсли;
    Колонки = Модель.Колонки;
    Если ТипЗнч(Колонки) <> Тип("КолонкиМоделиПрогноза") Или Колонки.Количество() = 0 Тогда
        ВызватьИсключение "Модель не создала реальные описания колонок";
    КонецЕсли;
    Вход = НайтиСвоюКолонку(Колонки, "Остаток", ТипКолонкиМоделиПрогноза.Входная);
    ИсточникОстатка = НайтиСвоюКолонку(Колонки, "ВходнойОстаток", ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных);
    ИсточникКода = НайтиСвоюКолонку(Колонки, "Код", ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных);
    Прогнозируемая = НайтиСвоюКолонку(Колонки, "РешениеПоПравилу", ТипКолонкиМоделиПрогноза.Прогнозируемая);
    Настройки = Модель.НастройкаВходныхКолонок;
    НастроитьСвойВход(Настройки, Вход, ИсточникОстатка);
    Отчет = "СВОЙ ПРОГНОЗ В ПАМЯТИ, НЕ РЕШЕНИЕ О ЗАКУПКЕ" + Символы.ПС;
    Отчет = Отчет + "Обучение: " + Строка(Обучение.Количество()) + "; отдельный вход прогноза: " + Строка(НовыеСлучаи.Количество()) + Символы.ПС;
    Отчет = Отчет + ОписатьСвоиКолонки(Колонки);
    Выход = Модель.КолонкиРезультата;
    Если ТипЗнч(Выход) <> Тип("КолонкиРезультатаМоделиПрогноза") Тогда
        ВызватьИсключение "Нужны настоящие настройки выходной таблицы";
    КонецЕсли;
    Отчет = Отчет + НастроитьСвойВыход(Выход, ИсточникКода, ИсточникОстатка, Прогнозируемая);
    Прогноз = Модель.Выполнить();
    Если ТипЗнч(Прогноз) <> Тип("ТаблицаЗначений") Или Прогноз.Количество() <> НовыеСлучаи.Количество() Тогда
        ВызватьИсключение "Нужна настоящая выходная таблица по четырем новым объектам";
    КонецЕсли;
    Если Прогноз.Колонки.Количество() <> 3 Или Прогноз.Колонки.Найти("УчебныйКод") = Неопределено
        Или Прогноз.Колонки.Найти("УчебныйОстаток") = Неопределено Или Прогноз.Колонки.Найти("УчебныйПрогноз") = Неопределено Тогда
        ВызватьИсключение "Выход не соответствует собственной явной схеме из трех колонок";
    КонецЕсли;
    ВиденныеКоды = Новый Соответствие;
    Для Каждого СтрокаПрогноза Из Прогноз Цикл
        Код = СтрокаПрогноза.УчебныйКод;
        ИсходнаяСтрока = НовыеСлучаи.Найти(Код, "Код");
        Если ТипЗнч(Код) <> Тип("Строка") Или ИсходнаяСтрока = Неопределено Или ВиденныеКоды.Получить(Код) <> Неопределено Тогда
            ВызватьИсключение "Неизвестный или повторный собственный код в результате";
        КонецЕсли;
        Если ТипЗнч(СтрокаПрогноза.УчебныйОстаток) <> Тип("Число") Или СтрокаПрогноза.УчебныйОстаток <> ИсходнаяСтрока.ВходнойОстаток Тогда
            ВызватьИсключение "В результате изменился собственный входной остаток";
        КонецЕсли;
        ВиденныеКоды.Вставить(Код, Истина);
        Отчет = Отчет + Код + "; вход=" + Строка(СтрокаПрогноза.УчебныйОстаток)
            + "; тип прогноза=" + Строка(ТипЗнч(СтрокаПрогноза.УчебныйПрогноз))
            + "; " + ОписатьСвоеРешение(СтрокаПрогноза.УчебныйПрогноз) + Символы.ПС;
    КонецЦикла;
    Если ВиденныеКоды.Количество() <> 4 Или Обучение.Количество() <> 32 Или НовыеСлучаи.Количество() <> 4 Тогда
        ВызватьИсключение "Не сошлись свои ключи или размеры независимых таблиц памяти";
    КонецЕсли;
    Отчет = Отчет + "Четыре новых кода используют знакомые обучению числа; это проверка конвейера, не независимая оценка качества";
    Возврат Отчет;
КонецФункции

Функция СоздатьСвоиНовыеСлучаи()
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
    Таблица.Колонки.Добавить("ВходнойОстаток", Новый ОписаниеТипов("Число"));
    Остатки = Новый Массив;
    Остатки.Добавить(0);
    Остатки.Добавить(1);
    Остатки.Добавить(10);
    Остатки.Добавить(11);
    Номер = 0;
    Для Каждого Остаток Из Остатки Цикл
        Номер = Номер + 1;
        НоваяСтрока = Таблица.Добавить();
        НоваяСтрока.Код = "own-predict-" + Строка(Номер);
        НоваяСтрока.ВходнойОстаток = Остаток;
    КонецЦикла;
    Если Таблица.Количество() <> 4 Или Таблица.Колонки.Количество() <> 2 Тогда
        ВызватьИсключение "Нужны четыре собственных входа без готовых меток";
    КонецЕсли;
    Возврат Таблица;
КонецФункции

Функция НайтиСвоюКолонку(Колонки, Имя, Вид)
    Колонка = Колонки.Найти(Имя, Вид);
    Если Колонка = Неопределено Или ТипЗнч(Колонка) <> Тип("КолонкаМоделиПрогноза") Тогда
        ВызватьИсключение "Нет настоящей колонки модели: " + Имя + "; вид=" + Строка(Вид);
    КонецЕсли;
    Если Колонка.Имя <> Имя Или Колонка.ТипКолонки <> Вид Тогда
        ВызватьИсключение "Найдена колонка с другим именем или ролью";
    КонецЕсли;
    Индекс = Колонки.Индекс(Колонка);
    Если Индекс < 0 Или Индекс >= Колонки.Количество() Тогда
        ВызватьИсключение "Индекс найденной колонки вне реальной коллекции";
    КонецЕсли;
    ПоИндексу = Колонки.Получить(Индекс);
    Если ПоИндексу.Имя <> Имя Тогда
        ВызватьИсключение "По индексу получено другое имя колонки";
    КонецЕсли;
    Возврат Колонка;
КонецФункции

Процедура НастроитьСвойВход(Настройки, Вход, ИсточникОстатка)
    Если ТипЗнч(Настройки) <> Тип("НастройкаВходныхКолонокМоделиПрогноза") Или Настройки.Количество() <> 1 Тогда
        ВызватьИсключение "Нужно одно реальное соответствие для собственного входа Остаток";
    КонецЕсли;
    Настройка = Настройки.Найти("Остаток");
    Если Настройка = Неопределено Или ТипЗнч(Настройка) <> Тип("НастройкаВходнойКолонкиМоделиПрогноза") Тогда
        ВызватьИсключение "Не найдена настройка собственного числового входа";
    КонецЕсли;
    Настройка.КолонкаМоделиПрогноза = Вход;
    Настройка.КолонкаИсточникаДанных = ИсточникОстатка;
    Индекс = Настройки.Индекс(Настройка);
    Если Индекс < 0 Или Индекс >= Настройки.Количество() Тогда
        ВызватьИсключение "Неверный индекс собственного соответствия";
    КонецЕсли;
    ПоИндексу = Настройки.Получить(Индекс);
    ПоИмени = Настройки.Остаток;
    Если ПоИндексу.КолонкаМоделиПрогноза.Имя <> "Остаток" Или ПоИмени.КолонкаМоделиПрогноза.Имя <> "Остаток"
        Или Настройка.КолонкаИсточникаДанных.Имя <> "ВходнойОстаток"
        Или ПоИндексу.КолонкаИсточникаДанных.ТипКолонки <> ТипКолонкиМоделиПрогноза.КолонкаИсточникаДанных Тогда
        ВызватьИсключение "Соответствие Остаток ← ВходнойОстаток не сохранилось";
    КонецЕсли;
КонецПроцедуры

Функция ОписатьСвоиКолонки(Колонки)
    Стек = Новый Массив;
    Для Каждого Колонка Из Колонки Цикл
        Стек.Добавить(Новый Структура("Колонка,Уровень", Колонка, 0));
    КонецЦикла;
    Обработано = 0;
    Отчет = "ДЕЙСТВИТЕЛЬНАЯ ИЕРАРХИЯ КОЛОНОК" + Символы.ПС;
    Пока Стек.Количество() > 0 Цикл
        Индекс = Стек.Количество() - 1;
        Кадр = Стек[Индекс];
        Стек.Удалить(Индекс);
        Если Кадр.Уровень > 16 Или Обработано >= 128 Тогда
            ВызватьИсключение "Своя диагностика превысила учебный предел 128 колонок или 16 уровней";
        КонецЕсли;
        Колонка = Кадр.Колонка;
        Если ТипЗнч(Колонка) <> Тип("КолонкаМоделиПрогноза") Тогда
            ВызватьИсключение "В иерархии нет настоящего описания колонки";
        КонецЕсли;
        Обработано = Обработано + 1;
        Отчет = Отчет + "Уровень=" + Строка(Кадр.Уровень) + "; имя=" + Колонка.Имя
            + "; путь=" + Колонка.ПутьКДанным + "; роль=" + Строка(Колонка.ТипКолонки)
            + "; тип дополнительных параметров=" + Строка(ТипЗнч(Колонка.ДополнительныеПараметры)) + Символы.ПС;
        Дети = Колонка.Колонки;
        Если ТипЗнч(Дети) <> Тип("ФиксированныйМассив") Тогда
            ВызватьИсключение "Вложенные описания должны быть настоящим фиксированным массивом";
        КонецЕсли;
        Для Каждого Дочерняя Из Дети Цикл
            Стек.Добавить(Новый Структура("Колонка,Уровень", Дочерняя, Кадр.Уровень + 1));
        КонецЦикла;
    КонецЦикла;
    Возврат Отчет;
КонецФункции

Функция НастроитьСвойВыход(Выход, ИсточникКода, ИсточникОстатка, Прогнозируемая)
    Выход.Очистить();
    Диагностика = Выход.Добавить(ИсточникКода);
    Диагностика.Имя = "УчебнаяДиагностика";
    Диагностика.Колонка = ИсточникОстатка;
    Решение = Выход.Добавить(Прогнозируемая);
    Решение.Имя = "УчебноеРешение";
    Если Диагностика.Колонка.Имя <> "ВходнойОстаток" Или Диагностика.Имя <> "УчебнаяДиагностика" Тогда
        ВызватьИсключение "Не изменено назначение собственной диагностической колонки";
    КонецЕсли;
    Отчет = "ДИАГНОСТИЧЕСКАЯ СХЕМА ДО УСТАНОВИТЬ" + Символы.ПС + ОписатьСвойВыход(Выход);
    Позиция = Выход.Индекс(Диагностика);
    Если Позиция < 0 Или Позиция >= Выход.Количество() Тогда
        ВызватьИсключение "Не найдена позиция заменяемой собственной колонки";
    КонецЕсли;
    Выход.Установить(Решение, Позиция);
    Отчет = Отчет + "ФАКТИЧЕСКАЯ СХЕМА ПОСЛЕ УСТАНОВИТЬ" + Символы.ПС + ОписатьСвойВыход(Выход);
    Выход.Очистить();
    Если Выход.Количество() <> 0 Тогда
        ВызватьИсключение "Собственные временные настройки не очищены";
    КонецЕсли;
    Остаток = Выход.Добавить(ИсточникОстатка);
    Остаток.Имя = "УчебныйОстаток";
    Прогноз = Выход.Добавить(Прогнозируемая);
    Прогноз.Имя = "УчебныйПрогноз";
    Код = Выход.Вставить(ИсточникКода, 0);
    Код.Имя = "УчебныйКод";
    Если Выход.Количество() <> 3 Или Выход.Индекс(Код) <> 0 Или Выход.Индекс(Прогноз) <> 2 Тогда
        ВызватьИсключение "Не подготовлен свой начальный порядок Код, Остаток, Прогноз";
    КонецЕсли;
    Выход.Сдвинуть(Прогноз, -1);
    Если Выход.Индекс(Прогноз) <> 1 Тогда
        ВызватьИсключение "Собственный прогноз не сдвинут на одну позицию влево";
    КонецЕсли;
    Выход.Удалить(Остаток);
    Если Выход.Количество() <> 2 Или Выход.Индекс(Остаток) <> -1 Тогда
        ВызватьИсключение "Собственная временная колонка остатка не удалена из настроек";
    КонецЕсли;
    Остаток = Выход.Вставить(ИсточникОстатка, 1);
    Остаток.Имя = "УчебныйОстаток";
    Если Выход.Количество() <> 3 Или Выход.Индекс(Код) <> 0 Или Выход.Индекс(Остаток) <> 1 Или Выход.Индекс(Прогноз) <> 2 Тогда
        ВызватьИсключение "Не восстановлен окончательный собственный порядок вывода";
    КонецЕсли;
    Возврат Отчет + "ОКОНЧАТЕЛЬНЫЙ ВЫХОД ДЛЯ РАСЧЕТА" + Символы.ПС + ОписатьСвойВыход(Выход);
КонецФункции

Функция ОписатьСвойВыход(Выход)
    Количество = Выход.Количество();
    Если Количество > 32 Тогда
        ВызватьИсключение "Слишком много колонок для своей небольшой диагностики";
    КонецЕсли;
    Отчет = "Колонок выхода: " + Строка(Количество) + Символы.ПС;
    Для Номер = 0 По Количество - 1 Цикл
        ПоИндексу = Выход.Получить(Номер);
        Отчет = Отчет + "Индекс=" + Строка(Номер) + "; имя=" + ПоИндексу.Имя
            + "; фактический тип Получить=" + Строка(ТипЗнч(ПоИндексу)) + Символы.ПС;
    КонецЦикла;
    Для Каждого Настройка Из Выход Цикл
        Если ТипЗнч(Настройка) <> Тип("КолонкаРезультатаМоделиПрогноза") Тогда
            ВызватьИсключение "Обход должен дать реальные настройки результата модели";
        КонецЕсли;
        Отчет = Отчет + Настройка.Имя + " ← " + Настройка.Колонка.ПутьКДанным + Символы.ПС;
    КонецЦикла;
    Возврат Отчет;
КонецФункции

Функция СоздатьСвоиСлучаи()
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
    Таблица.Колонки.Добавить("Остаток", Новый ОписаниеТипов("Число"));
    Таблица.Колонки.Добавить("РешениеПоПравилу", Новый ОписаниеТипов("Строка"));
    Остатки = Новый Массив;
    Остатки.Добавить(0);
    Остатки.Добавить(1);
    Остатки.Добавить(10);
    Остатки.Добавить(11);
    Для Повтор = 1 По 8 Цикл
        Для Каждого Остаток Из Остатки Цикл
            СтрокаСлучая = Таблица.Добавить();
            СтрокаСлучая.Код = "own-case-" + Строка(Повтор) + "-" + Строка(Остаток);
            СтрокаСлучая.Остаток = Остаток;
            СтрокаСлучая.РешениеПоПравилу = ?(Остаток < 5, "Нужно", "Достаточно");
        КонецЦикла;
    КонецЦикла;
    Если Таблица.Количество() <> 32 Тогда
        ВызватьИсключение "Нужны ровно32 собственных учебных случая";
    КонецЕсли;
    Возврат Таблица;
КонецФункции

Процедура НастроитьСвоиКолонки(Настройки)
    Код = Настройки.Найти("Код");
    Остаток = Настройки.Найти("Остаток");
    КолонкаРешения = Настройки.Найти("РешениеПоПравилу");
    Если Код = Неопределено Или Остаток = Неопределено Или КолонкаРешения = Неопределено Или Настройки.Количество() <> 3 Тогда
        ВызватьИсключение "Анализатор должен создать настройки трех собственных колонок";
    КонецЕсли;
    Код.ТипКолонки = ТипКолонкиАнализаДанныхДеревоРешений.НеИспользуемая;
    Остаток.ТипКолонки = ТипКолонкиАнализаДанныхДеревоРешений.Входная;
    Остаток.ВидДанных = ВидДанныхАнализа.Непрерывные;
    КолонкаРешения.ТипКолонки = ТипКолонкиАнализаДанныхДеревоРешений.Прогнозируемая;
    КолонкаРешения.ВидДанных = ВидДанныхАнализа.Дискретные;
    ПроверитьСвоиКолонкиРезультата(Настройки);
КонецПроцедуры

Процедура ПроверитьСвоиКолонкиРезультата(Настройки)
    Если ТипЗнч(Настройки) <> Тип("КолонкиАнализаДанных") Или Настройки.Количество() <> 3 Тогда
        ВызватьИсключение "Нужны настоящие три настройки колонок анализа";
    КонецЕсли;
    Код = Настройки.Найти("Код");
    Остаток = Настройки.Найти("Остаток");
    КолонкаРешения = Настройки.Найти("РешениеПоПравилу");
    Если Код = Неопределено Или Остаток = Неопределено Или КолонкаРешения = Неопределено Тогда
        ВызватьИсключение "Исчезла собственная колонка";
    КонецЕсли;
    Если Код.ТипКолонки <> ТипКолонкиАнализаДанныхДеревоРешений.НеИспользуемая
        Или Остаток.ТипКолонки <> ТипКолонкиАнализаДанныхДеревоРешений.Входная
        Или Остаток.ВидДанных <> ВидДанныхАнализа.Непрерывные
        Или КолонкаРешения.ТипКолонки <> ТипКолонкиАнализаДанныхДеревоРешений.Прогнозируемая
        Или КолонкаРешения.ВидДанных <> ВидДанныхАнализа.Дискретные Тогда
        ВызватьИсключение "Перепутаны ключ, числовой вход или собственная метка класса";
    КонецЕсли;
КонецПроцедуры

Функция НайтиСвойПараметр(Параметры, Имя)
    Параметр = Параметры.Найти(Имя);
    Если Параметр = Неопределено Или ТипЗнч(Параметр) <> Тип("ПараметрАнализаДанных") Тогда
        ВызватьИсключение "Не найден собственный параметр алгоритма " + Имя;
    КонецЕсли;
    Индекс = Параметры.Индекс(Параметр);
    Если Индекс < 0 Или Индекс >= Параметры.Количество() Тогда
        ВызватьИсключение "Индекс настоящего параметра выходит за границы";
    КонецЕсли;
    ПоИндексу = Параметры.Получить(Индекс);
    Если ПоИндексу.Имя <> Параметр.Имя Или ПоИндексу.Имя <> Имя Тогда
        ВызватьИсключение "Найти и Получить не вернули один собственный параметр";
    КонецЕсли;
    Возврат Параметр;
КонецФункции

Процедура НастроитьСвойПараметр(Параметры, Имя, Значение)
    Параметр = НайтиСвойПараметр(Параметры, Имя);
    Если Не Параметр.ТипЗначения.СодержитТип(ТипЗнч(Значение)) Тогда
        ВызватьИсключение "Тип значения не разрешен реальным параметром " + Имя;
    КонецЕсли;
    Параметр.Значение = Значение;
    ПроверитьСвойПараметр(Параметры, Имя, Значение);
КонецПроцедуры

Процедура ПроверитьСвойПараметр(Параметры, Имя, Эталон)
    Параметр = НайтиСвойПараметр(Параметры, Имя);
    Если ТипЗнч(Параметр.Значение) <> ТипЗнч(Эталон) Или Параметр.Значение <> Эталон Тогда
        ВызватьИсключение "Не совпал собственный параметр результата " + Имя;
    КонецЕсли;
КонецПроцедуры

Функция ОписатьСвоеСвойство(Описание)
    Если ТипЗнч(Описание) <> Тип("СвойствоОбъектаАнализаДанных") Тогда
        ВызватьИсключение "Нужно реальное описание значения или условия собственного анализа";
    КонецЕсли;
    Возврат Описание.Имя + "; сравнение=" + Строка(Описание.ВидСравнения)
        + "; значение=" + Строка(Описание.Значение) + "; с=" + Строка(Описание.ЗначениеС) + "; по=" + Строка(Описание.ЗначениеПо);
КонецФункции

Функция ОписатьСвойКласс(Класс)
    Если ТипЗнч(Класс) <> Тип("ОбъектАнализаДанных") Тогда
        ВызватьИсключение "Нужен реальный объект факта, прогноза или решения";
    КонецЕсли;
    Свойства = Новый Структура("РешениеПоПравилу", Неопределено);
    ЗаполнитьЗначенияСвойств(Свойства, Класс);
    Описание = Свойства.РешениеПоПравилу;
    Если Описание = Неопределено Тогда
        ВызватьИсключение "У собственного класса отсутствует единственная прогнозируемая колонка";
    КонецЕсли;
    Если ТипЗнч(Описание) <> Тип("СвойствоОбъектаАнализаДанных") Или Описание.Имя <> "РешениеПоПравилу"
        Или Описание.ВидСравнения <> ВидСравнения.Равно
        Или ТипЗнч(Описание.Значение) <> Тип("Строка")
        Или (Описание.Значение <> "Нужно" И Описание.Значение <> "Достаточно") Тогда
        ВызватьИсключение "Факт или прогноз не описывает собственную метку класса";
    КонецЕсли;
    Возврат ОписатьСвоеСвойство(Описание);
КонецФункции

Функция ОписатьСвоеРешение(Решение)
    Если ТипЗнч(Решение) <> Тип("РешениеАнализаДанных") Или Решение.КоличествоСлучаев < 0 Тогда
        ВызватьИсключение "Нужно настоящее решение собственного прогноза";
    КонецЕсли;
    Возврат ОписатьСвойКласс(Решение.Решение) + "; правильных случаев=" + Строка(Решение.КоличествоСлучаев)
        + "; вероятность как вернула платформа=" + Строка(Решение.Вероятность);
КонецФункции

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры
УчебныеНовыеСлучаи85.Форма

Собственная внешняя обработка → управляемая Форма → Модуль

Полный клиент-серверный модуль формы; на клиент возвращается только текст собственного серверного расчета.

&НаКлиенте
Процедура Выполнить(Команда)
    Отчет = ВыполнитьНаСервере();
    Сообщить(Отчет);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ВыполнитьНаСервере()
    Возврат УчебныйПрогнозДерева85.ВыполнитьПример();
КонецФункции

Разбор по шагам

  1. Защита проверяет собственную пустую конфигурацию, отсутствие объектов, расширений и активной транзакции. Реальное АнализДанных обучается по встроенным 32 строкам; модель берется только через СоздатьМодельПрогноза настоящего результата.

  2. ИсточникДанных модели назначается отдельной таблице НовыеСлучаи. Колонки модели, настройки входа и настройки результата получают именно из созданной модели. Не создаются поддельные Структура с похожими именами или неизвестный ИсходныйОбъект.

  3. НайтиСвоюКолонку вызывает Найти с двумя обязательными аргументами: именем и ТипКолонкиМоделиПрогноза. Остаток ищется как Входная, Код/ВходнойОстаток как КолонкаИсточникаДанных, РешениеПоПравилу как Прогнозируемая. Имя и роль проверяются; перед Получить проверяется индекс.

  4. Настройка входа содержит два объекта КолонкаМоделиПрогноза. В КолонкаИсточникаДанных нельзя передавать КолонкаТаблицыЗначений. Явная связь Остаток ← ВходнойОстаток показывает, что одинаковые имена таблиц не обязательны. Сохраненная связь перечитывается через Найти, Индекс, Получить и реальное динамическое свойство Остаток.

  5. ОписатьСвоиКолонки обходит настоящую иерархию без рекурсии и показывает Имя, ПутьКДанным, ТипКолонки, вложенные Колонки и тип ДополнительныеПараметры. Ограничения 128 описаний/16 уровней — учебная защита. Не придумывается строковый путь к вложенному значению; выводится фактический.

  6. У дерева верхняя прогнозируемая колонка содержит РешениеАнализаДанных; справка описывает вложенные Прогноз/Значение и Вероятность. Для результата выбирается настоящий верхний объект, найденный по собственному имени поля. Поэтому УчебныйПрогноз разбирается как решение с отдельным объектом класса, а не автоматически как Строка.

  7. КолонкиРезультата — readonly-свойство модели, но сама возвращенная коллекция и ее элементы редактируемы. Диагностическая колонка действительно меняет Колонка с кода на остаток, получает собственное Имя, затем Установить помещает имеющийся дескриптор решения на выбранную позицию. Отчет показывает схему до/после, не выдумывает сохранение числа колонок или поведение дубликатов.

  8. После диагностического опыта Очистить заново готовит окончательную схему. Добавить создает Остаток/Прогноз, Вставить(ИсточникКода, 0) добавляет код спереди. Сдвинуть(Прогноз, -1) меняет порядок; Удалить получает реальный объект настройки Остаток, не индекс. Вставить(ИсточникОстатка, 1) восстанавливает конечный порядок Код, Остаток, Прогноз; индексы и количество проверяются.

  9. У двух Получить установленная справка противоречива: КолонкиМоделиПрогноза объявляет КолонкаАнализаДанных, а КолонкиРезультатаМоделиПрогноза — КолонкаРезультатаЗапроса, хотя коллекции описывают другие элементы. Код использует у их возвратов только общее Имя и выводит фактический тип, не подменяет native-текст и не выдает гипотезу за runtime-проверку.

  10. Модель.Выполнить действительно присутствует после настройки и возвращает ТаблицаЗначений. Проверяются четыре строки, три собственных имени колонок, уникальные известные коды и сохранение входного остатка. Сопоставление с источником идет по коду, а не по предполагаемому порядку строк.

  11. Каждый полученный прогноз проверяется как РешениеАнализаДанных. Его вероятность, количество случаев и класс берутся из результата, не подставляются вручную. Динамическая метка класса проверяется через СвойствоОбъектаАнализаДанных; вывод не обещает точность 100% или конкретное числовое значение вероятности.

Как проверить результат

  1. Будущий положительный опыт в своей базе: один полный запуск должен создать 32 обучающих и четыре прогнозных объекта, показать связь разных имен входных колонок, действительную иерархию, три состояния схемы выхода и четыре результата с собственными кодами. Окончательная таблица содержит УчебныйКод, УчебныйОстаток, УчебныйПрогноз.

  2. Будущий отрицательный контроль имени: только в поиске источника остатка заменить ВходнойОстаток на ЧужоеПоле. НайтиСвоюКолонку должен остановиться до настройки/прогноза. Вернуть исходное имя после опыта.

  3. Будущий отрицательный контроль роли: только у поиска Остаток заменить Входная на Прогнозируемая. Колонка не должна приниматься как правильный вход; проверка должна остановиться до Модель.Выполнить. Затем вернуть исходную роль.

  4. Будущий отрицательный контроль схемы: удалить только последнюю Вставить(ИсточникОстатка, 1) и присваивание имени после нее. Проверка трех окончательных колонок должна остановиться до расчета. Вернуть полный код; проверяющую процедуру не ослаблять.

  5. Будущий отрицательный контроль результата: сразу после Прогноз = Модель.Выполнить() временно присвоить Прогноз = Неопределено. Типовая проверка должна остановиться до чтения строк/колонок. Затем вернуть код.

  6. runtimeVerifiedScenarios=0: BSL, обучение, модель, Установить, форма и база здесь не запускались. Статические тесты подтверждают текстовые контракты, привязки и наличие защит, а не фактические прогнозы. Будущие ручные проверки выполняются только на собственном отдельном стенде.

Ожидаемый результат

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

На что обратить внимание

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

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

  3. Имя результата и ПутьКДанным модели — разные значения. УчебныйПрогноз — собственное имя выходной колонки, РешениеПоПравилу — имя обучающего поля; вложенный native-путь не придумывается конкатенацией.

  4. ДополнительныеПараметры зависят от алгоритма и могут быть Неопределено. Никакие параметры кластеризации не создаются и не присваиваются дереву ради демонстрации свойства.

  5. Объект решения не равен строковой метке, вероятность решения не тождественна процентной ошибке обучения. Вероятность выводится без неподтвержденного умножения на 100 и без обещания точного диапазона.

  6. Получить использует только общий member Имя из реально описанных native-типов; прямое чтение других полей его результата не выводится из противоречивой справки. Для остальных операций используются настоящие объекты Найти, Добавить, Вставить или обхода коллекции.

  7. Очистить и Удалить затрагивают только выходные настройки собственного объекта модели в памяти, не строки базы и не пользовательские файлы. Нет Записать, транзакций, запросов к рабочей конфигурации или внешних действий.

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

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.