I built this.
Isn’t that cool?”I was at one point feeling like this with my most recent project.
I decided to take it to the next level by building a fully interactive Webapp — even though I’ve never built one before — where users can play with the data, build their model, pick their important features and get back a certain prediction/results.
Finally, I succeeded — building my first ever ML Webapp.
You can check out the app HERE.
This is an app about exploring rental properties in Singapore — where I’m staying.
Welcome to the night of the App Preview!The app consists of 3 sectionsA.
The first section that allows users to play with the data by specifying min & max rental rates, then choose the features and the property type they are interested in and the app returns back some interactive visualizationsB.
The second section allows users to propose a hypothetical property and the app will attempt to predict its rental rate using on a model built in-situ by the users via some guided questionsC.
The last section allows users to propose a hypothetical property, specify which attributes are important to them and the app returns most similar properties to the one proposed based on the established criteriaI used Flask as my Webapp framework to create my server-side Python program, Plotly Dash to serve my interactive visualizations, and the usual suspects Numpy, Pandas, Scikit-learn as tools to build up parts and parcels of my program.
Last but not least, I used the free app-hosting site Heroku to deploy my work.
Check them out here: https://www.
com/homeFor those of you are interested in learning how to build such app, fasten your seatbelt because I’ll move on to explaining the steps in more detail in subsequent sections.
GETTING TO KNOW THE REQUIRED LIBRARIESA.
FlaskFlask is a web-development microframework for Python based on Werkzeug, Jinja 2.
You can check out its official website here http://flask.
It allows you to set up different routes/views (more on this later) that interacts with your web browser’s HTTP requests and perform some functions/tasks to return something back to the browser or a rendered Html page.
You can download the framework with a simple command using pippip install -U flaskThe latest version is Flask 1.
2 — You can test out a simple Flask app herefrom flask import Flaskapp = Flask(__name__)@app.
route('/')def hello(): return 'Hello, World!'if __name__ == '__main__': app.
run(port=8080, debug=True)This will serve up the app at localhost:8080 for you to viewB.
DashDash is a Plotly product which is a Python framework for interactive visualizations to serve as part of web applications.
You can check out its official website here https://plot.
It allows you to gather different elements such as Dropdown/Slider/Barcharts/Maps that can cross-communicate, into a layout and serve it up inside a web viewYou can install the components herepip install -U dashpip install dash_core_componentspip install dash_html_componentsYou can test out the example program written on the main introduction page.
Remember to specify the followingapp.
serve_locally = Trueif __name__ == '__main__': app.
WtformsWtforms is a nice API that allows you to customize your front end forms which take users’ inputs and feed them to your backend app.
The API supports a horde of popular Python web development frameworks including Flask and Django.
You can read more about how to use wtforms from the documentation here https://wtforms.
You can install it withpip install -U dashD.
The usual suspects — Numpy, Pandas, Scikit-learn, Seaborn…These are the fundamental packages to clean, prepare, explore and analyze data, as well as building machine learning models to work with these data.
Readers who know a thing or two about practicing data science using Python should be familiar with these packages.
If not, you’re always welcome to check out my previous articles discussing other projects**Now that all the frameworks/packages have had their own introduction, let’s move on to discover how they can be used together to deliver a finished working product3.
BUILDING THE REQUIRED MODULESThere are a few modules/components required to make this project happen:A house is built from many bricksA.
The nested Dash app with a fully defined layoutB.
Configured input forms to be used with the main HTML pageC1.
The main HTML page consisting of different sections with input formsC2.
Other HTML pages to be served up by different routes/views of the main programD.
Helper functions to be called inside the main appLet’s discuss each and every component— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —Component A — The Dash appapp_dash = Dash app’s name.
A separate view named ‘/dashboard’ is also configured for the dashboardA dummy layout is first set for the Dash app.
‘/hahaha’ view will be triggered & the app’s layout is populated with some interactive charts whenever form4 submits a request — like previously mentioned.
Arguments to construct the plots are taken from the user’ inputs at form1.
This means the user needs to ensure that form1 is submitted (this action also induces the creation of the interactive charts and changes plot_charts_cue to True) before he/she triggers chart viewOtherwise, if the user fails to submit form1 first, first an error.
html page will be displayedInteractive charts are constructed with Plotly’s graph objects packaged (import as go).
Each chart consists of a chart layout and a set of elements.
There are many choices for these elements (go.
Map…), depending on the types of charts you want to plotAn example of how an interactive Bar chart is created is shown below— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —Component B — The configured input formsThe input forms can be configured by first defining an extended form class that builds upon Form, and defining different variable names representing the info needed to be filled in the form, and the input field types that go with these variables.
For example, the two form classes for section 1 (modifying the dataset) and section 3 (searching for similar listings) are:You can use validators to force some rules upon the input fields.
See the documentation for more details on how to use themOn the main index.
html page, the error message (specified by you) will be flashed if the validators are not satisfied.
The field will also flash its default error message if the input values’ type differs from the specified field typeThe forms are then integrated into the main program via the following codes.
from flask import requestform1 = ResuableForm(request.
form)form3 = ReusableForm_SimFilter(request.
form)//Parse the forms to the rendered main Html page@app.
route('/')def some_func(): //Do sth return render_template('index.
html', form1=form1, form3=form3Last but not least, on the index.
html page, there should be two form sections, whose respective IDs should be ‘form1’ and ‘form3’ respectively.
More on how this page can be constructed later— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —Component C — The required HTML templatesAll the HTML templates used for this project are put together into a “template” folder that is placed in the same directory as the main program.
This is a requirement of the render_template function.
You should do the same thing to the templates of your own projectThe real index.
html used for the main view is much longer and consists of many forms.
However, I will simplify the situation and present the short version of the template with only one form used (the form needed to obtain arguments to modify the dataset).
Take a look at the codes for the form below:***There are a few explanations to help you understand this form better:<form></form> is how a form section can be declared inside the template.
The attribute method = post dictates what kind of requests the form will send to the back-end program once it is submitted.
One can use the attribute action = ‘view_name’ to dictate which Flask route/view the form’s submission will trigger.
If the attribute is not specified, the submission will by default send its data to the main viewform1 is called within the template.
Thus, when the page is rendered the form1 would first need to be defined, assigned and parsed into the render_template() function as an argumentFields belonging to form1 can be called as form1.
field_name and dealt with by the template accordinglyYou can also use <select></select> to configure dropdown value selection for categorical features, instead of using blank input fieldsNotice also how the flash error messages are configured in the templateRegarding CSS styling of the form, just read the gist for yourselfIf you want to access the full index.
html version, you can check it out inside the folder Flaskapp/template of the project’s directory HERE!On top of the main page, your template folder should contain other templates (for example the one returned by one of the view showing the result of whatever your model is trying to forecast).
I use two other templates, one — prediction_result.
html — for returning the answer of Section 2 and the other — filtering_result.
html — for returning the answer of section 3.
I also use various more templates to return some error page with instructions to the user, whenever certain conditions of the program are not met.
An example is shown below— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —Component D — Helper functionsMany helper functions were required for my project.
For example:Functions to plot the interactive charts for the Dash app (section discussing component B show one such example)Functions to modify the datasets based on the user’s preferenceFunctions to create and train prediction models for section 2 using either Pyspark or Sklearn library (depending on the user’s choice)Functions used in section 2 to transform the test instance into the right format for the trained model, and return back the predictionFunctions used in section 3 to transform the test instance into the right format for the trained model, and return back similar resultsAn example of such functions is shown below.
This is the function mentioned in point 5 above.
The function builds a NearestNeighbors’ learning model and uses it to search for similar listings based on the weights given by the user:I will not go on to show all the helper functions used in this project.
If you are interested in reading them in depth, feel free to check out the project’s directory accessible via my Github repositoryand finally…After we have finished creating all the modules required for the Flaskapp, it is time to build the final and most important piece of the project: The main program.
Check out Part 2 of this post to see for yourself how to do this.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —.