Kebutuhan Hardware RemoveStopword.java

75 Normalisasi Z-Score No. Z-Score Threshold Minimal kemunculan kata Akurasi 9 9 61,5 10 10 59,8 11 2 1 44 12 2 46,4 13 3 51,3 14 4 35,5 15 5 53,7 16 6 53,8 17 7 54,8 18 8 55,1 19 9 54,9 20 10 52,9 21 3 1 33,5 22 2 42,8 23 3 57,4 24 4 54,9 25 5 56,2 26 6 55,5 27 7 58,9 28 8 52 29 9 54 30 10 53,1 31 4 1 40,2 32 2 35,6 33 3 44,4 34 4 51 35 5 58,3 36 6 52,2 37 7 51,8 38 8 57,9 39 9 54,1 40 10 49,5 41 5 1 49 42 2 64,2 43 3 58,4 44 4 58,9 45 5 60,3 46 6 62 76 Normalisasi Z-Score No. Z-Score Threshold Minimal kemunculan kata Akurasi 47 7 62,3 48 8 60,5 49 9 60,7 50 10 59,9 51 6 1 52,9 52 2 53,4 53 3 59,9 54 4 61 55 5 62,9 56 6 62,6 57 7 62,9 58 8 61,1 59 9 61,2 60 10 60,4 61 7 1 47,9 62 2 60 63 3 65,2 64 4 68,9 65 5 68,5 66 6 68 67 7 67,6 68 8 67,1 69 9 67 70 10 65,5 71 8 1 54,5 72 2 63,1 73 3 63 74 4 63,5 75 5 59,1 76 6 63,6 77 7 63,6 78 8 67,1 79 9 67 80 10 65,4 81 9 1 54,5 82 2 63,1 83 3 63 84 4 63,5 77 Normalisasi Z-Score No. Z-Score Threshold Minimal kemunculan kata Akurasi 85 5 59,1 86 6 63,6 87 7 63,6 88 8 67,1 89 9 67 90 10 65,4 91 10 1 55 92 2 64,1 93 3 62,5 94 4 63,4 95 5 58,9 96 6 63,6 97 7 64 98 8 67,1 99 9 67 100 10 65,4 Tabel 4.2 menunjukkan hasil percobaan menggunakan tahap normalisasi z-score. Percobaan dilakukan dengan mengubah-ubah nilai threshold normalisasi dan nilai minimal kemunculan kata. Z-Score Threshold = 7 berarti bobot kata yang dinormalisasi hanya bobot kata yang lebih dari sama dengan 7. Minimal kemunculan kata = 4 berarti kata yang digunakan hanyalah kata yang mempunyai jumlah kemunculan lebih dari sama dengan 4. Akurasi tertinggi ditandai dengan warna kuning yaitu sebesar 68,9. 78 Perbandingan akurasi setiap percobaan dapat dilihat lebih jelas pada grafik di bawah ini. Lihat Gambar 4.2 dan Gambar 4.3. Gambar 4.2 Hasil Akurasi Menggunakan Normalisasi Z-Score Gambar 4.3 Hasil Akurasi Menggunakan Normalisasi Z-Score Threshold = 7 10 20 30 40 50 60 70 80 90 100 1 2 3 4 5 6 7 8 9 10 ak u ras i minimal kemunculan kata Grafik Percobaan Menggunakan Normalisasi Z-Score Threshold 1 Threshold 2 Threshold 3 Threshold 4 Threshold 5 Threshold 6 Threshold 7 Threshold 8 Threshold 9 Threshold 10 10 20 30 40 50 60 70 80 90 100 1 2 3 4 5 6 7 8 9 10 ak u ras i minimal kemunculan kata Grafik Percobaan Menggunakan Normalisasi Z-Score Threshold = 7 79 3. Pengujian Menggunakan Normalisasi Min-Max Tabel 4.3 Tabel Pengujian Menggunakan Normalisasi Min-Max Normalisasi Min-Max No. Min-Max Threshold Minimal kemunculan kata Akurasi 1 1 1 41,6 2 2 43,8 3 3 44,8 4 4 45,3 5 5 45,1 6 6 44,4 7 7 43,7 8 8 42,1 9 9 42,8 10 10 43,3 11 2 1 49,1 12 2 50,1 13 3 49,7 14 4 50,4 15 5 50 16 6 49,9 17 7 48,9 18 8 49,4 19 9 46,7 20 10 49,8 21 3 1 64,5 22 2 64,7 23 3 65,3 24 4 64,9 25 5 64,8 26 6 64,4 27 7 65,1 28 8 64,5 29 9 64,6 30 10 62,9 31 4 1 67,1 32 2 72,3 33 3 73,9 34 4 74,4 80 Normalisasi Min-Max No. Min-Max Threshold Minimal kemunculan kata Akurasi 35 5 75,2 36 6 75,1 37 7 75,5 38 8 75 39 9 75 40 10 71,3 41 5 1 63,6 42 2 74,1 43 3 76,3 44 4 76,2 45 5 75,5 46 6 75,9 47 7 75,5 48 8 75,2 49 9 74,5 50 10 71 51 6 1 56,3 52 2 58,2 53 3 58,9 54 4 64,4 55 5 64,2 56 6 64,7 57 7 64,2 58 8 63,3 59 9 64,3 60 10 57,3 61 7 1 56,5 62 2 58,1 63 3 58,7 64 4 64,1 65 5 64,2 66 6 64,6 67 7 64,1 68 8 63,2 69 9 64,5 70 10 57 71 8 1 57,4 72 2 65 81 Normalisasi Min-Max No. Min-Max Threshold Minimal kemunculan kata Akurasi 73 3 69,6 74 4 65,2 75 5 68,6 76 6 68,2 77 7 67,6 78 8 67,1 79 9 67 80 10 65,4 81 9 1 57,4 82 2 65 83 3 69,6 84 4 65,2 85 5 68,6 86 6 68,2 87 7 67,6 88 8 67,1 89 9 67 90 10 65,4 91 10 1 57,5 92 2 65 93 3 69,6 94 4 65,2 95 5 68,6 96 6 68,2 97 7 67,5 98 8 67,1 99 9 67 100 10 65,4 Tabel 4.3 menunjukkan hasil percobaan menggunakan tahap normalisasi min-max. Percobaan dilakukan dengan mengubah-ubah nilai threshold normalisasi dan nilai minimal kemunculan kata. Min- Max Threshold = 5 berarti bobot kata yang dinormalisasi hanya bobot kata yang lebih dari sama dengan 5. Minimal kemunculan kata = 3 82 berarti kata yang digunakan hanyalah kata yang mempunyai jumlah kemunculan lebih dari sama dengan 3. Akurasi tertinggi ditandai dengan warna kuning yaitu sebesar 76,3. Perbandingan akurasi setiap percobaan dapat dilihat lebih jelas pada grafik di bawah ini. Lihat Gambar 4.4 dan Gambar 4.5. Gambar 4.4 Hasil Akurasi Menggunakan Normalisasi Min-Max 10 20 30 40 50 60 70 80 90 100 1 2 3 4 5 6 7 8 9 10 ak u ras i kemunculan kata Grafik Percobaan Menggunakan Normalisasi Min-Max Threshold 1 Threshold 2 Threshold 3 Threshold 4 Threshold 5 Threshold 6 Threshold 7 Threshold 8 Threshold 9 Threshold 10 83 Gambar 4.5 Hasil Akurasi Menggunakan Normalisasi Min-Max Threshold = 5 Berdasarkan hasil dari tiga macam perlakuan di atas, akurasi tertinggi diperoleh dengan menggunakan normalisasi min-max. Akurasi tertinggi sebesar 76,3 didapat dengan nilai min-max threshold = 5 dan minimal kemunculan kata = 3. Tabel 4.4 merupakan confusion matrix dari pengujian dengan nilai min- max threshold = 5 dan minimal kemunculan kata = 3. 10 20 30 40 50 60 70 80 90 100 1 2 3 4 5 6 7 8 9 10 ak u ras i minimal kemunculan kata Grafik Percobaan Menggunakan Normalisasi Min-Max Threshold = 5 84 Tabel 4.4 Confusion Matrix Pengujian Dengan Min-Max Threshold = 5 dan Minimal Kemunculan Kata = 3 Cinta Marah Sedih Senang Takut Cinta 168 10 4 17 1 Marah 37 129 19 3 12 Sedih 35 8 140 12 5 Senang 17 2 177 4 Takut 18 12 16 5 149 Berdasarkan confusion matrix di atas dan persamaan 2.5, didapat akurasi sebagai berikut: � � � = + + + + + + + + + + + + + + + + + + + + + + + + + + + + = ,

