Data Mining: Advance Affinity Analysis A.K.A Algoritma Sugesti Tingkat Lanjut (Algoritma Apriori)


Masih di topik yang sama dengan sebelumnya yaitu tentang data mining tepatnya algoritma sugesti. So, what's new? Pada kasus sebelumnya variabel atau fitur yang ada hanya sedikit. Sementara itu, pada kenyataannya dikehidupan sehari-hari variabel ini bisa banyak sekali. Barang-barang yang di jual di supermarket bisa sampai puluhan atau mungkin ratusan jenis barang. Selain itu ketika berbelanja, kebanyakan orang akan membeli barang lebih dari 1. Misalnya contoh ada orang yang ingin membuat roti bakar (lagi) orang itu akan membeli roti, meses dan mentega dan pemanggang roti juga mungkin. Orang lain yang punya tujuan yang sama akan cenderung membeli barang yang sama sehingga barang-barang ini bisa di gabungkan dalam 1 grup. Kemudian dari 1 grup ini kita cari hubungannya dengan terbelinya barang lain. Misal kebetulan orang yang ada di daerah supermarket tersebut punya kebiasaan makan roti bakar dengan minum teh maka kemungkinan besar ketika orang-orang membeli barang-barang yang kita buatkan grup tadi, orang itu juga akan membeli teh.

Algoritma apriori hanyalah salah satu algoritma untuk kasus yang variabelnya banyak seperti ini. Sebelum kita lanjut lebih jauh, akan diperkenalkan istilah-istilah yang akan muncul pada penjelasan algoritma ini, yaitu:

k-item = kombinasi yang anggotanya ada k buah, misal kombinasi 2-item punya 2 buah anggota, 3-item punya 3 dst.

frequent = Standar minimal total terjadinya suatu kejadian. Misal dalam contoh kasus pembelian di supermarket, ini adalah standar minimal total pembelian suatu barang di supermarket tersebut bisa kita "anggap". Dari banyaknya barang di supermarket, ada beberapa barang yang sangat jarang dibeli tentunya dan ketika kita mencari nilai confidencenya hasilnya pasti 0 atau sangat kecil.

Kemudian secara garis besar, algoritmanya adalah


Jadi bisa dilihat bahwa hasil akhir dari algoritma ini adalah kombinasi-kombinasi yang frequent. Kombinasi-kombinasi inilah yang kita anggap "grup" tadi. Komputer yang mengolah data ini mempelajari bahwa roti, meses dan mentega itu bisa dijadikan 1 grup dengan "mempelajari" data-data yang ada, bukan karena kita memberitahukannya begitu.

Langsung saja kita praktekkan, scriptnya bisa di download di sini dan untuk datanya download di sini, ambil data yang 1 juta (1 million) kita akan menggunakan file ratings.dat pada data yang didownload tersebut. Di sini kita memakai data review film. Tiap orang yang mereview dipisahkan oleh nomor idnya dan begitu juga dengan judul film di bedakan dengan nomor idnya juga. Kita ingin menebak, dengan dasar jika orang menyukai film (a,b,c) maka orang itu juga pasti menyukai film d. See, (a,b,c) adalah "grup" itu dan dengan adanya d, kita akan mencari nilai confidencenya sama seperti artikel sebelumnya. Rating di atas 3 kita anggap orang itu menyukai film yang dia review sebaliknya dia tidak suka.

confidence = sum((a,b,c) and d) / sum((a,b,c))

Pertama adalah mencari itemset yang frequent. Standar kita di sini adalah 1000. Jadi semua film yang disukai kurang dari 1000 orang akan di eliminasi dan sisanya akan kita simpan.

 #elminate by minimum frequency  
 resfirst = [row for row in ratepd.values if row[1] > minfreq]  
 iteritem = np.zeros(len(resfirst), dtype = np.int)  
 valfreqfrst = []  
 for i in xrange(len(resfirst)):  
      iteritem[i] = resfirst[i][0]  
      valfreqfrst.append(int(resfirst[i][1]))  
 #store itemset in dictionary  
 kitem = defaultdict(int)  
 kitem[1] = zip(iteritem, valfreqfrst)  

Dari itemset ini kita bentuk kombinasi-kombinasi k-item dan mengeliminasi (lagi) semunya yang tidak frequent.

 #make second iter etc  
 for i in xrange(2, totnumtoshow+1):  
      #making list of combination from iter1  
      combigen = list(combinations(iteritem, i))  
      #container for combination that pass a minfreq test  
      container = []  
      for j in xrange(len(combigen)):  
           freq = calcfreq(set(combigen[j]), people, pepreview)  
           if freq > minfreq:  
                container.append((combigen[j], freq))  
      kitem[i] = container  

