Karena Anda tidak akan tahu kisaran optimal N, Anda pasti ingin dapat mengubahnya. Misalnya, jika aplikasi Anda memprediksi kemungkinan teks tertentu adalah bahasa Inggris, Anda mungkin ingin menggunakan karakter N-gram untuk N 3..5. (Itulah yang kami temukan secara eksperimental.)
Anda belum membagikan detail tentang aplikasi Anda, tetapi masalahnya cukup jelas. Anda ingin mewakili data N-gram dalam database relasional (atau solusi berbasis dokumen NoSQL). Sebelum menyarankan solusi saya sendiri, Anda mungkin ingin melihat pendekatan berikut:
- Bagaimana cara terbaik menyimpan Google ngrams dalam basis data?
- Menyimpan n-gram dalam basis data dalam <n jumlah tabel
- Mengelola Google Web 1T 5-gram dengan Database Relasional
Sekarang, setelah tidak membaca salah satu tautan di atas, saya menyarankan pendekatan database relasional sederhana menggunakan beberapa tabel, satu untuk setiap ukuran N-gram. Anda bisa meletakkan semua data dalam satu tabel dengan kolom maksimum yang diperlukan (mis. Menyimpan bigrams dan trigram di ngram_4, membiarkan kolom terakhir kosong), tapi saya sarankan mempartisi data. Bergantung pada mesin basis data Anda, satu tabel dengan banyak baris dapat berdampak negatif terhadap kinerja.
create table ngram_1 (
word1 nvarchar(50),
frequency FLOAT,
primary key (word1));
create table ngram_2 (
word1 nvarchar(50),
word2 nvarchar(50),
frequency FLOAT,
primary key (word1, word2));
create table ngram_3 (
word1 nvarchar(50),
word2 nvarchar(50),
word3 nvarchar(50),
frequency FLOAT,
primary key (word1, word2, word3));
create table ngram_4 (
word1 nvarchar(50),
word2 nvarchar(50),
word3 nvarchar(50),
word4 nvarchar(50),
frequency FLOAT,
primary key (word1, word2, word3, word4));
Selanjutnya, saya akan memberi Anda pertanyaan yang akan mengembalikan kata berikutnya yang paling mungkin diberikan pada semua tabel ngram Anda. Tetapi pertama-tama, berikut adalah beberapa contoh data yang harus Anda masukkan ke dalam tabel di atas:
INSERT [ngram_2] ([word1], [word2], [frequency]) VALUES (N'building', N'with', 0.5)
INSERT [ngram_2] ([word1], [word2], [frequency]) VALUES (N'hit', N'the', 0.1)
INSERT [ngram_2] ([word1], [word2], [frequency]) VALUES (N'man', N'hit', 0.2)
INSERT [ngram_2] ([word1], [word2], [frequency]) VALUES (N'the', N'bat', 0.7)
INSERT [ngram_2] ([word1], [word2], [frequency]) VALUES (N'the', N'building', 0.3)
INSERT [ngram_2] ([word1], [word2], [frequency]) VALUES (N'the', N'man', 0.4)
INSERT [ngram_2] ([word1], [word2], [frequency]) VALUES (N'with', N'the', 0.6)
INSERT [ngram_3] ([word1], [word2], [word3], [frequency]) VALUES (N'building', N'with', N'the', 0.5)
INSERT [ngram_3] ([word1], [word2], [word3], [frequency]) VALUES (N'hit', N'the', N'building', 0.3)
INSERT [ngram_3] ([word1], [word2], [word3], [frequency]) VALUES (N'man', N'hit', N'the', 0.2)
INSERT [ngram_3] ([word1], [word2], [word3], [frequency]) VALUES (N'the', N'building', N'with', 0.4)
INSERT [ngram_3] ([word1], [word2], [word3], [frequency]) VALUES (N'the', N'man', N'hit', 0.1)
INSERT [ngram_3] ([word1], [word2], [word3], [frequency]) VALUES (N'with', N'the', N'bat', 0.6)
INSERT [ngram_4] ([word1], [word2], [word3], [word4], [frequency]) VALUES (N'building', N'with', N'the', N'bat', 0.5)
INSERT [ngram_4] ([word1], [word2], [word3], [word4], [frequency]) VALUES (N'hit', N'the', N'building', N'with', 0.3)
INSERT [ngram_4] ([word1], [word2], [word3], [word4], [frequency]) VALUES (N'man', N'hit', N'the', N'building', 0.2)
INSERT [ngram_4] ([word1], [word2], [word3], [word4], [frequency]) VALUES (N'the', N'building', N'with', N'the', 0.4)
INSERT [ngram_4] ([word1], [word2], [word3], [word4], [frequency]) VALUES (N'the', N'man', N'hit', N'the', 0.1)
Untuk menanyakan kata berikutnya yang paling memungkinkan, Anda akan menggunakan kueri seperti ini.
DECLARE @word1 NVARCHAR(50) = 'the'
DECLARE @word2 NVARCHAR(50) = 'man'
DECLARE @word3 NVARCHAR(50) = 'hit'
DECLARE @bigramWeight FLOAT = 0.2;
DECLARE @trigramWeight FLOAT = 0.3
DECLARE @fourgramWeight FLOAT = 0.5
SELECT next_word, SUM(frequency) AS frequency
FROM (
SELECT word2 AS next_word, frequency * @bigramWeight AS frequency
FROM ngram_2
WHERE word1 = @word3
UNION
SELECT word3 AS next_word, frequency * @trigramWeight AS frequency
FROM ngram_3
WHERE word1 = @word2
AND word2 = @word3
UNION
SELECT word4 AS next_word, frequency * @fourgramWeight AS frequency
FROM ngram_4
WHERE word1 = @word1
AND word2 = @word2
AND word3 = @word3
) next_words
GROUP BY next_word
ORDER BY SUM(frequency) DESC
Jika Anda menambahkan lebih banyak tabel ngram, Anda perlu menambahkan klausa UNION lain untuk kueri di atas. Anda mungkin memperhatikan bahwa dalam permintaan pertama saya menggunakan word1 = @ word3. Dan dalam kueri kedua, word1 = @ word2 AND word2 = @ word3. Itu karena kita perlu menyelaraskan tiga kata dalam kueri untuk data ngram. Jika kita ingin kata berikutnya yang paling mungkin untuk urutan tiga kata, kita perlu memeriksa kata pertama dalam data bigram terhadap kata terakhir dari kata-kata dalam urutan.
Anda dapat mengubah parameter berat sesuai keinginan. Dalam contoh ini, saya mengasumsikan bahwa "n" gram ordinal yang lebih tinggi akan lebih dapat diandalkan.
PS Saya akan menyusun kode program untuk menangani sejumlah tabel ngram_N melalui konfigurasi. Anda dapat mengubah secara deklaratif program untuk menggunakan rentang N-gram N (1..6) setelah membuat tabel ngram_5 dan ngram_6.