4.2 Implementasi

4.2.1 Preprocessing dan Pembobotan

Tahap ini merupakan tahap awal yang dilakukan sebelum masuk ke dalam proses K-Means clustering. Data mentah berupa teks tweet akan diubah menjadi vector numerik dengan nilai bobot tiap term dalam kumpulan dokumen tweet. Vector bobot akan disimpan dalam file bertipe csv atau comma separated values. 85

4.2.1.1 Tokenizing

Proses tokenizing memecah kalimat tweet menjadi token dengan memanfaatkan karakter spasi sebagai pemisah tiap token. Kemudian penulisan token diubah menjadi huruf kecil lowercase. Proses ini juga akan menghilangkan tanda baca, angka, karakter selain huruf, dan noise pada tweet. Noise yang dihilangkan antara lain username, url link, dan tanda retweet. Gambar 4.6 menunjukkan potongan source code proses tokenizing. String nextToken = stringTokenizer.nextToken; nextToken = nextToken.toLowerCase; if nextToken.length 2 { nextToken = nextToken.replaceAllHASHTAG, nextToken.substring1; nextToken = nextToken.replaceAllHASHTAG, ; } nextToken = nextToken.replaceAllURL, ; nextToken = nextToken.replaceAllUSERNAME, ; nextToken = nextToken.replaceAllSTARTS_WITH_NUMBER, ; nextToken = nextToken.replaceAllCONSECUTIVE_CHAR, 1; nextToken = nextToken.replaceAllNUMBER, ; nextToken = nextToken.replaceAllNON_WORD, ; Gambar 4.6 Potongan Source Code Tokenizing

