Code icon

The App is Under a Quick Maintenance

We apologize for the inconvenience. Please come back later

Menu iconMenu iconNatural Language Processing with Python Updated Edition
Natural Language Processing with Python Updated Edition

Chapter 13: Project: Sentiment Analysis Dashboard

13.4 Developing the Dashboard Interface

Developing an intuitive and interactive dashboard interface is crucial for allowing users to interact with the sentiment analysis models, upload text data, and visualize the results. In this section, we will discuss how to build a web-based dashboard interface using Flask, a lightweight web framework for Python, along with HTML, CSS, and JavaScript for the frontend. We will also integrate data visualization libraries such as Plotly to create interactive charts.

13.4.1 Setting Up Flask

First, ensure Flask is installed if it hasn't been already:

pip install Flask

Next, let's set up the basic structure of our Flask application.

app.py:

from flask import Flask, request, render_template, jsonify
import pickle
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences

app = Flask(__name__)

# Load the LSTM model and tokenizer
lstm_model = load_model('models/lstm_model.h5')
with open('models/tokenizer.pickle', 'rb') as file:
    tokenizer = pickle.load(file)

# Load the Logistic Regression model
with open('models/best_logistic_regression_model.pickle', 'rb') as file:
    logistic_regression_model = pickle.load(file)

# Define function to preprocess text
def preprocess_text(text):
    max_length = 200
    sequences = tokenizer.texts_to_sequences([text])
    padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
    return padded_sequences

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

@app.route('/analyze', methods=['POST'])
def analyze():
    text = request.form['text']
    model_type = request.form['model_type']

    preprocessed_text = preprocess_text(text)

    if model_type == 'lstm':
        prediction_prob = lstm_model.predict(preprocessed_text)
        prediction = (prediction_prob > 0.5).astype(int)
    else:
        prediction = logistic_regression_model.predict(preprocessed_text)

    sentiment = 'Positive' if prediction[0] == 1 else 'Negative'

    return jsonify({'sentiment': sentiment})

if __name__ == '__main__':
    app.run(debug=True)

In this script, we define the basic routes for our Flask application:

  • The home route renders the home page.
  • The analyze route processes the text input, uses the selected model to predict sentiment, and returns the result as JSON.

13.4.2 Creating HTML Templates

Next, we will create HTML templates to render the web pages. We will use Bootstrap for styling to create a responsive and visually appealing interface.

templates/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentiment Analysis Dashboard</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Sentiment Analysis Dashboard</h1>
        <form id="analysis-form" class="mt-4">
            <div class="form-group">
                <label for="text">Enter Text</label>
                <textarea class="form-control" id="text" name="text" rows="3" required></textarea>
            </div>
            <div class="form-group">
                <label for="model_type">Select Model</label>
                <select class="form-control" id="model_type" name="model_type" required>
                    <option value="logistic_regression">Logistic Regression</option>
                    <option value="lstm">LSTM</option>
                </select>
            </div>
            <button type="submit" class="btn btn-primary">Analyze Sentiment</button>
        </form>
        <div id="result" class="mt-4"></div>
    </div>

    <script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
    <script>
        $(document).ready(function() {
            $('#analysis-form').on('submit', function(event) {
                event.preventDefault();
                const formData = $(this).serialize();
                $.post('/analyze', formData, function(data) {
                    $('#result').html(`<h3>Sentiment: ${data.sentiment}</h3>`);
                });
            });
        });
    </script>
</body>
</html>

In this HTML template, we create a simple form to enter text and select the model type. When the form is submitted, an AJAX request is sent to the /analyze endpoint, and the result is displayed on the page.

13.4.3 Adding Data Visualization

Data visualization helps users understand the sentiment analysis results more effectively. We will use Plotly, a graphing library, to create interactive charts.

app.py (continued):

import plotly.express as px
import pandas as pd

@app.route('/visualize', methods=['GET'])
def visualize():
    # Example data for visualization
    data = {
        'Text': ['I love this!', 'I hate this!', 'This is amazing!', 'This is terrible!'],
        'Sentiment': ['Positive', 'Negative', 'Positive', 'Negative']
    }
    df = pd.DataFrame(data)

    fig = px.histogram(df, x='Sentiment', title='Sentiment Distribution')
    graph_html = fig.to_html(full_html=False)

    return render_template('visualize.html', graph_html=graph_html)

