Liigu sisu juurde

Pipelini ülevaade — vastusest soovituseni

See leht on kompaktne „linnulennult“ ülevaade kõigest, mida mudel teeb: mis sisendid tulevad, millised 4 numbrit on iga mikrooskuse kohta, kuidas üks õpilase vastus uuendab oskuse hinnangut ja kuidas valime talle järgmise ülesande. Sobib kas õpiku sisenemispunktiks või spikriks meeskonna vestlusele.

0. Mida lühendid tähendavad

Jaotis «0. Mida lühendid tähendavad»

Kõik allpool kasutatavad terminid on lühendid või laenatud inglise keelest. Et neid iga kord ei peaks pähe ajama, siin on dekooder:

LühendInglise täiskujuEesti keeles
BKTBayesian Knowledge TracingBayesi teadmiste jälgimine
EMExpectation–Maximization„ootus–maksimeerimine“ algoritm
HMMHidden Markov Modelpeidetud Markovi mudel
ZPDZone of Proximal Developmentproksimaalse arengu tsoon (Võgotski)
P(L)Probability(Learned)tõenäosus, et õpilane oskab oskust
P(L₀) / pInitprior P(Learned), t=0t=0algne P(L) enne esimest katset
pTprobability of Transittõenäosus õppida ühe katsega
pSprobability of Sliptõenäosus eksida, oskates (slip = „libastumine“)
pGprobability of Guesstõenäosus arvata õigesti, mitte teades
P(solve)Probability(Solve)tõenäosus ülesannet õigesti lahendada
closeness(sõna-sõnalt „lähedus“)kui lähedal P(solve) on target ≈ 0.7-le
mastery(sõna-sõnalt „valdamine“)õpilase numbriline P(L) kõigi oskuste lõikes
microskillmicro-skillaatomoskus; selle kohta on üks P(L)
prereqprerequisiteoskuse eelkäija sõltuvuste graafis
rarity bonusbonus for rare skillsboonus „alatreenitud“ oskustele ülesandes
Baum–Welch(autorite nimed)EM-i konkreetne variant HMM-i jaoks

Edasi tekstis kasutatakse lühivorme — naasta siia tabelisse esimesel kohtumisel iga „pS“ või „pT“-ga.

🔧 Offline — kord N nädala järel

Jaotis «🔧 Offline — kord N nädala järel»
flowchart LR
classDef off fill:#fde68a,stroke:#a16207,color:#0f172a
A1[Logi]:::off --> A2[EM]:::off --> A3[Parameetrid]:::off
SammMis see on ja milleks
LogiKõikide õpilaste kõik vastused kogu aja jooksul — (õpilane, ülesanne, õige/vale, aeg). Kümneid tuhandeid ridu DB-s. See on offline-etapi sisend.
EMMasinõppe algoritm, mis vaatab logi ja valib 4 BKT numbrit iga mikrooskuse kohta nii, et need numbrid kõige paremini selgitaksid, kuidas õpilased reaalselt vastasid. Käivitub üks kord enne platvormi avamist (edasi kord N nädala järel), mitte õpilase sessiooni ajal. Erialakeeles konkreetset EM-i varianti, mida BKT-le rakendatakse, kutsutakse Baum–Welch-iks — see on EM-i erijuht peidetud Markovi ahelate jaoks.
ParameetridValmis 4 numbrit {pinit,pT,pS,pG}\{p_{init}, p_T, p_S, p_G\} iga 9 mikrooskuse kohta — EM-i väljund. „Õmmeldakse“ online-mootorisse kuni järgmise sobitamise tsüklini. Häkatonil kasutame kirjanduslikke vaikeväärtusi (0.2,0.1,0.1,0.2)(0.2, 0.1, 0.1, 0.2) kõigi oskuste jaoks, v2-s — päris numbreid EM-ist.

Parameetrid jõuavad online-mootorisse ja elavad seal kuni järgmise sobitamise tsüklini.

⚡ Online — iga õpilase vastuse peale