4.2.1.2 Stopword Removal

Proses stopword removal menghilangkan kata-kata umum yang sering muncul. Gambar 4.7 menunjukkan sebagian stopword yang disimpan dalam file stopwords.txt. 86 gue saya akan gua kau juga ketika Gambar 4.7 File Stopwords.txt Kata-kata stopwords dalam file stopwords.txt akan disimpan dalam stopWordsList. Program akan mencocokkan kata masukan dengan kata yang ada dalam daftar stopWordsList, jika cocok, program akan menghapus kata tersebut. Gambar 4.8 menunjukkan potongan source code proses stopword removal. for int key : map.keySet { ArrayListString list = map.getkey; ArrayListString helper = new ArrayList; for int i = 0; i stopWordsList.size; i++ { if list.containsstopWordsList.geti { helper.addstopWordsList.geti; } } list.removeAllhelper; map.putkey, list; } Gambar 4.8 Potongan Source Code Stopword Removal

4.2.1.3 Stemming

Proses stemming mengembalikan kata-kata berimbuhan ke bentuk dasarnya. Proses dilakukan dengan menghapus awalan prefiks 87 dan akhiran sufiks. Dalam proses ini, program dibantu dengan kamus kata dasar. Gambar 4.9 menunjukkan sebagian kata dasar yang disimpan dalam file dictionary.txt. suster n susu n susuh n susuk n susul v susun n Gambar 4.9 File Dictionary.txt Gambar 4.10 menunjukkan potongan source code proses stemming yang merupakan implementasi dari algoritma stemming Bobby Nazief dan Mirna Adriani. word = deleteSuffix; if dictionary.containsword { word = originalWord; word = deletePrefix; word = deleteSuffix; word = deletePrefix; if dictionary.containsword { word = originalWord; } } Gambar 4.10 Potongan Source Code Stemming Hapus Imbuhan Selain mengubah kata berimbuhan ke bentuk dasar, stemming juga akan mengubah kata-kata yang disingkat atau kata tidak baku menjadi bentuk baku. Kata-kata yang memiliki kemiripan arti akan disatukan dengan mengasumsikan salah satu kata merupakan sinonim 88 dari kata yang lain. Gambar 4.11 menunjukkan penggalan isi file synonym.txt. selesai,selese takut,tkut,tkutin,takutt,atut,ditakut tisu,tissue muncul,timbul,mucul mati,tewas,gugur,meninggal teriak,jerit temu,jumpa cepat,cepet Gambar 4.11 File Synonym.txt Gambar 4.12 menunjukkan potongan source code proses stemming mengubah kata bersinonim. if synonym.containsKeyw { word = synonym.getw; return word; } else { return w; } Gambar 4.12 Potongan Source Code Stemming Sinonim Kata

4.2.1.4 Negation Handling

Dalam penelitian ini, kata “tidak”, “bukan”, dan “tanpa” tidak dihilangkan karena kata-kata tersebut dapat mengubah emosi yang terkandung dalam tweet. K ata “tidak”, “bukan”, dan “tanpa” akan disambung dengan kata di belakangnya. Gambar 4.13 menunjukkan potongan source code proses penanganan kata tidak. String check = list.geti; switch check { 89 case tidak: if i + 1 = list.size - 1 { list.seti, tidak + list.geti + 1; list.removei + 1; break; } } Gambar 4.13 Potongan Source Code Penanganan Kata “Tidak”

4.2.1.5 Pembobotan

Proses selanjutnya adalah pembobotan dengan menggunakan metode tf-idf. Tiap dokumen tweet direpresentasikan sebagai vector numerik dengan nilai bobot kata term yang didapat dengan persamaan 2.1. Gambar 4.14 menunjukkan potongan source code proses pembobotan menggunakan metode tf-idf. double tf; double idf; double tfIdf; tfIdfDocsVector = new LinkedHashMap; for int key : allTermsMap.keySet { double[] tfIdfVector = new double[terms.size]; int c = 0; for String term : terms { tf = tfCalculatorallTermsMap.getkey, term; idf = idfCalculatorallTermsMap, term; tfIdf = tf idf; tfIdfVector[c] = tfIdf; c++; } tfIdfDocsVector.putkey, tfIdfVector; } 90 public double tfCalculatorArrayListString docTerms, String termToCheck { int tf = 0; for String s : docTerms { if s.equalsIgnoreCasetermToCheck { tf++; } } return tf; } public double idfCalculatorLinkedHashMapInteger, ArrayListString allTermsMap, String termToCheck { int df = 0; for int key : allTermsMap.keySet { if allTermsMap.getkey.containstermToCheck { df++; } } if df = 0 { if df == allTermsMap.size { return 1 + Math.log10allTermsMap.size df; } else { return Math.log10allTermsMap.size df; } } else { return 0; } } Gambar 4.14 Potongan Source Code Pembobotan tf-idf

4.2.1.6 Hasil Preprocessing dan Pembobotan

Hasil dari tahap preprocessing dan pembobotan disimpan dalam file csv atau comma separated values. Hasil tahap preprocessing dan 91 pembobotan digunakan untuk melakukan proses selanjutnya yaitu pengujian sistem. Gambar 4.15 menunjukkan hasil tahap preprocessing dan pembobotan yang sudah disimpan dalam file feature.csv. Gambar 4.15 Hasil Tahap Preprocessing dan Pembobotan

4.2.2 Pengujian Sistem

Hasil tahap preprocessing dan pembobotan dipakai sebagai data masukan dari proses pengujian sistem. Data akan melalui tahap normalisasi, inisialisasi centroid, dan clustering. Hasil yang didapat dari pengujian sistem adalah akurasi pengelompokkan tweet berdasarkan emosi dan centroid akhir untuk proses pengujian data baru. 92

4.2.2.1 Normalisasi

Normalisasi dilakukan agar tidak ada nilai dalam data yang melampaui nilai lain. Normalisasi yang digunakan yaitu normalisasi z- score dan normalisasi min-max. Kedua normalisasi dilakukan secara terpisah untuk mengetahui normalisasi yang lebih cocok pada penelitian ini.

4.2.2.1.1 Z-Score

Gambar 4.16 menunjukkan potongan source code proses normalisasi menggunakan metode z-score. Normalisasi z-score menggunakan batas threshold. Nilai yang lebih dari sama dengan batas akan dinormalisasi, sedangkan nilai yang kurang dari batas tetap seperti semula. getMeanmatrix; getStdDevmatrix; for int i = 0; i matrix.length; i++ { for int j = 0; j matrix[i].length; j++ { if int matrix[i][j] = 3 { matrix[i][j] = matrix[i][j] - mean[i] std[i]; } } } Gambar 4.16 Potongan Source Code Normalisasi Z-Score

4.2.2.1.2 Min-Max

Gambar 4.17 menunjukkan potongan source code proses normalisasi menggunakan metode min-max. Normalisasi min-max 93 menggunakan batas threshold. Nilai yang lebih dari sama dengan batas akan dinormalisasi, sedangkan nilai yang kurang dari batas tetap seperti semula. getMinmatrix; getMaxmatrix; for int i = 0; i matrix[0].length; i++ { for int j = 0; j matrix.length; j++ { if int matrix[j][i] = 5 { if min[i] == max[i] { matrix[j][i] = 0.5; } else { matrix[j][i] = matrix[j][i] - min[i] max[i] - min[i]; } } } } Gambar 4.17 Potongan Source Code Normalisasi Min-Max

4.2.2.2 Variance Initialization

Gambar 4.18 menunjukkan potongan source code proses variance initialization. Proses variance initialization digunakan untuk menentukan centroid awal cluster. Centroid awal yang didapat dengan proses ini selanjutnya dipakai pada tahap K-Means clustering. getVariancetermsMap; sortMapfeature; getInitCentsortedMap, k; Gambar 4.18 Potongan Source Code Variance Initialization 94 Gambar 4.19 menunjukkan centroid awal yang diperoleh melalui tahap variance initialization. Centroid akan digunakan sebagai pusat awal pada proses clustering. Gambar 4.19 Centroid Awal Berdasarkan Variance Initialization

