2. Cosa è FPGrowth?
Come funziona?
A cosa serve?
La nostra implementazione
I Dataset
3. E’ un Associatore
E’ basato sul concetto di Apriori, con alcune
differenze:
Non genera tutte le possibili soluzioni e le valuta in
seguito (Generate and test)
Minimizza l’occupazione di memoria
4. Fase 1: Ricerca del Frequent Item Set
1. Innanzitutto è necessario trovare il set di termini frequenti
del database e calcolarne il supporto.
2. Ordinato il set in ordine decrescente, si ottiene L,la lista di
termini frequenti.
Fase 2: Creazione dell’albero
1. Per ogni transazione T nel database gli elementi della
transazione vengono ordinati secondo L.
2. Detta T=[p|P], si controlla che il nodo radice non abbia già
l’elemento p tra i suoi figli.
1. Se è così, il nodo viene aggiunto e viene invocato un metodo
ricorsivo per l’aggiunta della coda P a p.
2. In caso contrario la coda P viene aggiunta direttamente
all’elemento p già presente.
5. Fase 3: FPGtowth
procedure FP_growth (Tree, a)
if Tree contains a single path P then
for each combination (denoted as b) of the nodes in the path P
generate pattern with support = minimum support of nodes in b;
else for each in the header of Tree {
generate pattern b = with support = .support;
construct b 's conditional pattern base and then b 's conditional FP_tree Treeb;
if then
call FP_growth (Treeb, b);
}
6. Viene utilizzato in
modo massiccio nella
valutazione di cosa
mostrare al cliente in
ambiti di commercio sia
elettronico che non
(Basket analysis):
La relazione evidenziata
è infatti del tipo “chi ha
fatto questo ha fatto
anche quest’altro con
questa probabilità”
7. Offre un framework che permette di
Semplificare l’accesso ai dati
Semplificare la gestione del plugin
Non occuparsi dei particolari poco interessanti
quali la GUI e l’interazione con l’utente
8.
9. inst = tuples.nextElement(); for(String item : m_itemSet.getInvertedSortedSet()) {
Enumeration<Attribute> attributes = inst.enumerateAttributes(); Vector<TreeNode> nodes =
TreeNodeManager.getInstance().getNodes(item);
String tid = inst.stringValue(attributes.nextElement());
CandidateRootTreeNode tmpSubTree = new CandidateRootTreeNode();
ArrayList<String> list = new ArrayList<String>();
for (TreeNode node : nodes) {
while (attributes.hasMoreElements()) {
tmpSubTree.addSubTree(node);
Attribute item = attributes.nextElement();
}
tmp = inst.stringValue(item);
if (m_verbose) {
StringTokenizer tok = new StringTokenizer(tmp,quot;;quot;);
System.out.println(quot;Unpruned candidate tree:quot;);
while(tok.hasMoreElements()) {
System.out.println(quot;quot;+ tmpSubTree);
String element = tok.nextToken();
}
list.add(element);
tmpSubTree.prune(item, m_calcMinSupport);
}
if (m_verbose) {
}
System.out.println(quot;Pruned candidate tree:quot;);
System.out.println(quot;quot;+ tmpSubTree);
m_itemSet.sortExternalVector(list);
}
if(m_verbose) {
System.out.print(quot;Elementi ordinati di TID quot;+tid+quot;: quot;);
toStringResult = toStringResult.concat(tmpSubTree.wekaToString());
for (String string : list) {
if (m_verbose) {
System.out.print(string);
System.out.println(quot;WekaToString:quot;);
}
System.out.println(tmpSubTree.wekaToString());
System.out.println();
}
}
}
m_tree.addTransaction(list);
10. inst = tuples.nextElement(); for(String item : m_itemSet.getInvertedSortedSet()) {
Enumeration<Attribute> attributes = inst.enumerateAttributes(); Vector<TreeNode> nodes =
TreeNodeManager.getInstance().getNodes(item);
String tid = inst.stringValue(attributes.nextElement());
CandidateRootTreeNode tmpSubTree = new CandidateRootTreeNode();
ArrayList<String> list = new ArrayList<String>();
for (TreeNode node : nodes) {
while (attributes.hasMoreElements()) {
tmpSubTree.addSubTree(node);
Attribute item = attributes.nextElement();
}
tmp = inst.stringValue(item);
if (m_verbose) {
StringTokenizer tok = new StringTokenizer(tmp,quot;;quot;);
System.out.println(quot;Unpruned candidate tree:quot;);
while(tok.hasMoreElements()) {
System.out.println(quot;quot;+ tmpSubTree);
String element = tok.nextToken();
}
list.add(element);
tmpSubTree.prune(item, m_calcMinSupport);
}
if (m_verbose) {
}
System.out.println(quot;Pruned candidate tree:quot;);
System.out.println(quot;quot;+ tmpSubTree);
m_itemSet.sortExternalVector(list);
}
if(m_verbose) {
System.out.print(quot;Elementi ordinati di TID quot;+tid+quot;: quot;);
toStringResult = toStringResult.concat(tmpSubTree.wekaToString());
for (String string : list) {
if (m_verbose) {
System.out.print(string);
System.out.println(quot;WekaToString:quot;);
}
System.out.println(tmpSubTree.wekaToString());
System.out.println();
}
}
}
m_tree.addTransaction(list);
11. inst = tuples.nextElement(); for(String item : m_itemSet.getInvertedSortedSet()) {
Enumeration<Attribute> attributes = inst.enumerateAttributes(); Vector<TreeNode> nodes =
TreeNodeManager.getInstance().getNodes(item);
String tid = inst.stringValue(attributes.nextElement());
CandidateRootTreeNode tmpSubTree = new CandidateRootTreeNode();
ArrayList<String> list = new ArrayList<String>();
for (TreeNode node : nodes) {
while (attributes.hasMoreElements()) {
tmpSubTree.addSubTree(node);
Attribute item = attributes.nextElement();
}
tmp = inst.stringValue(item);
if (m_verbose) {
StringTokenizer tok = new StringTokenizer(tmp,quot;;quot;);
System.out.println(quot;Unpruned candidate tree:quot;);
while(tok.hasMoreElements()) {
System.out.println(quot;quot;+ tmpSubTree);
String element = tok.nextToken();
}
list.add(element);
tmpSubTree.prune(item, m_calcMinSupport);
}
if (m_verbose) {
}
System.out.println(quot;Pruned candidate tree:quot;);
System.out.println(quot;quot;+ tmpSubTree);
m_itemSet.sortExternalVector(list);
}
if(m_verbose) {
System.out.print(quot;Elementi ordinati di TID quot;+tid+quot;: quot;);
toStringResult = toStringResult.concat(tmpSubTree.wekaToString());
for (String string : list) {
if (m_verbose) {
System.out.print(string);
System.out.println(quot;WekaToString:quot;);
}
System.out.println(tmpSubTree.wekaToString());
System.out.println();
}
}
}
m_tree.addTransaction(list);
12. inst = tuples.nextElement(); for(String item : m_itemSet.getInvertedSortedSet()) {
Enumeration<Attribute> attributes = inst.enumerateAttributes(); Vector<TreeNode> nodes =
TreeNodeManager.getInstance().getNodes(item);
String tid = inst.stringValue(attributes.nextElement());
CandidateRootTreeNode tmpSubTree = new CandidateRootTreeNode();
ArrayList<String> list = new ArrayList<String>();
for (TreeNode node : nodes) {
while (attributes.hasMoreElements()) {
tmpSubTree.addSubTree(node);
Attribute item = attributes.nextElement();
}
tmp = inst.stringValue(item);
if (m_verbose) {
StringTokenizer tok = new StringTokenizer(tmp,quot;;quot;);
System.out.println(quot;Unpruned candidate tree:quot;);
while(tok.hasMoreElements()) {
System.out.println(quot;quot;+ tmpSubTree);
String element = tok.nextToken();
}
list.add(element);
tmpSubTree.prune(item, m_calcMinSupport);
}
if (m_verbose) {
}
System.out.println(quot;Pruned candidate tree:quot;);
System.out.println(quot;quot;+ tmpSubTree);
m_itemSet.sortExternalVector(list);
}
if(m_verbose) {
System.out.print(quot;Elementi ordinati di TID quot;+tid+quot;: quot;);
toStringResult = toStringResult.concat(tmpSubTree.wekaToString());
for (String string : list) {
if (m_verbose) {
System.out.print(string);
System.out.println(quot;WekaToString:quot;);
}
System.out.println(tmpSubTree.wekaToString());
System.out.println();
}
}
}
m_tree.addTransaction(list);
13. inst = tuples.nextElement(); for(String item : m_itemSet.getInvertedSortedSet()) {
Enumeration<Attribute> attributes = inst.enumerateAttributes(); Vector<TreeNode> nodes =
TreeNodeManager.getInstance().getNodes(item);
String tid = inst.stringValue(attributes.nextElement());
CandidateRootTreeNode tmpSubTree = new CandidateRootTreeNode();
ArrayList<String> list = new ArrayList<String>();
for (TreeNode node : nodes) {
while (attributes.hasMoreElements()) {
tmpSubTree.addSubTree(node);
Attribute item = attributes.nextElement();
}
tmp = inst.stringValue(item);
if (m_verbose) {
StringTokenizer tok = new StringTokenizer(tmp,quot;;quot;);
System.out.println(quot;Unpruned candidate tree:quot;);
while(tok.hasMoreElements()) {
System.out.println(quot;quot;+ tmpSubTree);
String element = tok.nextToken();
}
list.add(element);
tmpSubTree.prune(item, m_calcMinSupport);
}
if (m_verbose) {
}
System.out.println(quot;Pruned candidate tree:quot;);
System.out.println(quot;quot;+ tmpSubTree);
m_itemSet.sortExternalVector(list);
}
if(m_verbose) {
System.out.print(quot;Elementi ordinati di TID quot;+tid+quot;: quot;);
toStringResult = toStringResult.concat(tmpSubTree.wekaToString());
for (String string : list) {
if (m_verbose) {
System.out.print(string);
System.out.println(quot;WekaToString:quot;);
}
System.out.println(tmpSubTree.wekaToString());
System.out.println();
}
}
}
m_tree.addTransaction(list);
14. I due dataset selezionati sono
Il dataset dimostrativo del paper
Un dataset legato ad un ipotetico negozio di DVD,
con acquisti effettuati da utenti di vario genere e
con diversi interessi di argomento o attori
15. FP-Growth Apriori
Pro Contro Pro Contro
Grande quantità di
Minimizza la ricerca di nodi memoria per mantenere
tutti i percorsi possibili.
Ricerca completamente tutte le Ricerca completamente tutte le
combinazioni combinazioni
E’ necessario esplorare tutto
l’albero più volte, quindi da un
punto di vista temporale
diventa molto oneroso
Si osserva come le performance
Tempo di esecuzione
degradino non tanto all’aumentare
della dimensione delle transazioni,
quanto più che altro all’aumentare
del loro numero. n=35
n=25
n=15
n=5
16. FP-Growth Apriori
Pro Contro Pro Contro
Grande quantità di
Minimizza la ricerca di nodi memoria per mantenere
tutti i percorsi possibili.
Ricerca completamente tutte le Ricerca completamente tutte le
combinazioni combinazioni
E’ necessario esplorare tutto
l’albero più volte, quindi da un
punto di vista temporale
diventa molto oneroso
Si osserva come le performance
Tempo di esecuzione
degradino non tanto all’aumentare
della dimensione delle transazioni,
quanto più che altro all’aumentare
del loro numero. n=35
n=25
n=15
Sarebbe stato
n=5
interessante usare
un cubo OLAP…