AlvinRedfors's picture
Upload 2 files
e9c3331 verified
Raw
History Blame Contribute Delete
2.86 kB
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Selma Lagerlof trigram language model</title>
<style>
body { font-family: system-ui, sans-serif; max-width: 40rem;
margin: 3rem auto; padding: 0 1rem; line-height: 1.5; }
input { width: 100%; padding: .6rem; font-size: 1rem; }
table { border-collapse: collapse; margin-top: 1rem; }
td { padding: .2rem 1.5rem .2rem 0; }
td.count { color: #666; }
#status { color: #666; }
</style>
</head>
<body>
<h1>Selma Lagerlof trigram language model</h1>
<p>Type the beginning of a Swedish sentence. The model proposes the five
most frequent continuations, counted on the novels of Selma Lagerlof
(EDAN20, lab 2).</p>
<input id="box" value="Det var en" disabled />
<p id="status">Loading the trigram counts...</p>
<table id="out"></table>
<script>
const CAND_NBR = 5;
let trigrams = null;
// The counts, stored as {"w1 w2": {"w3": count, ...}}
fetch('trigrams_compact.json')
.then(r => r.json())
.then(data => {
trigrams = data;
document.getElementById('status').textContent =
Object.keys(data).length.toLocaleString() + ' contexts loaded.';
document.getElementById('box').disabled = false;
predict();
})
.catch(e => {
document.getElementById('status').textContent = 'Could not load: ' + e;
});
function predict() {
if (!trigrams) return;
const tokens = document.getElementById('box').value.toLowerCase().split(/\s+/)
.filter(t => t.length > 0);
// Pad with the sentence tags so that a short input still has two
// words of context. "</s> <s>" is the start of a sentence.
const padded = ['</s>', '<s>'].concat(tokens);
const context = padded.slice(-2).join(' ');
const candidates = trigrams[context];
const out = document.getElementById('out');
out.innerHTML = '';
if (!candidates) {
out.innerHTML = '<tr><td>No prediction, this context is not in the corpus.</td></tr>';
return;
}
// Most frequent first, ties broken by alphabetical order
const best = Object.entries(candidates).sort(
(a, b) => (b[1] - a[1]) || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
for (const [word, count] of best.slice(0, CAND_NBR)) {
const row = out.insertRow();
row.insertCell().textContent = word;
const c = row.insertCell();
c.textContent = count;
c.className = 'count';
}
}
document.getElementById('box').addEventListener('input', predict);
</script>
</body>
</html>