deploy model machine learning

Deploy Model LVQ di Heroku App

Pada tutorial kali ini, kita akan membahas bagaimana cara deploy model machine learning yang telah kita buat supaya bisa diakses oleh semua orang. Disini kita akan melakukan deploy model LVQ di Heroku App dengan menggunakan Python Flask. Sebelumnya, saya sudah membahas tentang algoritma Learning Vector Quantization. Jadi, bagi kalian yang masih belum paham tentang Learning Vector Quantization wajib baca artikel berikut.

Membuat Folder Project

Pertama, kita buat folder project terlebih dahulu. Jalankan code berikut di terminal kalian.

mkdir lvq-flask
cd lvq-flask
python -m venv env

Setelah kita berhasil membuat virtual environment, kita harus mengaktifkannya agar dapat digunakan dalam proyek kita. Di windows, untuk mengaktifkan virtual environment dapat menjalankan kode di bawah ini:

env/Scripts/Activate.ps1

Membuat Model LVQ

Setelah membaca 2 artikel diatas, kita akan membuat model LVQ yang nantinya digunakan untuk memprediksi data baru. Disini kita masih tetap menggunakan dataset yang sama seperti sebelumnya yaitu dataset Crop Recommendation.

Kita buat file dengan nama LVQ.py terlebih dahulu. Lalu pada artikel Learning Vector Quantization dengan Python, kita telah melatih dataset Crop Recommendation dan mendapatkan bobot akhir. Bobot akhir yang kita dapatkan dimasukkan ke dalam function __init__().

Selain itu, kita juga memasukan data min dan max pada setiap kolom untuk digunakan dalam normalisasi dengan minmax scaler. Terakhir yaitu memasukkan setiap label dalam dataset.

Selanjutnya, kita perlu membuat function untuk tahap normalisasi data. Disini kita menggunakan minmax scaler supaya data berada pada range 0 sampai 1.

Kemudian, kita buat function untuk melakukan prediksi data. Tahapan prediksi diawali dengan melakukan normalisasi data dengan memanggil function normalisasi(). Setelah itu, melakukan perhitungan jarak terdekat dengan euclidean distance dan label terdekat merupakan hasil prediksi.

class model(object):

    def __init__(self):
        """
        Inisialisasi class (constructor)
        :min (array): Data minimum
        :max (array): Data maximum
        :label (array): Label data
        :bobot (array): Bobot data
        """

        self.min = [2, 5, 6, 9.47, 15.40, 4.37, 20.76]
        self.max = [136, 145, 205, 42.92, 99.65, 8.75, 271.32]
        
        self.bobot = [[0.51960041, 0.29535686, 0.17398024, 0.39742447, 0.79136829,
        0.55574885, 0.94646941],
       [0.5481731 , 0.27255562, 0.05880831, 0.39245013, 0.57166096,
        0.42937728, 0.26799873],
       [0.27844395, 0.46015617, 0.38354912, 0.30264184, 0.01468563,
        0.45950717, 0.24101461],
       [0.17745401, 0.39744164, 0.0746021 , 0.29141671, 0.0559883 ,
        0.33549181, 0.36431371],
       [0.21049004, 0.47259936, 0.0791285 , 0.58913546, 0.39608968,
        0.34658478, 0.52111898],
       [0.18216123, 0.34892531, 0.06030708, 0.55587112, 0.42428988,
        0.82889699, 0.14319505],
       [0.14381091, 0.369938  , 0.07350924, 0.57889131, 0.82850461,
        0.5889982 , 0.10521353],
       [0.32400528, 0.45794502, 0.04694031, 0.65720585, 0.55084997,
        0.67309343, 0.24776019],
       [0.12867096, 0.49880427, 0.0611555 , 0.40107903, 0.59595565,
        0.60914402, 0.10579218],
       [0.13031964, 0.09660164, 0.22043063, 0.35232786, 0.8713593 ,
        0.48355157, 0.3347107 ],
       [0.66630957, 0.59336023, 0.23522704, 0.52259519, 0.78473274,
        0.3678178 , 0.33223293],
       [0.14383926, 0.09184971, 0.13102044, 0.68951984, 0.41747537,
        0.27665562, 0.32847903],
       [0.17562558, 0.8882161 , 0.97153333, 0.79582336, 0.79431139,
        0.34352782, 0.19794904],
       [0.68242086, 0.12992479, 0.22276183, 0.47932085, 0.84269263,
        0.48635491, 0.12568735],
       [0.75701314, 0.13635248, 0.22185047, 0.58990257, 0.92029317,
        0.44261492, 0.01305237],
       [0.14120789, 0.91756349, 0.9939359 , 0.406742  , 0.93552776,
        0.34552959, 0.39727848],
       [0.09933643, 0.07184184, 0.01990075, 0.41497889, 0.90792412,
        0.69373026, 0.3635956 ],
       [0.39931911, 0.41051175, 0.2138201 , 0.80384929, 0.90870339,
        0.57078457, 0.67558329],
       [0.12934373, 0.06592468, 0.13261426, 0.53703606, 0.94469433,
        0.32953995, 0.60812968],
       [0.89250211, 0.27525857, 0.07281252, 0.45646583, 0.77479591,
        0.57404606, 0.26733202],
       [0.58114161, 0.23604086, 0.17230946, 0.45199751, 0.76967223,
        0.46944961, 0.65738547],
       [0.79810715, 0.16208719, 0.11530894, 0.42999708, 0.45686099,
        0.56040897, 0.49726977]]

        self.label = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]

    def normalisasi(self, data):
        """
        Proses normalisasi data
        :param data (array): Data
        :return: Data yang telah di normalisasi
        """
        
        for i in range(len(data)):
            data[i] = (data[i] - self.min[i]) / (self.max[i] - self.min[i])
            
        return data

    def predict(self, data):
        """
        Proses prediksi data
        :param data (array): Data
        :return: Data yang telah di prediksi
        """

        data = self.normalisasi(data)
        min_distance = float("inf")
        min_index = 0
        for i in range(len(self.bobot)):
            distance = 0
            for j in range(len(data)):
                distance += (data[j] - self.bobot[i][j]) ** 2
            if distance < min_distance:
                min_distance = distance
                min_index = i

        return self.label[min_index]

