Первый коммит: модульный монолит ядра (.NET 10) и gRPC-сервисы ai/ml/telegram, фронтенд Vue 3/Vite/Tailwind, документация (ТЗ, инструкция пользователя, техдокументация, код-стайл), бэклог, скрипты развёртывания и архив прототипа LeadRadar.
155 lines
6.1 KiB
C#
155 lines
6.1 KiB
C#
namespace Deal.Ml.Model;
|
||
|
||
/// <summary>
|
||
/// Пороги и константы наивно-байесовской модели по терминам (Ruling 4; 1:1
|
||
/// mlservice/model.py L20–31, L42–55, L178–181). Именованные константы вместо магических
|
||
/// чисел (код-стайл этапа); значения НЕ входят в .proto-контракт (README src/contracts L164–166).
|
||
/// </summary>
|
||
public static class ModelConstants
|
||
{
|
||
/// <summary>
|
||
/// Суммарно примеров по всем классам, чтобы модель «включилась» (MIN_TOTAL).
|
||
/// </summary>
|
||
public const double MinTotalExamples = 20.0;
|
||
|
||
/// <summary>
|
||
/// Минимум примеров у класса-победителя (не-спам; MIN_WINNER).
|
||
/// </summary>
|
||
public const double MinWinnerExamples = 6.0;
|
||
|
||
/// <summary>
|
||
/// Минимум примеров у класса-победителя «spam» (MIN_WINNER_SPAM).
|
||
/// </summary>
|
||
public const double MinWinnerSpamExamples = 4.0;
|
||
|
||
/// <summary>
|
||
/// Минимум различных терминов, встреченных у победителя (MIN_HITS).
|
||
/// </summary>
|
||
public const int MinHits = 2;
|
||
|
||
/// <summary>
|
||
/// Минимум примеров класса типа t:*, чтобы ML выдавал тип (MIN_TYPE_WINNER).
|
||
/// </summary>
|
||
public const double MinTypeWinnerExamples = 4.0;
|
||
|
||
/// <summary>
|
||
/// Метка класса «спам» (специальная роль — порог 4 и «корзина» карточки).
|
||
/// </summary>
|
||
public const string SpamLabel = "spam";
|
||
|
||
/// <summary>
|
||
/// Префикс внутренних классов типа заявки (t:hire/t:order отсекаются из колонок).
|
||
/// </summary>
|
||
public const string TypeLabelPrefix = "t:";
|
||
|
||
/// <summary>
|
||
/// Внутренний класс типа заявки «найм» (в UI — hire).
|
||
/// </summary>
|
||
public const string TypeClassHire = "t:hire";
|
||
|
||
/// <summary>
|
||
/// Внутренний класс типа заявки «разовая сделка» (в UI — order).
|
||
/// </summary>
|
||
public const string TypeClassOrder = "t:order";
|
||
|
||
/// <summary>
|
||
/// Множитель prior при ранжировании классов: score + 3·prior (predict L226–256).
|
||
/// </summary>
|
||
public const double PriorWeight = 3.0;
|
||
|
||
/// <summary>
|
||
/// ln-отрыв от второго класса на старте (MARGIN; адаптив 0.35/0.5/0.7 — см. ниже).
|
||
/// </summary>
|
||
public const double InitialMargin = 0.9;
|
||
|
||
/// <summary>
|
||
/// Суммарно примеров, после которых порог отрыва — 0.7.
|
||
/// </summary>
|
||
public const double TotalExamplesForMargin0_7 = 60.0;
|
||
|
||
/// <summary>
|
||
/// Суммарно примеров, после которых порог отрыва — 0.5.
|
||
/// </summary>
|
||
public const double TotalExamplesForMargin0_5 = 150.0;
|
||
|
||
/// <summary>
|
||
/// Суммарно примеров, после которых порог отрыва — 0.35.
|
||
/// </summary>
|
||
public const double TotalExamplesForMargin0_35 = 400.0;
|
||
|
||
/// <summary>
|
||
/// Адаптивный отрыв после 60 примеров.
|
||
/// </summary>
|
||
public const double MarginAfter60Examples = 0.7;
|
||
|
||
/// <summary>
|
||
/// Адаптивный отрыв после 150 примеров.
|
||
/// </summary>
|
||
public const double MarginAfter150Examples = 0.5;
|
||
|
||
/// <summary>
|
||
/// Адаптивный отрыв после 400 примеров.
|
||
/// </summary>
|
||
public const double MarginAfter400Examples = 0.35;
|
||
|
||
/// <summary>
|
||
/// Окно самооценки, которое отдаётся в /status (EVAL_WINDOW).
|
||
/// </summary>
|
||
public const int EvalWindowSize = 50;
|
||
|
||
/// <summary>
|
||
/// Сколько последних решений самооценки хранится в БД модели (EVAL_KEEP).
|
||
/// </summary>
|
||
public const int EvalKeepCount = 200;
|
||
|
||
/// <summary>
|
||
/// Сколько лучших весов классов отдаётся в predict (scores ≤ 5).
|
||
/// </summary>
|
||
public const int MaxScoresInReply = 5;
|
||
|
||
/// <summary>
|
||
/// Сколько узнанных терминов отдаётся в predict (terms ≤ 8).
|
||
/// </summary>
|
||
public const int MaxMatchedTerms = 8;
|
||
|
||
/// <summary>
|
||
/// Точность округления весов в scores (python round(…, 3)).
|
||
/// </summary>
|
||
public const int ScoresPrecision = 3;
|
||
|
||
/// <summary>
|
||
/// Точность округления весов классов в status (python round(…, 2)).
|
||
/// </summary>
|
||
public const int ClassesPrecision = 2;
|
||
|
||
/// <summary>
|
||
/// Точность округления отступа margin (python round(…, 2)).
|
||
/// </summary>
|
||
public const int MarginPrecision = 2;
|
||
|
||
/// <summary>
|
||
/// Точность округления доли верных в eval (python round(…, 3)).
|
||
/// </summary>
|
||
public const int AccuracyPrecision = 3;
|
||
|
||
/// <summary>
|
||
/// Минимальная длина токена, попадающего в модель (L83–86).
|
||
/// </summary>
|
||
public const int MinTokenLength = 3;
|
||
|
||
/// <summary>
|
||
/// Длина токена, при которой добавляется «хвостовой» префикс-термин.
|
||
/// </summary>
|
||
public const int MinTokenLengthForPrefix = 6;
|
||
|
||
/// <summary>
|
||
/// Длина префикса хвостового токена (w[:4]).
|
||
/// </summary>
|
||
public const int PrefixLength = 4;
|
||
|
||
/// <summary>
|
||
/// Префикс хвостового токена («~pyth» для «python») — не участвует в terms-подсказках.
|
||
/// </summary>
|
||
public const string TokenPrefixMarker = "~";
|
||
}
|