Hƣớng phát triển của đề tài là:

Một phần của tài liệu khai phá luật kết hợp trong cơ sở dữ liệu và ứng dụng (Trang 73 - 89)

Thực nghiệm khai phá luật kết hợp trên dữ liệu bán hàng của Siêu thị nhƣ đã trình bày ở trên mới chỉ dừng lại ở CSDL nhị phân( mặt hàng có xuất hiện hay không xuất hiện trong giao tác), chƣa quan tâm đến số lƣợng hàng bán đƣợc cũng nhƣ lợi nhuận của các giao tác. Đề tài luận văn có thể đƣợc nghiên cứu tiếp theo các hƣớng sau:

- Khai phá tập mục và luật kết hợp trên dữ liệu số để đánh giá đƣợc lợi nhuận của từng tập mục, từng luật tìm đƣợc.

- Kết quả khai phá sinh ra quá nhiều luật ứng với một độ hỗ trợ và một độ tin cậy tối thiểu cho trƣớc, do vậy cần nghiên cứu để sinh luật không dƣ thừa, tối ƣu hoá tính ứng dụng luật.

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

TÀI LIỆU THAM KHẢO

Tiếng Việt:

[1] Nguyễn Thanh Bình (2007), “Khai phá dữ liệu: Khái niệm và kỹ thuật”, Huế.

[2] Vũ Đức Thi, Nguyễn Huy Đức (2008), “Thuật toán hiệu quả khai phá tập mục lợi ích cao trên cấu trúc dữ liệu cây”, Tạp chí Tin học và Điều

khiển học, 24(3), tr. 204-216.

[3] Nguyễn Huy Đức (2009), “Khai phá tập mục cổ phần cao và lợi ích cao trong cơ sở dữ liệu”, Luận án Tiến sĩ Toán học, Viện Công nghệ Thông tin – Viện KH và CN Việt Nam

[4] Đỗ Phúc (2001), "Khảo sát quan hệ giữa tập mặt hàng phổ biến trong khai phá dữ liệu và dàn khái niệm", Hội Nghị kỷ niệm 25 năm thành lập

Viện Công nghệ Thông tin, Hà Nội.

[5] Vũ Đức Thi, Lê Hải Khôi ( 1999), “Một số nguyên lý hoạt động của kho dữ liệu”, Tạp chí Tin học và Điều khiển, Tr 27,29-32.

[6] Vũ Đức Thi (1997), “Cơ sở dữ liệu - Kiến thức và thực hành”, Nhà xuất bản Thống kê.

[7] Nguyễn Thanh Thủy (2003), “Phát hiện tri thức và khai phá dữ liệu: Công cụ, phƣơng pháp và ứng dụng”, Bài giảng Trường Thu, Hà Nội

Tiếng Anh:

[8] Agrawal R. And Srikant R. (1994), “Fast algorithms for mining association rules”, in proceedings of 20th International Conference on Very Large Databases, Santiago, Chile.

[9] Cai C. H., Chee Fu A. W., Cheng C. H., and Kwong W. W. (2005), “Mining Association Rules with Weighted Items”, Proceedings of the Sixth International Conference on Intelligent Data Engineering and Automated Learning (IDEAL 2005).

[10]Goethals B. and Zaki M. (2003), “Advances in frequent itemset mining implementations: Introduction to FIMI03”, In Workshop on Frequent

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

Itemset Mining Implementations (FIMI’03) in conjunction with IEEE-

ICDM.

[11]Grahne G. and Zhu J. (2003), “Efficient using prefix-tree in mining frequent itemsets”, in Proc. IEEE ICDM Workshop on Frequent Itemset

Mining Implementations, Melbourne, FL.

[12]Han J., Cheng H., Xin D., Yan X. (2007), “Frequent pattern mining: current status and future directions”. Data Min Knowl Disc, Vol. 15, pp. 55-86. Published online: 27 January 2007. Springer Science+Business Media, LLC 2007.

[13]Han J., Pei J., and Yin Y. (2000), “Mining frequent patterns without candidate generation”, In ACM SIGMOD Intl. Conference on Management of Data, pp. 1-12.

[14]Kotsiantis S., Kanellopoulos D. (2006), “Association Rules Mining: A Recent Overview”, GESTS International Transactions on Computer Science and Engineering, Vol. 32, No. 1, pp. 71-82.

