<jupyter_start><jupyter_text>Air Quality Prediction in Jakarta Nama Peserta:- <NAME>- <NAME>- Ita Sulistiani Universitas Host: Universitas IndonesiaKelas: MICRODENTIAL-002-UI-02 Associate Data ScientistKelompok: 2  Indeks Standar Pencemaran Udara (ISPU) Tahun 2020 Dataset ini berisi mengenai Indeks Standar Pencemar Udara (ISPU) yang diukur dari 5 stasiun pemantau kualitas udara (SPKU) yang ada di Provinsi DKI Jakarta Tahun 2020Penjelasan variabel dari data diatas sebagai berikut :1. tanggal : Tanggal pengukuran kualitas udara2. stasiun : Lokasi pengukuran di stasiun3. pm10 : Partikulat salah satu parameter yang diukur4. so2 : Sulfida (dalam bentuk SO2) salah satu parameter yang diukur5. co : Carbon Monoksida salah satu parameter yand diukur6. o3 : Ozon salah satu parameter yang diukur7. no2 : NItrogen dioksida salah satu parameter yang diukur8. max : Nilai ukur paling tinggi dari seluruh parameter yang diukur dalam waktu yang sama9. critical : Parameter yang hasil pengukurannya paling tinggi10. categori : Kategori hasil perhitungan indeks standar pencemaran udara  **1. Data Loading**<jupyter_code>#Import Library
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import sklearn
from sklearn import preprocessing
from sklearn.preprocessing import LabelEncoder
#Dataset API 
jan_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/0f168955-5771-43a2-9fed-9c74ac3c268e/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Januari-Tahun-2020.csv'
feb_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/67f87e67-4edd-4e5b-94f9-36f40f9295e2/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Februari-Tahun-2020.csv'
mar_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/22e21493-0c34-4255-95a4-b13f3c93bbab/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Maret-Tahun-2020.csv'
apr_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/3fa0ddf9-1aee-4fc6-b751-eb52f71af1c6/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-April-Tahun-2020.csv'
mei_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/d40162f0-1a2b-40a5-8d53-c52a38b33550/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Mei-Tahun-2020.csv'
jun_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/6541c39e-6c56-490a-ae16-2a78ae67fa73/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Juni-Tahun-2020.csv'
jul_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/dd5b5b60bfba593c41e8615269d9d221/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Juli-Tahun-2020.csv'
aug_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/c1fb35547ac7117719b7f3ac71d6f385/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Agustus-Tahun-2020.csv'
sep_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/3ad9f00b71e2f67f8fecf53cbf5a1fc7/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-September-Tahun-2020.csv'
oct_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/b037e029b2ca89430ec64e62817e79bf/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Oktober-Tahun-2020.csv'
nov_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/46a23fa64e3adb97f38191164e60694f/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-November-Tahun-2020.csv'
dec_url = 'https://data.jakarta.go.id/dataset/dd749a07-d36d-4f13-9e86-7d0a84bb90f3/resource/d3e2e8c2a651743aadf09c734e937ce7/download/Indeks-Standar-Pencemar-Udara-di-SPKU-Bulan-Desember-Tahun-2020.csv'
#Read CSV File
data_jan = pd.read_csv(jan_url)
data_feb = pd.read_csv(feb_url)
data_mar = pd.read_csv(mar_url)
data_apr = pd.read_csv(apr_url)
data_mei = pd.read_csv(mei_url)
data_jun = pd.read_csv(jun_url)
data_jul = pd.read_csv(jul_url)
data_aug = pd.read_csv(aug_url)
data_sep = pd.read_csv(sep_url)
data_oct = pd.read_csv(oct_url)
data_nov = pd.read_csv(nov_url)
data_dec = pd.read_csv(dec_url)
#Check Dataset Shape
print(data_jan.shape)
print(data_feb.shape)
print(data_mar.shape)
print(data_apr.shape)
print(data_mei.shape)
print(data_jun.shape)
print(data_jul.shape)
print(data_aug.shape)
print(data_sep.shape)
print(data_oct.shape)
print(data_nov.shape)
print(data_dec.shape)
#Combine Dataset
data_ispu = pd.concat([data_jan, data_feb, data_mar, data_apr, data_mei, data_jun, data_jul, data_aug, data_sep, data_oct, data_nov, data_dec], axis=0)
data_ispu.head()
#Reset Index (After concat index is mixed)
data_ispu = data_ispu.reset_index()
data_ispu.drop(columns = 'index', inplace = True)<jupyter_output><empty_output><jupyter_text>**2. Exploratory Data Analysis and Data Preprocessing**<jupyter_code>#Melihat Data 
data_ispu.head()
data_ispu[100:150]
#Lihat jumlah baris dan kolom
print('Jumlah Rows  :', data_ispu.shape[0])
print('jumlah kolom :', data_ispu.shape[1])
#Kolom pada dataframe
data_ispu.columns
#Melihat informasi dataset
data_ispu.info()
data_ispu.describe().T<jupyter_output><empty_output><jupyter_text>*   Based from our dataset info, other than 'max' has object data type. As for predicting air quality, we need integer / float data type. Therefore we need to convert other features except 'stasiun', 'critical' and 'categori'. As for 'tanggal' feature, we will convert it into datetime.*   'max' feature has 0 as its minimum value, 191.0 as maximum value and approximately around 58.1 as its mean value<jupyter_code>### **Handling Missing Value**<jupyter_output><empty_output><jupyter_text>Cek Missing Valuedata_ispu.isna().sum() Check Unwanted Datadata_ispu['pm10'].unique()<jupyter_code>Actually, when we check our dataset deeper, there are some rows that has '---' value. In this case, this value can be interpreted as NaN or Null. Therefore, we should drop these data which contains '---' value.

