Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Dicionários Naive Bayes

O dicionário naive_bayes (NAIVE_BAYES) classifica texto com um modelo multinomial de Naive Bayes, o modelo de eventos padrão para texto: ele atribui uma pontuação a cada classe com base na frequência com que os n-gramas da entrada aparecem nela. Você fornece uma tabela de contagens de n-gramas por classe, que ele compila em um modelo uma única vez, no momento do carregamento, e depois usa para classificar qualquer texto informado.

Ele é adequado para classificação de texto rápida e leve, como análise de sentimento, rotulagem de tópicos ou spam e detecção de idioma ou sistema de escrita.

Você consulta o dicionário com uma de três funções:

A função dictGet simples também classifica (consulte Notas). Outra função, naiveBayesNgrams, não classifica — ela divide o texto em n-gramas da mesma forma que o dicionário, para que você possa montar os dados de treinamento a partir de texto bruto (consulte criar dados de treinamento a partir de texto bruto).

Início rápido

Aqui, criamos um modelo unigrama (n = 1) em modo token para análise de sentimento.

1. Crie uma tabela de origem com contagens de n-gram por classe:

CREATE TABLE training_data (class_id UInt32, ngram String, count UInt64)
ENGINE = MergeTree ORDER BY (class_id, ngram);

2. Insira os dados de treinamento — palavras individuais (unigramas) e a frequência com que cada uma ocorre na classe positiva (1) e negativa (0):

INSERT INTO training_data VALUES
    (1,'good',10),(1,'great',8),(1,'excellent',6),(1,'love',7),(1,'happy',5),
    (1,'amazing',4),(1,'wonderful',3),(1,'best',3),(1,'fantastic',2),(1,'nice',4),
    (0,'bad',10),(0,'terrible',8),(0,'awful',6),(0,'hate',7),(0,'worst',5),
    (0,'horrible',4),(0,'poor',3),(0,'disappointing',3),(0,'ugly',2),(0,'sad',4);

3. Crie o dicionário com o layout NAIVE_BAYES:

