Membangun RESTful API Prediksi Bunga Iris Menggunakan Scikit-Learn dan Flask

Muhammad Arslan 12 Desember 2016

Membangun RESTful API Prediksi Bunga Iris Menggunakan Scikit-Learn dan Flask

Machine learning merupakan salah satu topik yang kian hari kian didengungkan di kalangan teknologi informasi, terlebih dunia enterprise pun mulai memanfaatkannya untuk mendapat profit yang lebih baik. Apa yang menjadi emasnya? tentu saja data. Dapat berupa data historis atau koleksi yang didapat dari aplikasi web kita yang telah lama menyimpan data dari transaksi harian, ataupun ingin mencoba menggali dari data yang belum banyak.

Salah satu yang akan kita coba sekarang adalah membuat sebuah web service sederhana untuk melakukan prediksi bunga iris dengan memanfaatkan algoritma support vector machine atau biasa disebut svm. SVM ini merupakan salah satu jenis algoritma yang biasa digunakan untuk melakukan klasifikasi terhadap suatu data baru. Data yang ada akan digunakan sebagai data latih dan akan digunakan untuk menebak data baru masuk ke dalam kelas mana.

Untuk itu kita akan menggunakan sebuah pustaka dalam bahasa Python yang dinamakan dengan Scikit-Learn. Di dalamnya terdapat berbagai class untuk melakukan tugas - tugas machine learning. Kemudian kita juga akan menggunakan Flask untuk membangun RESTful API karena sangat mudah untuk menggunakan web framework ini.

Di Scikit-Learn, sebuah kumpulan data disebut dengan datasets. Setiap atribut disebut dengan feature, dan kelas atau tujuan prediksi disebut dengan target. Untuk lebih jauhnya mari kita selesaikan tutorial ini.

Instalasi dan Persiapan

Pertama kita harus memasang terlebih dahulu pustaka Scikit-Learn ini dan Flask di dalam mesin kita. Anda dapat menggunakan Virtualenv bila ingin lebih rapih:
$ pip install scikit-learn
$ pip install flask
$ mkdir demo
$ touch iris-app.py
Sekarang bila kita coba load data iris melalui konsol Python, maka Anda dapat mengakses informasi seperti berikut:
In [1]: from sklearn import datasets

In [2]: iris = datasets.load_iris()

In [3]: iris.data.shape Out[3]: (150, 4)

In [4]: iris.data.f iris.data.fill iris.data.flags iris.data.flat iris.data.flatten

In [4]: iris.feature_names Out[4]: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

In [5]: iris.tar iris.target iris.target_names

In [5]: iris.target_names Out[5]: array(['setosa', 'versicolor', 'virginica'], dtype='|S10')

In [6]: iris.target Out[6]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

In [7]: iris.data Out[7]: array([[ 5.1, 3.5, 1.4, 0.2], [ 4.9, 3. , 1.4, 0.2], [ 4.7, 3.2, 1.3, 0.2], [ 4.6, 3.1, 1.5, 0.2], [ 5. , 3.6, 1.4, 0.2], [ 5.4, 3.9, 1.7, 0.4], [ 4.6, 3.4, 1.4, 0.3], [ 5. , 3.4, 1.5, 0.2], [ 4.4, 2.9, 1.4, 0.2], [ 4.9, 3.1, 1.5, 0.1], [ 5.4, 3.7, 1.5, 0.2], [ 4.8, 3.4, 1.6, 0.2], [ 4.8, 3. , 1.4, 0.1], [ 4.3, 3. , 1.1, 0.1], [ 5.8, 4. , 1.2, 0.2], [ 5.7, 4.4, 1.5, 0.4], [ 5.4, 3.9, 1.3, 0.4], [ 5.1, 3.5, 1.4, 0.3], [ 5.7, 3.8, 1.7, 0.3], [ 5.1, 3.8, 1.5, 0.3], [ 5.4, 3.4, 1.7, 0.2], [ 5.1, 3.7, 1.5, 0.4], [ 4.6, 3.6, 1. , 0.2], [ 5.1, 3.3, 1.7, 0.5], [ 4.8, 3.4, 1.9, 0.2], [ 5. , 3. , 1.6, 0.2], [ 5. , 3.4, 1.6, 0.4], [ 5.2, 3.5, 1.5, 0.2], [ 5.2, 3.4, 1.4, 0.2], [ 4.7, 3.2, 1.6, 0.2], [ 4.8, 3.1, 1.6, 0.2], [ 5.4, 3.4, 1.5, 0.4], [ 5.2, 4.1, 1.5, 0.1], [ 5.5, 4.2, 1.4, 0.2], [ 4.9, 3.1, 1.5, 0.1], [ 5. , 3.2, 1.2, 0.2], [ 5.5, 3.5, 1.3, 0.2], [ 4.9, 3.1, 1.5, 0.1], [ 4.4, 3. , 1.3, 0.2], [ 5.1, 3.4, 1.5, 0.2], [ 5. , 3.5, 1.3, 0.3], [ 4.5, 2.3, 1.3, 0.3], [ 4.4, 3.2, 1.3, 0.2], [ 5. , 3.5, 1.6, 0.6], [ 5.1, 3.8, 1.9, 0.4], [ 4.8, 3. , 1.4, 0.3], [ 5.1, 3.8, 1.6, 0.2], [ 4.6, 3.2, 1.4, 0.2], [ 5.3, 3.7, 1.5, 0.2], [ 5. , 3.3, 1.4, 0.2], [ 7. , 3.2, 4.7, 1.4], [ 6.4, 3.2, 4.5, 1.5], [ 6.9, 3.1, 4.9, 1.5], [ 5.5, 2.3, 4. , 1.3], [ 6.5, 2.8, 4.6, 1.5], [ 5.7, 2.8, 4.5, 1.3], [ 6.3, 3.3, 4.7, 1.6], [ 4.9, 2.4, 3.3, 1. ], [ 6.6, 2.9, 4.6, 1.3], [ 5.2, 2.7, 3.9, 1.4], [ 5. , 2. , 3.5, 1. ], [ 5.9, 3. , 4.2, 1.5], [ 6. , 2.2, 4. , 1. ], [ 6.1, 2.9, 4.7, 1.4], [ 5.6, 2.9, 3.6, 1.3], [ 6.7, 3.1, 4.4, 1.4], [ 5.6, 3. , 4.5, 1.5], [ 5.8, 2.7, 4.1, 1. ], [ 6.2, 2.2, 4.5, 1.5], [ 5.6, 2.5, 3.9, 1.1], [ 5.9, 3.2, 4.8, 1.8], [ 6.1, 2.8, 4. , 1.3], [ 6.3, 2.5, 4.9, 1.5], [ 6.1, 2.8, 4.7, 1.2], [ 6.4, 2.9, 4.3, 1.3], [ 6.6, 3. , 4.4, 1.4], [ 6.8, 2.8, 4.8, 1.4], [ 6.7, 3. , 5. , 1.7], [ 6. , 2.9, 4.5, 1.5], [ 5.7, 2.6, 3.5, 1. ], [ 5.5, 2.4, 3.8, 1.1], [ 5.5, 2.4, 3.7, 1. ], [ 5.8, 2.7, 3.9, 1.2], [ 6. , 2.7, 5.1, 1.6], [ 5.4, 3. , 4.5, 1.5], [ 6. , 3.4, 4.5, 1.6], [ 6.7, 3.1, 4.7, 1.5], [ 6.3, 2.3, 4.4, 1.3], [ 5.6, 3. , 4.1, 1.3], [ 5.5, 2.5, 4. , 1.3], [ 5.5, 2.6, 4.4, 1.2], [ 6.1, 3. , 4.6, 1.4], [ 5.8, 2.6, 4. , 1.2], [ 5. , 2.3, 3.3, 1. ], [ 5.6, 2.7, 4.2, 1.3], [ 5.7, 3. , 4.2, 1.2], [ 5.7, 2.9, 4.2, 1.3], [ 6.2, 2.9, 4.3, 1.3], [ 5.1, 2.5, 3. , 1.1], [ 5.7, 2.8, 4.1, 1.3], [ 6.3, 3.3, 6. , 2.5], [ 5.8, 2.7, 5.1, 1.9], [ 7.1, 3. , 5.9, 2.1], [ 6.3, 2.9, 5.6, 1.8], [ 6.5, 3. , 5.8, 2.2], [ 7.6, 3. , 6.6, 2.1], [ 4.9, 2.5, 4.5, 1.7], [ 7.3, 2.9, 6.3, 1.8], [ 6.7, 2.5, 5.8, 1.8], [ 7.2, 3.6, 6.1, 2.5], [ 6.5, 3.2, 5.1, 2. ], [ 6.4, 2.7, 5.3, 1.9], [ 6.8, 3. , 5.5, 2.1], [ 5.7, 2.5, 5. , 2. ], [ 5.8, 2.8, 5.1, 2.4], [ 6.4, 3.2, 5.3, 2.3], [ 6.5, 3. , 5.5, 1.8], [ 7.7, 3.8, 6.7, 2.2], [ 7.7, 2.6, 6.9, 2.3], [ 6. , 2.2, 5. , 1.5], [ 6.9, 3.2, 5.7, 2.3], [ 5.6, 2.8, 4.9, 2. ], [ 7.7, 2.8, 6.7, 2. ], [ 6.3, 2.7, 4.9, 1.8], [ 6.7, 3.3, 5.7, 2.1], [ 7.2, 3.2, 6. , 1.8], [ 6.2, 2.8, 4.8, 1.8], [ 6.1, 3. , 4.9, 1.8], [ 6.4, 2.8, 5.6, 2.1], [ 7.2, 3. , 5.8, 1.6], [ 7.4, 2.8, 6.1, 1.9], [ 7.9, 3.8, 6.4, 2. ], [ 6.4, 2.8, 5.6, 2.2], [ 6.3, 2.8, 5.1, 1.5], [ 6.1, 2.6, 5.6, 1.4], [ 7.7, 3. , 6.1, 2.3], [ 6.3, 3.4, 5.6, 2.4], [ 6.4, 3.1, 5.5, 1.8], [ 6. , 3. , 4.8, 1.8], [ 6.9, 3.1, 5.4, 2.1], [ 6.7, 3.1, 5.6, 2.4], [ 6.9, 3.1, 5.1, 2.3], [ 5.8, 2.7, 5.1, 1.9], [ 6.8, 3.2, 5.9, 2.3], [ 6.7, 3.3, 5.7, 2.5], [ 6.7, 3. , 5.2, 2.3], [ 6.3, 2.5, 5. , 1.9], [ 6.5, 3. , 5.2, 2. ], [ 6.2, 3.4, 5.4, 2.3], [ 5.9, 3. , 5.1, 1.8]])