[15]A.Tiwari, R.K. Gupta and D.P. Agrawal. (2010). “A Survey on Frequent Pattern Mining: Current Status and Challenging Issues”.

Information Technology Journal, 9(7), 1278-1293. Asian Network for

Scientific Infomation.

[16]Virendra Kumar Shrivastava, Dr. Parveen Kumar, (2010), “FP-tree and COFI Based Approach for Mining of Multiple Level Association Rules in Large Databases”. International Journal of Computer Science and Information Security, Vol. 7 No. 2.

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn PHỤ LỤC /*--- File: AprioriSets.cpp ---*/ #include <time.h> #include <algorithm> #include <iostream> #include <time.h> using namespace std; #include "AprioriSets.h" AprioriSets::AprioriSets() { data=0; minsup=0; remap=0; relist=0;

trie = new Item(0); verbose = false; countType = 1; }

AprioriSets::~AprioriSets() {

if(data) delete data; if(trie) {

trie->deleteChildren(); delete trie;

}

if(remap) delete remap; if(relist) delete relist; }

void AprioriSets::setData(char *fn, int type) {

data = new Data(fn, type); }

int AprioriSets::setOutputSets(char *fn) {

setsout.open(fn);

if(!setsout.is_open()) {

cerr << "error: could not open " << fn << endl; return -1; } return 0; } int AprioriSets::generateSets() {

int total=0, pass=0; bool running = true; while(running) { clock_t start;

int generated=0, nodes=0, tnr=0, pruned; pass++;

cout << pass << " " << flush; if(pass>2) {

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

generated = generateCandidates(pass); nodes = pruneNodes(pass);

if(verbose) cout << generated << " [" << (clock()- start)/double(CLOCKS_PER_SEC) << "s] " << flush; }

start = clock();

tnr = countCandidates(pass); if(verbose) {

if(pass == 1) cout << trie->getChildren()->size() << " ";

cout << tnr << " [" << (clock()-start)/double(CLOCKS_PER_SEC) << "s] " << flush;

}

if(pass==1 && setsout.is_open()) printSet(*trie,0,0); start = clock();

pruned = pruneCandidates(pass);

if(verbose) cout << pruned << " [" << (clock()- start)/double(CLOCKS_PER_SEC) << "s]\n" << flush; if(pass==1) ReOrder(); // Reorder all items total += pruned;

if(pruned <= pass) running = false; }

cout << endl; return total; }

int AprioriSets::generateCandidates(int level) {

int *tmp = new int[level];

int generated = generateCandidates(level, trie->getChildren(), 1, tmp);

delete [] tmp; return generated; }

int AprioriSets::generateCandidates(int level, set<Item> *items, int depth, int *current)

{

if(items == 0) return 0; int generated = 0;

set<Item>::reverse_iterator runner; if(depth == level-1) {

for(runner = items->rbegin(); runner != items->rend(); runner++) {

current[depth-1] = runner->getId();

set<Item> *children = runner->makeChildren();

for(set<Item>::reverse_iterator it = items->rbegin(); it != runner; it++) {

current[depth] = it->getId();

if(level<=2 || checkSubsets(level,current, trie- >getChildren(), 0, 1)) { children->insert(Item(it->getId())); generated++; } } } } else {

for(runner = items->rbegin(); runner != items->rend(); runner++) {

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

generated += generateCandidates(level, runner->getChildren(), depth+1, current);

} }

return generated; }

bool AprioriSets::checkSubsets(int sl, int *iset, set<Item> *items, int spos, int depth)

{

if(items==0) return 0; bool ok = true;

set<Item>::iterator runner; int loper = spos;

spos = depth+1;

while(ok && (--spos >= loper)) {

runner = items->find(Item(iset[spos])); if(runner != items->end()) {

if(depth<sl-1) ok = checkSubsets(sl, iset, runner->getChildren(), spos+1, depth+1); } else ok=false; } return ok; }

int AprioriSets::pruneNodes(int level) {

return pruneNodes(level,trie->getChildren(),1); }

int AprioriSets::pruneNodes(int level, set<Item> *items, int depth)