CREATE DICTIONARY sentiment (ngram String, class_id UInt32, count UInt64)
PRIMARY KEY ngram
SOURCE(CLICKHOUSE(TABLE 'training_data'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token'))
LIFETIME(0);

PRIMARY KEY ngram faz da coluna ngram a chave — mas, para um dicionário NAIVE_BAYES, essa "chave" é o texto que você fornece para classificar, e não um valor armazenado que você procura (veja Estrutura do dicionário). O LAYOUT configura o modelo: class_attribute 'class_id' marca class_id como o rótulo da classe (portanto, o outro atributo, count, é a contagem de ocorrências por classe), n 1 usa unigramas e mode 'token' divide o texto em palavras separadas por espaços em branco (veja Parâmetros de layout).

4. ClassifiquenaiveBayesClassifier retorna o ID da classe:

SELECT naiveBayesClassifier('sentiment', 'this is great') as predicted_class;
   ┌─predicted_class─┐
1. │               1 │
   └─────────────────┘

1 corresponde à classe positiva, com base nos dados de treinamento que inserimos na etapa 2.

SELECT naiveBayesClassifier('sentiment', 'this is terrible') as predicted_class;
   ┌─predicted_class─┐
1. │               0 │
   └─────────────────┘

Da mesma forma, 0 corresponde à classe negativa.

O mesmo resultado com dictGet:

SELECT dictGet('sentiment', 'class_id', 'this is great') as predicted_class;
   ┌─predicted_class─┐
1. │               1 │
   └─────────────────┘

Obtenha a probabilidade da predição ou de cada classe:

SELECT naiveBayesClassifierWithProb('sentiment', 'amazing food but terrible service') as predicted_id_with_prob;
   ┌─predicted_id_with_prob─────────────┐
1. │ {                                 ↴│
   │↳  "class_id": 0,                  ↴│
   │↳  "probability": 0.642857145060626↴│
   │↳}                                  │
   └────────────────────────────────────┘

A previsão é a classe 0 (negativa), com probabilidade 0.64.

SELECT naiveBayesClassifierWithAllProbs('sentiment', 'amazing food but terrible service') as all_predicted_ids_with_probs;
   ┌─all_predicted_ids_with_probs─────────┐
1. │ [{                                  ↴│
   │↳  "class_id": 0,                    ↴│
   │↳  "probability": 0.642857145060626  ↴│
   │↳},{                                 ↴│
   │↳  "class_id": 1,                    ↴│
   │↳  "probability": 0.35714285493937414↴│
   │↳}]                                   │
   └──────────────────────────────────────┘

naiveBayesClassifierWithAllProbs retorna todas as classes em ordem da mais provável para a menos provável, com probabilidades cuja soma é 1.0 — aqui, 0.64 para a classe negativa e 0.36 para a positiva.

Como funciona

Treinamento (no carregamento). Cada linha de origem é uma observação (n-gram, class, count). Quando o dicionário é carregado, as linhas são compiladas no modelo uma única vez. Linhas duplicadas de (n-gram, class) são somadas, e linhas com count = 0 são ignoradas.

Classificação (no momento da consulta). Para classificar uma string, o modelo:

  1. Divide a string em n-grams de acordo com mode e n (consulte Modos de tokenização).
  2. Calcula a pontuação de cada classe combinando o prior da classe com a frequência com que os n-grams da entrada foram vistos nessa classe.
  3. Ordena as classes por pontuação. A classe com a maior pontuação é a predição retornada por naiveBayesClassifier; naiveBayesClassifierWithProb e naiveBayesClassifierWithAllProbs também retornam probabilidades — dessa classe ou de todas elas.

Há dois fatores que afetam a pontuação de cada classe. O primeiro é alpha, usado para suavização. A suavização impede que o modelo atribua pontuação zero a uma classe só porque um n-gram não apareceu nessa classe durante o treinamento. Um alpha menor faz o modelo depender mais dos dados de treinamento, então uma classe pode receber uma pontuação muito maior do que as outras, mas isso também pode deixar o modelo sensível demais quando os dados de treinamento são escassos ou desbalanceados. Um alpha maior faz com que as contagens de n-grams tenham menos peso, tornando as pontuações das diferentes classes mais parecidas. Se alpha for muito grande, a informação dos n-grams quase não influencia, e a pontuação passa a ser determinada principalmente pelo prior da classe (descrito a seguir).

O segundo fator é o prior da classe — o que o modelo assume sobre a probabilidade de cada classe antes de analisar o texto. Ele funciona como uma pontuação inicial que cada classe recebe antes que qualquer n-gram seja considerado; assim, um prior mais alto torna uma classe mais propensa a ser prevista. A forma como ele é definido depende de priors_mode. Por padrão (proportional), uma classe com contagem total maior de n-grams nos dados de treinamento começa com uma pontuação mais alta. Com uniform, todas as classes começam em igualdade, então apenas os n-grams decidem. Com explicit, você define manualmente o ponto de partida de cada classe. Consulte Modos de prior.

Um n-gram que nunca apareceu em nenhum ponto dos dados de treinamento é ignorado: ele não faz parte do vocabulário do modelo, portanto não ajuda nem prejudica nenhuma classe.

O algoritmo segue o modelo multinomial Naive Bayes para classificação de texto; consulte Manning, Raghavan & Schütze, Introduction to Information Retrieval, ch. 13 (Text Classification and Naive Bayes).

Estrutura do dicionário

Um dicionário NAIVE_BAYES tem uma estrutura fixa:

  • A PRIMARY KEY é uma única coluna String — o n-gram. No momento da consulta, essa "chave" é o texto que você fornece para classificar, não uma chave de busca armazenada.
  • Junto com ela, declare exatamente dois atributos de inteiros sem sinal: o rótulo da classe e a contagem de ocorrências. Os IDs de classe sempre usam UInt32 internamente, então um rótulo de classe deve caber em UInt32 (no máximo 4294967295), mesmo que você declare o atributo como UInt64. Um valor maior é rejeitado quando o dicionário é carregado, não quando você o cria. O mesmo vale para os tipos declarados: se um ID de classe de origem ou uma contagem não couber no tipo de atributo declarado, o carregamento falhará em vez de o valor ser truncado silenciosamente.
  • O parâmetro de layout class_attribute indica qual atributo é o rótulo da classe; o outro passa a ser automaticamente a contagem. Os dois atributos podem ser declarados em qualquer ordem.

A tabela de origem armazena contagens pré-agregadas: uma linha por (n-gram, class) com o número de vezes que esse n-gram apareceu nessa classe. Você gera essas contagens tokenizando seu corpus e agrupando o resultado, seja no seu próprio pipeline de treinamento ou no ClickHouse a partir de texto bruto rotulado (veja Criar dados de treinamento a partir de texto bruto). O dicionário apenas consome esses dados.

Atualizando o modelo. Como o modelo é um dicionário baseado em uma tabela, faça o retreinamento atualizando a tabela e recarregando-a:

INSERT INTO training_data VALUES (1, 'awesome', 5);
SYSTEM RELOAD DICTIONARY sentiment;

Parâmetros de layout

Parâmetro Descrição Exemplo Padrão
class_attribute Nome do atributo que contém o rótulo da classe; o outro atributo é a contagem. 'class_id' Obrigatório
n Tamanho do n-grama: 1 = unigramas, 2 = bigramas, 3 = trigramas, … (1–1024). 2 Obrigatório
mode Método de tokenização: byte, codepoint ou token. Veja Modos de tokenização. 'token' Obrigatório
alpha Suavização aditiva (Lidstone) para probabilidades de n-gramas; alpha = 1 é suavização de Laplace (deve ser finito e > 0). 0.5 1.0
priors_mode Como os priors de classe são determinados: uniform, proportional ou explicit. Veja Modos de prior. 'uniform' 'proportional'
priors Priors explícitos por classe: uma coleção de pares (class, probability). Válido apenas com priors_mode 'explicit', caso em que é obrigatório; fornecê-lo em qualquer outro modo é um erro. Deve somar 1.0. [(0, 0.6), (1, 0.4)]
store_source Retém as linhas de origem para que SELECT * FROM dictionary funcione. Aproximadamente dobra o uso de memória. 1 0
start_token Token de fronteira prefixado à entrada (n-1) vezes. Veja Tokens de delimitação. '0x01' / '<s>' — (sem preenchimento)
end_token Token de fronteira anexado à entrada (n-1) vezes. '0xFF' / '</s>' — (sem preenchimento)

Você pode definir o dicionário com a DDL CREATE DICTIONARY (como no início rápido acima) ou em um arquivo de configuração XML; veja layouts de dicionário para saber onde esse arquivo deve ficar. O exemplo abaixo define todas as opções de layout para que você possa ver todas elas — apenas class_attribute, n e mode são obrigatórios, e a tabela acima fornece os valores padrão para o restante. Em um arquivo de configuração, os priors são escritos como elementos prior repetidos (um por classe, como mostrado abaixo), os tokens de preenchimento para byte e codepoint são números (a configuração não pode conter bytes brutos) e um literal token recebe escape de XML quando necessário, então <s> se torna &lt;s&gt;.

CREATE DICTIONARY naive_bayes (ngram String, class_id UInt32, count UInt64)
PRIMARY KEY ngram
SOURCE(CLICKHOUSE(TABLE 'training_data'))
LAYOUT(NAIVE_BAYES(
    class_attribute 'class_id'
    n 2
    mode 'token'
    alpha 0.5
    priors_mode 'explicit'
    priors [(0, 0.6), (1, 0.4)]
    store_source 1
    start_token '<s>'
    end_token '</s>'
))
LIFETIME(3600);

Modos de tokenização

mode define o que é um "token" e, portanto, como são os n-gramas. Os n-gramas de origem devem ter sido gerados com o mesmo mode e n.

  • byte — cada token é um único byte; não se assume UTF-8. Com n = 2, 'abc' gera os bigramas de bytes 'ab', 'bc'. Bom para detectar idioma ou codificação em sequências arbitrárias de bytes, e para quaisquer dados em que sinais abaixo do nível de caractere sejam importantes. Normalmente é usado com n >= 2.
  • codepoint — cada token é um ponto de código Unicode; a entrada é interpretada como UTF-8. Com n = 1, 'café' gera os pontos de código 'c', 'a', 'f', 'é'. Bom para detectar escrita e idioma, e para texto curto ou CJK, em que limites de palavras por espaço em branco não são confiáveis. (Os n-gramas de origem devem ser UTF-8 válidos; a entrada da consulta é decodificada de forma tolerante — veja Notas.)
  • token — cada token é uma palavra delimitada por espaços em branco ASCII (espaço, tabulação, quebra de linha, retorno de carro, avanço de página, tabulação vertical; sequências são reduzidas a um único separador). Espaços em branco Unicode não ASCII, como U+00A0 (espaço inseparável) ou U+2003 (espaço em), não são separadores e permanecem dentro de um token. Espaço em branco é a única coisa que separa — nada é convertido para minúsculas nem removido — então 'Hello, World!' se torna os tokens 'Hello,' e 'World!' (a vírgula, o ! e as letras maiúsculas são mantidos), e com n = 2 eles formam o único bigrama 'Hello, World!'. Bom para classificação no nível de palavras em idiomas separados por espaços — sentimento, tópico, spam, idioma de uma frase.

Modos de prior

O prior é a crença do modelo sobre cada classe antes de ele analisar o texto. priors_mode define como ele é configurado.

  • proportional (padrão) — o prior de cada classe é proporcional à sua contagem total de n-gramas nos dados de treinamento — a soma da coluna count para essa classe, não o número de linhas nem de documentos de treinamento — portanto, as classes vistas com mais frequência começam com maior probabilidade. Escolha-o quando as proporções das classes no treinamento (pela contagem total de n-gramas) corresponderem às frequências esperadas no momento da consulta. Nada a informar — ele é derivado das contagens de origem.

    LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token' priors_mode 'proportional'))
  • uniform — todas as classes começam com a mesma probabilidade, então nenhuma sai na frente e a previsão vem inteiramente dos n-gramas da entrada. Escolha-o quando as classes estiverem balanceadas ou quando as frequências de treinamento não refletirem a frequência com que cada classe aparece no momento da consulta. Nada a informar.

    LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token' priors_mode 'uniform'))
  • explicit — você fornece os priors com priors [(0, 0.6), (1, 0.4)]: um par (classe, probabilidade) por classe, cada probabilidade maior que 0 e no máximo 1, somando 1.0 no total. Escolha-o quando você souber as taxas-base reais e elas forem diferentes das do treinamento — por exemplo, apenas 1% do tráfego em produção é spam, embora o conjunto de treinamento tenha sido balanceado. Calcule-os com base na participação esperada de cada classe no mundo real.

    LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token' priors_mode 'explicit' priors [(0, 0.9), (1, 0.1)]))

Tokens de fronteira (padding)

O padding fica desativado por padrão. Ele só importa para n > 1, quando pode melhorar a precisão ao permitir que o modelo use sinais no início e no fim do texto.

Por que isso ajuda. Com n > 1, os n-grams no meio do texto recebem contexto completo à esquerda e à direita, mas os primeiros e os últimos tokens não. Adicionar tokens de fronteira cria n-grams que marcam "início do texto" e "fim do texto", para que o modelo possa aprender padrões ligados à posição — por exemplo, uma palavra que é distintiva quando começa uma mensagem, ou um caractere típico no fim de uma palavra.

O que você deve fazer:

  1. Decida separadamente para cada lado. start_token e end_token são independentes — defina um, ambos ou nenhum. Um valor vazio significa que aquele lado não recebe padding.
  2. Escolha valores raros que não entrem em conflito com dados reais, por exemplo 0x01 / 0xFF para byte, U+10FFFE / U+10FFFF para codepoint, ou <s> / </s> para token.
  3. Produza os n-grams de treinamento com o mesmo padding. O Dicionário aplica padding à entrada da consulta, mas nunca à sua fonte, então os tokens de fronteira já precisam estar incorporados aos n-grams que você carrega. A maneira mais fácil de garantir que eles correspondam é gerar a fonte com naiveBayesNgrams, passando os mesmos start_token e end_token (além de n e mode) que você fornece ao layout — ele emite exatamente os n-grams com padding que o Dicionário produz no momento da consulta.

O formato do token de padding depende do modo:

  • byte — um número para o valor do byte, em decimal ou hexadecimal 0x (portanto, '1' e '0x01' são iguais):

    LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 2 mode 'byte' start_token '0x01' end_token '0xFF'))
  • codepoint — um número para o ponto de código UTF-8, em decimal ou hexadecimal 0x (portanto, '1114110' e '0x10FFFE' são iguais):

    LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 2 mode 'codepoint' start_token '0x10FFFE' end_token '0x10FFFF'))
  • token — a string literal do token:

    LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 2 mode 'token' start_token '<s>' end_token '</s>'))