Dan pada akhirnya kita dapatkan "grup-grup" yang kita inginkan itu. Selanjutnya kita mencari nilai confidence antara film kita dengan kombinasi yang bisa memberikan nilai confidence tertinggi. Artinya ketika orang menyukai "grup" film ini, kemungkinan terbesarnya dia juga menyukai film yang kita cari (idnya kita masukkan sebagai input) itu.

 maxfreq = 0  
 for i in xrange(len(kitem[totnumtoshow])):  
      #print {nomorid}.issubset(set([9,4,5]))  
      cont = set(kitem[totnumtoshow][i][0])  
      if not {nomorid}.issubset(set(kitem[totnumtoshow][i][0])):  
           valfreq = kitem[totnumtoshow][i][1]  
           valcom = kitem[totnumtoshow][i][0]  
           newcombi = set(kitem[totnumtoshow][i][0])  
           newcombi.add(nomorid)  
           newcombifreq = calcfreq(newcombi, people, pepreview) / float(valfreq)  
           if newcombifreq > maxfreq:  
                maxfreq = newcombifreq  
                maxid = valcom  
 #print 'jadi kesimpulannya orang yang menyukai '+str(maxid[0])+' dan '+str(maxid[1])+ \  
 #' juga menyukai '+str(nomorid)+' dengan nilai confidence '+str(maxfreq)  
 #print "this is a tuple: %s" % (thetuple,)  
 print 'jadi kesimpulannya orang yang menyukai {0} juga menyukai {1} dengan nilai confidence {2}%'.format(maxid,nomorid,(maxfreq * 100))  

Oh iya, banyaknya anggota pada "grup-grup" yang kita dapatkan ditentukan pada variabel totnumtoshow dimana semakin tinggi nilainya atau semakin banyak anggota pada kombinasi yang dihasilkan maka akan semakin lama running timenya karena banyaknya kombinasi yang dihasilkan semakin banyak. Kombinasi-kombinasi ini dihasilkan dari function combinations() dari itertools.

Contoh kita running default (kombinasi 2 anggota mencari relasi film dengan id = 1) maka hasilnya

 ./apriori.py  
 menggunakan nilai default -> relasi 2 id dengan id 1  
 jadi kesimpulannya orang yang menyukai (2571, 1270) juga menyukai 1 dengan nilai confidence 56.0117302053%  

Running dengan mencari relasi film dengan id 318 (masih kombinasi 2 anggota)

 ./apriori.py 318  
 mencari relasi 2 id dengan id 318  
 jadi kesimpulannya orang yang menyukai (527, 296) juga menyukai 318 dengan nilai confidence 74.3362831858%  

Confidencenya tinggi, karena id 318 sendiri termasuk dalam itemset (yang disukai lebih dari 1000 orang). Sekarang kita cari id 318 dengan kombinasi 3 anggota.

 ./apriori.py 318 3  
 mencari relasi 3 id dengan id 318  
 jadi kesimpulannya orang yang menyukai (2858, 260, 1196) juga menyukai 318 dengan nilai confidence 61.7082533589%  

Nilai confidencenya semakin kecil. Ini masuk akal karena semakin rumit kombinasinya tentu saja banyak kejadian dari kombinasi tersebut akan semakin sedikit.

Well, proses extract data dari scriptnya ini tidak saya jelaskan karena terlalu ribet untuk tujuan yang sederhana.

Mungkin cukup sampai disini. Script ini sebenarnya bisa di optimasi lagi lebih lanjut karena outputnya hanya untuk kombinasi n item beserta confidence terhadap id input yang kita masukkan sedangkan sebenarnua script ini juga ikut menghitung kombinasi dan confidence dari kombinasi 2 item sampai n item. Ah, tapi saya terlalu malas untuk mengubahnya :p

Dari beberapa materi yang saya pelajari, saya memutuskan memposting yang ini karena menurut saya ini materi yang cukup menarik dan akan berguna kedepannya jadi ketika saya lupa, saya tinggal membaca ini lagi...tidak ada yang lebih baik daripada membaca catatan sendiri untuk merefresh pengetahuan kan? Sekian.

referensi:
buku: Learning Data Mining with Python

Komentar