Membuat Website Klasifikasi dengan Flask

Kita telah berhasil membuat model Learning Vector Quantization untuk melakukan prediksi. Selanjutnya kita akan menerapkan model tersebut ke dalam website dengan menggunakan bantuan Flask.

Pertama kita install terlebih dahulu library flask ke dalam virtual environment yang telah dibuat tadi.

pip install flask

Selanjutnya, kita buat file teks yang mencantumkan semua dependensi proyek kita dengan menjalankan kode di bawah ini:

pip freeze > requirements.txt

Lalu dalam folder projek kita buat sturktur folder seperti berikut.

deploy model machine learning

Note

Biarkan folder env dan file LVQ.py serta requirements.txt

Pada File wsgi.py sebagai root file yang menjalankan server pada port 5051. Isi file wsgi.py dengan code berikut.

from app.main import app
 
if __name__ == "__main__":
  app.run(port=5051, debug=True)

Selanjutnya, file Procfile digunakan untuk menjalankan website di Heroku App. Isi file Procfile dengan code berikut.

web: gunicorn wsgi:app

Setalah itu, file main.py akan digunakan sebagai router. Isi file main.py dengan code berikut.

from flask import Flask, render_template, jsonify, request
import LVQ

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/rekomendasi')
def rekomendasi():
    return render_template('rekomendasi.html')

@app.route('/result')
def result():
    return render_template('result.html')

@app.route('/predict', methods=['POST'])
def predict():
    try:
        json_ = request.get_json()

        data = [
            json_['N'],
            json_['P'],
            json_['K'],
            json_['temperature'],
            json_['humidity'],
            json_['ph'],
            json_['rainfall']
        ]

        lvq = LVQ.model()
        prediction = lvq.predict(data)

        return jsonify({'prediction': str(prediction)})
    except ValueError:
        return jsonify({'error': ValueError})
   

Pada code diatas function predict yang akan digunakan sebagai tahapan predisksi dengan menerima beberapa input sesuai dengan kolom pada dataset.

Kemudian, kita buat file style.css di app/static/css, lalu masukkan code dibawah.

body {
  font-family: 'Poppins', sans-serif !important;
}

.nav-link {
  color: #070F18 !important;
}

#jumbotron {
  margin-top: 80px;
}

#jumbotron h1 {
  font-weight: 600;
}