Jaotis «⚡ Online — iga õpilase vastuse peale»
flowchart LR
classDef onl fill:#bbf7d0,stroke:#15803d,color:#0f172a
classDef sel fill:#e9d5ff,stroke:#7e22ce,color:#0f172a
B1[applyAttempt]:::onl --> B2["P(L)"]:::onl --> B3["P(solve)"]:::onl --> B4[ZPD-skoor]:::sel --> B5[Top-N]:::sel
SammMis see on ja milleks
applyAttemptFunktsioon, mis iga õpilase vastuse peale uuendab tema P(L)-i iga mikrooskuse kohta, mis on ülesandes märgitud. Võtab vastu (praegune P(L), õige/vale, BKT parameetrid).
P(L)Õpilase „meisterlikkuse vektor“: iga 9 mikrooskuse kohta number 0 ja 1 vahel, mis peegeldab mudeli kindlust „kas õpilane oskab seda oskust“. Uueneb iga vastusega.
P(solve)Tõenäosus konkreetne ülesanne praegu õigesti lahendada. Arvutatakse õpilase P(L)-st ülesande mikrooskuste lõikes (geom. keskmine) ja samadest BKT parameetritest.
ZPD-skoorÜlesande lõplik prioriteet. Koosneb „kui lähedal P(solve) on 0.7-le“ (closeness) ja „kui palju alatreenitud oskusi ta puudutab“ (rarity bonus).
Top-NParimad N ülesannet ZPD-skoori järgi. Esimene jõuab õpilasele, ülejäänud on reservis (juhul „lahendas hiljuti“, vt §5).

Kaks faasi. Offline — aeglane: kord N nädala järel laseme EM-i läbi suure vastuste arhiivi ja saame 4 numbrit iga mikrooskuse kohta. Online — kiire: iga õpilase „Valmis“ kliki peale uuendame ühe P(L) ja arvutame ümber soovituse.

VäliTüüpNäideAllikas
student_idstring"u_142"sessioon / kasutajate DB
masteryRecord<skillId, number>{ "define.t1.add": 0.31 }täieneb online
historyAttemptRecord[]vt allpoolvastuste logi
task.idstring"q_007"ülesannete pool
task.microskillsstring[]["define.t2.mix"]ülesannete märgendamine
task.difficultynumber ∈ [0,1]0.55autori hinnang (tie-breaker)

AttemptRecord näide (üks vastus logis):

{
"task_id": "q_007",
"correct": true,
"ts": "2026-05-07T18:42:11Z",
"per_skill": { "define.t2.mix": true }
}

Task näide:

{
"id": "q_007",
"topic": "linear",
"microskills": ["define.t2.mix"],
"difficulty": 0.55,
"prompt_et": "Pille on 3 aastat vanem kui Mart…",
"answer": "x = 12"
}

3. BKT parameetrid (4 numbrit mikrooskuse kohta)

Jaotis «3. BKT parameetrid (4 numbrit mikrooskuse kohta)»
NimiTähendusVaikimisi
pinitp_{init}Tagasivaateline P(oskas enne esimest katset)0.20
pTp_TTõenäosus õppida ühe katsega0.10
pSp_SSlip — oskas, aga eksis0.10
pGp_GGuess — ei oskanud, aga arvas õigesti0.20

Allikas: packages/bkt-core/src/microskills.ts → DEFAULT_BKT.

Miks „konservatiivsed“. (0.2,  0.1,  0.1,  0.2)(0.2,\;0.1,\;0.1,\;0.2) on kirjandusliku vaikeväärtused koolimatemaatikale (Corbett & Anderson, 1995, ja hilisemad tööd). Need ei ole agressiivsed: mudel ei tee teravaid järeldusi pärast üht vastust. pT=0.1p_T = 0.1 on aeglane õppimine (üks vastus harva „õpetab“); pS,pG[0.1,0.2]p_S, p_G \in [0.1, 0.2] on tolerants juhuslike möödalaskmiste ja arvamiste suhtes. See on kindlustus üleennustamise vastu „üks õige katse → omandatud“.

