Liigu sisu juurde

Valija töös

flowchart TD
S["Õpilase olek · P(L) vektor"] --> Loop["Iga ülesanne kogumis"]
Loop --> P["Ühine P(solve) geomeetriline keskmine oskuste kaupa"]
P --> C["Lähedus sihtmärgile — Gaussi tuum ümber 0.7"]
P --> R["Haruldus oskuste osakaal, kus P(L) alla 0.4"]
C --> Score["punkt = lähedus + 0.15 * haruldus"]
R --> Score
Score --> Sort[Sorteeri punkti järgi kahanevalt]
Sort --> Recent[Välista viimase 5 katse ülesanded]
Recent --> TopN[Top-N soovitused]

Need on liikuvad osad. Ei mingeid närvivõrke, gradiente ega treeningahelat – lihtsalt kaalutud paremusjärjestus.

state = {
student_id: "S-12",
mastery: {
"linear_eq.expand_brackets": 0.166, // dropped after errors
"arith.signs": 0.831, // strong
"arith.distributive_law": 0.45,
"linear_eq.move_to_one_side": 0.62,
"linear_eq.divide_by_coefficient": 0.78,
// ...
},
history: [/* recent answers */]
}

2. Hinda iga ülesande sobivust

Jaotis «2. Hinda iga ülesande sobivust»

Ülesanne “T-147” oskustega “[laienda_sulgud, märgid]”:

  • P(solve1)=0.1660.9+0.8340.2=0.317P(\text{solve}_1) = 0.166 \cdot 0.9 + 0.834 \cdot 0.2 = 0.317
  • P(solve2)=0.8310.9+0.1690.2=0.782P(\text{solve}_2) = 0.831 \cdot 0.9 + 0.169 \cdot 0.2 = 0.782
  • Pjoint=0.3170.7820.498P_{\text{joint}} = \sqrt{0.317 \cdot 0.782} \approx 0.498

Lähedus: closeness=exp((0.4980.7)20.03)0.260\text{closeness} = \exp\left(-\frac{(0.498 - 0.7)^2}{0.03}\right) \approx 0.260

Haruldus (1 kahest oskusest alla 0,4): rarity=0.5\text{rarity} = 0.5

Tulemus: score=0.260+0.150.5=0.335\text{score} = 0.260 + 0.15 \cdot 0.5 = 0.335

3. Top-N pärast sorteerimist

Jaotis «3. Top-N pärast sorteerimist»

Valija skannib kogumit, hindab iga ülesande, sorteerib kahanevalt, langetab viimase viie katsega nähtud ülesanded (väldi kordusi), tagastab parima 5.

export function recommend(
state: StudentState,
pool: Task[],
topN = 5,
opts?: SelectorOptions,
params?: BktParams
): ScoredTask[] {
const recentIds = new Set(
state.history.slice(-5).map((h) => h.task_id)
);
const scored = pool
.filter((t) => !recentIds.has(t.id))
.map((t) => scoreTaskForStudent(state, t, opts, params));
scored.sort((a, b) => b.score - a.score);
return scored.slice(0, topN);
}

Kui iga ülesanne sobib halvasti

Jaotis «Kui iga ülesanne sobib halvasti»

Oletame, et Ivani P(L)P(L) sulgude jaoks on 0,166 ja kogumis puuduvad „sulgud + õrn aritmeetika” – kõik ühendab raskemad oskused. Mis siis?

Valija tagastab endiselt valiku kõige vähem halb, kuid parim valik näitab madalat “lähedust”. See on signaal:

  • õpetajale: “esemepank ei kata tegelikke klassivahesid”;
  • Andrile (sisujuht): “selle oskuse jaoks on vaja lihtsamaid harjutusi.”

Õpetaja kasutajaliides võib esile tuua „nõrga soovituse“, kui lähedus < 0,3 – osa selgitatavusest.

Pausid ja haruldaste oskuste boonus

Jaotis «Pausid ja haruldaste oskuste boonus»

Kui lähedus seob, eelistab “rareSkillBonus” nõrku oskusi treenivaid ülesandeid. Miks see on oluline:

  • ilma boonuseta võib valija mugavustsooni seiskuda;
  • koos lisatasuga uurib parandamise nõrkusi.

“rareSkillBonus = 0,15” saldod:

  • liiga väike (0,05): ei suru kunagi nõrkadele oskustele — stagnatsioon;
  • liiga suur (0,5): alati jõhker raskus – frustratsioon.

0,15 ütleb umbkaudselt: “Kui lähedus seob, eelistage ülesandeid, milles segatakse üks nõrk oskus kahe hulgas.”

Kui valija tundub vale

Jaotis «Kui valija tundub vale»

Kummaliste toppide suitsutestimisel taanduvad põhjused tavaliselt järgmistele:

  1. Meisterlik vektor on initsialiseerimata – puuduva oskuse vaikeväärtus on „params.pInit = 0,2”. Sobib külmkäivitamiseks.
  2. Stale history — kahenädalane vahe; meisterlikkus peaks lagunema. MVP ulatusest väljas.
  3. Taksonoomia tasakaalustamatus — Andri märkis oskuse A 80% asjadest, oskuse B 5%; valija kaldub A-sse. Parandage sildistamispoliitika kaudu.

Vt selgitatavus – põhjuste esiletoomine lihtsustab silumist ja teenib õpetajate usaldust.