14 KiB
14 KiB
複習時間算法完整設計方案
🎯 核心設計原則
- 漸進式增長: 避免過快跳躍,符合記憶曲線
- 簡單有效: 邏輯清晰易懂,便於實作和維護
- 智能糾錯: 根據表現動態調整
- 科學依據: 基於間隔重複記憶理論
📐 核心算法公式
基本公式(簡化版)
新間隔 = 舊間隔 × 增長係數 × 表現係數
這個公式很簡單:
- 舊間隔: 上次復習間隔天數
- 增長係數: 根據當前間隔階段決定
- 表現係數: 根據答題表現決定
📊 完整算法流程圖
graph TD
A[開始復習] --> B[獲取詞彙資訊]
B --> C[計算難易度係數]
C --> D[進行復習測試]
D --> E[記錄答題結果]
E --> F[計算表現係數]
F --> G[計算新的復習間隔]
G --> H[更新熟悉程度]
H --> I[設定下次復習時間]
I --> J[結束]
C --> C1[詞彙CEFR等級]
C --> C2[學習者程度]
C --> C3[歷史表現]
F --> F1[翻卡題評分]
F --> F2[客觀題正確率]
F --> F3[反應時間]
G --> G1[前次間隔]
G --> G2[難易度係數]
G --> G3[表現係數]
G --> G4[階段調整係數]
🧮 詳細算法設計
1. 難易度係數計算
interface DifficultyCalculation {
wordLevel: CEFRLevel // 詞彙等級
learnerLevel: CEFRLevel // 學習者程度
wordFrequency: number // 詞彙使用頻率
personalHistory: number // 個人歷史表現
}
function calculateDifficultyFactor(params: DifficultyCalculation): number {
const levels = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2']
const wordIndex = levels.indexOf(params.wordLevel)
const learnerIndex = levels.indexOf(params.learnerLevel)
// 基礎難度差異
const levelDifference = wordIndex - learnerIndex
const baseFactor = 1.0 + (levelDifference * 0.15)
// 詞頻調整(高頻詞較容易)
const frequencyAdjustment = params.wordFrequency > 1000 ? -0.1 : 0.1
// 個人歷史調整
const historyAdjustment = (params.personalHistory - 0.7) * 0.2
return Math.max(0.8, Math.min(2.2,
baseFactor + frequencyAdjustment + historyAdjustment
))
}
2. 表現係數計算
interface PerformanceData {
questionType: QuestionType
isCorrect: boolean
responseTime: number // 反應時間(秒)
confidence: number // 信心程度(1-5)
}
function calculatePerformanceFactor(data: PerformanceData): number {
let baseFactor: number
switch (data.questionType) {
case 'flipcard':
// 翻卡題:根據信心程度
const confidenceFactors = [0.5, 0.7, 1.0, 1.2, 1.4]
baseFactor = confidenceFactors[data.confidence - 1]
break
case 'multiple_choice':
case 'fill_blank':
case 'listening':
// 客觀題:正確/錯誤 + 反應時間
if (data.isCorrect) {
// 反應時間越快,表現越好
const timeBonus = data.responseTime < 3 ? 0.1 :
data.responseTime < 8 ? 0.0 : -0.1
baseFactor = 1.1 + timeBonus
} else {
baseFactor = 0.6
}
break
default:
baseFactor = data.isCorrect ? 1.0 : 0.6
}
return Math.max(0.4, Math.min(1.5, baseFactor))
}
3. 階段調整係數
graph LR
A[當前間隔] --> B{間隔階段}
B -->|1-7天| C[初期階段<br/>係數: 1.8-2.2]
B -->|8-30天| D[成長階段<br/>係數: 1.4-1.8]
B -->|31-90天| E[穩定階段<br/>係數: 1.2-1.5]
B -->|91-365天| F[熟練階段<br/>係數: 1.1-1.3]
function getStageAdjustment(currentInterval: number): number {
if (currentInterval <= 7) return 2.0 // 初期快速增長
if (currentInterval <= 30) return 1.6 // 成長期中等增長
if (currentInterval <= 90) return 1.35 // 穩定期緩慢增長
return 1.15 // 熟練期微調
}
4. 完整間隔計算公式
function calculateNextInterval(params: {
previousInterval: number
difficulty: DifficultyCalculation
performance: PerformanceData
reviewCount: number
}): number {
const difficultyFactor = calculateDifficultyFactor(params.difficulty)
const performanceFactor = calculatePerformanceFactor(params.performance)
const stageAdjustment = getStageAdjustment(params.previousInterval)
// 主要公式
let nextInterval = params.previousInterval *
difficultyFactor *
performanceFactor *
stageAdjustment
// 最小間隔保護
nextInterval = Math.max(1, nextInterval)
// 最大間隔限制
nextInterval = Math.min(365, nextInterval)
// 四捨五入到整天
return Math.round(nextInterval)
}
📈 熟悉程度計算重新設計
多維度熟悉度模型
pie title 熟悉程度組成 (100%)
"復習成功次數" : 40
"當前間隔長度" : 25
"正確率一致性" : 20
"最近表現趨勢" : 15
function calculateMasteryLevel(params: {
successfulReviews: number
currentInterval: number
totalReviews: number
recentPerformance: number[] // 最近5次表現
}): number {
// 1. 成功次數分數 (40%)
const successScore = Math.min(params.successfulReviews * 4, 40)
// 2. 間隔長度分數 (25%)
const intervalScore = Math.min((params.currentInterval / 365) * 25, 25)
// 3. 一致性分數 (20%)
const accuracy = params.totalReviews > 0 ?
params.successfulReviews / params.totalReviews : 0
const consistencyScore = accuracy * 20
// 4. 趨勢分數 (15%)
const recentAvg = params.recentPerformance.length > 0 ?
params.recentPerformance.reduce((a, b) => a + b) / params.recentPerformance.length : 0.7
const trendScore = recentAvg * 15
return Math.min(100, Math.round(
successScore + intervalScore + consistencyScore + trendScore
))
}
📅 復習時間線對比
現有算法 vs 新算法
| 復習次數 | 現有算法 | 新算法(理想情況) | 新算法(困難詞彙) | 新算法(簡單詞彙) |
|---|---|---|---|---|
| 1次成功 | 2天 | 2天 | 2天 | 3天 |
| 2次成功 | 4天 | 4天 | 3天 | 6天 |
| 3次成功 | 8天 | 7天 | 5天 | 12天 |
| 4次成功 | 16天 | 12天 | 8天 | 24天 |
| 5次成功 | 32天 | 21天 | 13天 | 42天 |
| 6次成功 | 64天 | 35天 | 22天 | 75天 |
| 7次成功 | 128天 | 60天 | 35天 | 130天 |
| 8次成功 | 256天 | 95天 | 55天 | 200天 |
| 9次成功 | 512天 | 145天 | 85天 | 300天 |
| 10次成功 | 1024天 | 220天 | 130天 | 365天 |
🎮 答題表現評分系統
翻卡題評分流程
graph TD
A[顯示詞彙] --> B[用戶自我評估]
B --> C{選擇信心程度}
C -->|1| D[完全不記得<br/>係數: 0.5]
C -->|2| E[有印象但不確定<br/>係數: 0.7]
C -->|3| F[記得但需思考<br/>係數: 1.0]
C -->|4| G[清楚記得<br/>係數: 1.2]
C -->|5| H[非常熟悉<br/>係數: 1.4]
D --> I[計算新間隔]
E --> I
F --> I
G --> I
H --> I
客觀題評分流程
graph TD
A[開始答題] --> B[記錄開始時間]
B --> C[用戶選擇答案]
C --> D[記錄結束時間]
D --> E[計算反應時間]
E --> F{答案正確?}
F -->|正確| G[基礎係數: 1.1]
F -->|錯誤| H[基礎係數: 0.6]
G --> I{反應時間}
I -->|< 3秒| J[快速正確<br/>+0.1獎勵]
I -->|3-8秒| K[正常速度<br/>無調整]
I -->|> 8秒| L[緩慢回答<br/>-0.1懲罰]
H --> M[錯誤分析]
M --> N[記錄錯題類型]
J --> O[最終係數計算]
K --> O
L --> O
N --> O
🔄 完整學習循環
sequenceDiagram
participant U as 用戶
participant S as 系統
participant A as 算法引擎
participant D as 資料庫
U->>S: 開始今日復習
S->>D: 查詢到期詞彙
D->>S: 返回復習列表
S->>A: 選擇復習題型
A->>S: 返回題目配置
loop 每個詞彙
S->>U: 展示題目
U->>S: 提交答案
S->>A: 分析表現
A->>A: 計算新間隔
A->>A: 更新熟悉度
A->>D: 保存復習記錄
end
S->>U: 復習完成報告
📋 實作階段規劃
階段1: 基礎優化 (Week 1)
目標: 改進現有算法,保持系統穩定
// 簡化版漸進算法
function calculateNextIntervalV1(
previousInterval: number,
isCorrect: boolean,
confidence: number = 3
): number {
let growthFactor: number
// 階段性增長係數
if (previousInterval <= 7) {
growthFactor = 1.8 // 初期較快
} else if (previousInterval <= 30) {
growthFactor = 1.4 // 中期放緩
} else {
growthFactor = 1.2 // 後期緩慢
}
// 表現調整
const performanceFactors = [0.5, 0.7, 1.0, 1.2, 1.4]
const performanceFactor = isCorrect ?
performanceFactors[confidence - 1] : 0.6
const nextInterval = previousInterval * growthFactor * performanceFactor
return Math.max(1, Math.min(365, Math.round(nextInterval)))
}
階段2: 個人化增強 (Week 2-3)
新增功能:
- 詞彙難度分析
- 學習者程度評估
- 個人化係數調整
// 完整版算法
class SpacedRepetitionEngine {
calculateNextInterval(params: {
flashcard: Flashcard
learner: LearnerProfile
performance: PerformanceData
history: ReviewHistory[]
}): number {
const difficulty = this.analyzeDifficulty(params.flashcard, params.learner)
const performance = this.analyzePerformance(params.performance)
const trend = this.analyzeTrend(params.history)
return this.computeInterval(difficulty, performance, trend)
}
}
階段3: 智能優化 (Week 4)
高級功能:
- 遺忘曲線預測
- 最佳復習時機推薦
- 學習效率分析
📈 效果預測圖表
學習進度曲線對比
熟悉程度 (%)
100 | ╭─── 新算法
| ╭───╯
80 | ╭───╯
| ╭───╯
60 | ╭───╯
|╭───╯
40 |╯
|
20 | ╭── 現有算法
| ╭───╯
0 +─────────────────────────→
0 5 10 15 20 25 30 復習次數
新算法特點:
- 更平滑的進度曲線
- 避免過早達到100%
- 提供更多中間階段
復習間隔增長對比
間隔天數
400 |
| ●── 現有算法 (過快)
300 | ╱
| ╱
200 |╱
|
100 | ╭──●──●──●── 新算法 (平滑)
| ╱
50 |╱
|
0 +────────────────────→
1 5 10 15 20 復習次數
🎯 關鍵改進點
1. 更科學的增長曲線
- 初期: 較快增長建立信心
- 中期: 穩定增長鞏固記憶
- 後期: 緩慢增長保持長期記憶
2. 個人化學習路徑
A1學習者 + C1詞彙 = 較慢增長 + 更多練習
C1學習者 + A1詞彙 = 較快增長 + 適度練習
3. 智能錯誤恢復
連續錯誤 → 重置到較短間隔
偶爾錯誤 → 輕微調整
長期正確 → 加速進展
🔧 實作考量
資料庫設計調整
-- 新增欄位到 Flashcard 表
ALTER TABLE Flashcards ADD COLUMN EasinessFactor REAL DEFAULT 2.5;
ALTER TABLE Flashcards ADD COLUMN ConsecutiveCorrect INTEGER DEFAULT 0;
ALTER TABLE Flashcards ADD COLUMN LastPerformanceScore REAL DEFAULT 0.0;
-- 新增復習記錄表
CREATE TABLE ReviewSessions (
Id TEXT PRIMARY KEY,
FlashcardId TEXT,
ReviewedAt DATETIME,
QuestionType TEXT,
IsCorrect BOOLEAN,
ResponseTimeMs INTEGER,
ConfidenceLevel INTEGER,
PreviousInterval INTEGER,
NewInterval INTEGER,
FOREIGN KEY (FlashcardId) REFERENCES Flashcards(Id)
);
API 設計
// 復習API
POST /api/flashcards/{id}/review
{
questionType: 'flipcard' | 'multiple_choice' | 'fill_blank',
isCorrect: boolean,
responseTimeMs: number,
confidenceLevel?: number, // 1-5, 僅翻卡題
selectedAnswer?: string, // 客觀題的選擇
}
// 響應
{
success: boolean,
data: {
newInterval: number,
nextReviewDate: string,
masteryLevel: number,
improvementTip?: string
}
}
🧪 測試與驗證計畫
A/B測試設計
- 控制組: 使用現有算法
- 實驗組: 使用新算法
- 測試指標:
- 學習完成率
- 長期記憶保持率
- 用戶滿意度
- 復習頻率合理性
參數調優策略
- 收集用戶數據 (2週)
- 分析學習模式 (1週)
- 調整算法參數 (1週)
- 驗證效果 (2週)
這個設計提供了更科學、更個人化、更有效的復習時間管理系統!