Mengukur Jarak Data¶
Mengukur Jarak Tipe Numerik¶
Ada beberapa cara untuk menghitung similaritas atau jarak dari dari data tipe numerik, diantaranya:
Minkowski Distance¶
$$ d _ { \operatorname { min } } = ( sum _ { i = 1 } ^ { n } | x _ { i } - y _ { i } | ^ { m } ) ^ { \frac { 1 } { m } } , m \geq 1 $$
Manhattan Distance¶
Euiclidian Distance¶
Average Distance¶
Weighted euclidean distance¶
Jika berdasarkan tingkatan penting dari masing masing atribut ditentukan, maka Weighted Euclidean distance adalah modifikisasi lain dari jarak Euclidean distance yang dapat digunakan. Ukuran ini dirumuskan dengan: $$ d _ { w e } = \left ( \sum _ { i = 1 } ^ { n } w _ { i } ( x _ { i } - y _ { i } \right) ^ { 2 } ) ^ { \frac { 1 } { 2 } } $$ dimana wi adalah bobot yang diberikan pada atribut ke i.
Chord distance¶
$$ d _ { \text {chord} } = \left ( 2 - 2 \frac { \sum _ { i = 1 } ^ { n } x _ { i } y _ { i } } { | x | _ { 2 } | y | _ { 2 } } \right) ^ { \frac { 1 } { 2 } } $$ dimana $ { | x | _ { 2 } } $ adalah $ L^2-norm { | x | _ { 2 } } =\sqrt { \sum_{ i = 1 }^{ n }x_{i}^{2}} $
Mahalanobis distance¶
$$ d _ { m a h } = \sqrt { ( x - y ) S ^ { - 1 } ( x - y ) ^ { T } } $$ diman $ S $ adalah matrik covariance data.
Cosine measure¶
Ukuran Cosine similarity lebih banyak digunakan dalam similaritas dokumen dan dinyatakan dengan $$ Cosine(x,y)=\frac { \sum _ { i = 1 } ^ { n } x _ { i } y _ { i } } { | x | _ { 2 } | y | _ { 2 } } $$ dimana $ | y | _ { 2 } $ adalah Euclidean norm dari vektor $ y=(y_{1} , y_{2} , \dots , y_{n} ) $ di definisikan dengan $ |y|_{2}=\sqrt{ y _ { 1 } ^ { 2 } + y _ { 2 } ^ { 2 } + \ldots + y _ { n } ^ { 2 } } $
Pearson Correlation¶
$$ Pearson ( x , y ) = \frac { \sum _ { i = 1 } ^ { n } ( x _ { i } - \mu _ { x } ) ( y _ { i } - \mu _ { y } ) } { \sqrt { \sum _ { i = 1 } ^ { n } ( x _ { i } - y _ { i } ) ^ { 2 } } \sqrt { \sum _ { i = 1 } ^ { n } ( x _ { i } - y _ { i } ) ^ { 2 } } } $$ The Pearson correlation kelemahannya adalah sensitif terhadap outlier
Mengukur Jarak Tipe Binary¶
$$ d ( i , j ) = \frac { r + s } { q + r + s + t } $$
$$ d ( i , j ) = \frac { r + s } { q + r + s } $$ Kita dapat mengukur perbedaan antara dua atribut biner berdasarkan pada disimilarity. Misalnya, biner asimetris kesamaan antara objek i dan j dapat dihitung dengan $$ \operatorname { sim } ( i , j ) = \frac { q } { q + r + s } = 1 - d ( i , j ) $$ Persamaan similarity ini disebut dengan Jaccard coefficient
Mengukur Jarak Tipe Kategorical¶
Sebuah data tipe kategorial bisa membawa dua atau lebih pernyataan. Misalnya, map_color sebuah atribut nominal yang mempunya 5 pernyataan yaitu: merah, kuning, hijau, merah jambu, dan biru. Status dapat dilambangkan dengan byletters, simbol, atau satu set bilangan bulat, seperti 1, 2, ..., M. Perhatikan bahwa bilangan bulat tersebut digunakan hanya untuk penanganan data dan tidak mewakili pemesanan khusus apa pun.
Perbedaan antara dua objek i dan j bisa di hitung dengan menggunakan rasio ketidak cocokan : $$ d_(i,j) = {p - m \over p} $$ dimana, $ m $ merupakan angka yang cocok (nomer yang cocok untuk $ i $ dan $ j $ ). Dan p merupakan banyak fitur yang di hitung sebagai tipe nominal.
Mengukur Jarak Tipe Ordinal¶
- Nilai$ f $ untuk objek ke-i adalah $ x_if $, dan f memiliki $ M_f $ status urutan , mewakili peringkat $ 1,..,Mf $ Ganti setiap $ x_if $ dengan peringkatnya, $ r_if ∈ {1...M_f} $
- Karena setiap atribut ordinal dapat memiliki jumlah state yang berbeda, diperlukan untuk memetakan rentang setiap atribut ke [0,0, 1.0] sehingga setiap atribut memiliki bobot yang sama. Perl melakukan normalisasi data dengan mengganti peringkat $ r_if $ dengan :
- Dissimilarity kemudian dihitung dengan menggunakan ukuran jarak seperti atribut numerik dengan data yang baru setelah ditransformasi $ z_if $
Mencari Jarak Data Tipe Campuran Menggunakan Python¶
Alat dan Bahan¶
Berikut merupakan library yang harus di persiapkan:
- pandas, digunakan untuk data manajemen dan data analysis.
- scipy, merupakan library berisi kumpulan algoritma dan fungsi matematika.
Pertama¶
Langkah pertama yang harus dilakukan adalah memasukkan library yang telah diunduh sebelumnya.
import pandas as pd import math as mt from sklearn.preprocessing import LabelEncoder
Kedua¶
Selanjutnya kita dapat membaca file csv tersebut.
data = pd.read_csv('data-mhs.csv', sep=';') df = pd.DataFrame(data) df.style.hide_index()
Maka akan tampil sebagai berikut:
Nama | Jenis Kelamin | IPK | Penghasilan Orangtua | Alamat | Prestasi |
---|---|---|---|---|---|
Ali | L | 3.4 | 3000000 | Sumenep | Internasional |
Ani | P | 3.2 | 5000000 | Surabaya | Regional |
Abi | L | 3.3 | 4000000 | Bangkalan | Nasional |
Ketiga¶
Langkah ini, kita menerapkan dari formula menghitung jarak diatas dalam bentuk fungsi pada python.
Fungsi berikut digunakan untuk melakukan normalisasi pada data numerikal.
def Zscore(x,mean,std): top = x - mean if top==0: return top else: return round(top / std, 2) def normalisasi(num, col_x): return Zscore(num, pd.Series(data[col_x].values).mean(), pd.Series(data[col_x].values).std())
Fungsi berikut merupakan penerapan dari rumus Euclidian Distance untuk menghitung jarak tipe numerikal.
#menghitung jarak tipe numerikal def euclidianDistance(x,y): dis = 0 for i in range(len(x)): dis += (x[i] - y[i]) ** 2 return round(mt.sqrt(dis),2)
Fungsi berikut untuk menghitung jarak pada data tipe binary symetris.
#Menghitung jarak tipe binary def distanceSimetris(x,y): q=r=s=t=0 for i in range(len(x)): if x[i]==1 and y[i]==1: q+=1 elif x[i]==1 and y[i]==0: r+=1 elif x[i]==0 and y[i]==1: s+=1 elif x[i]==0 and y[i]==0: t+=1 return ((r+s)/(q+r+s+t))
Fungsi berikut untuk menghitung jarak tipe kategorikal.
#Menghitung Jarak tipe categorikal def distanceNom(x,y): p = len(x) or len(y) m = 0 for i in range(len(x)): if x[i][0] == y[i][0]: m +=1 return (p - m) / p
Fungsi berikut untuk melakukan normalisasi pada data tipe ordinal:
#inisialisasi x = {'Internasional':3,'Nasional':2,'Regional':1} #Menghitung Jarak tipe ordinal def normalizedOrd(y): i_max = 0 for i in x: if x[i] > i_max: i_max = x[i] if y[0] == i: i_val = x[i] return (i_val - 1) / (i_max - 1)
Keempat¶
Pada langkah ini kita membuat inisialisasi dictionary dissimilarity matrix:
d_x = { 0 : ['', 'Ali', 'Ani', 'Abi'], 1 : ['Ali', 0, '', ''], 2 : ['Ani', '', 0, ''], 3 : ['Abi', '', '', 0] }
Kelima¶
Untuk mempermudah dalam menghitung jarak dari data tipe binary, alangkah lebih baiknya kita konversi nilai dari fitur tersebut dalam bentuk angka 0 / 1. Dalam proses konversi tersebut kita dapat menggunakan fungsi LabelEncode yang merupakan bawaan dari library sklearn.
X = data.iloc[:,:].values labelEncode_X = LabelEncoder() X[:,1] = labelEncode_X.fit_transform(X[:,1])
Keenam¶
Pada langkah ini kita akan menghitung jarak dari masing-masing tipe menggunakan fungsi yang telah dibuat sebelumnya.
Menghitung Jarak Tipe Numerikal¶
Berikut merupakan proses menghitung jarak dengan tipe numerikal. Pada proses berikut kita mengambil fitur-fitur numerik dari masing-masing objek, yaitu: ali, ani, dan abi. dari data numerik tersebut kemudian dilakukan normalisasi dan menghitungnya dengan mengunakan fungsi Euclidian Distance yang hasilnya di tampung pada dictionary dissimilarity matrix.
#ambil data numerikal aliNum = df.iloc[0, 2:4].values aniNum = df.iloc[1, 2:4].values abiNum = df.iloc[2, 2:4].values #normalisasi data numerikal aliNum = [normalisasi(aliNum[0], data.columns[2]), normalisasi(aliNum[1], data.columns[3])] aniNum = [normalisasi(aniNum[0], data.columns[2]), normalisasi(aniNum[1], data.columns[3])] abiNum = [normalisasi(abiNum[0], data.columns[2]), normalisasi(abiNum[1], data.columns[3])] d_x[1][2] = euclidianDistance(aniNum,aliNum) d_x[1][3] = euclidianDistance(abiNum,aliNum) d_x[2][3] = euclidianDistance(abiNum,aniNum) d_x = pd.DataFrame(d_x) d_x.style.hide_index()
Dari proses diatas, akan menampilkan jarak dalam bentuk dissimilarity matrix. Apabila nilai dari dissimilarity matrix mendekati 0, maka kedua objek tersebut semakin sama:
0 | 1 | 2 | 3 |
---|---|---|---|
Ali | Ani | Abi | |
Ali | 0 | ||
Ani | 2.83 | 0 | |
Abi | 1.41 | 1.41 | 0 |
Menghitung Jarak Tipe Kategorikal¶
Pada proses berikut kita menghitung jarak dengan tipe kategorikal / nominal. Pada proses tersebut kita akan mengambil nilai dari fitur kategorikal dari masing-masing objek. Dalam kasus ini yang menjadi fitur kategorikal adalah Kabupaten. Selanjutnya dari masing-masing nilai yang telah di ambil akan dihitung mengunakan fungsi distanceNom(obj1,obj2) yang telah dibuat sebelumnya, yang hasilnya ditampung pada dictionary dissimilarity matrix.
#ambil data kategorical aliKat = [df.iloc[0, 4:5].values] aniKat = [df.iloc[1, 4:5].values] abiKat = [df.iloc[2, 4:5].values] d_x[1][2] = distanceNom(aniKat,aliKat) d_x[1][3] = distanceNom(abiKat,aliKat) d_x[2][3] = distanceNom(abiKat,aniKat) d_x = pd.DataFrame(d_x) d_x.style.hide_index()
Dari proses diatas, akan menampilkan jarak dalam bentuk dissimilarity matrix. Pada dissimilarity matrix berikut, apabila nilainya berupa 0, maka kedua objek tersebut memiliki kesamaan dan juga sebaliknya, apabila nilainya berupa 1, kedua objek tersebut memiliki perbedaan.
0 | 1 | 2 | 3 |
---|---|---|---|
Ali | Ani | Abi | |
Ali | 0 | ||
Ani | 1 | 0 | |
Abi | 1 | 1 | 0 |
Menghitung Jarak Tipe Binary¶
Berikut ini kita akan menghitung jarak dengan tipe binary. Pada proses berikut kita harus mengambil nilai dari masing-masing objek. Dalam kasus ini, yang menjadi fitur biner adalah Jenis Kelamin. Selanjutnya, dari nilai masing-masing objek dihitung jaraknya menggunakan menggunakan fungsi distanceSimetris(obj1, obj2) yang telah dibuat sebelumnya. Dari hasil perhitungan tersebut ditampung pada dictionary dissimilarity matrix.
#ambil data binary aliBin = X[0, 1:2] aniBin = X[1, 1:2] abiBin = X[2, 1:2] d_x[1][2] = distanceSimetris(aniBin,aliBin) d_x[1][3] = distanceSimetris(abiBin,aliBin) d_x[2][3] = distanceSimetris(abiBin,aniBin) d_x = pd.DataFrame(d_x) d_x.style.hide_index()
Dari proses diatas, akan menampilkan jarak dalam bentuk dissimilarity matrix.
0 | 1 | 2 | 3 |
---|---|---|---|
Ali | Ani | Abi | |
Ali | 0 | ||
Ani | 1 | 0 | |
Abi | 0 | 1 | 0 |
Menghitung Jarak Tipe Ordinal¶
Berikut ini kita akan memghitung jarak tipe ordinal. Pada prosesnya, kita akan mengambil nilai dari masing-masing objek dari fitur Prestasi. Nilai dari masing-masing objek di normalisasi menggunakan fungsi normalizedOrd(ordObj) yang telah dibuat sebelumnya, dan dihitung jaraknya menggunakan fungsi euclidianDistance(obj1, obj2) yang hasilnya kemudian ditampung pada dictionary dissimilarity matrix.
#ambil data ordinal aliOrd = [df.iloc[0, 5:6].values] aniOrd = [df.iloc[1, 5:6].values] abiOrd = [df.iloc[2, 5:6].values] d_x[1][2] = euclidianDistance([normalizedOrd(aniOrd)],[normalizedOrd(aliOrd)]) d_x[1][3] = euclidianDistance([normalizedOrd(abiOrd)],[normalizedOrd(aliOrd)]) d_x[2][3] = euclidianDistance([normalizedOrd(abiOrd)],[normalizedOrd(aniOrd)]) d_x = pd.DataFrame(d_x) d_x.style.hide_index()
Dari proses diatas akan menampilkan jarak dalam bentuk dissimilarity matrix.
0 | 1 | 2 | 3 |
---|---|---|---|
Ali | Ani | Abi | |
Ali | 0 | ||
Ani | 1 | 0 | |
Abi | 0.5 | 0.5 | 0 |
Menghitung Jarak Tipe Campuran¶
Pada proses berikut kita akan menghitung jarak dengan berbagai tipe. Untuk menghitungnya kita dapat menjumlah jarak dari masing-masing tipe.
d_x[1][2] = euclidianDistance(aniNum,aliNum) + \ distanceNom(aniKat,aliKat) + distanceSimetris(aniBin,aliBin) +\ euclidianDistance([normalizedOrd(aniOrd)],[normalizedOrd(aliOrd)]) d_x[1][3] = euclidianDistance(abiNum,aliNum) + \ distanceNom(abiKat,aliKat) + distanceSimetris(abiBin,aliBin) +\ euclidianDistance([normalizedOrd(abiOrd)],[normalizedOrd(aliOrd)]) d_x[2][3] = euclidianDistance(abiNum,aniNum) + \ distanceNom(abiKat,aniKat) + distanceSimetris(abiBin,aniBin) +\ euclidianDistance([normalizedOrd(abiOrd)],[normalizedOrd(aniOrd)]) d_x = pd.DataFrame(d_x) d_x.style.hide_index()
Dari proses diatas, akan menampilkan jarak dalam bentuk dissimilarity matrix.
0 | 1 | 2 | 3 |
---|---|---|---|
Ali | Ani | Abi | |
Ali | 0 | ||
Ani | 5.83 | 0 | |
Abi | 2.91 | 3.91 | 0 |
Seluruh file percobaan diatas dapat di unduh disini