# HTML template for visualization
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentiment Analysis Visualization</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Sentiment Analysis Visualization</h1>
        <div id="graph-container">
            {{ graph_html | safe }}
        </div>
    </div>
</body>
</html>

In this example, we create a route /visualize that generates a simple histogram of sentiment distribution using Plotly. The generated chart is rendered in the visualize.html template.

13.4.4 Uploading Text Data

Allowing users to upload text data for sentiment analysis enhances the functionality of the dashboard. We will add an option for users to upload CSV files containing text data.

app.py (continued):

import os
from werkzeug.utils import secure_filename

UPLOAD_FOLDER = 'data/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'message': 'No file part'})
        file = request.files['file']
        if file.filename == '':
            return jsonify({'message': 'No selected file'})
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return jsonify({'message': 'File uploaded successfully'})
    return render_template('upload.html')

# HTML template for file upload
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Upload Text Data</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Upload Text Data for Sentiment Analysis</h1>
        <form action="/upload" method="post" enctype="multipart/form-data" class="mt-4">
            <div class="form-group">
                <label for="file">Choose CSV File</label>
                <input type="file" class="form-control-file" id="file" name="file" required>
            </div>
            <button type="submit" class="btn btn-primary">Upload</button>
        </form>
    </div>
</body>
</html>

In this example, we create a route /upload that handles file uploads. The uploaded CSV file is saved in the data/uploads directory. We also create an HTML template upload.html with a form to upload the file.

13.4.5 Integrating All Components

Finally, we integrate all components to create a comprehensive dashboard interface that allows users to analyze text data, visualize results, and upload new data.

app.py (final):

from flask import Flask, request, render_template, jsonify
import pickle
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences
import plotly.express as px
import pandas as pd
import os
from werkzeug.utils import secure_filename

app = Flask(__name__)

# Load models and tokenizer


lstm_model = load_model('models/lstm_model.h5')
with open('models/tokenizer.pickle', 'rb') as file:
    tokenizer = pickle.load(file)
with open('models/best_logistic_regression_model.pickle', 'rb') as file:
    logistic_regression_model = pickle.load(file)

# Set upload folder and allowed extensions
UPLOAD_FOLDER = 'data/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# Preprocess text
def preprocess_text(text):
    max_length = 200
    sequences = tokenizer.texts_to_sequences([text])
    padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
    return padded_sequences

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

@app.route('/analyze', methods=['POST'])
def analyze():
    text = request.form['text']
    model_type = request.form['model_type']

    preprocessed_text = preprocess_text(text)

    if model_type == 'lstm':
        prediction_prob = lstm_model.predict(preprocessed_text)
        prediction = (prediction_prob > 0.5).astype(int)
    else:
        prediction = logistic_regression_model.predict(preprocessed_text)

    sentiment = 'Positive' if prediction[0] == 1 else 'Negative'

    return jsonify({'sentiment': sentiment})

@app.route('/visualize', methods=['GET'])
def visualize():
    data = {
        'Text': ['I love this!', 'I hate this!', 'This is amazing!', 'This is terrible!'],
        'Sentiment': ['Positive', 'Negative', 'Positive', 'Negative']
    }
    df = pd.DataFrame(data)

    fig = px.histogram(df, x='Sentiment', title='Sentiment Distribution')
    graph_html = fig.to_html(full_html=False)

    return render_template('visualize.html', graph_html=graph_html)

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'message': 'No file part'})
        file = request.files['file']
        if file.filename == '':
            return jsonify({'message': 'No selected file'})
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return jsonify({'message': 'File uploaded successfully'})
    return render_template('upload.html')

if __name__ == '__main__':
    app.run(debug=True)

So far, we have developed the dashboard interface for the sentiment analysis project. We used Flask to create a web-based interface and integrated HTML, CSS, and JavaScript for the frontend. We also added data visualization using Plotly and enabled file uploads for user-generated text data.

By following these steps, we created a comprehensive dashboard that allows users to interact with the sentiment analysis models, upload data, and visualize the results in an intuitive and interactive way.

13.4 Developing the Dashboard Interface

Developing an intuitive and interactive dashboard interface is crucial for allowing users to interact with the sentiment analysis models, upload text data, and visualize the results. In this section, we will discuss how to build a web-based dashboard interface using Flask, a lightweight web framework for Python, along with HTML, CSS, and JavaScript for the frontend. We will also integrate data visualization libraries such as Plotly to create interactive charts.

13.4.1 Setting Up Flask

First, ensure Flask is installed if it hasn't been already:

pip install Flask

Next, let's set up the basic structure of our Flask application.

app.py:

from flask import Flask, request, render_template, jsonify
import pickle
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences

app = Flask(__name__)

# Load the LSTM model and tokenizer
lstm_model = load_model('models/lstm_model.h5')
with open('models/tokenizer.pickle', 'rb') as file:
    tokenizer = pickle.load(file)

# Load the Logistic Regression model
with open('models/best_logistic_regression_model.pickle', 'rb') as file:
    logistic_regression_model = pickle.load(file)

# Define function to preprocess text
def preprocess_text(text):
    max_length = 200
    sequences = tokenizer.texts_to_sequences([text])
    padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
    return padded_sequences

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

@app.route('/analyze', methods=['POST'])
def analyze():
    text = request.form['text']
    model_type = request.form['model_type']

    preprocessed_text = preprocess_text(text)

    if model_type == 'lstm':
        prediction_prob = lstm_model.predict(preprocessed_text)
        prediction = (prediction_prob > 0.5).astype(int)
    else:
        prediction = logistic_regression_model.predict(preprocessed_text)

    sentiment = 'Positive' if prediction[0] == 1 else 'Negative'

    return jsonify({'sentiment': sentiment})

if __name__ == '__main__':
    app.run(debug=True)

In this script, we define the basic routes for our Flask application:

  • The home route renders the home page.
  • The analyze route processes the text input, uses the selected model to predict sentiment, and returns the result as JSON.

13.4.2 Creating HTML Templates

Next, we will create HTML templates to render the web pages. We will use Bootstrap for styling to create a responsive and visually appealing interface.

templates/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentiment Analysis Dashboard</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Sentiment Analysis Dashboard</h1>
        <form id="analysis-form" class="mt-4">
            <div class="form-group">
                <label for="text">Enter Text</label>
                <textarea class="form-control" id="text" name="text" rows="3" required></textarea>
            </div>
            <div class="form-group">
                <label for="model_type">Select Model</label>
                <select class="form-control" id="model_type" name="model_type" required>
                    <option value="logistic_regression">Logistic Regression</option>
                    <option value="lstm">LSTM</option>
                </select>
            </div>
            <button type="submit" class="btn btn-primary">Analyze Sentiment</button>
        </form>
        <div id="result" class="mt-4"></div>
    </div>

    <script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
    <script>
        $(document).ready(function() {
            $('#analysis-form').on('submit', function(event) {
                event.preventDefault();
                const formData = $(this).serialize();
                $.post('/analyze', formData, function(data) {
                    $('#result').html(`<h3>Sentiment: ${data.sentiment}</h3>`);
                });
            });
        });
    </script>
</body>
</html>

In this HTML template, we create a simple form to enter text and select the model type. When the form is submitted, an AJAX request is sent to the /analyze endpoint, and the result is displayed on the page.

13.4.3 Adding Data Visualization

Data visualization helps users understand the sentiment analysis results more effectively. We will use Plotly, a graphing library, to create interactive charts.

app.py (continued):

import plotly.express as px
import pandas as pd

@app.route('/visualize', methods=['GET'])
def visualize():
    # Example data for visualization
    data = {
        'Text': ['I love this!', 'I hate this!', 'This is amazing!', 'This is terrible!'],
        'Sentiment': ['Positive', 'Negative', 'Positive', 'Negative']
    }
    df = pd.DataFrame(data)

    fig = px.histogram(df, x='Sentiment', title='Sentiment Distribution')
    graph_html = fig.to_html(full_html=False)

    return render_template('visualize.html', graph_html=graph_html)

