Spaces:
Build error
Build error
Commit ·
02c4ec3
1
Parent(s): aebd19f
Added Model Evaluation Tab
Browse files- app.py +54 -27
- classification_report.png +0 -0
- confusion_matrix.png +0 -0
- main.ipynb +92 -68
- sentiment_distribution.png +0 -0
- vectorizer.pkl +1 -1
app.py
CHANGED
|
@@ -14,30 +14,57 @@ with open("sentimentAnalysis_model.pkl", "rb") as model_file:
|
|
| 14 |
with open("vectorizer.pkl", "rb") as vectorizer_file:
|
| 15 |
vectorizer = joblib.load(vectorizer_file)
|
| 16 |
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
with open("vectorizer.pkl", "rb") as vectorizer_file:
|
| 15 |
vectorizer = joblib.load(vectorizer_file)
|
| 16 |
|
| 17 |
+
|
| 18 |
+
app, model_eval = st.tabs(["Application", "Model Evaluation"])
|
| 19 |
+
# STREAMLIT APP TAB 1
|
| 20 |
+
with app:
|
| 21 |
+
# MAPPING RESULTS
|
| 22 |
+
sentiment_mapping = {0: "Neutral", 1: "Positive", 2: "Negative"}
|
| 23 |
+
|
| 24 |
+
# FUNCTION TO REDUCE TEXT TO ITS MOST BASIC FORM
|
| 25 |
+
def clean_text(text):
|
| 26 |
+
text = text.lower()
|
| 27 |
+
text = re.sub(r'[^a-zA-Z\s]', '', text)
|
| 28 |
+
text = ' '.join([word for word in text.split() if word not in stop_words])
|
| 29 |
+
return text
|
| 30 |
+
|
| 31 |
+
# STREAMLIT UI
|
| 32 |
+
st.title("Sentiment Analysis App")
|
| 33 |
+
st.write("Enter text below to analyze its sentiment.")
|
| 34 |
+
|
| 35 |
+
user_input = st.text_area("Enter text:")
|
| 36 |
+
|
| 37 |
+
if st.button("Analyze Sentiment"):
|
| 38 |
+
if user_input:
|
| 39 |
+
cleaned_input = clean_text(user_input)
|
| 40 |
+
transformed_input = vectorizer.transform([cleaned_input])
|
| 41 |
+
|
| 42 |
+
prediction = model.predict(transformed_input)[0]
|
| 43 |
+
sentiment = sentiment_mapping[prediction]
|
| 44 |
+
|
| 45 |
+
st.write(f"Predicted Sentiment: **{sentiment}**")
|
| 46 |
+
else:
|
| 47 |
+
st.write("Please enter some text to analyze.")
|
| 48 |
+
|
| 49 |
+
with model_eval:
|
| 50 |
+
|
| 51 |
+
st.header("Model Evaluation")
|
| 52 |
+
st.write("The Sentiment Analysis model was trained in order to detect if a text is positive, negative, or neutral. The dataset was taken from kaggle.")
|
| 53 |
+
st.write("dataset by Dataset by Ismiel Hossen Abir. Link: https://www.kaggle.com/datasets/mdismielhossenabir/sentiment-analysis")
|
| 54 |
+
|
| 55 |
+
# SENTIMENT DISTRIBUTION
|
| 56 |
+
st.header("Sentinment Distribution")
|
| 57 |
+
st.write("The model was trained using a dataset with the total amount of text equivalent to the following labels")
|
| 58 |
+
|
| 59 |
+
# CONFUSION MATRIX
|
| 60 |
+
st.title("Confusion Matrix")
|
| 61 |
+
st.write("The confusion matrix displays the actual values or true labels with the predicted values from the model. With this, we can identify the margin of error the model has.")
|
| 62 |
+
st.image("confusion_matrix.png")
|
| 63 |
+
|
| 64 |
+
# EVALUATION MATRICS
|
| 65 |
+
st.title("Evaluation Metrics")
|
| 66 |
+
st.write("The image below represents the Accuracy, F1 score and the classification report of the model")
|
| 67 |
+
st.image("classification_report.png")
|
| 68 |
+
st.write("The model can be improved by using other models, but logistic regression was used for project purposes")
|
| 69 |
+
|
| 70 |
+
|
classification_report.png
ADDED
|
confusion_matrix.png
ADDED
|
main.ipynb
CHANGED
|
@@ -13,7 +13,7 @@
|
|
| 13 |
},
|
| 14 |
{
|
| 15 |
"cell_type": "code",
|
| 16 |
-
"execution_count":
|
| 17 |
"metadata": {},
|
| 18 |
"outputs": [
|
| 19 |
{
|
|
@@ -34,7 +34,7 @@
|
|
| 34 |
"from sklearn.model_selection import train_test_split\n",
|
| 35 |
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
| 36 |
"from sklearn.linear_model import LogisticRegression\n",
|
| 37 |
-
"from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n",
|
| 38 |
"import nltk\n",
|
| 39 |
"from nltk.corpus import stopwords\n",
|
| 40 |
"import re\n",
|
|
@@ -55,7 +55,7 @@
|
|
| 55 |
},
|
| 56 |
{
|
| 57 |
"cell_type": "code",
|
| 58 |
-
"execution_count":
|
| 59 |
"metadata": {},
|
| 60 |
"outputs": [],
|
| 61 |
"source": [
|
|
@@ -65,7 +65,7 @@
|
|
| 65 |
},
|
| 66 |
{
|
| 67 |
"cell_type": "code",
|
| 68 |
-
"execution_count":
|
| 69 |
"metadata": {},
|
| 70 |
"outputs": [],
|
| 71 |
"source": [
|
|
@@ -75,7 +75,7 @@
|
|
| 75 |
},
|
| 76 |
{
|
| 77 |
"cell_type": "code",
|
| 78 |
-
"execution_count":
|
| 79 |
"metadata": {},
|
| 80 |
"outputs": [
|
| 81 |
{
|
|
@@ -100,7 +100,7 @@
|
|
| 100 |
},
|
| 101 |
{
|
| 102 |
"cell_type": "code",
|
| 103 |
-
"execution_count":
|
| 104 |
"metadata": {},
|
| 105 |
"outputs": [
|
| 106 |
{
|
|
@@ -119,7 +119,7 @@
|
|
| 119 |
},
|
| 120 |
{
|
| 121 |
"cell_type": "code",
|
| 122 |
-
"execution_count":
|
| 123 |
"metadata": {},
|
| 124 |
"outputs": [
|
| 125 |
{
|
|
@@ -132,7 +132,7 @@
|
|
| 132 |
"Name: count, dtype: int64"
|
| 133 |
]
|
| 134 |
},
|
| 135 |
-
"execution_count":
|
| 136 |
"metadata": {},
|
| 137 |
"output_type": "execute_result"
|
| 138 |
}
|
|
@@ -143,7 +143,7 @@
|
|
| 143 |
},
|
| 144 |
{
|
| 145 |
"cell_type": "code",
|
| 146 |
-
"execution_count":
|
| 147 |
"metadata": {},
|
| 148 |
"outputs": [
|
| 149 |
{
|
|
@@ -158,10 +158,11 @@
|
|
| 158 |
}
|
| 159 |
],
|
| 160 |
"source": [
|
| 161 |
-
"# Data Visualization\n",
|
| 162 |
"sns.countplot(x=df[\"sentiment\"])\n",
|
| 163 |
"plt.title(\"Sentiment Distribution\")\n",
|
| 164 |
-
"plt.
|
|
|
|
|
|
|
| 165 |
]
|
| 166 |
},
|
| 167 |
{
|
|
@@ -174,7 +175,7 @@
|
|
| 174 |
},
|
| 175 |
{
|
| 176 |
"cell_type": "code",
|
| 177 |
-
"execution_count":
|
| 178 |
"metadata": {},
|
| 179 |
"outputs": [],
|
| 180 |
"source": [
|
|
@@ -187,7 +188,7 @@
|
|
| 187 |
},
|
| 188 |
{
|
| 189 |
"cell_type": "code",
|
| 190 |
-
"execution_count":
|
| 191 |
"metadata": {},
|
| 192 |
"outputs": [],
|
| 193 |
"source": [
|
|
@@ -203,7 +204,7 @@
|
|
| 203 |
},
|
| 204 |
{
|
| 205 |
"cell_type": "code",
|
| 206 |
-
"execution_count":
|
| 207 |
"metadata": {},
|
| 208 |
"outputs": [],
|
| 209 |
"source": [
|
|
@@ -222,7 +223,7 @@
|
|
| 222 |
},
|
| 223 |
{
|
| 224 |
"cell_type": "code",
|
| 225 |
-
"execution_count":
|
| 226 |
"metadata": {},
|
| 227 |
"outputs": [],
|
| 228 |
"source": [
|
|
@@ -231,7 +232,7 @@
|
|
| 231 |
},
|
| 232 |
{
|
| 233 |
"cell_type": "code",
|
| 234 |
-
"execution_count":
|
| 235 |
"metadata": {},
|
| 236 |
"outputs": [],
|
| 237 |
"source": [
|
|
@@ -249,13 +250,13 @@
|
|
| 249 |
},
|
| 250 |
{
|
| 251 |
"cell_type": "code",
|
| 252 |
-
"execution_count":
|
| 253 |
"metadata": {},
|
| 254 |
"outputs": [
|
| 255 |
{
|
| 256 |
"data": {
|
| 257 |
"text/html": [
|
| 258 |
-
"<style>#sk-container-id-
|
| 259 |
" /* Definition of color scheme common for light and dark mode */\n",
|
| 260 |
" --sklearn-color-text: black;\n",
|
| 261 |
" --sklearn-color-line: gray;\n",
|
|
@@ -285,15 +286,15 @@
|
|
| 285 |
" }\n",
|
| 286 |
"}\n",
|
| 287 |
"\n",
|
| 288 |
-
"#sk-container-id-
|
| 289 |
" color: var(--sklearn-color-text);\n",
|
| 290 |
"}\n",
|
| 291 |
"\n",
|
| 292 |
-
"#sk-container-id-
|
| 293 |
" padding: 0;\n",
|
| 294 |
"}\n",
|
| 295 |
"\n",
|
| 296 |
-
"#sk-container-id-
|
| 297 |
" border: 0;\n",
|
| 298 |
" clip: rect(1px 1px 1px 1px);\n",
|
| 299 |
" clip: rect(1px, 1px, 1px, 1px);\n",
|
|
@@ -305,7 +306,7 @@
|
|
| 305 |
" width: 1px;\n",
|
| 306 |
"}\n",
|
| 307 |
"\n",
|
| 308 |
-
"#sk-container-id-
|
| 309 |
" border: 1px dashed var(--sklearn-color-line);\n",
|
| 310 |
" margin: 0 0.4em 0.5em 0.4em;\n",
|
| 311 |
" box-sizing: border-box;\n",
|
|
@@ -313,7 +314,7 @@
|
|
| 313 |
" background-color: var(--sklearn-color-background);\n",
|
| 314 |
"}\n",
|
| 315 |
"\n",
|
| 316 |
-
"#sk-container-id-
|
| 317 |
" /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
|
| 318 |
" but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
|
| 319 |
" so we also need the `!important` here to be able to override the\n",
|
|
@@ -323,7 +324,7 @@
|
|
| 323 |
" position: relative;\n",
|
| 324 |
"}\n",
|
| 325 |
"\n",
|
| 326 |
-
"#sk-container-id-
|
| 327 |
" display: none;\n",
|
| 328 |
"}\n",
|
| 329 |
"\n",
|
|
@@ -339,14 +340,14 @@
|
|
| 339 |
"\n",
|
| 340 |
"/* Parallel-specific style estimator block */\n",
|
| 341 |
"\n",
|
| 342 |
-
"#sk-container-id-
|
| 343 |
" content: \"\";\n",
|
| 344 |
" width: 100%;\n",
|
| 345 |
" border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
|
| 346 |
" flex-grow: 1;\n",
|
| 347 |
"}\n",
|
| 348 |
"\n",
|
| 349 |
-
"#sk-container-id-
|
| 350 |
" display: flex;\n",
|
| 351 |
" align-items: stretch;\n",
|
| 352 |
" justify-content: center;\n",
|
|
@@ -354,28 +355,28 @@
|
|
| 354 |
" position: relative;\n",
|
| 355 |
"}\n",
|
| 356 |
"\n",
|
| 357 |
-
"#sk-container-id-
|
| 358 |
" display: flex;\n",
|
| 359 |
" flex-direction: column;\n",
|
| 360 |
"}\n",
|
| 361 |
"\n",
|
| 362 |
-
"#sk-container-id-
|
| 363 |
" align-self: flex-end;\n",
|
| 364 |
" width: 50%;\n",
|
| 365 |
"}\n",
|
| 366 |
"\n",
|
| 367 |
-
"#sk-container-id-
|
| 368 |
" align-self: flex-start;\n",
|
| 369 |
" width: 50%;\n",
|
| 370 |
"}\n",
|
| 371 |
"\n",
|
| 372 |
-
"#sk-container-id-
|
| 373 |
" width: 0;\n",
|
| 374 |
"}\n",
|
| 375 |
"\n",
|
| 376 |
"/* Serial-specific style estimator block */\n",
|
| 377 |
"\n",
|
| 378 |
-
"#sk-container-id-
|
| 379 |
" display: flex;\n",
|
| 380 |
" flex-direction: column;\n",
|
| 381 |
" align-items: center;\n",
|
|
@@ -393,14 +394,14 @@
|
|
| 393 |
"\n",
|
| 394 |
"/* Pipeline and ColumnTransformer style (default) */\n",
|
| 395 |
"\n",
|
| 396 |
-
"#sk-container-id-
|
| 397 |
" /* Default theme specific background. It is overwritten whether we have a\n",
|
| 398 |
" specific estimator or a Pipeline/ColumnTransformer */\n",
|
| 399 |
" background-color: var(--sklearn-color-background);\n",
|
| 400 |
"}\n",
|
| 401 |
"\n",
|
| 402 |
"/* Toggleable label */\n",
|
| 403 |
-
"#sk-container-id-
|
| 404 |
" cursor: pointer;\n",
|
| 405 |
" display: block;\n",
|
| 406 |
" width: 100%;\n",
|
|
@@ -410,7 +411,7 @@
|
|
| 410 |
" text-align: center;\n",
|
| 411 |
"}\n",
|
| 412 |
"\n",
|
| 413 |
-
"#sk-container-id-
|
| 414 |
" /* Arrow on the left of the label */\n",
|
| 415 |
" content: \"▸\";\n",
|
| 416 |
" float: left;\n",
|
|
@@ -418,13 +419,13 @@
|
|
| 418 |
" color: var(--sklearn-color-icon);\n",
|
| 419 |
"}\n",
|
| 420 |
"\n",
|
| 421 |
-
"#sk-container-id-
|
| 422 |
" color: var(--sklearn-color-text);\n",
|
| 423 |
"}\n",
|
| 424 |
"\n",
|
| 425 |
"/* Toggleable content - dropdown */\n",
|
| 426 |
"\n",
|
| 427 |
-
"#sk-container-id-
|
| 428 |
" max-height: 0;\n",
|
| 429 |
" max-width: 0;\n",
|
| 430 |
" overflow: hidden;\n",
|
|
@@ -433,12 +434,12 @@
|
|
| 433 |
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 434 |
"}\n",
|
| 435 |
"\n",
|
| 436 |
-
"#sk-container-id-
|
| 437 |
" /* fitted */\n",
|
| 438 |
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 439 |
"}\n",
|
| 440 |
"\n",
|
| 441 |
-
"#sk-container-id-
|
| 442 |
" margin: 0.2em;\n",
|
| 443 |
" border-radius: 0.25em;\n",
|
| 444 |
" color: var(--sklearn-color-text);\n",
|
|
@@ -446,79 +447,79 @@
|
|
| 446 |
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 447 |
"}\n",
|
| 448 |
"\n",
|
| 449 |
-
"#sk-container-id-
|
| 450 |
" /* unfitted */\n",
|
| 451 |
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 452 |
"}\n",
|
| 453 |
"\n",
|
| 454 |
-
"#sk-container-id-
|
| 455 |
" /* Expand drop-down */\n",
|
| 456 |
" max-height: 200px;\n",
|
| 457 |
" max-width: 100%;\n",
|
| 458 |
" overflow: auto;\n",
|
| 459 |
"}\n",
|
| 460 |
"\n",
|
| 461 |
-
"#sk-container-id-
|
| 462 |
" content: \"▾\";\n",
|
| 463 |
"}\n",
|
| 464 |
"\n",
|
| 465 |
"/* Pipeline/ColumnTransformer-specific style */\n",
|
| 466 |
"\n",
|
| 467 |
-
"#sk-container-id-
|
| 468 |
" color: var(--sklearn-color-text);\n",
|
| 469 |
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 470 |
"}\n",
|
| 471 |
"\n",
|
| 472 |
-
"#sk-container-id-
|
| 473 |
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 474 |
"}\n",
|
| 475 |
"\n",
|
| 476 |
"/* Estimator-specific style */\n",
|
| 477 |
"\n",
|
| 478 |
"/* Colorize estimator box */\n",
|
| 479 |
-
"#sk-container-id-
|
| 480 |
" /* unfitted */\n",
|
| 481 |
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 482 |
"}\n",
|
| 483 |
"\n",
|
| 484 |
-
"#sk-container-id-
|
| 485 |
" /* fitted */\n",
|
| 486 |
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 487 |
"}\n",
|
| 488 |
"\n",
|
| 489 |
-
"#sk-container-id-
|
| 490 |
-
"#sk-container-id-
|
| 491 |
" /* The background is the default theme color */\n",
|
| 492 |
" color: var(--sklearn-color-text-on-default-background);\n",
|
| 493 |
"}\n",
|
| 494 |
"\n",
|
| 495 |
"/* On hover, darken the color of the background */\n",
|
| 496 |
-
"#sk-container-id-
|
| 497 |
" color: var(--sklearn-color-text);\n",
|
| 498 |
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 499 |
"}\n",
|
| 500 |
"\n",
|
| 501 |
"/* Label box, darken color on hover, fitted */\n",
|
| 502 |
-
"#sk-container-id-
|
| 503 |
" color: var(--sklearn-color-text);\n",
|
| 504 |
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 505 |
"}\n",
|
| 506 |
"\n",
|
| 507 |
"/* Estimator label */\n",
|
| 508 |
"\n",
|
| 509 |
-
"#sk-container-id-
|
| 510 |
" font-family: monospace;\n",
|
| 511 |
" font-weight: bold;\n",
|
| 512 |
" display: inline-block;\n",
|
| 513 |
" line-height: 1.2em;\n",
|
| 514 |
"}\n",
|
| 515 |
"\n",
|
| 516 |
-
"#sk-container-id-
|
| 517 |
" text-align: center;\n",
|
| 518 |
"}\n",
|
| 519 |
"\n",
|
| 520 |
"/* Estimator-specific */\n",
|
| 521 |
-
"#sk-container-id-
|
| 522 |
" font-family: monospace;\n",
|
| 523 |
" border: 1px dotted var(--sklearn-color-border-box);\n",
|
| 524 |
" border-radius: 0.25em;\n",
|
|
@@ -528,18 +529,18 @@
|
|
| 528 |
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 529 |
"}\n",
|
| 530 |
"\n",
|
| 531 |
-
"#sk-container-id-
|
| 532 |
" /* fitted */\n",
|
| 533 |
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 534 |
"}\n",
|
| 535 |
"\n",
|
| 536 |
"/* on hover */\n",
|
| 537 |
-
"#sk-container-id-
|
| 538 |
" /* unfitted */\n",
|
| 539 |
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 540 |
"}\n",
|
| 541 |
"\n",
|
| 542 |
-
"#sk-container-id-
|
| 543 |
" /* fitted */\n",
|
| 544 |
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 545 |
"}\n",
|
|
@@ -626,7 +627,7 @@
|
|
| 626 |
"\n",
|
| 627 |
"/* \"?\"-specific style due to the `<a>` HTML tag */\n",
|
| 628 |
"\n",
|
| 629 |
-
"#sk-container-id-
|
| 630 |
" float: right;\n",
|
| 631 |
" font-size: 1rem;\n",
|
| 632 |
" line-height: 1em;\n",
|
|
@@ -641,31 +642,31 @@
|
|
| 641 |
" border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
|
| 642 |
"}\n",
|
| 643 |
"\n",
|
| 644 |
-
"#sk-container-id-
|
| 645 |
" /* fitted */\n",
|
| 646 |
" border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
|
| 647 |
" color: var(--sklearn-color-fitted-level-1);\n",
|
| 648 |
"}\n",
|
| 649 |
"\n",
|
| 650 |
"/* On hover */\n",
|
| 651 |
-
"#sk-container-id-
|
| 652 |
" /* unfitted */\n",
|
| 653 |
" background-color: var(--sklearn-color-unfitted-level-3);\n",
|
| 654 |
" color: var(--sklearn-color-background);\n",
|
| 655 |
" text-decoration: none;\n",
|
| 656 |
"}\n",
|
| 657 |
"\n",
|
| 658 |
-
"#sk-container-id-
|
| 659 |
" /* fitted */\n",
|
| 660 |
" background-color: var(--sklearn-color-fitted-level-3);\n",
|
| 661 |
"}\n",
|
| 662 |
-
"</style><div id=\"sk-container-id-
|
| 663 |
],
|
| 664 |
"text/plain": [
|
| 665 |
"LogisticRegression()"
|
| 666 |
]
|
| 667 |
},
|
| 668 |
-
"execution_count":
|
| 669 |
"metadata": {},
|
| 670 |
"output_type": "execute_result"
|
| 671 |
}
|
|
@@ -678,7 +679,7 @@
|
|
| 678 |
},
|
| 679 |
{
|
| 680 |
"cell_type": "code",
|
| 681 |
-
"execution_count":
|
| 682 |
"metadata": {},
|
| 683 |
"outputs": [],
|
| 684 |
"source": [
|
|
@@ -697,7 +698,7 @@
|
|
| 697 |
},
|
| 698 |
{
|
| 699 |
"cell_type": "code",
|
| 700 |
-
"execution_count":
|
| 701 |
"metadata": {},
|
| 702 |
"outputs": [
|
| 703 |
{
|
|
@@ -717,13 +718,35 @@
|
|
| 717 |
"weighted avg 0.76 0.76 0.76 50\n",
|
| 718 |
"\n"
|
| 719 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 720 |
}
|
| 721 |
],
|
| 722 |
"source": [
|
| 723 |
-
"#
|
| 724 |
"accuracy = accuracy_score(y_test, y_pred)\n",
|
|
|
|
|
|
|
|
|
|
| 725 |
"print(f\"Accuracy: {accuracy:.4f}\")\n",
|
| 726 |
-
"print(\"Classification Report:\\n\", classification_report(y_test, y_pred))"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 727 |
]
|
| 728 |
},
|
| 729 |
{
|
|
@@ -735,7 +758,7 @@
|
|
| 735 |
},
|
| 736 |
{
|
| 737 |
"cell_type": "code",
|
| 738 |
-
"execution_count":
|
| 739 |
"metadata": {},
|
| 740 |
"outputs": [
|
| 741 |
{
|
|
@@ -750,18 +773,18 @@
|
|
| 750 |
}
|
| 751 |
],
|
| 752 |
"source": [
|
| 753 |
-
"# Confusion Matrix\n",
|
| 754 |
"cm = confusion_matrix(y_test, y_pred)\n",
|
| 755 |
"sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=sentiment_mapping.keys(), yticklabels=sentiment_mapping.keys())\n",
|
| 756 |
"plt.xlabel(\"Predicted\")\n",
|
| 757 |
"plt.ylabel(\"Actual\")\n",
|
| 758 |
"plt.title(\"Confusion Matrix\")\n",
|
|
|
|
| 759 |
"plt.show()"
|
| 760 |
]
|
| 761 |
},
|
| 762 |
{
|
| 763 |
"cell_type": "code",
|
| 764 |
-
"execution_count":
|
| 765 |
"metadata": {},
|
| 766 |
"outputs": [
|
| 767 |
{
|
|
@@ -773,6 +796,7 @@
|
|
| 773 |
}
|
| 774 |
],
|
| 775 |
"source": [
|
|
|
|
| 776 |
"joblib.dump(model, \"sentimentAnalysis_model.pkl\")\n",
|
| 777 |
"joblib.dump(vectorizer, \"vectorizer.pkl\")\n",
|
| 778 |
"print(\"Model saved successfully\")"
|
|
|
|
| 13 |
},
|
| 14 |
{
|
| 15 |
"cell_type": "code",
|
| 16 |
+
"execution_count": 48,
|
| 17 |
"metadata": {},
|
| 18 |
"outputs": [
|
| 19 |
{
|
|
|
|
| 34 |
"from sklearn.model_selection import train_test_split\n",
|
| 35 |
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
| 36 |
"from sklearn.linear_model import LogisticRegression\n",
|
| 37 |
+
"from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, f1_score\n",
|
| 38 |
"import nltk\n",
|
| 39 |
"from nltk.corpus import stopwords\n",
|
| 40 |
"import re\n",
|
|
|
|
| 55 |
},
|
| 56 |
{
|
| 57 |
"cell_type": "code",
|
| 58 |
+
"execution_count": 49,
|
| 59 |
"metadata": {},
|
| 60 |
"outputs": [],
|
| 61 |
"source": [
|
|
|
|
| 65 |
},
|
| 66 |
{
|
| 67 |
"cell_type": "code",
|
| 68 |
+
"execution_count": 50,
|
| 69 |
"metadata": {},
|
| 70 |
"outputs": [],
|
| 71 |
"source": [
|
|
|
|
| 75 |
},
|
| 76 |
{
|
| 77 |
"cell_type": "code",
|
| 78 |
+
"execution_count": 51,
|
| 79 |
"metadata": {},
|
| 80 |
"outputs": [
|
| 81 |
{
|
|
|
|
| 100 |
},
|
| 101 |
{
|
| 102 |
"cell_type": "code",
|
| 103 |
+
"execution_count": 52,
|
| 104 |
"metadata": {},
|
| 105 |
"outputs": [
|
| 106 |
{
|
|
|
|
| 119 |
},
|
| 120 |
{
|
| 121 |
"cell_type": "code",
|
| 122 |
+
"execution_count": 53,
|
| 123 |
"metadata": {},
|
| 124 |
"outputs": [
|
| 125 |
{
|
|
|
|
| 132 |
"Name: count, dtype: int64"
|
| 133 |
]
|
| 134 |
},
|
| 135 |
+
"execution_count": 53,
|
| 136 |
"metadata": {},
|
| 137 |
"output_type": "execute_result"
|
| 138 |
}
|
|
|
|
| 143 |
},
|
| 144 |
{
|
| 145 |
"cell_type": "code",
|
| 146 |
+
"execution_count": 54,
|
| 147 |
"metadata": {},
|
| 148 |
"outputs": [
|
| 149 |
{
|
|
|
|
| 158 |
}
|
| 159 |
],
|
| 160 |
"source": [
|
|
|
|
| 161 |
"sns.countplot(x=df[\"sentiment\"])\n",
|
| 162 |
"plt.title(\"Sentiment Distribution\")\n",
|
| 163 |
+
"plt.savefig(\"sentiment_distribution.png\")\n",
|
| 164 |
+
"plt.show()\n",
|
| 165 |
+
"plt.close() "
|
| 166 |
]
|
| 167 |
},
|
| 168 |
{
|
|
|
|
| 175 |
},
|
| 176 |
{
|
| 177 |
"cell_type": "code",
|
| 178 |
+
"execution_count": 55,
|
| 179 |
"metadata": {},
|
| 180 |
"outputs": [],
|
| 181 |
"source": [
|
|
|
|
| 188 |
},
|
| 189 |
{
|
| 190 |
"cell_type": "code",
|
| 191 |
+
"execution_count": 56,
|
| 192 |
"metadata": {},
|
| 193 |
"outputs": [],
|
| 194 |
"source": [
|
|
|
|
| 204 |
},
|
| 205 |
{
|
| 206 |
"cell_type": "code",
|
| 207 |
+
"execution_count": 57,
|
| 208 |
"metadata": {},
|
| 209 |
"outputs": [],
|
| 210 |
"source": [
|
|
|
|
| 223 |
},
|
| 224 |
{
|
| 225 |
"cell_type": "code",
|
| 226 |
+
"execution_count": 58,
|
| 227 |
"metadata": {},
|
| 228 |
"outputs": [],
|
| 229 |
"source": [
|
|
|
|
| 232 |
},
|
| 233 |
{
|
| 234 |
"cell_type": "code",
|
| 235 |
+
"execution_count": 59,
|
| 236 |
"metadata": {},
|
| 237 |
"outputs": [],
|
| 238 |
"source": [
|
|
|
|
| 250 |
},
|
| 251 |
{
|
| 252 |
"cell_type": "code",
|
| 253 |
+
"execution_count": 60,
|
| 254 |
"metadata": {},
|
| 255 |
"outputs": [
|
| 256 |
{
|
| 257 |
"data": {
|
| 258 |
"text/html": [
|
| 259 |
+
"<style>#sk-container-id-4 {\n",
|
| 260 |
" /* Definition of color scheme common for light and dark mode */\n",
|
| 261 |
" --sklearn-color-text: black;\n",
|
| 262 |
" --sklearn-color-line: gray;\n",
|
|
|
|
| 286 |
" }\n",
|
| 287 |
"}\n",
|
| 288 |
"\n",
|
| 289 |
+
"#sk-container-id-4 {\n",
|
| 290 |
" color: var(--sklearn-color-text);\n",
|
| 291 |
"}\n",
|
| 292 |
"\n",
|
| 293 |
+
"#sk-container-id-4 pre {\n",
|
| 294 |
" padding: 0;\n",
|
| 295 |
"}\n",
|
| 296 |
"\n",
|
| 297 |
+
"#sk-container-id-4 input.sk-hidden--visually {\n",
|
| 298 |
" border: 0;\n",
|
| 299 |
" clip: rect(1px 1px 1px 1px);\n",
|
| 300 |
" clip: rect(1px, 1px, 1px, 1px);\n",
|
|
|
|
| 306 |
" width: 1px;\n",
|
| 307 |
"}\n",
|
| 308 |
"\n",
|
| 309 |
+
"#sk-container-id-4 div.sk-dashed-wrapped {\n",
|
| 310 |
" border: 1px dashed var(--sklearn-color-line);\n",
|
| 311 |
" margin: 0 0.4em 0.5em 0.4em;\n",
|
| 312 |
" box-sizing: border-box;\n",
|
|
|
|
| 314 |
" background-color: var(--sklearn-color-background);\n",
|
| 315 |
"}\n",
|
| 316 |
"\n",
|
| 317 |
+
"#sk-container-id-4 div.sk-container {\n",
|
| 318 |
" /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
|
| 319 |
" but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
|
| 320 |
" so we also need the `!important` here to be able to override the\n",
|
|
|
|
| 324 |
" position: relative;\n",
|
| 325 |
"}\n",
|
| 326 |
"\n",
|
| 327 |
+
"#sk-container-id-4 div.sk-text-repr-fallback {\n",
|
| 328 |
" display: none;\n",
|
| 329 |
"}\n",
|
| 330 |
"\n",
|
|
|
|
| 340 |
"\n",
|
| 341 |
"/* Parallel-specific style estimator block */\n",
|
| 342 |
"\n",
|
| 343 |
+
"#sk-container-id-4 div.sk-parallel-item::after {\n",
|
| 344 |
" content: \"\";\n",
|
| 345 |
" width: 100%;\n",
|
| 346 |
" border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
|
| 347 |
" flex-grow: 1;\n",
|
| 348 |
"}\n",
|
| 349 |
"\n",
|
| 350 |
+
"#sk-container-id-4 div.sk-parallel {\n",
|
| 351 |
" display: flex;\n",
|
| 352 |
" align-items: stretch;\n",
|
| 353 |
" justify-content: center;\n",
|
|
|
|
| 355 |
" position: relative;\n",
|
| 356 |
"}\n",
|
| 357 |
"\n",
|
| 358 |
+
"#sk-container-id-4 div.sk-parallel-item {\n",
|
| 359 |
" display: flex;\n",
|
| 360 |
" flex-direction: column;\n",
|
| 361 |
"}\n",
|
| 362 |
"\n",
|
| 363 |
+
"#sk-container-id-4 div.sk-parallel-item:first-child::after {\n",
|
| 364 |
" align-self: flex-end;\n",
|
| 365 |
" width: 50%;\n",
|
| 366 |
"}\n",
|
| 367 |
"\n",
|
| 368 |
+
"#sk-container-id-4 div.sk-parallel-item:last-child::after {\n",
|
| 369 |
" align-self: flex-start;\n",
|
| 370 |
" width: 50%;\n",
|
| 371 |
"}\n",
|
| 372 |
"\n",
|
| 373 |
+
"#sk-container-id-4 div.sk-parallel-item:only-child::after {\n",
|
| 374 |
" width: 0;\n",
|
| 375 |
"}\n",
|
| 376 |
"\n",
|
| 377 |
"/* Serial-specific style estimator block */\n",
|
| 378 |
"\n",
|
| 379 |
+
"#sk-container-id-4 div.sk-serial {\n",
|
| 380 |
" display: flex;\n",
|
| 381 |
" flex-direction: column;\n",
|
| 382 |
" align-items: center;\n",
|
|
|
|
| 394 |
"\n",
|
| 395 |
"/* Pipeline and ColumnTransformer style (default) */\n",
|
| 396 |
"\n",
|
| 397 |
+
"#sk-container-id-4 div.sk-toggleable {\n",
|
| 398 |
" /* Default theme specific background. It is overwritten whether we have a\n",
|
| 399 |
" specific estimator or a Pipeline/ColumnTransformer */\n",
|
| 400 |
" background-color: var(--sklearn-color-background);\n",
|
| 401 |
"}\n",
|
| 402 |
"\n",
|
| 403 |
"/* Toggleable label */\n",
|
| 404 |
+
"#sk-container-id-4 label.sk-toggleable__label {\n",
|
| 405 |
" cursor: pointer;\n",
|
| 406 |
" display: block;\n",
|
| 407 |
" width: 100%;\n",
|
|
|
|
| 411 |
" text-align: center;\n",
|
| 412 |
"}\n",
|
| 413 |
"\n",
|
| 414 |
+
"#sk-container-id-4 label.sk-toggleable__label-arrow:before {\n",
|
| 415 |
" /* Arrow on the left of the label */\n",
|
| 416 |
" content: \"▸\";\n",
|
| 417 |
" float: left;\n",
|
|
|
|
| 419 |
" color: var(--sklearn-color-icon);\n",
|
| 420 |
"}\n",
|
| 421 |
"\n",
|
| 422 |
+
"#sk-container-id-4 label.sk-toggleable__label-arrow:hover:before {\n",
|
| 423 |
" color: var(--sklearn-color-text);\n",
|
| 424 |
"}\n",
|
| 425 |
"\n",
|
| 426 |
"/* Toggleable content - dropdown */\n",
|
| 427 |
"\n",
|
| 428 |
+
"#sk-container-id-4 div.sk-toggleable__content {\n",
|
| 429 |
" max-height: 0;\n",
|
| 430 |
" max-width: 0;\n",
|
| 431 |
" overflow: hidden;\n",
|
|
|
|
| 434 |
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 435 |
"}\n",
|
| 436 |
"\n",
|
| 437 |
+
"#sk-container-id-4 div.sk-toggleable__content.fitted {\n",
|
| 438 |
" /* fitted */\n",
|
| 439 |
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 440 |
"}\n",
|
| 441 |
"\n",
|
| 442 |
+
"#sk-container-id-4 div.sk-toggleable__content pre {\n",
|
| 443 |
" margin: 0.2em;\n",
|
| 444 |
" border-radius: 0.25em;\n",
|
| 445 |
" color: var(--sklearn-color-text);\n",
|
|
|
|
| 447 |
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 448 |
"}\n",
|
| 449 |
"\n",
|
| 450 |
+
"#sk-container-id-4 div.sk-toggleable__content.fitted pre {\n",
|
| 451 |
" /* unfitted */\n",
|
| 452 |
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 453 |
"}\n",
|
| 454 |
"\n",
|
| 455 |
+
"#sk-container-id-4 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
|
| 456 |
" /* Expand drop-down */\n",
|
| 457 |
" max-height: 200px;\n",
|
| 458 |
" max-width: 100%;\n",
|
| 459 |
" overflow: auto;\n",
|
| 460 |
"}\n",
|
| 461 |
"\n",
|
| 462 |
+
"#sk-container-id-4 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
|
| 463 |
" content: \"▾\";\n",
|
| 464 |
"}\n",
|
| 465 |
"\n",
|
| 466 |
"/* Pipeline/ColumnTransformer-specific style */\n",
|
| 467 |
"\n",
|
| 468 |
+
"#sk-container-id-4 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
|
| 469 |
" color: var(--sklearn-color-text);\n",
|
| 470 |
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 471 |
"}\n",
|
| 472 |
"\n",
|
| 473 |
+
"#sk-container-id-4 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
|
| 474 |
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 475 |
"}\n",
|
| 476 |
"\n",
|
| 477 |
"/* Estimator-specific style */\n",
|
| 478 |
"\n",
|
| 479 |
"/* Colorize estimator box */\n",
|
| 480 |
+
"#sk-container-id-4 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
|
| 481 |
" /* unfitted */\n",
|
| 482 |
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 483 |
"}\n",
|
| 484 |
"\n",
|
| 485 |
+
"#sk-container-id-4 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
|
| 486 |
" /* fitted */\n",
|
| 487 |
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 488 |
"}\n",
|
| 489 |
"\n",
|
| 490 |
+
"#sk-container-id-4 div.sk-label label.sk-toggleable__label,\n",
|
| 491 |
+
"#sk-container-id-4 div.sk-label label {\n",
|
| 492 |
" /* The background is the default theme color */\n",
|
| 493 |
" color: var(--sklearn-color-text-on-default-background);\n",
|
| 494 |
"}\n",
|
| 495 |
"\n",
|
| 496 |
"/* On hover, darken the color of the background */\n",
|
| 497 |
+
"#sk-container-id-4 div.sk-label:hover label.sk-toggleable__label {\n",
|
| 498 |
" color: var(--sklearn-color-text);\n",
|
| 499 |
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 500 |
"}\n",
|
| 501 |
"\n",
|
| 502 |
"/* Label box, darken color on hover, fitted */\n",
|
| 503 |
+
"#sk-container-id-4 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
|
| 504 |
" color: var(--sklearn-color-text);\n",
|
| 505 |
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 506 |
"}\n",
|
| 507 |
"\n",
|
| 508 |
"/* Estimator label */\n",
|
| 509 |
"\n",
|
| 510 |
+
"#sk-container-id-4 div.sk-label label {\n",
|
| 511 |
" font-family: monospace;\n",
|
| 512 |
" font-weight: bold;\n",
|
| 513 |
" display: inline-block;\n",
|
| 514 |
" line-height: 1.2em;\n",
|
| 515 |
"}\n",
|
| 516 |
"\n",
|
| 517 |
+
"#sk-container-id-4 div.sk-label-container {\n",
|
| 518 |
" text-align: center;\n",
|
| 519 |
"}\n",
|
| 520 |
"\n",
|
| 521 |
"/* Estimator-specific */\n",
|
| 522 |
+
"#sk-container-id-4 div.sk-estimator {\n",
|
| 523 |
" font-family: monospace;\n",
|
| 524 |
" border: 1px dotted var(--sklearn-color-border-box);\n",
|
| 525 |
" border-radius: 0.25em;\n",
|
|
|
|
| 529 |
" background-color: var(--sklearn-color-unfitted-level-0);\n",
|
| 530 |
"}\n",
|
| 531 |
"\n",
|
| 532 |
+
"#sk-container-id-4 div.sk-estimator.fitted {\n",
|
| 533 |
" /* fitted */\n",
|
| 534 |
" background-color: var(--sklearn-color-fitted-level-0);\n",
|
| 535 |
"}\n",
|
| 536 |
"\n",
|
| 537 |
"/* on hover */\n",
|
| 538 |
+
"#sk-container-id-4 div.sk-estimator:hover {\n",
|
| 539 |
" /* unfitted */\n",
|
| 540 |
" background-color: var(--sklearn-color-unfitted-level-2);\n",
|
| 541 |
"}\n",
|
| 542 |
"\n",
|
| 543 |
+
"#sk-container-id-4 div.sk-estimator.fitted:hover {\n",
|
| 544 |
" /* fitted */\n",
|
| 545 |
" background-color: var(--sklearn-color-fitted-level-2);\n",
|
| 546 |
"}\n",
|
|
|
|
| 627 |
"\n",
|
| 628 |
"/* \"?\"-specific style due to the `<a>` HTML tag */\n",
|
| 629 |
"\n",
|
| 630 |
+
"#sk-container-id-4 a.estimator_doc_link {\n",
|
| 631 |
" float: right;\n",
|
| 632 |
" font-size: 1rem;\n",
|
| 633 |
" line-height: 1em;\n",
|
|
|
|
| 642 |
" border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
|
| 643 |
"}\n",
|
| 644 |
"\n",
|
| 645 |
+
"#sk-container-id-4 a.estimator_doc_link.fitted {\n",
|
| 646 |
" /* fitted */\n",
|
| 647 |
" border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
|
| 648 |
" color: var(--sklearn-color-fitted-level-1);\n",
|
| 649 |
"}\n",
|
| 650 |
"\n",
|
| 651 |
"/* On hover */\n",
|
| 652 |
+
"#sk-container-id-4 a.estimator_doc_link:hover {\n",
|
| 653 |
" /* unfitted */\n",
|
| 654 |
" background-color: var(--sklearn-color-unfitted-level-3);\n",
|
| 655 |
" color: var(--sklearn-color-background);\n",
|
| 656 |
" text-decoration: none;\n",
|
| 657 |
"}\n",
|
| 658 |
"\n",
|
| 659 |
+
"#sk-container-id-4 a.estimator_doc_link.fitted:hover {\n",
|
| 660 |
" /* fitted */\n",
|
| 661 |
" background-color: var(--sklearn-color-fitted-level-3);\n",
|
| 662 |
"}\n",
|
| 663 |
+
"</style><div id=\"sk-container-id-4\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LogisticRegression()</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\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-4\" type=\"checkbox\" checked><label for=\"sk-estimator-id-4\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\"> LogisticRegression<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.linear_model.LogisticRegression.html\">?<span>Documentation for LogisticRegression</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>LogisticRegression()</pre></div> </div></div></div></div>"
|
| 664 |
],
|
| 665 |
"text/plain": [
|
| 666 |
"LogisticRegression()"
|
| 667 |
]
|
| 668 |
},
|
| 669 |
+
"execution_count": 60,
|
| 670 |
"metadata": {},
|
| 671 |
"output_type": "execute_result"
|
| 672 |
}
|
|
|
|
| 679 |
},
|
| 680 |
{
|
| 681 |
"cell_type": "code",
|
| 682 |
+
"execution_count": 61,
|
| 683 |
"metadata": {},
|
| 684 |
"outputs": [],
|
| 685 |
"source": [
|
|
|
|
| 698 |
},
|
| 699 |
{
|
| 700 |
"cell_type": "code",
|
| 701 |
+
"execution_count": 62,
|
| 702 |
"metadata": {},
|
| 703 |
"outputs": [
|
| 704 |
{
|
|
|
|
| 718 |
"weighted avg 0.76 0.76 0.76 50\n",
|
| 719 |
"\n"
|
| 720 |
]
|
| 721 |
+
},
|
| 722 |
+
{
|
| 723 |
+
"data": {
|
| 724 |
+
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHiCAYAAAB4GX3vAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABkKElEQVR4nO3de1xUZf4H8M+AMCAMqFxEjZsoYutoXkpzFShGFDUVC01LZd1drYzWLe2XbKX+bFPXDC1bTfMnu9gaWd4Lky3wEiaFqaz3AkTygqCCN5DL9/eHP87PaQZlYHDA83m/XryS5zzzPM85z5nh07mNRkQERERERKQadrYeABERERHdWwyARERERCrDAEhERESkMgyARERERCrDAEhERESkMgyARERERCrDAEhERESkMgyARERERCrDAEhERESkMgyARERERCrDAEhERESkMgyARERERCrDAEhERESkMgyARERERCrDAEhERESkMlYNgLm5udBoNNBoNPjpp5+s2TRZ6NKlS4iNjUXr1q3h7u6OsWPHorCwsF5tBQQEKPP6659BgwYZ1RURrFixAt27d4ezszO8vb0xYsQIXL16tV7js+Z6EBER0S0trNlYSkoKPDw8AADbt2/Hiy++aM3myQLR0dHIysrCrFmz4ODggIULFyIqKgqZmZmwt7e3qK0lS5aYBLi8vDy88cYbJgEwPj4eCxYsQExMDOLi4nD16lXs2bMHN27cgKurq8Xjs+Z6EBER0f8RKxo+fLg89dRT8uSTT8rQoUOt2TRZYMeOHQJAEhMTlbJt27YJAElOTrZKH3PnzhWNRiP5+flK2dGjR8Xe3l7i4+OtMr57sR5ERERqZLVTwOXl5UhLS0NERAQiIiKQlpaGsrIys3V37dqFyMhIuLu7w93dHeHh4dixY4fF9RITE6HRaJCXl2f0uoCAAMTGxpq0p9FoMGfOHGzatAl6vR5OTk4ICgrCl19+CQC4ePEiZsyYge7du0On08HNzQ0GgwEZGRkWr8eNGzfg5uaGP/7xjyavW716NTQaDQ4ePGi23YbaunUrtFotxo4dq5RFRUXBw8MDW7ZssUofa9euxYABA+Dr66uUrVu3Dg4ODpg1axYAmBw1tHR892I9iIiI1MhqAXDnzp24du2aEgBv3LiBnTt3mtTbunUrHn/8ceTn5+PVV1/FO++8gw4dOmDlypX1qmepzMxM/O53v8PQoUOxZMkSGAwGJUDm5ORg9erVCAsLQ0JCAmbPno2CggJERETg2LFjFo3P2dkZo0aNwsaNG1FZWWn02vXr1+PBBx9Ejx49TMZXc21dQ2RnZyM4OBhOTk5KmZ2dHfR6PbKzsxvUNgDs27cPJ0+exPjx403K9Xo9tmzZAm9vb+h0Ovj6+mLdunX1Gl9jrwcREZFqWetQ4vTp08XX11f5/YEHHpA//elPRnUqKyvFz89PgoOD5cqVK0bLzpw5Y3G9NWvWCADJzc01quPv7y+TJk0yGSMAsbOzk/3795uMS0SktLRUSktLjZadOnVKNBqNzJw50+LxpaSkCADZvn27UlZcXCwtWrSQefPmmYyvZowNnZaQkBAxGAwiIhIRESHdu3eX8vJyGTNmjHh7ezeobRGRadOmiYODgxQVFRmVd+vWTQICAkSn08nf/vY3SU5OltDQUNFoNJKVlWXx+Bp7PYiIiNTKakcAU1JS8Pjjjyu/P/7440hJSTGqk5WVhfz8fMTFxRndEAAA7dq1s7hefQwaNAg9e/Y0Kqu5mUCn00Gn0wEAKisrUVxcjJYtW8LT0xO5ubkWj89gMMDb2xvJyclKWc0Rwaefftrs+Lp06YIuXbo0aB3Ly8vh6OgI4NbNGgUFBaioqIBWq631tHxdVVRUIDk5GZGRkcoNPzWuX7+OvLw8LFiwADNnzsSYMWPwxRdfwNXVFYsWLbJ4fI25HkRERGpmlQCYm5uL48ePo3v37igoKEBBQQG6d++OEydOICcnx6geAHTt2vWu7dWlXn2EhITUuqy6uhpLly5F586d4eTkBE9PT3h5eeHChQtGgaOu42vRogViYmKwadMmVFRUALh1+vfhhx9Gp06dzL7m2LFjJqebLaXVanHz5k0AwIEDB5CTkwMXFxeUl5cbnU6tj5SUFBQVFZmc/gWghLXRo0crZa6urujfvz8OHTpk8fgacz2IiIjUzCoBsOYmildeeQW+vr7w9fXFjBkzAMDkKOC9UFVVVeuyVq1a1bps4cKFmD59Ovr27YuPP/4YqampSE1NhaenJ0SkXmMZP348Ll26hNTUVFy8eBFff/01xo0bV6+26srHxwfnz58HcCuAubu7AwAKCwvh4+PToLaTkpLg4uKCkSNHmizz8vIy+m+NNm3aGD27r67ja8z1ICIiUjOrBMCUlBR07twZW7duNfrp3LmzUQAMDAwEABw5cuSO7dW1Xs0Rp+vXrytl1dXV9X5QcHJyMkJDQ7F27VqMHTsWBoMBYWFhuHz5cr3GBwD9+/dHQEAAkpOTsXHjRlRXV2PMmDH1Gl9d6fV6nDhxwuioZXV1NbKzs6HX6+vdbklJCbZt24YRI0bAxcXFZPmDDz4IADh37pxR+YULF9C+fXuLx9dY60FERKR2DQ6ANY9/MRgMGD58uNGPwWBAWloaysvLAQC9e/eGr68vli5diitXrhi1c3toq2u9Dh06ALh1TV6NLVu2KKcNLWVvbw8HBwejso8++sjkLt66jq/GuHHjsHnzZqxduxYDBw5Uxm1OSEjIHU9T18Xw4cNRXl5udO1hSkoKiouL8cQTT9S73/Xr16OsrMzs6V8AGDJkCADgX//6l1JWXFyMb7/9Fn369LF4fPVZDyIiIrq7Bn8TyM6dO3H9+nUMGDDAZNnAgQOxfPly7Ny5E5GRkbC3t8cHH3yA6Oho9OnTB5MmTYK3tzf27NmDa9euYf369QBQ53r9+vWDp6cnXn75ZZw+fRrXr19HcnKyyc0JdTVixAjMmTMHzz33HHr16oUff/wRmzdvhqenp1G9uo6vxrhx4zB//nykp6dj+fLldxzD8ePH6zX22w0aNAgDBw5EXFwczpw5AwcHByxYsAAPPfQQnnzyyXr3m5SUBA8PDwwePNjs8hEjRqB3796Ij49HYWEh/Pz8sGrVKlRVVeG1116zeHz1WQ8iIiKqg4beRjx9+nQBIKdOnTJZVlBQIABk+vTpRuXp6eliMBhEp9OJTqeT0NBQo0elWFJv79698tBDD4mzs7P07dtXsrKy7vgYmNmzZ9e6LuXl5TJz5kxp3769ODs7S1hYmBw8eFCCgoJk2LBh9RpfjW7duom9vb0UFhbW2n/NGK0wLVJcXCwTJkwQd3d30el0EhMTI2fPnq13v3l5eaLRaGTq1Kl37LewsFAmTpwobdq0Ea1WK/369ZO0tLR6j8/S9SAiIqK704jU8+4Gskjv3r3Rpk0bpKam2nooREREpHJWew4g1e7gwYPYv38/nnnmGVsPhYiIiAg8AtiI/vOf/+CHH35AQkICzp07pzzHjoiIiMiWeASwEX322WeYPHkybt68iY0bNzL8ERERUZPAI4BEREREKsMjgEREREQqwwBIREREpDJWCYB5eXnQaDRmf1xdXZV6FRUVmDdvHiIjI+Hm5gaNRoP09PQG9f3dd99h8ODBcHNzg6urK7p164Y///nPJl/fpjaXLl1CbGwsWrduDXd3d4wdO7beX5EXEBBQ6/wOGjTIqK6IYMWKFejevTucnZ3h7e2NESNG4OrVq0b1du/ejcceewytW7eGp6cnIiMjsW/fPqM6X331FYYNG4YOHTrAyckJQUFBiIuLQ3Fxcb3Wg4iIiG5p8DeB3G7cuHEYOnSoUdntX6127do1vPnmmwgMDIRer0dGRkaD+vv+++8RHh6OgIAAvPHGG2jTpg0OHjyIpKQk/P73v0erVq0a1H5zFh0djaysLMyaNQsODg5YuHAhoqKikJmZCXt7e4vaWrJkiUmAy8vLwxtvvGESAOPj47FgwQLExMQgLi4OV69exZ49e3Djxg3lfwYOHDgAg8GAHj164K233kJFRQWWL1+OiIgI/PDDD8pX0h08eBAODg6YNm0a2rZti9OnT+ODDz7A119/jf3798PJyakBW4iIiEjFrPE06dzcXAEgixYtumO9yspKyc/PFxGR9evXCwCz3xJRV6NGjRIvLy+5dOmSUXlJSYmUlpbWu93mbseOHQJAEhMTlbJt27YJAElOTrZKH3PnzhWNRqPMp4jI0aNHxd7eXuLj4+/42pdeekm0Wq2UlJQoZceOHRMAMm/evDu+dsuWLQJA1q9f37AVICIiUrF7eg2gvb09fH19rdbekSNH0K1bN5MjfW5ubtDpdCb1d+3ahcjISLi7u8Pd3R3h4eHYsWOHSZtDhw6FTqeDTqfDsGHDcOzYMbP9azQazJkzB5s2bYJer1dOU3755ZdKnQsXLmDKlCnw8fGBk5MTevXqZbS8MWzduhVarRZjx45VyqKiouDh4YEtW7ZYpY+1a9diwIABRvO5bt06ODg4YNasWQBgctSwxvnz5+Hk5AQ3NzelzNvbu079tmvXDgDqfTqbiIiIrHwTyPXr11FUVGT0U1ZWZs0ujLRr1w779+9HXl7eXetu3boVjz/+OPLz8/Hqq6/inXfeQYcOHbBy5UqlTmFhIcLCwvDDDz8gPj4e8fHxyMzMRFhYGIqKisy2m5mZid/97ncYOnQolixZAoPBoIyntLQUAwcOxOeff47nnnsO7777Llq3bo0RI0bUeu1jzbV1DZGdnY3g4GCjU6R2dnbQ6/XIzs5uUNsAsG/fPpw8eRLjx483Kdfr9diyZQu8vb2h0+ng6+uLdevWGdULCwtDSUkJZsyYgZycHBw7dgxxcXHw8vJCbGysSX8lJSU4f/489uzZgxdffBEajQb9+/dv8HoQERGpljUOI9acAjb3k5CQYPY11jgF/NlnnwkAadmypcTExMhHH30kxcXFJvUqKyvFz89PgoOD5cqVK0bLzpw5o/x79uzZAkAyMjKUst27dwsAmTt3rkm7AMTOzk72799v0p+IyOuvvy4ODg6SnZ2tLKuqqhK9Xi/h4eFm16lmuzVESEiIGAwGERGJiIiQ7t27S3l5uYwZM0a8vb0b1LaIyLRp08TBwUGKioqMyrt16yYBAQGi0+nkb3/7myQnJ0toaKhoNBrJyspS6lVUVMjUqVPF3t5eWd8uXbrITz/9ZLa/vn37KvVat24ty5cvb/A6EBERqZlVjwBOmTIFqampRj9PPvmkNbsw8uSTTyIlJQV9+vTB559/jj/84Q9o164d4uPjUVVVpdTLyspCfn4+4uLijO5KBv7/lCIApKeno2PHjnj00UeVsgEDBiAwMLDWI3aDBg1Cz549jcpqbrLYsGEDHn74Yfj4+ChHRC9evIj+/fsjIyPDaIw1unTpgi5duli8LW5XXl4OR0dHALdu1igoKEBFRQW0Wm2Dj8hWVFQgOTkZkZGR8PDwMFp2/fp15OXlYcGCBZg5cybGjBmDL774Aq6urli0aJFSr0WLFggODsbTTz+NTz75BGvWrIFGo8HIkSPN3uH7/vvv48svv8T8+fPRpUsXtG/fvkHrQEREpHZWvQu4c+fOMBgM1mzyroYMGYIhQ4bgwoULSE1NxXvvvYf58+ejQ4cOmDZtGgAgNzcXANC1a9c7tnX27Fn4+fmZlPv5+eGXX34x+5qaO1bN+fnnn1FeXg4vLy+zy0tLS9G6dWujstquN7SEVqvFzZs3Ady647aqqgouLi4oLy9v8J2zKSkpKCoqMjn9C0AJnaNHj1bKXF1d0b9/fxw6dEgpmz9/PlasWIGTJ08qr4mIiECnTp2wePFivP3220btPvzwwwBuXcc4cOBAhIaGIj09HQMHDmzQuhAREamVVQOgLXl5eWH8+PF48skn0bFjR3z66adKAGxMd3rUjEajweDBgzFjxgyzy399NNJafHx8cP78eZM+CgsL4ePj06C2k5KS4OLigpEjR5os8/LywrFjx0wCb5s2bZCVlaX8vnLlSoSGhirhDwB8fX3RtWvXuz4a6Le//S3atm2Ljz76iAGQiIionu6bAFhDq9UiODgYZ8+eVcoCAwMB3LrDNyIiotbXtmvXDvn5+Sblp06dUtqwRMeOHXHjxo17flRUr9dj5cqVKCsrU474VVdXIzs7G0OGDKl3uyUlJdi2bRuio6Ph4uJisvzBBx/E7t27ce7cOXTo0EEpv3DhgtFp219++cXs6e+qqipcu3btruO4efOmEnCJiIjIcs36q+B2795tEiSKiopw8OBBdOzYUSnr3bs3fH19sXTpUly5csWo/u2PEwkPD0dOTg727t1r1EdeXh7Cw8MtHl90dDR2795t9qjW6dOnzb4mJCTkjqeV62L48OEoLy9HcnKyUpaSkoLi4mI88cQT9e53/fr1KCsrM3v6F4ASLv/1r38pZcXFxfj222/Rp08fpSwwMBDffPON0WNifv75Zxw7dgx6vV4pqzl1f7sdO3aguLi4wduIiIhIzTQiIg1tJC8vD4GBgVi0aFGtpztrLFu2DJcvX8bhw4fxySefYPLkyQgMDESrVq3w4osvWtTvkCFDcPLkSTz99NMICgrC+fPnsXr1auTl5eGrr74yOtq3detWREdHIygoCJMmTYK3tzf27NmDa9euYf369QBuhcHf/OY3sLOzw/Tp0wEACQkJ0Gg0OHz4MDw9PY3612g0mD17NubMmWN2fKWlpXjkkUeQn5+PqVOnomvXrigoKMDXX38NNzc3pKSkmLym5hEwDZkWEUFYWBgOHDigfBPIggUL4Ovri++//x4tWpge+K1Lv2FhYTh8+DDOnj1r9A0vNaqrq/HII4/g4MGDmD59Ovz8/LBq1SocP34c//nPf9C5c2cAwKpVqzBlyhT06NEDkydPRllZGZYtW4aioiJkZmaiW7duAG4Fxc6dO2Pw4MFwd3fHf/7zH6xcuRLOzs7IyspCQEBAvbcRERGRqlnjVuK6fhOIiIi/v7/Zx8X4+/tb3O+///1vGTdunAQGBoqTk5O0a9dOoqKijB7jcrv09HQxGAyi0+lEp9NJaGiobN++3ajO4cOHZciQIeLi4iIuLi4yZMgQOXLkiNn2AMjs2bPvOMaioiKZNm2aPPDAA+Lo6Ci+vr4SExMjqamptbZpjWkpLi6WCRMmiLu7u+h0OomJiZGzZ8/WWv9u/ebl5YlGo5GpU6fesd/CwkKZOHGitGnTRrRarfTr18/so342bNgg/fr1Ezc3N3FxcRGDwSD79u0zqvO3v/1N+vfvL15eXuLo6CiBgYESGxsrp06duvPKExER0R1Z5QggERERETUfzfoaQCIiIiKyHAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpzD0NgM8++yw0Go3yk56efi+7t8icOXOg0WjuWu+XX37B8OHD4e7uDo1Gg9jY2Aa1ZytNfXxERERkPVYNgF999RUee+wxuLm5oVWrVhgwYAA2b96sLH/hhReQlJSE+Ph4a3ZrUy+//DK+++47/Pd//zeSkpIwdepUWw9JsWnTJixZssTWw6i3gIAA5X8WHBwc0KlTJ/zhD3/AL7/8Yuuh1Utznw8iIrp/aERErNFQYmIiJk+ejN69e2PixIlo0aIFvvrqK9jZ2WHDhg1GddPT0/HYY48hLS0N4eHh1uje6iorK1FZWQknJ6c71mvbti3GjRt31z/sdW3PmmJjY5Geno68vLy71rXF+O4mICAArVu3xiuvvIKKigocPHgQK1asQJs2bZCdnQ0PDw9bD9EilswHERFRY2phjUbOnz+PuLg4PProo9i5cydatLjV7PPPP4+CggJrdHHPtWjRQlmPO7lw4QJatWpltfZspamOr0OHDnj22WeV3zt16oS4uDj84x//wMsvv2zDkRERETVfVjkFvHbtWly9ehWvv/66SYh44IEHLG7v4sWLmDFjBrp37w6dTgc3NzcYDAZkZGSY1D169ChGjhwJb29vuLi4oFu3bpgzZ06963Xq1MnoOkVzEhMTleUigrlz5yq///oawLq0V2PXrl2IjIyEu7s73N3dER4ejh07dli8XWr6+sc//oFTp04Z9Z+YmFiv8R05cgRDhw6FTqeDTqfDsGHDcOzYMbPbJTMzE9HR0dDpdAgKCsLq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Ll26oLi4GO+//z78/PyMHm9Q1/ZeeOEFfPDBBxg1ahSmT58OAEhISIC3tzdeeOEFi7fL/cLa8ztixAjMmTMHzz33HHr16oUff/wRmzdvNvt4C+DWtU+PPPII5s2bh+rqari5uaFPnz4m1z3VtZ4tLFu2DJcvX8bhw4cB3Ho0x549e9CqVSu8+OKLFrVV1/2+rvNh7f2+rvuLrdR1+/Xr1w+enp54+eWXcfr0aVy/fh3JycnKJQu/VtfP07vVa6zPof79++P999/HlClTMGrUKDg6OkKv1ytBl2zA1rchk/rUPGZg586d0q1bN9FqtdKzZ09JT083Wx91eMRFUVGRTJs2TR544AFxdHQUX19fiYmJkdTUVJO66enpYjAYRKfTiU6nk9DQUNm+fbvJ+Mz93P4Yg5ycHImNjZWAgADRarXi4+MjMTExcvz4cbPre7f2REQOHz4sQ4YMERcXF3FxcZEhQ4bIkSNHjOrU9fEQzcW9nt/y8nKZOXOmtG/fXpydnSUsLEwOHjwoQUFBMmzYMLP9//TTTxIWFiZarVYASEJCQoPqWdvdtqG/v3+d9r+6qOt+X+Nu8yFSt/2+rusqYtn+cq9Zsv327t0rDz30kDg7O0vfvn0lKyur1sfA3O3z1JLPXWvPh8itR/G88sor0rZtW9FoNAJA1qxZc9fXUePhdwHTPTdnzhzMnTtX9RfcExE1VF0/T/m5S7/GawCJiIiIVIYBkIiIiEhlGACJiIiIVIbXABIRERGpDI8AEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMAyARERGRyjAAEhEREakMA6DKXbp0CbGxsWjdujXc3d0xduxYFBYW2npYzYY1t19AQAA0Go3Zn0GDBjVav/cTW83H7t278dhjj6F169bw9PREZGQk9u3bZ41VatZsNR+3mzFjBjQaDV588cX6rgaZUVFRgXnz5iEyMhJubm7QaDRIT083W5fvj6apha0HQLYVHR2NrKwszJo1Cw4ODli4cCGioqKQmZkJe3t7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kcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpDAMgERERkcowABIRERGpzP8Cp3cD0bgnZQcAAAAASUVORK5CYII=",
|
| 725 |
+
"text/plain": [
|
| 726 |
+
"<Figure size 800x600 with 1 Axes>"
|
| 727 |
+
]
|
| 728 |
+
},
|
| 729 |
+
"metadata": {},
|
| 730 |
+
"output_type": "display_data"
|
| 731 |
}
|
| 732 |
],
|
| 733 |
"source": [
|
| 734 |
+
"# MODEL EVALUATION\n",
|
| 735 |
"accuracy = accuracy_score(y_test, y_pred)\n",
|
| 736 |
+
"f1 = f1_score(y_test, y_pred, average=\"macro\")\n",
|
| 737 |
+
"report = classification_report(y_test, y_pred)\n",
|
| 738 |
+
"\n",
|
| 739 |
"print(f\"Accuracy: {accuracy:.4f}\")\n",
|
| 740 |
+
"print(\"Classification Report:\\n\", classification_report(y_test, y_pred))\n",
|
| 741 |
+
"\n",
|
| 742 |
+
"text_output = f\"Accuracy: {accuracy:.4f}\\nF1 Score: {f1:.4f}\\n\\nClassification Report:\\n{report}\"\n",
|
| 743 |
+
"\n",
|
| 744 |
+
"plt.figure(figsize=(8, 6))\n",
|
| 745 |
+
"plt.text(0.01, 0.99, text_output, fontsize=12, ha='left', va='top', family=\"monospace\")\n",
|
| 746 |
+
"plt.axis(\"off\")\n",
|
| 747 |
+
"\n",
|
| 748 |
+
"plt.savefig(\"classification_report.png\", bbox_inches=\"tight\", dpi=300)\n",
|
| 749 |
+
"plt.show()"
|
| 750 |
]
|
| 751 |
},
|
| 752 |
{
|
|
|
|
| 758 |
},
|
| 759 |
{
|
| 760 |
"cell_type": "code",
|
| 761 |
+
"execution_count": 63,
|
| 762 |
"metadata": {},
|
| 763 |
"outputs": [
|
| 764 |
{
|
|
|
|
| 773 |
}
|
| 774 |
],
|
| 775 |
"source": [
|
|
|
|
| 776 |
"cm = confusion_matrix(y_test, y_pred)\n",
|
| 777 |
"sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=sentiment_mapping.keys(), yticklabels=sentiment_mapping.keys())\n",
|
| 778 |
"plt.xlabel(\"Predicted\")\n",
|
| 779 |
"plt.ylabel(\"Actual\")\n",
|
| 780 |
"plt.title(\"Confusion Matrix\")\n",
|
| 781 |
+
"plt.savefig(\"confusion_matrix.png\")\n",
|
| 782 |
"plt.show()"
|
| 783 |
]
|
| 784 |
},
|
| 785 |
{
|
| 786 |
"cell_type": "code",
|
| 787 |
+
"execution_count": 64,
|
| 788 |
"metadata": {},
|
| 789 |
"outputs": [
|
| 790 |
{
|
|
|
|
| 796 |
}
|
| 797 |
],
|
| 798 |
"source": [
|
| 799 |
+
"# SAVING THE MODEL AS A .pkl FILE\n",
|
| 800 |
"joblib.dump(model, \"sentimentAnalysis_model.pkl\")\n",
|
| 801 |
"joblib.dump(vectorizer, \"vectorizer.pkl\")\n",
|
| 802 |
"print(\"Model saved successfully\")"
|
sentiment_distribution.png
ADDED
|
vectorizer.pkl
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
size 39183
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:005669f3aa2e6881f76c8ac6b49fed721f3ed10ac15622a25439da31c0716753
|
| 3 |
size 39183
|