The same thing happen to other features, so we need to drop them separately.<jupyter_output><empty_output><jupyter_text>Copy datadf = data_ispu.copy()df.shape Drop row with unwanted dataDrop pm10to_drop_1 = df[df['pm10'] == '---']df.drop(to_drop_1.index, inplace = True)Drop so2to_drop_2 = df[df['so2'] == '---']df.drop(to_drop_2.index, inplace = True)Drop coto_drop_3 = df[df['co'] == '---']df.drop(to_drop_3.index, inplace = True)Drop o3to_drop_4 = df[df['o3'] == '---']df.drop(to_drop_4.index, inplace = True)Drop no2to_drop_5 = df[df['no2'] == '---']df.drop(to_drop_5.index, inplace = True)df.shape<jupyter_code>### Data Type Casting<jupyter_output><empty_output><jupyter_text>casting 'tanggal' as datetimedf['tanggal'] = pd.to_datetime(df['tanggal']) casting 'pm10', 'so2', 'co', 'o3', 'no2' as int64df['pm10'] = df['pm10'].astype('int64')df['so2'] = df['so2'].astype('int64')df['co'] = df['co'].astype('int64')df['o3'] = df['o3'].astype('int64')df['no2'] = df['no2'].astype('int64')df.info() df.describe().T<jupyter_code>### Check for Data Duplication<jupyter_output><empty_output><jupyter_text>df.duplicated().sum()<jupyter_code>There is no duplicate data on our dataset.
### Checking for Categories Distribution<jupyter_output><empty_output><jupyter_text>sum = pd.DataFrame(df['categori'].value_counts().reset_index())sum = sum.rename({'index' : 'category', 'categori':'category_counts'}, axis = 1)sum fig, ax = plt.subplots()sns.set(font_scale = 1.4)df['categori'].value_counts().plot(kind='bar', figsize=(7, 6), rot = 0)plt.xlabel('Kategori Kualitas Udara', labelpad=14)labels = [item.get_text() for item in ax.get_xticklabels()]labels = ['Sedang', 'Baik', 'Tidak Sehat']ax.set_xticklabels(labels)plt.ylabel('Jumlah', labelpad=14)plt.title('Jumlah Data Kualitas Udara per Kategori Kualitas', fontsize = 20, pad = 20)plt.show()<jupyter_code>#### Checking Features Correlations<jupyter_output><empty_output><jupyter_text>fig, ax = plt.subplots()sns.set(font_scale = 0.8)ax = sns.heatmap(df.corr(), annot = True,                  cmap = 'YlGnBu', linewidths = .1)plt.title('Features Correlations Heatmap', fontsize = 15, pad = 15)plt.show()<jupyter_code>#### Boxplot<jupyter_output><empty_output><jupyter_text>nums = ['pm10', 'so2', 'co', 'o3', 'no2'] plt.figure(figsize=(8, 6))for i in range(len(nums)):  plt.subplot(1, 5, i+1)  sns.boxplot(y = df[nums[i]], color = 'blue')  plt.tight_layout()<jupyter_code>#### Histplot<jupyter_output><empty_output><jupyter_text>plt.figure(figsize=(15, 10))sns.histplot(x = df['pm10'], color = 'blue', kde = True)plt.title('PM10 Value Distributions', fontsize = 20, pad = 15)plt.tight_layout()plt.show() plt.figure(figsize=(15, 10))sns.histplot(x = df['so2'], color = 'blue', kde = True)plt.title('SO2 Value Distributions', fontsize = 20, pad = 15)plt.tight_layout()plt.show() plt.figure(figsize=(15, 10))sns.histplot(x = df['co'], color = 'blue', kde = True)plt.title('CO Value Distributions', fontsize = 20, pad = 15)plt.tight_layout()plt.show() plt.figure(figsize=(15, 10))sns.histplot(x = df['o3'], color = 'blue', kde = True)plt.title('O3 Value Distributions', fontsize = 20, pad = 15)plt.tight_layout()plt.show() plt.figure(figsize=(15, 10))sns.histplot(x = df['no2'], color = 'blue', kde = True)plt.title('NO2 Value Distributions', fontsize = 20, pad = 15)plt.tight_layout()plt.show()<jupyter_code>### Outliers Handling using Log Transformation
Based from our numerical features data, we can see in boxplot visualization section that our data has a lot outliers.