{

if(items == 0) return 0; int nodes = 0;

if(depth==level) nodes = items->size(); else {

for(set<Item>::iterator runner = items->begin(); runner != items- >end(); ) {

int now = pruneNodes(level, runner->getChildren(), depth+1); if(now) { nodes += now; nodes++; runner++; } else { runner->deleteChildren(); set<Item>::iterator tmp = runner++; items->erase(tmp); } } } return nodes; }

int AprioriSets::countCandidates(int level) {

int trans=0;

// count all single items if(level==1) {

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

while(Transaction *t = data->getNext()) { trie->Increment();

int *iset = t->t, sl = t->length;

set<Item> *items = trie->makeChildren(); for(int i=0; i<sl; i++) {

Item item(iset[i]);

set<Item>::iterator runner = items->find(item); if(runner == items->end()) runner = (items- >insert(item)).first; runner->Increment(); } trans++; delete t; } } else { while(Transaction *t = data->getNext()) { if(t->length >= level) { // Reorder transaction int i; vector<int> list;

for(i=0; i<t->length; i++) {

set<Element>::iterator it = relist->find(Element(t->t[i])); if(it != relist->end()) list.push_back(it->id);

}

int size=list.size();

sort(list.begin(), list.end()); delete t;

t = new Transaction(size);

for(i=0; i<size; i++) t->t[i] = list[i]; if(countType==1 || level<=2) { if(processTransaction(level, t, trie->getChildren(), 0, 1)) trans++; } else { if(processTransaction2(level, t, trie->getChildren(), 0, 1)) trans++; } delete t; } } } return trans; }

int AprioriSets::processTransaction2(int level, Transaction *t, set<Item> *items, int spos, int depth)

{

if(items == 0) return 0;

int used=0, max = t->length-level+depth;

for(set<Item>::iterator it = items->begin(); spos<max && it!=items->end(); it++)

{

while(spos<max && t->t[spos] < it->getId()) spos++; if(spos<max && (t->t[spos]==it->getId()) )

{

if(depth==level) {

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

it->Increment(); used++;

}

else used += processTransaction2(level,t,it- >getChildren(),spos+1,depth+1);

} }

return used; }

int AprioriSets::processTransaction(int level, Transaction *t, set<Item> *items, int spos, int depth)

{

if(items == 0) return 0;

int used=0, *iset = t->t, sl = t->length, loper = spos; set<Item>::iterator runner; spos = sl-(level-depth); while(--spos >= loper) { runner = items->find(Item(iset[spos])); if(runner != items->end()) { if(depth == level) { runner->Increment(); used++; } else {

if(depth==1 && level==2) runner->makeChildren();

used += processTransaction(level, t, runner->getChildren(), spos+1, depth+1);

} }

else if(depth==2 && level==2) {

set<Item> *singles = trie->getChildren();

if(singles->find(Item(iset[spos])) != singles->end()) { runner = items->insert(Item(iset[spos])).first; runner->Increment(); used++; } } } return used; }

int AprioriSets::pruneCandidates(int level) {

int pruned;

int *tmp = new int[level];

pruned = pruneCandidates(level,trie->getChildren(),1,tmp); delete [] tmp;

return pruned; }

int AprioriSets::pruneCandidates(int level, set<Item> *items, int depth, int *itemset)

{

if(items == 0) return 0; int left = 0;

for(set<Item>::iterator runner = items->begin(); runner != items- >end(); ) {

itemset[depth-1] = runner->getId(); if(depth == level) {

if(runner->getSupport() < minsup) { runner->deleteChildren();

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

set<Item>::iterator tmp = runner++; items->erase(tmp);

} else {

if(setsout.is_open()) printSet(*runner, itemset, depth); left++;

runner++; }

} else {

int now = pruneCandidates(level, runner->getChildren(), depth+1, itemset); if(now) { left += now; runner++; } else { runner->deleteChildren(); set<Item>::iterator tmp = runner++; items->erase(tmp); } } } return left; }

