<jupyter_start><jupyter_text>Iris Classification @ MAROON DAY DATA SCIENCE 3Pada pertemuan ini, kita akan membahas mengenai klasifikasi dataset Iris dengan menggunakan alogirtma KNN (k-Nearest Neighbor).Metadata|Informasi----|-----Tanggal|30 November 2019Waktu|19.00Pemateri|<NAME>, MTA.Materi|Membuat Klasifikasi Iris dengan k-Nearest Neighbor (KNN)Pada pertemuan ini kita akan mencoba melakukan tahap-tahap pembuatan model KNN sebagai berikut.1. Data ingestion2. Exploration3. Preprocessing4. Training5. Evaluation6. Optimization Data Ingestion**Data ingestion** adalah tahap untuk mengambil data dari sumber untuk diolah. Pada pertemuan ini kita akan menggunakan sumber data dari UCI Machine Learning yaitu dataset Iris.https://archive.ics.uci.edu/ml/datasets/IrisUntuk mendownload dataset-nya, kita bisa buka link di atas dan klik Data Folder untuk mendownload dataset tersebut.Dari sisi kode, kita akan menggunakan **DataFrame** dari library Pandas. Kita akan menggunakan kode berikut untuk mengimpor fungsi `read_csv` dari library Pandas untuk membaca file CSV.<jupyter_code>from pandas import read_csv<jupyter_output><empty_output><jupyter_text>Setelah kita mengimpor fungsi `read_csv`, kita akan memanggil fungsi tersebut untuk membaca data dari file `iris.data`. Perlu diketahui bahwa fungsi `read_csv` ini tidak hanya dapat membaca file dari disk, tapi juga bisa membaca file dari URL.Selain itu, disini kita langsung membaca file `iris.data` langsung ke `DataFrame`, hal ini bisa kita lakukan karena data awal dari file `iris.data` ini sudah dalam format yang CSV yang benar, sehingga bisa langsung kita baca ke dalam `DataFrame`.Jika file dataset tidak memiliki format yang sesuai, maka perlu dilakukan pembersihan data (data cleaning) terlebih dahulu.<jupyter_code>file_path = r'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
attributes = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']
dataset = read_csv(file_path, names=attributes)<jupyter_output><empty_output><jupyter_text>Kode di atas akan membaca file `iris.data` dari URL di atas. Karena di dalam file `iris.data` tidak terdapat kolom/atribut, maka kita perlu menambahkan nama kolom saat memanggil fungsi `read_csv`.Sekarang kita sudah memiliki dataset di dalam variabel `dataset` yang siap untuk kita olah. Data ExplorationSetelah kita mendapatkan data yang akan kita olah, sekarang kita akan melihat bagaimana karakteristik data yang kita punya.Kita akan menggunakan library `matplotlib` dan `Seaborn` untuk melakukan visualisasi data.<jupyter_code>from matplotlib import pyplot
from seaborn import pairplot<jupyter_output><empty_output><jupyter_text>Untuk eksplorasi data yang pertama, kita akan melihat 5 data pertama. Ini akan memberikan sedikit gambaran mengenai bagaimana data pada dataset Iris.<jupyter_code>print(dataset.head())<jupyter_output>sepal-length  sepal-width  petal-length  petal-width        class
0           5.1          3.5           1.4          0.2  Iris-setosa
1           4.9          3.0           1.4          0.2  Iris-setosa
2           4.7          3.2           1.3          0.2  Iris-setosa
3           4.6          3.1           1.5          0.2  Iris-setosa
4           5.0          3.6           1.4          0.2  Iris-setosa<jupyter_text>Sekarang kita akan melihat berapa banyak data untuk masing-masing jenis bunga. Pada dataset ini, spesies bunga terdapat pada kolom `class`.<jupyter_code>print(dataset.groupby('class').size())<jupyter_output>class
Iris-setosa        50
Iris-versicolor    50
Iris-virginica     50
dtype: int64<jupyter_text>Dapat dilihat pada hasil running kode di atas, terdapat masing-masing 50 data untuk setiap spesies bunga. Selanjutnya kita akan menampilkan hubungan-hubungan antara satu atribut dengan atribut lainnya. Disini kita akan menggunakan fungsi `pairplot` dari library `Seaborn`.Sekarang kita akan melakukan plotting data untuk melihat hubungan antara tiap-tiap variabel pada dataset. Disini kita akan menggunakan fungsi `pairplot` untuk menampilkan plot hubungan antara tiap atribut.<jupyter_code>pairplot(dataset, hue='class', size=3)
pyplot.show()<jupyter_output>/usr/local/lib/python3.6/dist-packages/seaborn/axisgrid.py:2065: UserWarning: The `size` parameter has been renamed to `height`; pleaes update your code.
  warnings.warn(msg, UserWarning)<jupyter_text>Disini, kita bisa melihat hubungan antara tiap-tiap atribut dengan atribut lainnya. Pada plot diagonal, kita bisa melihat distribusi datanya. PreprocessingSekarang kita akan mengolah dataset yang kita punya sebelum melakukan training model. Disini kita akan melakukan tiga tahap preprocessing, yaitu:1. Attribute and label separation, memisahkan dataset menjadi input dan output.2. Membagi data untuk training dan evaluation.3. Menskalakan data dengan Standard Scaler (mengubah rata-rata = 0 dan standar deviasi = 1). Memisahkan feature dan labelUntuk memisahkan feature dan label, kita dapat menggunakan fungsi `iloc`.<jupyter_code>x = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 4].values<jupyter_output><empty_output><jupyter_text>Kode di atas berguna untuk memilih kolom 1-4 (sepal length, sepal width, petal length, petal width) sebagai input features dan sisanya (kolom 5, class) sebagai output label. Membagi data untuk training dan evaluationSekarang kita akan memisahkan data untuk digunakan untuk proses training dan evaluation. Pada contoh ini, kita akan membagi data menjadi 80% data training dan 20% data untuk evaluation (test).Untuk memisahkan dataset ini, kita bisa menggunakan fungsi `train_test_split` dari library `sklearn`.<jupyter_code>from sklearn.model_selection import train_test_split<jupyter_output><empty_output><jupyter_text>Setelah kita mengimpor fungsinya, kita bisa panggil fungsi tersebut dengan memberikan parameter input (x) dan output (y).<jupyter_code>x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)<jupyter_output><empty_output><jupyter_text>Nah sekarang kita punya empat variabel sebagai berikut.1. `x_train`, data atribut sebagai input untuk melatih algoritma.2. `y_train`, data atribut output untuk melatih algoritma.3. `x_test`, data atribut input untuk menguji algoritma.4. `y_test`, data atribut output untk menguji algoritma.> Ingat kembali, bahwa untuk variabel dengan awalan `x` memiliki empat kolom/atribut, yaitu *sepal length, sepal width, petal length* dan *petal width*. Sedankan variabel dengan awalan `y` memiliki satu kolom/atribut, yaitu *class*.  Menskalakan dataSebelum kita dapat menggunakan data untuk proses training, sebaiknya kita melakukan penskalaan data. Hal ini kita lakukan untuk menyamakan range data agar semua dataset menjadi berimbang sebelum digunakan untuk proses training.Disini kita akan menggunakan `StandardScaler` untuk melakukan transformasi data. `StandardScaler` akan mengubah dataset yang akan kita olah agar memiliki **rata-rata populasi = 0** dan **standar deviasi = 0**.<jupyter_code>from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()<jupyter_output><empty_output><jupyter_text>Kode di atas akan membuat objek `StandardScaler` yang akan kita gunakan untuk menskalakan data. Sama seperti algoritma lainnya, `StandardScaler` ini juga perlu berlatih dari data untuk mengetahui parameter-parameter yang akan digunakan untuk menskalakan data.Untuk melatih `StandardScaler`, kita bisa memanggil fungsi `fit`.<jupyter_code>scaler.fit(x_train)<jupyter_output><empty_output><jupyter_text>Setelah kita melatih objek `StandardScaler` kita dengan dataset yang kita miliki, sekarang kita akan mentransformasi dataset untuk training dan test dengan objek `StandardScaler` yang telah kita latih.<jupyter_code>x_train = scaler.transform(x_train)
