OpenCV di Java SVM Bagian 4

By | January 28, 2021
Print Friendly, PDF & Email
1,146 Views

Kalian sudah baca belum artikel sebelumnya mengenai cara menggunakan KMeans Clustering, disitu dijelaskan langkah demi langkah dalam mengubah Array ke Mat. Namun metode tersebut kurang begitu bagus karena akan banyak sekali waktu yang dibutuhkan! mengingat secara real akan ada ratusan ribu data yang harus diolah. Yuk ikuti saja terus artikel berserial ini yang akan membahas cara menggunakan function OpenCV-Java.

Mengubah Array ke Mat

Secara umum ada banyak array yang bisa dibentuk yaitu 2D sering disebut dengan data tabel karena terdiri dari baris dan kolom, ada juga yang 3D biasa disebut dengan tensor atau lebih cocok untuk mempresentasikan gambar 3 channel (RGB) jadi kayak bentuk kubus. Nah kalau di OpenCV untuk initial ke Mat menggunakan stream/vector. Maksudnya sebagai berikut

float [] trainingData = new float[]{ 1,1,  1,0, 0,1, 0,0};

Perhatikan variabel array diatas yang berupa vector, mempunyai panjang sebesar 8 yang sebenarnya merupakan sebuah dataset XY terdiri dari 4 baris dan 2 kolom = 8 data, maka untuk mengubah kedalam Mat agar mempunyai dimensi 4 baris dan 2 kolom, caranya sebagai berikut

int jumlah_record = 4;
int jumlah_fitur = 2;
Mat trainingDataMat = new Mat(jumlah_record,jumlah_fitur, CvType.CV_32F);
trainingDataMat.put(0, 0, trainingData);
System.out.println(trainingDataMat.dump());

Hasil output diatas yaitu

[1, 1;
 1, 0;
 0, 1;
 0, 0]

Kita lanjutkan lagi, perhatikan vector berikut

int [] labels = new int[]{ -1, 0, 0,-1};

Akan kita ubah menjadi 4 baris x 1 kolom saja

int jumlah_fitur_target = 1;
Mat labelsMat = new Mat(jumlah_record,jumlah_fitur_target, CvType.CV_32SC1);
labelsMat.put(0, 0, labels);
System.out.println(labelsMat.dump());

hasil

[-1;
 0;
 0;
 -1]

Dari kode diatas kita, sebenarnya sudah membuat dataset logika XOR berupa input dan target-label

See also  Belajar OpenCV di Java Bagian 2

Support Vector Machine di OpenCV-Java

Ingat baik-baik ya! SVM dipengaruhi oleh jenis kernel, misalkan kasus yang ditemui bersifat linear, ya gunakan saja kernel jenis linear sedangkan kalau kasusnya non linear maka bisa gunakan gaussian. Adapun pembahasan mengenai

  1. Dasar matematika pada Support Vector Machine, bisa dibaca disini
  2. Jenis kernel untuk SVM, bisa baca disini
  3. SVM dengan multiclass, bisa baca disini

Kalau kalian belum paham cara kerja SVM, baca saja artikel saya diatas. OK saya lanjutkan lagi SVM nya, yaitu

Membuat Criteria

Criteria perlu dibuat agar tahu kapan break akan didapatkan yaitu bisa melalui maksimal iterasi ataupun MSE yang telah dicapai

TermCriteria criteria = new TermCriteria(TermCriteria.MAX_ITER, 100000000, 1e-6);

Training SVM

Selanjutnya sudah lengkap, akan kita mulai saja dengan sesi training

SVM svm = SVM.create();
svm.setType(SVM.C_SVC);
svm.setKernel(SVM.RBF);
svm.setTermCriteria(criteria);
svm.train(trainingDataMat, Ml.ROW_SAMPLE, labelsMat);

Testing SVM

Kalian nggak sabar kan, ingin melihat hasilnya, kita langsung saja melakukan predict(), tapi jangan lupa untuk membuat variabel Mat sebagai penampung hasil

Mat results = new Mat();
svm.predict(trainingDataMat, results, 0);
System.out.println(results.dump());

hasilnya yaitu

[-1;
 0;
 0;
 -1]

Cucok dengan labels, tentu donk karena jenis kernel berupa RBF – Radial Basis Function

Coba saja ganti dengan SVM.Linear, pasti hasilnya tidak akan cocok, walaupun dikasih jutaaan iterasi

SVM svm = SVM.create();
svm.setType(SVM.C_SVC);
svm.setKernel(SVM.LINEAR);
svm.setTermCriteria(criteria);
svm.train(trainingDataMat, Ml.ROW_SAMPLE, labelsMat);

hasilnya tidak sama dengan target yang kita harapkan!

[0;
 0;
 0;
 0]

Kode lengkapnya bisa kalian pelajari dibawah ini

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.TermCriteria;
import org.opencv.ml.Ml;
import org.opencv.ml.SVM;


/**
 *
 * @author mulkan.ms@gmail.com
 */
public class DemoSVM {
    public static void main(String [] args)
    {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        //kita akan mencoba SVM untuk melakukan pemisahan
        //data yang bersifat non linear
        int [] labels = new int[]{ -1, 0, 0,-1};
        float [] trainingData = new float[]{ 1,1,
                                            1,0,
                                            0,1,
                                            0,0};
        int jumlah_record = 4;
        int jumlah_fitur = 2;
        Mat trainingDataMat = new Mat(jumlah_record,jumlah_fitur, CvType.CV_32F);
        trainingDataMat.put(0, 0, trainingData);
        trainingDataMat.put(0, 0, trainingData);
        System.out.println(trainingDataMat.dump());
        
        
        int jumlah_fitur_target = 1;
        Mat labelsMat = new Mat(jumlah_record,jumlah_fitur_target, CvType.CV_32SC1);
        labelsMat.put(0, 0, labels);        
        System.out.println(labelsMat.dump());
        
        TermCriteria criteria = new TermCriteria(TermCriteria.MAX_ITER, 100000000, 1e-6);
        
        SVM svm = SVM.create();
        svm.setType(SVM.C_SVC);
        svm.setKernel(SVM.RBF);
        svm.setTermCriteria(criteria);
        svm.train(trainingDataMat, Ml.ROW_SAMPLE, labelsMat);
        
        Mat results = new Mat();
        svm.predict(trainingDataMat, results, 0);
        System.out.println(results.dump());
        
    }
    
}

 

See also  OpenCV di Java untuk menghitung Histogram Bagian 5

 

 

 

Leave a Reply