Miks häkatonil fikseeritud. Õige sobitus nõuab ~3000 vaatlust iga oskuse kohta, ja EM-pipeline pole prodis veel ühendatud. Kirjandusliku vaikeväärtused annavad mõistliku stardikäitumise „karbist välja“, ilma et peaks midagi sobitama.

Mis muutub v2-s. Käivitame EM-i (vt põhjalikult §6 „Kust parameetrid tulevad“) kogutud andmete peal ja saame oma 4 numbrit iga 9 mikrooskuse kohta — aga ikka ühised kõigi õpilaste jaoks.

4. Õppimise samm (online, iga vastuse kohta)

Jaotis «4. Õppimise samm (online, iga vastuse kohta)»

Ülesande ühe mikrooskuse jaoks:

P(Lcorrect)=P(L)(1pS)P(L)(1pS)+(1P(L))pGP(L \mid correct) = \frac{P(L) \cdot (1 - p_S)}{P(L) \cdot (1 - p_S) + (1 - P(L)) \cdot p_G} P(Lwrong)=P(L)pSP(L)pS+(1P(L))(1pG)P(L \mid wrong) = \frac{P(L) \cdot p_S}{P(L) \cdot p_S + (1 - P(L)) \cdot (1 - p_G)}

ja seejärel „õppimise“ samm:

P(Lnew)=posterior+(1posterior)pTP(L_{new}) = posterior + (1 - posterior) \cdot p_T

Realisatsioon — bkt-core/src/bkt.ts:36-46 (bktUpdate). Mitme oskusega ülesande korral tehakse seda iga mikrooskuse kohta sõltumatult (applyAttempt, read 65–84).

Interaktiivne: BktSimulator — kliki „vastas õigesti / valesti“ ja vaata, kuidas P(L)P(L) liigub.

5. Ülesande valiku samm

Jaotis «5. Ülesande valiku samm»

Iga ülesande jaoks poolis arvutame ühise P(lahendada)P(\text{lahendada})geomeetriline keskmine mikrooskuste lõikes (rangem kui aritmeetiline: üks nõrk komponent tirib tugevamini alla):

P(solve)joint=exp ⁣(1ni=1nlogP(solve)i)P(solve)_{joint} = \exp\!\left(\frac{1}{n} \sum_{i=1}^{n} \log P(solve)_i\right)

Ülesande skoor:

score=exp ⁣((P(solve)joint0.7)20.03)closeness+0.15{s:P(Ls)<0.4}nrarityscore = \underbrace{\exp\!\left(-\frac{(P(solve)_{joint} - 0.7)^2}{0.03}\right)}_{closeness} + 0.15 \cdot \underbrace{\frac{|\{s : P(L_s) < 0.4\}|}{n}}_{rarity}

Gauss annab tipu väärtuses 0.7 (ZPD), rarity bonus tõukab ülesannete poole, kus on rohkem „alatreenitud“ oskusi.

Realisatsioon — bkt-core/src/bkt.ts:102-135 (scoreTaskForStudent), top-N valitakse recommend-iga (read 137–152), välja jäetakse viimased 5 task_id ajaloost.

Arvuline näide (Ivani peatükist)

Jaotis «Arvuline näide (Ivani peatükist)»
  • P(L)=0.166P(L) = 0.166 mikrooskuse „sulud“ kohta.
  • Ainult sulgude ülesande P(solve)P(solve): 0.1660.9+0.8340.2=0.3170.166 \cdot 0.9 + 0.834 \cdot 0.2 = 0.317.
  • Closeness: exp((0.3170.7)2/0.03)0.0073\exp(-(0.317 - 0.7)^2 / 0.03) \approx 0.0073 — peaaegu null, ei valita.
  • Mitu oskust (sulud + tuttav aritmeetika): P(solve)[0.55,0.65]P(solve) \in [0.55, 0.65] — ZPD-s.

Täielik illustratsioon allpool:

closeness = exp(−(p−target)²/σ²). Tipus on kõrgeim, langeb kiiresti äärtele. Mida väiksem σ², seda kitsam on «ZPD aken».

6. Kust parameetrid tulevad (EM-sobitamine, offline)