4.2.2.3 Langkah K-Means Clustering

K-Means clustering diawali dengan penentuan jumlah cluster. Langkah kedua adalah menempatkan data tweet pada cluster terdekat. Kedekatan data tweet dengan pusat cluster dihitung menggunakan cosine similarity. Langkah ketiga adalah meng-update pusat cluster dengan mencari rata-rata dari anggota cluster tersebut. Hasil rata-rata akan menjadi pusat centroid baru. Ulangi langkah kedua dan ketiga hingga centroid cluster tidak berubah. Pada penelitian ini, cluster yang digunakan adalah 5. Masing- masing cluster akan mewakili satu kelompok emosi. Cluster 1 merupakan cluster emosi cinta, cluster 2 merupakan cluster emosi marah, cluster 3 merupakan cluster emosi sedih, cluster 4 merupakan cluster emosi senang, dan cluster 5 merupakan cluster takut. Gambar 4.20 menunjukkan potongan source code proses K- Means clustering. 95 public LinkedHashMap kmeansClusteringLinkedHashMapInteger, double[] feature, LinkedHashMapInteger, double[] centroidMap, int k { clusters.clear; step.clear; for int key : centroidMap.keySet { step.putcentroidMap.getkey, new TreeSetInteger; } boolean go = true; int iteration = 1; while go { clusters = new LinkedHashMapstep; predicted = new int[feature.size]; for Integer key : feature.keySet { double[] cent = null; double[] cosSim = new double[k]; double[] distances = new double[k]; double sim = -1; double dist = 9999; int i = 0; for double[] c : clusters.keySet { double csim = new Distance.cosineSimilarityfeature.getkey, c; cosSim[i] = csim; if csim sim { sim = csim; cent = c; } i++; } clusters.getcent.addkey; int index = 0; 96 for int j = 1; j cosSim.length; j++ { if cosSim[j] cosSim[index] { index = j; } } predicted[key - 1] = index + 1; } step.clear; for double[] cent : clusters.keySet { double[] updatec = new double[cent.length]; for int d : clusters.getcent { double[] doc = feature.getd; for int i = 0; i updatec.length; i++ { updatec[i] += doc[i]; } } for int i = 0; i updatec.length; i++ { updatec[i] = clusters.getcent.size; } step.putupdatec, new TreeSetInteger; } String oldCent = , newCent = ; for double[] x : clusters.keySet { oldCent += Arrays.toStringx; } for double[] x : step.keySet { newCent += Arrays.toStringx; } if oldCent.equalsnewCent { go = false; } iteration++; 97 } return clusters; } Gambar 4.20 Potongan Source Code K-Means Clustering Gambar 4.21 menunjukkan hasil pengelompokkan tweet menggunakan K-Means clustering. Gambar 4.21 Hasil Implementasi K-Means Clustering

4.2.2.4 Output Centroid

Proses K-Means clustering akan menghasilkan keluaran berupa centroid akhir sebagai pusat dari masing-masing cluster. Centroid akhir akan digunakan untuk menguji data baru. Data baru akan dimasukkan ke sistem untuk mendapatkan label cluster menurut prediksi sistem. Gambar 4.22 menunjukkan centroid akhir hasil proses K-Means clustering. 98 Gambar 4.22 Output Centroid

4.2.2.5 Akurasi

Pada penelitian ini, pengujian akurasi yang digunakan adalah confusion matrix. Hasil prediksi akan dibandingkan dengan label aktual. Banyaknya kecocokan antara prediksi dengan label aktual akan mempengaruhi tingkat akurasi sistem. Gambar 4.23 menunjukkan potongan source code proses K- Means clustering. public void getConfusionMatrixint[] pred, int[] act, int centroid { int[][] confMat = new int[centroid][centroid]; int[] row = new int[centroid]; int rightAnswers = 0; for int i = 0; i pred.length; i++ { confMat[act[i] - 1] [pred[i] - 1]++; row[pred[i] - 1]++; } System.out.printlnConfusion Matrix : ; for int i = 0; i confMat.length; i++ { int[] x = confMat[i]; for int j = 0; j x.length; j++ { int d = x[j]; 99 System.out.print\t + d + ; if i == j { rightAnswers += d; } } System.out.println; } float accuration; int rows = 0; for int i = 0; i row.length; i++ { rows += row[i]; } System.out.println; accuration = float rightAnswers rows 100; System.out.printlnAccuration = + accuration + ; } Gambar 4.23 Potongan Source Code Confusion Matrix Gambar 4.24 Hasil Implementasi Confusion Matrix

