Add VLSP2016 dataset support and comprehensive evaluation updates
Browse filesMajor Features:
- Add dataset selection parameter to train.py (--dataset vlsp2016|uts2017)
- Train VLSP2016 models: Logistic Regression (70.19%), SVC Linear (71.14%)
- Create clean.py script to remove runs without exported models
- Update technical report with dual-dataset evaluation
Technical Improvements:
- Generic load_data() function routing to specific dataset loaders
- Support for both UTS2017_Bank (35 aspect-sentiment classes) and VLSP2016 (3 sentiment classes)
- N-gram comparison: bigrams (1-2) vs trigrams (1-3) analysis
- Export filename includes dataset name for better organization
Performance Results:
- VLSP2016: 71.14% (SVC), 70.19% (LR) - balanced 3-class sentiment
- UTS2017_Bank: 71.72% (SVC), 68.18% (LR) - imbalanced 35-class aspect-sentiment
- Consistent ~71% accuracy across different complexity levels
- Training efficiency: LR faster, SVC more accurate
Documentation Updates:
- Enhanced technical report with cross-dataset performance analysis
- Added comparative insights between balanced vs imbalanced datasets
- Updated abstract, methodology, and results sections
- Added VLSP2016 dataset description and characteristics
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- clean.py +212 -0
- paper/pulse_core_1_technical_report.tex +82 -15
- runs/20250928_131527/metadata.json +0 -1531
- runs/20250928_131527/models/labels.txt +0 -35
- runs/20250928_131527/training.log +0 -62
- runs/20250929_075333/metadata.json +77 -0
- runs/{20250928_131527/models/UTS2017_Bank_AspectSentiment_SVC_feat20k_ngram1-2.joblib → 20250929_075333/models/VLSP2016_Sentiment_LogisticRegression_feat20k_ngram1-2.joblib} +2 -2
- runs/20250929_075333/models/labels.txt +3 -0
- runs/{20250928_131527 → 20250929_075333}/models/model.joblib +2 -2
- runs/20250929_075333/training.log +40 -0
- runs/20250929_075529/metadata.json +77 -0
- runs/20250929_075529/models/VLSP2016_Sentiment_SVC_feat20k_ngram1-2.joblib +3 -0
- runs/20250929_075529/models/labels.txt +3 -0
- runs/20250929_075529/models/model.joblib +3 -0
- runs/20250929_075529/training.log +40 -0
- runs/20250929_075901/metadata.json +77 -0
- runs/20250929_075901/models/VLSP2016_Sentiment_SVC_feat20k_ngram1-3.joblib +3 -0
- runs/20250929_075901/models/labels.txt +3 -0
- runs/20250929_075901/models/model.joblib +3 -0
- runs/20250929_075901/training.log +40 -0
- train.py +165 -24
- vlsp2016_sentiment_20250929_075333.joblib +3 -0
- vlsp2016_sentiment_20250929_075529.joblib +3 -0
|
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Clean up script for removing training runs without exported models.
|
| 4 |
+
Removes all directories in runs/ folder that don't have a corresponding exported model file.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import argparse
|
| 8 |
+
import os
|
| 9 |
+
import shutil
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
import glob
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def find_exported_models():
|
| 15 |
+
"""Find all exported model files in the current directory"""
|
| 16 |
+
exported_models = []
|
| 17 |
+
seen_files = set() # Track files we've already processed
|
| 18 |
+
|
| 19 |
+
# Look for pattern: *_YYYYMMDD_HHMMSS.joblib
|
| 20 |
+
# This matches any exported model with timestamp format
|
| 21 |
+
patterns = [
|
| 22 |
+
"*_20[0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9].joblib"
|
| 23 |
+
]
|
| 24 |
+
|
| 25 |
+
for pattern in patterns:
|
| 26 |
+
for filepath in glob.glob(pattern):
|
| 27 |
+
# Skip if we've already seen this file
|
| 28 |
+
if filepath in seen_files:
|
| 29 |
+
continue
|
| 30 |
+
seen_files.add(filepath)
|
| 31 |
+
|
| 32 |
+
# Extract timestamp from filename
|
| 33 |
+
# Format: dataset_sentiment_YYYYMMDD_HHMMSS.joblib
|
| 34 |
+
filename = os.path.basename(filepath)
|
| 35 |
+
parts = filename.replace(".joblib", "").split("_")
|
| 36 |
+
if len(parts) >= 4:
|
| 37 |
+
# Get the last two parts which should be date and time
|
| 38 |
+
timestamp = "_".join(parts[-2:])
|
| 39 |
+
exported_models.append({
|
| 40 |
+
"file": filepath,
|
| 41 |
+
"timestamp": timestamp
|
| 42 |
+
})
|
| 43 |
+
|
| 44 |
+
return exported_models
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def find_all_runs():
|
| 48 |
+
"""Find all run directories in the runs folder"""
|
| 49 |
+
runs_dir = Path("runs")
|
| 50 |
+
if not runs_dir.exists():
|
| 51 |
+
return []
|
| 52 |
+
|
| 53 |
+
runs = []
|
| 54 |
+
for run_path in runs_dir.iterdir():
|
| 55 |
+
if run_path.is_dir():
|
| 56 |
+
# Run directories are named with timestamps: YYYYMMDD_HHMMSS
|
| 57 |
+
run_name = run_path.name
|
| 58 |
+
runs.append({
|
| 59 |
+
"path": run_path,
|
| 60 |
+
"timestamp": run_name
|
| 61 |
+
})
|
| 62 |
+
|
| 63 |
+
return runs
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def clean_runs(dry_run=False, verbose=False):
|
| 67 |
+
"""
|
| 68 |
+
Remove all run directories that don't have exported models.
|
| 69 |
+
|
| 70 |
+
Args:
|
| 71 |
+
dry_run: If True, only show what would be deleted without actually deleting
|
| 72 |
+
verbose: If True, show detailed information
|
| 73 |
+
|
| 74 |
+
Returns:
|
| 75 |
+
Tuple of (runs_to_keep, runs_to_delete)
|
| 76 |
+
"""
|
| 77 |
+
# Find all exported models
|
| 78 |
+
exported_models = find_exported_models()
|
| 79 |
+
exported_timestamps = {model["timestamp"] for model in exported_models}
|
| 80 |
+
|
| 81 |
+
# Find all runs
|
| 82 |
+
all_runs = find_all_runs()
|
| 83 |
+
|
| 84 |
+
# Categorize runs
|
| 85 |
+
runs_to_keep = []
|
| 86 |
+
runs_to_delete = []
|
| 87 |
+
|
| 88 |
+
for run in all_runs:
|
| 89 |
+
if run["timestamp"] in exported_timestamps:
|
| 90 |
+
runs_to_keep.append(run)
|
| 91 |
+
else:
|
| 92 |
+
runs_to_delete.append(run)
|
| 93 |
+
|
| 94 |
+
# Show summary
|
| 95 |
+
print(f"Found {len(all_runs)} total runs")
|
| 96 |
+
print(f"Found {len(exported_models)} exported models")
|
| 97 |
+
print(f"Runs to keep: {len(runs_to_keep)}")
|
| 98 |
+
print(f"Runs to delete: {len(runs_to_delete)}")
|
| 99 |
+
|
| 100 |
+
if verbose and exported_models:
|
| 101 |
+
print("\nExported models found:")
|
| 102 |
+
for model in exported_models:
|
| 103 |
+
print(f" - {model['file']} (timestamp: {model['timestamp']})")
|
| 104 |
+
|
| 105 |
+
if verbose and runs_to_keep:
|
| 106 |
+
print("\nRuns with exported models (will be kept):")
|
| 107 |
+
for run in runs_to_keep:
|
| 108 |
+
print(f" - {run['path']}")
|
| 109 |
+
|
| 110 |
+
if runs_to_delete:
|
| 111 |
+
print("\nRuns without exported models (will be deleted):")
|
| 112 |
+
for run in runs_to_delete:
|
| 113 |
+
print(f" - {run['path']}")
|
| 114 |
+
if verbose:
|
| 115 |
+
# Check if metadata exists and show some info
|
| 116 |
+
metadata_path = run["path"] / "metadata.json"
|
| 117 |
+
if metadata_path.exists():
|
| 118 |
+
import json
|
| 119 |
+
try:
|
| 120 |
+
with open(metadata_path) as f:
|
| 121 |
+
metadata = json.load(f)
|
| 122 |
+
print(f" Model: {metadata.get('model_name', 'unknown')}, "
|
| 123 |
+
f"Dataset: {metadata.get('dataset', 'unknown')}, "
|
| 124 |
+
f"Accuracy: {metadata.get('test_accuracy', 'N/A'):.4f}")
|
| 125 |
+
except (json.JSONDecodeError, KeyError):
|
| 126 |
+
pass
|
| 127 |
+
|
| 128 |
+
# Calculate space to be freed
|
| 129 |
+
total_size = 0
|
| 130 |
+
for run in runs_to_delete:
|
| 131 |
+
total_size += sum(f.stat().st_size for f in run["path"].rglob("*") if f.is_file())
|
| 132 |
+
|
| 133 |
+
if total_size > 0:
|
| 134 |
+
size_mb = total_size / (1024 * 1024)
|
| 135 |
+
print(f"\nTotal space to be freed: {size_mb:.2f} MB")
|
| 136 |
+
|
| 137 |
+
# Perform deletion if not dry run
|
| 138 |
+
if not dry_run and runs_to_delete:
|
| 139 |
+
deleted_count = 0
|
| 140 |
+
for run in runs_to_delete:
|
| 141 |
+
try:
|
| 142 |
+
shutil.rmtree(run["path"])
|
| 143 |
+
deleted_count += 1
|
| 144 |
+
if verbose:
|
| 145 |
+
print(f"Deleted: {run['path']}")
|
| 146 |
+
except Exception as e:
|
| 147 |
+
print(f"Error deleting {run['path']}: {e}")
|
| 148 |
+
|
| 149 |
+
print(f"\nSuccessfully deleted {deleted_count} run(s)")
|
| 150 |
+
elif dry_run and runs_to_delete:
|
| 151 |
+
print("\nDry run mode - no files were deleted")
|
| 152 |
+
print("Run without --dry-run to actually delete these directories")
|
| 153 |
+
elif not runs_to_delete:
|
| 154 |
+
print("\nNo runs to delete - all runs have exported models or no runs found")
|
| 155 |
+
|
| 156 |
+
return runs_to_keep, runs_to_delete
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def main():
|
| 160 |
+
parser = argparse.ArgumentParser(
|
| 161 |
+
description="Clean up training runs without exported models"
|
| 162 |
+
)
|
| 163 |
+
parser.add_argument(
|
| 164 |
+
"--dry-run",
|
| 165 |
+
action="store_true",
|
| 166 |
+
help="Show what would be deleted without actually deleting",
|
| 167 |
+
)
|
| 168 |
+
parser.add_argument(
|
| 169 |
+
"--verbose",
|
| 170 |
+
"-v",
|
| 171 |
+
action="store_true",
|
| 172 |
+
help="Show detailed information about runs",
|
| 173 |
+
)
|
| 174 |
+
parser.add_argument(
|
| 175 |
+
"--yes",
|
| 176 |
+
"-y",
|
| 177 |
+
action="store_true",
|
| 178 |
+
help="Skip confirmation prompt",
|
| 179 |
+
)
|
| 180 |
+
|
| 181 |
+
args = parser.parse_args()
|
| 182 |
+
|
| 183 |
+
# Check if runs directory exists
|
| 184 |
+
if not Path("runs").exists():
|
| 185 |
+
print("No 'runs' directory found. Nothing to clean.")
|
| 186 |
+
return
|
| 187 |
+
|
| 188 |
+
# Find runs to delete
|
| 189 |
+
print("Analyzing runs directory...\n")
|
| 190 |
+
|
| 191 |
+
# Do a dry run first to show what will be deleted
|
| 192 |
+
_, runs_to_delete = clean_runs(dry_run=True, verbose=args.verbose)
|
| 193 |
+
|
| 194 |
+
if not runs_to_delete:
|
| 195 |
+
return
|
| 196 |
+
|
| 197 |
+
# Ask for confirmation if not in dry-run mode and not auto-yes
|
| 198 |
+
if not args.dry_run and not args.yes and runs_to_delete:
|
| 199 |
+
print("\n" + "=" * 60)
|
| 200 |
+
response = input(f"Are you sure you want to delete {len(runs_to_delete)} run(s)? [y/N]: ")
|
| 201 |
+
if response.lower() != 'y':
|
| 202 |
+
print("Cleanup cancelled")
|
| 203 |
+
return
|
| 204 |
+
|
| 205 |
+
# Perform actual cleanup if not dry run
|
| 206 |
+
if not args.dry_run:
|
| 207 |
+
print("\nPerforming cleanup...")
|
| 208 |
+
clean_runs(dry_run=False, verbose=args.verbose)
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
if __name__ == "__main__":
|
| 212 |
+
main()
|
|
@@ -23,7 +23,7 @@
|
|
| 23 |
\maketitle
|
| 24 |
|
| 25 |
\begin{abstract}
|
| 26 |
-
This paper presents Pulse Core 1, a Vietnamese
|
| 27 |
\end{abstract}
|
| 28 |
|
| 29 |
\section{Introduction}
|
|
@@ -34,7 +34,7 @@ Vietnamese, spoken by approximately 95 million speakers globally, exhibits disti
|
|
| 34 |
|
| 35 |
Traditional machine learning approaches utilizing Term Frequency-Inverse Document Frequency (TF-IDF) vectorization with logistic regression maintain practical relevance for text classification tasks, particularly in resource-constrained computational environments \citep{pedregosa2011scikit}. These methodologies provide advantages in training efficiency, memory utilization, and model interpretability.
|
| 36 |
|
| 37 |
-
This paper presents Pulse Core 1, a Vietnamese
|
| 38 |
|
| 39 |
\section{Related Work}
|
| 40 |
|
|
@@ -46,7 +46,9 @@ Initial research in Vietnamese text classification employed rule-based methodolo
|
|
| 46 |
|
| 47 |
\subsection{Vietnamese Text Classification Datasets}
|
| 48 |
|
| 49 |
-
Contemporary Vietnamese
|
|
|
|
|
|
|
| 50 |
|
| 51 |
\textbf{UTS2017\_Bank Dataset}: A specialized corpus developed by the Underthesea NLP Team for Vietnamese banking aspect sentiment analysis. This dataset encompasses 14 banking aspects (ACCOUNT, CARD, CUSTOMER\_SUPPORT, DISCOUNT, INTEREST\_RATE, INTERNET\_BANKING, LOAN, MONEY\_TRANSFER, OTHER, PAYMENT, PROMOTION, SAVING, SECURITY, TRADEMARK) combined with 3 sentiment polarities (positive, negative, neutral), creating 35 unique aspect-sentiment combinations. The dataset represents specialized Vietnamese text classification challenges in the financial domain, focusing on customer feedback analysis and banking service categorization.
|
| 52 |
|
|
@@ -121,9 +123,11 @@ The system incorporates several optimization mechanisms to enhance computational
|
|
| 121 |
|
| 122 |
\subsection{Datasets}
|
| 123 |
|
| 124 |
-
This study evaluates performance on
|
|
|
|
|
|
|
| 125 |
|
| 126 |
-
The UTS2017\_Bank dataset contains 1,977 Vietnamese banking documents spanning 14 banking aspects combined with sentiment analysis, creating 35 unique aspect-sentiment categories. The dataset includes: account services, card services, customer support, discount offers, interest rates, internet banking, loans, money transfers, payments, promotions, savings, security features, trademark information, and miscellaneous services, each labeled with positive, negative, or neutral sentiment. The dataset exhibits significant class imbalance, with CUSTOMER\_SUPPORT\#negative (39\%) and TRADEMARK\#positive (35\%) categories dominating the distribution, while minority aspect-sentiment combinations have limited training examples.
|
| 127 |
|
| 128 |
\begin{table}[h]
|
| 129 |
\centering
|
|
@@ -131,10 +135,11 @@ The UTS2017\_Bank dataset contains 1,977 Vietnamese banking documents spanning 1
|
|
| 131 |
\toprule
|
| 132 |
\textbf{Dataset} & \textbf{Classes} & \textbf{Training} & \textbf{Test} & \textbf{Domain} \\
|
| 133 |
\midrule
|
|
|
|
| 134 |
UTS2017\_Bank & 35 & 1,581 & 396 & Banking Aspect Sentiment \\
|
| 135 |
\bottomrule
|
| 136 |
\end{tabular}
|
| 137 |
-
\caption{Dataset characteristics for Vietnamese
|
| 138 |
\label{tab:dataset_summary}
|
| 139 |
\end{table}
|
| 140 |
|
|
@@ -142,7 +147,7 @@ UTS2017\_Bank & 35 & 1,581 & 396 & Banking Aspect Sentiment \\
|
|
| 142 |
|
| 143 |
\subsection{Experimental Design}
|
| 144 |
|
| 145 |
-
The experimental evaluation employs the
|
| 146 |
|
| 147 |
\subsubsection{Evaluation Metrics}
|
| 148 |
|
|
@@ -167,7 +172,7 @@ The experimental design incorporates comparative analysis against established ba
|
|
| 167 |
\end{itemize}
|
| 168 |
|
| 169 |
\textbf{Baseline Performance Establishment:}
|
| 170 |
-
This work establishes
|
| 171 |
|
| 172 |
\begin{table}[h]
|
| 173 |
\centering
|
|
@@ -176,11 +181,15 @@ This work establishes the first comprehensive baseline for Vietnamese banking as
|
|
| 176 |
\hline
|
| 177 |
\textbf{Dataset} & \textbf{Method} & \textbf{Accuracy} \\
|
| 178 |
\hline
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
UTS2017\_Bank (35 aspect-sentiment) & \textbf{Pulse Core 1 - SVC with TF-IDF} & \textbf{71.72\%} \\
|
| 180 |
UTS2017\_Bank (35 aspect-sentiment) & \textbf{Pulse Core 1 - Logistic Regression with TF-IDF} & \textbf{68.18\%} \\
|
| 181 |
\hline
|
| 182 |
\end{tabular}
|
| 183 |
-
\caption{Performance results for Vietnamese
|
| 184 |
\label{tab:comprehensive_comparison}
|
| 185 |
\end{table}
|
| 186 |
|
|
@@ -192,6 +201,22 @@ This section presents comprehensive experimental results across both Vietnamese
|
|
| 192 |
|
| 193 |
\subsubsection{Overall Performance Summary}
|
| 194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
\textbf{UTS2017\_Bank Dataset (Banking Aspect Sentiment Analysis):}
|
| 196 |
The system exhibits competitive performance on the banking aspect sentiment analysis task:
|
| 197 |
\begin{itemize}
|
|
@@ -208,6 +233,24 @@ The system exhibits competitive performance on the banking aspect sentiment anal
|
|
| 208 |
|
| 209 |
\subsubsection{Detailed Per-Class Performance}
|
| 210 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
\textbf{UTS2017\_Bank Dataset: Selected Per-Class Results (Logistic Regression - 68.18\% accuracy):}
|
| 212 |
|
| 213 |
The following table shows performance for the most represented aspect-sentiment categories:
|
|
@@ -346,6 +389,22 @@ Analysis of the banking aspect sentiment task reveals important insights about V
|
|
| 346 |
\item \textbf{Class Balance Sensitivity}: Performance correlates strongly with training data availability, with dominant categories (CUSTOMER\_SUPPORT, TRADEMARK) achieving strong results while minority aspect-sentiment combinations suffer from data sparsity.
|
| 347 |
\end{itemize}
|
| 348 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 349 |
\section{Discussion}
|
| 350 |
|
| 351 |
\subsection{Research Implications}
|
|
@@ -421,16 +480,17 @@ The current investigation establishes several promising research trajectories fo
|
|
| 421 |
|
| 422 |
\section{Conclusion}
|
| 423 |
|
| 424 |
-
This paper presents Pulse Core 1, a Vietnamese
|
| 425 |
|
| 426 |
\begin{enumerate}
|
| 427 |
-
\item Traditional machine learning approaches achieve
|
| 428 |
-
\item Feature engineering methodologies retain critical importance for Vietnamese
|
| 429 |
-
\item
|
| 430 |
-
\item
|
|
|
|
| 431 |
\end{enumerate}
|
| 432 |
|
| 433 |
-
This research contributes to the Vietnamese
|
| 434 |
|
| 435 |
Future research initiatives should prioritize class imbalance mitigation strategies for minority aspect-sentiment combinations, integration of banking domain-specific feature representations, and exploration of joint aspect-sentiment modeling approaches that capture the interdependence between banking aspects and customer sentiment.
|
| 436 |
|
|
@@ -478,6 +538,13 @@ Toan Pham Van and Ta Minh Thanh.
|
|
| 478 |
|
| 479 |
\section{Changelog}
|
| 480 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
\textbf{2025-09-28}
|
| 482 |
\begin{itemize}
|
| 483 |
\item Initial release of Pulse Core 1
|
|
|
|
| 23 |
\maketitle
|
| 24 |
|
| 25 |
\begin{abstract}
|
| 26 |
+
This paper presents Pulse Core 1, a Vietnamese sentiment analysis system employing Term Frequency-Inverse Document Frequency (TF-IDF) feature extraction combined with machine learning classification algorithms. The system is evaluated on two Vietnamese datasets: (1) VLSP2016 general sentiment dataset achieving 70.19\% accuracy with Logistic Regression and 71.14\% accuracy with Support Vector Classification (SVC), and (2) UTS2017\_Bank aspect sentiment dataset containing 35 combined aspect-sentiment categories, achieving 68.18\% accuracy with Logistic Regression and 71.72\% accuracy with SVC. The implementation utilizes a 20,000-dimensional TF-IDF feature space with configurable n-gram analysis and incorporates hash-based caching for computational optimization. For banking applications, the model predicts combined aspect-sentiment labels in the format \texttt{<aspect>\#<sentiment>}, enabling fine-grained analysis of Vietnamese banking customer feedback across 14 banking aspects and 3 sentiment polarities. These results establish baseline performance metrics for Vietnamese sentiment analysis across both general and domain-specific applications, demonstrating the efficacy of traditional machine learning approaches for Vietnamese natural language processing tasks.
|
| 27 |
\end{abstract}
|
| 28 |
|
| 29 |
\section{Introduction}
|
|
|
|
| 34 |
|
| 35 |
Traditional machine learning approaches utilizing Term Frequency-Inverse Document Frequency (TF-IDF) vectorization with logistic regression maintain practical relevance for text classification tasks, particularly in resource-constrained computational environments \citep{pedregosa2011scikit}. These methodologies provide advantages in training efficiency, memory utilization, and model interpretability.
|
| 36 |
|
| 37 |
+
This paper presents Pulse Core 1, a Vietnamese sentiment analysis system implementing TF-IDF feature extraction with machine learning classification algorithms. The system is evaluated on two complementary datasets: (1) the VLSP2016 general sentiment dataset containing 6,150 Vietnamese reviews across 3 sentiment polarities, and (2) the UTS2017\_Bank aspect sentiment dataset containing 1,977 Vietnamese banking documents across 35 combined aspect-sentiment categories. The system achieves competitive performance with traditional machine learning approaches on both datasets, demonstrating its versatility for general sentiment analysis and specialized aspect-sentiment classification tasks. The dual-dataset evaluation provides comprehensive insights into Vietnamese sentiment analysis challenges across different domains and complexity levels.
|
| 38 |
|
| 39 |
\section{Related Work}
|
| 40 |
|
|
|
|
| 46 |
|
| 47 |
\subsection{Vietnamese Text Classification Datasets}
|
| 48 |
|
| 49 |
+
Contemporary Vietnamese sentiment analysis research employs both general-purpose and domain-specific datasets:
|
| 50 |
+
|
| 51 |
+
\textbf{VLSP2016 Dataset}: A standard Vietnamese sentiment analysis corpus from the Vietnamese Language and Speech Processing workshop, containing 6,150 product and service reviews categorized into three sentiment polarities (positive, negative, neutral). The dataset provides a balanced distribution with 1,700 samples per class in the training set and 350 per class in the test set, establishing a benchmark for general Vietnamese sentiment classification tasks.
|
| 52 |
|
| 53 |
\textbf{UTS2017\_Bank Dataset}: A specialized corpus developed by the Underthesea NLP Team for Vietnamese banking aspect sentiment analysis. This dataset encompasses 14 banking aspects (ACCOUNT, CARD, CUSTOMER\_SUPPORT, DISCOUNT, INTEREST\_RATE, INTERNET\_BANKING, LOAN, MONEY\_TRANSFER, OTHER, PAYMENT, PROMOTION, SAVING, SECURITY, TRADEMARK) combined with 3 sentiment polarities (positive, negative, neutral), creating 35 unique aspect-sentiment combinations. The dataset represents specialized Vietnamese text classification challenges in the financial domain, focusing on customer feedback analysis and banking service categorization.
|
| 54 |
|
|
|
|
| 123 |
|
| 124 |
\subsection{Datasets}
|
| 125 |
|
| 126 |
+
This study evaluates performance on two Vietnamese sentiment analysis datasets representing both general and domain-specific applications:
|
| 127 |
+
|
| 128 |
+
\textbf{VLSP2016 Dataset}: The VLSP2016 sentiment dataset contains 6,150 Vietnamese product and service reviews with balanced class distribution across three sentiment polarities. The dataset provides 5,100 training samples and 1,050 test samples, with each sentiment class (positive, negative, neutral) equally represented. This balanced distribution enables robust evaluation of general sentiment classification capabilities without class imbalance complications.
|
| 129 |
|
| 130 |
+
\textbf{UTS2017\_Bank Dataset}: The UTS2017\_Bank dataset contains 1,977 Vietnamese banking documents spanning 14 banking aspects combined with sentiment analysis, creating 35 unique aspect-sentiment categories. The dataset includes: account services, card services, customer support, discount offers, interest rates, internet banking, loans, money transfers, payments, promotions, savings, security features, trademark information, and miscellaneous services, each labeled with positive, negative, or neutral sentiment. The dataset exhibits significant class imbalance, with CUSTOMER\_SUPPORT\#negative (39\%) and TRADEMARK\#positive (35\%) categories dominating the distribution, while minority aspect-sentiment combinations have limited training examples.
|
| 131 |
|
| 132 |
\begin{table}[h]
|
| 133 |
\centering
|
|
|
|
| 135 |
\toprule
|
| 136 |
\textbf{Dataset} & \textbf{Classes} & \textbf{Training} & \textbf{Test} & \textbf{Domain} \\
|
| 137 |
\midrule
|
| 138 |
+
VLSP2016 & 3 & 5,100 & 1,050 & General Sentiment \\
|
| 139 |
UTS2017\_Bank & 35 & 1,581 & 396 & Banking Aspect Sentiment \\
|
| 140 |
\bottomrule
|
| 141 |
\end{tabular}
|
| 142 |
+
\caption{Dataset characteristics for Vietnamese sentiment analysis evaluation.}
|
| 143 |
\label{tab:dataset_summary}
|
| 144 |
\end{table}
|
| 145 |
|
|
|
|
| 147 |
|
| 148 |
\subsection{Experimental Design}
|
| 149 |
|
| 150 |
+
The experimental evaluation employs both the VLSP2016 general sentiment dataset and the UTS2017\_Bank banking aspect sentiment dataset. This dual-dataset approach enables comprehensive assessment of model performance across different complexity levels and domain requirements. Performance assessment utilizes standard multi-class classification evaluation metrics for both simple sentiment classification and complex aspect-sentiment prediction tasks.
|
| 151 |
|
| 152 |
\subsubsection{Evaluation Metrics}
|
| 153 |
|
|
|
|
| 172 |
\end{itemize}
|
| 173 |
|
| 174 |
\textbf{Baseline Performance Establishment:}
|
| 175 |
+
This work establishes comprehensive baselines for Vietnamese sentiment analysis across both general and banking-specific domains using traditional machine learning approaches. Table \ref{tab:comprehensive_comparison} presents performance results for both datasets:
|
| 176 |
|
| 177 |
\begin{table}[h]
|
| 178 |
\centering
|
|
|
|
| 181 |
\hline
|
| 182 |
\textbf{Dataset} & \textbf{Method} & \textbf{Accuracy} \\
|
| 183 |
\hline
|
| 184 |
+
VLSP2016 (3 sentiments) & \textbf{Pulse Core 1 - SVC Linear (1-2 gram)} & \textbf{71.14\%} \\
|
| 185 |
+
VLSP2016 (3 sentiments) & \textbf{Pulse Core 1 - SVC Linear (1-3 gram)} & \textbf{70.67\%} \\
|
| 186 |
+
VLSP2016 (3 sentiments) & \textbf{Pulse Core 1 - Logistic Regression} & \textbf{70.19\%} \\
|
| 187 |
+
\hline
|
| 188 |
UTS2017\_Bank (35 aspect-sentiment) & \textbf{Pulse Core 1 - SVC with TF-IDF} & \textbf{71.72\%} \\
|
| 189 |
UTS2017\_Bank (35 aspect-sentiment) & \textbf{Pulse Core 1 - Logistic Regression with TF-IDF} & \textbf{68.18\%} \\
|
| 190 |
\hline
|
| 191 |
\end{tabular}
|
| 192 |
+
\caption{Performance results for Vietnamese sentiment analysis using TF-IDF-based traditional machine learning approaches across general and banking-specific datasets.}
|
| 193 |
\label{tab:comprehensive_comparison}
|
| 194 |
\end{table}
|
| 195 |
|
|
|
|
| 201 |
|
| 202 |
\subsubsection{Overall Performance Summary}
|
| 203 |
|
| 204 |
+
\textbf{VLSP2016 Dataset (General Sentiment Analysis):}
|
| 205 |
+
The system achieves strong performance on general Vietnamese sentiment classification:
|
| 206 |
+
\begin{itemize}
|
| 207 |
+
\item \textbf{Test Classification Accuracy (SVC Linear, 1-2 gram)}: 71.14\%
|
| 208 |
+
\item \textbf{Test Classification Accuracy (SVC Linear, 1-3 gram)}: 70.67\%
|
| 209 |
+
\item \textbf{Test Classification Accuracy (Logistic Regression)}: 70.19\%
|
| 210 |
+
\item \textbf{Training Latency (SVC)}: 24.95 seconds
|
| 211 |
+
\item \textbf{Training Latency (Logistic Regression)}: 0.75 seconds
|
| 212 |
+
\item \textbf{Inference Latency}: 0.76 seconds for 1,050 test samples (0.72 ms per sample)
|
| 213 |
+
\item \textbf{Training Samples}: 5,100 reviews
|
| 214 |
+
\item \textbf{Test Samples}: 1,050 reviews
|
| 215 |
+
\item \textbf{Number of Classes}: 3 sentiment polarities
|
| 216 |
+
\item \textbf{Weighted Average F1-Score (SVC)}: 0.713
|
| 217 |
+
\item \textbf{Weighted Average F1-Score (Logistic Regression)}: 0.703
|
| 218 |
+
\end{itemize}
|
| 219 |
+
|
| 220 |
\textbf{UTS2017\_Bank Dataset (Banking Aspect Sentiment Analysis):}
|
| 221 |
The system exhibits competitive performance on the banking aspect sentiment analysis task:
|
| 222 |
\begin{itemize}
|
|
|
|
| 233 |
|
| 234 |
\subsubsection{Detailed Per-Class Performance}
|
| 235 |
|
| 236 |
+
\textbf{VLSP2016 Dataset: Per-Class Results (SVC Linear - 71.14\% accuracy):}
|
| 237 |
+
|
| 238 |
+
\begin{table}[h]
|
| 239 |
+
\centering
|
| 240 |
+
\begin{tabular}{lcccc}
|
| 241 |
+
\toprule
|
| 242 |
+
Sentiment & Precision & Recall & F1-Score & Support \\
|
| 243 |
+
\midrule
|
| 244 |
+
Negative & 0.70 & 0.72 & 0.71 & 350 \\
|
| 245 |
+
Neutral & 0.65 & 0.69 & 0.67 & 350 \\
|
| 246 |
+
Positive & 0.80 & 0.72 & 0.76 & 350 \\
|
| 247 |
+
\midrule
|
| 248 |
+
Weighted Avg & 0.72 & 0.71 & 0.71 & 1,050 \\
|
| 249 |
+
\bottomrule
|
| 250 |
+
\end{tabular}
|
| 251 |
+
\caption{VLSP2016 per-class performance metrics for SVC Linear model}
|
| 252 |
+
\end{table}
|
| 253 |
+
|
| 254 |
\textbf{UTS2017\_Bank Dataset: Selected Per-Class Results (Logistic Regression - 68.18\% accuracy):}
|
| 255 |
|
| 256 |
The following table shows performance for the most represented aspect-sentiment categories:
|
|
|
|
| 389 |
\item \textbf{Class Balance Sensitivity}: Performance correlates strongly with training data availability, with dominant categories (CUSTOMER\_SUPPORT, TRADEMARK) achieving strong results while minority aspect-sentiment combinations suffer from data sparsity.
|
| 390 |
\end{itemize}
|
| 391 |
|
| 392 |
+
\subsubsection{Cross-Dataset Performance Analysis}
|
| 393 |
+
|
| 394 |
+
\textbf{Comparative Insights:}
|
| 395 |
+
The evaluation across both VLSP2016 and UTS2017\_Bank datasets reveals important patterns:
|
| 396 |
+
|
| 397 |
+
\begin{itemize}
|
| 398 |
+
\item \textbf{Consistent SVC Performance}: SVC achieves approximately 71\% accuracy on both datasets despite vastly different complexity levels (3 classes vs. 35 classes), demonstrating robust generalization capabilities.
|
| 399 |
+
\item \textbf{N-gram Range Impact}: For VLSP2016, bigrams (1-2) outperform trigrams (1-3) by 0.47 percentage points, suggesting that local context is sufficient for general sentiment classification.
|
| 400 |
+
\item \textbf{Training Efficiency Trade-offs}:
|
| 401 |
+
\begin{itemize}
|
| 402 |
+
\item VLSP2016: Larger dataset requires more training time (24.95s for SVC vs. 0.75s for LR)
|
| 403 |
+
\item UTS2017\_Bank: Despite 35 classes, training is faster (5.3s for SVC) due to smaller dataset size
|
| 404 |
+
\end{itemize}
|
| 405 |
+
\item \textbf{Balanced vs. Imbalanced Performance}: VLSP2016's balanced distribution yields consistent per-class performance (0.67-0.76 F1), while UTS2017\_Bank's imbalanced distribution creates extreme performance variation (0.00-0.88 F1).
|
| 406 |
+
\end{itemize}
|
| 407 |
+
|
| 408 |
\section{Discussion}
|
| 409 |
|
| 410 |
\subsection{Research Implications}
|
|
|
|
| 480 |
|
| 481 |
\section{Conclusion}
|
| 482 |
|
| 483 |
+
This paper presents Pulse Core 1, a Vietnamese sentiment analysis system that establishes the viability of systematically optimized traditional machine learning methodologies for both general and domain-specific applications. The investigation yields several significant findings:
|
| 484 |
|
| 485 |
\begin{enumerate}
|
| 486 |
+
\item Traditional machine learning approaches achieve consistent performance across both general sentiment analysis (71.14\% on VLSP2016) and complex aspect-sentiment tasks (71.72\% on UTS2017\_Bank) while maintaining computational efficiency.
|
| 487 |
+
\item Feature engineering methodologies retain critical importance for Vietnamese applications, with the 20,000-dimensional TF-IDF representation effectively capturing sentiment patterns across both balanced 3-class and imbalanced 35-class scenarios.
|
| 488 |
+
\item N-gram analysis reveals that bigrams (1-2) provide optimal performance for Vietnamese sentiment classification, with trigrams offering minimal improvement while increasing computational overhead.
|
| 489 |
+
\item Class distribution significantly impacts performance, with balanced datasets (VLSP2016) yielding consistent per-class results while imbalanced datasets (UTS2017\_Bank) create extreme performance variations.
|
| 490 |
+
\item The fundamental trade-off between algorithmic complexity and model interpretability favors TF-IDF approaches for applications requiring transparency, rapid deployment, and regulatory compliance.
|
| 491 |
\end{enumerate}
|
| 492 |
|
| 493 |
+
This research contributes to the Vietnamese NLP ecosystem by establishing comprehensive baselines for both general sentiment analysis and banking-specific aspect-sentiment classification. The consistent performance across datasets of varying complexity demonstrates the robustness of traditional machine learning approaches for Vietnamese text classification. The demonstrated effectiveness on both simple sentiment and complex aspect-sentiment prediction indicates substantial potential for practical Vietnamese NLP applications across multiple domains.
|
| 494 |
|
| 495 |
Future research initiatives should prioritize class imbalance mitigation strategies for minority aspect-sentiment combinations, integration of banking domain-specific feature representations, and exploration of joint aspect-sentiment modeling approaches that capture the interdependence between banking aspects and customer sentiment.
|
| 496 |
|
|
|
|
| 538 |
|
| 539 |
\section{Changelog}
|
| 540 |
|
| 541 |
+
\textbf{2025-09-29}
|
| 542 |
+
\begin{itemize}
|
| 543 |
+
\item Added VLSP2016 dataset evaluation and cross-dataset analysis
|
| 544 |
+
\item Updated performance metrics with multiple n-gram configurations
|
| 545 |
+
\item Enhanced comparative analysis between balanced and imbalanced datasets
|
| 546 |
+
\end{itemize}
|
| 547 |
+
|
| 548 |
\textbf{2025-09-28}
|
| 549 |
\begin{itemize}
|
| 550 |
\item Initial release of Pulse Core 1
|
|
@@ -1,1531 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"timestamp": "20250928_131527",
|
| 3 |
-
"config_name": "UTS2017_Bank_AspectSentiment_SVC_feat20k_ngram1-2",
|
| 4 |
-
"model_name": "svc_linear",
|
| 5 |
-
"classifier": "SVC",
|
| 6 |
-
"max_features": 20000,
|
| 7 |
-
"ngram_range": [
|
| 8 |
-
1,
|
| 9 |
-
2
|
| 10 |
-
],
|
| 11 |
-
"split_ratio": 0.2,
|
| 12 |
-
"n_samples": null,
|
| 13 |
-
"train_samples": 1581,
|
| 14 |
-
"test_samples": 396,
|
| 15 |
-
"unique_labels": 35,
|
| 16 |
-
"labels": [
|
| 17 |
-
"ACCOUNT#negative",
|
| 18 |
-
"CARD#negative",
|
| 19 |
-
"CARD#neutral",
|
| 20 |
-
"CARD#positive",
|
| 21 |
-
"CUSTOMER_SUPPORT#negative",
|
| 22 |
-
"CUSTOMER_SUPPORT#neutral",
|
| 23 |
-
"CUSTOMER_SUPPORT#positive",
|
| 24 |
-
"DISCOUNT#negative",
|
| 25 |
-
"DISCOUNT#neutral",
|
| 26 |
-
"DISCOUNT#positive",
|
| 27 |
-
"INTEREST_RATE#negative",
|
| 28 |
-
"INTEREST_RATE#neutral",
|
| 29 |
-
"INTEREST_RATE#positive",
|
| 30 |
-
"INTERNET_BANKING#negative",
|
| 31 |
-
"INTERNET_BANKING#neutral",
|
| 32 |
-
"INTERNET_BANKING#positive",
|
| 33 |
-
"LOAN#negative",
|
| 34 |
-
"LOAN#positive",
|
| 35 |
-
"MONEY_TRANSFER#negative",
|
| 36 |
-
"MONEY_TRANSFER#positive",
|
| 37 |
-
"OTHER#negative",
|
| 38 |
-
"OTHER#neutral",
|
| 39 |
-
"OTHER#positive",
|
| 40 |
-
"PAYMENT#negative",
|
| 41 |
-
"PAYMENT#positive",
|
| 42 |
-
"PROMOTION#negative",
|
| 43 |
-
"PROMOTION#neutral",
|
| 44 |
-
"PROMOTION#positive",
|
| 45 |
-
"SAVING#negative",
|
| 46 |
-
"SAVING#neutral",
|
| 47 |
-
"SAVING#positive",
|
| 48 |
-
"SECURITY#neutral",
|
| 49 |
-
"SECURITY#positive",
|
| 50 |
-
"TRADEMARK#negative",
|
| 51 |
-
"TRADEMARK#positive"
|
| 52 |
-
],
|
| 53 |
-
"train_accuracy": 0.9430740037950665,
|
| 54 |
-
"test_accuracy": 0.7171717171717171,
|
| 55 |
-
"train_time": 7.737863779067993,
|
| 56 |
-
"prediction_time": 0.1107940673828125,
|
| 57 |
-
"classification_report": {
|
| 58 |
-
"ACCOUNT#negative": {
|
| 59 |
-
"precision": 0.0,
|
| 60 |
-
"recall": 0.0,
|
| 61 |
-
"f1-score": 0.0,
|
| 62 |
-
"support": 2.0
|
| 63 |
-
},
|
| 64 |
-
"CARD#negative": {
|
| 65 |
-
"precision": 1.0,
|
| 66 |
-
"recall": 0.14285714285714285,
|
| 67 |
-
"f1-score": 0.25,
|
| 68 |
-
"support": 7.0
|
| 69 |
-
},
|
| 70 |
-
"CARD#positive": {
|
| 71 |
-
"precision": 0.0,
|
| 72 |
-
"recall": 0.0,
|
| 73 |
-
"f1-score": 0.0,
|
| 74 |
-
"support": 1.0
|
| 75 |
-
},
|
| 76 |
-
"CUSTOMER_SUPPORT#negative": {
|
| 77 |
-
"precision": 0.4931506849315068,
|
| 78 |
-
"recall": 0.96,
|
| 79 |
-
"f1-score": 0.6515837104072398,
|
| 80 |
-
"support": 75.0
|
| 81 |
-
},
|
| 82 |
-
"CUSTOMER_SUPPORT#neutral": {
|
| 83 |
-
"precision": 0.0,
|
| 84 |
-
"recall": 0.0,
|
| 85 |
-
"f1-score": 0.0,
|
| 86 |
-
"support": 1.0
|
| 87 |
-
},
|
| 88 |
-
"CUSTOMER_SUPPORT#positive": {
|
| 89 |
-
"precision": 0.8641975308641975,
|
| 90 |
-
"recall": 0.8974358974358975,
|
| 91 |
-
"f1-score": 0.8805031446540881,
|
| 92 |
-
"support": 78.0
|
| 93 |
-
},
|
| 94 |
-
"DISCOUNT#negative": {
|
| 95 |
-
"precision": 0.0,
|
| 96 |
-
"recall": 0.0,
|
| 97 |
-
"f1-score": 0.0,
|
| 98 |
-
"support": 5.0
|
| 99 |
-
},
|
| 100 |
-
"DISCOUNT#neutral": {
|
| 101 |
-
"precision": 0.0,
|
| 102 |
-
"recall": 0.0,
|
| 103 |
-
"f1-score": 0.0,
|
| 104 |
-
"support": 1.0
|
| 105 |
-
},
|
| 106 |
-
"DISCOUNT#positive": {
|
| 107 |
-
"precision": 0.0,
|
| 108 |
-
"recall": 0.0,
|
| 109 |
-
"f1-score": 0.0,
|
| 110 |
-
"support": 0.0
|
| 111 |
-
},
|
| 112 |
-
"INTEREST_RATE#negative": {
|
| 113 |
-
"precision": 0.5555555555555556,
|
| 114 |
-
"recall": 0.5,
|
| 115 |
-
"f1-score": 0.5263157894736842,
|
| 116 |
-
"support": 10.0
|
| 117 |
-
},
|
| 118 |
-
"INTERNET_BANKING#negative": {
|
| 119 |
-
"precision": 0.0,
|
| 120 |
-
"recall": 0.0,
|
| 121 |
-
"f1-score": 0.0,
|
| 122 |
-
"support": 12.0
|
| 123 |
-
},
|
| 124 |
-
"INTERNET_BANKING#positive": {
|
| 125 |
-
"precision": 0.0,
|
| 126 |
-
"recall": 0.0,
|
| 127 |
-
"f1-score": 0.0,
|
| 128 |
-
"support": 1.0
|
| 129 |
-
},
|
| 130 |
-
"LOAN#negative": {
|
| 131 |
-
"precision": 0.875,
|
| 132 |
-
"recall": 0.5384615384615384,
|
| 133 |
-
"f1-score": 0.6666666666666666,
|
| 134 |
-
"support": 13.0
|
| 135 |
-
},
|
| 136 |
-
"MONEY_TRANSFER#negative": {
|
| 137 |
-
"precision": 0.0,
|
| 138 |
-
"recall": 0.0,
|
| 139 |
-
"f1-score": 0.0,
|
| 140 |
-
"support": 5.0
|
| 141 |
-
},
|
| 142 |
-
"OTHER#negative": {
|
| 143 |
-
"precision": 0.0,
|
| 144 |
-
"recall": 0.0,
|
| 145 |
-
"f1-score": 0.0,
|
| 146 |
-
"support": 10.0
|
| 147 |
-
},
|
| 148 |
-
"OTHER#neutral": {
|
| 149 |
-
"precision": 0.0,
|
| 150 |
-
"recall": 0.0,
|
| 151 |
-
"f1-score": 0.0,
|
| 152 |
-
"support": 1.0
|
| 153 |
-
},
|
| 154 |
-
"OTHER#positive": {
|
| 155 |
-
"precision": 0.6666666666666666,
|
| 156 |
-
"recall": 0.5,
|
| 157 |
-
"f1-score": 0.5714285714285714,
|
| 158 |
-
"support": 4.0
|
| 159 |
-
},
|
| 160 |
-
"PAYMENT#positive": {
|
| 161 |
-
"precision": 0.0,
|
| 162 |
-
"recall": 0.0,
|
| 163 |
-
"f1-score": 0.0,
|
| 164 |
-
"support": 3.0
|
| 165 |
-
},
|
| 166 |
-
"PROMOTION#negative": {
|
| 167 |
-
"precision": 0.0,
|
| 168 |
-
"recall": 0.0,
|
| 169 |
-
"f1-score": 0.0,
|
| 170 |
-
"support": 4.0
|
| 171 |
-
},
|
| 172 |
-
"PROMOTION#neutral": {
|
| 173 |
-
"precision": 0.0,
|
| 174 |
-
"recall": 0.0,
|
| 175 |
-
"f1-score": 0.0,
|
| 176 |
-
"support": 1.0
|
| 177 |
-
},
|
| 178 |
-
"PROMOTION#positive": {
|
| 179 |
-
"precision": 0.3333333333333333,
|
| 180 |
-
"recall": 0.2,
|
| 181 |
-
"f1-score": 0.25,
|
| 182 |
-
"support": 5.0
|
| 183 |
-
},
|
| 184 |
-
"SAVING#negative": {
|
| 185 |
-
"precision": 0.0,
|
| 186 |
-
"recall": 0.0,
|
| 187 |
-
"f1-score": 0.0,
|
| 188 |
-
"support": 1.0
|
| 189 |
-
},
|
| 190 |
-
"SAVING#positive": {
|
| 191 |
-
"precision": 0.0,
|
| 192 |
-
"recall": 0.0,
|
| 193 |
-
"f1-score": 0.0,
|
| 194 |
-
"support": 2.0
|
| 195 |
-
},
|
| 196 |
-
"SECURITY#negative": {
|
| 197 |
-
"precision": 0.0,
|
| 198 |
-
"recall": 0.0,
|
| 199 |
-
"f1-score": 0.0,
|
| 200 |
-
"support": 1.0
|
| 201 |
-
},
|
| 202 |
-
"SECURITY#neutral": {
|
| 203 |
-
"precision": 0.0,
|
| 204 |
-
"recall": 0.0,
|
| 205 |
-
"f1-score": 0.0,
|
| 206 |
-
"support": 1.0
|
| 207 |
-
},
|
| 208 |
-
"TRADEMARK#negative": {
|
| 209 |
-
"precision": 0.0,
|
| 210 |
-
"recall": 0.0,
|
| 211 |
-
"f1-score": 0.0,
|
| 212 |
-
"support": 14.0
|
| 213 |
-
},
|
| 214 |
-
"TRADEMARK#positive": {
|
| 215 |
-
"precision": 0.8936170212765957,
|
| 216 |
-
"recall": 0.9130434782608695,
|
| 217 |
-
"f1-score": 0.9032258064516129,
|
| 218 |
-
"support": 138.0
|
| 219 |
-
},
|
| 220 |
-
"accuracy": 0.7171717171717171,
|
| 221 |
-
"macro avg": {
|
| 222 |
-
"precision": 0.21042669602325392,
|
| 223 |
-
"recall": 0.17228881692649806,
|
| 224 |
-
"f1-score": 0.1740638403363653,
|
| 225 |
-
"support": 396.0
|
| 226 |
-
},
|
| 227 |
-
"weighted avg": {
|
| 228 |
-
"precision": 0.6464059257634583,
|
| 229 |
-
"recall": 0.7171717171717171,
|
| 230 |
-
"f1-score": 0.6601230396489957,
|
| 231 |
-
"support": 396.0
|
| 232 |
-
}
|
| 233 |
-
},
|
| 234 |
-
"confusion_matrix": [
|
| 235 |
-
[
|
| 236 |
-
0,
|
| 237 |
-
0,
|
| 238 |
-
0,
|
| 239 |
-
0,
|
| 240 |
-
1,
|
| 241 |
-
0,
|
| 242 |
-
1,
|
| 243 |
-
0,
|
| 244 |
-
0,
|
| 245 |
-
0,
|
| 246 |
-
0,
|
| 247 |
-
0,
|
| 248 |
-
0,
|
| 249 |
-
0,
|
| 250 |
-
0,
|
| 251 |
-
0,
|
| 252 |
-
0,
|
| 253 |
-
0,
|
| 254 |
-
0,
|
| 255 |
-
0,
|
| 256 |
-
0,
|
| 257 |
-
0,
|
| 258 |
-
0,
|
| 259 |
-
0,
|
| 260 |
-
0,
|
| 261 |
-
0,
|
| 262 |
-
0,
|
| 263 |
-
0,
|
| 264 |
-
0,
|
| 265 |
-
0,
|
| 266 |
-
0,
|
| 267 |
-
0,
|
| 268 |
-
0,
|
| 269 |
-
0,
|
| 270 |
-
0
|
| 271 |
-
],
|
| 272 |
-
[
|
| 273 |
-
0,
|
| 274 |
-
1,
|
| 275 |
-
0,
|
| 276 |
-
0,
|
| 277 |
-
5,
|
| 278 |
-
0,
|
| 279 |
-
0,
|
| 280 |
-
0,
|
| 281 |
-
0,
|
| 282 |
-
0,
|
| 283 |
-
1,
|
| 284 |
-
0,
|
| 285 |
-
0,
|
| 286 |
-
0,
|
| 287 |
-
0,
|
| 288 |
-
0,
|
| 289 |
-
0,
|
| 290 |
-
0,
|
| 291 |
-
0,
|
| 292 |
-
0,
|
| 293 |
-
0,
|
| 294 |
-
0,
|
| 295 |
-
0,
|
| 296 |
-
0,
|
| 297 |
-
0,
|
| 298 |
-
0,
|
| 299 |
-
0,
|
| 300 |
-
0,
|
| 301 |
-
0,
|
| 302 |
-
0,
|
| 303 |
-
0,
|
| 304 |
-
0,
|
| 305 |
-
0,
|
| 306 |
-
0,
|
| 307 |
-
0
|
| 308 |
-
],
|
| 309 |
-
[
|
| 310 |
-
0,
|
| 311 |
-
0,
|
| 312 |
-
0,
|
| 313 |
-
0,
|
| 314 |
-
0,
|
| 315 |
-
0,
|
| 316 |
-
0,
|
| 317 |
-
0,
|
| 318 |
-
0,
|
| 319 |
-
0,
|
| 320 |
-
0,
|
| 321 |
-
0,
|
| 322 |
-
0,
|
| 323 |
-
0,
|
| 324 |
-
0,
|
| 325 |
-
0,
|
| 326 |
-
0,
|
| 327 |
-
0,
|
| 328 |
-
0,
|
| 329 |
-
0,
|
| 330 |
-
0,
|
| 331 |
-
0,
|
| 332 |
-
0,
|
| 333 |
-
0,
|
| 334 |
-
0,
|
| 335 |
-
0,
|
| 336 |
-
0,
|
| 337 |
-
0,
|
| 338 |
-
0,
|
| 339 |
-
0,
|
| 340 |
-
0,
|
| 341 |
-
0,
|
| 342 |
-
0,
|
| 343 |
-
0,
|
| 344 |
-
0
|
| 345 |
-
],
|
| 346 |
-
[
|
| 347 |
-
0,
|
| 348 |
-
0,
|
| 349 |
-
0,
|
| 350 |
-
0,
|
| 351 |
-
0,
|
| 352 |
-
0,
|
| 353 |
-
0,
|
| 354 |
-
0,
|
| 355 |
-
0,
|
| 356 |
-
0,
|
| 357 |
-
0,
|
| 358 |
-
0,
|
| 359 |
-
0,
|
| 360 |
-
0,
|
| 361 |
-
0,
|
| 362 |
-
0,
|
| 363 |
-
0,
|
| 364 |
-
0,
|
| 365 |
-
0,
|
| 366 |
-
0,
|
| 367 |
-
0,
|
| 368 |
-
0,
|
| 369 |
-
0,
|
| 370 |
-
0,
|
| 371 |
-
0,
|
| 372 |
-
0,
|
| 373 |
-
0,
|
| 374 |
-
0,
|
| 375 |
-
0,
|
| 376 |
-
0,
|
| 377 |
-
0,
|
| 378 |
-
0,
|
| 379 |
-
0,
|
| 380 |
-
0,
|
| 381 |
-
1
|
| 382 |
-
],
|
| 383 |
-
[
|
| 384 |
-
0,
|
| 385 |
-
0,
|
| 386 |
-
0,
|
| 387 |
-
0,
|
| 388 |
-
72,
|
| 389 |
-
0,
|
| 390 |
-
1,
|
| 391 |
-
0,
|
| 392 |
-
0,
|
| 393 |
-
0,
|
| 394 |
-
1,
|
| 395 |
-
0,
|
| 396 |
-
0,
|
| 397 |
-
0,
|
| 398 |
-
0,
|
| 399 |
-
0,
|
| 400 |
-
1,
|
| 401 |
-
0,
|
| 402 |
-
0,
|
| 403 |
-
0,
|
| 404 |
-
0,
|
| 405 |
-
0,
|
| 406 |
-
0,
|
| 407 |
-
0,
|
| 408 |
-
0,
|
| 409 |
-
0,
|
| 410 |
-
0,
|
| 411 |
-
0,
|
| 412 |
-
0,
|
| 413 |
-
0,
|
| 414 |
-
0,
|
| 415 |
-
0,
|
| 416 |
-
0,
|
| 417 |
-
0,
|
| 418 |
-
0
|
| 419 |
-
],
|
| 420 |
-
[
|
| 421 |
-
0,
|
| 422 |
-
0,
|
| 423 |
-
0,
|
| 424 |
-
0,
|
| 425 |
-
1,
|
| 426 |
-
0,
|
| 427 |
-
0,
|
| 428 |
-
0,
|
| 429 |
-
0,
|
| 430 |
-
0,
|
| 431 |
-
0,
|
| 432 |
-
0,
|
| 433 |
-
0,
|
| 434 |
-
0,
|
| 435 |
-
0,
|
| 436 |
-
0,
|
| 437 |
-
0,
|
| 438 |
-
0,
|
| 439 |
-
0,
|
| 440 |
-
0,
|
| 441 |
-
0,
|
| 442 |
-
0,
|
| 443 |
-
0,
|
| 444 |
-
0,
|
| 445 |
-
0,
|
| 446 |
-
0,
|
| 447 |
-
0,
|
| 448 |
-
0,
|
| 449 |
-
0,
|
| 450 |
-
0,
|
| 451 |
-
0,
|
| 452 |
-
0,
|
| 453 |
-
0,
|
| 454 |
-
0,
|
| 455 |
-
0
|
| 456 |
-
],
|
| 457 |
-
[
|
| 458 |
-
0,
|
| 459 |
-
0,
|
| 460 |
-
0,
|
| 461 |
-
0,
|
| 462 |
-
6,
|
| 463 |
-
0,
|
| 464 |
-
70,
|
| 465 |
-
0,
|
| 466 |
-
0,
|
| 467 |
-
0,
|
| 468 |
-
0,
|
| 469 |
-
0,
|
| 470 |
-
0,
|
| 471 |
-
0,
|
| 472 |
-
0,
|
| 473 |
-
0,
|
| 474 |
-
0,
|
| 475 |
-
0,
|
| 476 |
-
0,
|
| 477 |
-
0,
|
| 478 |
-
0,
|
| 479 |
-
0,
|
| 480 |
-
0,
|
| 481 |
-
0,
|
| 482 |
-
0,
|
| 483 |
-
0,
|
| 484 |
-
0,
|
| 485 |
-
0,
|
| 486 |
-
0,
|
| 487 |
-
0,
|
| 488 |
-
0,
|
| 489 |
-
0,
|
| 490 |
-
0,
|
| 491 |
-
0,
|
| 492 |
-
2
|
| 493 |
-
],
|
| 494 |
-
[
|
| 495 |
-
0,
|
| 496 |
-
0,
|
| 497 |
-
0,
|
| 498 |
-
0,
|
| 499 |
-
5,
|
| 500 |
-
0,
|
| 501 |
-
0,
|
| 502 |
-
0,
|
| 503 |
-
0,
|
| 504 |
-
0,
|
| 505 |
-
0,
|
| 506 |
-
0,
|
| 507 |
-
0,
|
| 508 |
-
0,
|
| 509 |
-
0,
|
| 510 |
-
0,
|
| 511 |
-
0,
|
| 512 |
-
0,
|
| 513 |
-
0,
|
| 514 |
-
0,
|
| 515 |
-
0,
|
| 516 |
-
0,
|
| 517 |
-
0,
|
| 518 |
-
0,
|
| 519 |
-
0,
|
| 520 |
-
0,
|
| 521 |
-
0,
|
| 522 |
-
0,
|
| 523 |
-
0,
|
| 524 |
-
0,
|
| 525 |
-
0,
|
| 526 |
-
0,
|
| 527 |
-
0,
|
| 528 |
-
0,
|
| 529 |
-
0
|
| 530 |
-
],
|
| 531 |
-
[
|
| 532 |
-
0,
|
| 533 |
-
0,
|
| 534 |
-
0,
|
| 535 |
-
0,
|
| 536 |
-
1,
|
| 537 |
-
0,
|
| 538 |
-
0,
|
| 539 |
-
0,
|
| 540 |
-
0,
|
| 541 |
-
0,
|
| 542 |
-
0,
|
| 543 |
-
0,
|
| 544 |
-
0,
|
| 545 |
-
0,
|
| 546 |
-
0,
|
| 547 |
-
0,
|
| 548 |
-
0,
|
| 549 |
-
0,
|
| 550 |
-
0,
|
| 551 |
-
0,
|
| 552 |
-
0,
|
| 553 |
-
0,
|
| 554 |
-
0,
|
| 555 |
-
0,
|
| 556 |
-
0,
|
| 557 |
-
0,
|
| 558 |
-
0,
|
| 559 |
-
0,
|
| 560 |
-
0,
|
| 561 |
-
0,
|
| 562 |
-
0,
|
| 563 |
-
0,
|
| 564 |
-
0,
|
| 565 |
-
0,
|
| 566 |
-
0
|
| 567 |
-
],
|
| 568 |
-
[
|
| 569 |
-
0,
|
| 570 |
-
0,
|
| 571 |
-
0,
|
| 572 |
-
0,
|
| 573 |
-
0,
|
| 574 |
-
0,
|
| 575 |
-
0,
|
| 576 |
-
0,
|
| 577 |
-
0,
|
| 578 |
-
0,
|
| 579 |
-
0,
|
| 580 |
-
0,
|
| 581 |
-
0,
|
| 582 |
-
0,
|
| 583 |
-
0,
|
| 584 |
-
0,
|
| 585 |
-
0,
|
| 586 |
-
0,
|
| 587 |
-
0,
|
| 588 |
-
0,
|
| 589 |
-
0,
|
| 590 |
-
0,
|
| 591 |
-
0,
|
| 592 |
-
0,
|
| 593 |
-
0,
|
| 594 |
-
0,
|
| 595 |
-
0,
|
| 596 |
-
0,
|
| 597 |
-
0,
|
| 598 |
-
0,
|
| 599 |
-
0,
|
| 600 |
-
0,
|
| 601 |
-
0,
|
| 602 |
-
0,
|
| 603 |
-
0
|
| 604 |
-
],
|
| 605 |
-
[
|
| 606 |
-
0,
|
| 607 |
-
0,
|
| 608 |
-
0,
|
| 609 |
-
0,
|
| 610 |
-
4,
|
| 611 |
-
0,
|
| 612 |
-
0,
|
| 613 |
-
0,
|
| 614 |
-
0,
|
| 615 |
-
0,
|
| 616 |
-
5,
|
| 617 |
-
0,
|
| 618 |
-
0,
|
| 619 |
-
0,
|
| 620 |
-
0,
|
| 621 |
-
0,
|
| 622 |
-
0,
|
| 623 |
-
0,
|
| 624 |
-
0,
|
| 625 |
-
0,
|
| 626 |
-
0,
|
| 627 |
-
0,
|
| 628 |
-
0,
|
| 629 |
-
0,
|
| 630 |
-
0,
|
| 631 |
-
0,
|
| 632 |
-
0,
|
| 633 |
-
0,
|
| 634 |
-
0,
|
| 635 |
-
0,
|
| 636 |
-
0,
|
| 637 |
-
0,
|
| 638 |
-
0,
|
| 639 |
-
0,
|
| 640 |
-
1
|
| 641 |
-
],
|
| 642 |
-
[
|
| 643 |
-
0,
|
| 644 |
-
0,
|
| 645 |
-
0,
|
| 646 |
-
0,
|
| 647 |
-
0,
|
| 648 |
-
0,
|
| 649 |
-
0,
|
| 650 |
-
0,
|
| 651 |
-
0,
|
| 652 |
-
0,
|
| 653 |
-
0,
|
| 654 |
-
0,
|
| 655 |
-
0,
|
| 656 |
-
0,
|
| 657 |
-
0,
|
| 658 |
-
0,
|
| 659 |
-
0,
|
| 660 |
-
0,
|
| 661 |
-
0,
|
| 662 |
-
0,
|
| 663 |
-
0,
|
| 664 |
-
0,
|
| 665 |
-
0,
|
| 666 |
-
0,
|
| 667 |
-
0,
|
| 668 |
-
0,
|
| 669 |
-
0,
|
| 670 |
-
0,
|
| 671 |
-
0,
|
| 672 |
-
0,
|
| 673 |
-
0,
|
| 674 |
-
0,
|
| 675 |
-
0,
|
| 676 |
-
0,
|
| 677 |
-
0
|
| 678 |
-
],
|
| 679 |
-
[
|
| 680 |
-
0,
|
| 681 |
-
0,
|
| 682 |
-
0,
|
| 683 |
-
0,
|
| 684 |
-
0,
|
| 685 |
-
0,
|
| 686 |
-
0,
|
| 687 |
-
0,
|
| 688 |
-
0,
|
| 689 |
-
0,
|
| 690 |
-
0,
|
| 691 |
-
0,
|
| 692 |
-
0,
|
| 693 |
-
0,
|
| 694 |
-
0,
|
| 695 |
-
0,
|
| 696 |
-
0,
|
| 697 |
-
0,
|
| 698 |
-
0,
|
| 699 |
-
0,
|
| 700 |
-
0,
|
| 701 |
-
0,
|
| 702 |
-
0,
|
| 703 |
-
0,
|
| 704 |
-
0,
|
| 705 |
-
0,
|
| 706 |
-
0,
|
| 707 |
-
0,
|
| 708 |
-
0,
|
| 709 |
-
0,
|
| 710 |
-
0,
|
| 711 |
-
0,
|
| 712 |
-
0,
|
| 713 |
-
0,
|
| 714 |
-
0
|
| 715 |
-
],
|
| 716 |
-
[
|
| 717 |
-
0,
|
| 718 |
-
0,
|
| 719 |
-
0,
|
| 720 |
-
0,
|
| 721 |
-
12,
|
| 722 |
-
0,
|
| 723 |
-
0,
|
| 724 |
-
0,
|
| 725 |
-
0,
|
| 726 |
-
0,
|
| 727 |
-
0,
|
| 728 |
-
0,
|
| 729 |
-
0,
|
| 730 |
-
0,
|
| 731 |
-
0,
|
| 732 |
-
0,
|
| 733 |
-
0,
|
| 734 |
-
0,
|
| 735 |
-
0,
|
| 736 |
-
0,
|
| 737 |
-
0,
|
| 738 |
-
0,
|
| 739 |
-
0,
|
| 740 |
-
0,
|
| 741 |
-
0,
|
| 742 |
-
0,
|
| 743 |
-
0,
|
| 744 |
-
0,
|
| 745 |
-
0,
|
| 746 |
-
0,
|
| 747 |
-
0,
|
| 748 |
-
0,
|
| 749 |
-
0,
|
| 750 |
-
0,
|
| 751 |
-
0
|
| 752 |
-
],
|
| 753 |
-
[
|
| 754 |
-
0,
|
| 755 |
-
0,
|
| 756 |
-
0,
|
| 757 |
-
0,
|
| 758 |
-
0,
|
| 759 |
-
0,
|
| 760 |
-
0,
|
| 761 |
-
0,
|
| 762 |
-
0,
|
| 763 |
-
0,
|
| 764 |
-
0,
|
| 765 |
-
0,
|
| 766 |
-
0,
|
| 767 |
-
0,
|
| 768 |
-
0,
|
| 769 |
-
0,
|
| 770 |
-
0,
|
| 771 |
-
0,
|
| 772 |
-
0,
|
| 773 |
-
0,
|
| 774 |
-
0,
|
| 775 |
-
0,
|
| 776 |
-
0,
|
| 777 |
-
0,
|
| 778 |
-
0,
|
| 779 |
-
0,
|
| 780 |
-
0,
|
| 781 |
-
0,
|
| 782 |
-
0,
|
| 783 |
-
0,
|
| 784 |
-
0,
|
| 785 |
-
0,
|
| 786 |
-
0,
|
| 787 |
-
0,
|
| 788 |
-
0
|
| 789 |
-
],
|
| 790 |
-
[
|
| 791 |
-
0,
|
| 792 |
-
0,
|
| 793 |
-
0,
|
| 794 |
-
0,
|
| 795 |
-
1,
|
| 796 |
-
0,
|
| 797 |
-
0,
|
| 798 |
-
0,
|
| 799 |
-
0,
|
| 800 |
-
0,
|
| 801 |
-
0,
|
| 802 |
-
0,
|
| 803 |
-
0,
|
| 804 |
-
0,
|
| 805 |
-
0,
|
| 806 |
-
0,
|
| 807 |
-
0,
|
| 808 |
-
0,
|
| 809 |
-
0,
|
| 810 |
-
0,
|
| 811 |
-
0,
|
| 812 |
-
0,
|
| 813 |
-
0,
|
| 814 |
-
0,
|
| 815 |
-
0,
|
| 816 |
-
0,
|
| 817 |
-
0,
|
| 818 |
-
0,
|
| 819 |
-
0,
|
| 820 |
-
0,
|
| 821 |
-
0,
|
| 822 |
-
0,
|
| 823 |
-
0,
|
| 824 |
-
0,
|
| 825 |
-
0
|
| 826 |
-
],
|
| 827 |
-
[
|
| 828 |
-
0,
|
| 829 |
-
0,
|
| 830 |
-
0,
|
| 831 |
-
0,
|
| 832 |
-
4,
|
| 833 |
-
0,
|
| 834 |
-
0,
|
| 835 |
-
0,
|
| 836 |
-
0,
|
| 837 |
-
0,
|
| 838 |
-
0,
|
| 839 |
-
0,
|
| 840 |
-
0,
|
| 841 |
-
0,
|
| 842 |
-
0,
|
| 843 |
-
0,
|
| 844 |
-
7,
|
| 845 |
-
0,
|
| 846 |
-
0,
|
| 847 |
-
0,
|
| 848 |
-
0,
|
| 849 |
-
0,
|
| 850 |
-
0,
|
| 851 |
-
0,
|
| 852 |
-
0,
|
| 853 |
-
0,
|
| 854 |
-
0,
|
| 855 |
-
0,
|
| 856 |
-
0,
|
| 857 |
-
0,
|
| 858 |
-
0,
|
| 859 |
-
0,
|
| 860 |
-
0,
|
| 861 |
-
2,
|
| 862 |
-
0
|
| 863 |
-
],
|
| 864 |
-
[
|
| 865 |
-
0,
|
| 866 |
-
0,
|
| 867 |
-
0,
|
| 868 |
-
0,
|
| 869 |
-
0,
|
| 870 |
-
0,
|
| 871 |
-
0,
|
| 872 |
-
0,
|
| 873 |
-
0,
|
| 874 |
-
0,
|
| 875 |
-
0,
|
| 876 |
-
0,
|
| 877 |
-
0,
|
| 878 |
-
0,
|
| 879 |
-
0,
|
| 880 |
-
0,
|
| 881 |
-
0,
|
| 882 |
-
0,
|
| 883 |
-
0,
|
| 884 |
-
0,
|
| 885 |
-
0,
|
| 886 |
-
0,
|
| 887 |
-
0,
|
| 888 |
-
0,
|
| 889 |
-
0,
|
| 890 |
-
0,
|
| 891 |
-
0,
|
| 892 |
-
0,
|
| 893 |
-
0,
|
| 894 |
-
0,
|
| 895 |
-
0,
|
| 896 |
-
0,
|
| 897 |
-
0,
|
| 898 |
-
0,
|
| 899 |
-
0
|
| 900 |
-
],
|
| 901 |
-
[
|
| 902 |
-
0,
|
| 903 |
-
0,
|
| 904 |
-
0,
|
| 905 |
-
0,
|
| 906 |
-
3,
|
| 907 |
-
0,
|
| 908 |
-
0,
|
| 909 |
-
0,
|
| 910 |
-
0,
|
| 911 |
-
0,
|
| 912 |
-
2,
|
| 913 |
-
0,
|
| 914 |
-
0,
|
| 915 |
-
0,
|
| 916 |
-
0,
|
| 917 |
-
0,
|
| 918 |
-
0,
|
| 919 |
-
0,
|
| 920 |
-
0,
|
| 921 |
-
0,
|
| 922 |
-
0,
|
| 923 |
-
0,
|
| 924 |
-
0,
|
| 925 |
-
0,
|
| 926 |
-
0,
|
| 927 |
-
0,
|
| 928 |
-
0,
|
| 929 |
-
0,
|
| 930 |
-
0,
|
| 931 |
-
0,
|
| 932 |
-
0,
|
| 933 |
-
0,
|
| 934 |
-
0,
|
| 935 |
-
0,
|
| 936 |
-
0
|
| 937 |
-
],
|
| 938 |
-
[
|
| 939 |
-
0,
|
| 940 |
-
0,
|
| 941 |
-
0,
|
| 942 |
-
0,
|
| 943 |
-
0,
|
| 944 |
-
0,
|
| 945 |
-
0,
|
| 946 |
-
0,
|
| 947 |
-
0,
|
| 948 |
-
0,
|
| 949 |
-
0,
|
| 950 |
-
0,
|
| 951 |
-
0,
|
| 952 |
-
0,
|
| 953 |
-
0,
|
| 954 |
-
0,
|
| 955 |
-
0,
|
| 956 |
-
0,
|
| 957 |
-
0,
|
| 958 |
-
0,
|
| 959 |
-
0,
|
| 960 |
-
0,
|
| 961 |
-
0,
|
| 962 |
-
0,
|
| 963 |
-
0,
|
| 964 |
-
0,
|
| 965 |
-
0,
|
| 966 |
-
0,
|
| 967 |
-
0,
|
| 968 |
-
0,
|
| 969 |
-
0,
|
| 970 |
-
0,
|
| 971 |
-
0,
|
| 972 |
-
0,
|
| 973 |
-
0
|
| 974 |
-
],
|
| 975 |
-
[
|
| 976 |
-
0,
|
| 977 |
-
0,
|
| 978 |
-
0,
|
| 979 |
-
0,
|
| 980 |
-
8,
|
| 981 |
-
0,
|
| 982 |
-
0,
|
| 983 |
-
0,
|
| 984 |
-
0,
|
| 985 |
-
1,
|
| 986 |
-
0,
|
| 987 |
-
0,
|
| 988 |
-
0,
|
| 989 |
-
0,
|
| 990 |
-
0,
|
| 991 |
-
0,
|
| 992 |
-
0,
|
| 993 |
-
0,
|
| 994 |
-
0,
|
| 995 |
-
0,
|
| 996 |
-
0,
|
| 997 |
-
0,
|
| 998 |
-
0,
|
| 999 |
-
0,
|
| 1000 |
-
0,
|
| 1001 |
-
0,
|
| 1002 |
-
0,
|
| 1003 |
-
0,
|
| 1004 |
-
0,
|
| 1005 |
-
0,
|
| 1006 |
-
0,
|
| 1007 |
-
0,
|
| 1008 |
-
0,
|
| 1009 |
-
1,
|
| 1010 |
-
0
|
| 1011 |
-
],
|
| 1012 |
-
[
|
| 1013 |
-
0,
|
| 1014 |
-
0,
|
| 1015 |
-
0,
|
| 1016 |
-
0,
|
| 1017 |
-
1,
|
| 1018 |
-
0,
|
| 1019 |
-
0,
|
| 1020 |
-
0,
|
| 1021 |
-
0,
|
| 1022 |
-
0,
|
| 1023 |
-
0,
|
| 1024 |
-
0,
|
| 1025 |
-
0,
|
| 1026 |
-
0,
|
| 1027 |
-
0,
|
| 1028 |
-
0,
|
| 1029 |
-
0,
|
| 1030 |
-
0,
|
| 1031 |
-
0,
|
| 1032 |
-
0,
|
| 1033 |
-
0,
|
| 1034 |
-
0,
|
| 1035 |
-
0,
|
| 1036 |
-
0,
|
| 1037 |
-
0,
|
| 1038 |
-
0,
|
| 1039 |
-
0,
|
| 1040 |
-
0,
|
| 1041 |
-
0,
|
| 1042 |
-
0,
|
| 1043 |
-
0,
|
| 1044 |
-
0,
|
| 1045 |
-
0,
|
| 1046 |
-
0,
|
| 1047 |
-
0
|
| 1048 |
-
],
|
| 1049 |
-
[
|
| 1050 |
-
0,
|
| 1051 |
-
0,
|
| 1052 |
-
0,
|
| 1053 |
-
0,
|
| 1054 |
-
1,
|
| 1055 |
-
0,
|
| 1056 |
-
0,
|
| 1057 |
-
0,
|
| 1058 |
-
0,
|
| 1059 |
-
0,
|
| 1060 |
-
0,
|
| 1061 |
-
0,
|
| 1062 |
-
0,
|
| 1063 |
-
0,
|
| 1064 |
-
0,
|
| 1065 |
-
0,
|
| 1066 |
-
0,
|
| 1067 |
-
0,
|
| 1068 |
-
0,
|
| 1069 |
-
0,
|
| 1070 |
-
0,
|
| 1071 |
-
0,
|
| 1072 |
-
2,
|
| 1073 |
-
0,
|
| 1074 |
-
0,
|
| 1075 |
-
0,
|
| 1076 |
-
0,
|
| 1077 |
-
0,
|
| 1078 |
-
0,
|
| 1079 |
-
0,
|
| 1080 |
-
0,
|
| 1081 |
-
0,
|
| 1082 |
-
0,
|
| 1083 |
-
0,
|
| 1084 |
-
1
|
| 1085 |
-
],
|
| 1086 |
-
[
|
| 1087 |
-
0,
|
| 1088 |
-
0,
|
| 1089 |
-
0,
|
| 1090 |
-
0,
|
| 1091 |
-
0,
|
| 1092 |
-
0,
|
| 1093 |
-
0,
|
| 1094 |
-
0,
|
| 1095 |
-
0,
|
| 1096 |
-
0,
|
| 1097 |
-
0,
|
| 1098 |
-
0,
|
| 1099 |
-
0,
|
| 1100 |
-
0,
|
| 1101 |
-
0,
|
| 1102 |
-
0,
|
| 1103 |
-
0,
|
| 1104 |
-
0,
|
| 1105 |
-
0,
|
| 1106 |
-
0,
|
| 1107 |
-
0,
|
| 1108 |
-
0,
|
| 1109 |
-
0,
|
| 1110 |
-
0,
|
| 1111 |
-
0,
|
| 1112 |
-
0,
|
| 1113 |
-
0,
|
| 1114 |
-
0,
|
| 1115 |
-
0,
|
| 1116 |
-
0,
|
| 1117 |
-
0,
|
| 1118 |
-
0,
|
| 1119 |
-
0,
|
| 1120 |
-
0,
|
| 1121 |
-
0
|
| 1122 |
-
],
|
| 1123 |
-
[
|
| 1124 |
-
0,
|
| 1125 |
-
0,
|
| 1126 |
-
0,
|
| 1127 |
-
0,
|
| 1128 |
-
0,
|
| 1129 |
-
0,
|
| 1130 |
-
2,
|
| 1131 |
-
0,
|
| 1132 |
-
0,
|
| 1133 |
-
0,
|
| 1134 |
-
0,
|
| 1135 |
-
0,
|
| 1136 |
-
0,
|
| 1137 |
-
0,
|
| 1138 |
-
0,
|
| 1139 |
-
0,
|
| 1140 |
-
0,
|
| 1141 |
-
0,
|
| 1142 |
-
0,
|
| 1143 |
-
0,
|
| 1144 |
-
0,
|
| 1145 |
-
0,
|
| 1146 |
-
0,
|
| 1147 |
-
0,
|
| 1148 |
-
0,
|
| 1149 |
-
0,
|
| 1150 |
-
0,
|
| 1151 |
-
0,
|
| 1152 |
-
0,
|
| 1153 |
-
0,
|
| 1154 |
-
0,
|
| 1155 |
-
0,
|
| 1156 |
-
0,
|
| 1157 |
-
0,
|
| 1158 |
-
1
|
| 1159 |
-
],
|
| 1160 |
-
[
|
| 1161 |
-
0,
|
| 1162 |
-
0,
|
| 1163 |
-
0,
|
| 1164 |
-
0,
|
| 1165 |
-
3,
|
| 1166 |
-
0,
|
| 1167 |
-
0,
|
| 1168 |
-
0,
|
| 1169 |
-
0,
|
| 1170 |
-
0,
|
| 1171 |
-
0,
|
| 1172 |
-
0,
|
| 1173 |
-
0,
|
| 1174 |
-
0,
|
| 1175 |
-
0,
|
| 1176 |
-
0,
|
| 1177 |
-
0,
|
| 1178 |
-
0,
|
| 1179 |
-
0,
|
| 1180 |
-
0,
|
| 1181 |
-
0,
|
| 1182 |
-
0,
|
| 1183 |
-
0,
|
| 1184 |
-
0,
|
| 1185 |
-
0,
|
| 1186 |
-
0,
|
| 1187 |
-
0,
|
| 1188 |
-
1,
|
| 1189 |
-
0,
|
| 1190 |
-
0,
|
| 1191 |
-
0,
|
| 1192 |
-
0,
|
| 1193 |
-
0,
|
| 1194 |
-
0,
|
| 1195 |
-
0
|
| 1196 |
-
],
|
| 1197 |
-
[
|
| 1198 |
-
0,
|
| 1199 |
-
0,
|
| 1200 |
-
0,
|
| 1201 |
-
0,
|
| 1202 |
-
1,
|
| 1203 |
-
0,
|
| 1204 |
-
0,
|
| 1205 |
-
0,
|
| 1206 |
-
0,
|
| 1207 |
-
0,
|
| 1208 |
-
0,
|
| 1209 |
-
0,
|
| 1210 |
-
0,
|
| 1211 |
-
0,
|
| 1212 |
-
0,
|
| 1213 |
-
0,
|
| 1214 |
-
0,
|
| 1215 |
-
0,
|
| 1216 |
-
0,
|
| 1217 |
-
0,
|
| 1218 |
-
0,
|
| 1219 |
-
0,
|
| 1220 |
-
0,
|
| 1221 |
-
0,
|
| 1222 |
-
0,
|
| 1223 |
-
0,
|
| 1224 |
-
0,
|
| 1225 |
-
0,
|
| 1226 |
-
0,
|
| 1227 |
-
0,
|
| 1228 |
-
0,
|
| 1229 |
-
0,
|
| 1230 |
-
0,
|
| 1231 |
-
0,
|
| 1232 |
-
0
|
| 1233 |
-
],
|
| 1234 |
-
[
|
| 1235 |
-
0,
|
| 1236 |
-
0,
|
| 1237 |
-
0,
|
| 1238 |
-
0,
|
| 1239 |
-
0,
|
| 1240 |
-
0,
|
| 1241 |
-
0,
|
| 1242 |
-
0,
|
| 1243 |
-
0,
|
| 1244 |
-
0,
|
| 1245 |
-
0,
|
| 1246 |
-
0,
|
| 1247 |
-
0,
|
| 1248 |
-
0,
|
| 1249 |
-
0,
|
| 1250 |
-
0,
|
| 1251 |
-
0,
|
| 1252 |
-
0,
|
| 1253 |
-
0,
|
| 1254 |
-
0,
|
| 1255 |
-
0,
|
| 1256 |
-
0,
|
| 1257 |
-
1,
|
| 1258 |
-
0,
|
| 1259 |
-
0,
|
| 1260 |
-
0,
|
| 1261 |
-
0,
|
| 1262 |
-
1,
|
| 1263 |
-
0,
|
| 1264 |
-
0,
|
| 1265 |
-
0,
|
| 1266 |
-
0,
|
| 1267 |
-
0,
|
| 1268 |
-
0,
|
| 1269 |
-
3
|
| 1270 |
-
],
|
| 1271 |
-
[
|
| 1272 |
-
0,
|
| 1273 |
-
0,
|
| 1274 |
-
0,
|
| 1275 |
-
0,
|
| 1276 |
-
1,
|
| 1277 |
-
0,
|
| 1278 |
-
0,
|
| 1279 |
-
0,
|
| 1280 |
-
0,
|
| 1281 |
-
0,
|
| 1282 |
-
0,
|
| 1283 |
-
0,
|
| 1284 |
-
0,
|
| 1285 |
-
0,
|
| 1286 |
-
0,
|
| 1287 |
-
0,
|
| 1288 |
-
0,
|
| 1289 |
-
0,
|
| 1290 |
-
0,
|
| 1291 |
-
0,
|
| 1292 |
-
0,
|
| 1293 |
-
0,
|
| 1294 |
-
0,
|
| 1295 |
-
0,
|
| 1296 |
-
0,
|
| 1297 |
-
0,
|
| 1298 |
-
0,
|
| 1299 |
-
0,
|
| 1300 |
-
0,
|
| 1301 |
-
0,
|
| 1302 |
-
0,
|
| 1303 |
-
0,
|
| 1304 |
-
0,
|
| 1305 |
-
0,
|
| 1306 |
-
0
|
| 1307 |
-
],
|
| 1308 |
-
[
|
| 1309 |
-
0,
|
| 1310 |
-
0,
|
| 1311 |
-
0,
|
| 1312 |
-
0,
|
| 1313 |
-
0,
|
| 1314 |
-
0,
|
| 1315 |
-
0,
|
| 1316 |
-
0,
|
| 1317 |
-
0,
|
| 1318 |
-
0,
|
| 1319 |
-
0,
|
| 1320 |
-
0,
|
| 1321 |
-
0,
|
| 1322 |
-
0,
|
| 1323 |
-
0,
|
| 1324 |
-
0,
|
| 1325 |
-
0,
|
| 1326 |
-
0,
|
| 1327 |
-
0,
|
| 1328 |
-
0,
|
| 1329 |
-
0,
|
| 1330 |
-
0,
|
| 1331 |
-
0,
|
| 1332 |
-
0,
|
| 1333 |
-
0,
|
| 1334 |
-
0,
|
| 1335 |
-
0,
|
| 1336 |
-
0,
|
| 1337 |
-
0,
|
| 1338 |
-
0,
|
| 1339 |
-
0,
|
| 1340 |
-
0,
|
| 1341 |
-
0,
|
| 1342 |
-
0,
|
| 1343 |
-
0
|
| 1344 |
-
],
|
| 1345 |
-
[
|
| 1346 |
-
0,
|
| 1347 |
-
0,
|
| 1348 |
-
0,
|
| 1349 |
-
0,
|
| 1350 |
-
0,
|
| 1351 |
-
0,
|
| 1352 |
-
0,
|
| 1353 |
-
0,
|
| 1354 |
-
0,
|
| 1355 |
-
0,
|
| 1356 |
-
0,
|
| 1357 |
-
0,
|
| 1358 |
-
0,
|
| 1359 |
-
0,
|
| 1360 |
-
0,
|
| 1361 |
-
0,
|
| 1362 |
-
0,
|
| 1363 |
-
0,
|
| 1364 |
-
0,
|
| 1365 |
-
0,
|
| 1366 |
-
0,
|
| 1367 |
-
0,
|
| 1368 |
-
0,
|
| 1369 |
-
0,
|
| 1370 |
-
0,
|
| 1371 |
-
0,
|
| 1372 |
-
0,
|
| 1373 |
-
0,
|
| 1374 |
-
0,
|
| 1375 |
-
0,
|
| 1376 |
-
0,
|
| 1377 |
-
0,
|
| 1378 |
-
0,
|
| 1379 |
-
0,
|
| 1380 |
-
2
|
| 1381 |
-
],
|
| 1382 |
-
[
|
| 1383 |
-
0,
|
| 1384 |
-
0,
|
| 1385 |
-
0,
|
| 1386 |
-
0,
|
| 1387 |
-
1,
|
| 1388 |
-
0,
|
| 1389 |
-
0,
|
| 1390 |
-
0,
|
| 1391 |
-
0,
|
| 1392 |
-
0,
|
| 1393 |
-
0,
|
| 1394 |
-
0,
|
| 1395 |
-
0,
|
| 1396 |
-
0,
|
| 1397 |
-
0,
|
| 1398 |
-
0,
|
| 1399 |
-
0,
|
| 1400 |
-
0,
|
| 1401 |
-
0,
|
| 1402 |
-
0,
|
| 1403 |
-
0,
|
| 1404 |
-
0,
|
| 1405 |
-
0,
|
| 1406 |
-
0,
|
| 1407 |
-
0,
|
| 1408 |
-
0,
|
| 1409 |
-
0,
|
| 1410 |
-
0,
|
| 1411 |
-
0,
|
| 1412 |
-
0,
|
| 1413 |
-
0,
|
| 1414 |
-
0,
|
| 1415 |
-
0,
|
| 1416 |
-
0,
|
| 1417 |
-
0
|
| 1418 |
-
],
|
| 1419 |
-
[
|
| 1420 |
-
0,
|
| 1421 |
-
0,
|
| 1422 |
-
0,
|
| 1423 |
-
0,
|
| 1424 |
-
0,
|
| 1425 |
-
0,
|
| 1426 |
-
0,
|
| 1427 |
-
0,
|
| 1428 |
-
0,
|
| 1429 |
-
0,
|
| 1430 |
-
0,
|
| 1431 |
-
0,
|
| 1432 |
-
0,
|
| 1433 |
-
0,
|
| 1434 |
-
0,
|
| 1435 |
-
0,
|
| 1436 |
-
0,
|
| 1437 |
-
0,
|
| 1438 |
-
0,
|
| 1439 |
-
0,
|
| 1440 |
-
0,
|
| 1441 |
-
0,
|
| 1442 |
-
0,
|
| 1443 |
-
0,
|
| 1444 |
-
0,
|
| 1445 |
-
0,
|
| 1446 |
-
0,
|
| 1447 |
-
0,
|
| 1448 |
-
0,
|
| 1449 |
-
0,
|
| 1450 |
-
0,
|
| 1451 |
-
0,
|
| 1452 |
-
0,
|
| 1453 |
-
0,
|
| 1454 |
-
0
|
| 1455 |
-
],
|
| 1456 |
-
[
|
| 1457 |
-
0,
|
| 1458 |
-
0,
|
| 1459 |
-
0,
|
| 1460 |
-
0,
|
| 1461 |
-
10,
|
| 1462 |
-
0,
|
| 1463 |
-
0,
|
| 1464 |
-
0,
|
| 1465 |
-
0,
|
| 1466 |
-
0,
|
| 1467 |
-
0,
|
| 1468 |
-
0,
|
| 1469 |
-
0,
|
| 1470 |
-
0,
|
| 1471 |
-
0,
|
| 1472 |
-
0,
|
| 1473 |
-
0,
|
| 1474 |
-
0,
|
| 1475 |
-
0,
|
| 1476 |
-
0,
|
| 1477 |
-
0,
|
| 1478 |
-
0,
|
| 1479 |
-
0,
|
| 1480 |
-
0,
|
| 1481 |
-
0,
|
| 1482 |
-
0,
|
| 1483 |
-
0,
|
| 1484 |
-
0,
|
| 1485 |
-
0,
|
| 1486 |
-
0,
|
| 1487 |
-
0,
|
| 1488 |
-
0,
|
| 1489 |
-
0,
|
| 1490 |
-
0,
|
| 1491 |
-
4
|
| 1492 |
-
],
|
| 1493 |
-
[
|
| 1494 |
-
0,
|
| 1495 |
-
0,
|
| 1496 |
-
0,
|
| 1497 |
-
0,
|
| 1498 |
-
4,
|
| 1499 |
-
0,
|
| 1500 |
-
7,
|
| 1501 |
-
0,
|
| 1502 |
-
0,
|
| 1503 |
-
0,
|
| 1504 |
-
0,
|
| 1505 |
-
0,
|
| 1506 |
-
0,
|
| 1507 |
-
0,
|
| 1508 |
-
0,
|
| 1509 |
-
0,
|
| 1510 |
-
0,
|
| 1511 |
-
0,
|
| 1512 |
-
0,
|
| 1513 |
-
0,
|
| 1514 |
-
0,
|
| 1515 |
-
0,
|
| 1516 |
-
0,
|
| 1517 |
-
0,
|
| 1518 |
-
0,
|
| 1519 |
-
0,
|
| 1520 |
-
0,
|
| 1521 |
-
1,
|
| 1522 |
-
0,
|
| 1523 |
-
0,
|
| 1524 |
-
0,
|
| 1525 |
-
0,
|
| 1526 |
-
0,
|
| 1527 |
-
0,
|
| 1528 |
-
126
|
| 1529 |
-
]
|
| 1530 |
-
]
|
| 1531 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,35 +0,0 @@
|
|
| 1 |
-
ACCOUNT#negative
|
| 2 |
-
CARD#negative
|
| 3 |
-
CARD#neutral
|
| 4 |
-
CARD#positive
|
| 5 |
-
CUSTOMER_SUPPORT#negative
|
| 6 |
-
CUSTOMER_SUPPORT#neutral
|
| 7 |
-
CUSTOMER_SUPPORT#positive
|
| 8 |
-
DISCOUNT#negative
|
| 9 |
-
DISCOUNT#neutral
|
| 10 |
-
DISCOUNT#positive
|
| 11 |
-
INTEREST_RATE#negative
|
| 12 |
-
INTEREST_RATE#neutral
|
| 13 |
-
INTEREST_RATE#positive
|
| 14 |
-
INTERNET_BANKING#negative
|
| 15 |
-
INTERNET_BANKING#neutral
|
| 16 |
-
INTERNET_BANKING#positive
|
| 17 |
-
LOAN#negative
|
| 18 |
-
LOAN#positive
|
| 19 |
-
MONEY_TRANSFER#negative
|
| 20 |
-
MONEY_TRANSFER#positive
|
| 21 |
-
OTHER#negative
|
| 22 |
-
OTHER#neutral
|
| 23 |
-
OTHER#positive
|
| 24 |
-
PAYMENT#negative
|
| 25 |
-
PAYMENT#positive
|
| 26 |
-
PROMOTION#negative
|
| 27 |
-
PROMOTION#neutral
|
| 28 |
-
PROMOTION#positive
|
| 29 |
-
SAVING#negative
|
| 30 |
-
SAVING#neutral
|
| 31 |
-
SAVING#positive
|
| 32 |
-
SECURITY#neutral
|
| 33 |
-
SECURITY#positive
|
| 34 |
-
TRADEMARK#negative
|
| 35 |
-
TRADEMARK#positive
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,62 +0,0 @@
|
|
| 1 |
-
2025-09-28 13:15:27,107 - INFO - Starting training run: 20250928_131527
|
| 2 |
-
2025-09-28 13:15:27,107 - INFO - Model: svc_linear
|
| 3 |
-
2025-09-28 13:15:27,107 - INFO - Max features: 20000
|
| 4 |
-
2025-09-28 13:15:27,107 - INFO - N-gram range: (1, 2)
|
| 5 |
-
2025-09-28 13:15:27,107 - INFO - Loading UTS2017_Bank aspect sentiment dataset...
|
| 6 |
-
2025-09-28 13:15:31,618 - INFO - Train samples: 1581
|
| 7 |
-
2025-09-28 13:15:31,618 - INFO - Test samples: 396
|
| 8 |
-
2025-09-28 13:15:31,618 - INFO - Unique labels: 35
|
| 9 |
-
2025-09-28 13:15:31,618 - INFO - Label distribution (train): {np.str_('ACCOUNT#negative'): np.int64(3), np.str_('CARD#negative'): np.int64(47), np.str_('CARD#neutral'): np.int64(1), np.str_('CARD#positive'): np.int64(10), np.str_('CUSTOMER_SUPPORT#negative'): np.int64(288), np.str_('CUSTOMER_SUPPORT#neutral'): np.int64(4), np.str_('CUSTOMER_SUPPORT#positive'): np.int64(328), np.str_('DISCOUNT#negative'): np.int64(13), np.str_('DISCOUNT#neutral'): np.int64(3), np.str_('DISCOUNT#positive'): np.int64(19), np.str_('INTEREST_RATE#negative'): np.int64(45), np.str_('INTEREST_RATE#neutral'): np.int64(1), np.str_('INTEREST_RATE#positive'): np.int64(4), np.str_('INTERNET_BANKING#negative'): np.int64(36), np.str_('INTERNET_BANKING#neutral'): np.int64(2), np.str_('INTERNET_BANKING#positive'): np.int64(19), np.str_('LOAN#negative'): np.int64(48), np.str_('LOAN#positive'): np.int64(13), np.str_('MONEY_TRANSFER#negative'): np.int64(24), np.str_('MONEY_TRANSFER#positive'): np.int64(5), np.str_('OTHER#negative'): np.int64(25), np.str_('OTHER#neutral'): np.int64(3), np.str_('OTHER#positive'): np.int64(26), np.str_('PAYMENT#negative'): np.int64(4), np.str_('PAYMENT#positive'): np.int64(8), np.str_('PROMOTION#negative'): np.int64(13), np.str_('PROMOTION#neutral'): np.int64(2), np.str_('PROMOTION#positive'): np.int64(28), np.str_('SAVING#negative'): np.int64(5), np.str_('SAVING#neutral'): np.int64(1), np.str_('SAVING#positive'): np.int64(4), np.str_('SECURITY#neutral'): np.int64(1), np.str_('SECURITY#positive'): np.int64(1), np.str_('TRADEMARK#negative'): np.int64(33), np.str_('TRADEMARK#positive'): np.int64(514)}
|
| 10 |
-
2025-09-28 13:15:31,618 - INFO - Label distribution (test): {np.str_('ACCOUNT#negative'): np.int64(2), np.str_('CARD#negative'): np.int64(7), np.str_('CARD#neutral'): np.int64(0), np.str_('CARD#positive'): np.int64(1), np.str_('CUSTOMER_SUPPORT#negative'): np.int64(75), np.str_('CUSTOMER_SUPPORT#neutral'): np.int64(1), np.str_('CUSTOMER_SUPPORT#positive'): np.int64(78), np.str_('DISCOUNT#negative'): np.int64(5), np.str_('DISCOUNT#neutral'): np.int64(1), np.str_('DISCOUNT#positive'): np.int64(0), np.str_('INTEREST_RATE#negative'): np.int64(10), np.str_('INTEREST_RATE#neutral'): np.int64(0), np.str_('INTEREST_RATE#positive'): np.int64(0), np.str_('INTERNET_BANKING#negative'): np.int64(12), np.str_('INTERNET_BANKING#neutral'): np.int64(0), np.str_('INTERNET_BANKING#positive'): np.int64(1), np.str_('LOAN#negative'): np.int64(13), np.str_('LOAN#positive'): np.int64(0), np.str_('MONEY_TRANSFER#negative'): np.int64(5), np.str_('MONEY_TRANSFER#positive'): np.int64(0), np.str_('OTHER#negative'): np.int64(10), np.str_('OTHER#neutral'): np.int64(1), np.str_('OTHER#positive'): np.int64(4), np.str_('PAYMENT#negative'): np.int64(0), np.str_('PAYMENT#positive'): np.int64(3), np.str_('PROMOTION#negative'): np.int64(4), np.str_('PROMOTION#neutral'): np.int64(1), np.str_('PROMOTION#positive'): np.int64(5), np.str_('SAVING#negative'): np.int64(1), np.str_('SAVING#neutral'): np.int64(0), np.str_('SAVING#positive'): np.int64(2), np.str_('SECURITY#neutral'): np.int64(1), np.str_('SECURITY#positive'): np.int64(0), np.str_('TRADEMARK#negative'): np.int64(14), np.str_('TRADEMARK#positive'): np.int64(138)}
|
| 11 |
-
2025-09-28 13:15:31,619 - INFO - Selected classifier: SVC
|
| 12 |
-
2025-09-28 13:15:31,619 - INFO - ============================================================
|
| 13 |
-
2025-09-28 13:15:31,619 - INFO - Training: UTS2017_Bank_AspectSentiment_SVC_feat20k_ngram1-2
|
| 14 |
-
2025-09-28 13:15:31,619 - INFO - ============================================================
|
| 15 |
-
2025-09-28 13:15:31,619 - INFO - Creating pipeline with max_features=20000, ngram_range=(1, 2)
|
| 16 |
-
2025-09-28 13:15:31,619 - INFO - Training model...
|
| 17 |
-
2025-09-28 13:15:39,357 - INFO - Training completed in 7.74 seconds
|
| 18 |
-
2025-09-28 13:15:39,357 - INFO - Evaluating on training set...
|
| 19 |
-
2025-09-28 13:15:39,803 - INFO - Training accuracy: 0.9431
|
| 20 |
-
2025-09-28 13:15:39,803 - INFO - Evaluating on test set...
|
| 21 |
-
2025-09-28 13:15:39,914 - INFO - Test accuracy: 0.7172
|
| 22 |
-
2025-09-28 13:15:39,914 - INFO - Prediction time: 0.11 seconds
|
| 23 |
-
2025-09-28 13:15:39,914 - INFO - Classification Report:
|
| 24 |
-
2025-09-28 13:15:39,918 - INFO - precision recall f1-score support
|
| 25 |
-
|
| 26 |
-
ACCOUNT#negative 0.00 0.00 0.00 2
|
| 27 |
-
CARD#negative 1.00 0.14 0.25 7
|
| 28 |
-
CARD#positive 0.00 0.00 0.00 1
|
| 29 |
-
CUSTOMER_SUPPORT#negative 0.49 0.96 0.65 75
|
| 30 |
-
CUSTOMER_SUPPORT#neutral 0.00 0.00 0.00 1
|
| 31 |
-
CUSTOMER_SUPPORT#positive 0.86 0.90 0.88 78
|
| 32 |
-
DISCOUNT#negative 0.00 0.00 0.00 5
|
| 33 |
-
DISCOUNT#neutral 0.00 0.00 0.00 1
|
| 34 |
-
DISCOUNT#positive 0.00 0.00 0.00 0
|
| 35 |
-
INTEREST_RATE#negative 0.56 0.50 0.53 10
|
| 36 |
-
INTERNET_BANKING#negative 0.00 0.00 0.00 12
|
| 37 |
-
INTERNET_BANKING#positive 0.00 0.00 0.00 1
|
| 38 |
-
LOAN#negative 0.88 0.54 0.67 13
|
| 39 |
-
MONEY_TRANSFER#negative 0.00 0.00 0.00 5
|
| 40 |
-
OTHER#negative 0.00 0.00 0.00 10
|
| 41 |
-
OTHER#neutral 0.00 0.00 0.00 1
|
| 42 |
-
OTHER#positive 0.67 0.50 0.57 4
|
| 43 |
-
PAYMENT#positive 0.00 0.00 0.00 3
|
| 44 |
-
PROMOTION#negative 0.00 0.00 0.00 4
|
| 45 |
-
PROMOTION#neutral 0.00 0.00 0.00 1
|
| 46 |
-
PROMOTION#positive 0.33 0.20 0.25 5
|
| 47 |
-
SAVING#negative 0.00 0.00 0.00 1
|
| 48 |
-
SAVING#positive 0.00 0.00 0.00 2
|
| 49 |
-
SECURITY#negative 0.00 0.00 0.00 1
|
| 50 |
-
SECURITY#neutral 0.00 0.00 0.00 1
|
| 51 |
-
TRADEMARK#negative 0.00 0.00 0.00 14
|
| 52 |
-
TRADEMARK#positive 0.89 0.91 0.90 138
|
| 53 |
-
|
| 54 |
-
accuracy 0.72 396
|
| 55 |
-
macro avg 0.21 0.17 0.17 396
|
| 56 |
-
weighted avg 0.65 0.72 0.66 396
|
| 57 |
-
|
| 58 |
-
2025-09-28 13:15:39,922 - INFO - Confusion Matrix shape: (35, 35)
|
| 59 |
-
2025-09-28 13:15:40,052 - INFO - Model saved to runs/20250928_131527/models/model.joblib
|
| 60 |
-
2025-09-28 13:15:40,181 - INFO - Model also saved as runs/20250928_131527/models/UTS2017_Bank_AspectSentiment_SVC_feat20k_ngram1-2.joblib
|
| 61 |
-
2025-09-28 13:15:40,181 - INFO - Label mapping saved to runs/20250928_131527/models/labels.txt
|
| 62 |
-
2025-09-28 13:15:40,182 - INFO - Metadata saved to runs/20250928_131527/metadata.json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"timestamp": "20250929_075333",
|
| 3 |
+
"dataset": "vlsp2016",
|
| 4 |
+
"dataset_name": "VLSP2016_Sentiment",
|
| 5 |
+
"config_name": "VLSP2016_Sentiment_LogisticRegression_feat20k_ngram1-2",
|
| 6 |
+
"model_name": "logistic",
|
| 7 |
+
"classifier": "LogisticRegression",
|
| 8 |
+
"max_features": 20000,
|
| 9 |
+
"ngram_range": [
|
| 10 |
+
1,
|
| 11 |
+
2
|
| 12 |
+
],
|
| 13 |
+
"split_ratio": 0.2,
|
| 14 |
+
"n_samples": null,
|
| 15 |
+
"train_samples": 5100,
|
| 16 |
+
"test_samples": 1050,
|
| 17 |
+
"unique_labels": 3,
|
| 18 |
+
"labels": [
|
| 19 |
+
"negative",
|
| 20 |
+
"neutral",
|
| 21 |
+
"positive"
|
| 22 |
+
],
|
| 23 |
+
"train_accuracy": 0.9205882352941176,
|
| 24 |
+
"test_accuracy": 0.7019047619047619,
|
| 25 |
+
"train_time": 0.7513909339904785,
|
| 26 |
+
"prediction_time": 0.03164172172546387,
|
| 27 |
+
"classification_report": {
|
| 28 |
+
"negative": {
|
| 29 |
+
"precision": 0.6843575418994413,
|
| 30 |
+
"recall": 0.7,
|
| 31 |
+
"f1-score": 0.692090395480226,
|
| 32 |
+
"support": 350.0
|
| 33 |
+
},
|
| 34 |
+
"neutral": {
|
| 35 |
+
"precision": 0.6522911051212938,
|
| 36 |
+
"recall": 0.6914285714285714,
|
| 37 |
+
"f1-score": 0.6712898751733704,
|
| 38 |
+
"support": 350.0
|
| 39 |
+
},
|
| 40 |
+
"positive": {
|
| 41 |
+
"precision": 0.778816199376947,
|
| 42 |
+
"recall": 0.7142857142857143,
|
| 43 |
+
"f1-score": 0.7451564828614009,
|
| 44 |
+
"support": 350.0
|
| 45 |
+
},
|
| 46 |
+
"accuracy": 0.7019047619047619,
|
| 47 |
+
"macro avg": {
|
| 48 |
+
"precision": 0.7051549487992274,
|
| 49 |
+
"recall": 0.7019047619047619,
|
| 50 |
+
"f1-score": 0.702845584504999,
|
| 51 |
+
"support": 1050.0
|
| 52 |
+
},
|
| 53 |
+
"weighted avg": {
|
| 54 |
+
"precision": 0.7051549487992275,
|
| 55 |
+
"recall": 0.7019047619047619,
|
| 56 |
+
"f1-score": 0.7028455845049991,
|
| 57 |
+
"support": 1050.0
|
| 58 |
+
}
|
| 59 |
+
},
|
| 60 |
+
"confusion_matrix": [
|
| 61 |
+
[
|
| 62 |
+
245,
|
| 63 |
+
70,
|
| 64 |
+
35
|
| 65 |
+
],
|
| 66 |
+
[
|
| 67 |
+
72,
|
| 68 |
+
242,
|
| 69 |
+
36
|
| 70 |
+
],
|
| 71 |
+
[
|
| 72 |
+
41,
|
| 73 |
+
59,
|
| 74 |
+
250
|
| 75 |
+
]
|
| 76 |
+
]
|
| 77 |
+
}
|
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5a1f7db895c7cce8e9dac4632d99f594bbaff87295008b061949ea03b7929c0d
|
| 3 |
+
size 1262400
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
negative
|
| 2 |
+
neutral
|
| 3 |
+
positive
|
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5a1f7db895c7cce8e9dac4632d99f594bbaff87295008b061949ea03b7929c0d
|
| 3 |
+
size 1262400
|
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2025-09-29 07:53:33,898 - INFO - Starting training run: 20250929_075333
|
| 2 |
+
2025-09-29 07:53:33,898 - INFO - Dataset: vlsp2016
|
| 3 |
+
2025-09-29 07:53:33,898 - INFO - Model: logistic
|
| 4 |
+
2025-09-29 07:53:33,898 - INFO - Max features: 20000
|
| 5 |
+
2025-09-29 07:53:33,898 - INFO - N-gram range: (1, 2)
|
| 6 |
+
2025-09-29 07:53:33,898 - INFO - Loading vlsp2016 dataset...
|
| 7 |
+
2025-09-29 07:53:38,896 - INFO - Train samples: 5100
|
| 8 |
+
2025-09-29 07:53:38,896 - INFO - Test samples: 1050
|
| 9 |
+
2025-09-29 07:53:38,896 - INFO - Unique labels: 3
|
| 10 |
+
2025-09-29 07:53:38,896 - INFO - Label distribution (train): {np.str_('negative'): np.int64(1700), np.str_('neutral'): np.int64(1700), np.str_('positive'): np.int64(1700)}
|
| 11 |
+
2025-09-29 07:53:38,896 - INFO - Label distribution (test): {np.str_('negative'): np.int64(350), np.str_('neutral'): np.int64(350), np.str_('positive'): np.int64(350)}
|
| 12 |
+
2025-09-29 07:53:38,896 - INFO - Selected classifier: LogisticRegression
|
| 13 |
+
2025-09-29 07:53:38,897 - INFO - ============================================================
|
| 14 |
+
2025-09-29 07:53:38,897 - INFO - Training: VLSP2016_Sentiment_LogisticRegression_feat20k_ngram1-2
|
| 15 |
+
2025-09-29 07:53:38,897 - INFO - ============================================================
|
| 16 |
+
2025-09-29 07:53:38,897 - INFO - Creating pipeline with max_features=20000, ngram_range=(1, 2)
|
| 17 |
+
2025-09-29 07:53:38,897 - INFO - Training model...
|
| 18 |
+
2025-09-29 07:53:39,648 - INFO - Training completed in 0.75 seconds
|
| 19 |
+
2025-09-29 07:53:39,648 - INFO - Evaluating on training set...
|
| 20 |
+
2025-09-29 07:53:39,963 - INFO - Training accuracy: 0.9206
|
| 21 |
+
2025-09-29 07:53:39,963 - INFO - Evaluating on test set...
|
| 22 |
+
2025-09-29 07:53:39,994 - INFO - Test accuracy: 0.7019
|
| 23 |
+
2025-09-29 07:53:39,994 - INFO - Prediction time: 0.03 seconds
|
| 24 |
+
2025-09-29 07:53:39,995 - INFO - Classification Report:
|
| 25 |
+
2025-09-29 07:53:39,999 - INFO - precision recall f1-score support
|
| 26 |
+
|
| 27 |
+
negative 0.68 0.70 0.69 350
|
| 28 |
+
neutral 0.65 0.69 0.67 350
|
| 29 |
+
positive 0.78 0.71 0.75 350
|
| 30 |
+
|
| 31 |
+
accuracy 0.70 1050
|
| 32 |
+
macro avg 0.71 0.70 0.70 1050
|
| 33 |
+
weighted avg 0.71 0.70 0.70 1050
|
| 34 |
+
|
| 35 |
+
2025-09-29 07:53:40,004 - INFO - Confusion Matrix shape: (3, 3)
|
| 36 |
+
2025-09-29 07:53:40,165 - INFO - Model saved to runs/20250929_075333/models/model.joblib
|
| 37 |
+
2025-09-29 07:53:40,402 - INFO - Model also saved as runs/20250929_075333/models/VLSP2016_Sentiment_LogisticRegression_feat20k_ngram1-2.joblib
|
| 38 |
+
2025-09-29 07:53:40,751 - INFO - Model exported as ./vlsp2016_sentiment_20250929_075333.joblib
|
| 39 |
+
2025-09-29 07:53:40,752 - INFO - Label mapping saved to runs/20250929_075333/models/labels.txt
|
| 40 |
+
2025-09-29 07:53:40,753 - INFO - Metadata saved to runs/20250929_075333/metadata.json
|
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"timestamp": "20250929_075529",
|
| 3 |
+
"dataset": "vlsp2016",
|
| 4 |
+
"dataset_name": "VLSP2016_Sentiment",
|
| 5 |
+
"config_name": "VLSP2016_Sentiment_SVC_feat20k_ngram1-2",
|
| 6 |
+
"model_name": "svc_linear",
|
| 7 |
+
"classifier": "SVC",
|
| 8 |
+
"max_features": 20000,
|
| 9 |
+
"ngram_range": [
|
| 10 |
+
1,
|
| 11 |
+
2
|
| 12 |
+
],
|
| 13 |
+
"split_ratio": 0.2,
|
| 14 |
+
"n_samples": null,
|
| 15 |
+
"train_samples": 5100,
|
| 16 |
+
"test_samples": 1050,
|
| 17 |
+
"unique_labels": 3,
|
| 18 |
+
"labels": [
|
| 19 |
+
"negative",
|
| 20 |
+
"neutral",
|
| 21 |
+
"positive"
|
| 22 |
+
],
|
| 23 |
+
"train_accuracy": 0.9456862745098039,
|
| 24 |
+
"test_accuracy": 0.7114285714285714,
|
| 25 |
+
"train_time": 24.953126907348633,
|
| 26 |
+
"prediction_time": 0.762152910232544,
|
| 27 |
+
"classification_report": {
|
| 28 |
+
"negative": {
|
| 29 |
+
"precision": 0.7030812324929971,
|
| 30 |
+
"recall": 0.7171428571428572,
|
| 31 |
+
"f1-score": 0.71004243281471,
|
| 32 |
+
"support": 350.0
|
| 33 |
+
},
|
| 34 |
+
"neutral": {
|
| 35 |
+
"precision": 0.648,
|
| 36 |
+
"recall": 0.6942857142857143,
|
| 37 |
+
"f1-score": 0.670344827586207,
|
| 38 |
+
"support": 350.0
|
| 39 |
+
},
|
| 40 |
+
"positive": {
|
| 41 |
+
"precision": 0.7955974842767296,
|
| 42 |
+
"recall": 0.7228571428571429,
|
| 43 |
+
"f1-score": 0.7574850299401198,
|
| 44 |
+
"support": 350.0
|
| 45 |
+
},
|
| 46 |
+
"accuracy": 0.7114285714285714,
|
| 47 |
+
"macro avg": {
|
| 48 |
+
"precision": 0.7155595722565756,
|
| 49 |
+
"recall": 0.7114285714285714,
|
| 50 |
+
"f1-score": 0.7126240967803456,
|
| 51 |
+
"support": 1050.0
|
| 52 |
+
},
|
| 53 |
+
"weighted avg": {
|
| 54 |
+
"precision": 0.7155595722565756,
|
| 55 |
+
"recall": 0.7114285714285714,
|
| 56 |
+
"f1-score": 0.7126240967803456,
|
| 57 |
+
"support": 1050.0
|
| 58 |
+
}
|
| 59 |
+
},
|
| 60 |
+
"confusion_matrix": [
|
| 61 |
+
[
|
| 62 |
+
251,
|
| 63 |
+
72,
|
| 64 |
+
27
|
| 65 |
+
],
|
| 66 |
+
[
|
| 67 |
+
69,
|
| 68 |
+
243,
|
| 69 |
+
38
|
| 70 |
+
],
|
| 71 |
+
[
|
| 72 |
+
37,
|
| 73 |
+
60,
|
| 74 |
+
253
|
| 75 |
+
]
|
| 76 |
+
]
|
| 77 |
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b2ab63a5ec8c8f53581bc13d84ecbbe9912e84111c8cc163b9b8c85351a7d0b9
|
| 3 |
+
size 2947220
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
negative
|
| 2 |
+
neutral
|
| 3 |
+
positive
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b2ab63a5ec8c8f53581bc13d84ecbbe9912e84111c8cc163b9b8c85351a7d0b9
|
| 3 |
+
size 2947220
|
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2025-09-29 07:55:29,277 - INFO - Starting training run: 20250929_075529
|
| 2 |
+
2025-09-29 07:55:29,277 - INFO - Dataset: vlsp2016
|
| 3 |
+
2025-09-29 07:55:29,277 - INFO - Model: svc_linear
|
| 4 |
+
2025-09-29 07:55:29,277 - INFO - Max features: 20000
|
| 5 |
+
2025-09-29 07:55:29,277 - INFO - N-gram range: (1, 2)
|
| 6 |
+
2025-09-29 07:55:29,277 - INFO - Loading vlsp2016 dataset...
|
| 7 |
+
2025-09-29 07:55:34,138 - INFO - Train samples: 5100
|
| 8 |
+
2025-09-29 07:55:34,138 - INFO - Test samples: 1050
|
| 9 |
+
2025-09-29 07:55:34,138 - INFO - Unique labels: 3
|
| 10 |
+
2025-09-29 07:55:34,138 - INFO - Label distribution (train): {np.str_('negative'): np.int64(1700), np.str_('neutral'): np.int64(1700), np.str_('positive'): np.int64(1700)}
|
| 11 |
+
2025-09-29 07:55:34,138 - INFO - Label distribution (test): {np.str_('negative'): np.int64(350), np.str_('neutral'): np.int64(350), np.str_('positive'): np.int64(350)}
|
| 12 |
+
2025-09-29 07:55:34,138 - INFO - Selected classifier: SVC
|
| 13 |
+
2025-09-29 07:55:34,138 - INFO - ============================================================
|
| 14 |
+
2025-09-29 07:55:34,138 - INFO - Training: VLSP2016_Sentiment_SVC_feat20k_ngram1-2
|
| 15 |
+
2025-09-29 07:55:34,138 - INFO - ============================================================
|
| 16 |
+
2025-09-29 07:55:34,138 - INFO - Creating pipeline with max_features=20000, ngram_range=(1, 2)
|
| 17 |
+
2025-09-29 07:55:34,138 - INFO - Training model...
|
| 18 |
+
2025-09-29 07:55:59,092 - INFO - Training completed in 24.95 seconds
|
| 19 |
+
2025-09-29 07:55:59,092 - INFO - Evaluating on training set...
|
| 20 |
+
2025-09-29 07:56:03,151 - INFO - Training accuracy: 0.9457
|
| 21 |
+
2025-09-29 07:56:03,151 - INFO - Evaluating on test set...
|
| 22 |
+
2025-09-29 07:56:03,913 - INFO - Test accuracy: 0.7114
|
| 23 |
+
2025-09-29 07:56:03,913 - INFO - Prediction time: 0.76 seconds
|
| 24 |
+
2025-09-29 07:56:03,913 - INFO - Classification Report:
|
| 25 |
+
2025-09-29 07:56:03,918 - INFO - precision recall f1-score support
|
| 26 |
+
|
| 27 |
+
negative 0.70 0.72 0.71 350
|
| 28 |
+
neutral 0.65 0.69 0.67 350
|
| 29 |
+
positive 0.80 0.72 0.76 350
|
| 30 |
+
|
| 31 |
+
accuracy 0.71 1050
|
| 32 |
+
macro avg 0.72 0.71 0.71 1050
|
| 33 |
+
weighted avg 0.72 0.71 0.71 1050
|
| 34 |
+
|
| 35 |
+
2025-09-29 07:56:03,923 - INFO - Confusion Matrix shape: (3, 3)
|
| 36 |
+
2025-09-29 07:56:04,043 - INFO - Model saved to runs/20250929_075529/models/model.joblib
|
| 37 |
+
2025-09-29 07:56:04,162 - INFO - Model also saved as runs/20250929_075529/models/VLSP2016_Sentiment_SVC_feat20k_ngram1-2.joblib
|
| 38 |
+
2025-09-29 07:56:04,294 - INFO - Model exported as ./vlsp2016_sentiment_20250929_075529.joblib
|
| 39 |
+
2025-09-29 07:56:04,295 - INFO - Label mapping saved to runs/20250929_075529/models/labels.txt
|
| 40 |
+
2025-09-29 07:56:04,295 - INFO - Metadata saved to runs/20250929_075529/metadata.json
|
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"timestamp": "20250929_075901",
|
| 3 |
+
"dataset": "vlsp2016",
|
| 4 |
+
"dataset_name": "VLSP2016_Sentiment",
|
| 5 |
+
"config_name": "VLSP2016_Sentiment_SVC_feat20k_ngram1-3",
|
| 6 |
+
"model_name": "svc_linear",
|
| 7 |
+
"classifier": "SVC",
|
| 8 |
+
"max_features": 20000,
|
| 9 |
+
"ngram_range": [
|
| 10 |
+
1,
|
| 11 |
+
3
|
| 12 |
+
],
|
| 13 |
+
"split_ratio": 0.2,
|
| 14 |
+
"n_samples": null,
|
| 15 |
+
"train_samples": 5100,
|
| 16 |
+
"test_samples": 1050,
|
| 17 |
+
"unique_labels": 3,
|
| 18 |
+
"labels": [
|
| 19 |
+
"negative",
|
| 20 |
+
"neutral",
|
| 21 |
+
"positive"
|
| 22 |
+
],
|
| 23 |
+
"train_accuracy": 0.9425490196078431,
|
| 24 |
+
"test_accuracy": 0.7066666666666667,
|
| 25 |
+
"train_time": 25.364684104919434,
|
| 26 |
+
"prediction_time": 0.7415199279785156,
|
| 27 |
+
"classification_report": {
|
| 28 |
+
"negative": {
|
| 29 |
+
"precision": 0.6988950276243094,
|
| 30 |
+
"recall": 0.7228571428571429,
|
| 31 |
+
"f1-score": 0.7106741573033708,
|
| 32 |
+
"support": 350.0
|
| 33 |
+
},
|
| 34 |
+
"neutral": {
|
| 35 |
+
"precision": 0.6485013623978202,
|
| 36 |
+
"recall": 0.68,
|
| 37 |
+
"f1-score": 0.6638772663877266,
|
| 38 |
+
"support": 350.0
|
| 39 |
+
},
|
| 40 |
+
"positive": {
|
| 41 |
+
"precision": 0.7819314641744548,
|
| 42 |
+
"recall": 0.7171428571428572,
|
| 43 |
+
"f1-score": 0.7481371087928465,
|
| 44 |
+
"support": 350.0
|
| 45 |
+
},
|
| 46 |
+
"accuracy": 0.7066666666666667,
|
| 47 |
+
"macro avg": {
|
| 48 |
+
"precision": 0.7097759513988615,
|
| 49 |
+
"recall": 0.7066666666666667,
|
| 50 |
+
"f1-score": 0.7075628441613145,
|
| 51 |
+
"support": 1050.0
|
| 52 |
+
},
|
| 53 |
+
"weighted avg": {
|
| 54 |
+
"precision": 0.7097759513988614,
|
| 55 |
+
"recall": 0.7066666666666667,
|
| 56 |
+
"f1-score": 0.7075628441613147,
|
| 57 |
+
"support": 1050.0
|
| 58 |
+
}
|
| 59 |
+
},
|
| 60 |
+
"confusion_matrix": [
|
| 61 |
+
[
|
| 62 |
+
253,
|
| 63 |
+
68,
|
| 64 |
+
29
|
| 65 |
+
],
|
| 66 |
+
[
|
| 67 |
+
71,
|
| 68 |
+
238,
|
| 69 |
+
41
|
| 70 |
+
],
|
| 71 |
+
[
|
| 72 |
+
38,
|
| 73 |
+
61,
|
| 74 |
+
251
|
| 75 |
+
]
|
| 76 |
+
]
|
| 77 |
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1743c4adf26bd8d1e118fe4de9409cea4219c5357edd7b57910cfe01afc43c20
|
| 3 |
+
size 3019140
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
negative
|
| 2 |
+
neutral
|
| 3 |
+
positive
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1743c4adf26bd8d1e118fe4de9409cea4219c5357edd7b57910cfe01afc43c20
|
| 3 |
+
size 3019140
|
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2025-09-29 07:59:01,513 - INFO - Starting training run: 20250929_075901
|
| 2 |
+
2025-09-29 07:59:01,513 - INFO - Dataset: vlsp2016
|
| 3 |
+
2025-09-29 07:59:01,513 - INFO - Model: svc_linear
|
| 4 |
+
2025-09-29 07:59:01,513 - INFO - Max features: 20000
|
| 5 |
+
2025-09-29 07:59:01,513 - INFO - N-gram range: (1, 3)
|
| 6 |
+
2025-09-29 07:59:01,513 - INFO - Loading vlsp2016 dataset...
|
| 7 |
+
2025-09-29 07:59:05,847 - INFO - Train samples: 5100
|
| 8 |
+
2025-09-29 07:59:05,847 - INFO - Test samples: 1050
|
| 9 |
+
2025-09-29 07:59:05,848 - INFO - Unique labels: 3
|
| 10 |
+
2025-09-29 07:59:05,848 - INFO - Label distribution (train): {np.str_('negative'): np.int64(1700), np.str_('neutral'): np.int64(1700), np.str_('positive'): np.int64(1700)}
|
| 11 |
+
2025-09-29 07:59:05,848 - INFO - Label distribution (test): {np.str_('negative'): np.int64(350), np.str_('neutral'): np.int64(350), np.str_('positive'): np.int64(350)}
|
| 12 |
+
2025-09-29 07:59:05,848 - INFO - Selected classifier: SVC
|
| 13 |
+
2025-09-29 07:59:05,848 - INFO - ============================================================
|
| 14 |
+
2025-09-29 07:59:05,848 - INFO - Training: VLSP2016_Sentiment_SVC_feat20k_ngram1-3
|
| 15 |
+
2025-09-29 07:59:05,848 - INFO - ============================================================
|
| 16 |
+
2025-09-29 07:59:05,848 - INFO - Creating pipeline with max_features=20000, ngram_range=(1, 3)
|
| 17 |
+
2025-09-29 07:59:05,849 - INFO - Training model...
|
| 18 |
+
2025-09-29 07:59:31,214 - INFO - Training completed in 25.36 seconds
|
| 19 |
+
2025-09-29 07:59:31,214 - INFO - Evaluating on training set...
|
| 20 |
+
2025-09-29 07:59:35,246 - INFO - Training accuracy: 0.9425
|
| 21 |
+
2025-09-29 07:59:35,246 - INFO - Evaluating on test set...
|
| 22 |
+
2025-09-29 07:59:35,987 - INFO - Test accuracy: 0.7067
|
| 23 |
+
2025-09-29 07:59:35,987 - INFO - Prediction time: 0.74 seconds
|
| 24 |
+
2025-09-29 07:59:35,987 - INFO - Classification Report:
|
| 25 |
+
2025-09-29 07:59:35,992 - INFO - precision recall f1-score support
|
| 26 |
+
|
| 27 |
+
negative 0.70 0.72 0.71 350
|
| 28 |
+
neutral 0.65 0.68 0.66 350
|
| 29 |
+
positive 0.78 0.72 0.75 350
|
| 30 |
+
|
| 31 |
+
accuracy 0.71 1050
|
| 32 |
+
macro avg 0.71 0.71 0.71 1050
|
| 33 |
+
weighted avg 0.71 0.71 0.71 1050
|
| 34 |
+
|
| 35 |
+
2025-09-29 07:59:35,997 - INFO - Confusion Matrix shape: (3, 3)
|
| 36 |
+
2025-09-29 07:59:36,117 - INFO - Model saved to runs/20250929_075901/models/model.joblib
|
| 37 |
+
2025-09-29 07:59:36,233 - INFO - Model also saved as runs/20250929_075901/models/VLSP2016_Sentiment_SVC_feat20k_ngram1-3.joblib
|
| 38 |
+
2025-09-29 07:59:36,351 - INFO - Model exported as ./vlsp2016_sentiment_20250929_075901.joblib
|
| 39 |
+
2025-09-29 07:59:36,352 - INFO - Label mapping saved to runs/20250929_075901/models/labels.txt
|
| 40 |
+
2025-09-29 07:59:36,352 - INFO - Metadata saved to runs/20250929_075901/metadata.json
|
|
@@ -1,8 +1,8 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
-
Training script for Vietnamese
|
| 4 |
-
Trains TF-IDF + ML models on
|
| 5 |
-
This script trains various machine learning models for Vietnamese
|
| 6 |
"""
|
| 7 |
|
| 8 |
import argparse
|
|
@@ -86,8 +86,13 @@ def load_uts2017_data(split_ratio=0.2, random_state=42, n_samples=None):
|
|
| 86 |
|
| 87 |
# Apply sample limit if specified
|
| 88 |
if n_samples and n_samples < len(texts):
|
| 89 |
-
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
|
| 92 |
# Convert to numpy arrays for consistency
|
| 93 |
X = np.array(texts)
|
|
@@ -117,6 +122,99 @@ def load_uts2017_data(split_ratio=0.2, random_state=42, n_samples=None):
|
|
| 117 |
return (X_train, y_train), (X_test, y_test)
|
| 118 |
|
| 119 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
def get_available_models():
|
| 121 |
"""Get available classifier options"""
|
| 122 |
return {
|
|
@@ -139,7 +237,35 @@ def get_available_models():
|
|
| 139 |
}
|
| 140 |
|
| 141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
def train_model(
|
|
|
|
| 143 |
model_name="logistic",
|
| 144 |
max_features=20000,
|
| 145 |
ngram_range=(1, 2),
|
|
@@ -149,6 +275,7 @@ def train_model(
|
|
| 149 |
):
|
| 150 |
"""Train a single model with specified parameters
|
| 151 |
Args:
|
|
|
|
| 152 |
model_name: Name of the model to train ('logistic' or 'svc')
|
| 153 |
max_features: Maximum number of features for TF-IDF vectorizer
|
| 154 |
ngram_range: N-gram range for feature extraction
|
|
@@ -162,6 +289,7 @@ def train_model(
|
|
| 162 |
run_dir = setup_logging(timestamp)
|
| 163 |
|
| 164 |
logging.info(f"Starting training run: {timestamp}")
|
|
|
|
| 165 |
logging.info(f"Model: {model_name}")
|
| 166 |
logging.info(f"Max features: {max_features}")
|
| 167 |
logging.info(f"N-gram range: {ngram_range}")
|
|
@@ -173,11 +301,10 @@ def train_model(
|
|
| 173 |
os.makedirs(output_folder, exist_ok=True)
|
| 174 |
|
| 175 |
# Load data
|
| 176 |
-
logging.info("Loading
|
| 177 |
-
(X_train, y_train), (X_test, y_test) =
|
| 178 |
-
split_ratio=split_ratio, n_samples=n_samples
|
| 179 |
)
|
| 180 |
-
dataset_name = "UTS2017_Bank_AspectSentiment"
|
| 181 |
|
| 182 |
# Get unique labels for reporting
|
| 183 |
unique_labels = sorted(set(y_train))
|
|
@@ -275,9 +402,10 @@ def train_model(
|
|
| 275 |
|
| 276 |
# Export model if requested
|
| 277 |
if export_model:
|
| 278 |
-
# Use format:
|
| 279 |
run_id = os.path.basename(run_dir)
|
| 280 |
-
|
|
|
|
| 281 |
export_path = os.path.join(".", export_filename)
|
| 282 |
joblib.dump(text_clf, export_path)
|
| 283 |
logging.info(f"Model exported as {export_path}")
|
|
@@ -293,6 +421,8 @@ def train_model(
|
|
| 293 |
# Save metadata
|
| 294 |
metadata = {
|
| 295 |
"timestamp": timestamp,
|
|
|
|
|
|
|
| 296 |
"config_name": config_name,
|
| 297 |
"model_name": model_name,
|
| 298 |
"classifier": clf_name,
|
|
@@ -334,13 +464,13 @@ def train_model(
|
|
| 334 |
return metadata
|
| 335 |
|
| 336 |
|
| 337 |
-
def train_all_configurations(models=None, num_rows=None):
|
| 338 |
"""Train multiple model configurations and compare results"""
|
| 339 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 340 |
run_dir = setup_logging(timestamp)
|
| 341 |
|
| 342 |
logging.info(f"Starting comparison run: {timestamp}")
|
| 343 |
-
logging.info("Dataset:
|
| 344 |
if num_rows:
|
| 345 |
logging.info(f"Sample limit: {num_rows}")
|
| 346 |
|
|
@@ -357,6 +487,7 @@ def train_all_configurations(models=None, num_rows=None):
|
|
| 357 |
if model_name in ["svc_rbf", "gradient_boost", "ada_boost", "mlp"]:
|
| 358 |
# Use fewer features for computationally expensive models
|
| 359 |
configurations.append({
|
|
|
|
| 360 |
"model_name": model_name,
|
| 361 |
"max_features": 10000,
|
| 362 |
"ngram_range": (1, 2),
|
|
@@ -365,6 +496,7 @@ def train_all_configurations(models=None, num_rows=None):
|
|
| 365 |
else:
|
| 366 |
# Use more features for faster models
|
| 367 |
configurations.append({
|
|
|
|
| 368 |
"model_name": model_name,
|
| 369 |
"max_features": 20000,
|
| 370 |
"ngram_range": (1, 2),
|
|
@@ -416,22 +548,23 @@ def train_all_configurations(models=None, num_rows=None):
|
|
| 416 |
return results
|
| 417 |
|
| 418 |
|
| 419 |
-
def train_notebook(model_name="logistic", max_features=20000, ngram_min=1, ngram_max=2,
|
| 420 |
split_ratio=0.2, n_samples=None, compare=False, export_model=False):
|
| 421 |
"""
|
| 422 |
Convenience function for training in Jupyter/Colab notebooks without argparse.
|
| 423 |
Example usage:
|
| 424 |
from train import train_notebook
|
| 425 |
-
train_notebook(model_name="logistic", max_features=20000, export_model=True)
|
| 426 |
"""
|
| 427 |
if compare:
|
| 428 |
-
print("Training and comparing multiple configurations...")
|
| 429 |
-
return train_all_configurations()
|
| 430 |
else:
|
| 431 |
-
print(f"Training {model_name} model on
|
| 432 |
print(f"Configuration: max_features={max_features}, ngram=({ngram_min}, {ngram_max})")
|
| 433 |
|
| 434 |
return train_model(
|
|
|
|
| 435 |
model_name=model_name,
|
| 436 |
max_features=max_features,
|
| 437 |
ngram_range=(ngram_min, ngram_max),
|
|
@@ -448,7 +581,14 @@ def main():
|
|
| 448 |
in_notebook = hasattr(sys, 'ps1') or 'ipykernel' in sys.modules or 'google.colab' in sys.modules
|
| 449 |
|
| 450 |
parser = argparse.ArgumentParser(
|
| 451 |
-
description="Train Vietnamese
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
)
|
| 453 |
parser.add_argument(
|
| 454 |
"--model",
|
|
@@ -505,23 +645,24 @@ def main():
|
|
| 505 |
if args.compare or args.compare_models:
|
| 506 |
if args.compare_models:
|
| 507 |
print(f"Training and comparing selected models: {args.compare_models}")
|
| 508 |
-
print("Dataset:
|
| 509 |
if args.num_rows:
|
| 510 |
print(f"Using {args.num_rows} rows")
|
| 511 |
-
train_all_configurations(models=args.compare_models, num_rows=args.num_rows)
|
| 512 |
else:
|
| 513 |
print("Training and comparing all available models...")
|
| 514 |
-
print("Dataset:
|
| 515 |
if args.num_rows:
|
| 516 |
print(f"Using {args.num_rows} rows")
|
| 517 |
-
train_all_configurations(num_rows=args.num_rows)
|
| 518 |
else:
|
| 519 |
-
print(f"Training {args.model} model on
|
| 520 |
print(
|
| 521 |
f"Configuration: max_features={args.max_features}, ngram=({args.ngram_min}, {args.ngram_max})"
|
| 522 |
)
|
| 523 |
|
| 524 |
train_model(
|
|
|
|
| 525 |
model_name=args.model,
|
| 526 |
max_features=args.max_features,
|
| 527 |
ngram_range=(args.ngram_min, args.ngram_max),
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
+
Training script for Vietnamese sentiment classification.
|
| 4 |
+
Trains TF-IDF + ML models on VLSP2016 sentiment dataset.
|
| 5 |
+
This script trains various machine learning models for Vietnamese sentiment analysis.
|
| 6 |
"""
|
| 7 |
|
| 8 |
import argparse
|
|
|
|
| 86 |
|
| 87 |
# Apply sample limit if specified
|
| 88 |
if n_samples and n_samples < len(texts):
|
| 89 |
+
# Shuffle before sampling to get balanced classes
|
| 90 |
+
indices = np.arange(len(texts))
|
| 91 |
+
np.random.seed(random_state)
|
| 92 |
+
np.random.shuffle(indices)
|
| 93 |
+
indices = indices[:n_samples]
|
| 94 |
+
texts = [texts[i] for i in indices]
|
| 95 |
+
labels = [labels[i] for i in indices]
|
| 96 |
|
| 97 |
# Convert to numpy arrays for consistency
|
| 98 |
X = np.array(texts)
|
|
|
|
| 122 |
return (X_train, y_train), (X_test, y_test)
|
| 123 |
|
| 124 |
|
| 125 |
+
def load_vlsp2016_data(use_predefined_split=True, split_ratio=0.2, random_state=42, n_samples=None):
|
| 126 |
+
"""Load and prepare VLSP2016 sentiment dataset
|
| 127 |
+
Args:
|
| 128 |
+
use_predefined_split: If True, use the predefined train/test split from the dataset
|
| 129 |
+
split_ratio: Ratio for train/test split (only used if use_predefined_split is False)
|
| 130 |
+
random_state: Random seed for reproducibility
|
| 131 |
+
n_samples: Optional limit on number of samples
|
| 132 |
+
Returns:
|
| 133 |
+
Tuple of (X_train, y_train), (X_test, y_test)
|
| 134 |
+
"""
|
| 135 |
+
print("Loading VLSP2016 sentiment dataset from Hugging Face...")
|
| 136 |
+
|
| 137 |
+
# Load the dataset
|
| 138 |
+
dataset = load_dataset("ura-hcmut/vlsp2016")
|
| 139 |
+
|
| 140 |
+
if use_predefined_split:
|
| 141 |
+
# Use the predefined train/test split
|
| 142 |
+
train_data = dataset["train"]
|
| 143 |
+
test_data = dataset["test"]
|
| 144 |
+
|
| 145 |
+
# Extract texts and labels
|
| 146 |
+
X_train = [item["Data"] for item in train_data]
|
| 147 |
+
y_train = [item["Class"] for item in train_data]
|
| 148 |
+
X_test = [item["Data"] for item in test_data]
|
| 149 |
+
y_test = [item["Class"] for item in test_data]
|
| 150 |
+
|
| 151 |
+
# Apply sample limit if specified
|
| 152 |
+
if n_samples:
|
| 153 |
+
if n_samples < len(X_train):
|
| 154 |
+
# Shuffle before sampling to get balanced classes
|
| 155 |
+
indices = np.arange(len(X_train))
|
| 156 |
+
np.random.seed(random_state)
|
| 157 |
+
np.random.shuffle(indices)
|
| 158 |
+
indices = indices[:n_samples]
|
| 159 |
+
X_train = [X_train[i] for i in indices]
|
| 160 |
+
y_train = [y_train[i] for i in indices]
|
| 161 |
+
if n_samples < len(X_test):
|
| 162 |
+
# Proportionally reduce test set with shuffling
|
| 163 |
+
test_samples = int(n_samples * 0.2) # Keep similar ratio
|
| 164 |
+
indices = np.arange(len(X_test))
|
| 165 |
+
np.random.seed(random_state)
|
| 166 |
+
np.random.shuffle(indices)
|
| 167 |
+
indices = indices[:test_samples]
|
| 168 |
+
X_test = [X_test[i] for i in indices]
|
| 169 |
+
y_test = [y_test[i] for i in indices]
|
| 170 |
+
|
| 171 |
+
# Convert to numpy arrays
|
| 172 |
+
X_train = np.array(X_train)
|
| 173 |
+
y_train = np.array(y_train)
|
| 174 |
+
X_test = np.array(X_test)
|
| 175 |
+
y_test = np.array(y_test)
|
| 176 |
+
else:
|
| 177 |
+
# Combine train and test, then create custom split
|
| 178 |
+
all_data = list(dataset["train"]) + list(dataset["test"])
|
| 179 |
+
|
| 180 |
+
# Extract texts and labels
|
| 181 |
+
texts = [item["Data"] for item in all_data]
|
| 182 |
+
labels = [item["Class"] for item in all_data]
|
| 183 |
+
|
| 184 |
+
# Apply sample limit if specified
|
| 185 |
+
if n_samples and n_samples < len(texts):
|
| 186 |
+
texts = texts[:n_samples]
|
| 187 |
+
labels = labels[:n_samples]
|
| 188 |
+
|
| 189 |
+
# Convert to numpy arrays
|
| 190 |
+
X = np.array(texts)
|
| 191 |
+
y = np.array(labels)
|
| 192 |
+
|
| 193 |
+
# Split into train and test sets
|
| 194 |
+
# Use stratify only if we have enough samples per class (at least 2)
|
| 195 |
+
min_samples_per_class = 2
|
| 196 |
+
unique_classes, class_counts = np.unique(y, return_counts=True)
|
| 197 |
+
can_stratify = all(count >= min_samples_per_class for count in class_counts)
|
| 198 |
+
|
| 199 |
+
if can_stratify:
|
| 200 |
+
X_train, X_test, y_train, y_test = train_test_split(
|
| 201 |
+
X, y, test_size=split_ratio, random_state=random_state, stratify=y
|
| 202 |
+
)
|
| 203 |
+
else:
|
| 204 |
+
print(
|
| 205 |
+
f"Warning: Some classes have fewer than {min_samples_per_class} samples. Disabling stratification."
|
| 206 |
+
)
|
| 207 |
+
X_train, X_test, y_train, y_test = train_test_split(
|
| 208 |
+
X, y, test_size=split_ratio, random_state=random_state
|
| 209 |
+
)
|
| 210 |
+
|
| 211 |
+
print(f"Dataset loaded: {len(X_train)} train samples, {len(X_test)} test samples")
|
| 212 |
+
print(f"Number of unique labels: {len(set(y_train))}")
|
| 213 |
+
print(f"Labels: {sorted(set(y_train))}")
|
| 214 |
+
|
| 215 |
+
return (X_train, y_train), (X_test, y_test)
|
| 216 |
+
|
| 217 |
+
|
| 218 |
def get_available_models():
|
| 219 |
"""Get available classifier options"""
|
| 220 |
return {
|
|
|
|
| 237 |
}
|
| 238 |
|
| 239 |
|
| 240 |
+
def load_data(dataset_name="vlsp2016", split_ratio=0.2, random_state=42, n_samples=None):
|
| 241 |
+
"""Load data from the specified dataset
|
| 242 |
+
Args:
|
| 243 |
+
dataset_name: Name of the dataset to load ('vlsp2016' or 'uts2017')
|
| 244 |
+
split_ratio: Ratio for train/test split
|
| 245 |
+
random_state: Random seed for reproducibility
|
| 246 |
+
n_samples: Optional limit on number of samples
|
| 247 |
+
Returns:
|
| 248 |
+
Tuple of (X_train, y_train), (X_test, y_test), dataset_display_name
|
| 249 |
+
"""
|
| 250 |
+
if dataset_name.lower() == "vlsp2016":
|
| 251 |
+
(X_train, y_train), (X_test, y_test) = load_vlsp2016_data(
|
| 252 |
+
use_predefined_split=True, split_ratio=split_ratio,
|
| 253 |
+
random_state=random_state, n_samples=n_samples
|
| 254 |
+
)
|
| 255 |
+
display_name = "VLSP2016_Sentiment"
|
| 256 |
+
elif dataset_name.lower() == "uts2017":
|
| 257 |
+
(X_train, y_train), (X_test, y_test) = load_uts2017_data(
|
| 258 |
+
split_ratio=split_ratio, random_state=random_state, n_samples=n_samples
|
| 259 |
+
)
|
| 260 |
+
display_name = "UTS2017_Bank_AspectSentiment"
|
| 261 |
+
else:
|
| 262 |
+
raise ValueError(f"Unknown dataset: {dataset_name}. Choose 'vlsp2016' or 'uts2017'")
|
| 263 |
+
|
| 264 |
+
return (X_train, y_train), (X_test, y_test), display_name
|
| 265 |
+
|
| 266 |
+
|
| 267 |
def train_model(
|
| 268 |
+
dataset="vlsp2016",
|
| 269 |
model_name="logistic",
|
| 270 |
max_features=20000,
|
| 271 |
ngram_range=(1, 2),
|
|
|
|
| 275 |
):
|
| 276 |
"""Train a single model with specified parameters
|
| 277 |
Args:
|
| 278 |
+
dataset: Name of the dataset to use ('vlsp2016' or 'uts2017')
|
| 279 |
model_name: Name of the model to train ('logistic' or 'svc')
|
| 280 |
max_features: Maximum number of features for TF-IDF vectorizer
|
| 281 |
ngram_range: N-gram range for feature extraction
|
|
|
|
| 289 |
run_dir = setup_logging(timestamp)
|
| 290 |
|
| 291 |
logging.info(f"Starting training run: {timestamp}")
|
| 292 |
+
logging.info(f"Dataset: {dataset}")
|
| 293 |
logging.info(f"Model: {model_name}")
|
| 294 |
logging.info(f"Max features: {max_features}")
|
| 295 |
logging.info(f"N-gram range: {ngram_range}")
|
|
|
|
| 301 |
os.makedirs(output_folder, exist_ok=True)
|
| 302 |
|
| 303 |
# Load data
|
| 304 |
+
logging.info(f"Loading {dataset} dataset...")
|
| 305 |
+
(X_train, y_train), (X_test, y_test), dataset_name = load_data(
|
| 306 |
+
dataset_name=dataset, split_ratio=split_ratio, random_state=42, n_samples=n_samples
|
| 307 |
)
|
|
|
|
| 308 |
|
| 309 |
# Get unique labels for reporting
|
| 310 |
unique_labels = sorted(set(y_train))
|
|
|
|
| 402 |
|
| 403 |
# Export model if requested
|
| 404 |
if export_model:
|
| 405 |
+
# Use format: <dataset>_sentiment_<timestamp>.joblib
|
| 406 |
run_id = os.path.basename(run_dir)
|
| 407 |
+
dataset_prefix = dataset.lower()
|
| 408 |
+
export_filename = f"{dataset_prefix}_sentiment_{run_id}.joblib"
|
| 409 |
export_path = os.path.join(".", export_filename)
|
| 410 |
joblib.dump(text_clf, export_path)
|
| 411 |
logging.info(f"Model exported as {export_path}")
|
|
|
|
| 421 |
# Save metadata
|
| 422 |
metadata = {
|
| 423 |
"timestamp": timestamp,
|
| 424 |
+
"dataset": dataset,
|
| 425 |
+
"dataset_name": dataset_name,
|
| 426 |
"config_name": config_name,
|
| 427 |
"model_name": model_name,
|
| 428 |
"classifier": clf_name,
|
|
|
|
| 464 |
return metadata
|
| 465 |
|
| 466 |
|
| 467 |
+
def train_all_configurations(dataset="vlsp2016", models=None, num_rows=None):
|
| 468 |
"""Train multiple model configurations and compare results"""
|
| 469 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 470 |
run_dir = setup_logging(timestamp)
|
| 471 |
|
| 472 |
logging.info(f"Starting comparison run: {timestamp}")
|
| 473 |
+
logging.info(f"Dataset: {dataset}")
|
| 474 |
if num_rows:
|
| 475 |
logging.info(f"Sample limit: {num_rows}")
|
| 476 |
|
|
|
|
| 487 |
if model_name in ["svc_rbf", "gradient_boost", "ada_boost", "mlp"]:
|
| 488 |
# Use fewer features for computationally expensive models
|
| 489 |
configurations.append({
|
| 490 |
+
"dataset": dataset,
|
| 491 |
"model_name": model_name,
|
| 492 |
"max_features": 10000,
|
| 493 |
"ngram_range": (1, 2),
|
|
|
|
| 496 |
else:
|
| 497 |
# Use more features for faster models
|
| 498 |
configurations.append({
|
| 499 |
+
"dataset": dataset,
|
| 500 |
"model_name": model_name,
|
| 501 |
"max_features": 20000,
|
| 502 |
"ngram_range": (1, 2),
|
|
|
|
| 548 |
return results
|
| 549 |
|
| 550 |
|
| 551 |
+
def train_notebook(dataset="vlsp2016", model_name="logistic", max_features=20000, ngram_min=1, ngram_max=2,
|
| 552 |
split_ratio=0.2, n_samples=None, compare=False, export_model=False):
|
| 553 |
"""
|
| 554 |
Convenience function for training in Jupyter/Colab notebooks without argparse.
|
| 555 |
Example usage:
|
| 556 |
from train import train_notebook
|
| 557 |
+
train_notebook(dataset="vlsp2016", model_name="logistic", max_features=20000, export_model=True)
|
| 558 |
"""
|
| 559 |
if compare:
|
| 560 |
+
print(f"Training and comparing multiple configurations on {dataset}...")
|
| 561 |
+
return train_all_configurations(dataset=dataset)
|
| 562 |
else:
|
| 563 |
+
print(f"Training {model_name} model on {dataset} dataset...")
|
| 564 |
print(f"Configuration: max_features={max_features}, ngram=({ngram_min}, {ngram_max})")
|
| 565 |
|
| 566 |
return train_model(
|
| 567 |
+
dataset=dataset,
|
| 568 |
model_name=model_name,
|
| 569 |
max_features=max_features,
|
| 570 |
ngram_range=(ngram_min, ngram_max),
|
|
|
|
| 581 |
in_notebook = hasattr(sys, 'ps1') or 'ipykernel' in sys.modules or 'google.colab' in sys.modules
|
| 582 |
|
| 583 |
parser = argparse.ArgumentParser(
|
| 584 |
+
description="Train Vietnamese sentiment classification model on various datasets"
|
| 585 |
+
)
|
| 586 |
+
parser.add_argument(
|
| 587 |
+
"--dataset",
|
| 588 |
+
type=str,
|
| 589 |
+
choices=["vlsp2016", "uts2017"],
|
| 590 |
+
default="vlsp2016",
|
| 591 |
+
help="Dataset to use for training (default: vlsp2016)",
|
| 592 |
)
|
| 593 |
parser.add_argument(
|
| 594 |
"--model",
|
|
|
|
| 645 |
if args.compare or args.compare_models:
|
| 646 |
if args.compare_models:
|
| 647 |
print(f"Training and comparing selected models: {args.compare_models}")
|
| 648 |
+
print(f"Dataset: {args.dataset}")
|
| 649 |
if args.num_rows:
|
| 650 |
print(f"Using {args.num_rows} rows")
|
| 651 |
+
train_all_configurations(dataset=args.dataset, models=args.compare_models, num_rows=args.num_rows)
|
| 652 |
else:
|
| 653 |
print("Training and comparing all available models...")
|
| 654 |
+
print(f"Dataset: {args.dataset}")
|
| 655 |
if args.num_rows:
|
| 656 |
print(f"Using {args.num_rows} rows")
|
| 657 |
+
train_all_configurations(dataset=args.dataset, num_rows=args.num_rows)
|
| 658 |
else:
|
| 659 |
+
print(f"Training {args.model} model on {args.dataset} dataset...")
|
| 660 |
print(
|
| 661 |
f"Configuration: max_features={args.max_features}, ngram=({args.ngram_min}, {args.ngram_max})"
|
| 662 |
)
|
| 663 |
|
| 664 |
train_model(
|
| 665 |
+
dataset=args.dataset,
|
| 666 |
model_name=args.model,
|
| 667 |
max_features=args.max_features,
|
| 668 |
ngram_range=(args.ngram_min, args.ngram_max),
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5a1f7db895c7cce8e9dac4632d99f594bbaff87295008b061949ea03b7929c0d
|
| 3 |
+
size 1262400
|
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b2ab63a5ec8c8f53581bc13d84ecbbe9912e84111c8cc163b9b8c85351a7d0b9
|
| 3 |
+
size 2947220
|