# HTML template for visualization
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentiment Analysis Visualization</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Sentiment Analysis Visualization</h1>
        <div id="graph-container">
            {{ graph_html | safe }}
        </div>
    </div>
</body>
</html>

In this example, we create a route /visualize that generates a simple histogram of sentiment distribution using Plotly. The generated chart is rendered in the visualize.html template.

13.4.4 Uploading Text Data

Allowing users to upload text data for sentiment analysis enhances the functionality of the dashboard. We will add an option for users to upload CSV files containing text data.

app.py (continued):

import os
from werkzeug.utils import secure_filename

UPLOAD_FOLDER = 'data/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'message': 'No file part'})
        file = request.files['file']
        if file.filename == '':
            return jsonify({'message': 'No selected file'})
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return jsonify({'message': 'File uploaded successfully'})
    return render_template('upload.html')

# HTML template for file upload
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Upload Text Data</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Upload Text Data for Sentiment Analysis</h1>
        <form action="/upload" method="post" enctype="multipart/form-data" class="mt-4">
            <div class="form-group">
                <label for="file">Choose CSV File</label>
                <input type="file" class="form-control-file" id="file" name="file" required>
            </div>
            <button type="submit" class="btn btn-primary">Upload</button>
        </form>
    </div>
</body>
</html>

In this example, we create a route /upload that handles file uploads. The uploaded CSV file is saved in the data/uploads directory. We also create an HTML template upload.html with a form to upload the file.

13.4.5 Integrating All Components

Finally, we integrate all components to create a comprehensive dashboard interface that allows users to analyze text data, visualize results, and upload new data.

app.py (final):

from flask import Flask, request, render_template, jsonify
import pickle
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences
import plotly.express as px
import pandas as pd
import os
from werkzeug.utils import secure_filename

app = Flask(__name__)

# Load models and tokenizer


lstm_model = load_model('models/lstm_model.h5')
with open('models/tokenizer.pickle', 'rb') as file:
    tokenizer = pickle.load(file)
with open('models/best_logistic_regression_model.pickle', 'rb') as file:
    logistic_regression_model = pickle.load(file)

# Set upload folder and allowed extensions
UPLOAD_FOLDER = 'data/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# Preprocess text
def preprocess_text(text):
    max_length = 200
    sequences = tokenizer.texts_to_sequences([text])
    padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
    return padded_sequences

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

@app.route('/analyze', methods=['POST'])
def analyze():
    text = request.form['text']
    model_type = request.form['model_type']

    preprocessed_text = preprocess_text(text)

    if model_type == 'lstm':
        prediction_prob = lstm_model.predict(preprocessed_text)
        prediction = (prediction_prob > 0.5).astype(int)
    else:
        prediction = logistic_regression_model.predict(preprocessed_text)

    sentiment = 'Positive' if prediction[0] == 1 else 'Negative'

    return jsonify({'sentiment': sentiment})

@app.route('/visualize', methods=['GET'])
def visualize():
    data = {
        'Text': ['I love this!', 'I hate this!', 'This is amazing!', 'This is terrible!'],
        'Sentiment': ['Positive', 'Negative', 'Positive', 'Negative']
    }
    df = pd.DataFrame(data)

    fig = px.histogram(df, x='Sentiment', title='Sentiment Distribution')
    graph_html = fig.to_html(full_html=False)

    return render_template('visualize.html', graph_html=graph_html)

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'message': 'No file part'})
        file = request.files['file']
        if file.filename == '':
            return jsonify({'message': 'No selected file'})
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return jsonify({'message': 'File uploaded successfully'})
    return render_template('upload.html')

if __name__ == '__main__':
    app.run(debug=True)

So far, we have developed the dashboard interface for the sentiment analysis project. We used Flask to create a web-based interface and integrated HTML, CSS, and JavaScript for the frontend. We also added data visualization using Plotly and enabled file uploads for user-generated text data.

