Context and what I want to do :
Hi, here is an example with the iris dataset. I have imported my machine learning model, and my web-app idea is :
- that instead of entering floating values of features in fields myself to run an iris class estimation,
- I want to use instead the index of the dataframe in a dropdown menu.
That way, I only have to select the test set row and the model would get the x_test
features automatically to do its estimation.
Problem :
My problem is that the dropdown menu appears but there is nothing I can select in it. I feel I am almost done with it, but I can't figure out where is the problem (this is my 1st flask project), do you have any idea how to do this please? thank you very much for your kind help, here is my code :
My code :
- app.py :
# libraries
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
import piskle
from flask import Flask, request, jsonify, render_template
app = Flask(__name__) # initialization
model = piskle.load('model.pskl') # model
iris = pd.read_csv('iris.csv') # dataset
X = iris[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']]
y = iris['species']
x_train,x_test,y_train,y_test = train_test_split(X,y, test_size=0.3, random_state=0)
@app.route('/') # homepage
def home():
return render_template('index.html')
@app.route('/predict',methods=['POST']) # estimation
def predict():
index_list = x_test.index.to_list()
feat = [x_test.iloc[i] for i in index_list]
final_feat = np.array(feat).reshape(1, -1)
prediction = model.predict(pd.DataFrame(final_feat))
# result
return render_template('index.html', index_list=index_list, prediction_text='Predicted Class: {}'.format(prediction))
if __name__ == "__main__":
app.run(debug=True)
- index.html :
<!DOCTYPE html>
<html >
<!-- Titre et fichier/police CSS -->
<head>
<meta charset="UTF-8">
<title>Iris classifier web-app</title>
</head>
<body>
<div>
<h1>Predict Iris Class</h1>
<form action="{{ url_for('predict')}}"method="post">
<select name="index_list" method="GET" action="/">
{% for i in index_list %}
<option value="{{ i }}">{{ i }}</option>
{% endfor %}
</select>
<br>
<br>
<button type="submit" >Predict</button>
</form>
<br>
<br>
{{ prediction_text }}
</div>
</body>
</html>
CodePudding user response:
Not sure how to answer your question. Copy paste this code and tell me if it worked the way you wanted.
I suppose these items did not show up because you've opened "/"
route instead of "/predict"
, or maybe because your .index_to_list()
method did not return list at all.
main.py
:
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/predict', methods=['GET', 'POST']) # estimation
def predict():
index_list = [1, 2, 3, 4]
prediction = 0
chosen_option = None
if request.method == 'POST':
default_value = 0
chosen_option = request.form.get(
key='select_name',
default=default_value,
)
chosen_option = int(chosen_option)
# your prediction code goes into calc_prediction
prediction = calc_prediction(chosen_option=chosen_option)
return render_template(
template_name_or_list='index.html',
index_list=index_list,
prediction=prediction,
chosen_option=chosen_option,
)
def calc_prediction(chosen_option: int):
prediction = 0
if not chosen_option:
return 0
# Do your prediction calculatoins (I guess your prediction were somehow based on
# options from select)
print(type(chosen_option))
print(chosen_option)
prediction = chosen_option / 4
return prediction
if __name__ == "__main__":
app.run(debug=True)
index.html
:
<!DOCTYPE html>
<html>
<!-- Titre et fichier/police CSS -->
<head>
<meta charset="UTF-8">
<title>Iris classifier web-app</title>
</head>
<body>
<div>
<h1>Predict Iris Class</h1>
<form action="{{ url_for('predict')}}" method="post">
<select name="select_name">
{% for i in index_list %}
<option value="{{ i }}">{{ i }}</option>
{% endfor %}
</select>
<br>
<br>
<button type="submit">Predict</button>
</form>
<br>
<p>Predicted Class: {{ prediction }}</p>
<p>Chosen option: {{ chosen_option }}</p>
</div>
</body>
</html>