En uygun N aralığını bilmediğiniz göz önüne alındığında, kesinlikle onu değiştirmek istersiniz. Örneğin, uygulamanız belirli bir metnin İngilizce olduğunu tahmin ederse, muhtemelen N 3..5 için N-gram karakter kullanmak istersiniz. (Deneysel olarak bulduğumuz şey budur.)
Başvurunuzla ilgili ayrıntıları paylaşmadınız, ancak sorun yeterince açık. İlişkisel bir veritabanında (veya NoSQL belge tabanlı çözümde) N-gram verilerini temsil etmek istiyorsunuz. Kendi çözümümü önermeden önce, aşağıdaki yaklaşımlara göz atmak isteyebilirsiniz:
- Google ngramlarını bir veritabanında en iyi şekilde nasıl saklayabilirim?
- N-gramın veritabanında <n tablo sayısı içinde depolanması
- İlişkisel Veritabanı ile Google Web 1T 5 gram'ı yönetme
Şimdi, yukarıdaki bağlantılardan herhangi birini okumadıktan sonra, N-gramın her boyutu için bir tane olmak üzere birden çok tablo kullanarak basit, ilişkisel bir veritabanı yaklaşımı öneririm. Tüm verileri maksimum gerekli sütunlarla tek bir tabloya koyabilirsiniz (yani, son sütunları boş bırakarak, ngram_4'te bigram ve trigram depolayın), ancak verileri bölümlendirmenizi öneririz. Veritabanı motorunuza bağlı olarak, çok sayıda satırı olan tek bir tablo performansı olumsuz etkileyebilir.
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));
Daha sonra, size tüm ngram tablolarınız verildiğinde en olası sonraki kelimeyi döndürecek bir sorgu vereceğim. Ama önce, yukarıdaki tablolara eklemeniz gereken bazı örnek veriler:
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)
En olası sonraki kelimeyi sorgulamak için böyle bir sorgu kullanırsınız.
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
Daha fazla ngram tablosu eklerseniz, yukarıdaki sorguya başka bir UNION deyimi eklemeniz gerekir. İlk sorguda word1 = @ word3 kullandığımı fark edebilirsiniz. Ve ikinci sorguda, word1 = @ word2 VE word2 = @ word3. Çünkü ngram verileri için sorgudaki üç kelimeyi hizalamamız gerekiyor . Üç kelimelik bir dizi için en olası sonraki kelimeyi istiyorsak, bigram verilerindeki ilk kelimeyi dizideki kelimelerin son kelimesine karşı kontrol etmemiz gerekir .
Ağırlık parametrelerini dilediğiniz gibi değiştirebilirsiniz. Bu örnekte, daha yüksek sıra sayıdaki "n" gramın daha güvenilir olacağını varsaydım.
PS Ben program kodu yapılandırma üzerinden herhangi bir sayıda ngram_N tablolarını işlemek için yapı. Programı, ngram_5 ve ngram_6 tablolarını oluşturduktan sonra N-gram aralığı N (1..6) kullanacak şekilde bildirimsel olarak değiştirebilirsiniz.