Minggu, 06 Januari 2019

C# - Learning Vector Quantization




UPDATE: 01 FEBRUARI 2019
BAHASA: C#
SYSTEM:
  1. Windows 10
  2. IDE : SharpDevelop Version : 5.1.0.5216-0e58df71
  3. NET Version         : 4.7.03056

PENGANTAR

Mengenal LVQ yaitu algoritma non linear yang bekerja untuk melakukan klasifikasi supervisi sehingga kita harus mempunyai input dan target yang telah diketahui sebagai ‘bahan’ untuk mencari nilai ‘bobot’ yang optimal
Aturan LVQ agar berbeda dengan backpropagation yaitu lebih simple tidak menggunakan fungsi aktifasi, tapi yang lebih penting adalah bobot awal yang digunakan harus tepat.


DATASET:

Berikut contoh dataset yang kita gunakan, terdiri dari 3 kelas yaitu A, B, C dengan 2 ciri fitur yaitu X dan Y



Agar lebih mudah, kita plotkan saja ke versi 2 dimensi yaitu


Dataset diatas, disusun menjadi array seperti berikut
Berikut potongan kode untuk persiapan data

int jumlahParamater = 2; //jumlah kolom sample
int jumlahTarget = 3; //jumlah kelas
double[,] sample = new double[,]
  {{7,8},
  {8, 8},
  {9, 8},
  {8, 7},
  {8, 9},
  {1, 3},
  {3, 1},
  {5, 3},
  {3, 5},
  {2, 13},
  {3, 13},
  {4, 13},
  {3, 12},
  {3, 14}};
Program.Print(sample);

/* LVQ hanya support untuk 1 target paramater saja!
 * dan dimulai dari 1 sampai nilai tertentu!
 * sehingga tidak diijinkan untuk diisi angka 0
 */
int[,] target = new int[,]
  {{1},
  {1},
  {1},
  {1},
  {1},
  {2},
  {2},
  {2},
  {2},
  {3},
  {3},
  {3},
  {3},
  {3}};

Dilanjutkan dengan pengisian bobot, agar lebih bagus hasilnya, maka digunakan bobot secara random

double[,] bobot = LVQ.initRandomBobot(jumlahTarget,jumlahParamater);

Kita juga butuh normalisasi data dengan rentang 0 sampai dengan 1
    Ref: http://www.softscients.web.id/2014/09/teknik-untuk-melakukan-normalisasi.html


double[] minmax = DataNorm.MinMax(sample);

Ok, sesi training dimulai dengan membuat class LVQ

LVQ lvqPelatihan = new LVQ(); //panggil class LVQ

//masukan data sample nya!
lvqPelatihan.CreateSample(DataNorm.Normalisasi(sample, minmax[0], minmax[1])); 
lvqPelatihan.TARGET = target; //setting target
lvqPelatihan.MAX_EPOCH = 1000; //setting ulangan
lvqPelatihan.BOBOT = bobot; //setting bobot
lvqPelatihan.TARGET_ERROR = 0.0001; //nilai MSE minimum square error nya!
lvqPelatihan.MOMENTUM = true; //pakai momentum!
lvqPelatihan.Training(); //proses pelatihan dimulai!!!

Untuk mengetahui proses training, cek errornya

/* untuk mengetahui LVQ berjalan dengan baik!
 * maka kita bisa cek nilai error nya!
 * jika nilai error nya = 0
 * maka itu tandanya proses pelatihan 100% sukses
 * kalau tidak! maka mungkin ada yang tidak sesuai antara
 * target dan result nya
 */
 //cek nilai error nya!
Console.WriteLine("Cek nilai error : " + lvqPelatihan.CurrentError);

Setelah selesai, dapatkan nilai bobotnya!

//setelah selesai training!
//maka ambil bobotnya
double [,] bobotFinal = lvqPelatihan.BOBOT; 

/* kita akan mencoba melakukan proses pengujian!
 * kita ambil saja 2 baris saja!
 */
double[,] sample2 = new double[,]{
 {7, 8},
 {8, 8}
};
Console.WriteLine("Data berikut termasuk kelas");
Print(sample2);


LVQ lvqPengujian = new LVQ(); //panggil class LVQ

int[,] prediksi = lvqPengujian.Testing(
 DataNorm.Normalisasi(sample2, minmax[0], minmax[1]),bobotFinal);