Crie dados de treinamento a partir de texto bruto

Se você partir de texto bruto rotulado, em vez de contagens pré-agregadas, use a função naiveBayesNgrams para dividi-lo em n-grams. Forneça a ela os mesmos n, mode, start_token e end_token do seu layout, e ela produzirá exatamente os n-grams que o dicionário espera, para que os dados de treinamento correspondam ao que o modelo vê em tempo de consulta.

Dada uma tabela com linhas (class_id, text), construa a fonte (ngram, class_id, count) com um GROUP BY:

CREATE TABLE docs (class_id UInt32, text String) ENGINE = MergeTree ORDER BY tuple();
INSERT INTO docs VALUES
    (1, 'The food was amazing and the service was great'),
    (0, 'The service was terrible and the food was awful'),
    (1, 'I loved this cozy little place and the friendly staff'),
    (0, 'I hated the bad weather and the long wait'),
    (1, 'Best dinner we have had here, everything was delicious');

CREATE TABLE training_data (ngram String, class_id UInt32, count UInt64)
ENGINE = MergeTree ORDER BY (class_id, ngram);

INSERT INTO training_data
SELECT ngram, class_id, count()
FROM docs
ARRAY JOIN naiveBayesNgrams(text, 1, 'token') AS ngram
GROUP BY ngram, class_id;
SELECT * FROM training_data ORDER BY ngram LIMIT 5;
   ┌─ngram─┬─class_id─┬─count─┐