x_test = scaler.transform(x_test)<jupyter_output><empty_output><jupyter_text>TrainingSekarang kita akan melatih algoritma KNN kita dengan data training. Disini kita akan membuat objek `KNeighborsClassifier` dengan nilai $k = 3$. Nilai $k$ untuk sementara ini kita set secara acak, artinya kita tidak punya dasar apapun untuk menggunakan angka ini, ini hanya tebakan :)<jupyter_code>from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier(n_neighbors=3)<jupyter_output><empty_output><jupyter_text>Setelah kita membuat objek `KNeighborsClassifier`, kita akan melatih objek KNN kita dengan memanggil fungsi yang sama dengan `StandardScaler`, yaitu dengan memanggil fungsi `fit`.<jupyter_code>classifier.fit(x_train, y_train)<jupyter_output><empty_output><jupyter_text>Disini, kita sudah selesai melatih algoritma KNN dan siap untuk diuji. Nah sekarang kita akan menguji apakah model yang telah kita buat memiliki akurasi yang baik sebelum kita gunakan.Sekarang kita akan melakukan prediksi dengan data uji untuk membandingkan dengan output uji, kemudian kita akan menghitung seberapa baik model yang kita buat.Kita dapat memanggil fungsi `predict` untuk melakukan prediksi.<jupyter_code>y_pred = classifier.predict(x_test)<jupyter_output><empty_output><jupyter_text>Sekarang kita memiliki variabel `y_pred`, yang berisi hasil klasifikasi dari classifier KNN yang sudah kita train. Sekarang kita akan melihat statistik akurasi model yang sudah kita buat dengan memanggil fungsi `classification_report`.<jupyter_code>from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))<jupyter_output>precision    recall  f1-score   support

    Iris-setosa       1.00      1.00      1.00         9