Kode lengkap untuk training dan testing seperti berikut

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pustaka_LVQ;
namespace Demo_LVQ_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            Program.Test();
            Console.ReadKey();
        }
        private static void Test()
        {
            /* kita akan memberikan sebuah contoh LVQ yaitu 
             * menggunakan 2 parameter dengan data 14            
             */
            int jumlahParamater = 2; //jumlah kolom sample
            int jumlahTarget = 3; //jumlah kelas
            double[,] sample = new double[,]
                     {{7,8},
                                    {8, 8},
                                    {9, 8},
                                    {8, 7},
                                    {8, 9},
                                    {1, 3},
                                    {3, 1},
                                    {5, 3},
                                    {3, 5},
                                    {2, 13},
                                    {3, 13},
                                    {4, 13},
                                    {3, 12},
                                    {3, 14}};
            Program.Print(sample);
            
            /* LVQ hanya support untuk 1 target paramater saja!
             * dan dimulai dari 1 sampai nilai tertentu!
             * sehingga tidak diijinkan untuk diisi angka 0
             */
            int[,] target = new int[,]
                     {{1},
                            {1},
                            {1},
                            {1},
                            {1},
                            {2},
                            {2},
                            {2},
                            {2},
                            {3},
                            {3},
                            {3},
                            {3},
                            {3}};
            
            //biar mudah, kita menggunakan bobot random saja!
            double[,] bobot = LVQ.initRandomBobot(jumlahTarget,jumlahParamater); 
            

            //juga kita butuh normalisasi data!
            //dengan class DataNorm untuk 
         //menghitung nilai maksimal dan minimal sebuah data!
            double[] minmax = DataNorm.MinMax(sample); 

            LVQ lvqPelatihan = new LVQ(); //panggil class LVQ

            //masukan data sample nya!
            lvqPelatihan.CreateSample(DataNorm.Normalisasi(sample, minmax[0], minmax[1])); 
            lvqPelatihan.TARGET = target; //setting target
            lvqPelatihan.MAX_EPOCH = 1000; //setting ulangan
            lvqPelatihan.BOBOT = bobot; //setting bobot
            lvqPelatihan.TARGET_ERROR = 0.0001; //nilai MSE minimum square error nya!
            lvqPelatihan.MOMENTUM = true; //pakai momentum!
            lvqPelatihan.Training(); //proses pelatihan dimulai!!!
                        
            /* untuk mengetahui LVQ berjalan dengan baik!
             * maka kita bisa cek nilai error nya!
             * jika nilai error nya = 0
             * maka itu tandanya proses pelatihan 100% sukses
             * kalau tidak! maka mungkin ada yang tidak sesuai antara
             * target dan result nya
             */
             //cek nilai error nya!
            Console.WriteLine("Cek nilai error : " + lvqPelatihan.CurrentError);
            //nilai error itu dihitung dengan cara MSE antara target dan result nya!
            //jika nilai error != 0, maka ulangi saja proses training! 
            //dikarenakan juga inisiasi bobot itu dengan random
            //terkadang bisa berhasil - juga tidak!
            //cek nilai epoch nya!
            Console.WriteLine("Dicapai pada epoch : " + lvqPelatihan.EPOCH); 
            Console.WriteLine("Cek result nya : ");            
            Program.Print(lvqPelatihan.RESULT);
            Console.WriteLine("Hasil Akhir bobot nya : ");
            Program.Print(lvqPelatihan.BOBOT);
            
            if(lvqPelatihan.CurrentError!=0)
            {
                Console.WriteLine("proses pelatihan harus diulangi lagi!, " +
                               "karena error tidak mencapai 0");
                return;
            }

            /* kita akan mencoba melakukan proses pengujian!
             * kita ambil saja 2 baris saja!
             */
            double[,] sample2 = new double[,]{
                                    {7, 8},
                                    {8, 8}
            };
            Console.WriteLine("Data berikut termasuk kelas");
            Print(sample2);

            LVQ lvqPengujian = new LVQ(); //panggil class LVQ
            
            int[,] prediksi = lvqPengujian.Testing(
                DataNorm.Normalisasi(sample2, minmax[0], minmax[1]),bobot);

            Console.WriteLine("Cek prediksi nya : ");
            Program.Print(prediksi);




        }
        public static void Print(double[,] a)
        {
            for (int i = 0; i < a.GetLength(0);i++ )
            {
                for (int j = 0; j < a.GetLength(1);j++ )
                {
                    Console.Write(a[i, j] + " ");
                }
                Console.Write("\n");

            }
        }
        public static void Print(int[,] a)
        {
            for (int i = 0; i < a.GetLength(0); i++)
            {
                for (int j = 0; j < a.GetLength(1); j++)
                {
                    Console.Write(a[i, j] + " ");
                }
                Console.Write("\n");

            }
        }
    }
    




}


PUSTAKA LVQ:


Kode LVQ yaitu di LearningVectorQuantization.cs tidak memerlukan library tambahan karena ditulis sendiri.

Tidak ada komentar: