Nの最適範囲がわからない場合は、絶対に変更できるようにする必要があります。たとえば、アプリケーションが特定のテキストが英語である可能性を予測する場合、おそらくN 3..5に文字N-gramを使用する必要があります。(これは実験的に発見したものです。)
アプリケーションに関する詳細を共有していませんが、問題は十分に明確です。リレーショナルデータベース(またはNoSQLドキュメントベースのソリューション)でN-gramデータを表現したい。私自身の解決策を提案する前に、次のアプローチを検討してください。
- Google ngramsをデータベースに最適に保存する方法は?
- nグラム未満のテーブルのデータベースにn-gramを保存する
- リレーショナルデータベースを使用したGoogle Web 1T 5-gramの管理
さて、上記のリンクをまったく読んでいないので、N-gramのサイズごとに1つずつ、複数のテーブルを使用する単純なリレーショナルデータベースアプローチをお勧めします。すべてのデータを必要な最大列を持つ単一のテーブルに入れることができます(つまり、ngram_4にバイグラムとトライグラムを格納し、最終列をnullのままにします)が、データをパーティション分割することをお勧めします。データベースエンジンによっては、多数の行を持つ単一のテーブルがパフォーマンスに悪影響を与える可能性があります。
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));
次に、すべてのngramテーブルから最も可能性の高い次の単語を返すクエリを提供します。ただし、最初に、上記の表に挿入する必要があるサンプルデータをいくつか示します。
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)
最も可能性の高い次の単語をクエリするには、次のようなクエリを使用します。
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
さらにngramテーブルを追加する場合は、上記のクエリに別のUNION句を追加する必要があります。最初のクエリでword1 = @ word3を使用したことに気付くかもしれません。2番目のクエリでは、word1 = @ word2 AND word2 = @ word3です。これは、ngramデータのクエリで3つの単語を揃える必要があるためです。3つの単語のシーケンスで最も可能性の高い次の単語が必要な場合は、シーケンス内の単語の最後の単語に対してバイグラムデータの最初の単語をチェックする必要があります。
必要に応じて、重量パラメーターを調整できます。この例では、序数の「n」グラムが高いほど信頼性が高いと想定しました。
PS構成を介して任意の数のngram_Nテーブルを処理するプログラムコードを構築します。ngram_5およびngram_6テーブルを作成した後、N-gram範囲N(1..6)を使用するようにプログラムを宣言的に変更できます。