#jumbotron p {
  font-size: 16px;
  color: #575455;
  line-height: 32px;
}

#jumbotron a {
  margin-top: 10px;
  border-radius: 50px;
  padding: 10px 25px;
}

#why-us {
  margin-top: 150px;
}

#why-us h3 {
  font-weight: 600;
  margin-bottom: 30px;
}

#why-us .sub-text {
  width: 35%;
  margin: 0 auto;
  color: #575455;
  line-height: 32px;
}

#why-us h5 {
  display: inline-block;
  margin-top: 80px;
  margin-left: 10px;
}

#why-us .text-desc {
  display: inline-block;
  margin-left: 75px;
  color: #575455;
  line-height: 32px;
}

#tutorial {
  margin-top: 100px;
  padding-bottom: 120px;
  background-color: #F9F9F9;
}

#tutorial h3 {
  font-weight: 600;
  margin-top: 80px;
  margin-bottom: 80px;
}

#tutorial .card {
  border-radius: 50px;
  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}

#tutorial .card-body {
  margin: 50px;
}

.stepper-wrapper {
  margin-top: auto;
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}
.stepper-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
}

.stepper-item::before {
  position: absolute;
  content: "";
  border-bottom: 2px solid #1F7CFF;
  width: 100%;
  top: 20px;
  left: -50%;
  z-index: 2;
}

.stepper-item::after {
  position: absolute;
  content: "";
  border-bottom: 2px solid #1F7CFF;
  width: 100%;
  top: 20px;
  left: 50%;
  z-index: 2;
}

.stepper-item .step-counter {
  position: relative;
  z-index: 5;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #1F7CFF;
  color: #fff;
  margin-bottom: 6px;
  cursor: pointer;
}


.stepper-item.active .step-counter {
  background-color: #ffffff;
  color: #1F7CFF;
  font-weight: 600;
  box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.3);
}

.stepper-item.active::after {
  position: absolute;
  content: "";
  border-bottom: 2px solid #1F7CFF;
  width: 100%;
  top: 20px;
  left: 50%;
  z-index: 3;
}

.stepper-item:first-child::before {
  content: none;
}
.stepper-item:last-child::after {
  content: none;
}

#benefits {
  margin-top: 120px;
}

#benefits .info {
  padding-left: 50px;
}

#benefits h5 {
  color: #F75C4E;
  font-weight: 600;
  font-size: 16px;
}

#benefits h3 {
  font-weight: 600;
  font-size: 36px;
}

#benefits p {
  margin: 20px 0;
  font-size: 16px;
  color: #575455;
  line-height: 32px;
}

#benefits a {
  border-radius: 50px;
  padding: 10px 25px;
}

footer {
  margin-top: 100px;
  padding: 20px 0;
  left: 0;
  bottom: 0;
  width: 100%;
}

footer p {
  color: #8B8BA5;
  font-size: 18px;
}

#recommendation {
  margin-top: 50px;
}

#recommendation .card-body {
  padding: 40px;
}

#recommendation a {
  border-radius: 50px;
  padding: 10px 25px;
  width: 100%;
}

#recommendation img {
  display: block;
  margin-left: auto;
  margin-right: auto;
  width: 50%;
  margin-top: 30px;
  margin-bottom: 30px;
}

@media screen and (max-width: 992px) {
  #jumbotron img {
    margin-top: 80px;
  }
}

@media screen and (max-width: 576px) {
  #why-us img {
    display: none;
  }

  #why-us .sub-text {
    width: 80%;
  }

  #why-us .text-desc {
    margin-top: 30px;
    margin-left: 0;
  }
}

Download gambar yang akan kita gunakan di link berikut Download Image. Setelah gambar terdownload masukkan gambar tersebut ke dalam folder img.

Terakhir yaitu pada folder templates yang berisi file html. Untuk yang pertama kita akan isi file footer.html dengan code berikut.

<footer>
  <div class="container">
    <div class="row">
      <div class="col-md-12 text-center">
        <hr>
        <p>All Rights Reserved © 2022 by Leravio</p>
      </div>
    </div>
  </div>
</footer>

Dilanjutkan dengan mengisi file navbar.html dengan code dibawah ini.