By following these steps, we created a comprehensive dashboard that allows users to interact with the sentiment analysis models, upload data, and visualize the results in an intuitive and interactive way.

13.4 Developing the Dashboard Interface

Developing an intuitive and interactive dashboard interface is crucial for allowing users to interact with the sentiment analysis models, upload text data, and visualize the results. In this section, we will discuss how to build a web-based dashboard interface using Flask, a lightweight web framework for Python, along with HTML, CSS, and JavaScript for the frontend. We will also integrate data visualization libraries such as Plotly to create interactive charts.

13.4.1 Setting Up Flask

First, ensure Flask is installed if it hasn't been already:

pip install Flask

Next, let's set up the basic structure of our Flask application.

app.py:

from flask import Flask, request, render_template, jsonify
import pickle
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences

app = Flask(__name__)

# Load the LSTM model and tokenizer
lstm_model = load_model('models/lstm_model.h5')
with open('models/tokenizer.pickle', 'rb') as file:
    tokenizer = pickle.load(file)

# Load the Logistic Regression model
with open('models/best_logistic_regression_model.pickle', 'rb') as file:
    logistic_regression_model = pickle.load(file)

# Define function to preprocess text
def preprocess_text(text):
    max_length = 200
    sequences = tokenizer.texts_to_sequences([text])
    padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
    return padded_sequences

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

@app.route('/analyze', methods=['POST'])
def analyze():
    text = request.form['text']
    model_type = request.form['model_type']

    preprocessed_text = preprocess_text(text)

    if model_type == 'lstm':
        prediction_prob = lstm_model.predict(preprocessed_text)
        prediction = (prediction_prob > 0.5).astype(int)
    else:
        prediction = logistic_regression_model.predict(preprocessed_text)

    sentiment = 'Positive' if prediction[0] == 1 else 'Negative'

    return jsonify({'sentiment': sentiment})

if __name__ == '__main__':
    app.run(debug=True)

In this script, we define the basic routes for our Flask application:

  • The home route renders the home page.
  • The analyze route processes the text input, uses the selected model to predict sentiment, and returns the result as JSON.

13.4.2 Creating HTML Templates

Next, we will create HTML templates to render the web pages. We will use Bootstrap for styling to create a responsive and visually appealing interface.

templates/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentiment Analysis Dashboard</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Sentiment Analysis Dashboard</h1>
        <form id="analysis-form" class="mt-4">
            <div class="form-group">
                <label for="text">Enter Text</label>
                <textarea class="form-control" id="text" name="text" rows="3" required></textarea>
            </div>
            <div class="form-group">
                <label for="model_type">Select Model</label>
                <select class="form-control" id="model_type" name="model_type" required>
                    <option value="logistic_regression">Logistic Regression</option>
                    <option value="lstm">LSTM</option>
                </select>
            </div>
            <button type="submit" class="btn btn-primary">Analyze Sentiment</button>
        </form>
        <div id="result" class="mt-4"></div>
    </div>

    <script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
    <script>
        $(document).ready(function() {
            $('#analysis-form').on('submit', function(event) {
                event.preventDefault();
                const formData = $(this).serialize();
                $.post('/analyze', formData, function(data) {
                    $('#result').html(`<h3>Sentiment: ${data.sentiment}</h3>`);
                });
            });
        });
    </script>
</body>
</html>

In this HTML template, we create a simple form to enter text and select the model type. When the form is submitted, an AJAX request is sent to the /analyze endpoint, and the result is displayed on the page.

13.4.3 Adding Data Visualization

Data visualization helps users understand the sentiment analysis results more effectively. We will use Plotly, a graphing library, to create interactive charts.

app.py (continued):

import plotly.express as px
import pandas as pd

@app.route('/visualize', methods=['GET'])
def visualize():
    # Example data for visualization
    data = {
        'Text': ['I love this!', 'I hate this!', 'This is amazing!', 'This is terrible!'],
        'Sentiment': ['Positive', 'Negative', 'Positive', 'Negative']
    }
    df = pd.DataFrame(data)

    fig = px.histogram(df, x='Sentiment', title='Sentiment Distribution')
    graph_html = fig.to_html(full_html=False)

    return render_template('visualize.html', graph_html=graph_html)

