chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
from flask import Flask, render_template, request
|
||||
from wtforms import Form, TextAreaField, validators
|
||||
import pickle
|
||||
import sqlite3
|
||||
import os
|
||||
import numpy as np
|
||||
|
||||
# import HashingVectorizer from local dir
|
||||
from vectorizer import vect
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
######## Preparing the Classifier
|
||||
cur_dir = os.path.dirname(__file__)
|
||||
clf = pickle.load(open(os.path.join(cur_dir,
|
||||
'pkl_objects',
|
||||
'classifier.pkl'), 'rb'))
|
||||
db = os.path.join(cur_dir, 'reviews.sqlite')
|
||||
|
||||
def classify(document):
|
||||
label = {0: 'negative', 1: 'positive'}
|
||||
X = vect.transform([document])
|
||||
y = clf.predict(X)[0]
|
||||
proba = np.max(clf.predict_proba(X))
|
||||
return label[y], proba
|
||||
|
||||
def train(document, y):
|
||||
X = vect.transform([document])
|
||||
clf.partial_fit(X, [y])
|
||||
|
||||
def sqlite_entry(path, document, y):
|
||||
conn = sqlite3.connect(path)
|
||||
c = conn.cursor()
|
||||
c.execute("INSERT INTO review_db (review, sentiment, date)"\
|
||||
" VALUES (?, ?, DATETIME('now'))", (document, y))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
######## Flask
|
||||
class ReviewForm(Form):
|
||||
moviereview = TextAreaField('',
|
||||
[validators.DataRequired(),
|
||||
validators.length(min=15)])
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
form = ReviewForm(request.form)
|
||||
return render_template('reviewform.html', form=form)
|
||||
|
||||
@app.route('/results', methods=['POST'])
|
||||
def results():
|
||||
form = ReviewForm(request.form)
|
||||
if request.method == 'POST' and form.validate():
|
||||
review = request.form['moviereview']
|
||||
y, proba = classify(review)
|
||||
return render_template('results.html',
|
||||
content=review,
|
||||
prediction=y,
|
||||
probability=round(proba*100, 2))
|
||||
return render_template('reviewform.html', form=form)
|
||||
|
||||
@app.route('/thanks', methods=['POST'])
|
||||
def feedback():
|
||||
feedback = request.form['feedback_button']
|
||||
review = request.form['review']
|
||||
prediction = request.form['prediction']
|
||||
|
||||
inv_label = {'negative': 0, 'positive': 1}
|
||||
y = inv_label[prediction]
|
||||
if feedback == 'Incorrect':
|
||||
y = int(not(y))
|
||||
train(review, y)
|
||||
sqlite_entry(db, review, y)
|
||||
return render_template('thanks.html')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
body{
|
||||
width:600px;
|
||||
}
|
||||
|
||||
.button{
|
||||
padding-top: 20px;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{% macro render_field(field) %}
|
||||
<dt>{{ field.label }}
|
||||
<dd>{{ field(**kwargs)|safe }}
|
||||
{% if field.errors %}
|
||||
<ul class=errors>
|
||||
{% for error in field.errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</dd>
|
||||
{% endmacro %}
|
||||
@@ -0,0 +1,32 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Movie Classification</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h3>Your movie review:</h3>
|
||||
<div>{{ content }}</div>
|
||||
|
||||
<h3>Prediction:</h3>
|
||||
<div>This movie review is <strong>{{ prediction }}</strong>
|
||||
(probability: {{ probability }}%).</div>
|
||||
|
||||
<div id='button'>
|
||||
<form action="/thanks" method="post">
|
||||
<input type=submit value='Correct' name='feedback_button'>
|
||||
<input type=submit value='Incorrect' name='feedback_button'>
|
||||
<input type=hidden value='{{ prediction }}' name='prediction'>
|
||||
<input type=hidden value='{{ content }}' name='review'>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id='button'>
|
||||
<form action="/">
|
||||
<input type=submit value='Submit another review'>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Movie Classification</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Please enter your movie review:</h2>
|
||||
|
||||
{% from "_formhelpers.html" import render_field %}
|
||||
|
||||
<form method=post action="/results">
|
||||
<dl>
|
||||
{{ render_field(form.moviereview, cols='30', rows='10') }}
|
||||
</dl>
|
||||
<div>
|
||||
<input type=submit value='Submit review' name='submit_btn'>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Movie Classification</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h3>Thank you for your feedback!</h3>
|
||||
|
||||
<div id='button'>
|
||||
<form action="/">
|
||||
<input type=submit value='Submit another review'>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
from sklearn.feature_extraction.text import HashingVectorizer
|
||||
import re
|
||||
import os
|
||||
import pickle
|
||||
|
||||
cur_dir = os.path.dirname(__file__)
|
||||
stop = pickle.load(open(
|
||||
os.path.join(cur_dir,
|
||||
'pkl_objects',
|
||||
'stopwords.pkl'), 'rb'))
|
||||
|
||||
def tokenizer(text):
|
||||
text = re.sub('<[^>]*>', '', text)
|
||||
emoticons = re.findall('(?::|;|=)(?:-)?(?:\)|\(|D|P)',
|
||||
text.lower())
|
||||
text = re.sub('[\W]+', ' ', text.lower()) \
|
||||
+ ' '.join(emoticons).replace('-', '')
|
||||
tokenized = [w for w in text.split() if w not in stop]
|
||||
return tokenized
|
||||
|
||||
vect = HashingVectorizer(decode_error='ignore',
|
||||
n_features=2**21,
|
||||
preprocessor=None,
|
||||
tokenizer=tokenizer)
|
||||
Reference in New Issue
Block a user