<nav class="navbar navbar-expand-lg mt-4">
  <div class="container-fluid">
    <a href="{{ url_for('index') }}">
      <img src="{{ url_for('static', filename='img/logo.png') }}" alt="logo" class="navbar-brand">
    </a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ms-auto mb-2 mb-lg-0">
        <li class="nav-item me-4">
          <a class="nav-link {{ 'fw-bold' if active_page == 'home' else '' }}" href="{{ url_for('index') }}">Home</a>
        </li>
        <li class="nav-item me-4">
          <a class="nav-link {{ 'fw-bold' if active_page == 'recommendation' else '' }}" href="{{ url_for('rekomendasi') }}">Fitur Rekomendasi</a>
        </li>
      </ul>
    </div>
  </div>
</nav>

Selanjutnya yaitu file base.html yang berisi keseluruhan code dari head hingga body dan juga yang menghubungkan file code body dan javascript yang terpisah.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  {% block head %}{% endblock %}
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@100;300;400;700;900&family=Poppins:wght@100;200;400;500;600;700;800;900&display=swap" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
  <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
  {% block body %}{% endblock %}
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
  <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
  {% block js %}{% endblock %}
</body>
</html>

Lalu, kita buat tampilan homepage pada file index.html dengan code berikut.

{% extends 'base.html' %}
{% set active_page = "home" %}

{% block head %}
  <title>Sistem Klasifikasi Tanaman Pangan</title>
{% endblock %}

{% block body %}
<div class="container">
  {% include 'include/navbar.html' %}

  <div class="row" id="jumbotron">
    <div class="col-lg-5">
      <h1>Pertanian Presisi
        Solusi Terkini untuk
        Pertanian Masa Kini</h1>
      <p>Saran Tani dikembangkan untuk membantu Anda 
        mengoptimalkan sumberdaya lahan yang Anda miliki untuk
        memberikan hasil yang maksimal pada pertanian Anda
      </p>
      <a href="{{ url_for('rekomendasi') }}" class="btn btn-primary">Coba Sekarang</a>
    </div>
    <div class="col-lg-7">
      <img src="{{ url_for('static', filename='img/home.png') }}" alt="home" class="img-fluid">
    </div>
  </div>
  
  <div class="row justify-content-center" id="why-us">
    <div class="col-md-12 text-center">    
     <h3>Mengapa Harus Saran Tani?</h3>
     <p class="sub-text">We did research what your needs and
      here we are providing all of them just for you</p>
    </div>
    <div class="col-md-12">
      <img src="{{ url_for('static', filename='img/tick.png') }}" alt="tick" class="img-fluid">
      <h5>Rekomendasi Pemilihan Tanaman Terbaik</h5>
      <p class="text-desc">Pertanian merupakan sektor penting dalam kehidupan manusia. karena hasil pertanian dibutuhkan untuk keberlangsungan
        seluruh kehidupan semua orang. Pertanian di masa depan (precison agriculture) menitikberatkan pada pengoptimalan dan
        efisiensi sumber daya yang ada untuk menghasilkan output yang semaksimal mungkin. Para petani diharapkan mampu 
        memberikan kontribusi yang maksimal dengan pertanian yang dimiliki. Kontribusi tersebut berupa produktivitas hasil pertanian.
        Salah satu cara agar produktivitas hasil pertanian maksimal adalah dengan memanfatkan lahan pertanian se-optimal mungkin
        dengan menentukan tanaman yang sesuai dengan kondisi lahan yang dimiliki petani. Saran Tani hadir dengan membantu
        Anda (para petani) untuk mentukan pemilihan tanaman terbaik sesuai lahan yang Anda miliki.</p>
    </div>
  </div>
</div>

<div id="tutorial">
  <div class="container">
    <div class="row justify-content-center">
        <div class="col-md-12 text-center">
          <h3>Bagaimana Cara Menggunakan Saran Tani?</h3>
          <div class="card">
            <div class="card-body">
              <div class="stepper-wrapper">
                <div class="stepper-item active">
                  <div class="step-counter">01</div>
                </div>
                <div class="stepper-item">
                  <div class="step-counter">02</div>
                </div>
                <div class="stepper-item">
                  <div class="step-counter">03</div>
                </div>
              </div>
              <p class="mt-5">Klik fitur rekomendasi pada menu navigasi yang telah disediakan diatas</p>
            </div>
          </div>
      </div>
    </div>
  </div>
</div>

