quarta-feira, 18 de fevereiro de 2015

No post anterior trabalhamos com as regras de associação no R - Regras de associação - Algoritmo apriori. Hoje vamos mostrar a implantação do algoritmo de extração de regras no Python. O que facilita o trabalho no Python é o módulo Itertools, que permite a criação de associações entre elementos de um modo mais prático. Também vamos utilizar o módulo Counter, já visto no post Python - Como contar valores distintos de uma lista, para fazermos a contagem dos conjuntos de regras.

Começamos importando os módulos e definindo os valores de suporte e confiança para 50%.

 from collections import Counter  
 import itertools  
 import sys  
 #Parâmetros de suporte e confiança  
 s = 0.5  
 c = 0.5  

Em seguida, criamos um dicionário de transações para servir como exemplo em nossa aplicação:

 #Conjunto de transações  
 transacoes = {     1: {"Cerveja", "Amendoim", "Laranja"},  
                     2: {"Cerveja", "Cafe", "Laranja", "Amendoim"},  
                     3: {"Cerveja", "Laranja", "Ovos"},  
                     4: {"Cerveja", "Amendoim", "Ovos", "Leite"},  
                     5: {"Cafe", "Laranja", "Ovos", "Leite"},  
                     6: {"Cafe", "Laranja", "Ovos", "Leite"},  
                     7: {"Laranja", "Cafe", "Cerveja", "Ovos"},  
                     8: {"Amendoim", "Cafe", "Cerveja", "Ovos"},  
                     9: {"Amendoim", "Laranja", "Cerveja", "Ovos"},  
                     10: {"Amendoim", "Cafe", "Cerveja", "Ovos"}  
                     }  

Agora, "quebramos" cada transação item por item, lendo os valores dos pares "chave-valor" do dicionário de transações. Iteramos cada itemset presente em transacoes.values().

 #Faz a leitura do dicionário de transações  
 #Armazena cada item no vetor items  
 items = []   
 for itemsets in transacoes.values():  
   for item in itemsets:  
     items.append(item)  
 items = set(items)  

No trecho de código a seguir temos algoritmo que cria as regras de associação. A função frequentItems receberá como parâmetros nosso vetor de items (items), o dicionário de transações (trans), a quantidade de items por conjunto (n) e o suporte (s). O módulo itertools é utilizado para realizar todas a n-combinações (n) dos items.

 ### Cria as regras de associação ##############################  
 def frequentItems(items, trans, n, s):  
   itemsets = set(itertools.combinations(items, n))  
   itemTransactions = []  
   for i in itemsets:  
     for k,v in transacoes.items():  
       if set(v).intersection(set(i)) == set(i):  
         itemTransactions.append(i)  
   ret = []  
   for k,v in sorted(Counter(itemTransactions).items()):  
     if v >= s * len(trans):  
       ret.append([k, v])  
   return(dict(ret))  
 ###############################################################  

Na sequência, vamos imprimir os conjuntos de items (1 a 1, 2 a 2 e 3 a 3) mais frequentes das transações do exemplo.

 #Mostra os resultados  
 print("1-itemsets mais frequentes:")  
 print(frequentItems(items, transacoes, 1, s))  
 print  
 print("2-itemsets mais frequentes:")  
 print(frequentItems(items, transacoes, 2, s))  
 print  
 print("3-itemsets mais frequentes:")  
 print(frequentItems(items, transacoes, 3, s))  
 print  

Veja que temos a saída abaixo:


Por fim, vamos mostrar as regras que possuam suporte e confiança superiores aos 50% estabelecidos como parâmetros no início do código.

 #Imprime as regras de associação  
 #De acordo com o suporte e confiança  
 print("Regras de associacao com suporte")  
 print("e confianca maiores que 50%")  
 f2 = frequentItems(items, transacoes, 2, s)  
 k2 = [k for k in f2.keys()]  
 v2 = [v for v in f2.values()]  
 f1 = frequentItems(items, transacoes, 1, s)  
 k1 = [k[0] for k in f1.keys()]  
 v1 = [v  for v in f1.values()]  
 for i in range(len(k2)):  
   i1 = k2[i][0]  
   i2 = k2[i][1]  
   for j in range(len(k1)):  
     if k1[j] == i1:  
       confidence = v2[i]/v1[j]  
   if v2[i] >= s * len(transacoes) and confidence >= c:  
     print("{0:<6} -> {1:<6}: ({2},{3})".format(i1, i2,str(v2[i]),confidence))  
   i1 = k2[i][1]  
   i2 = k2[i][0]  
   for j in range(len(k1)):  
     if k1[j] == i1:  
       confidence = v2[i]/v1[j]  
   if v2[i] >= s * len(transacoes) and confidence >= c:  
     print("{0:<6} -> {1:<6}: ({2},{3})".format(i1, i2,str(v2[i]),confidence))  
     print  

E como saída temos a regra Amendoim -> Cerveja, que aparece em 6 das 10 transações (suporte de 60%) e possui confiança de 100%, já que todas as vezes que apareceu "Amendoim", o item Cerveja também aparece.


Apenas para ilustração, vamos estabelecer um suporte de 25% e manter a confiança em 50%.


Repare que nosso resultado é totalmente diferente e, além da regra Amendoim -> Cerveja, temos também a regra Leite -> Ovos obedecendo os critérios de suporte e confiança estabelecidos.

O código apriori.py está disponível no GitHub Arte dos Dados.

Um abraço e até o próximo post!

0 comentários:

Postar um comentário