<jupyter_start><jupyter_text>Analisis Peramalan Penjualan Peralatan Laboratorium Menggunakan Metode ARIMA Kelompok 08 Kelas ITS05     Indrianto Kuseni      <NAME>      <NAME>   1. Business Understanding  Identifikasi Permasalahan Bisnis    Permasalahan bisnis yang dapat diidentifikasi adalah bagimana membangun sebuah sistem yang dapat menganalisa peramalan penjualan produk peralatan kesehatan untuk setiap kota di Bali dan sekitarnya, sehingga rantai pasok (supply chain) dapat diperkirakan dan terencana dengan baik. Asumsi, Kebutuhan, dan Limitasi    Analisis dan pembuatan sistem/aplikasi ini memerlukan data histori setiap transaksi yang terjadi untuk setiap kota dan kategori barang/alkes yang terjual. Berdasarkan data histori tersebut dapat dipelajari polanya berdasarkan urutan waktu (time series), sehingga trendnya dapat dipelajari dan  dijadikan dasar untuk prediksi kebutuhan di waktu yang akan datang.     2. Data Understanding dan Data Cleansing<jupyter_code># import librari yang diperlukan
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.metrics import mean_squared_error
from math import sqrt
import ipywidgets as widgets
# load data 
dts=pd.read_csv('detail_penjualan_4.csv', header=0,parse_dates=True, index_col='tgl_jual')<jupyter_output><empty_output><jupyter_text>Cek lima data awal<jupyter_code># cek lima data awal
dts=dts.copy()
dts.head(5)<jupyter_output><empty_output><jupyter_text>Cek lima data Akhir<jupyter_code># cek lima data akhir
dts.tail()<jupyter_output><empty_output><jupyter_text>Cek Informasi Tipe Data<jupyter_code>#cek type data
dts.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 17107 entries, 2016-01-04 to 2019-03-29
Data columns (total 19 columns):
 #   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  
 0   id             17107 non-null  int64  
 1   no_faktur      17107 non-null  object 
 2   idbarang       17103 non-null  object 
 3   sn             0 non-null      float64
 4   qtt            17107 non-null  int64  
 5   hrg_jual       17107 non-null  float64
 6   pot_onf        17107 non-null  float64
 7   pot_off        17107 non-null  float64
 8   hrg_beli       17107 non-null  object 
 9   nama_barang    17107 non-null  object 
 10  satuan         17051 non-null  object 
 11  idkategori     17107 non-null  object 
 12  nama_kategori  17107 non-null  object 
 13  merek          17107 non-null  object 
 14  nama_merek     17107 non-null  object 
 15  idcustomer     17107 non-null  int64  
 16  nama_customer  17107 non-null  object 
 17  alamat         16326 non-null  ob[...]<jupyter_text>Drop Fitur yang tidak diperlukan<jupyter_code># karena tidak semua fitur digunakan, maka dilakukan penghapusan fitur yang tidak digunakan
# fitur yang dipertahankan untuk analisis adalah 'tgl_jual', 'qtt', 'kota', 'nama_kategori'
# fitur 'kota' dan 'nama_kategori' digunakan untuk mengelompokkan dataset per kota per nama_kategori..agar dapat melakukan prediksi jumlah barang yang dapat dijual untuk setiap kategori di kota tertentu
dt_an=dts.drop(['id', 'no_faktur', 'idbarang', 'sn', 'pot_onf',
       'pot_off', 'hrg_beli','nama_barang', 'satuan',
       'idkategori', 'merek', 'nama_merek', 'idcustomer','hrg_jual',
       'nama_customer', 'alamat'],axis='columns')