<div id="benefits">
  <div class="container">
    <div class="row">
      <div class="col-md-6">
        <img src="{{ url_for('static', filename='img/benefit.png') }}" alt="benefit" class="img-fluid">
      </div>
      <div class="col-md-6 mt-5 info">
        <h5>SAVE MORE TIME</h5>
        <h3>And Boost Productivity</h3>
        <p>Tunggu apalagi?
          Segera temukan tanaman terbaik untuk pertanian Anda</p>
        <a href="{{ url_for('rekomendasi') }}" class="btn btn-primary">Coba Sekarang</a>
      </div>
    </div>
  </div>
</div>

{% include 'include/footer.html' %}
{% endblock %}

{% block js %}
  <script>
    $(document).ready(function() {
      $(".step-counter").click(function(e) {
        var index = $(this).text() - 1;
        $(".stepper-item").removeClass("active");
        $(".stepper-item").eq(index).addClass("active");
        if (index == 0) {
          $("#tutorial p").text('Klik fitur rekomendasi pada menu navigasi yang telah disediakan diatas')
        } else if (index == 1) {
          $("#tutorial p").text('Inputkan data-data yang dibutuhkan sesuai kondisi pada lahan pertanian yang Anda miliki                        seperti Nitrogen, Fosfor, Kalium, Suhu, Kelembapan, pH tanah dan Curah Hujan')
        } else if (index == 2) {
          $("#tutorial p").text('Sistem akan memberikan rekomendasi tanaman terbaik. Anda dapat melihat tanaman yang sesuai untuk ditanam dengan kondisi lahan pertanian yang Anda miliki.')
        } 
      });
    });
  </script>
{% endblock %}

Selanjutnya, pada isi file rekomendasi.html dengan code berikut yang berisi input data yang nantinya digunakan dalam tahapan prediksi.

{% extends 'base.html' %}
{% set active_page = "recommendation" %}

{% block head %}
  <title>Rekomendasi Tanaman Pangan</title>
{% endblock %}

{% block body %}
<div class="container">
  {% include 'include/navbar.html' %}

  <div class="row justify-content-center" id="recommendation">
    <div class="col-md-12 text-center">
      <h3>Fitur Rekomendasi Tanaman</h3>
    </div>
    <div class="col-md-8">
      <div class="card mt-5 mb-5">
        <div class="card-body">
          <h5>Kondisi Lahan Anda</h5>
          <p class="pb-3">Masukkan data yang dibutuhkan terkait lahan Anda pada form dibawah ini</p>
          <form>
            <div class="mb-4">
              <label for="N" class="form-label">Nitrogen</label>
              <input type="text" class="form-control" id="N" name="N">
              <div id="NHelp" class="form-text">rasio kandungan Nitrogen (N) di dalam tanah</div>
            </div>
            <div class="mb-4">
              <label for="P" class="form-label">Fosfor</label>
              <input type="text" class="form-control" id="P" name="P">
              <div id="PHelp" class="form-text">rasio kandungan Fosfor (P) di dalam tanah</div>
            </div>
            <div class="mb-4">
              <label for="K" class="form-label">Kalium</label>
              <input type="text" class="form-control" id="K" name="K">
              <div id="KHelp" class="form-text">rasio kandungan Kalium (K) di dalam tanah</div>
            </div>
            <div class="mb-4">
              <label for="Temperature" class="form-label">Suhu</label>
              <input type="text" class="form-control" id="Temperature" name="Temperature">
              <div id="TemperatureHelp" class="form-text">suhu dalam derajat Celcius</div>
            </div>
            <div class="mb-4">
              <label for="Humidity" class="form-label">Kelembapan</label>
              <input type="text" class="form-control" id="Humidity" name="Humidity">
              <div id="HumidityHelp" class="form-text">kelembaban relatif dalam %</div>
            </div>
            <div class="mb-4">
              <label for="PH" class="form-label">PH</label>
              <input type="text" class="form-control" id="PH" name="PH">
              <div id="PHHelp" class="form-text">nilai PH tanah</div>
            </div>
            <div class="mb-4">
              <label for="Rainfall" class="form-label">Curah Hujan</label>
              <input type="text" class="form-control" id="Rainfall" name="Rainfall">
              <div id="KHelp" class="form-text">Tingkat curah hujan</div>
            </div>
            <a id="predict" class="btn btn-primary">Rekomendasi</a>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

{% include 'include/footer.html' %}
{% endblock %}