In [8]:

Selanjutnya kita akan membuat kode RESTful API ini di dalam file app.py. Kita akan membuat aplikasi sederhana dengan Flask terlebih dahulu sebelum memasang Scikit-Learn di dalam web service kita ini.

Membangun Web Service dengan Flask

Sekarang mari kita buat sebuah response selamat datang untuk web service kita. Disana kita akan dapat melihat response "Welcome to Iris Predictor :D...":
from flask import Flask, Response, request

import json import datetime

app = Flask(name)

@app.route('/') def index(): msg = { "message": "Welcome to Iris Predictor :D..." }

resp = Response(response=json.dumps(msg),
                status=200, \
                mimetype="application/json")

return resp

if name=="main": app.run(debug=True)

Pada kode diatas kita mengimpor beberapa class seperti Flask, Response, dan request dari flask. Kemudian kita impor modul json dan datetime. Selanjutnya kita buat sebuah aplikasi flask, yang akan menandai function index() agar dapat ditembak melalui URL root. Berikutnya kita gunakan class Response untuk menampilkan response berupa pesan JSON. Selanjutnya Anda dapat menjalankannya melalui konsol atau terminal seperti berikut:

$ python iris-app.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 317-230-625

Sekarang mari kita coba tembak melalui Postman. Hasilnya dapat dilihat seperti pada gambar berikut:

[caption id="attachment_13990" align="aligncenter" width="700"]Response hello world Response hello world[/caption]

Memasang Scikit-Learn pada Flask

Setelah selesai menyiapkan pondasi web service prediksi bunga iris kita, selanjutnya kita pasang Scikit-Learn beserta data latihnya di dalam kode sebelumnya. Pertama kita ipmort dulu Scikit-Learn terlebih dahulu, kemudian memuat data iris, memuat classifier SVM, dan melatih data iris sebelumnya ke dalam classifier SVM. Di function predict(), Anda akan menggunakan classifier untuk menentukan data yang diterima merupakan bunga apa.
from sklearn import datasets, svm
from flask import Flask, Response, request

import json import datetime

app = Flask(name)

iris = datasets.load_iris() classifier = svm.LinearSVC() classifier.fit(iris.data, iris.target)

...................................................

@app.route('/predict', methods=["POST"]) def predict(): req_body = request.get_json(silent=True)

sepal_length = req_body['sepal_length']
sepal_width = req_body['sepal_width']
petal_length = req_body['petal_length']
petal_width = req_body['petal_width']

iris_class = classifier.predict([
        [sepal_length, sepal_width, petal_length, petal_width]
    ])

print iris_class

if (iris_class[0] == 0):
    result = "Iris Setosa"
elif (iris_class[0] == 1):
    result = "Iris Versicolor"
elif (iris_class[0] == 2):
    result = "Iris Virginica"

msg = {
    "message": "Your flower is %s" % (result)
}

resp = Response(response=json.dumps(msg),
                status=200, \
                mimetype="application/json")

return resp

if name=="main": app.run(debug=True)

Di dalam function predict(), metod POST akan berperan dalam menerima request. Karena akan menerima JSON, maka kita akan menggunakan get_json() untuk mem-parsing JSON yang dikirimkan ke URL "/predict". Lalu setiap feature yang dikirimkan akan disimpan dalam variabel dan ditebak menggunakan classifier.predict(). Terakhir kita ambil label feature-nya dan response pun dikembalikan kepada client.

Mencoba API Prediksi Bunga Iris

Mari kita coba beberapa contoh data untuk ditebak melalui Postman:

[caption id="attachment_13991" align="aligncenter" width="700"]Memprediksi data iris virginica Memprediksi data iris virginica[/caption]

 

[caption id="attachment_13993" align="aligncenter" width="700"]Memprediksi data iris versicolor Memprediksi data iris versicolor[/caption]

 

[caption id="attachment_13992" align="aligncenter" width="700"]Memprediksi data iris setosa Memprediksi data iris setosa[/caption]

Penutup

Bagaimana cukup mudah bukan? Scikit-Learn merupakan salah satu pustaka machine learning yang ditulis oleh Python. Selain itu terdapat pustaka lain seperti Orange, Tensorflow, DeepLearning, dan lainnya. Scikit-Learn ini tidak hanya memiliki algoritma SVM saja, ada algoritma lain seperti Naive Bayes, K-Nearest Neighboor, K-Means, Linear Regression, dan lainnya. Selain itu terdapat class lain untuk melakukan text mining dan computer vision.

Dipadukan dengan Flask, Anda sudah dapat memulai sebuah web service untuk machine learning yang dapat ditanamkan didalam bisnis proses Anda. Bagi Anda yang masih kuliah pun, Scikit-Learn ini dapat digunakan untuk tugas akhir atau skripsi, dengan catatan kuasai terlebih dahulu algoritmanya sebelum menggunakan pustaka ini. Semoga bermanfaat :D

Referensi

  • http://scikit-learn.org/stable/documentation.html
  • http://flask.pocoo.org/
(arslan/python/flask/scikit-learn)