CAPÍTULO 2 – O ALGORITMO APRIORI
2.2 Descrição do Algoritmo Apriori
Com vistas a organizar sua apresentação e padronizar a sua descrição, o algoritmo Apriori discutido nesta seção, tem por input (a) uma base de dados (BD) contendo um conjunto de transações (cada uma delas tratada como um itemset; no que segue ambos os termos são usados como referência a um mesmo conceito); (b) um conjunto I contendo todos os possíveis itens de dados disponíveis no domínio de aplicação considerado e (c) um valor numérico (freq) a ser usado para a caracterização de um item frequente. É importante lembrar que o Apriori não faz uso do conceito de sequência, que é empregado, por exemplo, pelo MEMISP.
Basicamente, o foco do algoritmo Apriori é a busca, em uma base de dados que lhe é informada, de conjuntos de itemsets que sejam frequentes para, posteriormente, gerar as chamadas regras de associação. Regras de associação nada mais são que regras que associam a presença de determinados itens (em uma transação), à presença de outros.
Um fluxograma do algoritmo Apriori em alto nível é apresentado na Figura 2.1 e nele podem ser identificados três procedimentos principais, a saber:
itemsets_frequentes_uni, gera_itemsets_candidatos e valida_candidatos_frequentes.
O procedimento itemsets_frequentes_uni é invocado apenas uma vez logo no início do processamento ( passo k = 1 ); inicialmente determina o suporte de cada item de I, com base nas transações armazenadas na BD e, então, constrói L1, que
42
conterá apenas aqueles itens com suporte maior que o valor freq, fornecido como
input ao algoritmo. Apesar de não ter sido tratado no documento em que foi proposto,
neste trabalho a geração de L1 é feita de maneira tal que, ao final da geração, os itens participantes de L1 estão em ordem lexicográfica.
O algoritmo Apriori entra então em um ciclo de repetição em que, primeiro incrementa o contador do passo e, então, faz chamadas aos dois procedimentos i.e.,
o gera_itemsets_candidatos e, então, o valida_candidatos_frequentes,
permanecendo no ciclo até que o procedimento valida_candidatos_frequentes gere um conjunto vazio de tais candidatos.
O procedimento gera_itemsets_candidatos expande o conjunto de candidatos (itemsets) frequentes gerado no passo anterior, com tamanho k−1, em 1 item, gerando assim um conjunto de itemsets candidatos (a serem frequentes), cada um deles com k itens. Tais itemsets são então promovidos (ou não) a itemsets frequentes pelo procedimento valida_candidatos_frequentes, dependendo ou não do valor do suporte de cada um deles. Aqueles que forem promovidos formam então o conjunto Lk que, se não for vazio, provoca o reinício do ciclo de chamadas.
O algoritmo Apriori (AGRAWAL; SRIKANT, 1994), apresentado em Algoritmo 2.1, é descrito na notação adotada nesta dissertação. É importante observar que o procedimento valida_candidatos_frequentes, parte do ciclo repetitivo interno ao algoritmo, faz uma varredura na BD.
Uma a uma, todas as transações que compõem a BD são selecionadas e o valor de suporte dos candidatos que são encontrados nelas, é incrementado. Dessa forma, após a análise de todos os candidatos gerados, é possível identificar aqueles frequentes a partir de seus valores de suporte.
Figura 2.1 –Fluxograma alto nível do algoritmo Apriori. Lk = ∅ Input: BD, I, freq L0 ← itemsets_frequentes_uni(BD,freq) k ← 1; All_L ← ∅ Ck ← gera_itemsets_candidatos(Lk-1) Lk ← valida_candidatos_frequentes(Ck, BD, freq) k ← k +1 S N output: All_L All_L ←All_L ∪ Lk
44
Algoritmo 2.1 – Pseudocódigo do algoritmo Apriori com geração de regras.
O Algoritmo 2.2 mostra o procedimento gera_itemsets_candidatos descrito em pseudocódigo. Levando em conta o conjunto de itemsets frequentes construído no passo anterior, o procedimento busca exaustivamente por pares de itemsets que possam ser aglutinados em um único itemset, cujo tamanho será exatamente 1 a mais do que o tamanho dos pares considerados.
Procedure Apriori(BD, freq) Entrada: BD = { t1,t2,...t|BD|}
freq: {limite mínimo de frequência}
Saída: All_L = {L1,L2,...Lk} {conjunto com todos itemsets frequentes de BD} R {conjunto de regras de associação}
1. begin 2. All_L ←∅ 3. L1← itemsets_frequentes_uni(BD,freq) 4. k ← 2 5. while (Lk-1≠∅) do 6. begin
7. {is1,is2,...,isM} ← gera_itemsets_candidatos(Lk-1) {1a. poda é feita pelo procedimento} 8. {a seguir, o suporte de cada um dos M itemsets candidatos é determinado}
9. for i ← 1 to |BD| do {para cada transação da BD} 10. begin
11. for j ← 1 to M do { para cada itemset candidato} 12. begin
13. if isj⊆ ti then incrementa_counter(isj) 14. end
15. end
16. {a seguir é construído Lk, com itemsets cujo counter for maior que min_sup}
17. Lk← ∅
18. for j ← 1 to M do {para cada itemset candidato} 19. begin
20. if counter(isj) > freq then Lk← Lk∪ {isj} {2a. poda é feita
21. {procedimentovalida_candidatos_frequentes }
22. All_L← All_L ∪ Lk 23. k ← k +1
24. end
25. end
26. R ← gera_regras(All_L,R) {ver Algoritmo 2.4} 27. return (All_L, R)
Algoritmo 2.2 – Pseudocódigo do procedimento gera_itemsets_candidatos.
A condição para que dois itemsets possam ser aglutinados é a de que ambos sejam exatamente iguais até o penúltimo de seus itens e cujos últimos itens são tais que o último do primeiro itemset é lexicograficamente menor que o último do segundo itemset sendo considerado. Tal condição é formalizada a seguir, na Definição 2.1.
Definição 2.1 Considere dois itemsets is1 = (i1, i2, ..., ik-1) e is2 = (j1, j2, ..., jk-1) tal que |is1| = |is2| = k–1 (i.e., ambos possuem k−1 itens). Um itemset is3, |is3| = k, pode ser gerado a partir da extensão de is1, com o último item de is2 se satisfizerem as duas condições a seguir: (1) ambos possuem seus k–2 primeiros itens iguais e (2) o último item de is1 é lexicograficamente menor que o último item de is2, ou seja, i1 = j1, i2 = j2, ..., ik−2 = jk−2, ik−1 < jk−1. O itemset gerado será pois is3 = (i1 = j1, i2 = j2, ..., ik−2 = jk−2,
ik−1, jk−1).
Procedure gera_itemsets_candidatos(Lk-1)
Entrada: Lk-1 {Conjunto de itemsets frequentes da iteração k−1 do ciclo interno}
Saída: Ck{Conjunto com todos os candidatos a itemsets frequentes}
1.begin 2. Ck ←∅
3. for i ← 1 to |Lk-1| − 1 do
4. for j ← 1 to |Lk-1| do 5. begin
6. if can_join(isi,isj,k−1) then new_is ← append(isi,last_item(isj))
7. Ck ← Ck ∪ new_is 8. end
9. return Ck
10.end
Procedure can_join(is1,is2,k)
Entrada: is1, is2{itemsets para serem comparados}
k = |is1| = |is2|
Saída: true ou false
1.begin
2. for i ← 1 to k − 1 do 3. begin
4. if is1[i] ≠ is2[i] then return false
5. end
6. if is1[k] ≥ is2[k] then return false
7. else return true 8.end
46
O procedimento gera_itemsets_candidatos (Algoritmo 2.2) é a descrição, em pseudocódigo, da operação join, seguida pela operação prune, ambas descritas na referência (AGRAWAL; SRIKANT, 1994), Como comentado em tal referência, a satisfação da condição is1[k] < is2[k] (que permite o procedimento can_join retornar com valor true) garante que o procedimento gera_itemsets_candidatos não gerará
itemsets duplicados.
Uma vez gerado o conjunto dos candidatos a itemsets frequentes, cada um dos candidatos é validado, para confirmar se é, efetivamente, um itemset frequente. O procedimento valida_candidatos_frequentes, descrito no Algoritmo 2.3, implementa a tarefa de validação. Antes, entretanto, para tornar o processo mais inteligível, é detalhado o exemplo apresentado em (AGRAWAL; SRIKANT, 1994).
Considerando o conjunto de itens I = {1,2,3,4,5}, suponha que L3 = {(1,2,3), (1,2,4), (1,3,4), (1,3,5), (2,3,4)}. A execução do gera_itensets_candidatos(L3) para a geração do conjunto de candidatos contendo 4 itens, como descrito na Definição 2.1, produz o conjunto C4 = {(1,2,3,4),(1,3,4,5)}. Na sequência o procedimento
valida_candidatos_frequentes avalia cada itemset de C4, com vistas a gerar o
conjunto daqueles que forem efetivamente frequentes, isto é, elementos do conjunto L4.
No exemplo em questão o valida_candidatos_frequentes: (1) irá manter o
itemset (1,2,3,4), uma vez que os (k−1)-itemsets (i.e., com 3 itens) dele derivados, a
saber, (1,2,3), (1,2,4), (1,3,4) e (2,3,4), estão todos em L3 (ou seja, todos são frequentes) e (2) irá remover o itemset (1,3,4,5), uma vez que tal itemset, que tem como 3-itemsets: (1,3,4), (1,3,5), (1,4,5) e (3,4,5), tem dois deles, o (1,4,5) e o (3,4,5), que não estão em L3.
Algoritmos baseados no Apriori, como por exemplo o GSP, possuem uma abordagem muito próxima daquela usada pelo Apriori, quando da geração de candidatos a itemsets frequentes. A partir de itens (unitários) tais algoritmos geram
itemsets candidatos que, por sua vez, servem de base para a geração de novos
candidatos, a cada iteração do algoritmo. Tais algoritmos geralmente diferem na forma como os candidatos a itemsets frequentes são avaliados, com o objetivo de confirmar se são efetivamente frequentes ou, então, diferem no número de varreduras feitas da BD, para a execução do algoritmo.
Algoritmo 2.3 – Pseudocódigo do procedimento valida_candidatos_frequentes.
Os itemsets pertencentes a Ck são armazenados em uma estrutura de dados denominada árvore-hash, discutida na próxima seção.