鉴于您不知道N的最佳范围,您肯定希望能够更改它。例如,如果您的应用程序预测某个文本为英语的可能性,则可能要对N 3..5使用字符N-gram。(这是我们通过实验发现的。)
您尚未共享有关应用程序的详细信息,但是问题很明显。您想在关系数据库(或基于NoSQL文档的解决方案)中表示N元语法数据。在提出自己的解决方案之前,您可能需要看一下以下方法:
- 如何最好地将Google ngram存储在数据库中?
- 将n元语法存储在<n个表中
- 使用关系数据库管理Google Web 1T 5克
现在,在没有阅读上述任何链接的情况下,我建议一种简单的关系数据库方法,该方法使用多个表,每个表用于N-gram的大小。您可以将所有数据放在具有最大必要列的单个表中(即,将双字母组和三字组存储在ngram_4中,将最后一列保留为空),但是我建议对数据进行分区。根据您的数据库引擎,具有大量行的单个表可能会对性能产生负面影响。
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。在第二个查询中,word1 = @ word2和word2 = @ word3。那是因为我们需要将查询中的三个单词对齐为ngram数据。如果我们想要三个单词序列中最有可能的下一个单词,则需要将bigram数据中的第一个单词与该序列中单词的最后一个单词进行比较。
您可以根据需要调整权重参数。在此示例中,我假设序数较高的“ n”克将更可靠。
PS我将构造程序代码以通过配置处理任意数量的ngram_N表。创建ngram_5和ngram_6表后,可以声明性地更改程序以使用N-gram范围N(1..6)。