{% block js %}
  <script>
    $(document).ready(function() {
      $("#predict").click(function(e) {
        e.preventDefault();

        var N = parseFloat($("#N").val());
        var P = parseFloat($("#P").val());
        var K = parseFloat($("#K").val());
        var Temperature = parseFloat($("#Temperature").val());
        var Humidity = parseFloat($("#Humidity").val());
        var PH = parseFloat($("#PH").val());
        var Rainfall = parseFloat($("#Rainfall").val());

        $.ajax("{{ url_for('predict') }}", {
          data: JSON.stringify({
            "N": N,
            "P": P,
            "K": K,
            "temperature": Temperature,
            "humidity": Humidity,
            "ph": PH,
            "rainfall": Rainfall
          }),
          type: "POST",
          contentType: 'application/json',
          success: function(data) {
            window.location.href = "result?prediction=" + data.prediction;
          },
          error: function(data) {
            console.log(data);
          }
        });
      });
    });
  </script>
{% endblock %}

Terakhir yaitu file result.html yang menampilkan hasil prediksi beserta gambarnya. Isikan file result.html dengan code dibawah ini.

{% extends 'base.html' %}
{% set active_page = "recommendation" %}

{% block head %}
  <title>Hasil Rekomendasi Tanaman Pangan</title>
{% endblock %}

{% block body %}
<div class="container">
  {% include 'include/navbar.html' %}

  <div class="row justify-content-center" id="recommendation">
    <div class="col-md-12 text-center">
      <h3>Fitur Rekomendasi Tanaman</h3>
    </div>
    <div class="col-md-8">
      <div class="card mt-5 mb-5">
        <div class="card-body">
          <h5 class="text-center mb-4">Hasil Rekomendasi</h5>
          <img id="image">
          <p>Rekomendasi tanaman yang sesuai dengan kondisi lahan Anda adalah <span class="fw-bold" id="result"></span></p>
          
          <a href="{{ url_for('rekomendasi') }}" class="btn btn-primary mt-3">Kembali</a>
        </div>
      </div>
    </div>
  </div>
</div>

{% include 'include/footer.html' %}
{% endblock %}
 
{% block js %} 

<script>
  $(document).ready(function(){
    var url = window.location.href;
    var predict = url.split('?')[1];
    var data = predict.split('=')[1];
    
    var label = {
              'apel': 16,
              'pisang': 11,
              'kacang hitam': 8,
              'kacang arab' : 3,
              'kelapa': 19,
              'kopi': 22,
              'kapas': 20,
              'anggur': 13,
              'rami': 21,
              'kacang merah': 4,
              'kacang lentil': 9,
              'jagung': 2,
              'mangga': 12,
              'kacang kupu kupu': 6,
              'kacang hijau': 7,
              'melon': 15,
              'jeruk': 17,
              'pepaya': 18,
              'kacang gude': 5,
              'delima': 10,
              'padi': 1,
              'semangka': 14
            };  
      
    
    for (var key in label) {
      if (label[key] == data) {
        $("#image").attr("src", "static/img/tanaman/"+data+".png");
        $('#result').text(key);
      }
    }
  });
</script>
{% endblock %}

Deploy Model Machine Learning ke Heroku App

Setelah kita selesai membuat website untuk prediksi data dengan menggunakan flask, kita bisa langsung mendeploy website tersebut ke dalam heroku app.

Sebelum kita deploy model machine learning ke heroku, kita inisialisasikan local git repository dan commit ke app kita. Jalankan perintah berikut di terminal untuk membuat git repository.

git init
git add .
git commit -m "My first commit"

Selanjutnya, login terlebih dahulu ke heroku dengan jalankan perintah berikut di terminal.

heroku login

Setelah berhasil login, kita akan membuat app baru seperti berikut.

heroku create -a example-app

Kalian bisa ubah nama example-app sesuai dengan nama app yang kalian inginkan. Lalu lakukan perintah dibawah untuk memastikan remote app sudah sesuai.

git remote -v

Terakhir, kita tinggal deploy app kita ke heroku dengan perintah berikut.

git push heroku main

Setelah itu, untuk menjalankan website flask python yang kita buat. Kita perlu menjalankan code berikut terlebih dahalu.

heroku ps

Jika tidak ada masalah, maka website telah berhasil terdeploy ke heroku.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top