Перейти к содержимому

Задачи с несколькими навыками

Реальная задача из учебника редко проверяет один микро-навык. Например:

2(x3)=102(x − 3) = 10

требует одновременно:

  • linear_eq.expand_brackets (раскрытие скобок),
  • arith.signs (умножение на отрицательное число),
  • linear_eq.move_to_one_side (перенос через равно),
  • linear_eq.divide_by_coefficient (деление на коэффициент).

Если у Ивана один из этих навыков на нуле — задача проваливается, даже если остальные на 0.95.

Как объединить P(solve)P(\text{solve}) по нескольким навыкам

Заголовок раздела «Как объединить P(solve)P(\text{solve})P(solve) по нескольким навыкам»

У нас есть P(solvei)P(\text{solve}_i) для каждого навыка ii. Как получить общую P(solvejoint)P(\text{solve}_{\text{joint}}) — для всей задачи?

PAM=1ni=1nP(solvei)P_{\text{AM}} = \frac{1}{n} \sum_{i=1}^{n} P(\text{solve}_i)

Возьмём задачу с 3 навыками: P1=0.95P_1 = 0.95, P2=0.95P_2 = 0.95, P3=0.20P_3 = 0.20.

PAM=0.95+0.95+0.203=0.70P_{\text{AM}} = \frac{0.95 + 0.95 + 0.20}{3} = 0.70

Получилось 0.70 — выглядит отлично. Селектор скажет: «эта задача в самой ZPD, дай её Ивану». Но в реальности Иван не справится: он гарантированно споткнётся на навыке 3, в котором у него только 0.20.

Арифметическое среднее скрывает слабое звено. Это плохо.

Вариант B: геометрическое среднее (правильно)

Заголовок раздела «Вариант B: геометрическое среднее (правильно)»
PGM=exp(1ni=1nlogP(solvei))=i=1nP(solvei)nP_{\text{GM}} = \exp\left(\frac{1}{n} \sum_{i=1}^{n} \log P(\text{solve}_i)\right) = \sqrt[n]{\prod_{i=1}^{n} P(\text{solve}_i)}

На том же примере:

PGM=0.950.950.203=0.180530.565P_{\text{GM}} = \sqrt[3]{0.95 \cdot 0.95 \cdot 0.20} = \sqrt[3]{0.1805} \approx 0.565

GM = 0.565 — гораздо ниже AM. Селектор увидит, что задача далеко не в ZPD (closeness 0.5650.7|0.565 - 0.7| всё-таки немалая), и возможно выберет что-то получше.

Если хоть один из множителей маленький, всё произведение маленькое. Геометрическое среднее наследует это свойство. Это аналог «слабого звена цепи» — задача проваливается, если хоть один навык подведёт.

P1P_1P2P_2P3P_3AMGM
0.50.50.50.5000.500
0.70.70.70.7000.700
0.90.90.30.7000.624
0.950.950.20.7000.503
0.990.990.10.6930.461
0.50.50.050.3500.171

Чем больше разрыв между сильным и слабым навыком, тем сильнее GM ниже AM. Это и есть то, что нам нужно.

Двигай ползунки трёх P(solve)P(\text{solve}) и сравнивай три способа агрегации рядом. Особенно интересно: подвинь P₁=P₂=0.95, а P₃ — от 0.05 до 1.0. Заметишь, как GM «ловит» слабое звено, а AM его прячет.

Задача с тремя микро-навыками. Подвигайте ползунки и смотрите, как ведут себя разные способы агрегации.
Arith. mean
0.700
Geom. mean (мы)
0.565
min
0.200

Когда хоть одно P низкое — GM падает резко, AM — нет. min — слишком жёстко. GM — компромисс «слабого звена», который нам нужен.

В коде web/lib/bkt.ts мы считаем GM через сумму логарифмов для численной стабильности (произведения маленьких чисел могут получить underflow):

const perSkillPL: Record<MicroSkillId, number> = {};
let logSum = 0;
for (const skillId of task.microskills) {
const pL = state.mastery[skillId] ?? params.pInit;
perSkillPL[skillId] = pL;
logSum += Math.log(Math.max(1e-6, pSolve(pL, params)));
}
const pSolveJoint = Math.exp(logSum / task.microskills.length);

Тонкость: Math.max(1e-6, ...) защищает от log(0)=\log(0) = -\infty. На практике P(solve)P(\text{solve}) никогда не должно быть строго 0 (благодаря P(G)>0P(G) > 0), но защита бесплатна.

МетодИдеяПочему не взяли
Минимум minPi\min P_i«Задача провалится на самом слабом навыке»Слишком жёстко; сильные навыки немного компенсируют слабые в реальности
Произведение Pi\prod P_iКаждый навык — независимое событиеРовно то же, что nn-я степень GM; для разных nn задачи нельзя сравнивать
Гармоническое среднееТоже подавляет слабое звеноСложнее объяснить, такая же по эффекту как GM
Многомерная логистикаРегрессия по навыкамНужны параметры на пары навыков — для разметки нужно много данных

GM — это простой, интерпретируемый и математически обоснованный компромисс.

Чем больше навыков, тем сильнее «штраф за разнобой». Это OK для начальной школы, но для длинных задач (10+ навыков) GM становится слишком пессимистичным.

В нашем плане для хака мы намеренно ограничиваем задачи 2-4 микро-навыками. Если задача требует 7+ — это значит её надо разбить на отдельные шаги (по одному микро-навыку) или это просто слишком большая задача для адаптивной модели.

«Мы используем геометрическое среднее по микро-навыкам — это означает, что задача проваливается, если хоть один навык подведёт. Это лучше отражает реальность, чем простое усреднение, и формально мотивировано: PGMP_{\text{GM}} соответствует независимым событиям провала.»