Da Sie den optimalen Bereich von N nicht kennen, möchten Sie ihn auf jeden Fall ändern können. Wenn Ihre Anwendung beispielsweise die Wahrscheinlichkeit vorhersagt, dass ein bestimmter Text Englisch ist, möchten Sie wahrscheinlich das Zeichen N-Gramm für N 3..5 verwenden. (Das haben wir experimentell gefunden.)
Sie haben keine Details zu Ihrer Anwendung mitgeteilt, aber das Problem ist klar genug. Sie möchten N-Gramm-Daten in einer relationalen Datenbank (oder einer dokumentbasierten NoSQL-Lösung) darstellen. Bevor Sie eine eigene Lösung vorschlagen, sollten Sie sich die folgenden Ansätze ansehen:
- Wie speichere ich Google ngrams am besten in einer Datenbank?
- Speichern von n-Gramm in der Datenbank in <n Tabellen
- Verwalten des Google Web 1T 5-Gramm mit der relationalen Datenbank
Nachdem ich keinen der oben genannten Links gelesen habe, schlage ich einen einfachen relationalen Datenbankansatz vor, der mehrere Tabellen verwendet, eine für jede Größe von N-Gramm. Sie könnten alle Daten in eine einzige Tabelle mit den maximal erforderlichen Spalten einfügen (dh Bigrams und Trigramme in ngram_4 speichern, wobei die letzten Spalten null bleiben), aber ich empfehle, die Daten zu partitionieren. Abhängig von Ihrem Datenbankmodul kann eine einzelne Tabelle mit einer großen Anzahl von Zeilen die Leistung beeinträchtigen.
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));
Als nächstes werde ich Ihnen eine Abfrage geben, die das wahrscheinlichste nächste Wort bei all Ihren ngram-Tabellen zurückgibt. Aber zuerst sind hier einige Beispieldaten, die Sie in die obigen Tabellen einfügen sollten:
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)
Um das wahrscheinlichste nächste Wort abzufragen, würden Sie eine Abfrage wie diese verwenden.
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
Wenn Sie weitere ngram-Tabellen hinzufügen, müssen Sie der obigen Abfrage eine weitere UNION-Klausel hinzufügen. Möglicherweise stellen Sie fest, dass ich in der ersten Abfrage word1 = @ word3 verwendet habe. Und in der zweiten Abfrage ist word1 = @ word2 AND word2 = @ word3. Das ist , weil wir müssen ausrichten , die drei Wörter in der Abfrage für die ngram Daten. Wenn wir das wahrscheinlichste nächste Wort für eine Folge von drei Wörtern wollen, müssen wir das erste Wort in den Bigram-Daten mit dem letzten Wort der Wörter in der Folge vergleichen.
Sie können die Gewichtsparameter nach Ihren Wünschen anpassen. In diesem Beispiel habe ich angenommen, dass höhere Ordnungszahlen "n" zuverlässiger sind.
PS Ich würde den Programmcode so strukturieren, dass er eine beliebige Anzahl von ngram_N-Tabellen über die Konfiguration verarbeitet. Sie können das Programm deklarativ ändern, um den N-Gramm-Bereich N (1..6) zu verwenden, nachdem Sie die Tabellen ngram_5 und ngram_6 erstellt haben.