Algoritma Levenberg–Marquardt adalah salah satu algoritma yang digunakan untuk memperkirakan hasil berikutnya berdasarkan data-data yang sudah ada sebelumnya. Contoh yang dibahas kali ini adalah mengenai memperkirakan penjualan pada periode berikutnya berdasarkan data penjualan pada periode sebelumnya.
Algoritma ini biasa digunakan dalam menyelesaikan permasalahan nonlinier yang menggunakan prinisip pencarian nilai minimum berdasarkan jumlah kuadrat terendah. Proses ini biasanya ditemukan dalam kasus penyesuaian data ke dalam sebuah kurva.
Dalam kasus penerapannya ke dalam pemrograman, algoritma Levenberg–Marquardt kemudian dimodifikasi untuk diterjemahkan ke dalam bahasa pemrograman FORTRAN oleh Fletcher, sehingga algoritma ini terkadang disebut juga sebagai algoritma Levenberg–Marquardt-Fletcher
Diasumsikan ada 4 data barang yang sudah diketahui hasil penjualannya
Masing-masing barang memiliki data penjualan pada 5 periode sebelumnya
Maka tentukan prediksi penjualan untuk 3 periode berikutnya
Diasumsikan data penjualan adalah sebagai berikut:
Nama Barang | Periode1 | Periode2 | Periode3 | Periode4 | Periode5 |
---|---|---|---|---|---|
Pensil | 10 | 12 | 8 | 11 | 20 |
Penghapus | 15 | 12 | 13 | 14 | 14 |
Pena | 9 | 7 | 15 | 15 | 10 |
Penggaris | 1 | 2 | 4 | 12 | 13 |
Langkah pertama adalah memasukkan data-data yang digunakan.
Contoh data awal adalah sebagai berikut:
data=[10 12 8 11 20; ... 15 12 13 14 14; ... 9 7 15 15 10; ... 1 2 4 12 13];
Sebelum masuk kedalam langkah-langkah pembahasan algoritma, ada beberapa konstanta atau parameter yang harus diketahui, yaitu:
* Tentukan persamaan Non-linier yang digunakan
fx = @(x) sqrt(-1*x(1)*x(1) + -0.5*x(2)*x(2) + 0.5*x(3)*x(3) + 0.75*x(4)*x(4) + x(5)*x(5));
* Tentukan batas toleransi selisih data dan batas toleransi nilai fungsi yang diperbolehkan
Diasumsikan dalam kasus ini, batas toleransi selisih data adalah 0.0000001,
dan batas toleransi selisih nilai fungsi adalah 0.0000001
epsX = 1e-7; epsFX = 1e-7;
* Tentukan nama fungsi yang digunakan untuk menghitung matriks Jacobian
Metode yang digunakan adalah penaksiran Jacobian dengan selisih terbatas
jacobian = 'finiteJacobian';
* Tentukan jumlah iterasi yang digunakan dalam perhitungan
Diasumsikan dalam kasus ini, jumlah iterasi adalah 500 kali
maksIterasi = 500;
* Tentukan bobot selisih minimal dan maksimal untuk nantinya dibandingkan dengan selisih output
Diasumsikan dalam kasus ini, bobot selisih minimal adalah 0.25 dan bobot selisih maksimal adalah 0.75
minBobotSelisih = 0.25; maksBobotSelisih = 0.75;
Langkah-langkah penggunaan algoritma ini adalah
* Lakukan perhitungan pada masing-masing data (poin 1 – 2)
for i=1:size(data,1) . . .
1. Lakukan proses perhitungan dengan menggunakan metode Levenberg-Marquardt
Penjelasan tentang fungsi ini akan dijelaskan pada perhitungan dibawah ini (poin 1a – 1c)
output = LMF(fx,data(i,:)', epsX, ... epsFX, jacobian, maksIterasi, minBobotSelisih, maksBobotSelisih);
Memasuki perhitungan pada fungsi LMF
1a. Lakukan inisialisasi variabel yang digunakan dalam perhitungan (poin 1a1 – 1a7)
1a1. Tentukan jumlah data yang dihitung, yaitu sama dengan banyak data pada parameter data
Kemudian lakukan inisialisasi parameter epsX sebanyak jumlah data
jumlahData = length(data); epsX = epsX * ones(jumlahData,1);
1a2. Beri nilai awal lambda dengan angka 0 dan lambdaC dengan angka 1
lambda = 0; lambdaC = 1;
1a3. Hitung nilai output menggunakan fungsi yang sudah ditentukan sebelumnya
outputData = feval(fungsi,data);
1a4. Hitung jumlah kuadrat dari output data, yaitu kuadrat dari masing-masing elemen dalam output data
jumlahKuadratOutputData = outputData'*outputData;
1a5. Lakukan perhitungan untuk menghitung nilai JTJ dan JTOutput
Penjelasan tentang fungsi ini akan dijelaskan pada perhitungan dibawah ini
[JTJ,JTOutput] = HitungJTJJTOutput(fungsi,jacobian,data,outputData,epsX);
* Gunakan fungsi ini untuk menghitung nilai JTJ dan JTOutput
matriks Jacobian (J) dihitung menggunakan fungsi Jacobian
function [JTJ,JTOutput] = HitungJTJJTOutput(fungsi,jacobian,data,outputData,epsX) if isa(jacobian,'function_handle') J = jacobian(data); else J = feval(jacobian,fungsi,outputData,data,epsX); end JTJ = J'*J; JTOutput = J'*outputData;
* Gunakan fungsi ini untuk melakukan linierisasi pada fungsi non-linier,
Teknik yang digunakan adalah diferensiasi kompleks dengan metode Jacobian
function J = finiteJacobian(fungsi,outputData,data,epsX) jumlahData = length(data); J = zeros(length(outputData),jumlahData); for k = 1:jumlahData deltaX = .25 * epsX(k); if deltaX==0, deltaX=eps; end xData = data; xData(k) = xData(k) + deltaX; outputTerhitung = feval(fungsi,xData); J(:,k)=((outputTerhitung(:)-outputData(:))/deltaX); end
1a6. Hitung nilai skala kontrol D, yaitu nilai diagonal dari JTJ
Kemudian hitung akar dari skala tersebut
skalaD = diag(JTJ); skalaD(skalaD<=0)=1; akarSkalaD = sqrt(skalaD);
1a7. Beri nilai awal untuk jumlah iterasi dan jumlah iterasi delta yang akan dilakukan
iterasi = 0; iterasiDeltaJumlahKuadrat = 1;
* Lakukan proses perhitungan untuk menghitung nilai output (poin 1b)
1b. Lakukan perhitungan sampai salah satu kondisi terpenuhi (poin 1b1 – 1b5)
while 1 . . .
1b1. Simpan nilai diagonal dari matriks JTJ untuk digunakan dalam perhitungan selanjutnya
diagJTJ = diag(JTJ);
1b2. Lakukan perhitungan sampai selisih nilai output data dan output terhitung sudah kurang dari batas toleransi selisih data (poin 1b2a – 1b2l)
while 1 . . .
1b2a. Lakukan faktorisasi matriks JTJ menggunakan teknik Cholesky sampai variabel p bernilai 0
Jika variabel p belum bernilai 0, maka nilai lambda pada perulangan berikutnya akan dikalikan 2
while 1 UA = triu(JTJ,1); JTJ = UA' + UA + diag(diagJTJ+lambda*skalaD); [U,p] = chol(JTJ); if p==0, break, end lambda = 2*lambda; if lambda==0, lambda=1; end end
1b2b. Hitung nilai deltaX, kemudian hitung bobot dari matriks JTOutput
Jika bobot matriks JTOutput bernilai kurang dari 0, maka hentikan perhitungan
deltaX = U\(U'\JTOutput); bobotJTOutput = deltaX'*JTOutput; if bobotJTOutput<=0, break, end
1b2c. Lakukan perhitungan pada masing-masing data
Hitung nilai z, kemudian hitung nilai deltaS dengan rumus:
ds = 2 * JTOutput – z
for i=1:jumlahData z = diagJTJ(i)*deltaX(i); if i>1, z=JTJ(i,1:i-1)*deltaX(1:i-1)+z; end if i<jumlahdata, z="JTJ(i+1:jumlahData,i)'*deltaX(i+1:jumlahData)+z;" end="" deltas(i)="2*JTOutput(i)-z;" <="" pre="">
1b2d. Hitung nilai deltaQ dengan cara mengalikan setiap elemen deltaS dengan deltaX
deltaQ = deltaS'*deltaX;
1b2e. Hitung nilai deltaS yang baru, yaitu selisih antara dawa awal dengan deltaX
Kemudian hitung nilai output dari deltaS menggunakan fungsi Jacobian
deltaS = data-deltaX; outputTerhitung = feval(fungsi,deltaS);
1b2f. Hitung jumlah kuadrat dari masing-masing elemen dalam output terhitung
Kemudian hitung selisih dari jumlah kuadrat output data dengan jumlah kuadrat output terhitung
jumlahKuadratOutputTerhitung = outputTerhitung'*outputTerhitung; deltaOutput = jumlahKuadratOutputData-jumlahKuadratOutputTerhitung;
1b2g. Hentikan perhitungan apabila semua nilai elemen deltaX lebih rendah dari batas toleransi selisih data
atau jumlah iterasi yang dilakukan sudah melebihi batas maksimal perulangan
atau nilai selisih output jumlah kuadrat kurang dari batas toleransi selisih nilai fungsi
isSelesai = 1; if all((abs(deltaX)-epsX)<=0) || iterasiDeltaJumlahKuadrat>=maksIterasi || abs(deltaOutput)<=epsFX break end isSelesai = 0;
1b2h. Jika kondisi sebelumnya tidak terpenuhi, lanjutkan ke pengecekan kedua
Hentikan perhitungan apabila selisih output lebih dari bobot minimal selisih dikali dengan deltaQ
if deltaOutput>=minBobotSelisih*deltaQ, break, end
1b2i. Hitung nilai JTJ yang baru, variabel y dan variabel z
Nantinya variabel y akan digunakan untuk mengupdate nilai lambda yang baru
JTJ = U; y = .5; z = 2*bobotJTOutput-deltaOutput; if z>0, y=bobotJTOutput/z; end if y>.5, y=.5; end if y<.1, y=.1; end
1b2j. Jika faktorisasi dengan teknik Cholesky pada perhitungan sebelumnya langsung menghasilkan p = 0,
maka lakukan perhitungan dibawah ini untuk mendapatkan nilai lambda (poin 1b2j1 – 1b2j4)
if lambda==0 . . .
1b2j1. Hitung nilai y yang baru, yaitu 2 kali dari y sekarang
y = 2*y;
1b2j2. Lakukan perhitungan untuk mendapatkan nilai JTJ yang baru
for i = 1:jumlahData JTJ(i,i) = 1/JTJ(i,i); end for i = 2:jumlahData ii = i-1; for j= 1:ii JTJ(j,i) = -JTJ(j,j:ii)*JTJ(j:ii,i).*JTJ(i,i); end end for i = 1:jumlahData for j= i:jumlahData JTJ(i,j) = abs(JTJ(i,j:jumlahData)*JTJ(j,j:jumlahData)'); end end
1b2j3. Lakukan perhitungan pada masing-masing data
Hitung nilai z, kemudian cari nilai z tertinggi untuk dijadikan sebagai nilai lambda
lambda = 0; for i = 1:jumlahData z = JTJ(1:i,i)'*akarSkalaD(1:i)+z; if ilambda, lambda=z; end end
1b2j4. Hitung nilai jumlah perkalian antara setiap elemen pada diagonal JTJ yang baru dengan skala kontrol D
Jika nilai ini kurang dari nilai lambda yang telah ditemukan, maka ambil nilai ini sebagai nilai lambda yang baru
Kemudian hitung nilai lambda dan lambdaC yang baru dengan cara angka 1 dibagi dengan lambda sekarang
tr = diag(JTJ)'*skalaD; if tr<lambda, lambda="tr;" end="" lambdac="lambda;" <="" pre="">
1b2k. Hitung nilai lambda yang baru dengan membagi nilai lambda sebelumnya dengan variabel y
lambda = lambda/y;
1b2l. Hentikan perhitungan apabila nilsi selisih output sudah lebih dari 0
if deltaOutput>0, deltaOutput=-1e300; break, end
1b3. Hentikan perhitungan apabila memenuhi salah satu syarat sebelumnya,
yaitu apabila semua nilai elemen deltaX lebih rendah dari batas toleransi selisih data
atau jumlah iterasi yang dilakukan sudah melebihi batas maksimal perulangan
atau nilai selisih output jumlah kuadrat kurang dari batas toleransi selisih nilai fungsi
if isSelesai, break, end
1b4. Jika nilai selisih output lebih dari bobot selisih maksimal dikali dengan deltaQ,
maka nilai lambda akan dibagi dengan 2,
dan apabila nilainya kurang dari nilai lambdaC, maka nilai lambda akan dikembalikan menjadi 0
if deltaOutput > maksBobotSelisih*deltaQ lambda = lambda/2; if lambda < lambdaC, lambda=0; end end
1b5. Sebelum menuju ke perulangan berikutnya,
Gunakan nilai deltaS untuk menggantikan nilai data,
nilai output terhitung menggantikan nilai output data
nilai jumlah kuadrat dari output terhitung untuk menggantikan nilai jumlah kuadrat output data
kemudian hitung nilai JTJ dan JTOutput menggunakan nilai data dan output data yang baru
data=deltaS; outputData=outputTerhitung; jumlahKuadratOutputData=jumlahKuadratOutputTerhitung; [JTJ,JTOutput] = HitungJTJJTOutput(fungsi,jacobian,data,outputData,epsX);
1c. Nilai output adalah nilai data yang sudah dihitung sebelumnya
output = data;
2. Nilai prediksi akhir diambil dari nilai terakhir output yang sudah dihitung sebelumnya
lmf(i) = round(output(end),0);
Hasil akhir adalah:
Algoritma Levenberg-Marquardt / Levenberg-Marquardt-Fletcher Contoh: Memperkirakan penjualan pada periode berikutnya berdasarkan data penjualan pada periode sebelumnya Diasumsikan ada 4 data barang yang sudah diketahui hasil penjualannya Masing-masing barang memiliki data penjualan pada 5 periode sebelumnya Maka tentukan prediksi penjualan untuk 3 periode berikutnya Diasumsikan data penjualan adalah sebagai berikut: Nama Barang, Periode1, Periode2, Periode3, Periode4, Periode5 Pensil , 10 , 12 , 8 , 11 , 20 Penghapus , 15 , 12 , 13 , 14 , 14 Pena , 9 , 7 , 15 , 15 , 10 Penggaris , 1 , 2 , 4 , 12 , 13 Hasil Perhitungan dengan metode Levenberg-Marquardt / Levenberg-Marquardt-Fletcher Nama Barang, Periode1, Periode2, Periode3, Periode4, Periode5, Prediksi Periode berikutnya Pensil , 10 , 12 , 8 , 11 , 20 , 17 Penghapus , 15 , 12 , 13 , 14 , 14 , 13 Pena , 9 , 7 , 15 , 15 , 10 , 6 Penggaris , 1 , 2 , 4 , 12 , 13 , 12
Contoh modul / source code menggunakan Matlab dapat didownload disini:
Jika membutuhkan jasa kami dalam pembuatan program, keterangan selanjutnya dapat dilihat di Fasilitas dan Harga
Jika ada yang kurang paham dengan langkah-langkah algoritma diatas, silahkan berikan komentar Anda.
Selamat mencoba.
</lambda,>
</jumlahdata,>