Jaotis «6. Kust parameetrid tulevad (EM-sobitamine, offline)»

Eesmärk — taastada (pinit,pT,pS,pG)(p_{init}, p_T, p_S, p_G) vastuste massiivist. Algoritm: EM (Baum–Welch) kahe seisundiga peidetud Markovi ahelatele (HMM) „oskab / ei oska“.

Algoritm ise:

  1. Võtame vaatluste massiivi: ~3000 vastust oskuse kohta.
  2. Arvame algväärtused 4 parameetrile (näiteks kirjanduslikud vaikeväärtused).
  3. E-samm: praeguste parameetritega arvutame, kui tõenäoline on iga peidetud jada „oskas / ei oskanud“ igal hetkel.
  4. M-samm: hindame parameetreid ümber, et vaadeldud andmed oleksid kõige tõenäolisemad.
  5. Kordame 3–4, kuni parameetrid stabiliseeruvad (~20 iteratsiooni).
PunktVäärtus
Andmemaht oskuse kohta~3000 vaatlust
Iteratsioone koondumiseni~20
Parameetri täpsus±0.01

Lähemalt — NB-3 EM-sobitamine.

7. Kas me kasutame sõltuvuste graafi?

Jaotis «7. Kas me kasutame sõltuvuste graafi?»

Lühike vastus — ei. Graaf on UI-s inimeste jaoks joonistatud, kuid selektori kood seda ei loe.

Kaks erinevat mõistet — ärge segi ajage

Jaotis «Kaks erinevat mõistet — ärge segi ajage»
MisKus elabKes täidabKas koodis kasutatakse?
Oskuste sõltuvuste DAG (t3.mix → t1.add, t2.mix…)data/matx-define/microskills.json, väli prereqcurriculum-i autor üks kord❌ ei — ainult kuvatakse UI-s
Ülesande märgendid (task.microskills = ["t3.mix", "t1.add", …])data/matx-define/tasks.jsonõpetaja iga ülesande lisamisel✅ jah — loetakse iga recommend() käivitusel

microskills.json-is sõltuvuste graaf näeb välja nii:

define.t2.mix → prereq: [t1.add, t1.mul, t2.add, t2.mul] ← 4 eelkäijat
define.t3.mix → prereq: [t1.add, t1.mix, t1.mul, t2.add,
t2.mix, t2.mul, t3.add, t3.mul] ← 8 eelkäijat

Seda graafi kuvatakse vidinas ProgressionMatrix.tsx (vaata raamatust), aga recommend() seda mällu ei lae.

Kui õpetaja lisab ülesande panka, tema:

  1. Kirjutab ülesande teksti ja õige vastuse.
  2. Käsitsi loetleb task.microskills-is kõik mikrooskused, mida ülesanne nõuab — sealhulgas eelkäijad.

Näiteks t3.mix ülesande puhul õpetaja kirjutab:

{
"id": "MD-15",
"microskills": [
"define.t3.mix",
"define.t2.mix",
"define.t1.add",
"define.t1.mul"
],
"prompt_et": "...",
"answer": "..."
}

Ehk õpetaja ise rullib graafi lahti lameks loendiks märgenduse ajal. 20 ülesande pangast 16 — mitme oskusega (vt tabelit allpool).

Miks mudel ilma graafi lugemata töötab

Jaotis «Miks mudel ilma graafi lugemata töötab»

Selektor vaatab ainult task.microskills-i ja state.mastery-t. Kui ta arvutab geom. keskmist P(solve), nõrk t1.add (näiteks P(L)=0.0 algajal) tirib ühise P(solve) 0.2-le → closeness läheb ~0-le → ülesanne automaatselt ei valita.

Niisiis prereq-i kontroll juhtub „tasuta“ — sest eelkäija on juba task.microskills-is ja jõuab valemisse.

Mida me kaotame, ilma graafi otse lugemata

Jaotis «Mida me kaotame, ilma graafi otse lugemata»
  • Haavatavus märgenduse vigade suhtes. Kui õpetaja unustab t1.add-i lisada t3.mix ülesandele, mudel ei tea, et õpilasel on alustes auk — ja võib pakkuda liiga keerulist ülesannet.
  • Otseseid reegleid ei saa kirja panna: „ära näita t3.mix-i, kuni t2.mix ei jõua P(L)0.5P(L) \geq 0.5“ — pole kohta koodis, kus selline tingimus arvutuks ilma graafi lugemata.
  • UI ei saa pakkuda „siin on oskused, mida pead omandama enne seda ülesannet“, sest vajalik info (DAG) selektoris puudub.

Ülesannete jaotus oskuste järgi (praegustest andmetest)

Jaotis «Ülesannete jaotus oskuste järgi (praegustest andmetest)»

9 mikrooskust, 20 ülesannet. Neist mitme oskusega — 16 / 20:

Oskusi ülesandesÜlesandeid
14
26
35
53
61
91

Niisiis 80% ülesannetest on seotud 2+ oskusega. Geomeetriline keskmine töötab tegelikult peaaegu igal katsel.

Avatud küsimused vestluseks

Jaotis «Avatud küsimused vestluseks»

Iga küsimus — disaini-otsus, millele on vaja meeskonnaga vastata. Struktuur on üks: „kuidas praegu → kuidas oleks → millest rääkida“.

1. Kas v2-s õpetame koodi sõltuvuste graafi lugema?

Jaotis «1. Kas v2-s õpetame koodi sõltuvuste graafi lugema?»

Praegu: kood vaatab ainult ülesande oskuste loendit (task.microskills) ja õpilase P(L)-i. Graafi „t3 vajab t1“ fail on kõrval, aga kood seda ei ava.

Kui loeks: kood teaks ise „ilma t1.add-ita on t3.mix ülesannet vara anda“ — isegi kui õpetaja unustas t1.add selle ülesande juurde märkida.

Millest meeskonnaga rääkida:

  • Teeme selge reegli nagu „t3 on suletud, kuni t2 < 0.5“? Annab ennustatavuse, aga lisab koodi ja võimalikke konflikte ZPD-loogikaga.
  • Või jätame nii nagu on (reegel käivitub „juhuslikult“ geom. keskmise kaudu)? Vähem koodi, aga sõltume õpetaja distsipliinist.

2. Kes vastutab märgenduse eest — õpetaja või kood?

Jaotis «2. Kes vastutab märgenduse eest — õpetaja või kood?»

Praegu: õpetaja. Ülesannet lisades loetleb käsitsi kõik oskused, mida ülesanne nõuab, sealhulgas eelkäijad. See on rutiin ja vigade allikas.

Kui kood aitaks: õpetaja märgib ainult „ülemise“ oskuse (näiteks t3.mix), kood graafi kaudu lisab automaatselt kõik tema eelkäijad (t2.mix, t1.add, t1.mul).

Millest meeskonnaga rääkida:

  • Usaldame õpetaja distsipliini? Siis on vaja märgenduse valideerimise tööriista (linterit).
  • Või usaldame graafi? Siis arvestage — üks viga graafis tiražeerub kõigile ülesannetele korraga.

3. Üks komplekt pT,pS,pGp_T, p_S, p_G — või oma iga oskuse jaoks?

Jaotis «3. Üks komplekt pT,pS,pGp_T, p_S, p_GpT​,pS​,pG​ — või oma iga oskuse jaoks?»

Praegu: kõik 9 mikrooskust jagavad sama 4 numbrit (0.2,0.1,0.1,0.2)(0.2, 0.1, 0.1, 0.2). Ehk „libastumise tõenäosus“ (slip) on sama nii lihtsa aritmeetika (t1.add) kui ka pika kolmeosalise võrrandi (t3.mix) puhul.

Reaalselt erinevad: pikas ülesandes on kergem libastuda (slip suurem). Lihtsas ilma teadmata arvata on peaaegu võimatu (guess väiksem). Ideaalne — oma 4 numbrit iga 9 oskuse kohta.

Millest meeskonnaga rääkida:

  • Millal meil on ~3000 vastust iga oskuse kohta, et neid EM-iga per-oskus sobitada?
  • Kas tasub hakata praegu sellel eesmärgil andmeid koguma?