4.2.3 Pengujian Data Baru

Pengujian data baru dilakukan pada sebuah kalimat tweet. Data baru tersebut akan melalui tahap ekstraksi fitur kemudian sistem akan menentukan tweet termasuk dalam cluster cinta, marah, sedih, senang, 100 atau takut. Penentuan dilakukan dengan mengukur kedekatan data baru pada centroid tiap cluster. Gambar 4.25 menunjukkan contoh tweet yang digunakan sebagai data baru. Menurut prediksi sistem, data baru termasuk dalam cluster senang. Hasil prediksi sistem ditunjukkan pada Gambar 4.26. astiastung 17.02.2016, Yogyakarta Selamat Wisuda Kelulusan dear, Moch Ryan Ardiansyah Semoga ilmunya bermanfaat : proudofyou Gambar 4.25 Input Uji Data Baru Gambar 4.26 Output Uji Data Baru 101

5. BAB V

PENUTUP

5.1 Kesimpulan

Berdasarkan hasil penelitian ini, analisis sentimen data Twitter menggunakan K-Means clustering, diperoleh kesimpulan sebagai berikut: 1. Percobaan tanpa normalisasi dengan minimal kemunculan kata 3 memperoleh hasil akurasi sebesar 69,4. 2. Percobaan menggunakan normalisasi z-score dengan batas nilai yang dinormalisasi 7 dan minimal kemunculan kata 4 memperoleh hasil akurasi sebesar 68,9. 3. Percobaan menggunakan normalisasi min-max dengan batas nilai yang dinormalisasi 5 dan minimal kemunculan kata 3 memperoleh hasil akurasi sebesar 76,3. 4. Berdasarkan kesimpulan 1, 2, dan 3, akurasi tertinggi diperoleh dengan perlakuan percobaan menggunakan metode normalisasi min-max. 5. Penelitian tentang analisis sentimen data Twitter menggunakan K- Means clustering mendapat akurasi tertinggi sebesar 76,3. 102

5.2 Saran