# HTML template for visualization
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentiment Analysis Visualization</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Sentiment Analysis Visualization</h1>
        <div id="graph-container">
            {{ graph_html | safe }}
        </div>
    </div>
</body>
</html>

In this example, we create a route /visualize that generates a simple histogram of sentiment distribution using Plotly. The generated chart is rendered in the visualize.html template.

13.4.4 Uploading Text Data

Allowing users to upload text data for sentiment analysis enhances the functionality of the dashboard. We will add an option for users to upload CSV files containing text data.

app.py (continued):

import os
from werkzeug.utils import secure_filename

UPLOAD_FOLDER = 'data/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'message': 'No file part'})
        file = request.files['file']
        if file.filename == '':
            return jsonify({'message': 'No selected file'})
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return jsonify({'message': 'File uploaded successfully'})
    return render_template('upload.html')

# HTML template for file upload
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Upload Text Data</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Upload Text Data for Sentiment Analysis</h1>
        <form action="/upload" method="post" enctype="multipart/form-data" class="mt-4">
            <div class="form-group">
                <label for="file">Choose CSV File</label>
                <input type="file" class="form-control-file" id="file" name="file" required>
            </div>
            <button type="submit" class="btn btn-primary">Upload</button>
        </form>
    </div>
</body>
</html>

In this example, we create a route /upload that handles file uploads. The uploaded CSV file is saved in the data/uploads directory. We also create an HTML template upload.html with a form to upload the file.

13.4.5 Integrating All Components

Finally, we integrate all components to create a comprehensive dashboard interface that allows users to analyze text data, visualize results, and upload new data.

app.py (final):

from flask import Flask, request, render_template, jsonify
import pickle
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences
import plotly.express as px
import pandas as pd
import os
from werkzeug.utils import secure_filename

app = Flask(__name__)

# Load models and tokenizer


lstm_model = load_model('models/lstm_model.h5')
with open('models/tokenizer.pickle', 'rb') as file:
    tokenizer = pickle.load(file)
with open('models/best_logistic_regression_model.pickle', 'rb') as file:
    logistic_regression_model = pickle.load(file)

# Set upload folder and allowed extensions
UPLOAD_FOLDER = 'data/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# Preprocess text
def preprocess_text(text):
    max_length = 200
    sequences = tokenizer.texts_to_sequences([text])
    padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
    return padded_sequences

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

@app.route('/analyze', methods=['POST'])
def analyze():
    text = request.form['text']
    model_type = request.form['model_type']

    preprocessed_text = preprocess_text(text)

    if model_type == 'lstm':
        prediction_prob = lstm_model.predict(preprocessed_text)
        prediction = (prediction_prob > 0.5).astype(int)
    else:
        prediction = logistic_regression_model.predict(preprocessed_text)

    sentiment = 'Positive' if prediction[0] == 1 else 'Negative'

    return jsonify({'sentiment': sentiment})

@app.route('/visualize', methods=['GET'])
def visualize():
    data = {
        'Text': ['I love this!', 'I hate this!', 'This is amazing!', 'This is terrible!'],
        'Sentiment': ['Positive', 'Negative', 'Positive', 'Negative']
    }
    df = pd.DataFrame(data)

    fig = px.histogram(df, x='Sentiment', title='Sentiment Distribution')
    graph_html = fig.to_html(full_html=False)

    return render_template('visualize.html', graph_html=graph_html)

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'message': 'No file part'})
        file = request.files['file']
        if file.filename == '':
            return jsonify({'message': 'No selected file'})
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return jsonify({'message': 'File uploaded successfully'})
    return render_template('upload.html')

if __name__ == '__main__':
    app.run(debug=True)

So far, we have developed the dashboard interface for the sentiment analysis project. We used Flask to create a web-based interface and integrated HTML, CSS, and JavaScript for the frontend. We also added data visualization using Plotly and enabled file uploads for user-generated text data.

By following these steps, we created a comprehensive dashboard that allows users to interact with the sentiment analysis models, upload data, and visualize the results in an intuitive and interactive way.

