
WEKA – merupakan tools yang dibuat oleh universitas wakaito yang berbasis java sebagai implementasi java di ranah machine learning. Tampilan WEKA juga sangat sederhana dan fokus pada fungsionalitas. Berbasis Open Source memudahkan penggunaan API WEKA bila para developer ingin menggunakan kemampuan WEKA seutuhnya.
Machine learning sudah sangat luas digunakan oleh dunia industri, seperti hitachi – https://community.hitachivantara.com/s/global-search/weka
Dibanding dengan bahasa Python /R maka untuk membuat library machine learning di java agak lebih susah karena termasuk bahasa imperatif serta untuk run nya pun harus di compile sama seperti bahasa C/C++/C# ataupun bahasa Pascal/Basic. Sehingga alangkah baiknya untuk para developer lebih baik menggunakan library yang sudah ada. API WEKA bisa kalian temui dokumentasinya disini https://waikato.github.io/weka-wiki/.
Java Builder Gradle
Contents
Dalam membuat project di java, ada banyak pilihan java builder yang digunakan seperti Ant, Gradle, dan Maven. Tapi saya lebih suka menggunakan Gradle karena sudah terbiasa di android menggunakan gradle dalam builder nya. Untuk add WEKA pada gradle, tambahkan kode berikut, Sekalian juga ditambahkan library untuk mengolah data berbasis tabular seperti CSV yaitu table saw.
dependencies { testImplementation 'junit:junit:4.13' implementation group: 'nz.ac.waikato.cms.weka', name: 'weka-stable', version: '3.8.0' implementation group: 'tech.tablesaw', name: 'tablesaw-core', version: '0.38.3' }
Data Tabular dengan table Saw
Sebagai contoh dataset yang digunakan yaitu iris-data, bisa kalian peroleh dengan format csv dilink berikut https://www.kaggle.com/uciml/iris. Langsung saja, kita akan melihat struktur dan isi dataset menggunakan perintah berikut.
File file = new File("D:\\Weka-Java\\Iris.csv"); Table bushTable = Table.read().csv(file.getAbsoluteFile()); System.out.println(bushTable.structure()); System.out.println(bushTable);
hasilnya ditampilkan dalam bentuk tabular yang terdiri dari 6 kolom
Structure of Iris.csv Index | Column Name | Column Type | ------------------------------------------- 0 | Id | INTEGER | 1 | SepalLengthCm | DOUBLE | 2 | SepalWidthCm | DOUBLE | 3 | PetalLengthCm | DOUBLE | 4 | PetalWidthCm | DOUBLE | 5 | Species | STRING | Iris.csv Id | SepalLengthCm | SepalWidthCm | PetalLengthCm | PetalWidthCm | Species | ------------------------------------------------------------------------------------------------ 1 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa | 2 | 4.9 | 3 | 1.4 | 0.2 | Iris-setosa | 3 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa | 4 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa | 5 | 5 | 3.6 | 1.4 | 0.2 | Iris-setosa | 6 | 5.4 | 3.9 | 1.7 | 0.4 | Iris-setosa | 7 | 4.6 | 3.4 | 1.4 | 0.3 | Iris-setosa | 8 | 5 | 3.4 | 1.5 | 0.2 | Iris-setosa | 9 | 4.4 | 2.9 | 1.4 | 0.2 | Iris-setosa | 10 | 4.9 | 3.1 | 1.5 | 0.1 | Iris-setosa | ... | ... | ... | ... | ... | ... | 141 | 6.7 | 3.1 | 5.6 | 2.4 | Iris-virginica | 142 | 6.9 | 3.1 | 5.1 | 2.3 | Iris-virginica | 143 | 5.8 | 2.7 | 5.1 | 1.9 | Iris-virginica | 144 | 6.8 | 3.2 | 5.9 | 2.3 | Iris-virginica | 145 | 6.7 | 3.3 | 5.7 | 2.5 | Iris-virginica | 146 | 6.7 | 3 | 5.2 | 2.3 | Iris-virginica | 147 | 6.3 | 2.5 | 5 | 1.9 | Iris-virginica | 148 | 6.5 | 3 | 5.2 | 2 | Iris-virginica | 149 | 6.2 | 3.4 | 5.4 | 2.3 | Iris-virginica | 150 | 5.9 | 3 | 5.1 | 1.8 | Iris-virginica |
Loading CSV sebagai instances
Dataset yang digunakan oleh WEKA ada banyak seperti format CSV, arff, bahkan akses SQL seperti MYSQL Server. Misalkan dataset iris tersimpan di mysql server maka cukup gunakan perintah berikut bahkan lebih mudah karena bisa dengan query untuk memilih kolom tertentu saja yang akan digunakan
InstanceQuery query = new InstanceQuery(); query.setUsername("root"); query.setPassword(""); query.setDatabaseURL("jdbc:mariadb://localhost/dataset"); query.setQuery("select SepalLengthCm,SepalWidthCm, PetalLengthCm, PetalWidthCm, Species from iris_data"); Instances dataset_train = query.retrieveInstances();
namun bila menggunakan data CSV, kita harus melakukan filter tersendiri. Perhatikan nama kolom dibawah ini.
- Id
- SepalLengthCm
- SepalWidthCm
- PetalLengthCm
- PetalWidthCm
- Species
Hanya kolom 2 sampai dengan 6 yang akan digunakan untuk dataset. Namun jangan bingung, urutan index tetap seperti array pada java yaitu dimulai dari NOL. Sehingga no 0 yang akan dihapus menggunakan filter pada WEKA
Structure of Iris.csv Index | Column Name | Column Type | ------------------------------------------- 0 | Id | INTEGER | 1 | SepalLengthCm | DOUBLE | 2 | SepalWidthCm | DOUBLE | 3 | PetalLengthCm | DOUBLE | 4 | PetalWidthCm | DOUBLE | 5 | Species | STRING |
Kita coba dulu loading dataset di WEKA menggunakan format CSV.
File file = new File("D:\\Weka-Java\\Iris.csv"); // load CSV CSVLoader loader = new CSVLoader(); loader.setSource(file); Instances data = loader.getDataSet(); Enumeration <Attribute> atr = data.enumerateAttributes(); //System.out.println(atr.nextElement().name()); for (Enumeration<Attribute> e = data.enumerateAttributes(); e.hasMoreElements();){ System.out.println(e.nextElement().name()); }
Hasilnya
Id SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm Species
Remove Spesific Attribute arff WEKA
Pada penjelasan sebelumnya kita butuh menghapus 1 kolom pada index 0, maka cukup gunakan perintah API WEKA untuk remove spesific attribute menggunakan kode berikut
Kita lihat saja hasilnya
1 Iris-setosa --> Iris-setosa 2 Iris-setosa --> Iris-setosa 3 Iris-setosa --> Iris-setosa 4 Iris-setosa --> Iris-setosa 5 Iris-setosa --> Iris-setosa 6 Iris-setosa --> Iris-setosa 7 Iris-setosa --> Iris-setosa 8 Iris-setosa --> Iris-setosa 9 Iris-setosa --> Iris-setosa 10 Iris-setosa --> Iris-setosa 11 Iris-setosa --> Iris-setosa 12 Iris-setosa --> Iris-setosa 13 Iris-setosa --> Iris-setosa 14 Iris-setosa --> Iris-setosa 15 Iris-setosa --> Iris-setosa 16 Iris-setosa --> Iris-setosa 17 Iris-setosa --> Iris-setosa 18 Iris-setosa --> Iris-setosa 19 Iris-setosa --> Iris-setosa 20 Iris-setosa --> Iris-setosa 21 Iris-setosa --> Iris-setosa 22 Iris-setosa --> Iris-setosa 23 Iris-setosa --> Iris-setosa 24 Iris-setosa --> Iris-setosa 25 Iris-setosa --> Iris-setosa 26 Iris-setosa --> Iris-setosa 27 Iris-setosa --> Iris-setosa 28 Iris-setosa --> Iris-setosa 29 Iris-setosa --> Iris-setosa 30 Iris-setosa --> Iris-setosa 31 Iris-setosa --> Iris-setosa 32 Iris-setosa --> Iris-setosa 33 Iris-setosa --> Iris-setosa 34 Iris-setosa --> Iris-setosa 35 Iris-setosa --> Iris-setosa 36 Iris-setosa --> Iris-setosa 37 Iris-setosa --> Iris-setosa 38 Iris-setosa --> Iris-setosa 39 Iris-setosa --> Iris-setosa 40 Iris-setosa --> Iris-setosa 41 Iris-setosa --> Iris-setosa 42 Iris-setosa --> Iris-setosa 43 Iris-setosa --> Iris-setosa 44 Iris-setosa --> Iris-setosa 45 Iris-setosa --> Iris-setosa 46 Iris-setosa --> Iris-setosa 47 Iris-setosa --> Iris-setosa 48 Iris-setosa --> Iris-setosa 49 Iris-setosa --> Iris-setosa 50 Iris-setosa --> Iris-setosa 51 Iris-versicolor --> Iris-versicolor 52 Iris-versicolor --> Iris-versicolor 53 Iris-versicolor --> Iris-versicolor 54 Iris-versicolor --> Iris-versicolor 55 Iris-versicolor --> Iris-versicolor 56 Iris-versicolor --> Iris-versicolor 57 Iris-versicolor --> Iris-versicolor 58 Iris-versicolor --> Iris-versicolor 59 Iris-versicolor --> Iris-versicolor 60 Iris-versicolor --> Iris-versicolor 61 Iris-versicolor --> Iris-versicolor 62 Iris-versicolor --> Iris-versicolor 63 Iris-versicolor --> Iris-versicolor 64 Iris-versicolor --> Iris-versicolor 65 Iris-versicolor --> Iris-versicolor 66 Iris-versicolor --> Iris-versicolor 67 Iris-versicolor --> Iris-versicolor 68 Iris-versicolor --> Iris-versicolor 69 Iris-versicolor --> Iris-versicolor 70 Iris-versicolor --> Iris-versicolor 71 Iris-versicolor --> Iris-virginica * 72 Iris-versicolor --> Iris-versicolor 73 Iris-versicolor --> Iris-versicolor 74 Iris-versicolor --> Iris-versicolor 75 Iris-versicolor --> Iris-versicolor 76 Iris-versicolor --> Iris-versicolor 77 Iris-versicolor --> Iris-versicolor 78 Iris-versicolor --> Iris-virginica * 79 Iris-versicolor --> Iris-versicolor 80 Iris-versicolor --> Iris-versicolor 81 Iris-versicolor --> Iris-versicolor 82 Iris-versicolor --> Iris-versicolor 83 Iris-versicolor --> Iris-versicolor 84 Iris-versicolor --> Iris-versicolor 85 Iris-versicolor --> Iris-versicolor 86 Iris-versicolor --> Iris-versicolor 87 Iris-versicolor --> Iris-versicolor 88 Iris-versicolor --> Iris-versicolor 89 Iris-versicolor --> Iris-versicolor 90 Iris-versicolor --> Iris-versicolor 91 Iris-versicolor --> Iris-versicolor 92 Iris-versicolor --> Iris-versicolor 93 Iris-versicolor --> Iris-versicolor 94 Iris-versicolor --> Iris-versicolor 95 Iris-versicolor --> Iris-versicolor 96 Iris-versicolor --> Iris-versicolor 97 Iris-versicolor --> Iris-versicolor 98 Iris-versicolor --> Iris-versicolor 99 Iris-versicolor --> Iris-versicolor 100 Iris-versicolor --> Iris-versicolor 101 Iris-virginica --> Iris-virginica 102 Iris-virginica --> Iris-virginica 103 Iris-virginica --> Iris-virginica 104 Iris-virginica --> Iris-virginica 105 Iris-virginica --> Iris-virginica 106 Iris-virginica --> Iris-virginica 107 Iris-virginica --> Iris-versicolor * 108 Iris-virginica --> Iris-virginica 109 Iris-virginica --> Iris-virginica 110 Iris-virginica --> Iris-virginica 111 Iris-virginica --> Iris-virginica 112 Iris-virginica --> Iris-virginica 113 Iris-virginica --> Iris-virginica 114 Iris-virginica --> Iris-virginica 115 Iris-virginica --> Iris-virginica 116 Iris-virginica --> Iris-virginica 117 Iris-virginica --> Iris-virginica 118 Iris-virginica --> Iris-virginica 119 Iris-virginica --> Iris-virginica 120 Iris-virginica --> Iris-versicolor * 121 Iris-virginica --> Iris-virginica 122 Iris-virginica --> Iris-virginica 123 Iris-virginica --> Iris-virginica 124 Iris-virginica --> Iris-virginica 125 Iris-virginica --> Iris-virginica 126 Iris-virginica --> Iris-virginica 127 Iris-virginica --> Iris-virginica 128 Iris-virginica --> Iris-virginica 129 Iris-virginica --> Iris-virginica 130 Iris-virginica --> Iris-virginica 131 Iris-virginica --> Iris-virginica 132 Iris-virginica --> Iris-virginica 133 Iris-virginica --> Iris-virginica 134 Iris-virginica --> Iris-versicolor * 135 Iris-virginica --> Iris-versicolor * 136 Iris-virginica --> Iris-virginica 137 Iris-virginica --> Iris-virginica 138 Iris-virginica --> Iris-virginica 139 Iris-virginica --> Iris-virginica 140 Iris-virginica --> Iris-virginica 141 Iris-virginica --> Iris-virginica 142 Iris-virginica --> Iris-virginica 143 Iris-virginica --> Iris-virginica 144 Iris-virginica --> Iris-virginica 145 Iris-virginica --> Iris-virginica 146 Iris-virginica --> Iris-virginica 147 Iris-virginica --> Iris-virginica 148 Iris-virginica --> Iris-virginica 149 Iris-virginica --> Iris-virginica 150 Iris-virginica --> Iris-virginica
Save dan Load Model
Tentu setelah sesi training dengan hasil akurasi tinggi, maka model tersebut butuh disimpan untuk kemudian dapat digunakan kembali pada dataset training. Mekanisme penyimpanan model API WEKA menggunakan teknik serialisasi java. Tapi kita nggak usah ribet2 menggunakan kode yang panjang, namun cukup gunakan perintah API WEKA sebagai berikut
SerializationHelper.write("model.obj",model);
Adapun untuk loading model menggunakan API WEKA sebagai berikut
//loading model NaiveBayes cls = (NaiveBayes) weka.core.SerializationHelper.read("model.obj");
Membuat Attribute dan Instance API WEKA
Tentu tidak semua loading dataset menggunakan format CSV/ARFF ataupun akses ke mysql Server, namun bersifat on the fly alias dari beragam input data primitif java. Misalkan saja data array digunakan sebagai masukan untuk membuat instance API WEKA. Perhatikan kode berikut dibawah ini, yaitu mula-mula kita buat Attribut terlebih dahulu.
Attribute SepalLengthCm, SepalWidthCm,PetalLengthCm, PetalWidthCm; SepalLengthCm = new Attribute("SepalLengthCm"); SepalWidthCm = new Attribute("SepalWidthCm"); PetalLengthCm = new Attribute("PetalLengthCm"); PetalWidthCm = new Attribute("PetalWidthCm");
Kemudian dibuatlah arraylist untuk menampung semuanya
ArrayList attributes; attributes = new ArrayList(); attributes.add(SepalLengthCm); attributes.add(SepalWidthCm); attributes.add(PetalLengthCm); attributes.add(PetalWidthCm);
Jangan lupa membuat atribut kelas karena sifatnya kategorikal
ArrayList Species; Species = new ArrayList(); Species.add("Iris-setosa"); Species.add("Iris-versicolor"); Species.add("Iris-virginica"); attributes.add(new Attribute("Species", Species));
lanjutkan pembuatan Instances
Instances dataRaw = new Instances("TestInstances", attributes, 0);
Seperti biasa, kita cek menggunakan enumerator
for (Enumeration<Attribute> e = dataRaw.enumerateAttributes(); e.hasMoreElements();){ System.out.println(e.nextElement().name()); }
hasilnya
SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm Species
Ok, sudah cocok dengan format sebelumnya, mari kita isi dengan sebuah array. Perhatikan variabel nilai_sembarang yang bisa diisi dengan nilai sembarang karena wajib diisi yang akan berubah nilainya setelah hasil prediksi
dataRaw.setClassIndex(dataRaw.numAttributes() - 1); //setting kolom terakhir sebagai target double nilai_sembarang = 0; double[] value = new double[]{ 5.9, //sepal 3.0, 5.1, //petal 1.8, nilai_sembarang}; dataRaw.add(new DenseInstance(1.0, value));
Lakukan prediksi
double hasil = cls.classifyInstance(dataRaw.firstInstance()); String label = dataRaw.classAttribute().value((int) hasil); System.out.println("Prediksi: "+label);
Menghasilkan kelas
Iris-virginica