Berikut ini adalah saran yang dapat membantu penelitian ini agar lebih baik dan berkembang: 1. Kamus kata dasar dan kamus sinonim kata dilengkapi dan disesuaikan dengan bahasa yang digunakan dalam menulis tweet atau media sosial lain. 2. Data yang digunakan lebih banyak sehingga dapat mencakup lebih banyak kosakata dan pengenalan emosi menjadi lebih akurat. 3. Pengumpulan data tweet dilakukan secara otomatis menggunakan fasilitas Twitter API dan library bahasa pemrograman. 4. Pembuatan user interface untuk memudahkan pengguna menggunakan sistem ini. 103 DAFTAR PUSTAKA Agha, M. E., Ashour, W. M. 2012. Efficient and Fast Initialization Algorithm for K-means Clustering. International Journal of Intelligent Systems and Applications, 41, 21-31. Agusta, L. 2009. Perbandingan Algoritma Stemming Porter dengan Algoritma Nazief Adriani untuk Stemming Dokumen Teks Bahasa Indonesia. Konferensi Nasional Sistem dan Informatika, hal. 196-201. Bali. Al-Daoud, M. B. 2007. A New Algorithm for Cluster Initialization. International Journal of Computer, Electrical, Automation, Control and Information Engineering, 14. Destuardi, I., Sumpeno, S. 2009. Klasifikasi Emosi Untuk Teks Bahasa Indonesia Menggunakan Metode Naive Bayes. Seminar Nasional Pascasarjana Institut Teknologi Sepuluh Nopember. Surabaya. Goleman, D. 2006. Emotional Intelligence : Kecerdasan Emosional, Mengapa EI Lebih Penting Daripada IQ. T. Hermaya, Penerj. Jakarta: P.T. Gramedia Pustaka Utama. Liu, B. 2012. Sentiment Analysis and Opinion Mining. Morgan Claypool Publishers. Luhulima, Y. Y. 2013. Sentiment Analysis Pada Review Barang Berbahasa Indonesia dengan Metode K-Nearest Neighbor. Jurnal Mahasiswa PTIIK UB, 25, 1-7. Manning, C. D., Raghavan, P., Schütze, H. 2009. An Introduction to Information Retrieval. Cambridge: Cambridge University Press. Mustaffa, Z., Yusof, Y. 2011. A Comparison of Normalization Techniques in Predicting Dengue Outbreak. 2010 International Conference on Business and Economics Research. 1, hal. 345-349. Kuala Lumpur: IACSIT Press. Nur, M. Y., Santika, D. D. 2011. Analisis Sentimen Pada Dokumen Berbahasa Indonesia Dengan Pendekatan Support Vector Machine. Konferensi Nasional Sistem dan Informatika 2011. Bali. Putri, P. A. 2013. Implementasi Metode Improved K-Nearest Neighbor Pada Analisis Sentimen Twitter Berbahasa Indonesia. Jurnal Mahasiswa PTIIK UB, 22, 1-8. Shaver, P. R., Murdaya, U., Fraley, R. C. 2001. Structure of the Indonesian Emotion Lexicon. Asian Journal of Social Psychology, 4, 201-224. 104 Sujana, A. P. 2013. Memanfaatkan Big Data Untuk Mendeteksi Emosi. Jurnal Teknik Komputer Unikom - Komputika, 22, 1-4. Tan, P.-N., Steinbach, M., Kumar, V. 2006. Introduction To Data Mining. Boston: Pearson Addison Wesley. 105 LAMPIRAN A. Source Code 1. Tokenizing.java To change this license header, choose License Headers in Project Properties. To change this template file, choose Tools | Templates and open the template in the editor. package sentimentanalysis; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.StringTokenizer; author agung public class Tokenizing { private LinkedHashMapInteger, ArrayListString map; private ArrayListString token; private String fileLocation; private final static String HASHTAG = \\w+; private final static String NUMBER = [0-9]; private final static String NON_WORD = [\\p{L}\\p{Nd}]+; private final static String URL = www\\.[\\s]+|https?:[\\s]+; private final static String USERNAME = [\\s]+; private final static String STARTS_WITH_NUMBER = [0-9]\\s\\w+; private final static String CONSECUTIVE_CHAR = [.?\\w]\\1{2,}; private String[] label = {cinta, marah, sedih, senang, seneng, takut}; private String[] noise = {view, translation, jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec, rt, hours, hour, ago}; public TokenizingString fileLocation { this.fileLocation = fileLocation; } public Tokenizing { } public LinkedHashMap getAllTokenint j throws FileNotFoundException, IOException { map = new LinkedHashMap; String line; 106 BufferedReader bufferedReader = new BufferedReadernew FileReaderfileLocation; while line = bufferedReader.readLine = null { StringTokenizer stringTokenizer = new StringTokenizerline; token = new ArrayList; while stringTokenizer.hasMoreTokens { String nextToken = stringTokenizer.nextToken; nextToken = nextToken.toLowerCase; for String lbl : label { if lbl.equalsIgnoreCasenextToken { nextToken = ; } } for String thisnoise : noise { if thisnoise.equalsIgnoreCasenextToken { nextToken = ; } } if nextToken.length 2 { nextToken = nextToken.replaceAllHASHTAG, nextToken.substring1; nextToken = nextToken.replaceAllHASHTAG, ; } nextToken = nextToken.replaceAllURL, ; nextToken = nextToken.replaceAllUSERNAME, ; nextToken = nextToken.replaceAllSTARTS_WITH_NUMBER, ; nextToken = nextToken.replaceAllCONSECUTIVE_CHAR, 1; nextToken = nextToken.replaceAllNUMBER, ; nextToken = nextToken.replaceAllNON_WORD, ; if nextToken.length = 2 { if nextToken.contains { String[] temp = nextToken.split ; token.addAllArrays.asListtemp; token.remove; } else { token.addnextToken; } } } if token.size 1 { map.putj, token; j++; } } return map; } } 107

2. RemoveStopword.java

package sentimentanalysis; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.StringTokenizer; public class RemoveStopword { private LinkedHashMapInteger, ArrayListString map; private ArrayListString stopWordsList; private final String fileLocation; public RemoveStopwordString location throws IOException { this.fileLocation = location; loadStopWords; System.out.printlnstopWordsList; } public LinkedHashMap getWordsHashMap throws IOException { for int key : map.keySet { ArrayListString list = map.getkey; ArrayListString helper = new ArrayList; for int i = 0; i stopWordsList.size; i++ { if list.containsstopWordsList.geti { helper.addstopWordsList.geti; } } 108 list.removeAllhelper; map.putkey, list; } return map; } public ArrayList loadStopWords throws FileNotFoundException, IOException { String words = ; String line; BufferedReader bufferedReader = new BufferedReadernew FileReaderfileLocation; while line = bufferedReader.readLine = null { words += line + \n; } StringTokenizer stringTokenizer = new StringTokenizerwords; stopWordsList = new ArrayList; int i = 0; while stringTokenizer.hasMoreTokens { String nextToken = stringTokenizer.nextToken.toLowerCase; if stopWordsList.containsnextToken { stopWordsList.addi, nextToken; i++; } } return stopWordsList; } public void setWordsHashMapLinkedHashMap allToken { this.map = allToken; } 109 }

