Меня зовут Кирилл, я работаю BIM‑менеджером, писал эту статью совместно со своей коллегой Анастасией @nobimnolife. Помучавшись с разработкой ЦИМ без какой‑либо автоматизации, вместе мы подготовили плагин IDS Core. В этой статье – способы подбора кода без ИИ, метод Левенштейна и сила общего труда.

С 2026 года архитектурно-градостроительное решение в Москве сдаётся вместе с цифровой информационной моделью в IFC. У каждого помещения в ней должны быть заполнены два свойства: RUS_MSSK_SpaceAndZone_Code и RUS_MSSK_SpaceAndZone_Name — код и наименование по Московской строительной системе классификаторов (МССК), раздел «Помещения и зоны». В жилом доме это сотни помещений, и называются они в модели так, как привыкла мастерская: «С/у», «Кладовка», «ПУИ/Мусороудаление (К1)», «Элетрощитовая жилой части». Классификатор таких имён не знает, а проверяющие на вопрос «а если нужного нет?» отвечают честно: берите близкое по смыслу.

Мы решили, что «близкое по смыслу» можно хотя бы частично посчитать. Ниже — как устроен классификатор, на чём ломается наивный поиск похожих строк, где пригодился Левенштейн и почему точность упирается не в алгоритм, а в людей.

Классификатор: 638 строк и одна, которой нет

МССК распространяется в свободном доступе, нужный раздел — «Помещения и зоны». Это 638 кодов с иерархией по уровням:

ПЗ 30          Помещения квартир

ПЗ 30 10         Жилые помещения

ПЗ 30 10 03        Жилая комната

ПЗ 30 20         Вспомогательные помещения

ПЗ 30 20 13        Совмещенный санузел

ПЗ 31          Общественная зона

ПЗ 31 10 19        Санузел

 

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

И ещё один вывод, который стоит знать всем, кто сдаёт модели: в файлах IDS, по которым проверяют ЦИМ, для элементов перечислены все допустимые коды, а для помещений проверяется только, что код заполнен. Неправильный код автоматическая проверка не поймает — его увидит человек. Значит, подбирать нужно аккуратно, а не «хоть что-нибудь».

Почему не нейросеть

Первая мысль — отдать имена языковой модели. Мы её отложили по трём причинам. Плагин работает в Revit, часто на машинах без свободного доступа в интернет. Нужна воспроизводимость: одно и то же имя сегодня и завтра должно давать один и тот же код. И главное — при сомнении человек должен видеть, почему предложен именно этот код, а не «так решила модель». Поэтому сначала сделали детерминированный подбор, а нейросеть оставили на потом — для того, что не найдётся.

Путь одного имени

Путь одного имени через подбор
Путь одного имени через подбор

Подбор идёт по шагам, первое точное совпадение его останавливает.

Нормализация. Регистр, «ё», номера («Спальня 2», «Пом. 1.05», «(К1)»), знаки. Сокращения раскрываются словарём: «С/у», «Сан. узел» → санузел, «ЭЩ», «Эл.щитовая» → электрощитовая, «м/м» → машиноместо, «Тех.» → техническое. Служебные слова — «помещение», «комната», «для» — в ключ сравнения не входят, иначе «Спальная комната» и «Спальня» оказываются разными помещениями.

Словарь синонимов. Слоями: типовые имена жилья, примеры заполнения реальных проектов, свой файл пользователя. О нём ниже.

Точное наименование МССК — только если оно однозначно. «Кладовая» в МССК есть и как «ПЗ 31 10 04 Кладовая», и как часть «Кладовая тары», «Кладовая овощей» — точным совпадением считается только первое.

Главная функция. «ИТП, Насосная и Водомерный узел» — одно помещение с тремя функциями. Код в таких случаях ставят по первой, поэтому всё после /, ,, ; отбрасывается.

Похожие имена — если ничего точного не нашлось.

Левенштейн, и где он врёт

Для похожих имён первым делом берётся расстояние Левенштейна — минимальное число вставок, удалений и замен букв, чтобы превратить одно слово в другое. Считается классическим динамическим программированием по таблице (|a|+1) × (|b|+1):

d[i][j] = min( d[i-1][j] + 1,                    // удалить

               d[i][j-1] + 1,                    // вставить

               d[i-1][j-1] + (a[i] == b[j] ? 0 : 1) )   // заменить

 

Хранить всю таблицу не нужно — хватает двух строк. Сходство — 1 − d / max(|a|, |b|).

Опечатка и морфология: где Левенштейн работает, а где нет
Опечатка и морфология: где Левенштейн работает, а где нет

На опечатках это работает отлично: «элетрощитовая» и «электрощитовая» отличаются одной вставкой, сходство 0,93. А на русской морфологии — плохо. «Раздевалка» в модели и «Раздевальная» в классификаторе — одно и то же помещение, но для Левенштейна это три правки из двенадцати букв, 0,75, на грани «не похоже».

Тащить полноценный морфологический анализатор в плагин ради имён помещений не хотелось, поэтому правило получилось грубым, но рабочим: если у слов общее начало от четырёх букв и обрывается оно не раньше чем за две буквы до конца короткого слова — сходство 0,9. «Раздевал-ка» и «раздевал-ьная», «спальн-я» и «спальн-ая» проходят, «кладовая» и «кладбище» — нет.