We will perform log transformation method for treating outliers on so2, co, o3, and no2, considering the amount of our data. 

We will use log transform because it is not affected by outliers thus avoiding data loss.<jupyter_output><empty_output><jupyter_text>data_outl = df.copy() Create Function to Log Transformationdef log_tf(value):  return np.log(value) sns.boxplot(data_outl['co'])plt.title('Boxplot of CO before using Log Transformation')plt.show() Performing Log Transformationdata_outl['co'] = data_outl['co'].apply(log_tf)sns.boxplot(data_outl['co'])plt.title('Boxplot of CO after Log Transformation')plt.show() sns.boxplot(data_outl['no2'])plt.title('Boxplot of NO2 before using Log Transformation')plt.show() Performing Log Transformationdata_outl['no2'] = data_outl['no2'].apply(log_tf)sns.boxplot(data_outl['no2'])plt.title('Boxplot of NO2 after Log Transformation')plt.show()<jupyter_code>### Label Encoding<jupyter_output><empty_output><jupyter_text>data_label = data_outl.copy() data_label label_encoder = preprocessing.LabelEncoder() data_label['categori'] = label_encoder.fit_transform(data_label['categori'])data_label['categori'].unique() data_label['categori'].value_counts() data_outl['categori'].value_counts()<jupyter_code>Based from label encoding process, quality 'SEDANG' corresponds to label 1, quality 'BAIK' corresponds to label 0, and quality 'TIDAK SEHAT' corresponds to label 2.
### Feature Engineering<jupyter_output><empty_output><jupyter_text>data_fe = data_label.copy() data_fe features = ['pm10', 'so2', 'co', 'o3', 'no2', 'categori']data_fe = data_fe.loc[:, features]data_fe<jupyter_code>### Data Preprocessing
#### Data Normalization<jupyter_output><empty_output><jupyter_text>data_norm = data_fe.copy() Pilihan yang akan di normalisasilabelNorm = ['pm10','so2','co','o3','no2']<jupyter_code>##### Using Robust Scaling<jupyter_output><empty_output><jupyter_text>Using Robust Scalingfrom sklearn.preprocessing import RobustScalerrs = RobustScaler() Fungsi Normalisasi Robust Scalingdef AirRobust(dtframe,label):    dtframe[label] = rs.fit_transform(dtframe[[label]]) Copy dataframeair_robust = data_norm.copy() Proses Normalisasifor column in labelNorm:    AirRobust(air_robust,column) Copy dataframeair_robust = data_norm.copy() rs2 = RobustScaler()rs2.fit(air_robust.drop('categori', axis = 1)) data_fe = air_robust.drop('categori', axis = 1)scaled = rs2.transform(data_fe)scaled_data = pd.DataFrame(scaled, columns = labelNorm)scaled_data scaled<jupyter_code>##### Using MinMax Scaller<jupyter_output><empty_output><jupyter_text>Min Max Scallerfrom sklearn.preprocessing import MinMaxScalermm = MinMaxScaler() Fungsi Normalisasi Robust Scalingdef AirMinMaxScaller(dtframe,label):    dtframe[label] = mm.fit_transform(dtframe[[label]]) Copy dataframeair_minmax = data_norm.copy() Proses Normalisasifor column in labelNorm:    AirMinMaxScaller(air_minmax,column)<jupyter_code>##### Using StdScaller<jupyter_output><empty_output><jupyter_text>Std Scallerfrom sklearn.preprocessing import StandardScalersc = StandardScaler() Fungsi Normalisasi Robust Scalingdef AirStdScaller(dtframe,label):    dtframe[label] = sc.fit_transform(dtframe[[label]]) Copy dataframeair_stdsclr = data_norm.copy() Proses Normalisasifor column in labelNorm:    AirStdScaller(air_stdsclr,column)<jupyter_code># **3. Modelling**<jupyter_output><empty_output><jupyter_text>Additional Library import library for build model from sklearn.linear_model import LogisticRegressionfrom sklearn.svm import SVCfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.naive_bayes import GaussianNBfrom sklearn.model_selection import train_test_split import library untuk evaluasi from sklearn.metrics import r2_scorefrom sklearn.metrics import f1_scorefrom sklearn.metrics import classification_reportfrom sklearn.metrics import confusion_matrixfrom sklearn.metrics import accuracy_score,precision_score,recall_score testSize = 0.3randState = 7<jupyter_code>#### LogisticRegression<jupyter_output><empty_output><jupyter_text>Buat function untuk otomatisasi training & testingLRG_list = ['LogisticRegression']def modelTrainTestLRG(df_air,testSize,randState):      X=df_air.iloc[:,:5].values    y=df_air.iloc[:,-1:].values    y = y.reshape(-1)    Membagi size antara data training dan data test 8:2    X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=testSize,random_state=randState)        Training dengan Logistic Regression    logreg = LogisticRegression(solver= 'lbfgs',max_iter=400)    logreg.fit(X_train, y_train)    Y_pred = logreg.predict(X_test)    valTrain = logreg.score(X_train, y_train)        valTest = logreg.score(X_test, y_test)        Evaluation    cm = confusion_matrix(y_test,Y_pred)    accuracy = accuracy_score(y_test,Y_pred)    precision = precision_score(y_test, Y_pred,average='micro')    recall = recall_score(y_test, Y_pred,average='micro')    f1 = f1_score(y_test,Y_pred,average='micro')        Cetak Evaluasi       print('Confusion matrix : \n',cm)    print('Training         : %.3f' %valTrain)    print('Testing          : %.3f' %valTest)         print('Accuracy         : %.3f' %accuracy)    print('precision        : %.3f' %precision)    print('Recall           : %.3f' %recall)    print('F1-score         : %.3f' %f1)        Save Score    LRG_list.append(valTrain)    LRG_list.append(valTest)        LRG_list.append(accuracy*100)    LRG_list.append(precision*100)    LRG_list.append(recall*100)    LRG_list.append(f1*100) Proses Training & Evalprint('----RobustScaller-----')modelTrainTestLRG(air_robust,testSize,randState)print('----MinMaxScaller-----')modelTrainTestLRG(air_minmax,testSize,randState)print('----StdScaller-----')modelTrainTestLRG(air_stdsclr,testSize,randState)<jupyter_code>#### SVC<jupyter_output><empty_output><jupyter_text>Buat function untuk otomatisasi training & testingSVC_list = ['SVC']def modelTrainTestSVC(df_air,testSize,randState):      X=df_air.iloc[:,:5].values    y=df_air.iloc[:,-1:].values    y = y.reshape(-1)    Membagi size antara data training dan data test 8:2    X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=testSize,random_state=randState)        Training dengan Logistic Regression    svc = SVC()    svc.fit(X_train, y_train)    Y_pred = svc.predict(X_test)    valTrain = svc.score(X_train, y_train)        valTest = svc.score(X_test, y_test)        Evaluation    cm = confusion_matrix(y_test,Y_pred)    accuracy = accuracy_score(y_test,Y_pred)    precision = precision_score(y_test, Y_pred,average='micro')    recall = recall_score(y_test, Y_pred,average='micro')    f1 = f1_score(y_test,Y_pred,average='micro')        Cetak Evaluasi       print('Confusion matrix : \n',cm)    print('Training         : %.3f' %valTrain)    print('Testing          : %.3f' %valTest)         print('Accuracy         : %.3f' %accuracy)    print('precision        : %.3f' %precision)    print('Recall           : %.3f' %recall)    print('F1-score         : %.3f' %f1)        Save Score    SVC_list.append(valTrain)    SVC_list.append(valTest)        SVC_list.append(accuracy*100)    SVC_list.append(precision*100)    SVC_list.append(recall*100)    SVC_list.append(f1*100) Proses Training & EvaltestSize = 0.3randState = 7print('----RobustScaller-----')modelTrainTestSVC(air_robust,testSize,randState)print('----MinMaxScaller-----')modelTrainTestSVC(air_minmax,testSize,randState)print('----StdScaller-----')modelTrainTestSVC(air_stdsclr,testSize,randState)<jupyter_code>### Random Forest<jupyter_output><empty_output><jupyter_text>Buat function untuk otomatisasi training & testingRFC_list = ['RandomForest']RF_model = []def modelTrainTestRCF(df_air,testSize,randState):      X=df_air.iloc[:,:5].values    y=df_air.iloc[:,-1:].values    y = y.reshape(-1)    Membagi size antara data training dan data test 8:2    X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=testSize,random_state=randState)        Training dengan Logistic Regression    rdmFC = RandomForestClassifier()    rdmFC.fit(X_train, y_train)    Y_pred = rdmFC.predict(X_test)    valTrain = rdmFC.score(X_train, y_train)        valTest = rdmFC.score(X_test, y_test)        Evaluation    cm = confusion_matrix(y_test,Y_pred)    accuracy = accuracy_score(y_test,Y_pred)    precision = precision_score(y_test, Y_pred,average='micro')    recall = recall_score(y_test, Y_pred,average='micro')    f1 = f1_score(y_test,Y_pred,average='micro')        Cetak Evaluasi       print('Confusion matrix : \n',cm)    print('Training         : %.3f' %valTrain)    print('Testing          : %.3f' %valTest)         print('Accuracy         : %.3f' %accuracy)    print('precision        : %.3f' %precision)    print('Recall           : %.3f' %recall)    print('F1-score         : %.3f' %f1)        Save Score    RFC_list.append(valTrain)    RFC_list.append(valTest)        RFC_list.append(accuracy*100)    RFC_list.append(precision*100)    RFC_list.append(recall*100)    RFC_list.append(f1*100)        save model    RF_model.append(rdmFC) Proses Training & EvaltestSize = 0.3randState = 7print('----RobustScaller-----')modelTrainTestRCF(air_robust,testSize,randState)print('----MinMaxScaller-----')modelTrainTestRCF(air_minmax,testSize,randState)print('----StdScaller-----')modelTrainTestRCF(air_stdsclr,testSize,randState)<jupyter_code>### KNeighborsClassifier<jupyter_output><empty_output><jupyter_text>Buat function untuk otomatisasi training & testingKNC_list = ['KNeighbors']def modelTrainTestKNC(df_air,testSize,randState):      X=df_air.iloc[:,:5].values    y=df_air.iloc[:,-1:].values    y = y.reshape(-1)    Membagi size antara data training dan data test 8:2    X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=testSize,random_state=randState)        Training dengan Logistic Regression    knnC = KNeighborsClassifier()    knnC.fit(X_train, y_train)    Y_pred = knnC.predict(X_test)    valTrain = knnC.score(X_train, y_train)        valTest = knnC.score(X_test, y_test)        Evaluation    cm = confusion_matrix(y_test,Y_pred)    accuracy = accuracy_score(y_test,Y_pred)    precision = precision_score(y_test, Y_pred,average='micro')    recall = recall_score(y_test, Y_pred,average='micro')    f1 = f1_score(y_test,Y_pred,average='micro')        Cetak Evaluasi       print('Confusion matrix : \n',cm)    print('Training         : %.3f' %valTrain)    print('Testing          : %.3f' %valTest)         print('Accuracy         : %.3f' %accuracy)    print('precision        : %.3f' %precision)    print('Recall           : %.3f' %recall)    print('F1-score         : %.3f' %f1)        Save Score    KNC_list.append(valTrain)    KNC_list.append(valTest)        KNC_list.append(accuracy*100)    KNC_list.append(precision*100)    KNC_list.append(recall*100)    KNC_list.append(f1*100) Proses Training & EvaltestSize = 0.3randState = 7print('----RobustScaller-----')modelTrainTestKNC(air_robust,testSize,randState)print('----MinMaxScaller-----')modelTrainTestKNC(air_minmax,testSize,randState)print('----StdScaller-----')modelTrainTestKNC(air_stdsclr,testSize,randState)<jupyter_code>### Naive Bayes<jupyter_output><empty_output><jupyter_text>Buat function untuk otomatisasi training & testingNBC_list = ['NaiveBayes']def modelTrainTestNBC(df_air,testSize,randState):      X=df_air.iloc[:,:5].values    y=df_air.iloc[:,-1:].values    y = y.reshape(-1)    Membagi size antara data training dan data test 8:2    X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=testSize,random_state=randState)        Training dengan Logistic Regression    nbyc = GaussianNB()    nbyc.fit(X_train, y_train)    Y_pred = nbyc.predict(X_test)    valTrain = nbyc.score(X_train, y_train)        valTest = nbyc.score(X_test, y_test)        Evaluation    cm = confusion_matrix(y_test,Y_pred)    accuracy = accuracy_score(y_test,Y_pred)    precision = precision_score(y_test, Y_pred,average='micro')    recall = recall_score(y_test, Y_pred,average='micro')    f1 = f1_score(y_test,Y_pred,average='micro')        Cetak Evaluasi       print('Confusion matrix : \n',cm)    print('Training         : %.3f' %valTrain)    print('Testing          : %.3f' %valTest)         print('Accuracy         : %.3f' %accuracy)    print('precision        : %.3f' %precision)    print('Recall           : %.3f' %recall)    print('F1-score         : %.3f' %f1)        Save Score    NBC_list.append(valTrain)    NBC_list.append(valTest)        NBC_list.append(accuracy*100)    NBC_list.append(precision*100)    NBC_list.append(recall*100)    NBC_list.append(f1*100) Proses Training & EvaltestSize = 0.3randState = 7print('----RobustScaller-----')modelTrainTestNBC(air_robust,testSize,randState)print('----MinMaxScaller-----')modelTrainTestNBC(air_minmax,testSize,randState)print('----StdScaller-----')modelTrainTestNBC(air_stdsclr,testSize,randState)<jupyter_code>### Visualisasi Performa Masing Masing Model<jupyter_output><empty_output><jupyter_text>list_model = [LRG_list, SVC_list, RFC_list, KNC_list, NBC_list] model_tabel = pd.DataFrame(columns = ['Algorithm', 'Robust> Train', 'Test', 'Acc1', 'Prec', 'Recall', 'F1-score',                                     'MinMax> Train', 'Test', 'Acc2', 'Prec', 'Recall', 'F1-score',                                     'StdScaller> Train', 'Test', 'Acc3', 'Prec', 'Recall', 'F1-score',])  Append all list to dataframefor model_apnd in list_model :    model_tabel.loc[len(model_tabel)] = model_apnd model_tabel = model_tabel.sort_values(by='Acc1', ascending=False)model_tabel = model_tabel.reset_index(drop=True)model_tabel<jupyter_code>Untuk Model terbaik adalah RandomForest dengan penggunaan normalisasi RobustScaller atau StdScaller<jupyter_output><empty_output><jupyter_text>Model Extraction We will use Robust Train normalizer and Random Forest Classifier as the model predictor<jupyter_code>import pickle
# extract Robust Scaler
pickle_out = open('robust_train_normalizer.pkl', mode = 'wb')
pickle.dump(rs2, pickle_out)
pickle_out.close()
# extract the model
# pickle_out_model = open('rf_final_model.pkl', mode = 'wb')
# pickle.dump(RF_model, pickle_out_model)
# pickle_out_model.close()
print(type(RF_model))
print(RF_model)
model_final = RF_model[0]
# extract the model
pickle_out_model = open('rf_final_model.pkl', mode = 'wb')
pickle.dump(model_final, pickle_out_model)
pickle_out_model.close()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13389681576635007, 'fraction_numerical': 0.03799322147370183, 'mean_word_length': 5.565934065934066, 'pattern_counts': {'":': 0, '<': 107, '<?xml version=': 0, '>': 110, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '26', 'dir': 'jupyter-structured-clean-dedup', 'id': '341978', 'license': 'CC0-1.0', 'n_tokens_mistral': 9479, 'n_tokens_neox': 8874, 'n_words': 1493, 'path': 'model/.ipynb_checkpoints/Jakarta Air Quality Prediction-checkpoint.ipynb', 'repo_name': 'haruharuru16/air-quality-prediction-deployment', 'size': '23920'}