3. Stemming.java

package sentimentanalysis; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.; public class Stemming { private String word, originalWord; private ArrayListString dictionary; private TreeMapString, String synonym; private final String dictLocation, synLocation; public StemmingString location1, String location2 throws IOException { this.dictLocation = location1; this.synLocation = location2; loadDictionary; loadSynonym; } public LinkedHashMap stemLinkedHashMapInteger, ArrayListString map { ArrayListString helper; for int key : map.keySet { helper = map.getkey; for int i = 0; i helper.size; i++ { setWordhelper.geti; String stem = getStemWord; 110 String stem2 = getSynonymstem; helper.seti, stem2; } map.putkey, helper; } return map; } public final ArrayList loadDictionary throws FileNotFoundException, IOException { String words = ; String line; BufferedReader bufferedReader = new BufferedReadernew FileReaderdictLocation; while line = bufferedReader.readLine = null { words += line + \n; } StringTokenizer stringTokenizer = new StringTokenizerwords; dictionary = new ArrayList; int i = 0; while stringTokenizer.hasMoreTokens { String nextToken = stringTokenizer.nextToken; dictionary.addi, nextToken.toLowerCase; i++; } return dictionary; } public final TreeMap loadSynonym throws FileNotFoundException, IOException { String line; synonym = new TreeMap; 111 BufferedReader bufferedReader = new BufferedReadernew FileReadersynLocation; String delimiter = ,; while line = bufferedReader.readLine = null { if line.equals { continue; } String[] strData = line.splitdelimiter; for int i = 1; i strData.length; i++ { synonym.putstrData[i], strData[0]; } } return synonym; } public String getStemWord { word = deleteReduplicate; word = deleteSuffix; if dictionary.containsword { word = originalWord; word = deletePrefix; word = deleteSuffix; word = deletePrefix; if dictionary.containsword { word = originalWord; } } return word; } private String getSynonymString w { if synonym.containsKeyw { word = synonym.getw; return word; 112 } else { return w; } } public void setWordString word { this.word = word; originalWord = word; } private String deletePrefix { try { if dictionary.containsword { if word.startsWithdi { word = word.substring2; } else if word.startsWithke { word = word.substring2; } else if word.startsWithse { word = word.substring2; } else if word.startsWithku { word = word.substring2; } } if dictionary.containsword { if word.startsWithber { if dictionary.containsword.substring3 { word = word.substring3; } else if dictionary.containsword.substring2 { word = word.substring2; } } if word.startsWithbel { if dictionary.containsword.substring3 { 113 word = word.substring3; } } else if word.startsWithter { if dictionary.containsword.substring3 { word = word.substring3; } else if dictionary.containsword.substring2 { word = word.substring2; } } else if word.startsWithpe { if dictionary.containsword.substring2 { word = word.substring2; } if word.startsWithpel { if dictionary.containsword.substring3 { word = word.substring3; } else if dictionary.containsword.substring2 { word = word.substring2; } } else if word.startsWithper { if dictionary.containsword.substring3 { word = word.substring3; } else if dictionary.containsword.substring2 { word = word.substring2; } } else if word.startsWithpem { if word.substring3, 4.matches[bfv] { word = word.substring3; } else if dictionary.containsp + word.substring3 { word = p + word.substring3; } } else if word.startsWithpen { if word.substring3, 4.matches[jdcz] { word = word.substring3; 114 } else if dictionary.containst + word.substring3 { word = t + word.substring3; } else if word.startsWithpeng { if dictionary.containsk + word.substring4 { word = k + word.substring4; } else if dictionary.containsword.substring4 { word = word.substring4; } } else if word.startsWithpeny { if dictionary.containss + word.substring4 { word = s + word.substring4; } } } } } if dictionary.containsword { if word.startsWithme { if dictionary.containsword.substring2 { word = word.substring2; } else if word.startsWithmem { if word.substring3, 4.matches[bpf] { word = word.substring3; } else if dictionary.containsp + word.substring3 { word = p + word.substring3; } } else if word.startsWithmen { if word.substring3, 4.matches[cdj] { word = word.substring3; } else if dictionary.containst + word.substring3 { word = t + word.substring3; } else if word.startsWithmeng { if word.substring4, 5.matches[gh] {