1. │ Best  │        1 │     1 │
2. │ I     │        1 │     1 │
3. │ I     │        0 │     1 │
4. │ The   │        0 │     1 │
5. │ The   │        1 │     1 │
   └───────┴──────────┴───────┘

training_data agora é uma fonte válida para um dicionário NAIVE_BAYES (aqui, unigramas de token; altere os argumentos n e mode para corresponder ao seu layout). O dicionário tokeniza a entrada da consulta exatamente como ela é fornecida; portanto, se o texto de treinamento estiver em minúsculas, mas o texto da consulta não, os n-gramas não corresponderão e a precisão do modelo será prejudicada.

Em seguida, crie o dicionário a partir de training_data, passando o prior explícito calculado acima, e classifique novas avaliações:

CREATE DICTIONARY review_sentiment (ngram String, class_id UInt32, count UInt64)
PRIMARY KEY ngram
SOURCE(CLICKHOUSE(TABLE 'training_data'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token' priors_mode 'explicit' priors [(0, 0.4), (1, 0.6)]))
LIFETIME(0);
SELECT
    naiveBayesClassifier('review_sentiment', 'amazing food and friendly staff') AS positive_review,
    naiveBayesClassifier('review_sentiment', 'awful service and a terrible meal') AS negative_review;
   ┌─positive_review─┬─negative_review─┐
1. │               1 │               0 │
   └─────────────────┴─────────────────┘

A classe 1 é positiva e 0 é negativa, portanto ambas as avaliações foram classificadas corretamente.

Mais exemplos

Modo byte — bigramas de bytes (n = 2, mode 'byte'; classe 0 = sequências de letras ad, classe 1 = letras xz):

CREATE TABLE byte_patterns_src (class_id UInt32, ngram String, count UInt64) ENGINE = MergeTree ORDER BY (class_id, ngram);
INSERT INTO byte_patterns_src VALUES (0,'ab',5),(0,'bc',5),(0,'cd',5),(1,'xy',5),(1,'yz',5),(1,'zw',5);

CREATE DICTIONARY byte_patterns (ngram String, class_id UInt32, count UInt64)
PRIMARY KEY ngram SOURCE(CLICKHOUSE(TABLE 'byte_patterns_src'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 2 mode 'byte')) LIFETIME(0);

SELECT naiveBayesClassifier('byte_patterns', 'abcd') AS abcd, naiveBayesClassifier('byte_patterns', 'xyzw') AS xyzw;
   ┌─abcd─┬─xyzw─┐
1. │    0 │    1 │
   └──────┴──────┘

Modo de ponto de código — detecção do sistema de escrita por caractere (n = 1, mode 'codepoint'; classe 0 = latino, 1 = cirílico):

CREATE TABLE script_src (class_id UInt32, ngram String, count UInt64) ENGINE = MergeTree ORDER BY (class_id, ngram);
INSERT INTO script_src VALUES (0,'a',5),(0,'b',5),(0,'c',5),(0,'d',5),(1,'а',5),(1,'б',5),(1,'в',5),(1,'г',5);

CREATE DICTIONARY script (ngram String, class_id UInt32, count UInt64)
PRIMARY KEY ngram SOURCE(CLICKHOUSE(TABLE 'script_src'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'codepoint')) LIFETIME(0);

SELECT naiveBayesClassifier('script', 'abcd') AS latin, naiveBayesClassifier('script', 'абвг') AS cyrillic;
   ┌─latin─┬─cyrillic─┐
1. │     0 │        1 │
   └───────┴──────────┘

Leia novamente os dados de treinamento com store_source:

CREATE TABLE stored_src (class_id UInt32, ngram String, count UInt64) ENGINE = MergeTree ORDER BY (class_id, ngram);
INSERT INTO stored_src VALUES (0,'alpha',3),(0,'beta',2),(1,'gamma',4);

CREATE DICTIONARY stored (ngram String, class_id UInt32, count UInt64)
PRIMARY KEY ngram SOURCE(CLICKHOUSE(TABLE 'stored_src'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 1 mode 'token' store_source 1)) LIFETIME(0);

SELECT ngram, class_id, count FROM stored ORDER BY ngram;
   ┌─ngram─┬─class_id─┬─count─┐
1. │ alpha │        0 │     3 │
2. │ beta  │        0 │     2 │
3. │ gamma │        1 │     4 │
   └───────┴──────────┴───────┘

Detecção de idioma a partir de raw text — palavras curtas com padding nas bordas (n = 2, mode 'codepoint'; classe 0 = inglês, 1 = espanhol). Os n-grams de treinamento são gerados a partir de palavras brutas com naiveBayesNgrams, e os tokens de fronteira — passados tanto para a função quanto para o layout — permitem que o modelo use a primeira e a última letra de cada palavra:

CREATE TABLE words (class_id UInt32, text String) ENGINE = MergeTree ORDER BY tuple();
INSERT INTO words VALUES
    (0,'dog'),(0,'cat'),(0,'fish'),(0,'bird'),(0,'book'),(0,'hand'),(0,'tree'),(0,'milk'),(0,'duck'),(0,'frog'),(0,'lamp'),(0,'desk'),
    (1,'gato'),(1,'casa'),(1,'perro'),(1,'libro'),(1,'mano'),(1,'leche'),(1,'arbol'),(1,'agua'),(1,'queso'),(1,'fuego'),(1,'mesa'),(1,'silla');

CREATE TABLE word_ngrams (ngram String, class_id UInt32, count UInt64) ENGINE = MergeTree ORDER BY (class_id, ngram);
INSERT INTO word_ngrams
SELECT ngram, class_id, count()
FROM words
ARRAY JOIN naiveBayesNgrams(text, 2, 'codepoint', '0x10FFFE', '0x10FFFF') AS ngram
GROUP BY ngram, class_id;

CREATE DICTIONARY lang (ngram String, class_id UInt32, count UInt64)
PRIMARY KEY ngram SOURCE(CLICKHOUSE(TABLE 'word_ngrams'))
LAYOUT(NAIVE_BAYES(class_attribute 'class_id' n 2 mode 'codepoint' start_token '0x10FFFE' end_token '0x10FFFF')) LIFETIME(0);

SELECT naiveBayesClassifier('lang', 'window') AS window, naiveBayesClassifier('lang', 'fiesta') AS fiesta;
   ┌─window─┬─fiesta─┐
1. │      0 │      1 │
   └────────┴────────┘

Notas

  • Semântica computacional de dicionário. Este é um dicionário computacional: dictGet(dict, '<class_attribute>', text) classifica text (a chave é uma entrada a ser classificada, não uma chave armazenada), o atributo de contagem não é consultável, e dictHas sempre retorna 1.
  • Validação da origem no carregamento. Todo n-grama de origem deve corresponder ao n e ao mode configurados (no modo codepoint, também deve ser UTF-8 válido); qualquer incompatibilidade faz o carregamento falhar. Como linhas com contagem zero são ignoradas (consulte Como funciona), uma origem vazia ou que contenha apenas contagens zero não tem nada com que treinar e falha ao carregar.
  • A tokenização no momento da consulta é tolerante. Ao contrário da validação da origem, a entrada da consulta nunca é rejeitada. No modo codepoint, bytes que não são UTF-8 válidos são decodificados da melhor forma possível, em vez de fazer a consulta falhar; no modo token, apenas espaços em branco ASCII separam palavras (espaços em branco Unicode, como U+00A0, permanecem dentro de um token). Entradas malformadas ainda são classificadas — normalmente com base no prior, já que seus n-gramas não corresponderão aos usados no treinamento.
Navigation