# kota dan nama_kategori dibuat kapital
dt_an['kota']=dt_an['kota'].str.upper()
dt_an['nama_kategori']=dt_an['nama_kategori'].str.upper()
dt_an<jupyter_output><empty_output><jupyter_text>Cek Data Kosong<jupyter_code>#cek data kosong 
dt_an.isnull().sum().sum()<jupyter_output><empty_output><jupyter_text>3. Data Preparation    Pada tahapan ini dilakukan pengelompokkan data berdasarkan kota dan nama kategori barang, sebagai contoh disini data dikelompokkan berdasarkan Kota "Denpasar" dengan kategori "Mikrobiologi".<jupyter_code>#mengelompokkan data berdasarkan kota dan nama_kategori
dtg=dt_an.groupby(['kota','nama_kategori'])
dtg=dtg.get_group(('DENPASAR','MIKROBIOLOGI'))
dtg
dtg.shape<jupyter_output><empty_output><jupyter_text>Statistik     Menampilkan informasi statistik dasar dari data yang dikelompokkan berdasarkan kota dan nama kategori<jupyter_code>#statistik deskriptive
dtg.describe()<jupyter_output><empty_output><jupyter_text>Visualisasi Data    Ploting data yang dikelompokkan per 6 bulan mulai dari 2016-01 s.d 2020-01<jupyter_code># visualisasi data 
dtg_viz=dtg.plot()<jupyter_output><empty_output><jupyter_text>Pencuplikan Ulang Data    Agar observasi lebih jelas, data dicuplik ulang/resampling menjadi data bulanan dengan nilai rata-rata<jupyter_code># resampling ke data bulanan deng menjumlahkan rata-rata
dtg_b=dtg.resample('M').mean()
dtg_b.plot()<jupyter_output><empty_output><jupyter_text>4. Analytical Approach: Model Selection and Metric Analysis  Dekomposisi Data    Selanjutnya visualisasi pada gambar di atas di dekomposisi untuk menemukan trend, seasonal dan residu yang bermanfaat untuk menemukan parameter-parameter yang akan digunakan pada model yang akan digunakan.   Dekomposisi Model Additive<jupyter_code># Dekompose
from statsmodels.tsa.seasonal import seasonal_decompose
seas_add=seasonal_decompose(dtg_b, model='additive')
seas_add.plot()<jupyter_output><empty_output><jupyter_text>Dekomposisi Model Multiplicative<jupyter_code>seas_mul=seasonal_decompose(dtg_b, model='multiplicative').plot()<jupyter_output><empty_output><jupyter_text>Plotting Autocorrelation dan Partial Autocorrelation    Plotting autocorrelation ini bermanfaat untuk mencari jumlah lag (p) sebagai salah satu parameter yang diperlukan.<jupyter_code># plot autocorelasi 
from pandas.plotting import autocorrelation_plot
autocorrelation_plot(dtg_b)
# dari ploting autocorrelation di atas, maka nilai p berada di sekitar 3 p=3, 
# nilai diff dapat dilihat dari trend line yang lebih mengarah ke polinomial d=2
# q untuk banyaknya windows untuk MA q=1
# lihat partial autocorrelation
from statsmodels.graphics.tsaplots import plot_pacf
plot_pacf(dtg_b,lags=20)<jupyter_output>/home/alif/Videos/venv/lib/python3.9/site-packages/statsmodels/graphics/tsaplots.py:348: FutureWarning: The default method 'yw' can produce PACF values outside of the [-1,1] interval. After 0.13, the default will change tounadjusted Yule-Walker ('ywm'). You can use this method now by setting method='ywm'.
  warnings.warn(<jupyter_text>Pemrosesan Data dengan Model ARIMA    Pemrosesan data dengan model ARIMA dengan parameter p, d dan q yang sudah didapatkan dari proses seblumnya (dekomposisi dan autocorrelation) yang hasilnya dapat dilihat pada ringkasan berikut:<jupyter_code>from statsmodels.tsa.arima.model import ARIMA
model=ARIMA((dtg_b),order=(4,2,1))
fit_model=model.fit()
fit_model.summary()<jupyter_output><empty_output><jupyter_text>Plotting Data Residu<jupyter_code>#plot residu
residu=fit_model.resid.plot()<jupyter_output><empty_output><jupyter_text>Prediksi Data    Berikut adalah prediksi penjualan dengan menggunakan ARIMA untuk 5 periode berikutnya.<jupyter_code>hasil_pred=fit_model.forecast(5)
hasil_pred<jupyter_output><empty_output><jupyter_text>Plotting Data Bulanan VS Data Prediksi<jupyter_code>yh=fit_model.predict()
yh.head()
plt.plot(dtg_b, label='data bulanan')
plt.plot(yh,label='data prediksi',color='red')
plt.legend(loc='upper left')
plt.show()<jupyter_output><empty_output><jupyter_text>Validasi dan Evaluasi Model    Validasi data pada analisis ini dilakukan menggunakan model walk forward, sedangkan untuk evaluasi model menggunakan RMSE. Sebelumnya data displit menjadi data latih dan data uji dengan proporsi 80:20.  Split data Latih dan data Uji<jupyter_code>uk_train=int(dtg_b.shape[0]*0.8)
X=dtg_b.values
train, test =X[0:uk_train],X[uk_train:]<jupyter_output><empty_output><jupyter_text>Data Latih: 5 Data Latih Awal<jupyter_code>train[0:5]<jupyter_output><empty_output><jupyter_text>Data Uji: 5 Data Uji Awal<jupyter_code>test[0:5]<jupyter_output><empty_output><jupyter_text>Plotting Hasil Prediksi dan Hasil Evaluasi    Berikut ini adalah plotting hasil prediksi menggunakan data uji dan hasil evaluasi model dengan RMSE<jupyter_code># Validasi dengan model walk forward arima
# Evaluasi dengan RMSE

log= [x for x in train]
lst_prediksi = list()

for t in range(len(test)):
	model = ARIMA(log, order=(3,2,1))
	fit_model = model.fit()
	hasil = fit_model.forecast()
	yh = hasil[0]
	lst_prediksi.append(yh)
	obs = test[t]
	log.append(obs)
	print('prediksi=%f, observasi=%f' % (yh, obs))
    
# evaluasi forcast
rmse = sqrt(mean_squared_error(test, lst_prediksi))
print('Test RMSE: %.3f' % rmse)

# plot forecasts vs prediksi hasil ev
plt.plot(test, label="data uji",color='blue')
plt.plot(lst_prediksi, label='data prediksi',color='green')
plt.legend(loc='upper left')
plt.show()<jupyter_output>prediksi=1.492578, observasi=1.500000
prediksi=1.421487, observasi=5.062500
prediksi=2.710669, observasi=5.310345
prediksi=3.408548, observasi=8.352941
prediksi=4.710301, observasi=3.086957
prediksi=4.890790, observasi=12.352941
prediksi=7.400910, observasi=3.821429
prediksi=7.350162, observasi=3.000000
prediksi=4.280168, observasi=4.073171
prediksi=7.006092, observasi=13.139535
Test RMSE: 4.149
{'fraction_non_alphanumeric': 0.08793969849246232, 'fraction_numerical': 0.03921782827179375, 'mean_word_length': 5.776461880088823, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '21', 'dir': 'jupyter-structured-clean-dedup', 'id': '321010', 'license': 'Unlicense', 'n_tokens_mistral': 3832, 'n_tokens_neox': 3470, 'n_words': 816, 'path': 'tgiArima.ipynb', 'repo_name': 'alifsaso/tgi_arima_app', 'size': '9166'}