void AprioriSets::printSet(const Item& item, int *itemset, int length) { set<int> outset; for(int j=0; j<length; j++) if(remap) outset.insert(remap[itemset[j]]); else outset.insert(itemset[j]);

for(set<int>::iterator k=outset.begin(); k!=outset.end(); k++) setsout << *k << " ";

setsout << "(" << item.getSupport() << ")" << endl; } void AprioriSets::ReOrder() { set<Item> *src = trie->getChildren(); set<Item>::iterator itI; multiset<Element>::iterator itE; multiset<Element> list;

for(itI = src->begin();itI != src->end(); itI++)

list.insert(Element(itI->getSupport(), itI->getId())); remap = new int[list.size()+1];

relist = new set<Element>; src->clear(); int i=1; for(itE=list.begin(); itE!=list.end();itE++) { if(itE->oldid >= minsup) { remap[i] = itE->id; relist->insert(Element(itE->id,i)); Item a(i); a.Increment(itE->oldid); src->insert(a); i++; } } }

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn /*--- File: aprioritest.cpp ---*/ #include "AprioriSets.h" #include <iostream> #include <time.h>

int main(int argc, char *argv[]) {

cout << "Apriori frequent itemset mining implementation" << endl; if(argc < 4) {

} else {

AprioriSets a;

a.setVerbose(); // print information on nr of candidate itemsets etc

a.setData(argv[1],atoi(argv[2])); a.setCountType(2);

// 1: to check k-subsets of transaction in set of candidates // 2: to check all candidates in transaction (default - best performance)

a.setMinSup(atoi(argv[3]));

if(argc==5) a.setOutputSets(argv[4]); clock_t start = clock();

int sets = a.generateSets();

cout << sets << "\t[" << (clock()-start)/double(CLOCKS_PER_SEC) << "s]" << endl;

if(argc==5) cout << "Frequent sets written to " << argv[4] << endl; } return 0; } /*--- File: Data.cpp ---*/ #include <vector> #include <set> using namespace std; #include "Data.h"

Transaction::Transaction(const Transaction &tr) {

length = tr.length; t = new int[tr.length];

for(int i=0; i< length; i++) t[i] = tr.t[i]; }

Data::Data(char *filename, int t) { fn = filename; type = t; current=0; if(type>1) in = fopen(fn,"rt"); else in = fopen(fn,"rb"); } Data::~Data() { if(in) fclose(in); }

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn Transaction *Data::getNext() { Transaction *t=0; switch(type) {

case 1: t= getNextBin(); break; case 2: t= getNextAs(); break; case 3: t= getNextAsFlat(); break; case 4: t= getNextAsQuest(); break; } if(t) current++; else { rewind(in); current=0; } return t; } Transaction *Data::getNextAs() { Transaction *t; int tid, item, i; vector<int> list;

static int cur=0,prev=-1; static bool begin=true; if(feof(in)) { begin=true; prev=-1; return 0; } if(!begin) { list.push_back(cur); } else begin=false; while(true) { int dummy;

fscanf(in, "%d %d %d",&dummy, &tid, &item); //fscanf(in, "%d %d", &tid, &item);

if(feof(in)) {

int size=list.size(); t = new Transaction(size);

for(i=0; i<size; i++) t->t[i] = list[i]; list.clear();

return t; }

else if(prev<0) prev=tid; else if(tid != prev)

{

prev = tid; cur = item;

int size=list.size(); t = new Transaction(size);

for(i=0; i<size; i++) t->t[i] = list[i]; list.clear();

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn return t; } list.push_back(item); } } Transaction *Data::getNextAsFlat() { vector<int> list; char c;

// read list of items do {

int item=0, pos=0; c = getc(in); while((c >= '0') && (c <= '9')) { item *=10; item += int(c)-int('0'); c = getc(in); pos++; } if(pos) list.push_back(item); }while(c != '\n' && !feof(in)); if(feof(in))

return 0;

// Note, also last transaction must end with newline, // else, it will be ignored

// sort list of items

// sort(list.begin(),list.end()); // put items in Transaction structure

Transaction *t = new Transaction(list.size()); for(int i=0; i<int(list.size()); i++)

t->t[i] = list[i]; return t;

}

Transaction *Data::getNextAsQuest() {

int tmptid, tid,l,i; Transaction *t;

fscanf(in,"%d %d %d",&tmptid,&tid,&l); if(feof(in)) return 0;

t = new Transaction(l); for(i=0; i<l; i++)

fscanf(in,"%d",&t->t[i]); return t;

}