4. Sundparandus vs ZPD

Jaotis «4. Sundparandus vs ZPD»

Stsenaarium: Maša tuli esimest korda. Tema P(L)=0P(L) = 0 baasil t1.add.

Kui selektor vaatab iga ülesannet, kus on t1.add oskustes, geom. keskmine annab P(solve)0.2P(\text{solve}) \approx 0.2 → closeness ≈ 0 → ülesanne kõrvale heidetud. Jäävad ainult puhtad t1.add-i ülesanded.

See on hariduslikult õige — sunnime baasi sulgema.

Aga võib olla igav — kui pangas on vaid 3 puhast t1.add-i ülesannet, lahendab Maša neid ringi 6 korda. Motivatsioon kukub.

Millest meeskonnaga rääkida:

  • Kas lisada „päästemehhanism“: kui õpilane saab 5 korda järjest ülesande sama oskusega, ZPD-aken laieneb automaatselt ja pulli pääsevad „naaberülesanded“?
  • Või sulgeme augud rangelt, isegi sama-tüüpi ülesannete hinnaga?

5. Kui ühendame MATx — tulevad oskused erinevatest teemadest

Jaotis «5. Kui ühendame MATx — tulevad oskused erinevatest teemadest»

Praegu: kõik 9 meie oskust on ühest teemast (define, ülesannete modelleerimine).

Pärast MATx-i integratsiooni: lisandub 9 oskust 3 teisest teemast — protsendid (protsendid), vorrandid (võrrandid), abivalemid (abivalemid). Kokku 18 oskust, 4 teemat.

Tekib uus ülesannete klass — teemadevahelised. Näiteks „protsentide tekstülesanne, kus tuleb võrrand koostada“ — see on define.t2.mul (modelleerimine) + vorrandid.lihtsad (arvutamine).

Millest meeskonnaga rääkida:

  • Loeme sellise ülesande ühe valemiga kõigi oskuste lõikes (matemaatiliselt töötab, aga semantiliselt veider)?
  • Või toome paralleelsed rajad ja vahetame teemade vahel?
  • Tasakaalustame soovitusi — „mitte rohkem kui 5 ülesannet järjest ühest teemast“?

6. ZPD-akna jäikus (σ2=0.03\sigma^2 = 0.03) — staatiline või dünaamiline?

Jaotis «6. ZPD-akna jäikus (σ2=0.03\sigma^2 = 0.03σ2=0.03) — staatiline või dünaamiline?»

Mis see number on: ülesande skoorimise valemis σ2\sigma^2 juhib, kui lähedal P(solve)P(\text{solve}) peab olema 0.7-le. Väiksem σ² — kitsam aken (ainult ülesanded P(solve)[0.65,0.75]P(\text{solve}) \in [0.65, 0.75] läbivad). Suurem σ² — laiem.

Praegu: σ2=0.03\sigma^2 = 0.03 (staatiline). Lubab P(solve)[0.55,0.85]P(\text{solve}) \in [0.55, 0.85].

Kui σ² liiguks:

  • Algaja just tuli — σ2=0.10\sigma^2 = 0.10 (lai aken: „kõik, mis annab vähegi edusammu — sobib“).
  • Kogenud õpilane — σ2=0.01\sigma^2 = 0.01 (kitsas aken: „rangelt kasvuvööndis, ilma igava keskmiseta“).
  • Pärast õigete seeriat — kitsendame (tõstame latti), pärast valede — laiendame (anname puhkust).

Millest meeskonnaga rääkida:

  • Kas automatiseerida või jätta käsitsi reguleerimiseks õpetajale?
  • Kui automatiseerida — milliste signaalide põhjal (seeria pikkus, keskmine P(L), kasvu kiirus)?
  • Tüübid ja parameetrid — packages/bkt-core/src/microskills.ts
  • Update / select — packages/bkt-core/src/bkt.ts
  • Oskuste graaf — data/matx-bridge.json
  • Simulaator-vidinad — study-guide/src/widgets/