PREDIKSI PEMBELIAN PRODUK KURSUS DENGAN DATA STRUKTUR PYTHON Muhamad Kurniawan Fauzi 5312422037 Teknik Komputer/Teknik Elektro Universitas Negeri Semarang 2022/2023 BAB I PENDAHULUAN A. Latar Belakang Kemajuan teknologi yang sudah menyusuri dalam berbagai bidang, menuntut masyarakat untuk lebih cermat dalam pengolahan informasi. Namun dengan pesatnya perkembangan informasi yang tersedia seringkali membuat para peneliti untuk membuat keputusan yang salah atau barangkali tidak relevan terkait data yang disajikan. Hal ini tak hanya disebabkan karena ketidakpastian data yang disajikan, namun juga karena banyaknya data yang perlu diproses. AI (Artificial Intelligence) merupakan teknologi kecerdasan buatan yang diimplementasikan menggunakan suatu program komputer dalam bentuk mesin yang dapat belajar, memahami, merencanakan, dan beradaptasi. Dengan teknologi AI, tugas yang seringkali merupakan pekerjaan repetitif atau berulang-ulang dapat dengan mudah dilakukan untuk mempersingkat waktu dan menghindari kesalahan. Selain itu, dengan teknologi AI juga mampuu untuk memberikan gambaran atau bahkan memberikan kesimpulan terkait data yang diberikan. Semua itu tergantung dari program AI yang dibuat. Pada kasus ini akan menggunakan suatu purwarupa program yang melakukan suatu analisa pada data yang merujuk kepada suatu web bernama WeKTeK yang merupaka suatu website yang menyediakan kursus yang berkaitan dengan Teknik Komputer dengan uji coba menggunakan dataset yang di-generate secara acak dengan menggunakan struktur data yang ada pada Python. Data tersebut akan dilakukan tes dengan model untuk dilakukan uji ketepatan dengan data validasi yang juga di-generate dari program tadi. Dari data tersebut diperlukan suatu analisis data untuk dilakukan prediksi dan evaluasi dari model yang dibuat. Dengan itu juga akan diperlukan juga data pengguna yang sudah diprediksi untuk memiliki kecenderungan untuk membeli kursus di masa mendatang dengan pendekatan supervised learning dalam bentuk data mentahnya. B. Rumusan Masalah Dari kondisi yang diberikan maka perlu mnghimpun: 1. Apakah dari data yang diguakan akan menggambarkan dengan baik dengan perilaku pengguna pada kasus dunia nyata? 2. Dengan model yang digunakan, apakah sudah mampu untuk melakukan analisa data pada kasus dunia nyata? 3. Apa sajakah pendekatan yang bisa dilakukan untuk mendapatkan hasil yang lebih baik dengan model yang sama? BAB II PEMBAHASAN A. Konsep Kerja Konsep kerja dari program yang dibuat memiliki 3 (tiga) tahap utama, yaitu generasi_dataset (7 fungsi), konversi_npz (8 fungsi) dan machine_learning (6 fungsi) dengan fungsi yang dimaksud adalah banyaknya pemanggilan fungsi lain di luar dari ketiga fungsi itu yang berupakan fungsi yang didefinisikan. 1. Tahap 1: Generasi Dataset Untuk tahap pertama adalah tahap generasi_dataset, berikut kode lengkapnya: # A. Kode generasi dataset class Node: def __init__(self, data): self.data = data self.next = None class LinkedList: def __init__(self): self.head = None def append(self, data): new_node = Node(data) if self.head is None: self.head = new_node else: current = self.head while current.next: current = current.next current.next = new_node def read_names_from_file(file_name): with open(file_name, 'r') as input_file: lines = list(set(line.strip() for line in input_file.readlines())) return lines def generate_combined_names(names, num): combined_names = LinkedList() for _ in range(num): if not names: break num_strings = min(random.randint(1, 5), len(names)) selected_names = random.sample(names, num_strings) combined_name = ' '.join(selected_names).strip() combined_id = hash(combined_name) & sys.maxsize target = 1 if random.random() <= 0.1 else 0 # Tambahkan nilai target combined_names.append((combined_id, selected_names, target)) # Perbarui struktur data names = list(set(names) - set(selected_names)) return combined_names def generate_course_data(num_courses): course_data = [] for _ in range(num_courses): course_id = random.randint(1000, 9999) harga_kursus = (random.randint(50, 500)) * 1000 lama_kursus = random.randint(30, 300) category_id = random.randint(1, 30) course_data.append((course_id, category_id, lama_kursus)) return course_data harga_kursus, def calculate_probability(num_selected_courses): return (3*math.exp(-(3 * num_selected_courses))) def assign_course_ids(combined_names, course_data, num_courses): combined_list = LinkedList() current = combined_names.head while current: combined_id, combined_name, target = current.data num_selected_courses = 1 while random.random() <= calculate_probability(num_selected_courses): num_selected_courses += 1 selected_courses = random.sample(course_data, num_selected_courses) combined_list.append((combined_id, selected_courses, target)) current = current.next return combined_list def mean_dan_tambahkan_data(combined_list): bilangan_positif = [] current = combined_list.head while current: combined_id, course_data, target = current.data for i in range(len(course_data)): course_id, category_id, harga_kursus, course_data[i] lama_kursus = persentase_penyelesaian = round(random.uniform(0, 1), 2) lama_user_di_kursus = round(lama_kursus * persentase_penyelesaian * 1.25) review_int = 1 if random.random() <= 0.2 else 0 review_float = float(random.randint(1, 10)) if review_int == 1 else -1 kunjungan_terakhir = random.randint(0, 365) if random.random() <= 0.8 else 0 if review_float > 0: bilangan_positif.append(review_float) data = [combined_id, course_id, category_id, harga_kursus, persentase_penyelesaian, lama_user_di_kursus, lama_kursus, review_int, review_float, kunjungan_terakhir, target] course_data[i] = data current = current.next if len(bilangan_positif) > 0: mean = sum(bilangan_positif) / len(bilangan_positif) else: mean = 0 return mean def ubah_tampilkan_data(combined_list, mean, file): current = combined_list.head while current: combined_id, course_data, target = current.data for i in range(len(course_data)): if course_data[i][7] == 0: course_data[i][8] = mean print("Data akhir: ") for data in course_data: print(data, file=file) current = current.next return combined_list def ekspor_data(combined_list, file_csv, file): try: data = [] current = combined_list.head while current: combined_id, course_data, target = current.data for data_row in course_data: data.append(data_row) current = current.next df = pd.DataFrame(data, columns=['Combined ID', 'Course ID', 'Category ID', 'Harga Kursus', 'Persentase Penyelesaian', 'Lama User di Kursus', 'Lama Kursus', 'Review Int', 'Review Float', 'Kunjungan Terakhir', 'Target']) df.to_csv(file_csv, index=False, header=False) print(f"Data berhasil diekspor ke file {file_csv}", file=file) return data except Exception as e: print(f"Terjadi file=file) return None kesalahan saat mengekspor data: {str(e)}", def generasi_dataset(file): input_file = 'dictionary_nama_simplified.txt' num_nama = int(input("Masukkan jumlah nama diinginkan: ")) num_courses = int(input("Masukkan jumlah kursus diinginkan: ")) file_csv = input("Nama file .csv yang akan diekspor: ") + '.csv' names = read_names_from_file(input_file) combined_names = generate_combined_names(names, num_nama) course_data = generate_course_data(num_courses) combined_list = assign_course_ids(combined_names, course_data, num_courses) mean = mean_dan_tambahkan_data(combined_list) ubah_tampilkan_data(combined_list, mean, file) data_awal = ekspor_data(combined_list, file_csv, file) return data_awal, file_csv # Akhir kode generasi dataset data_awal, file_csv = generasi_dataset(file) Dari kode itu melakukan generasi dataset yang merujuk seperti layaknya website penyedia kursus online. Fungsi utama yang bekerja adalah fungsi generasi_dataset yang memanggil fungsi-fungsi lain. Berikut adalah penjabaran Langkah yang dilakukan: 1. Pada fungsi read_names_from_file, membaca nama yang ada pada file dictionary_nama_simplified.txt yang berisi deretan nama yang sudah ada sebelumnya 2. Fungsi generate_combined_names digunakan untuk menghasilkan kombinasi namanama dengan kursus-kursus yang terkait. Pertama, sebuah linked list kosong combined_names dibuat. Selanjutnya, nama-nama dipilih secara acak dari variable names untuk membentuk kombinasi nama. Setiap kombinasi nama diberikan sebuah ID yang dihasilkan dengan menggunakan fungsi hash dan bitwise AND yang kemudian disimpan dalam linked list bersama dengan kursus-kursus yang dipilih secara acak. Fungsi ini mengembalikan linked list combined_names. 3. Fungsi generate_course_data digunakan untuk menghasilkan data kursus-kursus secara acak. Jumlah kursus yang dihasilkan ditentukan oleh num_courses yang dihasilkan dari masukkan user. Setiap kursus memiliki ID, kategori, harga, dan lama kursus yang dihasilkan secara acak. ID pada kasus ini merujuk pada setiap kursus yang ada, sehingga setiap kursus memiliki ID yang unik. Sedangkan untuk kategori memiliki artia klasifikasi dari setiap kursus yang ada. Misalkan apabila ada kursus Python Web Development, Python IoT with Raspberry, Python Competitive Programming, C++ Competitive Programming dari data itu akan menghasilkan 2 kategori berbeda dan 4 ID yang berbeda. Sedangkan untuk lama kursus lebih cenderung untuk menghitung lamanya video on demand yang berada pada kursus tersebut. Data kursus-kursus ini disimpan dalam sebuah list course_data yang kemudian dikembalikan oleh fungsi. 4. Fungsi calculate_probability digunakan untuk menghitung probabilitas untuk memilih beberapa kursus terkait berdasarkan jumlah kursus yang dipilih sebelumnya. Rumus yang digunakan adalah 3 × 𝑒 −3×𝑛𝑢𝑚 𝑠𝑒𝑙𝑒𝑐𝑡𝑒𝑑 𝑐𝑜𝑢𝑟𝑠𝑒𝑠 . 5. Fungsi assign_course_ids mengambil linked list combined_names dan data kursuskursus course_data untuk menghasilkan data akhir dengan mengasosiasikan ID kursus dengan kombinasi nama-kursus. Data ini disimpan dalam linked list combined_list dan dikembalikan oleh fungsi. 6. Fungsi mean_dan_tambahkan_data mengiterasi melalui setiap kombinasi nama-kursus dalam combined_list dan menambahkan data tambahan seperti persentase penyelesaian, lama user di kursus, review, dan kunjungan terakhir. Jika terdapat review positif, nilai-nilai review tersebut akan dijumlahkan untuk dihitung rata-ratanya. Fungsi ini mengembalikan nilai mean dari review-review positif. 7. Fungsi ubah_tampilkan_data mengiterasi melalui setiap kombinasi nama-kursus dalam combined_list dan memperbarui nilai review dengan nilai mean jika review awalnya bernilai 0. Pada bagian selanjutnya adalah mengubah target dengan meninjau variable variable sebelumnya yaitu seperti harga_kursus, persentase_penyelesaian, lama_kursus, review_float dan kunjungan_terakhir. Penentuan nilai probabilitas target akan memiliki ketentuan sebagai berikut: a. probabilitas_target memiliki nilai awal 0.15 b. Ketentuan probabilitas yang diperoleh dari price2probtarget adalah: 𝑝𝑟𝑖𝑐𝑒2𝑝𝑟𝑜𝑏𝑡𝑎𝑟𝑔𝑒𝑡 = 0.12 ∗ (1 − ((( ℎ𝑎𝑟𝑔𝑎 𝑘𝑢𝑟𝑠𝑢𝑠 1 ) − 1) ∗ ( ))) 50000 4 Jika price2probtarget < 0 maka price2probtarget akan dikali dengan 4 3 Berikut adalah grafik dari price2probtarget: c. Ketentuan probabilitas yang diperoleh dari percent2probtarget memiliki rumus sebagai berikut: 𝑝𝑒𝑟𝑐𝑒𝑛𝑡2𝑝𝑟𝑜𝑏𝑡𝑎𝑟𝑔𝑒𝑡 = 0.1 ∗ ((( 𝑝𝑒𝑟𝑠𝑒𝑛𝑡𝑎𝑠𝑒 𝑝𝑒𝑛𝑦𝑒𝑙𝑒𝑠𝑎𝑖𝑎𝑛 1 ) − 1) ∗ ( )) 0.2 4 Berikut adalah grafik untuk percent2probtarget: d. Ketentuan probabilitas target yang diperoleh dari dur2probtarget memiliki rumus sebagai berikut: 𝑙𝑎𝑚𝑎 𝑘𝑢𝑟𝑠𝑢𝑠 ) 𝑑𝑢𝑟2𝑝𝑟𝑜𝑏𝑡𝑎𝑟𝑔𝑒𝑡 = 0.1 ∗ ( 120 Namun apabila lama_kursus lebih dari 2 jam maka akan mengguakan rumus berikut ini : 𝑑𝑢𝑟2𝑝𝑟𝑜𝑏𝑡𝑎𝑟𝑔𝑒𝑡 = 0.1 ∗ (2 ∗ 𝑙𝑎𝑚𝑎_𝑘𝑢𝑟𝑠𝑢𝑠 − 0.01 ∗ 𝑙𝑎𝑚𝑎_𝑘𝑢𝑟𝑠𝑢𝑠 2 ) Berikut adalah grafikuntuk dur2probtarget: e. Ketentuan review2probtarget memiliki ketentuan rumus sebagai berikut: (𝑟𝑒𝑣𝑖𝑒𝑤 𝑓𝑙𝑜𝑎𝑡 − 𝑚𝑒𝑎𝑛) 𝑟𝑒𝑣2𝑝𝑟𝑜𝑏𝑡𝑎𝑟𝑔𝑒𝑡 = 0.2 ∗ ( ) 10.0 − 𝑚𝑒𝑎𝑛 Jika mean memiliki nilai ≤ 5 maka variabel mean akan diganti dengan konstanta 5. Berikut adalah grafik untuk rev2probtarget: f. Setelah semua probabilitas diperoleh dari kelima variabel tadi maka akan dijumlahkan semuanya dengan probabilitas_target Setelah itu, data diubah menjadi format yang sesuai dan ditampilkan di file yang diberikan dengan mengembalikan combined_list. 8. Fungsi ekspor_data mengumpulkan data dari setiap kombinasi nama-kursus dalam combined_list dan menyimpannya dalam sebuah DataFrame menggunakan library pandas. DataFrame tersebut kemudian diekspor ke file CSV yang diberikan dengan menggunakan metode to_csv. 9. Fungsi generasi_dataset menggabungkan langkah-langkah sebelumnya untuk menghasilkan dataset secara keseluruhan. Input yang diminta termasuk jumlah nama yang diinginkan, jumlah kursus yang diinginkan, dan nama file CSV yang akan diekspor. Dataset awal disimpan dalam variabel data_awal, sementara file CSV disimpan dalam variabel file_csv. 2. Tahap 2: Preprocessing data yang kedua merupakan bagian di mana data yang sudah di ekspor akan dilakukan preprocessing dan diekspor ke dalam bentuk 3 bagian file .npz. ketiga file untuk dilakukan evaluasi dan prediksi pada fungsi machine_learning. Pada fungsi konversi_npz memiliki langkah-langkah sebagai berikut: a. Memuat data mentah dari file .csv. b. Mengambil data input awal dari data ke 4 hingga kedua dari belakang. Kemudian menyimpan variabel data_input untuk menyimpan data_mentah untuk machine_learning. Fungsi yang digunakan adalah ambil_input_awal c. Mengambil target awal dari data terakhir dari data_csv dengan ambil_target_awal. d. Mengacak data dengan pengacakan_index. e. Menyeimbangkan data dengan menghapus sampel yang dominan dengan mengguunakan penyeimbangan_data. f. Melakukan standarisasi data dengan melakukan scaling pada input yang sudah diseimbangkan dari penyeimbangan_data. Selain itu, dicari rata-rata dan juga standar deviasi dari data untuk preservasi data untuk hasmap pada machine_learning. g. Acak lagi data yang sudah distandarisasi dengan pengacakan_standarisasi_data. h. Bagi data untuk validasi, tes dan training. Di sini dilakukan perbandingan training:tes:validasi 8:1:1. i. Ekspor data ke file .npz. Berikut adalah kode lengkapnya: # B. Kode preprocessing dataset def muat_data_csv(file_csv, file): data_csv = np.loadtxt(file_csv, delimiter=',') print("Data CSV Raw:", file=file) for i in data_csv: print(i, file=file) return data_csv def ambil_input_awal(data_csv, file): input_awal = data_csv[:,3:-1] data_input = input_awal.copy() print("Input Awal Raw:", file=file) for i in input_awal: print(i, file=file) return input_awal, data_input def ambil_target_awal(data_csv, file): target_awal = data_csv[:,-1] print("Target Awal Raw: ", file=file) print(target_awal) return target_awal def pengacakan_index(input_awal, target_awal, file): index_diacak = np.arange(input_awal.shape[0]) print("Index Sebelum Diacak: ", file=file) print(index_diacak, file=file) np.random.shuffle(index_diacak) print("Idex Setelah Diacak: ", file=file) for i in index_diacak: print(i, file=file) input_diacak = input_awal[index_diacak] print("Input Diacak: ", file=file) for i in input_diacak: print(i, file=file) target_diacak = target_awal[index_diacak] print("Target Diacak: ", file=file) print(target_diacak) return input_diacak, target_diacak def penyeimbangan_data(input_diacak, target_diacak, file): angka_satu = int(np.sum(target_diacak)) angka_nol = 0 hapus_index = [] for i in range(target_diacak.shape[0]): if target_diacak[i] == 0: angka_nol += 1 if angka_nol > angka_satu: hapus_index.append(i) input_imbang = np.delete(input_diacak, hapus_index, axis=0) print("Input Setelah Dihapus:", file=file) for i in input_imbang: print(i, file=file) target_imbang = np.delete(target_diacak, hapus_index, axis=0) print("Target Setelah Diahpus", file=file) print(target_imbang) return input_imbang, target_imbang def pengacakan_standarisasi_data(input_imbang, target_imbang, file): input_standard = preprocessing.scale(input_imbang) print("Input Setelah Distandardisasi:", file=file) for i in input_standard: print(i, file=file) mean = input_imbang.mean(axis=0) std = input_imbang.std(axis=0) index_diacak = np.arange(input_standard.shape[0]) np.random.shuffle(index_diacak) input_diacak = input_standard[index_diacak] print("Input Setelah Diacak:", file=file) for i in input_diacak: print(i, file=file) target_diacak = target_imbang[index_diacak] print("Target Setelah Diacak:", file=file) print(target_diacak, file=file) return input_diacak, target_diacak, mean, std def bagi_data(input_diacak, target_diacak, file): banyak_sampel = input_diacak.shape[0] print("Banyak Sampel:", file=file) print(banyak_sampel, file=file) banyak_sampel_training = int(0.8 * banyak_sampel) print("Banyak Sampel Training:", file=file) print(banyak_sampel_training, file=file) banyak_sampel_validasi = int(0.1 * banyak_sampel) print("Banyak Sampel Validasi:", file=file) print(banyak_sampel_validasi, file=file) banyak_sampel_tes = banyak_sampel banyak_sampel_training banyak_sampel_validasi print("Banyak Sampel Tes:", file=file) print(banyak_sampel_tes, file=file) input_training = input_diacak[:banyak_sampel_training] print("Input Training:", file=file) print(input_training, file=file) target_training = target_diacak[:banyak_sampel_training] print("Target Training:", file=file) print(target_training, file=file) input_validasi = input_diacak[banyak_sampel_training:banyak_sampel_training+banyak_sampel_v alidasi] print("Input Validasi:", file=file) print(input_validasi, file=file) target_validasi= target_diacak[banyak_sampel_training:banyak_sampel_training+banyak_sampel_ validasi] print("Target Validasi:", file=file) print(target_validasi, file=file) input_tes = input_diacak[banyak_sampel_training+banyak_sampel_validasi:] print("Input Tes:", file=file) print(input_tes, file=file) target_tes = target_diacak[banyak_sampel_training+banyak_sampel_validasi:] print("Target Tes:", file=file) print(target_tes, file=file) print("Pembagian Data: ") print(np.sum(target_training), banyak_sampel_training, np.sum(target_training) / banyak_sampel_training, file=file) print(np.sum(target_validasi), banyak_sampel_validasi, np.sum(target_validasi) / banyak_sampel_validasi, file=file) print(np.sum(target_tes), banyak_sampel_tes, np.sum(target_tes) / banyak_sampel_tes, file=file) return input_training, target_training, input_validasi, target_validasi, input_tes, target_tes def ekspor_npz(file_csv, input_training, target_training, input_validasi, target_validasi, input_tes, target_tes): file_training = file_csv[:-4] + '_training' np.savez(file_training, inputs=input_training, targets=target_training) file_vlidasi = file_csv[:-4] + '_validasi' np.savez(file_vlidasi, inputs=input_validasi, targets=target_validasi) file_tes = file_csv[:-4] + '_tes' np.savez(file_tes, inputs=input_tes, targets=target_tes) return file_training, file_vlidasi, file_tes def konversi_npz(file_csv, file): try: data_csv = muat_data_csv(file_csv, file) input_awal, data_input = ambil_input_awal(data_csv, file) target_awal = ambil_target_awal(data_csv, file) input_diacak, target_diacak = pengacakan_index(input_awal, target_awal, file) input_imbang, target_imbang = penyeimbangan_data(input_diacak, target_diacak, file) input_diacak, target_diacak, mean, std = pengacakan_standarisasi_data(input_imbang, target_imbang, file) input_training, target_training, input_validasi, target_validasi, input_tes, target_tes = bagi_data(input_diacak, target_diacak, file) file_training, file_validasi, file_tes = ekspor_npz(file_csv, input_training, target_training, input_validasi, target_validasi, input_tes, target_tes) return file_training, file_validasi, file_tes, data_input, mean, std except Exception as e: print(f"Terjadi kesalahan saat memuat data: {str(e)}", file=file) # Akhir kode preprocessing dataset file_training, file_validasi, file_tes, konversi_npz(file_csv, file) data_input, mean, std = 3. Tahap 3: Pembelajaran mesin Tahap yang ketiga adalah bagian permbelajaran mesin yang digunakan untuk melakukan evaluasi dan prediksi dari data yang sudah dipersiapkan. Pada kali ini akan digunakan model dengan jenis FNN (FeedForward Neural Network) dengan menggunakan dua layer ReLU (Rectified Linear Unit) dengan masing-masing layer memiliki 16 neuron yang kemudian dihubungkan dengan satu layer output, yaitu dua node softmax. Dari model yang digunakan, terlihat bahwa model menggunakan aktifasi ReLU pada layer yang disembunyikan. Hal ini dikarenakan ReLU akan mengabaikan input dengan nilai negative yang mana dengan ini akan mengembalikan nilai input jika positif dan akan mengembalikan 0 jika negatif. Tujuan dilakukan pengabaian untuk nilai negative dengan menggunakan ReLU sendiri memiliki alasan karena untuk mengurangi korupsi ataupun noise pada data yang digunakan dan juga untuk meningkatkan akurasi pada uji coba dengan menggunakan data bernilai positif yang lebih akurat. Dengan ini, model akan lebih focus terhadap input yang bernilai positif yang mana akan optimal untuk data yang non-linear atau tidak secara langsung berkaitan. Kemudian untuk penggunaann neuron softmax pada output yaitu dikarenakan data yang digunakan memiliki klasifikasi data dengan dua buah kemungkinan. Untuk kasus ini, klasifikasi data didapat dari target yang hanya akan bernilai 0 atau 1. Berikut adalah kode selengkapnya: # C. Kode machine learning def hashmap(data_input, data_awal): diksi = {} for i in range(len(data_awal)): diksi[str(i)] = [] diksi[str(i)].append(data_awal[i]) diksi[str(i)].append(list(data_input[i])) return diksi def bongkar_data(file_training, file_validasi, file_tes): npz = np.load(file_training + ".npz") input_training, target_training = npz['inputs'].astype(float), npz['targets'].astype(int) print("Input Training:", file=file) print(input_training, file=file) print("Target Training:", file=file) print(target_training, file=file) npz = np.load(file_validasi + '.npz') input_validasi, target_validasi = npz['inputs'].astype(float), npz['targets'].astype(int) print("Input Validasi:", file=file) print(input_validasi, file=file) print("Target Validasi:", file=file) print(target_validasi, file=file) npz = np.load(file_tes + '.npz') input_tes, target_tes = npz['inputs'].astype(float), npz['targets'].astype(int) print("Input Tes:", file=file) print(input_tes, file=file) print("Target Tes:", file=file) print(target_tes, file=file) return input_training, target_training, input_validasi, target_validasi, input_tes, target_tes def infrastruktur_model(): output_size = 2 hidden_layer_size = 16 # Un-comment kode di bawah ini untuk mencoba dengan ukuran lainnya # output_size = int(input("Masukkan ukuran untuk model outputnya")) # hidden_layer_size = int(input("Masukkan untuk ukuran model yang disembunyikan")) model = tf.keras.Sequential([ tf.keras.layers.Dense(hidden_layer_size, activation='relu'), tf.keras.layers.Dense(hidden_layer_size, activation='relu'), tf.keras.layers.Dense(output_size, activation='softmax') ]) return model def kompiler_model(model): optimizer = 'adam' loss = 'sparse_categorical_crossentropy' metrics = ['accuracy'] # # Un-comment kode di bawah ini untuk coba-coba # optimizer = input('Masukkan optimizer yang akan digunakan: ') # loss = input('Masukkan kompiler loss yang akan digunakan: ') # metrics = input('Masukkan metrik yang akan digunakan: ') model.compile(optimizer=optimizer, loss=loss, metrics=metrics) return model def training_model(input_training, target_training, input_validasi, target_validasi, model): batch_size = 32 max_epochs = 100 early_stopping = tf.keras.callbacks.EarlyStopping(patience=2) # Un-comment kode di bawah ini untuk coba-coba # batch_size = int(input("Masukkan banyaknya data maksimal yang dikerjakan per epoch: ")) # max_epochs = int(input("Masukkan banyaknya iterasi yang dilakukan: ")) # patience = int(input("Masukkan banyaknya data maksimal yang dikerjakan per epoch: ")) # early_stopping = tf.keras.callbacks.EarlyStopping(patience=patience) model.fit( input_training, target_training, batch_size, max_epochs, callbacks=[early_stopping], validation_data=(input_validasi, target_validasi), verbose = 2 ) return model def prediksi(model, input_tes, diksi, mean, std): predictions = model.predict(input_tes) predicted_targets = np.argmax(predictions, axis=1) predicted_list = input_tes[predicted_targets == 1] restored_data = predicted_list * std + mean predicted_list_original = [] for i in range(len(restored_data)): for key, value in diksi.items(): if np.array_equal(restored_data[i], value[1]): predicted_list_original.append(value[0]) # Print out the predicted list in the original form. print("List prediksi dalam bentuk data awal:", file=file) for i in range(len(predicted_list_original)): print(predicted_list_original[i], file=file) def machine_learning(file_training, file_validasi, file_tes, file, data_awal, data_input, mean, std): diksi = hashmap(data_input, data_awal) input_training, target_training, input_validasi, target_validasi, input_tes, target_tes = bongkar_data(file_training, file_validasi, file_tes) model = infrastruktur_model() model = kompiler_model(model) model = training_model(input_training, target_training, input_validasi, target_validasi, model) test_loss, test_accuracy = model.evaluate(input_tes, target_tes) print('\nTest loss: {0:.2f}. Test accuracy: {1:.2f}%'.format(test_loss, test_accuracy*100.), file=file) prediksi(model, input_tes, diksi, mean, std) # Akhir kode machine learning machine_learning(file_training, file_validasi, file_tes, file, data_awal, data_input, mean, std) Berikut adalah alur kerja yang digunakan: a. Buat dictionary sebagai hash table untuk mapping antara data matriks dengan data awal dengan data mentah .csv. b. Membongkar data dari file-file .npz. c. Membagi data menjadi set validasi, training dan tes d. Mendefinisikan bentuk infrastruktur model yang akan digunakan e. Melakukan kompilasi model dengan menggunakan optimizer Adam dan fungsi loss sparse_categorical_crossentropy f. Latih model dengan set latihan g. Evaluasi model dengan set vaalidasi h. Lakukan prediksi dengan model menggunakan set tes i. Cetak hasil prediksi dengan menggunakan hashmap untuk mencetak dalam bentuk data awal B. Pembahasan Pada aplikasi analisis data ini dilakukan contoh penerapan analisis data dengan menggunakan pendekatan supervised learning dengan menggunakan dataset yang sudah direkayasa sedemikian rupa. Dari dataset tersebut memiliki probabilitas untuk bernilai 1 saat best-case dengan probabilitas 67% sedangkan 15% dengan kondisi default. Selain itu variabel yang digunakan untuk analisis data juga masih kurang bervariasi sehingga masih memungkinkan model untuk overfitting atau hapal dataset yang akan memperburuk hasil evaluasi. Model yang digunakan memiliki compiler awal dengan optimizer ‘adam’ yang mana akan secara dinamis mengubah laju pembelajaran model dengan memperlambat perubahan pada ssetiap langkah seiring dengan adaptasi laju pembelajarannya. Hal ini seringkali menjadi solusi untuk mangantsipasi model untuk tidak terjadi overfitting terlebih lagi dengan menggunakan parameter yang beragam. Hal ini karena merupakan gabungan dari kedua algoritma optimisasi lainnya, yaitu RMSProp dengan fleksibilitasnya dalam menanganu parameter yang beragam dan AdaGrad yang melakukan pembelajaran dinamis seiring Langkah yang dilakukan. Namun jika menggunakan RMSProp atau AdaGrad secara mandiri akan mengurangi hasil evaluasi, dengan itu disarankan untuk menggunakan Adam sebagai optimizer. Berikut adalah komparasi dari ketiga optimizer tadi dengan dataset yang relative sama: loss: 0.4286 - accuracy: 0.7515 adam loss: 0.4990 - accuracy: 0.7430 adagrad loss: 0.4619 - accuracy: 0.7177 rmsprop Selain optimizer, fungsi loss yang digunakan pada uji coba kali ini adalah sparse_categorical_crossentropy. Fungsi ini digunakan untuk menentukan seberapa akurat model dalam mengklasifikasikan input. Selain sparse_categorical_crossentropy, ada fungsi lain yang memiliki kemiripan fungsionalitas, yaitu binary_crossentropy. Namun, pada uji coba binary_crossentropy, fungsi ini memiliki penurunan performa. Berikut adalah komparasi antara sparse_categorical_crossentropy dengan optimizer Adam. binary_crossentropy dan BAB III KESIMPULAN Secara umum dari beberapa tes yang dilakukan, model akan mendapat akurasi sebanyak ~70% dan loss ~45% dengan menggunakan data yang sudah direkayasa masih belum bisa dikatakan sempurna untuk kasus di dunia nyata yang memiliki ketidakpastian yang besar. Namun sebagai purwarupa masih bisa digunakan untuk berbagai kasus, khususnya untuk menganalisis pengguna yang ada pada website WeKTeK yang bisa menganalisis dan prediksi pengguna. Beberapa pendekatan yang bisa dilakukan adalah dengan mengambil beberapa variabel tambahan yang bisa relevan pada kasus yang diatasi. Beberapa variabel tersebut bisa merupakan variabel turunan dari yang sudah ada, misalkan untuk menentukan banyaknya kursus yang sudah suatu pengguna beli, bisa digunakan jumlah waktu dari semua kursus yang ia beli, atau mungkin seluruh bantuan yang telah diberikan pada user seperti pada kasus lupa kata sandi dan promosi. Dengan menambahkan beberapa variabel tambahan sebagai input dapat menambah akurasi dari model yang digunakan. Berikut adalah link GirHub untuk project ini: https://github.com/Mousynano/simulasi_data_analysis.git