Iris-versicolor       0.92      1.00      0.96        11
 Iris-virginica       1.00      0.90      0.95        10

       accuracy                           0.97        30
      macro avg       0.97      0.97      0.97        30
   weighted avg       0.97      0.97      0.97        30<jupyter_text>Nah dari hasil di atas, kita bisa melihat output dari confusion matrix. Di atas merupakan hasil statistik untuk temu kembali informasi. Silakan di lihat pada bagian referensi untuk informasi lebih lanjut. OptimizationDi bagian akhir ini kita akan mengoptimalkan model yang kita buat agar dapat memberikan hasil prediksi yang lebih baik. Disini kita akan mencoba untuk mencari nilai $k$ yang optimal agar model yang kita buat dapat memberikan hasil prediksi yang lebih akurat.Kode di bawah ini akan mencoba nilai $k$ dari 1 sampai 40 dan menghitung rata-rata error yang akan dihasilkan.<jupyter_code># lupa numpy
import numpy as np

# variabel error untuk menyimpan data rata-rata error
error = []

# melakukan perulangan untuk nilai k antara 1-40
for i in range(1, 40):
    # membuat classifier dengan k = i
    knn = KNeighborsClassifier(n_neighbors=i)

    # melakukan training dengan dataset
    knn.fit(x_train, y_train)

    # melakukan prediksi dengan data uji
    pred_i = knn.predict(x_test)

    # menghitung rata-rata error untuk hasil uji
    error.append(np.mean(pred_i != y_test))<jupyter_output><empty_output><jupyter_text>Nah setelah kita menghitung rata-rata error, sekarang bisa kita plot menjadi sebuah grafik.<jupyter_code># membuat plot baru hubungan antara nilai k dan rata-rata error prediksi
pyplot.figure(figsize=(12, 6))
pyplot.plot(range(1, 40), error, color='red', linestyle='dashed', marker='o',
         markerfacecolor='blue', markersize=10)
pyplot.title('Rata-Rata Error terhadap nilai K')
pyplot.xlabel('Nilai K')
pyplot.ylabel('Rata-Rata Error')
pyplot.show()<jupyter_output><empty_output><jupyter_text>Nah dapat dilihat nilai $k$ yang menghasilkan error yang paling rendah dapat kita gunakan untuk nilai parameter $k$. Sekarang kita akan ubah lagi kode di atas sesuai dengan plot yang kita buat disini. Penggunaan ModelSetelah kita memiliki model, sekarang kita bisa menggunakan model yang sudah kita buat untuk melakukan prediksi.<jupyter_code># ambil input
sepal_length = 3 #@param {type:"number"}
sepal_width = 4 #@param {type:"number"}
petal_length = 2 #@param {type:"number"}
petal_width = 3 #@param {type:"number"}

# buat vektor untuk uji
x_coba = [[sepal_length, sepal_width, petal_length, petal_width]]

# prediksikan dengan model
y_pred = classifier.predict(x_coba)

# cetak hasil
print("Hasil prediksi: %s" % y_pred[0])<jupyter_output>Hasil prediksi: Iris-virginica
{'fraction_non_alphanumeric': 0.06833470057424118, 'fraction_numerical': 0.015258408531583265, 'mean_word_length': 4.9847815414825725, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 74, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '19', 'dir': 'jupyter-structured-clean-dedup', 'id': '96131', 'license': 'MIT', 'n_tokens_mistral': 4557, 'n_tokens_neox': 4324, 'n_words': 1306, 'path': 'day3-klasifikasi-iris-knn/MAROON_DAY_3_Iris_KNN_Classification.ipynb', 'repo_name': 'fahminlb33/maroon-data-science', 'size': '12200'}