uploading model
Browse files- SA_model.pkl +3 -0
- app.py +128 -0
- model.ipynb +721 -0
SA_model.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d379ad2f488dc26887b9ab48c3529838564c21bea545d0052ada39f4408dd8ce
|
| 3 |
+
size 1547944
|
app.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# import libraries
|
| 2 |
+
import streamlit as st
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import matplotlib.pyplot as plt
|
| 5 |
+
import seaborn as sns
|
| 6 |
+
import joblib
|
| 7 |
+
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
|
| 8 |
+
from sklearn.model_selection import train_test_split
|
| 9 |
+
|
| 10 |
+
#load model
|
| 11 |
+
import joblib
|
| 12 |
+
|
| 13 |
+
@st.cache_resource # Caches the model in Streamlit's memory
|
| 14 |
+
def load_model():
|
| 15 |
+
return joblib.load("SA_model.pkl") # Ensure your model is saved and available
|
| 16 |
+
|
| 17 |
+
model = load_model()
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
#load dataset
|
| 22 |
+
df = pd.read_csv('Tweets.csv', encoding='utf-8')
|
| 23 |
+
X = df['text']
|
| 24 |
+
y = df['airline_sentiment']
|
| 25 |
+
X_train, X_test, y_train, y_test = train_test_split(
|
| 26 |
+
X, y , test_size=0.33, random_state=42
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
#compute sentiment
|
| 31 |
+
class_report_data = {
|
| 32 |
+
"Precision": [0.67, 0.51, 0.88],
|
| 33 |
+
"Recall": [0.73, 0.64, 0.79],
|
| 34 |
+
"F1-score": [0.70, 0.57, 0.83]
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
# Properly structured DataFrame
|
| 38 |
+
class_report_df = pd.DataFrame(class_report_data, index=["Positive", "Neutral", "Negative"])
|
| 39 |
+
|
| 40 |
+
#predict text sentiment
|
| 41 |
+
def predict_sentiment(text):
|
| 42 |
+
if isinstance(text, str):
|
| 43 |
+
text = [text] # Ensure input is a list
|
| 44 |
+
|
| 45 |
+
prediction = model.predict(text) # Get numerical prediction
|
| 46 |
+
|
| 47 |
+
# Mapping numerical labels to sentiment categories
|
| 48 |
+
sentiment_mapping = {0: "Negative", 1: "Neutral", 2: "Positive"}
|
| 49 |
+
|
| 50 |
+
return sentiment_mapping.get(prediction[0], "Unknown") # Convert number to label
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
#Model Introduction
|
| 55 |
+
st.title('📌 Sentiment Analysis Web Application')
|
| 56 |
+
|
| 57 |
+
st.markdown(
|
| 58 |
+
"""
|
| 59 |
+
## 📖 Introduction
|
| 60 |
+
Welcome to the **Sentiment Analysis Web Application**! This tool is designed to analyze the sentiment of text messages
|
| 61 |
+
using a **Support Vector Machine (SVM) model**. The model has been trained on the **Airline Tweets dataset from Kaggle**
|
| 62 |
+
and classifies text into three sentiment categories:
|
| 63 |
+
- ✅ **Positive**
|
| 64 |
+
- ❌ **Negative**
|
| 65 |
+
- ⚖ **Neutral**
|
| 66 |
+
"""
|
| 67 |
+
)
|
| 68 |
+
|
| 69 |
+
#Tab Structuring
|
| 70 |
+
|
| 71 |
+
tab1, tab2, tab3 = st.tabs(['📊 Dataset Preview', '📈 Model Performance', '🔍 Sentiment Prediction'])
|
| 72 |
+
|
| 73 |
+
with tab1:
|
| 74 |
+
st.markdown(
|
| 75 |
+
"""
|
| 76 |
+
## 📊 Dataset Preview
|
| 77 |
+
The dataset used for training this model consists of tweets related to airline services. Each tweet is labeled
|
| 78 |
+
with one of the three sentiment categories (**Positive, Negative, or Neutral**). Below is a sample of the dataset:
|
| 79 |
+
"""
|
| 80 |
+
)
|
| 81 |
+
st.write (df)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
with tab2:
|
| 85 |
+
st.markdown(
|
| 86 |
+
"""
|
| 87 |
+
## 📈 Model Performance
|
| 88 |
+
Below are the key performance metrics of the trained **Support Vector Machine (SVM)** model:
|
| 89 |
+
|
| 90 |
+
- **Model Accuracy**: The percentage of correctly classified instances.
|
| 91 |
+
- **Classification Report**: Includes precision and recall for each sentiment class.
|
| 92 |
+
- **Confusion Matrix**: A visual representation comparing actual versus predicted classifications.
|
| 93 |
+
"""
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
st.write(f"**📌 Model Accuracy:** 75%")
|
| 97 |
+
|
| 98 |
+
st.markdown("### 📋 Classification Report")
|
| 99 |
+
st.dataframe(class_report_df)
|
| 100 |
+
|
| 101 |
+
st.markdown("### 🔢 Confusion Matrix")
|
| 102 |
+
|
| 103 |
+
# Load and display confusion matrix image
|
| 104 |
+
cm_image_path = "cmap.png"
|
| 105 |
+
try:
|
| 106 |
+
st.image(cm_image_path, caption="Confusion Matrix", use_container_width=True)
|
| 107 |
+
except FileNotFoundError:
|
| 108 |
+
st.warning("⚠️ Confusion matrix image not found. Please check the file path.")
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
with tab3:
|
| 114 |
+
st.markdown(
|
| 115 |
+
"""
|
| 116 |
+
## 🔍 Sentiment Prediction
|
| 117 |
+
Type a sentence in the text box below, and the model will classify it as **Positive, Neutral, or Negative**.
|
| 118 |
+
"""
|
| 119 |
+
)
|
| 120 |
+
|
| 121 |
+
user_input = st.text_area("Type your sentence here:", "")
|
| 122 |
+
|
| 123 |
+
if st.button("🔎 Analyze Sentiment"):
|
| 124 |
+
if user_input.strip():
|
| 125 |
+
sentiment_result = predict_sentiment(user_input)
|
| 126 |
+
st.success(f"### 🎯 Prediction: **{sentiment_result}**")
|
| 127 |
+
else:
|
| 128 |
+
st.warning("⚠️ Please enter a valid text input.")
|
model.ipynb
ADDED
|
@@ -0,0 +1,721 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "markdown",
|
| 5 |
+
"metadata": {},
|
| 6 |
+
"source": [
|
| 7 |
+
"## This Model Allows Sentiment Analysis using Support Vector Machine Algorithm"
|
| 8 |
+
]
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"cell_type": "markdown",
|
| 12 |
+
"metadata": {},
|
| 13 |
+
"source": [
|
| 14 |
+
"#### This model is comprised of different steps as listed below:\n",
|
| 15 |
+
"1. Importing Libraries\n",
|
| 16 |
+
"2. Data Loading\n",
|
| 17 |
+
"3. Data Cleaning\n",
|
| 18 |
+
"4. Data Preprocessing\n",
|
| 19 |
+
"5. Train Test Split\n",
|
| 20 |
+
"6. Model Training\n",
|
| 21 |
+
"7. Model Evaluation\n",
|
| 22 |
+
"8. Pickle Export"
|
| 23 |
+
]
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"cell_type": "markdown",
|
| 27 |
+
"metadata": {},
|
| 28 |
+
"source": [
|
| 29 |
+
"#### Importing Libraries"
|
| 30 |
+
]
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"cell_type": "code",
|
| 34 |
+
"execution_count": 55,
|
| 35 |
+
"metadata": {},
|
| 36 |
+
"outputs": [],
|
| 37 |
+
"source": [
|
| 38 |
+
"import numpy as np\n",
|
| 39 |
+
"import pandas as pd\n",
|
| 40 |
+
"import matplotlib.pyplot as plt\n",
|
| 41 |
+
"import seaborn as sns\n",
|
| 42 |
+
"from sklearn import svm\n",
|
| 43 |
+
"from sklearn.model_selection import train_test_split\n",
|
| 44 |
+
"from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, ConfusionMatrixDisplay\n",
|
| 45 |
+
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
| 46 |
+
"from sklearn.pipeline import Pipeline\n",
|
| 47 |
+
"import joblib"
|
| 48 |
+
]
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"cell_type": "markdown",
|
| 52 |
+
"metadata": {},
|
| 53 |
+
"source": [
|
| 54 |
+
"#### Data Load"
|
| 55 |
+
]
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"cell_type": "code",
|
| 59 |
+
"execution_count": 56,
|
| 60 |
+
"metadata": {},
|
| 61 |
+
"outputs": [],
|
| 62 |
+
"source": [
|
| 63 |
+
"df = pd.read_csv('Tweets.csv') # Load dataset\n",
|
| 64 |
+
"df = df[['text', 'airline_sentiment']] # Ensure these columns exist"
|
| 65 |
+
]
|
| 66 |
+
},
|
| 67 |
+
{
|
| 68 |
+
"cell_type": "markdown",
|
| 69 |
+
"metadata": {},
|
| 70 |
+
"source": [
|
| 71 |
+
"#### Data Cleaning"
|
| 72 |
+
]
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"cell_type": "code",
|
| 76 |
+
"execution_count": 57,
|
| 77 |
+
"metadata": {},
|
| 78 |
+
"outputs": [
|
| 79 |
+
{
|
| 80 |
+
"name": "stdout",
|
| 81 |
+
"output_type": "stream",
|
| 82 |
+
"text": [
|
| 83 |
+
"0\n"
|
| 84 |
+
]
|
| 85 |
+
}
|
| 86 |
+
],
|
| 87 |
+
"source": [
|
| 88 |
+
"print(df['airline_sentiment'].isnull().sum())"
|
| 89 |
+
]
|
| 90 |
+
},
|
| 91 |
+
{
|
| 92 |
+
"cell_type": "code",
|
| 93 |
+
"execution_count": 58,
|
| 94 |
+
"metadata": {},
|
| 95 |
+
"outputs": [],
|
| 96 |
+
"source": [
|
| 97 |
+
"df = df.dropna(subset=['airline_sentiment'])\n",
|
| 98 |
+
"df['airline_sentiment'] = df['airline_sentiment'].map({\n",
|
| 99 |
+
" 'positive': 2,\n",
|
| 100 |
+
" 'neutral': 1,\n",
|
| 101 |
+
" 'negative': 0\n",
|
| 102 |
+
"})"
|
| 103 |
+
]
|
| 104 |
+
},
|
| 105 |
+
{
|
| 106 |
+
"cell_type": "markdown",
|
| 107 |
+
"metadata": {},
|
| 108 |
+
"source": [
|
| 109 |
+
"#### Train Test Split"
|
| 110 |
+
]
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"cell_type": "code",
|
| 114 |
+
"execution_count": 59,
|
| 115 |
+
"metadata": {},
|
| 116 |
+
"outputs": [],
|
| 117 |
+
"source": [
|
| 118 |
+
"# Split dataset\n",
|
| 119 |
+
"X = df['text']\n",
|
| 120 |
+
"y = df['airline_sentiment']\n",
|
| 121 |
+
"X_train, X_test, y_train, y_test = train_test_split(\n",
|
| 122 |
+
" X, y , test_size=0.33, random_state=42\n",
|
| 123 |
+
")"
|
| 124 |
+
]
|
| 125 |
+
},
|
| 126 |
+
{
|
| 127 |
+
"cell_type": "markdown",
|
| 128 |
+
"metadata": {},
|
| 129 |
+
"source": [
|
| 130 |
+
"#### Model Training"
|
| 131 |
+
]
|
| 132 |
+
},
|
| 133 |
+
{
|
| 134 |
+
"cell_type": "code",
|
| 135 |
+
"execution_count": 60,
|
| 136 |
+
"metadata": {},
|
| 137 |
+
"outputs": [],
|
| 138 |
+
"source": [
|
| 139 |
+
"#model pipelining\n",
|
| 140 |
+
"\n",
|
| 141 |
+
"model = Pipeline([\n",
|
| 142 |
+
" ('tfidf', TfidfVectorizer(max_features=10000, ngram_range=(1,2), stop_words='english')),\n",
|
| 143 |
+
" ('svm', svm.SVC(kernel='linear', probability=True, class_weight='balanced'))])"
|
| 144 |
+
]
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"cell_type": "code",
|
| 148 |
+
"execution_count": 61,
|
| 149 |
+
"metadata": {},
|
| 150 |
+
"outputs": [
|
| 151 |
+
{
|
| 152 |
+
"data": {
|
| 153 |
+
"text/html": [
|
| 154 |
+
"<style>#sk-container-id-2 {\n",
|
| 155 |
+
" /* Definition of color scheme common for light and dark mode */\n",
|
| 156 |
+
" --sklearn-color-text: #000;\n",
|
| 157 |
+
" --sklearn-color-text-muted: #666;\n",
|
| 158 |
+
" --sklearn-color-line: gray;\n",
|
| 159 |
+
" /* Definition of color scheme for unfitted estimators */\n",
|
| 160 |
+
" --sklearn-color-unfitted-level-0: #fff5e6;\n",
|
| 161 |
+
" --sklearn-color-unfitted-level-1: #f6e4d2;\n",
|
| 162 |
+
" --sklearn-color-unfitted-level-2: #ffe0b3;\n",
|
| 163 |
+
" --sklearn-color-unfitted-level-3: chocolate;\n",
|
| 164 |
+
" /* Definition of color scheme for fitted estimators */\n",
|
| 165 |
+
" --sklearn-color-fitted-level-0: #f0f8ff;\n",
|
| 166 |
+
" --sklearn-color-fitted-level-1: #d4ebff;\n",
|
| 167 |
+
" --sklearn-color-fitted-level-2: #b3dbfd;\n",
|
| 168 |
+
" --sklearn-color-fitted-level-3: cornflowerblue;\n",
|
| 169 |
+
"\n",
|
| 170 |
+
" /* Specific color for light theme */\n",
|
| 171 |
+
" --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
|
| 172 |
+
" --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
|
| 173 |
+
" --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
|
| 174 |
+
" --sklearn-color-icon: #696969;\n",
|
| 175 |
+
"\n",
|
| 176 |
+
" @media (prefers-color-scheme: dark) {\n",
|
| 177 |
+
" /* Redefinition of color scheme for dark theme */\n",
|
| 178 |
+
" --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
|
| 179 |
+
" --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
|
| 180 |
+
" --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
|
| 181 |
+
" --sklearn-color-icon: #878787;\n",
|
| 182 |
+
" }\n",
|
| 183 |
+
"}\n",
|
| 184 |
+
"\n",
|
| 185 |
+
"#sk-container-id-2 {\n",
|
| 186 |
+
" color: var(--sklearn-color-text);\n",
|
| 187 |
+
"}\n",
|
| 188 |
+
"\n",
|
| 189 |
+
"#sk-container-id-2 pre {\n",
|
| 190 |
+
" padding: 0;\n",
|
| 191 |
+
"}\n",
|
| 192 |
+
"\n",
|
| 193 |
+
"#sk-container-id-2 input.sk-hidden--visually {\n",
|
| 194 |
+
" border: 0;\n",
|
| 195 |
+
" clip: rect(1px 1px 1px 1px);\n",
|
| 196 |
+
" clip: rect(1px, 1px, 1px, 1px);\n",
|
| 197 |
+
" height: 1px;\n",
|
| 198 |
+
" margin: -1px;\n",
|
| 199 |
+
" overflow: hidden;\n",
|
| 200 |
+
" padding: 0;\n",
|
| 201 |
+
" position: absolute;\n",
|
| 202 |
+
" width: 1px;\n",
|
| 203 |
+
"}\n",
|
| 204 |
+
"\n",
|
| 205 |
+
"#sk-container-id-2 div.sk-dashed-wrapped {\n",
|
| 206 |
+
" border: 1px dashed var(--sklearn-color-line);\n",
|
| 207 |
+
" margin: 0 0.4em 0.5em 0.4em;\n",
|
| 208 |
+
" box-sizing: border-box;\n",
|
| 209 |
+
" padding-bottom: 0.4em;\n",
|
| 210 |
+
" background-color: var(--sklearn-color-background);\n",
|
| 211 |
+
"}\n",
|
| 212 |
+
"\n",
|
| 213 |
+
"#sk-container-id-2 div.sk-container {\n",
|
| 214 |
+
" /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
|
| 215 |
+
" but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
|
| 216 |
+
" so we also need the `!important` here to be able to override the\n",
|
| 217 |
+
" default hidden behavior on the sphinx rendered scikit-learn.org.\n",
|
| 218 |
+
" See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
|
| 219 |
+
" display: inline-block !important;\n",
|
| 220 |
+
" position: relative;\n",
|
| 221 |
+
"}\n",
|
| 222 |
+
"\n",
|
| 223 |
+
"#sk-container-id-2 div.sk-text-repr-fallback {\n",
|
| 224 |
+
" display: none;\n",
|
| 225 |
+
"}\n",
|
| 226 |
+
"\n",
|
| 227 |
+
"div.sk-parallel-item,\n",
|
| 228 |
+
"div.sk-serial,\n",
|
| 229 |
+
"div.sk-item {\n",
|
| 230 |
+
" /* draw centered vertical line to link estimators */\n",
|
| 231 |
+
" background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
|
| 232 |
+
" background-size: 2px 100%;\n",
|
| 233 |
+
" background-repeat: no-repeat;\n",
|
| 234 |
+
" background-position: center center;\n",
|
| 235 |
+
"}\n",
|
| 236 |
+
"\n",
|
| 237 |
+
"/* Parallel-specific style estimator block */\n",
|
| 238 |
+
"\n",
|
| 239 |
+
"#sk-container-id-2 div.sk-parallel-item::after {\n",
|
| 240 |
+
" content: \"\";\n",
|
| 241 |
+
" width: 100%;\n",
|
| 242 |
+
" border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
|
| 243 |
+
" flex-grow: 1;\n",
|
| 244 |
+
"}\n",
|
| 245 |
+
"\n",
|
| 246 |
+
"#sk-container-id-2 div.sk-parallel {\n",
|
| 247 |
+
" display: flex;\n",
|
| 248 |
+
" align-items: stretch;\n",
|
| 249 |
+
" justify-content: center;\n",
|
| 250 |
+
" background-color: var(--sklearn-color-background);\n",
|
| 251 |
+
" position: relative;\n",
|
| 252 |
+
"}\n",
|
| 253 |
+
"\n",
|
| 254 |
+
"#sk-container-id-2 div.sk-parallel-item {\n",
|
| 255 |
+
" display: flex;\n",
|
| 256 |
+
" flex-direction: column;\n",
|
| 257 |
+
"}\n",
|
| 258 |
+
"\n",
|
| 259 |
+
"#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
|
| 260 |
+
" align-self: flex-end;\n",
|
| 261 |
+
" width: 50%;\n",
|
| 262 |
+
"}\n",
|
| 263 |
+
"\n",
|
| 264 |
+
"#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
|
| 265 |
+
" align-self: flex-start;\n",
|
| 266 |
+
" width: 50%;\n",
|
| 267 |
+
"}\n",
|
| 268 |
+
"\n",
|
| 269 |
+
"#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
|
| 270 |
+
" width: 0;\n",
|
| 271 |
+
"}\n",
|
| 272 |
+
"\n",
|
| 273 |
+
"/* Serial-specific style estimator block */\n",
|
| 274 |
+
"\n",
|
| 275 |
+
"#sk-container-id-2 div.sk-serial {\n",
|
| 276 |
+
" display: flex;\n",
|
| 277 |
+
" flex-direction: column;\n",
|
| 278 |
+
" align-items: center;\n",
|
| 279 |
+
" background-color: var(--sklearn-color-background);\n",
|
| 280 |
+
" padding-right: 1em;\n",
|
| 281 |
+
" padding-left: 1em;\n",
|
| 282 |
+
"}\n",
|
| 283 |
+
"\n",
|
| 284 |
+
"\n",
|
| 285 |
+
"/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
|
| 286 |
+
"clickable and can be expanded/collapsed.\n",
|
| 287 |
+
"- Pipeline and ColumnTransformer use this feature and define the default style\n",
|
| 288 |
+
"- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
|
| 289 |
+
"*/\n",
|
| 290 |
+
"\n",
|
| 291 |
+
"/* Pipeline and ColumnTransformer style (default) */\n",
|
| 292 |
+
"\n",
|
| 293 |
+
"#sk-container-id-2 div.sk-toggleable {\n",
|
| 294 |
+
" /* Default theme specific background. It is overwritten whether we have a\n",
|
| 295 |
+
" specific estimator or a Pipeline/ColumnTransformer */\n",
|
| 296 |
+
" background-color: var(--sklearn-color-background);\n",
|
| 297 |
+
"}\n",
|
| 298 |
+
"\n",
|
| 299 |
+
"/* Toggleable label */\n",
|
| 300 |
+
"#sk-container-id-2 label.sk-toggleable__label {\n",
|
| 301 |
+
" cursor: pointer;\n",
|
| 302 |
+
" display: flex;\n",
|
| 303 |
+
" width: 100%;\n",
|
| 304 |
+
" margin-bottom: 0;\n",
|
| 305 |
+
" padding: 0.5em;\n",
|
| 306 |
+
" box-sizing: border-box;\n",
|
| 307 |
+
" text-align: center;\n",
|
| 308 |
+
" align-items: start;\n",
|
| 309 |
+
" justify-content: space-between;\n",
|
| 310 |
+
" gap: 0.5em;\n",
|
| 311 |
+
"}\n",
|
| 312 |
+
"\n",
|
| 313 |
+
"#sk-container-id-2 label.sk-toggleable__label .caption {\n",
|
| 314 |
+
" font-size: 0.6rem;\n",
|
| 315 |
+
" font-weight: lighter;\n",
|
| 316 |
+
" color: var(--sklearn-color-text-muted);\n",
|
| 317 |
+
"}\n",
|
| 318 |
+
"\n",
|
| 319 |
+
"#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
|
| 320 |
+
" /* Arrow on the left of the label */\n",
|
| 321 |
+
" content: \"▸\";\n",
|
| 322 |
+
" float: left;\n",
|
| 323 |
+
" margin-right: 0.25em;\n",
|
| 324 |
+
" color: var(--sklearn-color-icon);\n",
|
| 325 |
+
"}\n",
|
| 326 |
+
"\n",
|
| 327 |
+
"#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
|
| 328 |
+
" color: var(--sklearn-color-text);\n",
|
| 329 |
+
"}\n",
|
| 330 |
+
"\n",
|
| 331 |
+
"/* Toggleable content - dropdown */\n",
|
| 332 |
+
"\n",
|
| 333 |
+
"#sk-container-id-2 div.sk-toggleable__content {\n",
|
| 334 |
+
" max-height: 0;\n",
|
| 335 |
+
" max-width: 0;\n",
|
| 336 |
+
" overflow: hidden;\n",
|
| 337 |
+
" text-align: left;\n",
|
| 338 |
+
" /* unfitted */\n",
|
| 339 |
+
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 340 |
+
"}\n",
|
| 341 |
+
"\n",
|
| 342 |
+
"#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
|
| 343 |
+
" /* fitted */\n",
|
| 344 |
+
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 345 |
+
"}\n",
|
| 346 |
+
"\n",
|
| 347 |
+
"#sk-container-id-2 div.sk-toggleable__content pre {\n",
|
| 348 |
+
" margin: 0.2em;\n",
|
| 349 |
+
" border-radius: 0.25em;\n",
|
| 350 |
+
" color: var(--sklearn-color-text);\n",
|
| 351 |
+
" /* unfitted */\n",
|
| 352 |
+
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 353 |
+
"}\n",
|
| 354 |
+
"\n",
|
| 355 |
+
"#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
|
| 356 |
+
" /* unfitted */\n",
|
| 357 |
+
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 358 |
+
"}\n",
|
| 359 |
+
"\n",
|
| 360 |
+
"#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
|
| 361 |
+
" /* Expand drop-down */\n",
|
| 362 |
+
" max-height: 200px;\n",
|
| 363 |
+
" max-width: 100%;\n",
|
| 364 |
+
" overflow: auto;\n",
|
| 365 |
+
"}\n",
|
| 366 |
+
"\n",
|
| 367 |
+
"#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
|
| 368 |
+
" content: \"▾\";\n",
|
| 369 |
+
"}\n",
|
| 370 |
+
"\n",
|
| 371 |
+
"/* Pipeline/ColumnTransformer-specific style */\n",
|
| 372 |
+
"\n",
|
| 373 |
+
"#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
|
| 374 |
+
" color: var(--sklearn-color-text);\n",
|
| 375 |
+
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 376 |
+
"}\n",
|
| 377 |
+
"\n",
|
| 378 |
+
"#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
|
| 379 |
+
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 380 |
+
"}\n",
|
| 381 |
+
"\n",
|
| 382 |
+
"/* Estimator-specific style */\n",
|
| 383 |
+
"\n",
|
| 384 |
+
"/* Colorize estimator box */\n",
|
| 385 |
+
"#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
|
| 386 |
+
" /* unfitted */\n",
|
| 387 |
+
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 388 |
+
"}\n",
|
| 389 |
+
"\n",
|
| 390 |
+
"#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
|
| 391 |
+
" /* fitted */\n",
|
| 392 |
+
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 393 |
+
"}\n",
|
| 394 |
+
"\n",
|
| 395 |
+
"#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
|
| 396 |
+
"#sk-container-id-2 div.sk-label label {\n",
|
| 397 |
+
" /* The background is the default theme color */\n",
|
| 398 |
+
" color: var(--sklearn-color-text-on-default-background);\n",
|
| 399 |
+
"}\n",
|
| 400 |
+
"\n",
|
| 401 |
+
"/* On hover, darken the color of the background */\n",
|
| 402 |
+
"#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
|
| 403 |
+
" color: var(--sklearn-color-text);\n",
|
| 404 |
+
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 405 |
+
"}\n",
|
| 406 |
+
"\n",
|
| 407 |
+
"/* Label box, darken color on hover, fitted */\n",
|
| 408 |
+
"#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
|
| 409 |
+
" color: var(--sklearn-color-text);\n",
|
| 410 |
+
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 411 |
+
"}\n",
|
| 412 |
+
"\n",
|
| 413 |
+
"/* Estimator label */\n",
|
| 414 |
+
"\n",
|
| 415 |
+
"#sk-container-id-2 div.sk-label label {\n",
|
| 416 |
+
" font-family: monospace;\n",
|
| 417 |
+
" font-weight: bold;\n",
|
| 418 |
+
" display: inline-block;\n",
|
| 419 |
+
" line-height: 1.2em;\n",
|
| 420 |
+
"}\n",
|
| 421 |
+
"\n",
|
| 422 |
+
"#sk-container-id-2 div.sk-label-container {\n",
|
| 423 |
+
" text-align: center;\n",
|
| 424 |
+
"}\n",
|
| 425 |
+
"\n",
|
| 426 |
+
"/* Estimator-specific */\n",
|
| 427 |
+
"#sk-container-id-2 div.sk-estimator {\n",
|
| 428 |
+
" font-family: monospace;\n",
|
| 429 |
+
" border: 1px dotted var(--sklearn-color-border-box);\n",
|
| 430 |
+
" border-radius: 0.25em;\n",
|
| 431 |
+
" box-sizing: border-box;\n",
|
| 432 |
+
" margin-bottom: 0.5em;\n",
|
| 433 |
+
" /* unfitted */\n",
|
| 434 |
+
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 435 |
+
"}\n",
|
| 436 |
+
"\n",
|
| 437 |
+
"#sk-container-id-2 div.sk-estimator.fitted {\n",
|
| 438 |
+
" /* fitted */\n",
|
| 439 |
+
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 440 |
+
"}\n",
|
| 441 |
+
"\n",
|
| 442 |
+
"/* on hover */\n",
|
| 443 |
+
"#sk-container-id-2 div.sk-estimator:hover {\n",
|
| 444 |
+
" /* unfitted */\n",
|
| 445 |
+
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 446 |
+
"}\n",
|
| 447 |
+
"\n",
|
| 448 |
+
"#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
|
| 449 |
+
" /* fitted */\n",
|
| 450 |
+
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 451 |
+
"}\n",
|
| 452 |
+
"\n",
|
| 453 |
+
"/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
|
| 454 |
+
"\n",
|
| 455 |
+
"/* Common style for \"i\" and \"?\" */\n",
|
| 456 |
+
"\n",
|
| 457 |
+
".sk-estimator-doc-link,\n",
|
| 458 |
+
"a:link.sk-estimator-doc-link,\n",
|
| 459 |
+
"a:visited.sk-estimator-doc-link {\n",
|
| 460 |
+
" float: right;\n",
|
| 461 |
+
" font-size: smaller;\n",
|
| 462 |
+
" line-height: 1em;\n",
|
| 463 |
+
" font-family: monospace;\n",
|
| 464 |
+
" background-color: var(--sklearn-color-background);\n",
|
| 465 |
+
" border-radius: 1em;\n",
|
| 466 |
+
" height: 1em;\n",
|
| 467 |
+
" width: 1em;\n",
|
| 468 |
+
" text-decoration: none !important;\n",
|
| 469 |
+
" margin-left: 0.5em;\n",
|
| 470 |
+
" text-align: center;\n",
|
| 471 |
+
" /* unfitted */\n",
|
| 472 |
+
" border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
|
| 473 |
+
" color: var(--sklearn-color-unfitted-level-1);\n",
|
| 474 |
+
"}\n",
|
| 475 |
+
"\n",
|
| 476 |
+
".sk-estimator-doc-link.fitted,\n",
|
| 477 |
+
"a:link.sk-estimator-doc-link.fitted,\n",
|
| 478 |
+
"a:visited.sk-estimator-doc-link.fitted {\n",
|
| 479 |
+
" /* fitted */\n",
|
| 480 |
+
" border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
|
| 481 |
+
" color: var(--sklearn-color-fitted-level-1);\n",
|
| 482 |
+
"}\n",
|
| 483 |
+
"\n",
|
| 484 |
+
"/* On hover */\n",
|
| 485 |
+
"div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
|
| 486 |
+
".sk-estimator-doc-link:hover,\n",
|
| 487 |
+
"div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
|
| 488 |
+
".sk-estimator-doc-link:hover {\n",
|
| 489 |
+
" /* unfitted */\n",
|
| 490 |
+
" background-color: var(--sklearn-color-unfitted-level-3);\n",
|
| 491 |
+
" color: var(--sklearn-color-background);\n",
|
| 492 |
+
" text-decoration: none;\n",
|
| 493 |
+
"}\n",
|
| 494 |
+
"\n",
|
| 495 |
+
"div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
|
| 496 |
+
".sk-estimator-doc-link.fitted:hover,\n",
|
| 497 |
+
"div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
|
| 498 |
+
".sk-estimator-doc-link.fitted:hover {\n",
|
| 499 |
+
" /* fitted */\n",
|
| 500 |
+
" background-color: var(--sklearn-color-fitted-level-3);\n",
|
| 501 |
+
" color: var(--sklearn-color-background);\n",
|
| 502 |
+
" text-decoration: none;\n",
|
| 503 |
+
"}\n",
|
| 504 |
+
"\n",
|
| 505 |
+
"/* Span, style for the box shown on hovering the info icon */\n",
|
| 506 |
+
".sk-estimator-doc-link span {\n",
|
| 507 |
+
" display: none;\n",
|
| 508 |
+
" z-index: 9999;\n",
|
| 509 |
+
" position: relative;\n",
|
| 510 |
+
" font-weight: normal;\n",
|
| 511 |
+
" right: .2ex;\n",
|
| 512 |
+
" padding: .5ex;\n",
|
| 513 |
+
" margin: .5ex;\n",
|
| 514 |
+
" width: min-content;\n",
|
| 515 |
+
" min-width: 20ex;\n",
|
| 516 |
+
" max-width: 50ex;\n",
|
| 517 |
+
" color: var(--sklearn-color-text);\n",
|
| 518 |
+
" box-shadow: 2pt 2pt 4pt #999;\n",
|
| 519 |
+
" /* unfitted */\n",
|
| 520 |
+
" background: var(--sklearn-color-unfitted-level-0);\n",
|
| 521 |
+
" border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
|
| 522 |
+
"}\n",
|
| 523 |
+
"\n",
|
| 524 |
+
".sk-estimator-doc-link.fitted span {\n",
|
| 525 |
+
" /* fitted */\n",
|
| 526 |
+
" background: var(--sklearn-color-fitted-level-0);\n",
|
| 527 |
+
" border: var(--sklearn-color-fitted-level-3);\n",
|
| 528 |
+
"}\n",
|
| 529 |
+
"\n",
|
| 530 |
+
".sk-estimator-doc-link:hover span {\n",
|
| 531 |
+
" display: block;\n",
|
| 532 |
+
"}\n",
|
| 533 |
+
"\n",
|
| 534 |
+
"/* \"?\"-specific style due to the `<a>` HTML tag */\n",
|
| 535 |
+
"\n",
|
| 536 |
+
"#sk-container-id-2 a.estimator_doc_link {\n",
|
| 537 |
+
" float: right;\n",
|
| 538 |
+
" font-size: 1rem;\n",
|
| 539 |
+
" line-height: 1em;\n",
|
| 540 |
+
" font-family: monospace;\n",
|
| 541 |
+
" background-color: var(--sklearn-color-background);\n",
|
| 542 |
+
" border-radius: 1rem;\n",
|
| 543 |
+
" height: 1rem;\n",
|
| 544 |
+
" width: 1rem;\n",
|
| 545 |
+
" text-decoration: none;\n",
|
| 546 |
+
" /* unfitted */\n",
|
| 547 |
+
" color: var(--sklearn-color-unfitted-level-1);\n",
|
| 548 |
+
" border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
|
| 549 |
+
"}\n",
|
| 550 |
+
"\n",
|
| 551 |
+
"#sk-container-id-2 a.estimator_doc_link.fitted {\n",
|
| 552 |
+
" /* fitted */\n",
|
| 553 |
+
" border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
|
| 554 |
+
" color: var(--sklearn-color-fitted-level-1);\n",
|
| 555 |
+
"}\n",
|
| 556 |
+
"\n",
|
| 557 |
+
"/* On hover */\n",
|
| 558 |
+
"#sk-container-id-2 a.estimator_doc_link:hover {\n",
|
| 559 |
+
" /* unfitted */\n",
|
| 560 |
+
" background-color: var(--sklearn-color-unfitted-level-3);\n",
|
| 561 |
+
" color: var(--sklearn-color-background);\n",
|
| 562 |
+
" text-decoration: none;\n",
|
| 563 |
+
"}\n",
|
| 564 |
+
"\n",
|
| 565 |
+
"#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
|
| 566 |
+
" /* fitted */\n",
|
| 567 |
+
" background-color: var(--sklearn-color-fitted-level-3);\n",
|
| 568 |
+
"}\n",
|
| 569 |
+
"</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>Pipeline(steps=[('tfidf',\n",
|
| 570 |
+
" TfidfVectorizer(max_features=10000, ngram_range=(1, 2),\n",
|
| 571 |
+
" stop_words='english')),\n",
|
| 572 |
+
" ('svm',\n",
|
| 573 |
+
" SVC(class_weight='balanced', kernel='linear',\n",
|
| 574 |
+
" probability=True))])</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item sk-dashed-wrapped\"><div class=\"sk-label-container\"><div class=\"sk-label fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-4\" type=\"checkbox\" ><label for=\"sk-estimator-id-4\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>Pipeline</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.pipeline.Pipeline.html\">?<span>Documentation for Pipeline</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>Pipeline(steps=[('tfidf',\n",
|
| 575 |
+
" TfidfVectorizer(max_features=10000, ngram_range=(1, 2),\n",
|
| 576 |
+
" stop_words='english')),\n",
|
| 577 |
+
" ('svm',\n",
|
| 578 |
+
" SVC(class_weight='balanced', kernel='linear',\n",
|
| 579 |
+
" probability=True))])</pre></div> </div></div><div class=\"sk-serial\"><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-5\" type=\"checkbox\" ><label for=\"sk-estimator-id-5\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>TfidfVectorizer</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html\">?<span>Documentation for TfidfVectorizer</span></a></div></label><div class=\"sk-toggleable__content fitted\"><pre>TfidfVectorizer(max_features=10000, ngram_range=(1, 2), stop_words='english')</pre></div> </div></div><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-6\" type=\"checkbox\" ><label for=\"sk-estimator-id-6\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>SVC</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.svm.SVC.html\">?<span>Documentation for SVC</span></a></div></label><div class=\"sk-toggleable__content fitted\"><pre>SVC(class_weight='balanced', kernel='linear', probability=True)</pre></div> </div></div></div></div></div></div>"
|
| 580 |
+
],
|
| 581 |
+
"text/plain": [
|
| 582 |
+
"Pipeline(steps=[('tfidf',\n",
|
| 583 |
+
" TfidfVectorizer(max_features=10000, ngram_range=(1, 2),\n",
|
| 584 |
+
" stop_words='english')),\n",
|
| 585 |
+
" ('svm',\n",
|
| 586 |
+
" SVC(class_weight='balanced', kernel='linear',\n",
|
| 587 |
+
" probability=True))])"
|
| 588 |
+
]
|
| 589 |
+
},
|
| 590 |
+
"execution_count": 61,
|
| 591 |
+
"metadata": {},
|
| 592 |
+
"output_type": "execute_result"
|
| 593 |
+
}
|
| 594 |
+
],
|
| 595 |
+
"source": [
|
| 596 |
+
"#model training\n",
|
| 597 |
+
"model.fit(X_train, y_train)"
|
| 598 |
+
]
|
| 599 |
+
},
|
| 600 |
+
{
|
| 601 |
+
"cell_type": "markdown",
|
| 602 |
+
"metadata": {},
|
| 603 |
+
"source": [
|
| 604 |
+
"#### Model Evaluation"
|
| 605 |
+
]
|
| 606 |
+
},
|
| 607 |
+
{
|
| 608 |
+
"cell_type": "code",
|
| 609 |
+
"execution_count": null,
|
| 610 |
+
"metadata": {},
|
| 611 |
+
"outputs": [
|
| 612 |
+
{
|
| 613 |
+
"name": "stdout",
|
| 614 |
+
"output_type": "stream",
|
| 615 |
+
"text": [
|
| 616 |
+
"Model Accuracy: 0.7510\n",
|
| 617 |
+
"\n",
|
| 618 |
+
"Classification Report:\n",
|
| 619 |
+
" precision recall f1-score support\n",
|
| 620 |
+
"\n",
|
| 621 |
+
" negative 0.88 0.79 0.83 3085\n",
|
| 622 |
+
" neutral 0.51 0.64 0.57 984\n",
|
| 623 |
+
" positive 0.67 0.73 0.70 763\n",
|
| 624 |
+
"\n",
|
| 625 |
+
" accuracy 0.75 4832\n",
|
| 626 |
+
" macro avg 0.69 0.72 0.70 4832\n",
|
| 627 |
+
"weighted avg 0.77 0.75 0.76 4832\n",
|
| 628 |
+
"\n"
|
| 629 |
+
]
|
| 630 |
+
}
|
| 631 |
+
],
|
| 632 |
+
"source": [
|
| 633 |
+
"# Evaluate model\n",
|
| 634 |
+
"y_pred = model.predict(X_test)\n",
|
| 635 |
+
"accuracy = accuracy_score(y_test, y_pred)\n",
|
| 636 |
+
"\n",
|
| 637 |
+
"#Display model accuracy\n",
|
| 638 |
+
"print(f\"Model Accuracy: {accuracy:.4f}\")\n",
|
| 639 |
+
"\n",
|
| 640 |
+
"# Display classification report\n",
|
| 641 |
+
"print(\"\\nClassification Report:\")\n",
|
| 642 |
+
"print(classification_report(y_test, y_pred, target_names=['negative', 'neutral', 'positive']))"
|
| 643 |
+
]
|
| 644 |
+
},
|
| 645 |
+
{
|
| 646 |
+
"cell_type": "code",
|
| 647 |
+
"execution_count": 63,
|
| 648 |
+
"metadata": {},
|
| 649 |
+
"outputs": [
|
| 650 |
+
{
|
| 651 |
+
"data": {
|
| 652 |
+
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjkAAAHHCAYAAABdm0mZAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAV0BJREFUeJzt3Qd8U+XXwPHTslfZe+8NMvwzFBAQEJCtqCB7yFaGIogsAZE9RIayRQFRUNnIFhAQWbKXsvcoq8y8n/PwJjalDS1Nx739ff1c2+Te3NwkNDk55zzP9XE4HA4BAACwGd+oPgAAAICIQJADAABsiSAHAADYEkEOAACwJYIcAABgSwQ5AADAlghyAACALRHkAAAAWyLIAQAAtkSQA8QQR44ckapVq0rSpEnFx8dHFi1a5NX9//PPP2a/M2bM8Op+reyVV14xC4CoQZADRKJjx47Je++9Jzly5JD48eOLn5+fvPTSSzJ27Fi5e/duhN53s2bNZO/evTJ48GCZPXu2lCxZUuyiefPmJsDS5zO451EDPF2vy4gRI8K8/7Nnz0r//v1l165dXjpiAJEhdqTcCwBZsmSJvPnmmxIvXjxp2rSpFCpUSO7fvy+///67fPjhh7Jv3z6ZMmVKhNy3fvBv2bJFPvnkE+nUqVOE3EfWrFnN/cSJE0eiQuzYseXOnTvy66+/SsOGDd3WzZkzxwSVAQEBz7VvDXIGDBgg2bJlkxdeeCHUt1u5cuVz3R8A7yDIASLBiRMn5O233zaBwJo1ayR9+vSudR07dpSjR4+aICiiXLp0yfxMlixZhN2HZkk0kIgqGjxqVuz7779/Ksj57rvvpGbNmvLjjz9GyrFosJUwYUKJGzdupNwfgOBRrgIiwbBhw+TWrVsydepUtwDHKVeuXPL++++7Lj98+FA+++wzyZkzp/nw1gxC79695d69e2630+tff/11kw363//+Z4IMLYXNmjXLtY2WWTS4Upox0mBEb+cs8zh/D0xvo9sFtmrVKnn55ZdNoJQ4cWLJmzevOaZn9eRoUFeuXDlJlCiRuW2dOnXkwIEDwd6fBnt6TLqd9g61aNHCBAyh1ahRI1m2bJlcv37ddd327dtNuUrXBXX16lXp0aOHFC5c2DwmLXdVr15ddu/e7dpm3bp18uKLL5rf9XicZS/n49SeG83K7dixQ8qXL2+CG+fzErQnR0uG+hoFffzVqlWT5MmTm4wRAO8hyAEigZZQNPgoW7ZsqLZv3bq19O3bV4oXLy6jR4+WChUqyOeff26yQUFpYPDGG29IlSpVZOTIkebDUgMFLX+p+vXrm32od955x/TjjBkzJkzHr/vSYEqDrIEDB5r7qV27tmzatMnj7X777TfzAX7x4kUTyHTr1k02b95sMi4aFAWlGZibN2+ax6q/ayChZaLQ0seqAchPP/3klsXJly+feS6DOn78uGnA1sc2atQoEwRq35I+386AI3/+/OYxq7Zt25rnTxcNaJyuXLligiMtZelzW7FixWCPT3uvUqdObYKdR48emesmT55sylrjx4+XDBkyhPqxAggFB4AIdePGDYf+qdWpUydU2+/atcts37p1a7fre/ToYa5fs2aN67qsWbOa6zZs2OC67uLFi4548eI5unfv7rruxIkTZrvhw4e77bNZs2ZmH0H169fPbO80evRoc/nSpUshHrfzPqZPn+667oUXXnCkSZPGceXKFdd1u3fvdvj6+jqaNm361P21bNnSbZ/16tVzpEyZMsT7DPw4EiVKZH5/4403HJUrVza/P3r0yJEuXTrHgAEDgn0OAgICzDZBH4c+fwMHDnRdt3379qcem1OFChXMukmTJgW7TpfAVqxYYbYfNGiQ4/jx447EiRM76tat+8zHCCDsyOQAEczf39/8TJIkSai2X7p0qfmpWY/Aunfvbn4G7d0pUKCAKQc5aaZAS0mapfAWZy/Pzz//LI8fPw7Vbc6dO2dGI2lWKUWKFK7rixQpYrJOzscZWLt27dwu6+PSLInzOQwNLUtpien8+fOmVKY/gytVKS0F+vo+eRvUzIrel7MU99dff4X6PnU/WsoKDR3GryPsNDukmSctX2k2B4D3EeQAEUz7PJSWYULj33//NR+82qcTWLp06UywoesDy5Ily1P70JLVtWvXxFveeustU2LSMlratGlN2Wz+/PkeAx7ncWrAEJSWgC5fviy3b9/2+Fj0caiwPJYaNWqYgHLevHlmVJX20wR9Lp30+LWUlzt3bhOopEqVygSJe/bskRs3boT6PjNmzBimJmMdxq6BnwaB48aNkzRp0oT6tgBCjyAHiIQgR3st/v777zDdLmjjb0hixYoV7PUOh+O578PZL+KUIEEC2bBhg+mxadKkiQkCNPDRjEzQbcMjPI/FSYMV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",
|
| 653 |
+
"text/plain": [
|
| 654 |
+
"<Figure size 640x480 with 2 Axes>"
|
| 655 |
+
]
|
| 656 |
+
},
|
| 657 |
+
"metadata": {},
|
| 658 |
+
"output_type": "display_data"
|
| 659 |
+
}
|
| 660 |
+
],
|
| 661 |
+
"source": [
|
| 662 |
+
"# Plot confusion matrix\n",
|
| 663 |
+
"cm = confusion_matrix(y_test, y_pred)\n",
|
| 664 |
+
"disp = ConfusionMatrixDisplay(confusion_matrix=cm, \n",
|
| 665 |
+
" display_labels=['Negative', 'Neutral', 'Positive'])\n",
|
| 666 |
+
"disp.plot(cmap=plt.cm.Blues)\n",
|
| 667 |
+
"plt.title('Confusion Matrix')\n",
|
| 668 |
+
"plt.show()"
|
| 669 |
+
]
|
| 670 |
+
},
|
| 671 |
+
{
|
| 672 |
+
"cell_type": "markdown",
|
| 673 |
+
"metadata": {},
|
| 674 |
+
"source": [
|
| 675 |
+
"#### Model Export"
|
| 676 |
+
]
|
| 677 |
+
},
|
| 678 |
+
{
|
| 679 |
+
"cell_type": "code",
|
| 680 |
+
"execution_count": 64,
|
| 681 |
+
"metadata": {},
|
| 682 |
+
"outputs": [
|
| 683 |
+
{
|
| 684 |
+
"data": {
|
| 685 |
+
"text/plain": [
|
| 686 |
+
"['SA_model.pkl']"
|
| 687 |
+
]
|
| 688 |
+
},
|
| 689 |
+
"execution_count": 64,
|
| 690 |
+
"metadata": {},
|
| 691 |
+
"output_type": "execute_result"
|
| 692 |
+
}
|
| 693 |
+
],
|
| 694 |
+
"source": [
|
| 695 |
+
"# Save the trained model\n",
|
| 696 |
+
"joblib.dump(model, \"SA_model.pkl\")"
|
| 697 |
+
]
|
| 698 |
+
}
|
| 699 |
+
],
|
| 700 |
+
"metadata": {
|
| 701 |
+
"kernelspec": {
|
| 702 |
+
"display_name": "venv",
|
| 703 |
+
"language": "python",
|
| 704 |
+
"name": "python3"
|
| 705 |
+
},
|
| 706 |
+
"language_info": {
|
| 707 |
+
"codemirror_mode": {
|
| 708 |
+
"name": "ipython",
|
| 709 |
+
"version": 3
|
| 710 |
+
},
|
| 711 |
+
"file_extension": ".py",
|
| 712 |
+
"mimetype": "text/x-python",
|
| 713 |
+
"name": "python",
|
| 714 |
+
"nbconvert_exporter": "python",
|
| 715 |
+
"pygments_lexer": "ipython3",
|
| 716 |
+
"version": "3.12.2"
|
| 717 |
+
}
|
| 718 |
+
},
|
| 719 |
+
"nbformat": 4,
|
| 720 |
+
"nbformat_minor": 2
|
| 721 |
+
}
|