Transaction *Data::getNextBin() {

int tmptid, tid,l,i; Transaction *t; fread(&tmptid,4, 1,in); if(feof(in)) return 0; fread(&tid,4, 1,in); fread(&l,4, 1,in); t = new Transaction(l); for(i=0; i<l; i++) {

fread(&t->t[i],4, 1,in); }

return t; }

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

/*---

File: Item.cpp

---*/ #include "Item.h"

set<Item> *Item::makeChildren() const {

if(children) return children; return children = new set<Item>; }

int Item::deleteChildren() const {

int deleted=0; if(children) {

for(set<Item>::iterator it = children->begin(); it != children- >end(); it++) { deleted += it->deleteChildren(); } delete children; children = 0; deleted++; } return deleted; } /*--- File: AprioriRules.cpp ---*/ #include <iostream> #include <fstream> #include <stdio.h> #include <set> #include <vector> #include <time.h> using namespace std; #include "Item.h" #include "AprioriRules.h" AprioriRules::AprioriRules() { data=0; minconf=0; maxhead=0;

trie = new Item(0); verbose = false; } AprioriRules::~AprioriRules() { if(data) fclose(data); if(trie) { trie->deleteChildren(); delete trie; } } void AprioriRules::setData(char *fn) {

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn data = fopen(fn,"rt"); } int AprioriRules::setOutputRules(char *fn) { rulesout.open(fn); if(!rulesout.is_open()) {

cerr << "error: could not open " << fn << endl; return -1; } return 0; } Itemset *AprioriRules::getNextSet() { Itemset *t; vector<int> list; char c; do {

int item=0, pos=0; c = getc(data); while((c >= '0') && (c <= '9')) { item *=10; item += int(c)-int('0'); c = getc(data); pos++; } if(pos) list.push_back(item); }while(c != '\n' && !feof(data)); if(feof(data)) return 0;

int size = list.size() - 1; if(size>=0) {

t = new Itemset(size); t->support = list[size];

for(int i=0; i<size; i++) t->t[i] = list[i]; return t;

}

else return getNextSet(); }

int AprioriRules::generateRules() {

int size=0; clock_t start;

// Read all frequent itemsets

if(verbose) cout << "reading frequent itemsets" << flush; start = clock();

while(Itemset *t = getNextSet()) { set<Item>::iterator it;

set<Item>* items = trie->makeChildren(); for(int depth=0;depth < t->length; depth++) { it = items->find(Item(t->t[depth]));

if(it == items->end()) it = items->insert(Item(t- >t[depth])).first;

items = it->makeChildren(); }

if(t->length) it->Increment(t->support); else trie->Increment(t->support);

size = (t->length>size? t->length: size); delete t;

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

if(verbose) cout << "[" << (clock()-start)/double(CLOCKS_PER_SEC) << "s]" << endl << flush;

// generate rules

if(verbose) cout << "generating rules" << flush; int *iset = new int[size];

int added = generateRules(trie->getChildren(), iset, 1); delete [] iset;

if(verbose) cout << "[" << (clock()-start)/double(CLOCKS_PER_SEC) << "s]" << endl << flush;

return added; }

int AprioriRules::generateRules(set<Item> *current, int *iset, int depth)

{

if(current==0) return 0; int added = 0;

for(set<Item>::iterator runner = current->begin(); runner!= current->end(); runner++) {

iset[depth-1] = runner->getId(); if(depth > 1) {

int *tmp = new int[depth];

added += processSet(trie->getChildren(), depth, iset, runner- >getSupport(), tmp, 0,1);

delete [] tmp; }

added += generateRules(runner->getChildren(), iset, depth+1); }

return added; }

int AprioriRules::processSet(set<Item> *items, int sl, int *iset, int sup, int *head, int spos, int depth)

{

int loper = spos;

set<Item>::iterator runner, it; int added=0,i,j,k;

spos = sl;

while(--spos >= loper) { head[depth-1] = iset[spos];

runner = items->find(Item(iset[spos])); // find body and its support

set<Item> *tmp = trie->getChildren();

Một phần của tài liệu khai phá luật kết hợp trong cơ sở dữ liệu và ứng dụng (Trang 73 - 89)

Tải bản đầy đủ (PDF)

(89 trang)