13.4 Developing the Dashboard Interface

Developing an intuitive and interactive dashboard interface is crucial for allowing users to interact with the sentiment analysis models, upload text data, and visualize the results. In this section, we will discuss how to build a web-based dashboard interface using Flask, a lightweight web framework for Python, along with HTML, CSS, and JavaScript for the frontend. We will also integrate data visualization libraries such as Plotly to create interactive charts.

13.4.1 Setting Up Flask

First, ensure Flask is installed if it hasn't been already:

pip install Flask

Next, let's set up the basic structure of our Flask application.

app.py:

from flask import Flask, request, render_template, jsonify
import pickle
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences

app = Flask(__name__)

# Load the LSTM model and tokenizer
lstm_model = load_model('models/lstm_model.h5')
with open('models/tokenizer.pickle', 'rb') as file:
    tokenizer = pickle.load(file)

# Load the Logistic Regression model
with open('models/best_logistic_regression_model.pickle', 'rb') as file:
    logistic_regression_model = pickle.load(file)

# Define function to preprocess text
def preprocess_text(text):
    max_length = 200
    sequences = tokenizer.texts_to_sequences([text])
    padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
    return padded_sequences

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

@app.route('/analyze', methods=['POST'])
def analyze():
    text = request.form['text']
    model_type = request.form['model_type']

    preprocessed_text = preprocess_text(text)

    if model_type == 'lstm':
        prediction_prob = lstm_model.predict(preprocessed_text)
        prediction = (prediction_prob > 0.5).astype(int)
    else:
        prediction = logistic_regression_model.predict(preprocessed_text)

    sentiment = 'Positive' if prediction[0] == 1 else 'Negative'

    return jsonify({'sentiment': sentiment})

if __name__ == '__main__':
    app.run(debug=True)

In this script, we define the basic routes for our Flask application:

  • The home route renders the home page.
  • The analyze route processes the text input, uses the selected model to predict sentiment, and returns the result as JSON.

13.4.2 Creating HTML Templates

Next, we will create HTML templates to render the web pages. We will use Bootstrap for styling to create a responsive and visually appealing interface.

templates/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentiment Analysis Dashboard</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Sentiment Analysis Dashboard</h1>
        <form id="analysis-form" class="mt-4">
            <div class="form-group">
                <label for="text">Enter Text</label>
                <textarea class="form-control" id="text" name="text" rows="3" required></textarea>
            </div>
            <div class="form-group">
                <label for="model_type">Select Model</label>
                <select class="form-control" id="model_type" name="model_type" required>
                    <option value="logistic_regression">Logistic Regression</option>
                    <option value="lstm">LSTM</option>
                </select>
            </div>
            <button type="submit" class="btn btn-primary">Analyze Sentiment</button>
        </form>
        <div id="result" class="mt-4"></div>
    </div>

    <script src="<https://code.jquery.com/jquery-3.5.1.min.js>"></script>
    <script>
        $(document).ready(function() {
            $('#analysis-form').on('submit', function(event) {
                event.preventDefault();
                const formData = $(this).serialize();
                $.post('/analyze', formData, function(data) {
                    $('#result').html(`<h3>Sentiment: ${data.sentiment}</h3>`);
                });
            });
        });
    </script>
</body>
</html>

In this HTML template, we create a simple form to enter text and select the model type. When the form is submitted, an AJAX request is sent to the /analyze endpoint, and the result is displayed on the page.

13.4.3 Adding Data Visualization

Data visualization helps users understand the sentiment analysis results more effectively. We will use Plotly, a graphing library, to create interactive charts.

app.py (continued):

import plotly.express as px
import pandas as pd

@app.route('/visualize', methods=['GET'])
def visualize():
    # Example data for visualization
    data = {
        'Text': ['I love this!', 'I hate this!', 'This is amazing!', 'This is terrible!'],
        'Sentiment': ['Positive', 'Negative', 'Positive', 'Negative']
    }
    df = pd.DataFrame(data)

    fig = px.histogram(df, x='Sentiment', title='Sentiment Distribution')
    graph_html = fig.to_html(full_html=False)

    return render_template('visualize.html', graph_html=graph_html)