Слова против букв

Сравнивать имена целиком тоже не получается: порядок слов («Комната жилая»), лишние уточнения, слитное написание. Поэтому итоговая оценка складывается из двух частей:

• 0,7 — сходство по словам. Каждое слово ищет самое похожее на другой стороне.

• 0,3 — триграммы, коэффициент Дайса по тройкам букв. Ловят то, что ломает слова: «венткамера» и «вент. камера», «техпространство».

Первая версия считала сходство по словам симметрично и споткнулась на самом частом случае. «Элетрощитовая жилой части» против «Электрощитовая»: слово «электрощитовая» в имени нашлось, а «жилой» и «части» пары не имеют — и оценка проваливается ниже порога. Лишние уточнения в именах помещений — норма, а не исключение. Поэтому сейчас важнее, чтобы в имени нашлись все слова наименования МССК (55 % оценки), чем чтобы каждое слово имени нашло себе пару (45 %). А первое слово имени весит вдвое: «Кладовая продуктов» — это кладовая, а не продукты.

Пороги такие: от 88 % код отмечается сам, но строка подсвечивается жёлтым; от 62 % предлагается без отметки; ниже — «не найдено» и список ближайших. Отдельное правило: если два разных кода идут почти вровень (разница меньше 4 %), галочку не ставим никогда.

Данные: 506 имён и первые 47 %

Без данных все эти веса — гадание. Нам повезло: коллеги дали таблицы заполнения реальных проектов — «имя помещения → код МССК», шесть таблиц, 519 пар, 506 уникальных имён. Там много неожиданного: «Лапомойка», «Бьюти пространство», «КНС».

Как росла точность
Как росла точность

Первый прогон — только классификатор и поиск похожих — дал 47 % верных кодов. Разбор ошибок оказался полезнее любых формул.

Латинская C. «C/У» во многих моделях набрано латиницей, и нормализация превращала его в пустую строку. Теперь латинские буквы, похожие на кириллические, заменяются в словах, где есть кириллица, и в коротких словах вроде «C».

Скобки — не мусор. Сначала мы отбрасывали пояснения в скобках вместе со вторичными функциями. Это сломало «Кладовая (Сухие продукты)» и «Помещение персонала (Гардероб)»: в скобках оказалось уточнение типа, а номера вида «(К1)» и так уходят на нормализации. Отбрасывать стали только то, что после /, ,, ;.

«Ж» и «М». «Раздевалка Ж» — женская. Но «Спортзал 20х40 м» — метры, поэтому одиночная «м» сразу после числа не раскрывается.

С этим получилось 54 %. Дальше — словарь.

Честная проверка

Самое простое — положить пары из таблиц в словарь и проверить на них же. Получится 96 %, и это ничего не значит: на новом проекте таких имён не будет. Поэтому проверяли перекрёстно — словарь строится без одной таблицы, проверка идёт на ней, и так по очереди.

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

Перекрёстно словарь поднял точность до 65 %. И уронил то, что важнее: из автоматически отмеченных верными оказалось 86 % вместо 90 %. Автоматика стала чаще ошибаться уверенно.

Проекты не согласны друг с другом

Причина — не алгоритм. Одиннадцать имён в разных проектах получили разные коды:

• С/у — ПЗ 30 20 13 (квартира) и ПЗ 31 10 19 (МОП)

• Гардероб — ПЗ 30 20 04 и ПЗ 31 08 03

• Помещение СС — ПЗ 31 09 02, ПЗ 31 13 12, ПЗ 31 13 14 и ПЗ 31 13 21

• ПОН — ПЗ 31 09 01 и ПЗ 31 13 11

• Помещение отдыха — ПЗ 12 и ПЗ 31 12 05

• Обеденный зал — ПЗ 31 14 01 и ПЗ 31 14 02

Часть расхождений законна: санузел в квартире и санузел в местах общего пользования — действительно разные коды. Такие записи мы развели по области. Часть решается большинством. А для остальных — «Помещения СС» с четырьмя кодами в четырёх проектах — правильного ответа у нас нет, и делать вид, что он есть, хуже, чем промолчать. Такие имена помечены как неоднозначные: варианты из проектов попадают в список похожих, но сами не ставятся.

Это вернуло точность автоматики к 91 %, а общую — подняло до 67 %.

Квартира или МОП

Разведение по области работает, только если область известна. В ЦИМ её задаёт RUS_Group_Type: «Квартира» — помещение квартиры, другое значение — нет. С заполненной областью точность выросла до 69 %, автоматики — до 92 %.

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

Общий словарь без утечек

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

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

Что в итоге

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

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

Выводы, которые не зависят от инструмента:

• Левенштейн хорош для опечаток и плох для морфологии; для русских слов без простого правила общей основы он отбрасывает очевидные пары.

• Проверка на тех же данных, на которых строили словарь, бесполезна, а копии таблиц между проектами незаметно её завышают.

• Потолок точности здесь задают не формулы, а разногласия в самих данных. Модель, которая «уверенно» выбирает одно из четырёх мнений, вредна — честнее показать все четыре.

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

Комментарии (0)