최적의 N 범위를 알지 못한다면 분명히 변경할 수 있기를 원합니다. 예를 들어, 응용 프로그램에서 특정 텍스트가 영어 일 가능성을 예측하는 경우 N 3..5에 문자 N- 그램을 사용할 수 있습니다. (이것이 실험적으로 찾은 것입니다.)
응용 프로그램에 대한 세부 정보를 공유하지 않았지만 문제는 분명합니다. 관계형 데이터베이스 (또는 NoSQL 문서 기반 솔루션)에서 N-gram 데이터를 나타내려고합니다. 내 자신의 해결책을 제안하기 전에 다음 접근법을 살펴볼 수 있습니다.
- 데이터베이스에 Google ngram을 가장 잘 저장하는 방법은 무엇입니까?
- <n 개의 테이블 수로 데이터베이스에 n- 그램 저장
- 관계형 데이터베이스를 사용하여 Google Web 1T 5 그램 관리
이제 위의 링크를 읽지 않은 상태에서 각 N-gram 크기에 대해 여러 테이블을 사용하는 간단한 관계형 데이터베이스 접근 방식을 제안합니다. 필요한 최대 열을 사용하여 모든 데이터를 단일 테이블에 넣을 수 있습니다 (예 : nram_4에 bigrams 및 trigram을 저장하고 최종 열은 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을 사용했음을 알 수 있습니다. 그리고 두 번째 쿼리에서 word1 = @ word2 AND word2 = @ word3입니다. ngram 데이터에 대한 쿼리에서 세 단어 를 정렬 해야하기 때문 입니다. 세 단어의 시퀀스에서 가장 가능성이 높은 다음 단어를 원한다면 bigram 데이터의 첫 번째 단어를 시퀀스의 단어 의 마지막 단어 와 비교 해야합니다.
원하는대로 무게 매개 변수를 조정할 수 있습니다. 이 예에서는 더 높은 서수 "n"그램이 더 안정적이라고 가정했습니다.
추신 : 구성을 통해 여러 ngram_N 테이블을 처리하도록 프로그램 코드를 구성합니다. ngram_5 및 ngram_6 테이블을 작성한 후 N-gram 범위 N (1..6)을 사용하도록 프로그램을 선언적으로 변경할 수 있습니다.