# HTML template for visualization
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sentiment Analysis Visualization</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Sentiment Analysis Visualization</h1>
        <div id="graph-container">
            {{ graph_html | safe }}
        </div>
    </div>
</body>
</html>

In this example, we create a route /visualize that generates a simple histogram of sentiment distribution using Plotly. The generated chart is rendered in the visualize.html template.

13.4.4 Uploading Text Data

Allowing users to upload text data for sentiment analysis enhances the functionality of the dashboard. We will add an option for users to upload CSV files containing text data.

app.py (continued):

import os
from werkzeug.utils import secure_filename

UPLOAD_FOLDER = 'data/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'message': 'No file part'})
        file = request.files['file']
        if file.filename == '':
            return jsonify({'message': 'No selected file'})
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return jsonify({'message': 'File uploaded successfully'})
    return render_template('upload.html')

# HTML template for file upload
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Upload Text Data</title>
    <link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Upload Text Data for Sentiment Analysis</h1>
        <form action="/upload" method="post" enctype="multipart/form-data" class="mt-4">
            <div class="form-group">
                <label for="file">Choose CSV File</label>
                <input type="file" class="form-control-file" id="file" name="file" required>
            </div>
            <button type="submit" class="btn btn-primary">Upload</button>
        </form>
    </div>
</body>
</html>

In this example, we create a route /upload that handles file uploads. The uploaded CSV file is saved in the data/uploads directory. We also create an HTML template upload.html with a form to upload the file.

13.4.5 Integrating All Components

Finally, we integrate all components to create a comprehensive dashboard interface that allows users to analyze text data, visualize results, and upload new data.

app.py (final):

from flask import Flask, request, render_template, jsonify
import pickle
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences
import plotly.express as px
import pandas as pd
import os
from werkzeug.utils import secure_filename

app = Flask(__name__)

# Load models and tokenizer


lstm_model = load_model('models/lstm_model.h5')
with open('models/tokenizer.pickle', 'rb') as file:
    tokenizer = pickle.load(file)
with open('models/best_logistic_regression_model.pickle', 'rb') as file:
    logistic_regression_model = pickle.load(file)

# Set upload folder and allowed extensions
UPLOAD_FOLDER = 'data/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# Preprocess text
def preprocess_text(text):
    max_length = 200
    sequences = tokenizer.texts_to_sequences([text])
    padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
    return padded_sequences

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

@app.route('/analyze', methods=['POST'])
def analyze():
    text = request.form['text']
    model_type = request.form['model_type']

    preprocessed_text = preprocess_text(text)

    if model_type == 'lstm':
        prediction_prob = lstm_model.predict(preprocessed_text)
        prediction = (prediction_prob > 0.5).astype(int)
    else:
        prediction = logistic_regression_model.predict(preprocessed_text)

    sentiment = 'Positive' if prediction[0] == 1 else 'Negative'

    return jsonify({'sentiment': sentiment})

@app.route('/visualize', methods=['GET'])
def visualize():
    data = {
        'Text': ['I love this!', 'I hate this!', 'This is amazing!', 'This is terrible!'],
        'Sentiment': ['Positive', 'Negative', 'Positive', 'Negative']
    }
    df = pd.DataFrame(data)

    fig = px.histogram(df, x='Sentiment', title='Sentiment Distribution')
    graph_html = fig.to_html(full_html=False)

    return render_template('visualize.html', graph_html=graph_html)

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'message': 'No file part'})
        file = request.files['file']
        if file.filename == '':
            return jsonify({'message': 'No selected file'})
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return jsonify({'message': 'File uploaded successfully'})
    return render_template('upload.html')

if __name__ == '__main__':
    app.run(debug=True)

So far, we have developed the dashboard interface for the sentiment analysis project. We used Flask to create a web-based interface and integrated HTML, CSS, and JavaScript for the frontend. We also added data visualization using Plotly and enabled file uploads for user-generated text data.

By following these steps, we created a comprehensive dashboard that allows users to interact with the sentiment analysis models, upload data, and visualize the results in an intuitive and interactive way.