厳密一致と簡易的なファジー判定例えばクイズの答えが「母」の場合、「母親、おかあさん、ママ」など予想できるいくつかの解答文字列を用意して、
ユーザーの解答と順番に比較していけば、ある程度のゆるさを許容する正解判定が可能です。
しかし用意した答えと一文字でも違えば、例えば「おかーさん」などは間違いと判定されます。
つまり、単純な文字列同士の等値演算ではユーザーの解答の真意をくみ取った判定が難しいことになります。
/* 解答マップにユーザーの答えがある場合 */
const synonyms = ["母親", "お母さん", "ママ", "母", "おかあさん"];
const userInput = "ママ";
if (synonyms.includes(userInput)) {
console.log("正解!");
} else {
console.log("不正解!");
}
/* 解答マップにユーザーの答えがない場合 */
const synonyms = ["母親", "お母さん", "ママ", "母", "おかあさん"];
const userInput = "おかーさん";
if (synonyms.includes(userInput)) {
console.log("正解!");
} else {
console.log("不正解!");
もう少し柔軟に!類似度で判定してみるたとえば「おかあさん」「お母さん」「おかーさん」…これらはすべて意味は同じですが、文字列としては一致しません。
そこで使えるのが「Levenshtein距離(レーベンシュタイン距離、編集距離)」です。
これは、2つの文字列の違いを「何回の編集で一致させられるか?」という視点で測るアルゴリズムです。
・「ママ」と「まま」 → 距離 1(1文字の置換)
・「お母さん」と「おかあさん」 → 距離 1(1文字の変換)
・「おかあさん」と「おかーさん」 → 距離 1(1文字の置換)
距離が0に近いほど、よく似た文字列ということになります。
これを使って、「●文字までの違いなら正解とみなす」といった処理ができます。
/*Levenshtein距離(編集距離)を使う例*/
function levenshtein(a, b) {
const dp = Array.from({ length: a.length + 1 }, (_, i) =>
Array(b.length + 1).fill(0)
);
for (let i = 0; i <= a.length; i++) dp[i][0] = i;
for (let j = 0; j <= b.length; j++) dp[0][j] = j;
for (let i = 1; i <= a.length; i++) {
for (let j = 1; j <= b.length; j++) {
dp[i][j] = a[i - 1] === b[j - 1]
? dp[i - 1][j - 1]
: Math.min(
dp[i - 1][j] + 1,
dp[i][j - 1] + 1,
dp[i - 1][j - 1] + 1
);
}
}
return dp[a.length][b.length];
}
// 類似度を元に許容判定
function isFuzzyMatch(input, list, maxDistance = 2) {
return list.some(word => levenshtein(input, word) <= maxDistance);
}
const synonyms = ["母親", "お母さん", "ママ", "母", "おかあさん"];
const userInput = "おかーさん";
if (isFuzzyMatch(userInput, synonyms)) {
console.log("正解!");
} else {
console.log("不正解!");
}
簡単な解説maxDistance = 1 のように設定することで、「少しの違い(1回の編集)」までを許容できます。
編集距離の閾値を 2 にするとさらにゆるく、「タイプミス」程度もカバーできます。
完全一致と違い、柔軟に“だいたい合ってる”入力を拾うことができます。
Levenshtein距離の面白いポイント”正解っぽいけど違う”を、数字でスコア化できる。
これはAIや自然言語処理の基礎にも使われるアルゴリズム。
検索機能・予測変換・スペルチェック・クイズ判定など応用先が広い。
また、ユーザー入力を感じを全部ひらがなに変換してから判定を行う方法などもあります。
その他、判定だけでなく類義語辞書と組み合わせて文章の生成などにも応用ができます。
さらにJaro-Winkler距離(ジャロウ・ウィンクラー)というアルゴリズムもあります。
これはライブラリーを使うのでまたの機会にご紹介。
予算があるならChatGPTを使うのが効率がいい予算が許せるならもちろんChatGPTを使うのが最も正確で効率がいいのは言うまでもありません。