Exemplo de Uso da Classe Uflamon

Propaganda
NATÁLIA CRISTINA SCHNEIDER
SIMDATAMAPPER: UM PADRÃO
ARQUITETURAL PARA INTEGRAÇÃO DE
OPERAÇÕES DE SIMILARIDADE TEXTUAL
EM SISTEMAS DE BANCO DE DADOS
LAVRAS – MG
2014
NATÁLIA CRISTINA SCHNEIDER
SIMDATAMAPPER: UM PADRÃO ARQUITETURAL PARA
INTEGRAÇÃO DE OPERAÇÕES DE SIMILARIDADE TEXTUAL EM
SISTEMAS DE BANCO DE DADOS
Trabalho de Conclusão de Curso de Graduação
apresentado ao Colegiado do Curso de Bacharelado
em Ciência da Computação, para obtenção do título
de Bacharel.
Orientador
Prof. Dr. Leonardo Andrade Ribeiro
Coorientador
Prof. Dr. Ahmed Ali Abdalla Esmin
LAVRAS – MG
2014
Dedico à minha família, em especial aos meus pais, Edemilson e Maria Luiza .
AGRADECIMENTOS
Quero agradecer aos meus pais Maria Luiza e Edemilson pelo apoio,
dedicação, esforço e pelo amor incondicional durante esta fase. Aos
meus irmãos Renan e Guilherme por acreditarem em mim em todos
os momentos. Ao meu namorado Vinicius por toda a paciência e compreensão. Aos familiares que sempre estiveram presentes. Aos amigos de Rio Claro que compreenderam a minha ausência. Aos amigos
de Lavras quero agradecer pelo companheirismo e amizade durante
toda esta trajetória, vocês fizeram que esta etapa fosse inesquecível.
SUMÁRIO
1. INTRODUÇÃO ............................................................................................. 10
2. TRABALHOS RELACIONADOS .............................................................. 11
3. CONCEITOS BÁSICOS .............................................................................. 12
3.1. Mapeamento de Strings para Conjuntos ...................................................... 12
3.2. Esquema de Pesos ........................................................................................ 12
3.3. Funções de Similaridade .............................................................................. 13
3.4. Funções de Similaridade baseadas em Conjuntos........................................ 13
3.5. Filtros baseados em Tamanho ...................................................................... 14
3.6. Função de Similaridade baseada em Distância de Edição ........................... 14
3.7. Prefix Filtering ............................................................................................. 15
3.8. Design Pattern e Data Mapper Pattern ......................................................... 15
4. SIMDATAMAPPER .................................................................................... 16
5. IMPLEMENTAÇÃO.................................................................................... 17
5.1. Implementação das Funções de Similaridade baseadas em Conjuntos ....... 18
5.2. Implementação da Função de Similaridade baseada na Distância de
Edição ......................................................................................................... 21
5.3. Implementação do Prefix Filtering ............................................................. 22
5.4. Implementação SimDataMapper ................................................................ 23
6. EXPERIMENTOS ....................................................................................... 23
6.1. Dados .......................................................................................................... 23
6.2. Seleções por Similaridade ........................................................................... 23
6.3. Junções por Similaridade ............................................................................ 25
6.4. Prefix Filtering ........................................................................................... 25
6.5. Atualizações de estatísticas ......................................................................... 26
7. CONCLUSÃO ............................................................................................. 27
REFERÊNCIAS BIBLIOGRÁFICAS .......................................................... 28
APÊNDICE A .................................................................................................. 29
LISTA DE FIGURAS
Figura 1 - Mapeamento de uma string para um conjunto de tokens .................12
Figura 2 - SimDataMapper.................................................................................16
Figura 3 - Diagrama de sequência da operação que constrói o suporte a
operações de similaridade....................................................................................17
Figura 4 - Diagrama de sequência da operação Retrieve....................................17
Figura 5 - Diagrama de sequência da operação Update ....................................17
Figura 6 - Digrama de classe SimDataMapper..................................................24
Figura 7 - Gráfico das seleções do Estágio 2.....................................................24
Figura 8 - Gráfico das seleções do Estágio 3.....................................................24
Figura 9 - Gráfico das seleções do Estágio 4.....................................................25
Figura 10 - Gráfico das Junções.........................................................................25
Figura 11 - Criação das tabelas de prefixo ........................................................26
Figura 12 - Tempo de execução da junção com Prefix Filtering.......................26
Figura 13 - Comparação do tempo de execução com e sem prefixo..................26
Figura 14 - Gráfico da propagação de estatística ..............................................27
LISTA DE TABELAS
Tabela 1 – Funções de Similaridade baseadas em conjunto...............................13
Tabela 2 – Filtros baseados em tamanho............................................................14
Tabela 3 – Relação de tabelas por estágios........................................................17
Tabela 4 – Tempo de criação das tabelas auxiliares...........................................24
SimDataMapper: um Padrão Arquitetural para Integração de
Operações de Similaridade Textual em Sistemas de Banco de Dados
Natália Cristina Schneider1 Leonardo Andrade Ribeiro2
1 Universidade
Federal de Lavras, Departamento de Ciência da Computação, Brasil
Federal de Góias, Instituto de Informática, Brasil
[email protected], [email protected]
2 Universidade
Keywords:
Banco de Dados, Operações de Similaridade, Processamento Avançado de Consultas, Integração de Dados,
Identificação de Duplicatas
Abstract:
Dados textuais são onipresentes, por isso gerenciar esses tipos dados é de fundamental importância. Neste
cenário, a duplicação de informação é algo comum em sistemas de banco de dados, principalmente em decorrência de erros ortográficos e da falta de um padrão representativo. Consequentemente, operações baseadas
em noções de similaridade são essenciais para a manutenção consistente dos dados armazenados. Entretanto,
operações de similaridade não são suportadas nativamente por sistemas gerenciadores de banco de dados atuais. Por exemplo, no caso de junções, a implementação mais direta baseada em procedimentos armazenados
realiza os cálculos de similaridade sobre a saída do produto cartesiano entre duas tabelas, e, com isso, apresenta tempo de execução excessivamente alto, mesmo para volumes moderados de dados. Para mitigar este
problema, uma série de trabalhos foram propostos que utilizam diversos filtros para reduzir o espaço de comparação e expressam comparações baseadas em similaridade declarativamente em SQL. Por outro lado, apesar de
permitir ganhos significativos de performance, estas estratégias dificultam consideravelmente o acesso transparente e integração de programas de aplicação ao banco de dados. Por exemplo, o suporte a operações por
similaridade sobre um simples atributo requer a construção, acesso e manutenção de várias tabelas auxiliares.
Este artigo apresenta um padrão arquitetural de software para permitir a integração de operações baseadas em
diversas noções de similaridade e aplicações orientadas a objetos de maneira simples e flexível. Um conjunto
abrangente de experimentos são reportados e demonstram que a abordagem proposta é flexível e permite a
execução eficiente de uma variedade de operações de similaridade, incluindo consultas baseadas em seleções
e junções e operações de atualização dos dados.
1
INTRODUÇÃO
Sistemas hospitalares, sistemas comerciais, catálogos
de produtos são apenas alguns exemplos de aplicações comuns que utilizam atributos textuais. Duplicação de informação é algo comum nesses sistemas,
principalmente em decorrência de erros ortográficos
e da falta de um padrão representativo. De fato, atributos textuais usados em um banco de dados para armazenar informações como endereço e nome de um
cliente normalmente não asseguram uma formatação
rígida durante a entrada dos dados.
Por exemplo, considere uma empresa que possui
diversas fontes de dados de clientes e a necessidade de
relacionar estas fontes é muito comum. Um mesmo
cliente pode estar presente em diferentes fontes e o
seu nome pode estar armazenado de maneiras diferentes, ou seja, em uma fonte ele pode ter sido cadastrado
com o seu primeiro nome seguido pelo sobrenome,
em outra com o sobrenome seguido de seu primeiro
nome, e ainda existe a possibilidade de possuir algum
erro de digitação em uma terceira fonte. Neste cenário, a utilização de uma operação de junção baseada
em comparações de igualdade será insuficiente. Mais
ainda, além de relacionar fontes de dados diferentes,
pode ser necessário realizar consultas de um determinado cliente que foi armazenado na mesma base de
dados de duas ou mais formas diferentes. Neste caso,
também não será adequado utilizar operações baseadas em testes de correspondência exata.
Os cenários descritos ressaltam os problemas encontrados por aplicações que relacionam dados textuais. Pois a abordagem baseada em comparações de
igualdade apresenta uma qualidade inferior do que a
esperada, sendo ineficaz e muitas vezes inadequada.
Como forma de diminuir o impacto causado por este
rentes domínios de aplicação. Onde elementos comuns entre as diversas técnicas implementadas foram
identificados e organizados com um padrão arquitetural de software. Com isso, além do desempenho
computacional, critérios importantes no lado do desenvolvimento de aplicações como facilidade de desenvolvimento, composibilidade, reusabilidade de código também passam a ser considerados. Este padrão
arquitetural visa facilitar a incorporação de operações
de similaridade em sistemas de banco de dados, sem a
necessidade de aquisição de produtos especializados.
O restante deste artigo está estruturado da seguinte
maneira. Trabalhos relacionados são discutidos na
Seção 2. Os conceitos básicos necessários para o entendimento deste trabalho são apresentados na Seção
3. A apresentação do padrão arquitetural é apresentado na Seção 4. Estratégias para implementação são
apresentadas na Seção 5. Na Seção 6 são apresentados os experimentos. Finalmente, as conclusões são
apresentadas na Seção 7.
problema é imprescindível a utilização de um paradigma mais geral, baseado no conceito de similaridade, onde seleções e junções são usadas para encontrar e relacionar objetos textuais similares em um
banco de dados. Neste contexto, a similaridade entre
dois objetos textuais é definida quantitativamente por
uma função de similaridade. Existe uma variedade de
funções de similaridade, entre as mais comuns estão
a Cosseno, a Distância de Edição, a Dice e a Jaccard
(Cohen, 1998). Para executar junções e seleções por
similaridade é utilizado um limiar de corte e apenas
tuplas ou pares de tuplas cujo valor retornado pela
função de similaridade for maior que este limiar estarão presentes no resultado, neste caso estas tuplas
são consideradas semelhantes.
Infelizmente, operações de similaridade não são
suportadas diretamente nos Sistemas Gerenciadores
de Banco de Dados (SGBDs) atuais. Uma forma de
implementar essas funções é através da utilização de
UDFs (acrônimo do inglês User Defined Function).
Entretanto, esta abordagem possui custo computacional proibitivamente alto. No caso de junções, a
UDF é executada sobre o produto cartesiano das tabelas de entrada, o que faz com todos os pares de tuplas sejam comparados entre si. Com foco em dados
do tipo texto, diversas propostas têm sido apresentadas nos últimos anos para contornar este problema,
usando uma variedade de filtros para reduzir o espaço de comparação (Gravano et al., 2001; Koudas
et al., 2007; Gravano et al., 2003; Koudas et al., 2004;
Chandel et al., 2007).
Entretanto, apesar de permitir ganhos significativos de performance, estas estratégias dificultam consideravelmente o acesso transparente e integração de
programas de aplicação ao banco de dados. Por exemplo, o suporte a operações por similaridade sobre um
simples atributo requer a construção, acesso e manutenção de várias tabelas auxiliares. O problema é exacerbado quando são usadas funções de similaridade
que adotam esquemas de pesos para unidades textuais baseados em estatísticas, porque cada modificação na tabela original requer atualização e propagação de estatísticas para as tabelas auxiliares. Além
disso, aplicações podem requerer o suporte a múltiplas funções de similaridade, pois é um fato conhecido que nenhuma função apresenta um melhor resultado em todos os domínios e cenários (Cohen et al.,
2003). Com isso haveria a dificuldade de gerenciar
um número maior ainda de tabelas auxiliares. Essas
questões dificultam significativamente a adoção da similaridade declarativa por aplicações.
Este artigo apresenta a modelagem e implementação do SimDataMapper, um padrão para suportar
uma variedade de noções de similaridade em dife-
2
TRABALHOS RELACIONADOS
Os trabalhos de pesquisa para o processamento de
operações de similaridade sobre dados textuais podem ser agrupados de acordo com três abordagens gerais bastante relacionadas entre si:
1) implementação “no topo” do SGBD;
2) algoritmos especializados;
3) integração com mecanismos internos do SGBD.
Na abordagem 1), operações de similaridade implementadas no topo do SGBD são expressas declarativamente em SQL e executadas usando infraestrutura
puramente relacional, como índices agrupados baseados em árvores B e UDFs. Como mencionado anteriormente, trabalhos anteriores focaram em estratégias
para suportar um conjunto diversificado de funções
de similaridade (Gravano et al., 2001; Gravano et al.,
2003; Koudas et al., 2004; Koudas et al., 2007; Chandel et al., 2007).
Além da definição de um padrão arquitetural, vários outros aspectos diferenciam este trabalho de outros apresentados anteriormente (Koudas et al., 2007;
Chandel et al., 2007). Primeiramente, existe a preocupação em definir um conjunto comum de tabelas auxiliares para suportar várias funções de similaridade.
Além de considerar execução de junção e seleção de
similaridade. Foram realizadas otimizações, como a
utilização do Prefix Filtering. Finalmente, neste trabalho a propagação de estatística é feita proceduralmente em UDFs por questões de desempenho, se di-
11
o conceito de q-grams (Ukkonen, 1992), isto é, substrings de tamanho q obtidas através do “deslizamento
de uma janela” de tamanho q sobre uma string. Como
os tokens no início ou fim da string podem ser menores do que q e para garantir que cada caractere apareça
em exatamente q tokens, a string é estendida no início e no fim. Neste caso a string é pré-fixada com q-1
ocorrências do caractere "#"e sufixada com q-1 ocorrências do caractere "$"(Koudas et al., 2004; Gravano
et al., 2003)
Por exemplo, a string “token” pode ser mapeada
para o conjunto de 3-gram tokens apresentado na Figura 1. O resultado desse processo pode ser uma bag,
neste caso, o símbolo de um número sequencial ordinal é anexado ao final de cada ocorrência de um token
em uma string (Chaudhuri et al., 2006). Dessa maneira, a bag {a,b,b} é convertida para o conjunto {a1,
b1, b2}.
ferenciando novamente do que já foi apresentado em
outros trabalhos (Koudas et al., 2007).
A abordagem 2) consiste no desenvolvimento
de algoritmos especializados (Sarawagi and Kirpal,
2004; Bayardo et al., 2007; Xiao et al., 2008; Ribeiro
and Härder, 2011; Wang et al., 2012). Estas abordagens utilizam técnicas que não são facilmente reproduzidas por operadores relacionais e normalmente
obtém performance superior a soluções implementadas no topo do SGBD.
Finalmente, a abordagem 3) foca na integração
de algoritmos de similaridade no núcleo do SGBD
(Chaudhuri et al., 2006; Jr. et al., 2006; Augsten et al.,
2014) (veja também (Ribeiro and Härder, 2007) e (Ribeiro et al., 2009) para SGBDs XML). Tipicamente,
algoritmos especializados são integrados como operadores da álgebra física do SGBD. Esta abordagem requer modificações em todos os componentes do compilador de consultas como a álgebra lógica, modelo
de custos e regras de compilação, além da extensão
da linguagem de consulta para inclusão de construtores para operações de similaridade.
O desenvolvimento de um sistema genérico para
suportar várias operações de similaridade juntamente
com a modelagem de um padrão arquitetural de software representa uma nova abordagem: 4) Integração
de realização declarativa de operações de similaridade
textual no ambiente de aplicação. Apesar deste aspecto ser fundamental para a disseminação do uso de
operações de similaridade em sistemas de banco de
dados, tem recebido pouca atenção na literatura. O
trabalho proposto se encaixa na nova abordagem (4),
que busca a integração com o ambiente de aplicação.
3
Figura 1: Mapeamento de uma string para um conjunto de
tokens.
CONCEITOS BÁSICOS
3.2
Nesta seção, são apresentados os principais componentes conceituais envolvidos em operações de similaridade. Incluindo a definição das funções de similaridade, transformação de strings para conjuntos,
esquemas para associação de pesos e noções de similaridade baseadas em conjuntos e distância de edição.
As operações de junção e seleção por similaridade são
definidas formalmente. Finalmente, são apresentadas
as vantagens de se utilizar o Data Mapper Pattern.
3.1
Esquema de Pesos
Tokens podem possuir importância diferente para um
determinado cálculo de similaridade. Neste caso, um
esquema de pesos pode ser usado para quantificar a
importância relativa de cada token através da associação de pesos a cada token. Um esquema de pesos que é amplamente conhecido é o IDF (acrônimo
do inglês Inverse Document Frequency) (Baeza-Yates
and Ribeiro-Neto, 2011), onde o peso de um token t é
definido da seguinte maneira: IDF (t)=ln (N/df (t)),
onde df (t) é o chamado document frequency (DF),
isto é, o número de strings nas quais um token t aparece em um banco de dados de N strings. A intuição por trás de IDF é que tokens raros normalmente
possuem mais conteúdo e são mais discriminativos.
Neste tipo de associação tokens mais raros possuem
um DF menor e consequentemente um IDF maior.
Já os tokens que não são tão raros possuem um DF
Mapeamento de Strings para
Conjuntos
A similaridade entre strings é calculada em termos
de conjuntos de unidades básicas e indivisíveis de
informação textual denominadas tokens. Strings podem ser mapeadas para conjuntos de tokens usando
12
Tabela 1: Funções de Similaridade baseadas em conjunto
Função
Jaccard
Dice
Cosseno
Definição
intersec (r, s)
w (r ∩ s)
w (r ∪ s)
2 · w (r ∩ s)
w (r) + w (s)
w (r ∩ s)
p
w (r) · w (s)
τ · (w (r) + w (s))
1+τ
τ · (w (r) + w (s))
2
p
τ · w (r) · w (s)
2007; Xiao et al., 2008; Ribeiro and Härder, 2011;
Wang et al., 2012), são apresentadas na Tabela 1.
Exemplo 1. Considere os conjuntos r ={hc, 9i,hb,
7i,hd, 7i,he, 7i,hh, 5i,hi, 5i} e s ={ha, 10i,hc, 9i,hb,
7i,hd, 7i,he, 7i,hf, 5i,hh, 5i} — observe a associação entre tokens e pesos ht, w (t)i. Tem-se w (r) = 40,
w (s) = 50, e w (r ∩ s) = 35. Seja sim a similaridade
w(r∩s)
35
Jaccard. Portanto, sim (r, s) = w(r)∪w(s)
= 40+50−35
≈
0.64.
A seguir, as operações de seleção e junção por similaridade baseadas em conjuntos são definidas formalmente.
maior, mas um IDF menor.
O peso de um token t é denotado por w (t). O tamanho de um conjunto r, denotado por |r|, é a quantidade de tokens em r, e o peso de r, denotado por
w (r), é o somatório dos pesos de seus tokens, isto é
w (r) = ∑t∈r w (t).
3.3
Definition 1 (Seleção por Similaridade). Dada uma
coleção de conjuntos CR , um conjunto s, uma função
de similaridade sim e um limiar de corte τ no intervalo [0, 1], uma Seleção por Similaridade sobre CR
usando s, denotado por SS (CR , s), retorna todos conjuntos valorados hr, τ0i, tal que r ∈ Cr e sim (r, s) =
τ0 ≥ τ.
Funções de Similaridade
Uma função de similaridade tem o objetivo de quantificar o grau de semelhança entre os objetos de um
banco de dados. Dois atributos são comparados e,
normalmente um valor entre 0 e 1 é retornado, sendo
que quanto maior o valor, maior o grau de similaridade. Com isso, são selecionadas para análise posterior as palavras que possuem uma semelhança maior
ou igual a um limite (threshold), geralmente um valor entre 0 e 1, que é fornecido pelo usuário (Koudas
et al., 2004; Gravano et al., 2003).
Existe uma variedade de funções de similaridade
na literatura, entre as mais populares estão o Cosseno,
Dice e Jaccard (Cohen, 1998). Além disso, existe
uma outra classe de funções que calculam o grau de
diferença entre dois objetos, mas que podem ser facilmente adaptadas para uso em operações de similaridade. A Distância de Edição (Navarro, 2001) é uma
representante popular dessa classe. No restante do artigo, o termo função de similaridade será usado para
se referir a funções de ambas as classes.
Exemplo 2. Considere a coleção de conjuntos CR =
(r ={hc, 9i,hb, 7i,hd, 7i,he, 7i,hh, 5i,hi, 5i} e t ={ha,
10i,hc, 9i,hb, 7i,hd, 7i,he, 7i,hf, 5i,hh, 5i} ) e o conjunto s ={ha, 10i,hc, 9i,hb, 7i,hd, 7i,he, 7i,hj, 5i} —
observe a associação entre tokens e pesos ht, w (t)i.
Tem-se w (r) = 40, w (t) = 50, w (s) = 45, w (r ∩ s) =
30, w (t ∩ s) = 40 e um τ = 0.7. Seja sim a simiw(r∩s)
laridade Jaccard. Portanto, sim (r, s) = w(r)∪w(s)
=
3.4
Exemplo 3. Considere a coleção de conjuntos CR =
(r ={hc, 9i,hb, 7i,hd, 7i,he, 7i,hh, 5i,hi, 5i} e t ={ha,
10i,hc, 9i,hb, 7i,hd, 7i,he, 7i,hf, 5i,hh, 5i} ) e a coleção de conjuntos Cs = (s ={ha, 10i,hc, 9i,hb, 7i,hd,
7i,he, 7i,hj, 5i} e u ={hc, 9i,hb, 7i,hd, 7i,he, 7i,hh,
5i,hk, 3i} ) — observe a associação entre tokens
e pesos ht, w (t)i. Tem-se w (r) = 40, w (t) = 50,
w (s) = 45, w (u) = 38, w (r ∩ s) = 30, w (r ∩ u) = 35,
w (t ∩ s) = 40, w (t ∩ u) = 35 e um τ = 0.7. Seja
sim a similaridade Jaccard. Portanto, sim (r, s) =
w(r∩s)
w(r∩u)
30
w(r)∪w(s) = 40+45−30 ≈ 0.54, sim (r, u) = w(r)∪w(u) =
w(t∩s)
40
≈ 0.54 e sim (t, s) = w(t)∪w(s)
= 50+45−40
≈
0.72. Neste caso apenas o conjunto (t, s) seria retornado pela seleção, pois o valor de similaridade é
maior que o limiar de corte.
30
40+45−30
Definition 2 (Junção por Similaridade). Dadas duas
coleções de conjuntos CR e CS , uma função de similaridade sim e um limiar de corte τ no intervalo
[0, 1], a Junção por Similaridade entre CR e CS , denotada por JS (CR , CS ), retorna todos os pares de conjuntos valorados h(r, s), τ0i tal que (r, s) ∈ Cr × Cs e
sim (r, s) = τ0 ≥ τ.
Funções de Similaridade baseadas
em Conjuntos
Neste trabalho, é considerada uma família de funções
de similaridade baseadas em conjuntos (ou simplesmente função de similaridade, por brevidade). Dados
dois conjuntos r e s, uma função de similaridade baseada em conjuntos sim (r, s) retorna um valor entre
[0, 1] para representar a similaridade desses conjuntos; um valor maior indica que r e s possuem maior similaridade. As definições das funções Jaccard, Dice e
Cosseno (Sarawagi and Kirpal, 2004; Bayardo et al.,
35
40+38−35
13
≈ 0.81, sim (t, s) =
w(t∩s)
w(t)∪w(s)
=
40
50+45−40
≈
Tabela 2: Filtros baseados em tamanho
w(t∩u)
35
0.72 e sim (t, u) = w(t)∪w(u)
= 50+38−35
≈ 0.66. Neste
caso os conjuntos (t, s) e (r, u) seriam retornados pela
junção, pois o valor de similaridade é maior que o limiar de corte.
É importante observar que todas as funções de
similaridade consideradas medem a interseção entre
dois conjuntos para derivar um valor de similaridade.
Como resultado, predicados do tipo sim (r, s) >= τ,
onde τ é limiar de corte entre [0, 1], podem ser representados de maneira equivalente em termos de um
limite de interseção. Mais formalmente, dados dois
conjuntos r e s, uma função de similaridade sim e um
limiar de corte τ, o limite de interseção entre r e s
para sim, denotado por intersec (r, s), é uma função
que mapeia τ e os pesos de r e s para um valor real tal
que sim (r, s) ≥ τ iff w (r ∩ s) ≥ intersec (r, s).
Tabela 1 mostra o limite de interseção das funções
de similaridade apresentadas anteriormente. Agora,
operações de similaridade podem ser reduzidas ao
problema de encontrar pares de conjuntos r e s cuja
interseção não é menor que intersec (r, s).
3.5
[minsize(r),maxsize(r)]
Jaccard
[τ · |r|, |r|
τ]
Dice
(2−τ)·|r|
]
[ τ·|r|
2·τ ,
τ
Cosseno
]
[τ · |r|, |x|
τ2
rações de edição (Gravano et al., 2001).
Definition 4 (Distância de Edição). A distância de
edição entre duas strings é o número mínimo de operações de edição (isto é, inserções, exclusões e substituições) dos caracteres individuais necessários para
transformar a primeira string na segunda.
Neste trabalho foi utilizada uma variante da distância de edição, baseada em custo unitário para todas
operações de edição.
Por exemplo, considere uma string σ1 = tokens e
uma string σ2 = token. A distância de edição entre
elas é igual a 1, pois é necessário apenas excluir o
caractere ’s’ da primeira string para que as duas sejam
iguais.
A função executa uma junção entre duas tabelas
bases e retorna apenas os pares de tuplas que possuem
uma distância de edição menor ou igual a uma variável definida como k (Gravano et al., 2001).
Filtros baseados em Tamanho
O limite de interseção entre dois conjuntos r e s
em relação à função de similaridade, denotado por
intersec(r, s) foi especificado com maiores detalhes
na Seção 3.4. Onde pode-se descartar todos os pares
onde a interseção é menor do que intersec(r, s).
Com essa definição de interseção é possível formular limites de tamanho para estes conjuntos. Explorando a definição das funções de similaridade
apresentadas na Tabela 1. Derivando limites mais rígidos que permitem a poda imediata de pares de candidatos cujos tamanhos diferem bastante. Os limites
de tamanho do conjunto r em relação a similaridade
são as funções minsize(r) e maxsize(r) (Ribeiro and
Härder, 2011).
Definition 5 (Junção baseada em Distância de Edição). Dada duas tabelas A e B, com atributos textuais A.Ai e B.Bi e um inteiro positivo k, a junção recupera todos os pares de tuplas (t,t 0 ) ∈ AxB, tal que
edit_distance(A.Ai(t), B.Bi(t 0 )) ≤ k
A função pode executar uma seleção em uma tabela base, neste caso são retornadas apenas as tuplas
que possuem uma distância de edição menor ou igual
a k.
Definition 3 (Filtro de Tamanho). Dado um conjunto
r, uma função de similaridade Sim e um threshold τ.
O filtro por tamanho de r relativo a Sim, denotado por
minsize(r) e maxsize(r), mapeiam o τ e o tamanho de
r a um valor real ∀ s. Se a similaridade(r, s) >= τ então minsize(r) ≤ |s| ≤ maxsize(r). Neste caso podese ignorar todos os conjuntos cujo tamanho não caem
dentro do intervalo [minsize(r), maxsize(r)].
Definition 6 (Seleção baseada em Distância de Edição). Dada uma tabela A, com atributo textual A.Ai,
uma string σ para a seleção e um inteiro positivo
k, a seleção recupera todas as tuplas t ∈ A, tal que
edit_distance(σ, A.Ai(t)) ≤ k
Uma forma de melhorar o desempenho da junção
é através da utilizaçao das propriedades dos q-grams.
O objetivo principal neste caso é identificar eficientemente os candidatos do problema. Neste caso são
utilizados dois filtros: tamanho e contagem.
A ideia básica do filtro por contagem é aproveitar a informação transmitida pelos conjuntos dos tokens das strings para determinar se elas estão dentro
de uma distância de edição k. A intuição aqui é que
Estes limites podem ser observados na Tabela 2.
3.6
Função
Função de Similaridade baseada em
Distância de Edição
A distância de edição é uma medida comum para medir a distância entre duas strings baseando-se em ope-
14
prefixo de s1 formado pelos seus dois primeiros elementos tem uma interseção não nula com o prefixo de
s2, isto é, o subconjunto formado pelos dois primeiros
elementos de s2. Portanto, em vez de calcular a interseção entre todos os elementos dos conjuntos originais, podemos inicialmennte ignorar um grande parte
dos tokens e apenas verificar se existe alguma interseção nos prefixos. Pares de conjuntos cuja interseção
dos prefixos for nula podem ser imediatamente descartados. Dessa maneira, é possível filtrar uma parte
considerável do espaço de comparação usando apenas
subconjuntos dos conjuntos originais.
É importante ressaltar que a interseção entre prefixos é uma condição necessária, mas não suficiente
para que dois conjuntos possuam uma determinada interseção. Ou seja, pares de conjuntos com interseção
de prefixos diferente de vazio são considerados candidatos e devem ter sua interseção verificada em uma
fase posterior.
Uma questão relevante é a definição da ordem global dos tokens. Normalmente é utilizado a estatística
DF de forma crescente (Chaudhuri et al., 2006) (relembrando, DF refere-se à frequência de cada token
no banco de dados). A ideia é que, comos prefixos
serão formados pelos tokens mais raros de cada conjunto, então o número de candidatos será reduzido.
O princípio do prefix filtering pode ser estendido
para conjuntos com pesos. Dado um conjunto r com
peso, o prefixo(r) é um subconjunto correspondente
ao prefixo mais curto cujo somatório seja maior que
β. Sendo assim:
as strings estão dentro de uma distância de edição pequena se elas partilham um grande número de tokens
em comum. A seguir esta intuição será definida formalmente.
Considere uma string σ1, e outra σ2, que é obtida pela substituição de um único caractere de σ1.
Então os conjuntos q-grams Gσ1 e Gσ2, diferem por
no máximo q (o comprimento de q-gram). Isto porque os q-grams que não se sobrepõem com o caractere substituído devem ser comuns aos dois conjuntos, e há apenas q q-grams que se sobrepõe ao caractere substituído. Uma observação semelhante vale
para inserções e exclusões de um único caractere.
Em outras palavras, σ1 e σ2 tem de ter pelo menos
(max(|σ1|, |σ2|) + q − 1) − q = max(|σ1|, |σ2|) − 1 qgrams em comum. Quando a distância de edição de
σ1, e σ2 é k, o limite inferior do número correspondentes de q-grams é (Gravano et al., 2001):
Definition 7 (Filtro por contagem). Considere as
string σ1, e σ2 de comprimento |σ1| e |σ2| respectivamente. Se σ1 e σ2 estão a uma distância de edição
k, então a cardinalidade de Gσ1 ∩ Gσ2, ignorandose a informação posicional, deve ser de pelo menos
max(|σ1|, |σ2|) − 1 − (k − 1) · q.
O filtro por tamanho possui uma ideia simples: o
tamanho da string fornece informações úteis para rapidamente descartar strings que não estão dentro da
distância de edição desejada.
Definition 8 (Filtro por tamanho). Duas strings σ1 e
σ2 estão dentro de uma distância de edição k, se seus
comprimentos não diferem em mais de k.
3.7
Definition 10 (Prefix Filtering com Peso). Considere dois conjuntos s1 e s2 com pesos, de modo
que wt(s1 ∩ s2) ≥ α. Se β1 = wt(s1) − α e β2 =
/
wt(s2) − α, então o prefixo β1(s1) ∩ β2(s2) 6= 0.
Prefix Filtering
A intuição do prefix filtering é que quando dois conjuntos tem uma determinada interseção, então também deve existir alguma interseção entre subconjuntos ordenados de acordo com um determinada ordem
global. Para concretizar a intuição considere o caso
em que todos os conjuntos não possuem peso e tem
um tamanho fixo h (Chaudhuri et al., 2006). Com
isso, pode-se observar a seguinte propriedade:
3.8
Design Pattern e Data Mapper
Pattern
Design Pattern descreve uma solução reutilizável para
um problema frequente no desenvolvimento de sistemas orientados a objeto. Um design pattern não é um
código final, mas uma descrição de como resolver determinado problema. Podendo assim ser usado em situações diferentes que envolvam o mesmo problema.
Normalmente o Design Pattern define as relações e as
interações entre as classes e os objetos envolvidos.
Os objetos e o banco de dados têm diferentes maneiras de estruturar os dados, que não combinam entre si. É necessário transferir os dados entre os dois
esquemas, e essas transferências são de extrema complexidade.
O Data Mapper é uma camada de software que
separa os objetos e o banco de dados. A sua responsa-
Definition 9 (Princípio Prefix Filtering). Sendo s1 e
s2 dois conjuntos de tamanho h, ordenados segundo
uma determinada ordem global. Considere r1 um
subconjunto formado pelos primeiros h − k + 1 elementos de s1. Similarmente, considere um conjunto
/
r2. Se |s1 ∩ s2| ≥ k então |r1 ∩ r2| 6= 0.
Por exemplo, considere os conjuntos ordenados segundo uma determinada ordem global s1 =
{1,2,3,4,5} e s2 = {1,3,4,5,6}. É possível observar
que s1 e s2 possuem uma interseção de 4. O chamado
15
de estatísticas. O conceito já foi explicado com maiores detalhes na Seção 3.8.
Para a criação de um objeto SimDataMapper, primeiramente é necessária a escolha de um atributo textual para suporte a operações de similaridade. Este
objeto passa a intermediar operações CRUD subsequentes.
A operação create envolve a criação das tabelas
auxiliares, que estão divididas em quatro estágios diferentes. A relação de tabelas criadas em cada estágio é especificado na Tabela 3. As tabelas até o Estágio 1 são chamdadas tabelas “Base”, ao passo que as
tabelas nos demais estágios podem ser interpretadas
como tabelas de indíces (do inglês index tables). Não
é necessário a criação das tabelas de todos os estágios,
esta escolha depende do tipo de aplicação sobre a qual
o padrão arquitetural será implantado. Mais especificamente, o estágio adequado depende da característica da carga de trabalho imposta pela aplicação ao
SGBD, em particular, da proporção entre operações
de leitura e escrita. Os estágios superiores propiciam
consultas mais rápidas, mas a atualização é mais onerosa; para os estágios inferiores é o inverso: consultas
são mais custosas e atualização é mais rápida. Por
exemplo, se o banco de dados alvo possui um maior
número de operações de atualização (inserção, exclusão ou modificação) do que consultas, pode ser interessante manter as tabelas apenas até o estágio 2.
Caso o banco de dados possua um maior número de
consultas do que operações de edição, o interessante é
manter todas as tabelas, ou seja, dos 4 estágios (Koudas et al., 2007). Neste trabalho, iremos apenas considerar consultas a partir do estágio 2. Detalhes sobre
a criação das tabelas serão apresentados na Seção 5.
Figura 3 apresenta o diagrama de sequência da
operação que constrói um objeto SimDataMapper.
Após a criação, o objeto SimDataMapper recebe a invocação do método de instalação com diversos parâmetros: a tabela, o identificador e o atributo sobre os
quais o suporte para similaridade será instalado; paramêtro para o algoritmo de geração de tokens, isto é, o
tamanho de q e o estágio definindo as tabelas auxiliares a serem criadas. O conjunto de strings associadas
com o atributo selecionado são copiadas para um ResultSet que é posteriormente lido para geração de tokens e população da tabela BaseTokens. As demais
tabelas auxiliares são criadas em seguida, baseado no
estágio informado.
A operação delete tem a função de excluir as tabelas auxiliares quando for solicitado, nos estágios informados.
Em operações retrieve ocorre a conversão em uma
seleção por similaridade (caso a condição da seleção
envolva um atributo que tenha sido escolhido para su-
bilidade é a transferência de dados entre esses mecanismos, mantendo-os isolados um do outro. Ou seja,
não é necessário o conhecimento sobre o esquema do
banco de dados e nem de interface SQL. A principal
função de um Data Mapper é a separação do domínio
e a fonte de dados.
O Data Mapper Pattern é um padrão baseado no
CRUD (Create, Retrieve, Update, Delete) (Fowler,
2002). O CRUD define as operações básicas no contexto de banco de dados, elas operam em objetos que
representam entidades.
4
SIMDATAMAPPER
Esta seção descreve o padrão arquitetural SimDataMapper, que permite que aplicações executem
operações de similaridade sobre SGBDs de maneira
transparente e flexível. Com isso, o SimDataMapper
permite que aplicações incorporem operações de similaridade com pouco esforço de desenvolvimento. O
SimDataMapper suporta todas as funções e operações
de similaridade discutidas anteriormente. A Figura 2
ilustra a organização do SimDataMapper.
Figura 2: SimDataMapper
O componente central é a camada representada
pelo SimDataMapper, um padrão arquitetural baseado no conceito de Data Mappers (Fowler, 2002). Assim como qualquer Data Mapper, o SimDataMapper
é uma camada de software que separa objetos em memória de detalhes a respeito do acesso ao banco de
dados. Diferentemente de Data Mappers comuns, o
SimDataMapper também isola os detalhes de aplicações sobre o processamento de operações de similaridade, encapsulando e gerenciando todo o suporte a
essas operações. Incluindo criação e manutenção de
tabelas auxiliares, execução de consultas de acordo
com a noção de similaridade escolhida e propagação
16
prover de maneira flexível diferentes noções de similaridade. Este fato é de particular importância porque
é amplamente reconhecida a inexistência de uma função de similaridade que seja a melhor em todos os
cenários (Cohen et al., 2003).
Figura 3: Diagrama de sequência da operação que constrói
o suporte a operações de similaridade
Tabela 3: Relação de tabelas por estágios
Estágio
1
2
Figura 4: Diagrama de sequência da operação Retrieve
Tabela(s)
Finalmente, as operações de edição são executadas pela aplicação da operação update, ela é descrita
no diagrama de sequência ilustrado na Figura 5. Primeiramente, é feita uma consulta para verificar se o
limite de operações já foi atingido. Se for o caso, o
mapeamento contendo o conjunto de operações pendentes para cada string é acessado e processado, e as
modificações são propagadas para as tabelas auxiliares. Dependendo do estágio de propagação selecionado.
BaseTokens, BaseDF,
BaseSize
BaseRawWeights,
BaseRawLenght
3
BaseLenght
4
BaseWeights
portar operações por similaridade). Neste caso a seleção depende do tipo de função escolhida (Jaccard,
Dice, Cosseno) e do(s) estágio(s) envolvido(s). A
execução da operação depende de dois parâmetros,
são eles: a string a ser pesquisada e o threshold.
A operação update envolve as operações de edição, neste caso elas são sempre intermediadas pelo
objeto SimDataMapper e envolve a estratégia de propagação de estatísticas. Para isso é necessário informar a quantidade necessária de operações de edição
para disparar a propagação. Neste caso é utilizada a
estratégia de blocagem (Koudas et al., 2007), onde
a propagação de estatísticas é postergada até um um
certo número de operações de modificações identificado previamente. Atualmente as edições são realizadas com o auxílio de um arquivo texto. Em uma nova
versão, as informações serão mantidas armazenadas
no banco de dados.
A operação de seleção por similaridade é ilustrada
na Figura 4. A invocação da operação é repassada
para o objeto SimDataMapper que realiza a seleção
por similaridade através de chamadas JDBC. Como o
conjunto de tabelas auxiliares é independente da função de similaridade, o objeto SimDataMapper pode
Figura 5: Diagrama de sequência da operação Update
5
IMPLEMENTAÇÃO
Esta seção apresenta detalhes sobre a implementação das funções de similaridade discutidas anteriormente em SGBDs. As operações de similaridade são
17
expressadas declarativamente em SQL. Uma observação importante neste contexto é que a maior parte das
funções de similaridade são totalmente especificadas
em SQL, sem o uso de UDFs. Este aspecto é importante porque a otimização de consultas envolvendo
UDFs é notoriamente difícil (Chaudhuri and Shim,
1999). Neste cenário, a implementação das funções
são divididas entre as que são baseadas em conjuntos,
descritas na Seção 5.1 e a função baseada em distância de edição, descrita na Seção 5.2.
5.1
mero de operações é identificado por uma constante
definida como batch. Portanto, se o batch for igual a
100, o arquivo possui 100 operações divididas entre
inserções, exclusões e modificações e as tabelas afetadas dependem do estágio definido.
Para isso, os valores do DF são obtidos da seguinte
maneira:
INSERT INTO BaseDF(tok, DF)
SELECT T.tok, COUNT(T.tid)
FROM BaseTokens T
GROUP BY T.tok
Implementação das Funções de
Similaridade baseadas em
Conjuntos
Para cada token distinto presente na tabela
BaseTokens é realizado uma contagem para identificar a frequência dos tokens na tabela base.
Completando a criação de tabelas do Estágio 1 é
necessário criar a tabela size, ela armazena apenas um
campo que contêm a quantidade de registros da tabela
base. A seguir são apresentados os comandos para sua
criação:
A implementação das funções baseadas em conjuntos
utiliza as tabelas auxiliares dos quatro estágios descritas anteriormente na Seção 4.
O primeiro passo é a escolha de um atributo
textual de uma tabela para suportar seleções e junções por similaridade. Para isso é necessário inicialmente a criação de uma tabela de q-gram tokens:
BaseTokens(tid, tok), onde tid é a chave primária da tabela original e tok armazena os tokens para
cada string.
Os tokens são criados utilizando os delimitadores
no início e no fim e o conceito de bag, apresentados na Seção 3.1. O q utilizado foi igual a 3, pois
observando-se trabalhos anteriores (Gravano et al.,
2001) é o valor que apresenta melhor resultado.
Os pesos IDF associados com cada token são armazenados em uma outra tabela auxiliar. Neste ponto,
surgem questões à respeito da atualização dos pesos
após modificações no banco de dados. Praticamente
toda alteração causará modificação da estatística DF
e portanto o peso IDF de todos tokens envolvidos terá
que ser atualizado, pois depende diretamente do número de tuplas da tabela base. Claramente, este requisito pode ter um impacto negativo de desempenho.
Mais problemático ainda são inserções e exclusões,
que alteram a quantidade de strings consideradas N,
e resultam na atualização do peso IDF de todos os
tokens. Uma maneira direta de mitigar o problema
da atualização das estatísticas é usar uma estratégia
de propagação de estatística. Neste caso os IDFs alterados nas tabelas do estágio 2 serão apenas os que
estão relacionados aos tokens que sofreram esta mudança. Já as tabelas do estágio 3 e 4 terão que ser
reconstruídas totalmente, pois dependem diretamente
da quantidade de strings armazenadas na tabela base.
No trabalho, a estratégia de blocagem utilizada foi
baseada em um arquivo texto, ou seja, um arquivo
possui certo número de operações de edição que são
executadas dependendo do estágio informado. O nú-
INSERT INTO BaseSize(size)
SELECT COUNT(*)
FROM Base
Para lidar com alterações na quantidade de strings,
é necessário isolar o valor de N no cálculo do peso
dos conjuntos. Seja r um conjunto de tokens e df (t)
a estatística DF de um token t, o cálculo do peso pode
ser representado da seguinte forma:
w (r) = ∑ w (t)
t∈r
= ∑ log (N) − log (df (t))
t∈r
= log (N) ∑ 1 − ∑ −log (df (t))
t∈r
t∈r
= log (N) · |r| − ∑ log (df (t)) .
t∈r
Dessa maneira, é possivel armazenar os fatores
s1 = |r| e s2 = ∑t∈r log (df (t)) para cada string:
INSERT INTO BaseRawLength(
SELECT t.tid, COUNT(*) as s1,
SUM(log(d.DF)) as s2
FROM BaseTokens t, BaseDF d
WHERE t.tok = d.tok
GROUP BY t.tid)
O fator s1 armazena a quantidade de tokens que
a string possui e s2 armazena o somatório dos logaritmos dos DFs, ou seja, o somatório dos pesos dos
tokens da string.
18
Além da tabela apresentada anteriormente, é necessário manter outra para completar o conjunto de
tabelas auxiliares pertencentes ao Estágio 2. Essa tabela tem por objetivo associar strings, tokens e estatísticas DF:
Observando as consultas das funções é possível
verificar que o cálculo da similaridade é um pouco
mais complexo. Pois ainda não existe o armazenamento dos pesos dos tokens e nem dos pesos dos conjuntos. Este cálculo é realizado em tempo de execução, o que faz com que o tempo de consulta aumente.
Por isso, caso a carga do banco de dados seja caracterizada mais por consultas do que por inserções,
pode ser vantajoso manter uma tabela com os pesos
dos conjuntos de tokens associados com cada string,
nesse caso é criada a tabela auxiliar do Estágio 3:
INSERT INTO BaseRawWeights
(SELECT t.tid, t.token, d.DF
FROM BaseTokens t, BaseDF d
WHERE t.tok = d.tok)
Neste ponto, é possível realizar seleções por
similaridade baseadas nas funções de similaridade
Jaccard, Dice ou Cosseno. Dada uma string s
usada na condição da seleção, uma tabela de tokens
SearchToken(sid, token) é criada em tempo de
execução, esta tabela possui apenas a finalidade de
armazenar os tokens da string a ser pesquisada. Em
seguida é criada a tabela com os pesos do conjunto de
tokens de s, estes pesos são baseados nas estatísticas
armazenas nas tabelas auxiliares BaseDF e BaseSize.
INSERT INTO BaseLength(
SELECT br.tid,
(log(bs.size)*br.s1 - br.s2)
FROM BaseRawLength br, BaseSize bs)
Com isso é possível realizar novas seleções utilizando a tabela BaseLength. Definindo assim o processamento de consultas para o Estágio 3. A seguir
será apresentada a consulta para a função Jaccard, as
consultas paras as funções Dice e Cosseno estão no
Apêndice A, considere t como threshold.
INSERT INTO SearchLength(
SELECT s.sid, SUM(log(b.size/df.df))
FROM SearchToken s,BaseSize b,BaseDF df
WHERE s.tok = df.tok
GROUP BY s.sid)
[Jaccard]
SELECT br.tid, SUM(log(bs.size/br.df))/
(bl.len + sl.len - SUM(
log(bs.size/br.df))) as JACCARD
FROM BaseLength bl,
BaseSize bs,
BaseRawWeights br,
SearchToken st,
SearchLength sl
WHERE br.tok = st.tok AND
st.sid = sl.sid AND
bl.tid = br.tid AND
bl.len >= t * sl.len AND
bl.len <= bl.len / t
GROUP BY st.sid, br.tid,
bl.len, sl.len
HAVING SUM(log(bs.size/br.df)) >=
(t/(1+t)) * (bl.len + sl.len)
A consulta abaixo define o processamento da consulta de seleção para o Estágio 2 (o Estágio 1 seria operar diretamente sobre as tabelas BaseToken e
BaseDF) para a função Jaccard, as consultas para as
funções Dice e Cosseno estão no Apêndice A, considere t como threshold.
[Jaccard]
SELECT br.tid, SUM(log(bs.size/br.DF))/
((log(bs.size)*brl.s1-brl.s2)
+ sl.len - SUM(log(bs.size/
br.df))) as JACCARD
FROM BaseSize bs,
BaseRawWeights br,
BaseRawLength brl,
SearchToken st,
SearchLength sl
WHERE br.tok = st.tok AND
st.sid = sl.sid AND
brl.tid = br.tid
GROUP BY st.sid, br.tid,
bs.size, brl.s1,
brl.s2, sl.len
HAVING SUM(log(bs.size/br.df)) >=
(t/(1+t)) * ((log(bs.size)*
brl.s1 - brl.s2) + sl.len)
Com a nova tabela não é mais necessário calcular
o peso dos tokens, pois estes já foram pré-processados
e armazenados. Consequentemente ocorre à diminuição no tempo de execução da consulta.
Finalmente, é possível armazenar o peso de cada
token juntamente com o peso do conjunto. Diminuindo assim ainda mais o tempo de execução da consulta. Para isso é necessário criar a última das tabelas
auxiliares, referente ao Estágio 4:
INSERT into BaseWeights(
SELECT bl.tid, br.tok,
19
porque é necessário associar o tamanho das duas tabelas bases e os pesos dos tokens das strings nas duas
relações. A seguir serão apresentadas as criações das
tabelas necessárias. Considere a junção das tabelas
Base e Base2. Para associar o tamanho é necessário
criar uma nova tabela size, contendo a quantidade de
tuplas presentes nas duas bases. A nova tabela de DF
contém a junção dos DFs das duas tabelas bases. Finalmente é necessário a criação de duas novas tabelas
de pesos dos tokens, que são associadas uma a cada
tabela base.
log(bs.size/br.df), bl.len
FROM BaseLength bl, BaseSize bs,
BaseRawWeights br
WHERE bl.tid = br.tid)
Com ela é possível definir o processamento das últimas consultas de seleção, as pertencentes ao Estágio
4. As consultas paras as funções Dice e Cosseno estão
no Apêndice A, considere t como threshold,
[Jaccard]
SELECT bw.tid, SUM(idf)/(bw.len +
sl.len - SUM(idf)) as JACCARD
FROM BaseWeights bw,
SearchToken st,
SearchLength sl
WHERE bw.tok = st.tok AND
st.sid = sl.sid AND
bw.len >= t * sl.len AND
bw.len <= bw.len / t
GROUP BY st.sid, bw.tid,
bw.len, sl.len
HAVING SUM(idf) >= (t/(1+t)) *
(bw.len + sl.len)
[Junção DF]
INSERT INTO BaseBase2DF(tok,df)
SELECT tok, SUM(df)
FROM (SELECT * FROM BaseDF
union all
SELECT * FROM Base2DF)
as combDF
GROUP BY tok)
[Junção Size]
INSERT INTO BaseBase2Size(size)
(SELECT t1Size.count +
t2Size.count as size
FROM (SELECT COUNT(*) FROM Base)
as t1Size(count),
(SELECT COUNT(*) FROM Base2)
as t2Size(count))
A implementação da atualização de estatística
ocorre através da utilização de duas Stored Procedure,
uma para inserção e outra para exclusão. Neste caso
as consultas são realizadas de maneira declarativa e as
atualizações de estatísticas são executadas de maneira
procedural por questões de desempenho. Como já citado anteriormente, a propagação depende do estágio
informado, por isso a Stored Procedure recebe o estágio como parâmetro. Além disso recebe um conjunto
de tokens referentes a string que sofrerá a operação
de edição. Se o estágio informado for o 2, apenas as
strings que possuem os tokens que sofrerão alteração
no peso serão atualizadas. As tabelas dos Estágios 3
e 4 serão reconstruídas totalmente, por isso uma outra estratégia foi definida. Neste caso se o tamanho
do batch for igual a 100, 99 operações serão executas apenas até o estágio 2 e apenas a última operação
de edição executará a Stored Procedure toda, fazendo
com que assim as tabelas do Estágio 3 e 4 sejam reconstruídas apenas uma vez.
Utilizando todas as tabelas auxiliares, podemos
observar que as consultas se tornam mais simples porque os valores dos pesos já estão pré-processados e armazenados. Eliminando a necessidade de calculá-los
em tempo de execução.
Com a apresentação das seleções é possível iniciar a apresentação das junções. Nas funções baseadas em conjuntos, elas são implementadas no Estágio
3. Primeiramente é necessário criar tabelas especificas para serem utilizadas nas junções. Isso acontece
[BaseSearchLenght]
INSERT INTO BaseSearchLength(
SELECT t.tid, SUM(log(b.size/df.df))
FROM BaseTokens t, BaseBase2Size b,
BaseBase2DF df
WHERE t.tok = df.tok
GROUP BY t.tid)
A tabela Base2SearchLenght(tid, len) é criada analogamente a BaseSearchLenght(tid,len)
citada anteriomente. A diferença é que utiliza a tabela de tokens referente a Base2. Depois que as todas
estas tabelas foram criadas, já é possível executar as
junções por similaridade das funções Jaccard, Dice e
Cosseno, considere t como o threshold. As consultas
paras as funções Dice e Cosseno estão no Apêndice
A.
[Jaccard]
SELECT bl1.tid, bl2.tid,
SUM(log(bs.size/df.df))/
(bl1.len + bl2.len SUM(log(bs.size/df.df)))
20
as JACCARD
FROM BaseSearchLength bl1,
BaseTokens t1,
Base2SearchLength bl2,
Base2Tokens t2,
BaseBase2Size bs,
BaseBase2DF df
WHERE df.tok = t1.tok AND
df.tok = t2.tok AND
t1.tid = bl1.tid AND
t2.tid = bl2.tid AND
bl1.len >= t * bl2.len AND
bl1.len <= bl1.len / t
GROUP BY bl1.tid, bl2.tid,
bl1.len, bl2.len
HAVING SUM(log(bs.size/df.df)) >=
(t/(1+t)) * (bl1.len + bl2.len)
Neste ponto é importante observar que os limites
de interseção apresentados na Tabela 1 foram utilizados para as funções Jaccard, Dice e Cosseno em todas as seleções e junções apresentadas anteriormente.
Estes limites foram implementados na cláusula HAVING das consultas.
Uma observação importante é que a complexidade
envolvida no cálculo de interseção também diminui
em relação aos estágios. Pois também utilizam os valores dos pesos dos tokens que já estão armazenados.
Nas seleções dos Estágios 3 e 4 e nas junções é
possível verificar a utilização dos filtros apresentados
na Tabela 2 para diminuir o conjunto de candidatos e
consequentemente diminuir o tempo da consulta. Eles
são implementados na cláusula WHERE em todas
as consultas e são baseados no conceito de minsize
e maxsize.
5.2
int n;
int[][] distance;
m <-- length(s1)+1;
n <-- length(s2)+1;
Para i=1 até m faça
distance[i][1] <-- i-1;
Fim
Para j=1 até n faça
distance[1][j] <-- j-1;
Fim
Para j=1 até n-1 faça
Para i=1 até m-1 faça
Se s1.substring(i)=
s2.substring(j) então
distance[i+1][j+1]<-distance[i][j];
Senão
distance[i+1][j+1] <-minimo(
ditance[i][j+1],
distance[i+1][j]+1;
distance[i][j]);
Fim
Fim
Fim
Return distance[m][n];
}
Para executar a junção, é necessário utilizar duas
tabelas bases e suas tabelas de tokens correspondentes. O código para a execução da função é apresentado a seguir. As tabelas bases são Base e Base2, o
atributo textual habiltado para similaridade é o name,
e o identificador é o id. A função utiliza dois tipos
de filtros: tamanho e contagem. Apenas as tuplas que
possuem uma distância de edição menor ou igual a
k são retornadas nesta consulta e q é o tamanho dos
q-grams (Gravano et al., 2001).
Implementação da Função de
Similaridade baseada na Distância
de Edição
Até agora a implementação apresentada trata apenas
das funções por similaridade baseadas em conjuntos.
A implementação da distância de edição é a mais simples das quatro funções que estão presentes neste trabalho. Ela trabalha apenas com a tabela de tokens e
necessita de uma função para calcular a distância de
edição entre duas strings. Esta função é criada baseada no algoritmo Levenshtein distance. No padrão
SimDataMapper ela foi implementada como UDF.
SELECT Base.id, Base2.id, Base.name,
Base2.name
FROM Base, BaseTokens,
Base2, Base2Tokens
WHERE Base.id = BaseTokens.tid AND
Base2.id = Base2Tokens.tid AND
BaseTokens.tok=Base2Tokens.tok AND
ABS(character_length(Base.name) character_length(Base2.name)) <= k
AND (character_length(Base.name)+
[Algoritmo Edit Distance]
Algoritmo edit_distance(String s1,
String s2, int k){
int m;
21
conjunto:
q -1 > k * q
OR character_length(Base2.name)+
q -1 > k * q )
GROUP BY Base.id, Base2.id, Base.name,
Base2.name
HAVING COUNT(*)>=char_length(Base.name)
- 1 - (k-1)*q AND
COUNT(*)>=char_length(Base2.name)
- 1 - (k-1)*q AND
edit_distance(Base.name,
Base2.name,k)
[Consulta Genérica Prefix Filtering]
INSERT INTO BasePrefixTable
(SELECT tid, tok
FROM
(SELECT br.tid, tok, len,
(SUM(log(bs.size/br.df)) OVER
(PARTITION BY br.tid
ORDER BY br.df asc,tok) log(bs.size/br.df)) as partSum
FROM BaseLength bl,
BaseSize bs,
BaseRawWeights br
WHERE bl.tid = br.tid) as prefTmp
WHERE partSum <= (filtro de tamanho)
Observando o código, é possível verificar que o
Filtro de Tamanho é realizado na condição da cláusula WHERE, na condição que verifica a diferença
de tamanho das duas strings.
O Filtro de Contagem, elimina os pares de atributos que possuem poucos tokens em comum, ele é
executado pelas condições em COUNT(*) da cláusula HAVING.
Algo particularmente interessante é que filtro por
contagem e o filtro por tamanho, podem ser expressos naturalmente por uma expressão SQL no banco
de dados.
5.3
As consultas se diferem apenas pela condição da
cláusula WHERE, que define o filtro de tamanho.
Neste caso para a função Jaccard a condição é definida como WHERE partSum <= len - (len * τ). A
função Dice utiliza a condição como WHERE partSum <= len - ((len * τ)/(2 - τ)) e finalmente para função Cosseno a definição é WHERE partSum <= len
- (len * τ * τ), sendo τ o threshold.
A cláusula OVER é responsável por referenciar
a janela que fará parte da agregação. Neste caso
(SUM(log(bs.size/br.df)). A cláusula PARTITION
BY determina a janela, ela agrupa as tuplas, fazendo
com que todas do mesmo grupo, ou mesma partição receba o resultado da agregação, ou seja PARTITION BY br.tid ORDER BY br.df asc,tok) log(bs.size/br.df)) as partSum.
Na distância de edição, a criação é parecida, mas
utiliza uma funcionalidade a mais, além das cláusulas OVER e PARTITION BY é utilizada a cláusula
RANK que realiza a ordenação dos resultados por
partição.
Implementação do Prefix Filtering
A implementação do prefix filtering exige a criação de
mais duas tabelas BasePrefixTable(tid, tok) e
Base2PrefixTable(tid, tok), uma tabela de prefixo para cada tabela base envolvida na junção. A
definição dos tokens pertencentes ao prefixo para as
funções baseadas em conjunto é diferente para cada
função. Pois se baseiam nos filtros de tamanho apresentados na Tabela 2.
Para definir o Prefix Filtering para a distância de
edição é utilizada pela primeira vez para esta função a
informação dos DFs dos tokens, e para definir o limite
são utilizadas as variáveis k e q.
Para auxiliar na criação do prefixo foram utilizadas Windows Functions (PostgreSQL, 2014), elas são
capazes de realizar cálculos em uma linha com dados
presentes em linhas relacionadas a ela. Neste caso um
grupo de linhas correlacionadas é considerada uma
janela. Window Function foram adicionadas na especificação do SQL em 2003, e hoje são suportadas
por boa parte dos principais SGBDs, entre eles PostgreSQL, DB2 e Oracle.
É importante ressaltar que neste trabalho, o prefix filtering foi implementado de forma declarativa,
diferenciando-se da maioria dos trabalhos anteriores que implementaram o prefix filtering via UDFs
(Chaudhuri et al., 2006).
A seguir será apresentada uma consulta genérica
para a criação do prefixo para as funções baseadas em
[Distância de edição]
INSERT INTO BasePrefixTableED
SELECT tid, tok
FROM (SELECT bt.tid, bt.tok,
rank() OVER (PARTITION BY bt.tid
ORDER BY bd.df asc, bt.tok)
as rank
FROM BaseTokens bt, BaseDF bd, Base
WHERE bt.tok = bd.tok AND
bt.tid = Base.id) as pref
WHERE rank <= q*k+1
Depois que as tabelas foram criadas já é possível
executar as junções com a utilização do Prefix Filtering. Neste caso as consultas serão muito parecidas
com as apresentação na Seção 5.1 e 5.2. Mas será
22
acrescentado na cláusula FROM a geração dos candidatos a participarem da junção. É verificado se duas
tuplas possuem pelo menos um token em comum no
prefix filtering:
A distância de edição estende apenas o Stage1,
pois utiliza apenas as tabelas BaseTokens e BaseDF,
como a função é apenas habilitada a junção por similaridade, sua função retrieve implementa esta funcionalidade. A tabela de DF é utilizada para a criação do
Prefix Filtering.
[Seleção de Candidatos]
(SELECT DISTINCT p1.tid as tid1,
p2.tid as tid2
FROM BasePrefixTable p1,
Base2PrefixTable p2
WHERE p1.tok = p2.tok) as CANDIDATOS
6
Nesta seção serão apresentados os experimentos e
as conclusões envolvidas na análise dos mesmos. Para
a execução dos experimentos foram utilizadas algumas ferramentas no desenvolvimento. A linguagem
utilizada foi Java, que é uma linguagem orientada a
objetos. O banco de dados foi o PostgreSQL, que oferece inúmeros recursos e suporta uma grande parte do
padrão SQL. Para conexão da linguagem Java com o
banco de dados foi utilizado o driver JDBC 9.3. JDBC
é uma API do núcleo do Java que fornece um conjunto
padrão de interfaces para bancos de dados SQL.
O hardware utilizado foi um processador Intel
Core I5 - 4200U CPU @ 1.60 GHz com 6.00 GB de
memória RAM.
E na clásula WHERE é acrescentada a condição CANDIDATOS.tid1=t1.tid And CANDIDATOS.tid2=t2.tid.
5.4
EXPERIMENTOS
Implementação SimDataMapper
A Figura 6 apresenta a estrutura das classes desenvolvidas baseadas no padrão arquitetural. É possível observar que existe uma interface SimDataMapper que
se baseia no CRUD. A classe AbstractSimDataMapper implementa a interface SimDataMapper, implementando os componentes comuns a todos os estágios, por exemplo, a Stored Procedure de atualização
de estatísticas.
Os 4 estágios são representados por 4 classes diferentes, uma representando cada um. Elas estendem a
classe abstrata apresentada anteriormente. Cada uma
é responsável por criar e excluir as tabelas auxiliares envolvidas em cada estágio em particular. Estas
operações são implementadas nos métodos create e
delete.
Nesse conjunto de classes a operação retrieve é
implementada apenas no Stage1, pois é o único que
é comum a todas as funções de similaridade baseadas
em conjuntos. Neste caso, ela é responsável por criar
as tabelas SearchToken e SearchLength . A operação update é responsável pela propagação de estatística. Neste caso é verificado o tipo de edição (inserção, deleção e modificação). Também verifica se
é viável a edição no banco de dados, por exemplo,
se realmente existe a string a ser excluída e invoca a
Stored Procedure dependendo do estágio.
O Stage3 é responsável pela construção das tabelas de prefixo, dependendo do tipo de função selecionada.
As 4 classes dos estágios são estendidas para implementar os estágios diferentes das funções Jaccard,
Dice e Cosseno. Neste caso a operação retrieve é implementada dependendo da função e do estágio envolvido, elas são utilizadas com chamadas JDBC. O
estágio 3 de cada uma dessas funções também é responsável por implementar a junção por similaridade
com e sem prefixo.
6.1
Dados
Os dados utilizados são os do banco de dados online
IMDB (Internet Movie Database). Que possui informações de atores, personagens fictícios, entre outras
informações de filmes, seriados, programas de televisão e video-games. A tabela utilizada como base será
a name, que contêm nome de atrizes e atores.
Amostras são geradas a partir desta tabela name.
Os experimentos serão realizados com duas tabelas
geradas a partir do banco IMDB, as duas contendo 20
mil tuplas. Sendo que a primeira foi criada como uma
amostra da tabela name e a segunda foi gerada utilizando a primeira com erros aleatórios inseridos propositalmente. Esse procedimento de “sujar” os dados
é realizado com o auxílio de uma função implementada em Java.
6.2
Seleções por Similaridade
Inicialmente as tabelas auxiliares apresentadas na Tabela 3 foram criadas utilizando a tabela base do banco
de dados IMDB com 20 mil tuplas. Os tempos envolvidos na criação estão na Tabela 4 e estão divididos
por estágios. É importante observar que o tamanho de
q-gram utilizado foi 3.
Os experimentos de seleção foram realizados nos
4 estágios das funções Jaccard, Dice e Cosseno.
O Estágio 1 realiza apenas a criação das tabelas
23
Figura 6: Digrama de classe SimDataMapper
Tabela 4: Tempo de criação das tabelas auxiliares
Estágio
Tempo (segundos)
1
47,984
2
8,126
3
0,274
4
3,838
Figura 7: Gráfico das seleções do Estágio 2
envolvidas na seleção, neste caso SearchToken e
SearchLenght.
Para realizar a operação de seleção é necessário
informar uma string e um threshold para a busca.
Neste caso foram realizadas 20 seleções para cada
função de similaridade. Após as execuções foi calculada uma média dos tempos de execução. As strings
foram selecionadas aleatoriamente na base de dados.
O threshold utilizado foi de 0.7.
Nas Figuras 7, 8 e 9 observam-se três gráficos referentes aos tempos de seleção. Existe um gráfico
para cada estágio e em cada gráfico é possível observar o tempo referente a cada função de similaridade
baseada em conjunto.
O tempo do Estágio 1 é igual para as três funções,
pois são criadas as mesmas tabelas informadas anteriormente. Neste caso o tempo foi de 0,078 segundos. Observando o Estágio 2 pode-se verificar que os
tempos de seleção estão próximos, eles divergem em
poucos segundos, mas a função Dice se sobressai em
Figura 8: Gráfico das seleções do Estágio 3
relação as outras duas.
Nos Estágios 3 e 4 os tempos de busca caem
abruptamente, isso se deve a dois fatores: o cálculo
menos complexo da similaridade, que diminui con-
24
gura 10, analisando é possível verificar que a Distância de Edição apresentou o melhor desempenho. Isto
se deve ao fato de que os seus filtros apresentaram
melhor desempenho para este conjunto de dados. Dos
400.000.000 pares de tuplas possíveis na junção, apenas 117.238 foram verificadas pelo algoritmo de distância de edição, os outros foram descartados pelos
dois filtros presentes na consulta.
Entre as funções baseadas em conjuntos a que
apresentou melhor desempenho foi a Jaccard. Este
desempenho também se deve ao fato dos filtros serem
mais efetivos, neste caso 59.942.451 pares de tuplas
foram analisados pela função, os outros foram descartados.
A função Dice analisou 77.255.206 pares de tuplas e a função Cosseno analisou 79.490.280 pares de
tuplas. Com isso é possível observar que os filtros
novamente foram efetivos, pois no mínimo conseguiu
filtrar 80% dos candidatos.
Figura 9: Gráfico das seleções do Estágio 4
forme aumenta o número dos estágios, ou seja, a consulta envolvida no Estágio 2 é mais complexa que a
envolvida no Estágio 3. Mas principalmente isto se
deve o fato da utilização dos filtros baseados no conceito de minsize e maxsize, que foi apresentado na Tabela 2, que é possível apenas nestes dois estágios.
No Estágio 3 as consultas se comportam de maneira diferente do 2, neste caso a função que apresenta
melhor desempenho é a Cosseno, seguida da Dice e
depois pela Jaccard, elas também diferem em poucos
segundos. O estágio 4 apresenta novamente uma variação do comportamento das funções, neste caso a que
apresentou melhor desempenho foi novamente a Cosseno, porém ela foi seguida pela função Jaccard e por
último a Dice.
Neste caso podemos concluir que a utilização dos
filtros é de extrema importância para a execução das
seleções por similaridade de uma forma mais eficiente
e que para este conjunto de dados a função Cosseno é
a melhor escolha.
6.3
Figura 10: Gráfico das Junções
6.4
Junções por Similaridade
Prefix Filtering
Para a utilização do Prefix Filtering é necessário utilizar as mesmas tabelas de associação de DFs e tamanho criadas para executar a junção. Além disso, foram criadas as tabelas de prefixo para cada função de
similaridade utilizando as mesmas tabelas bases envolvidas na junção anterior.
Na Figura 11 pode-se observar que os tempos para
criar as duas tabelas de prefixo variam pouco entre
as funções de similaridade. A que apresenta menor
tempo é à distância de edição e a de maior tempo é a
função Dice.
Os tempos da junção utilizando o prefixo são apresentados na Figura 12. Comparando o tempo de junção com a utilização do prefixo e sem a utilização é
visível a diminuição drástica do tempo de execução da
consulta.Isto pode ser verificado na Figura 13, onde é
possível observar a diferença entre os tempos de exe-
A operação de junção foi realizada para as quatro funções: Distância de edição, Jaccard, Dice e Cosseno.
Foi utilizada a mesma tabela base utilizada nas seleções e as tabelas auxiliares que foram criadas. Neste
caso também foi utilizada a tabela “suja”, com erros
inseridos aleatoriamente, e suas tabelas auxiliares correspondentes.
Primeiramente foi necessário criar as tabelas auxiliares que englobam os DFs e tamanhos das duas
tabelas bases para as funções baseadas em conjunto,
que foi apresentado na Seção 5.1. O tempo para a criação desse conjunto de tabelas foi de 7,951 segundos.
Na distância de edição foi utilizado k=3. E nas
funções baseadas em conjunto foi utilizado um threshold de 0.7.
Os tempos de junção podem ser verificados na Fi-
25
Verificando a quantidade de pares de candidatos
que foram descartados pelo prefixo podemos entender a diferença no tempo de execução quando não é
utilizado o prefixo. Dos 400.000.000 pares de candidatos, apenas 1.351.357 pares foram avaliados pela
função Dice, 1.937.080 pares pela função Cosseno,
1.157.306 pares pela função Jaccard e finalmente
46.202 pares pela função Distância de Edição. Como
resultado direto da redução drástica do número de
candidatos, o tempo de execução de todas funções é
agora substancialmente menor. A função Dice agora
é 74x mais rápida, a função Cosseno é 115x mais rápida, a função Jaccard é 40x mais rápida e a distância
de edição é 2x mais rápida.
A distância de edição ainda produz um número
menor de candidatos em comparação com as demais
funções, entrentato, a diferença agora é bem menor.
Por exemplo, enquanto que sem o emprego do prefix filtering a quantidade de candidatos para a distância de edição é aproximadamente 511x menor do
que para Jaccard, usando o prefixo esta proporção cai
para 25x. Com isso, a maior complexidade da UDF
usada para calcular a distância passa a representar o
fator preponderante. De fato, o tempo de execução
para a distância de edição é agora significativa maior
em comparação com as demais funções de similaridade. Um fato interessante é que agora a função Jaccard, mesmo apresentando um número menor de candidatos, é (moderadamente) mais lenta que as funções
Dice e Cosseno. Ainda não foi possível identificar o
motivo preciso deste resultado.
Pode-se concluir que a utilização do prefixo é de
extrema importância para uma junção rápida quando
estão envolvidos muitos pares de candidatos. O ganho
de desempenho é evidente.
Figura 11: Criação das tabelas de prefixo
cução das junções com e sem prefixo. Isso demonstra
como a abordagem utilizando o Prefix Filtering diminui notoriamente os pares de candidatos.
Figura 12: Tempo de execução da junção com Prefix Filtering
6.5
Atualizações de estatísticas
Os experimentos da propagação de estatísticas foram
realizados com batches de 1, 10 e 100 tuplas. Ou
seja, utilizando a técnica de blocagem, onde as operações de edição são postergadas até um número prédefinido de operações. Neste caso os batches representam o número de operações que serão armazenadas. Quando este número for atingido, a propagação
é iniciada e são executadas todas as operações pendentes. Neste trabalho, com a ajuda de uma classe
em Java, foi criado um arquivo auxiliar para gerar as
operações de edição, para isto foram utilizadas as seguintes regras:
Figura 13: Comparação do tempo de execução com e sem
prefixo
Comparando a execução entre as quatro funções
utilizando o prefixo, a que apresenta o melhor desempenho é a Dice, seguida pela Cosseno, pela Jaccard e
por último a Distância de Edição. Isto se deve ao fato
do número de candidatos filtrados.
• 50% inserção
• 35% deleção
• 15% modificação
26
tipo de banco de dados. O tamanho do q-grams e o do
threshold.
Esse arquivo foi utilizado para realizar as operações de edição. Os experimentos foram efetuados nos
4 estágios de propagação diferentes e os resultados
podem ser observados na Figura 14.
Analisando, é possível observar que quanto maior
o tamanho do batch, menor é o tempo por operação de
edição. Por exemplo, o tempo do batch de 100 para
o Estágio 4 foi de 58,571 segundos, ou seja, o tempo
médio de cada operação foi de 0,58 segundos, já o
batch de 10 para o Estágio 4 apresentou o tempo de
10,647 segundos, um tempo médio de 1,06 segundos.
Porém a escolha do tamanho do batch depende da
aplicação, pois se for uma base de dados que possua
um número pequeno de inserções, exclusões e modificações pode não ser interessante utilizar um batch de
100.
Figura 14: Gráfico da propagação de estatística
7
CONCLUSÃO
Este artigo apresentou o padrão arquitetural SimDataMapper, que tem por objetivo incorporar uma
variedade de funções de similaridade em um único
ambiente de aplicação, separando a lógica de domínio e o acesso ao banco de dados, de maneira simples
e flexível.
Analisando os experimentos é possível observar
que a abordagem proposta é flexível e permite a execução eficiente de uma variedade de operações similaridade, incluindo consultas baseadas em seleções e
junções e operações de atualização dos dados.
Trabalhos futuros visam desenvolver uma aplicação gráfica, onde será possível habilitar a similaridade
em um atributo textual e prover todas as funcionalidades apresentadas neste artigo. E utilizar uma análise
estatística para definir parâmetros importantes na utilização do padrão arquitetural. Como qual função de
similaridade apresenta o melhor resultado para qual
27
REFERÊNCIAS BIBLIOGRÁFICAS
Navarro, G. (2001).
A guided tour to approximate
string matching. ACM computing surveys (CSUR),
33(1):31–88.
PostgreSQL (2014). Online manual documentation.
Ribeiro, L. A. and Härder, T. (2007). Embedding similarity
joins into native xml databases. In Anais do XXII Simpósio Brasileiro de Banco de Dados, pages 285–299.
Ribeiro, L. A. and Härder, T. (2011). Generalizing prefix
filtering to improve set similarity joins. Information
Systems, 36(1):62–78.
Ribeiro, L. A., Härder, T., and Pimenta, F. S. (2009). A
cluster-based approach to xml similarity joins. In
Proc. of the Intl. Database Engineering and Applications Symposium (IDEAS 2009), pages 182–193.
Sarawagi, S. and Kirpal, A. (2004). Efficient set joins on
similarity predicates. In Proc. of the ACM SIGMOD
Intl. Conf. on Management of Data (SIGMOD 2004),
pages 743–754.
Ukkonen, E. (1992). Approximate string matching with qgrams and maximal matches. Theoretical Computer
Science, 92(1):191–211.
Wang, J., Li, G., and Feng, J. (2012). Can we beat the prefix
filtering?: an adaptive framework for similarity join
and search. In Proc. of the ACM SIGMOD Intl. Conf.
on Management of Data (SIGMOD 2012), pages 85–
96.
Xiao, C., Wang, W., Lin, X., and Yu, J. X. (2008). Efficient
similarity joins for near duplicate detection. In Proc.
of the 17th Intl. Conf. on World Wide Web (WWW
2008), pages 131–140.
Augsten, N., Miraglia, A., Neumann, T., and Kemper, A.
(2014). On-the-fly token similarity joins in relational databases. In Proc. of the ACM SIGMOD Intl.
Conf. on Management of Data (SIGMOD 2014), pages 1495–1506.
Baeza-Yates, R. A. and Ribeiro-Neto, B. A. (2011). Modern Information Retrieval - the concepts and technology behind search, Second edition. Pearson Education Ltd., Harlow, England.
Bayardo, R. J., Ma, Y., and Srikant, R. (2007). Scaling up
all pairs similarity search. In Proc. of the 16th Intl.
Conf. on World Wide Web (WWW 2007), pages 131–
140.
Chandel, A., Hassanzadeh, O., Koudas, N., Sadoghi, M.,
and Srivastava, D. (2007). Benchmarking declarative
approximate selection predicates. In Proc. of the ACM
SIGMOD Intl. Conf. on Management of Data, pages
353–364.
Chaudhuri, S., Ganti, V., and Kaushik, R. (2006). A primitive operator for similarity joins in data cleaning.
In Proc. of the 22nd Intl. Conf. on Data Engineering
(ICDE 2006), page 5.
Chaudhuri, S. and Shim, K. (1999). Optimization of queries
with user-defined predicates. ACM Transactions on
Database Systems (TODS), 24(2):177–228.
Cohen, W. W. (1998). Integration of heterogeneous databases without common domains using queries based
on textual similarity. In ACM SIGMOD Record, volume 27, pages 201–212. ACM.
Cohen, W. W., Ravikumar, P. D., and Fienberg, S. E. (2003).
A comparison of string distance metrics for namematching tasks. In Proc. of IJCAI-03 Workshop on
Information Integration on the Web (IIWeb-03), pages
73–78.
Fowler, M. (2002). Patterns of enterprise application architecture. Addison-Wesley Longman Publishing Co.,
Inc.
Gravano, L., Ipeirotis, P. G., Jagadish, H. V., Koudas, N.,
Muthukrishnan, S., and Srivastava, D. (2001). Approximate string joins in a database (almost) for free. In
Proc. of 27th Intl. Conf. on Very Large Data Bases,
pages 491–500.
Gravano, L., Ipeirotis, P. G., Koudas, N., and Srivastava, D.
(2003). Text joins in an rdbms for web data integration. In Proc. of the 12th Intl. World Wide Web Conf.,
pages 90–101.
Jr., C. T., Traina, A. J. M., Vieira, M. R., Arantes, A. S., and
Faloutsos, C. (2006). Efficient processing of complex
similarity queries in rdbms through query rewriting.
In CIKM, pages 4–13.
Koudas, N., Marathe, A., and Srivastava, D. (2004). Flexible string matching against large databases in practice.
In Proc. of the 13th Intl. Conf. on Very Large Data Bases, pages 1078–1086.
Koudas, N., Marathe, A., and Srivastava, D. (2007). Propagating updates in spider. In Proc. of the 23rd Intl.
Conf. on Data Engineering, pages 1146–1153.
28
A
EXPRESSÕES SQL PARA DICE
E COSSENO
as DICE
FROM BaseLength bl,
BaseSize bs,
BaseRawWeights br,
SearchToken st,
SearchLength sl
WHERE br.tok = st.tok AND
st.sid = sl.sid AND
bl.tid = br.tid AND
bl.len >= (t * sl.len)/(2-t) AND
bl.len <= ((2-t)*bl.len) / t
GROUP BY st.sid, br.tid,
bl.len, sl.len
HAVING SUM(log(bs.size/br.df)) >=
(t * (bl.len + sl.len))/2
Nesta seção serão apresentadas as consultas SQL
para a execução das seleções dos estágios 2, 3 e 4
para as funções Dice e Cosseno. E as junções para as
mesmas funções.
Consultas de seleção para estágio 2:
[Dice]
SELECT br.tid,(2*SUM(log(bs.size/br.df)))/
((log(bs.size)*brl.s1-brl.s2)+sl.len)
as DICE
FROM BaseSize bs,
BaseRawWeights br,
BaseRawLength brl,
SearchToken st,
SearchLength sl
WHERE br.tok = st.tok AND
st.sid = sl.sid AND
brl.tid = br.tid
GROUP BY st.sid, br.tid,
bs.size, brl.s1,
brl.s2, sl.len
HAVING SUM(log(bs.size/br.df)) >=
(t * ((log(bs.size)*brl.s1 brl.s2) + sl.len))/2
[Cosseno]
SELECT br.tid, (SUM(log(bs.size/br.df)))/
sqrt(bl.len * sl.len) as COSSENO
FROM BaseLength bl,
BaseSize bs,
BaseRawWeights br,
SearchToken st,
SearchLength sl
WHERE br.tok = st.tok AND
st.sid = sl.sid AND
bl.tid = br.tid AND
bl.len >= power(t, 2)*sl.len AND
bl.len <= sl.len/power(t, 2)
GROUP BY st.sid, br.tid,
bl.len, sl.len
HAVING SUM(log(bs.size/br.df)) >=
t * sqrt(bl.len * sl.len)
[Cosseno]
SELECT br.tid, (SUM(log(bs.size/br.df)))/
sqrt((log(bs.size)*brl.s1-brl.s2)
*sl.len) as COSSENO
FROM BaseSize bs,
BaseRawWeights br,
BaseRawLength brl,
SearchToken st,
SearchLength sl
WHERE br.tok = st.tok AND
st.sid = sl.sid AND
brl.tid = br.tid
GROUP BY st.sid, br.tid,
bs.size, brl.s1,
brl.s2, sl.len
HAVING SUM(log(bs.size/br.df)) >=
t * sqrt((log(bs.size)*brl.s1
- brl.s2)* sl.len)
Consultas de seleção para o estágio 4:
[Dice]
SELECT bw.tid, (2 * sum(idf))/
(bw.len + sl.len) as DICE
FROM BaseWeights bw,
SearchToken st,
SearchLength sl
WHERE bw.tok = st.tok AND
st.sid = sl.sid AND
bw.len >= (t * sl.len)/(2-t) AND
bw.len <= ((2-t)*bw.len) / t
GROUP BY st.sid, bw.tid,
bw.len, sl.len
HAVING SUM(idf)>=(t * (bw.len + sl.len))/2
Consultas de seleção para o estágio 3:
[Dice]
SELECT br.tid, (2 * SUM(log(bs.size/
br.df)))/(bl.len + sl.len)
[Cosseno]
SELECT st.sid, bw.tid, (sum(idf))/
29
sqrt(bw.len * sl.len) as COSSENO
FROM BaseWeights bw,
SearchToken st,
SearchLength sl
WHERE bw.tok = st.tok AND
st.sid = sl.sid AND
bw.len >= power(t, 2) * sl.len AND
bw.len <= sl.len/power(t, 2)
GROUP BY st.sid, bw.tid,
bw.len, sl.len
HAVING SUM(idf) >= t * sqrt(bw.len
* sl.len)
Consultas para executar as junções:
[Dice]
SELECT bl1.tid, bl2.tid,
(2 * SUM(log(bs.size/df.df)))/
(bl1.len + bl2.len) as DICE
FROM BaseSearchLength bl1,
BaseTokens t1,
Base2SearchLength bl2,
BaseTokens t2,
BaseBase2Size bs,
BaseBase2DF df
WHERE df.tok = t1.tok AND
df.tok = t2.tok AND
t1.tid = bl1.tid AND
t2.tid = bl2.tid AND
bl1.len >= (t * bl2.len)/(2-t) AND
bl1.len <= ((2-t)*bl1.len) / t
GROUP BY bl1.tid, bl2.tid,
bl1.len, bl2.len
HAVING SUM(log(bs.size/df.df)) >=
(t * (bl1.len + bl2.len))/2
[Cosseno]
SELECT bl1.tid, bl2.tid,
(SUM(log(bs.size/df.df)))/
sqrt(bl1.len * bl2.len)
as COSINE
FROM BaseSearchLength bl1, BaseTokens t1,
Base2SearchLength bl2, Base2Tokens t2,
BaseBase2Size bs, BaseBase2DF df
WHERE df.tok = t1.tok AND df.tok = t2.tok
AND t1.tid = bl1.tid
AND t2.tid = bl2.tid
AND bl1.len >= power(t, 2)*bl2.len
AND bl1.len <= bl2.len/power(t, 2)
GROUP BY bl1.tid, bl2.tid, bl1.len,
bl2.len
HAVING SUM(log(bs.size/df.df)) >=
t * sqrt(bl1.len * bl2.len)
30
Download