Lavender825 commited on
Commit
306b259
·
1 Parent(s): 0ace5b0

Update app with compact reports dashboard

Browse files
Files changed (27) hide show
  1. .gitignore +3 -0
  2. app.py +323 -68
  3. data/demo_products.json +165 -0
  4. reports/aspect_level_proposed_vs_no_meta.csv +7 -0
  5. reports/explanation_attention.html +0 -0
  6. reports/explanation_attention_meta_source_summary.csv +7 -0
  7. reports/explanation_attention_summary.csv +0 -0
  8. reports/explanation_ig.html +0 -0
  9. reports/explanation_ig_meta_source_summary.csv +7 -0
  10. reports/explanation_ig_summary.csv +0 -0
  11. reports/overall_model_comparison.csv +6 -0
  12. reports_for_frontend/01_evaluation/aspect_level_proposed_vs_no_meta.csv +7 -0
  13. reports_for_frontend/01_evaluation/evaluation_comparison.json +689 -0
  14. reports_for_frontend/01_evaluation/overall_model_comparison.csv +6 -0
  15. reports_for_frontend/01_evaluation/per_aspect_acsa_no_meta.json +332 -0
  16. reports_for_frontend/01_evaluation/per_aspect_proposed.json +332 -0
  17. reports_for_frontend/03_ablation/ablation_A1.json +335 -0
  18. reports_for_frontend/03_ablation/ablation_A2.json +335 -0
  19. reports_for_frontend/03_ablation/ablation_A3.json +335 -0
  20. reports_for_frontend/03_ablation/ablation_summary.json +122 -0
  21. reports_for_frontend/04_visualization/category_aspect_aggregation.csv +61 -0
  22. reports_for_frontend/05_explanation/explanation_attention.html +0 -0
  23. reports_for_frontend/05_explanation/explanation_attention_meta_source_summary.csv +7 -0
  24. reports_for_frontend/05_explanation/explanation_attention_summary.csv +0 -0
  25. reports_for_frontend/05_explanation/explanation_ig.html +0 -0
  26. reports_for_frontend/05_explanation/explanation_ig_meta_source_summary.csv +7 -0
  27. reports_for_frontend/05_explanation/explanation_ig_summary.csv +0 -0
.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ .ipynb_checkpoints/
app.py CHANGED
@@ -1,6 +1,7 @@
1
- """Dual-interface Hugging Face Space for clothing aspect-level sentiment analysis."""
2
  from __future__ import annotations
3
 
 
4
  import html
5
  import json
6
  import re
@@ -36,6 +37,7 @@ from src.inference import AspectPredictor
36
 
37
  ROOT = Path(__file__).resolve().parent
38
  REPORT_DIR = ROOT / "reports"
 
39
  CHECKPOINT_DIR = ROOT / "checkpoints" / "meta_acsa"
40
  CHECKPOINT_PATH = CHECKPOINT_DIR / "best.pt"
41
  META_ENCODER_PATH = ROOT / "data" / "meta_encoder.pkl"
@@ -60,16 +62,127 @@ ASPECT_KEYWORDS = {
60
  LABEL_BG = {"Positive": "#dcfce7", "Negative": "#fee2e2", "Not_Mentioned": "#f1f5f9", "Neutral": "#e0f2fe"}
61
  LABEL_FG = {"Positive": "#15803d", "Negative": "#b91c1c", "Not_Mentioned": "#475569", "Neutral": "#0369a1"}
62
 
63
- PRODUCTS = [
64
- {"name": "Cotton Graphic Tee", "category": "Tops", "features": "100% Cotton, Slim Fit, Machine Wash Cold, Graphic Print", "categories": "Clothing > Men > T-Shirts > Graphic Tees", "price": 19.99, "average_rating": 4.2, "rating_number": 312, "tags": ["cotton", "casual", "print"], "review": "The size runs really small, I ordered an XL but it fits like a Medium. The fabric feels soft and the print looks great."},
65
- {"name": "Stretch Yoga Leggings", "category": "Bottoms", "features": "Nylon Spandex Blend, High Waist, Four-Way Stretch, Moisture Wicking", "categories": "Clothing > Women > Activewear > Leggings", "price": 29.99, "average_rating": 4.5, "rating_number": 1280, "tags": ["stretch", "activewear", "high waist"], "review": "These leggings fit perfectly and the stretch is comfortable. The material is not see-through, but the seams started to loosen after washing."},
66
- {"name": "Oversized Denim Jacket", "category": "Outerwear", "features": "Denim Cotton Blend, Oversized Fit, Button Front, Distressed Wash", "categories": "Clothing > Women > Jackets > Denim Jackets", "price": 58.00, "average_rating": 4.0, "rating_number": 447, "tags": ["denim", "oversized", "jacket"], "review": "The oversized style is cute and the color looks like the photo. It is heavier than expected and the buttons feel a little cheap."},
67
- {"name": "Floral Summer Dress", "category": "Dresses", "features": "Rayon Blend, Floral Print, A-Line, Lightweight, V-Neck", "categories": "Clothing > Women > Dresses > Summer Dresses", "price": 36.50, "average_rating": 4.3, "rating_number": 864, "tags": ["floral", "summer", "dress"], "review": "The dress looks beautiful and the floral print is exactly as shown. The waist is a bit tight and the fabric wrinkles easily."},
68
- {"name": "Fleece Pullover Hoodie", "category": "Tops", "features": "Cotton Polyester Fleece, Regular Fit, Kangaroo Pocket, Ribbed Cuffs", "categories": "Clothing > Unisex > Hoodies > Pullover Hoodies", "price": 42.99, "average_rating": 4.6, "rating_number": 2214, "tags": ["fleece", "hoodie", "warm"], "review": "Very warm and soft hoodie. The quality feels good for the price, though the sleeves are a little long for me."},
69
- {"name": "Linen Button-Up Shirt", "category": "Tops", "features": "Linen Cotton Blend, Relaxed Fit, Button Front, Breathable Fabric", "categories": "Clothing > Men > Shirts > Button-Up Shirts", "price": 34.99, "average_rating": 3.9, "rating_number": 186, "tags": ["linen", "breathable", "shirt"], "review": "The shirt is breathable and stylish, but it wrinkles badly and the stitching near one button came loose."},
70
  ]
71
 
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  def _safe_float(value: Any, default: float = 0.0) -> float:
74
  try:
75
  if value in (None, ""):
@@ -105,6 +218,27 @@ def _load_json(name: str) -> Dict[str, Any]:
105
  return {}
106
 
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  @lru_cache(maxsize=1)
109
  def _predictor() -> AspectPredictor:
110
  return AspectPredictor(checkpoint_dir=CHECKPOINT_DIR)
@@ -180,6 +314,64 @@ def _overall_html(result: Dict[str, Any]) -> str:
180
  return f'<div class="overall-card"><div class="small-label">Overall sentiment</div><div class="overall-main">{_chip(label)} <span class="conf">confidence {conf:.2f}</span></div>{"".join(bars)}</div>'
181
 
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  def _aspect_cards(result: Dict[str, Any], review: str, selected_aspect: str) -> str:
184
  details = result.get("aspect_details", {})
185
  sources = result.get("top_meta_source_by_aspect", {})
@@ -212,7 +404,7 @@ def consumer_product_view(product_name: str, selected_aspect: str) -> Tuple[str,
212
  result = _predict_product(product_name)
213
  except Exception:
214
  return _error_html(traceback.format_exc(limit=5)), "", "", []
215
- detail = f'<div class="product-card"><h3>{_esc(product["name"])}</h3><p class="muted">{_esc(product["categories"])}</p><div class="meta-pills"><span>Price: ${_safe_float(product["price"]):.2f}</span><span>Rating: {_safe_float(product["average_rating"]):.1f}</span><span>Reviews: {int(_safe_float(product["rating_number"]))}</span></div><p><b>Metadata:</b> {_esc(product["features"])}</p>{_overall_html(result)}</div>'
216
  evidence = f'<h4>Key review evidence</h4>{_highlight_review(product["review"], selected_aspect)}'
217
  return detail, _aspect_cards(result, product["review"], selected_aspect), evidence, _aspect_rows(result, product["review"])
218
 
@@ -242,10 +434,14 @@ def filter_products(aspect: str, sentiment: str, category: str, tags: List[str],
242
  rows.append([product["name"], product["category"], label, round(conf, 4), product["average_rating"], product["price"], product["features"]])
243
  score = conf + 0.03 * _safe_float(product["average_rating"])
244
  if best is None or score > best[0]:
245
- best = (score, product["name"], label, conf)
246
  summary = '<div class="note-card">No product matched the current filters.</div>'
247
  if best:
248
- summary = f'<div class="note-card"><b>Best match:</b> {_esc(best[1])} - {_esc(aspect)} is {_esc(best[2])} with confidence {best[3]:.2f}.</div>'
 
 
 
 
249
  return rows, summary
250
 
251
 
@@ -273,12 +469,21 @@ def research_cards_html() -> str:
273
 
274
 
275
  def overall_metric_rows() -> List[List[Any]]:
 
 
 
276
  cmp = _payload()["eval"].get("overall_3class_comparison", {})
277
  pairs = [("TF-IDF + Logistic Regression", "Baseline_1_TFIDF_LogReg"), ("BERT Overall Classifier", "Baseline_2_BERT_overall_3class"), ("Proposed BERT + Metadata Fusion", "Proposed_BERT_Meta_Fusion__overall_head")]
278
  return [[name, _num(cmp.get(key, {}).get("macro_f1")), _num(cmp.get(key, {}).get("accuracy"))] for name, key in pairs]
279
 
280
 
281
  def aspect_metric_rows() -> List[List[Any]]:
 
 
 
 
 
 
282
  data = _payload()
283
  proposed = data["proposed"].get("per_aspect", {})
284
  no_meta = data["no_meta"].get("per_aspect", {})
@@ -298,6 +503,40 @@ def ablation_rows() -> List[List[Any]]:
298
  return [[labels.get(k, k), _num(ab.get(k, {}).get("mean_macro_f1")), _num(ab.get(k, {}).get("mean_accuracy"))] for k in labels if k in ab]
299
 
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  def merchant_product_scores(metric: str) -> List[List[Any]]:
302
  rows = []
303
  for product in PRODUCTS:
@@ -366,20 +605,25 @@ def _status_html() -> str:
366
  missing.append("data/meta_encoder.pkl")
367
  if missing:
368
  return '<div class="status bad"><b>Model artifacts missing:</b> ' + _esc(", ".join(missing)) + '</div>'
369
- return '<div class="status ok"><b>Model ready.</b> 10W0715 checkpoint and metadata encoder are available.</div>'
370
 
371
 
372
  CSS = """
373
- :root { --accent:#f97316; --ink:#0f172a; --muted:#475569; --line:#dbe3ef; }
374
  .gradio-container { max-width:1240px !important; margin:auto !important; color:var(--ink); }
375
- #hero { border:1px solid var(--line); background:#f8fbff; border-radius:8px; padding:22px 28px; margin:10px 0 22px; }
376
- #hero h1 { margin:0 0 8px; font-size:30px; line-height:1.15; }
377
- #hero p { margin:0; color:#334155; }
 
 
 
378
  button.primary, .gradio-button.primary { background:var(--accent) !important; border-color:var(--accent) !important; color:white !important; font-weight:700 !important; }
379
- .status { border-radius:8px; padding:12px 14px; margin:8px 0 18px; border:1px solid var(--line); }
380
  .status.ok { background:#ecfdf5; border-color:#86efac; color:#065f46; }
381
  .status.bad { background:#fff1f2; border-color:#fda4af; color:#991b1b; }
382
  .product-card, .overall-card, .note-card { border:1px solid var(--line); border-radius:8px; padding:16px; background:white; }
 
 
383
  .muted { color:var(--muted); }
384
  .meta-pills { display:flex; flex-wrap:wrap; gap:8px; margin:10px 0; }
385
  .meta-pills span { background:#f1f5f9; border:1px solid #e2e8f0; border-radius:999px; padding:5px 9px; font-size:13px; }
@@ -389,8 +633,8 @@ button.primary, .gradio-button.primary { background:var(--accent) !important; bo
389
  .prob-row { display:grid; grid-template-columns:82px 1fr 44px; gap:8px; align-items:center; font-size:13px; margin:6px 0; }
390
  .bar { height:8px; background:#e2e8f0; border-radius:999px; overflow:hidden; }
391
  .bar i { display:block; height:100%; background:var(--accent); }
392
- .aspect-grid { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:12px; }
393
- .aspect-card { border:1px solid var(--line); border-top:4px solid #64748b; border-radius:8px; padding:13px; background:white; min-height:165px; }
394
  .aspect-card.focus { border-top-color:var(--accent); box-shadow:0 2px 10px rgba(15,23,42,.08); }
395
  .aspect-card.dim { opacity:.66; }
396
  .aspect-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:8px; }
@@ -400,8 +644,8 @@ button.primary, .gradio-button.primary { background:var(--accent) !important; bo
400
  .evidence-token { color:#1d4ed8; background:#eef2ff; border:1px solid #bfdbfe; border-radius:999px; padding:3px 8px; font-size:12px; }
401
  .review-box { border:1px dashed #cbd5e1; background:#f8fafc; border-radius:8px; padding:14px; line-height:1.6; }
402
  mark { background:#fde68a; color:#111827; border-radius:4px; padding:1px 3px; }
403
- .metric-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:14px; margin:8px 0 18px; }
404
- .metric { border:1px solid var(--line); border-radius:8px; padding:16px; background:white; }
405
  .metric span { display:block; color:#334155; font-size:13px; }
406
  .metric b { display:block; font-size:28px; margin:6px 0; }
407
  .metric small { color:#475569; }
@@ -409,6 +653,7 @@ mark { background:#fde68a; color:#111827; border-radius:4px; padding:1px 3px; }
409
  .kv-table { width:100%; border-collapse:collapse; }
410
  .kv-table td { border-bottom:1px solid #e2e8f0; padding:9px 12px; }
411
  .kv-table td:first-child { width:220px; color:#334155; font-weight:700; background:#f8fafc; }
 
412
  @media (max-width:860px) { .aspect-grid, .metric-grid { grid-template-columns:1fr; } }
413
  """
414
 
@@ -417,7 +662,7 @@ def build_app() -> gr.Blocks:
417
  categories = ["All"] + sorted({p["category"] for p in PRODUCTS})
418
  tags = sorted({tag for p in PRODUCTS for tag in p.get("tags", [])})
419
  with gr.Blocks(css=CSS, title="Clothing Sentiment Analysis") as demo:
420
- gr.HTML('<div id="hero"><h1>Aspect-Level Sentiment Analysis for Clothing Reviews</h1><p>BERT + metadata cross-attention fusion for consumer decision support and merchant diagnostics.</p></div>')
421
  gr.HTML(_status_html())
422
  with gr.Tabs():
423
  with gr.Tab("Consumer Interface"):
@@ -430,17 +675,18 @@ def build_app() -> gr.Blocks:
430
  with gr.Column(scale=6):
431
  aspect_html = gr.HTML()
432
  consumer_table = gr.Dataframe(headers=["Aspect", "Prediction", "Confidence", "Key review evidence"], datatype=["str", "str", "number", "str"], label="Aspect-level result table", interactive=False)
433
- gr.Markdown("### Product Finder")
434
- with gr.Row():
435
- filter_aspect = gr.Dropdown(["Overall"] + ASPECTS, value="Overall", label="Target metric")
436
- filter_sentiment = gr.Radio(["Any", "Positive", "Negative", "Not_Mentioned", "Neutral"], value="Any", label="Preferred prediction")
437
- filter_category = gr.Dropdown(categories, value="All", label="Category")
438
- with gr.Row():
439
- filter_tags = gr.CheckboxGroup(tags, label="Required metadata tags")
440
- min_rating = gr.Slider(3.0, 5.0, value=4.0, step=0.1, label="Minimum product rating")
441
- filter_btn = gr.Button("Filter Products", variant="primary")
442
- filter_summary = gr.HTML()
443
- filter_table = gr.Dataframe(headers=["Product", "Category", "Prediction", "Confidence", "Rating", "Price", "Metadata"], datatype=["str", "str", "str", "number", "number", "number", "str"], interactive=False, label="Filtered product candidates")
 
444
  product_select.change(consumer_product_view, [product_select, consumer_aspect], [product_detail, aspect_html, evidence_html, consumer_table])
445
  consumer_aspect.change(consumer_product_view, [product_select, consumer_aspect], [product_detail, aspect_html, evidence_html, consumer_table])
446
  filter_btn.click(filter_products, [filter_aspect, filter_sentiment, filter_category, filter_tags, min_rating], [filter_table, filter_summary])
@@ -455,48 +701,57 @@ def build_app() -> gr.Blocks:
455
  merchant_metric = gr.Dropdown(["Overall"] + ASPECTS, value="Overall", label="Choose overall or aspect")
456
  merchant_scores = gr.Dataframe(headers=["Product", "Category", "Metric", "Prediction", "Confidence", "Price", "Rating"], value=[["Click Refresh Product Scores", "", "", "", 0.0, 0.0, 0.0]], datatype=["str", "str", "str", "str", "number", "number", "number"], interactive=False)
457
  refresh_scores = gr.Button("Refresh Product Scores", variant="primary")
458
- gr.Markdown("### New Product Metadata Risk Screening")
459
- with gr.Row():
460
- new_features = gr.Textbox("Cotton Polyester Blend, Slim Fit, Graphic Print, Machine Wash", label="New product features")
461
- new_categories = gr.Textbox("Clothing > Women > Tops > T-Shirts", label="New product categories")
462
- with gr.Row():
463
- new_price = gr.Number(29.99, label="Price")
464
- new_rating = gr.Number(4.1, label="Expected or early average rating")
465
- new_count = gr.Number(35, label="Expected or early rating count")
466
- new_focus = gr.Dropdown(["All"] + ASPECTS, value="All", label="Focus aspect")
467
- screen_btn = gr.Button("Predict Metadata Risk", variant="primary")
468
- risk_summary = gr.HTML()
469
- risk_table = gr.Dataframe(headers=["Aspect", "Risk Level", "Model Signal", "Confidence", "Reason"], value=[["Click Predict Metadata Risk", "", "", 0.0, ""]], datatype=["str", "str", "str", "number", "str"], interactive=False)
470
- gr.Markdown("### External Review Prediction")
471
- external_review = gr.Textbox("The fabric is soft and the color looks good, but it runs small and the zipper feels weak.", label="External customer review", lines=4)
472
- with gr.Row():
473
- ext_features = gr.Textbox("Cotton Blend, Slim Fit, Zipper Closure", label="Product features")
474
- ext_categories = gr.Textbox("Clothing > Women > Jackets", label="Product categories")
475
- with gr.Row():
476
- ext_price = gr.Number(39.99, label="Price")
477
- ext_rating = gr.Number(4.2, label="Average rating")
478
- ext_count = gr.Number(312, label="Rating count")
479
- ext_aspect = gr.Dropdown(["All"] + ASPECTS, value="All", label="Highlight aspect")
480
- external_btn = gr.Button("Analyze External Review", variant="primary")
481
- ext_overall = gr.HTML()
482
- ext_aspects = gr.HTML()
483
- ext_table = gr.Dataframe(headers=["Aspect", "Prediction", "Confidence", "Key review evidence"], value=[["Click Analyze External Review", "", 0.0, ""]], datatype=["str", "str", "number", "str"], interactive=False)
484
  refresh_scores.click(merchant_product_scores, merchant_metric, merchant_scores)
485
  merchant_metric.change(merchant_product_scores, merchant_metric, merchant_scores)
486
  screen_btn.click(screen_new_product, [new_features, new_categories, new_price, new_rating, new_count, new_focus], [risk_summary, risk_table])
487
  external_btn.click(external_review_predict, [external_review, ext_features, ext_categories, ext_price, ext_rating, ext_count, ext_aspect], [ext_overall, ext_aspects, ext_table])
488
 
489
  with gr.Tab("Research Metrics"):
490
- gr.Markdown("Metrics are loaded from the bundled 10W0715 experiment reports.")
491
  research_cards = gr.HTML(research_cards_html())
492
- gr.Markdown("### 1. Overall Sentiment Metrics")
493
- overall_table = gr.Dataframe(headers=["Model", "Macro-F1", "Accuracy"], value=overall_metric_rows(), interactive=False)
494
- gr.Markdown("### 2. Aspect-Level Overall Comparison")
495
- aspect_table = gr.Dataframe(headers=["Aspect", "No-meta F1", "Proposed F1", "F1 Delta", "No-meta Acc", "Proposed Acc", "Acc Delta"], value=aspect_metric_rows(), interactive=False)
496
- gr.Markdown("### 3. Ablation Comparison")
497
- ablation_table = gr.Dataframe(headers=["Variant", "Mean Macro-F1", "Mean Accuracy"], value=ablation_rows(), interactive=False)
 
 
 
 
 
 
 
 
 
498
  refresh_research = gr.Button("Refresh Research Metrics", variant="primary")
499
- refresh_research.click(lambda: (research_cards_html(), overall_metric_rows(), aspect_metric_rows(), ablation_rows()), outputs=[research_cards, overall_table, aspect_table, ablation_table])
500
  demo.load(consumer_product_view, [product_select, consumer_aspect], [product_detail, aspect_html, evidence_html, consumer_table])
501
  demo.load(merchant_product_scores, merchant_metric, merchant_scores)
502
  demo.load(filter_products, [filter_aspect, filter_sentiment, filter_category, filter_tags, min_rating], [filter_table, filter_summary])
@@ -506,5 +761,5 @@ def build_app() -> gr.Blocks:
506
  demo = build_app()
507
 
508
  if __name__ == "__main__":
509
- demo.launch()
510
 
 
1
+ """Dual-interface Hugging Face Space for clothing aspect-level sentiment analysis."""
2
  from __future__ import annotations
3
 
4
+ import csv
5
  import html
6
  import json
7
  import re
 
37
 
38
  ROOT = Path(__file__).resolve().parent
39
  REPORT_DIR = ROOT / "reports"
40
+ DATA_DIR = ROOT / "data"
41
  CHECKPOINT_DIR = ROOT / "checkpoints" / "meta_acsa"
42
  CHECKPOINT_PATH = CHECKPOINT_DIR / "best.pt"
43
  META_ENCODER_PATH = ROOT / "data" / "meta_encoder.pkl"
 
62
  LABEL_BG = {"Positive": "#dcfce7", "Negative": "#fee2e2", "Not_Mentioned": "#f1f5f9", "Neutral": "#e0f2fe"}
63
  LABEL_FG = {"Positive": "#15803d", "Negative": "#b91c1c", "Not_Mentioned": "#475569", "Neutral": "#0369a1"}
64
 
65
+ FALLBACK_PRODUCTS = [
66
+ {"name": "Demo - Cotton Graphic Tee", "category": "Tops", "features": "100% Cotton, Slim Fit, Machine Wash Cold, Graphic Print", "categories": "Clothing > Men > T-Shirts > Graphic Tees", "price": 19.99, "average_rating": 4.2, "rating_number": 312, "tags": ["cotton", "casual", "print"], "source": "curated demo fallback", "review": "The size runs really small, I ordered an XL but it fits like a Medium. The fabric feels soft and the print looks great."},
67
+ {"name": "Demo - Stretch Yoga Leggings", "category": "Bottoms", "features": "Nylon Spandex Blend, High Waist, Four-Way Stretch, Moisture Wicking", "categories": "Clothing > Women > Activewear > Leggings", "price": 29.99, "average_rating": 4.5, "rating_number": 1280, "tags": ["stretch", "activewear", "high waist"], "source": "curated demo fallback", "review": "These leggings fit perfectly and the stretch is comfortable. The material is not see-through, but the seams started to loosen after washing."},
68
+ {"name": "Demo - Oversized Denim Jacket", "category": "Outerwear", "features": "Denim Cotton Blend, Oversized Fit, Button Front, Distressed Wash", "categories": "Clothing > Women > Jackets > Denim Jackets", "price": 58.00, "average_rating": 4.0, "rating_number": 447, "tags": ["denim", "oversized", "jacket"], "source": "curated demo fallback", "review": "The oversized style is cute and the color looks like the photo. It is heavier than expected and the buttons feel a little cheap."},
69
+ {"name": "Demo - Floral Summer Dress", "category": "Dresses", "features": "Rayon Blend, Floral Print, A-Line, Lightweight, V-Neck", "categories": "Clothing > Women > Dresses > Summer Dresses", "price": 36.50, "average_rating": 4.3, "rating_number": 864, "tags": ["floral", "summer", "dress"], "source": "curated demo fallback", "review": "The dress looks beautiful and the floral print is exactly as shown. The waist is a bit tight and the fabric wrinkles easily."},
70
+ {"name": "Demo - Fleece Pullover Hoodie", "category": "Tops", "features": "Cotton Polyester Fleece, Regular Fit, Kangaroo Pocket, Ribbed Cuffs", "categories": "Clothing > Unisex > Hoodies > Pullover Hoodies", "price": 42.99, "average_rating": 4.6, "rating_number": 2214, "tags": ["fleece", "hoodie", "warm"], "source": "curated demo fallback", "review": "Very warm and soft hoodie. The quality feels good for the price, though the sleeves are a little long for me."},
71
+ {"name": "Demo - Linen Button-Up Shirt", "category": "Tops", "features": "Linen Cotton Blend, Relaxed Fit, Button Front, Breathable Fabric", "categories": "Clothing > Men > Shirts > Button-Up Shirts", "price": 34.99, "average_rating": 3.9, "rating_number": 186, "tags": ["linen", "breathable", "shirt"], "source": "curated demo fallback", "review": "The shirt is breathable and stylish, but it wrinkles badly and the stitching near one button came loose."},
72
  ]
73
 
74
 
75
+ TAG_CANDIDATES = [
76
+ "cotton", "polyester", "linen", "denim", "fleece", "leather", "stretch", "soft",
77
+ "breathable", "warm", "shirt", "dress", "jacket", "shorts", "sneakers",
78
+ "wallet", "jewelry", "casual", "formal", "activewear", "print", "floral",
79
+ "slim fit", "relaxed fit", "oversized", "high waist", "plus size",
80
+ ]
81
+
82
+
83
+ def _safe_float(value, default=0.0):
84
+ try:
85
+ if value in (None, ""):
86
+ return default
87
+ return float(value)
88
+ except Exception:
89
+ return default
90
+
91
+
92
+ def _parse_numeric_blob(blob):
93
+ text = str(blob or "")
94
+ out = {}
95
+ for key in ("price", "average_rating", "rating_number"):
96
+ match = re.search(rf"{key}\s*=\s*([-+]?\d+(?:\.\d+)?)", text)
97
+ if match:
98
+ out[key] = _safe_float(match.group(1))
99
+ return out
100
+
101
+
102
+ def _tags_from_text(text):
103
+ low = str(text or "").lower()
104
+ tags = [tag for tag in TAG_CANDIDATES if tag in low]
105
+ return list(dict.fromkeys(tags))[:8]
106
+
107
+
108
+ def _load_products_from_json():
109
+ path = DATA_DIR / "demo_products.json"
110
+ try:
111
+ if path.exists():
112
+ products = json.loads(path.read_text(encoding="utf-8"))
113
+ if isinstance(products, list) and products:
114
+ return [_coerce_product(p, i + 1) for i, p in enumerate(products)]
115
+ except Exception:
116
+ pass
117
+ return []
118
+
119
+
120
+ def _load_products_from_explanation_csv():
121
+ path = REPORT_DIR / "explanation_attention_summary.csv"
122
+ if not path.exists():
123
+ return []
124
+ products = {}
125
+ try:
126
+ with path.open("r", encoding="utf-8", newline="") as fh:
127
+ for row in csv.DictReader(fh):
128
+ example_id = str(row.get("example") or "").strip()
129
+ if not example_id or example_id in products:
130
+ continue
131
+ numeric = _parse_numeric_blob(row.get("numeric"))
132
+ category = str(row.get("category") or "Clothing").strip() or "Clothing"
133
+ features = str(row.get("features") or "").strip()
134
+ categories = str(row.get("categories") or category).strip()
135
+ review = str(row.get("text") or "").strip()
136
+ source = "real held-out explanation example"
137
+ item = {
138
+ "name": f"Real Review {int(float(example_id)):02d} - {category}",
139
+ "category": category,
140
+ "features": features[:700],
141
+ "categories": categories[:300],
142
+ "price": numeric.get("price", 0.0),
143
+ "average_rating": numeric.get("average_rating", _safe_float(row.get("rating"), 0.0)),
144
+ "rating_number": numeric.get("rating_number", 0.0),
145
+ "review": review,
146
+ "source": source,
147
+ }
148
+ item["tags"] = _tags_from_text(" ".join([features, categories, review]))
149
+ products[example_id] = _coerce_product(item, int(float(example_id)))
150
+ except Exception:
151
+ return []
152
+ return list(products.values())
153
+
154
+
155
+ def _coerce_product(item, idx=0):
156
+ features = str(item.get("features") or item.get("features_text") or "")
157
+ categories = str(item.get("categories") or item.get("categories_text") or "")
158
+ review = str(item.get("review") or item.get("review_text") or "")
159
+ category = str(item.get("category") or (categories.split(">")[-1].strip() if categories else "Clothing"))
160
+ name = str(item.get("name") or item.get("title") or f"Product Example {idx:02d}")
161
+ tags = item.get("tags") or _tags_from_text(" ".join([features, categories, review]))
162
+ return {
163
+ "name": name,
164
+ "category": category,
165
+ "features": features,
166
+ "categories": categories,
167
+ "price": _safe_float(item.get("price")),
168
+ "average_rating": _safe_float(item.get("average_rating")),
169
+ "rating_number": _safe_float(item.get("rating_number")),
170
+ "review": review,
171
+ "tags": list(tags) if isinstance(tags, (list, tuple)) else _tags_from_text(tags),
172
+ "source": str(item.get("source") or "demo product"),
173
+ }
174
+
175
+
176
+ def _load_products():
177
+ products = _load_products_from_json() or _load_products_from_explanation_csv()
178
+ if products:
179
+ return products
180
+ return FALLBACK_PRODUCTS
181
+
182
+
183
+ PRODUCTS = _load_products()
184
+
185
+
186
  def _safe_float(value: Any, default: float = 0.0) -> float:
187
  try:
188
  if value in (None, ""):
 
218
  return {}
219
 
220
 
221
+ def _load_csv_rows(name: str, columns: List[str], limit: int | None = None) -> List[List[Any]]:
222
+ path = REPORT_DIR / name
223
+ if not path.exists():
224
+ return []
225
+ rows = []
226
+ try:
227
+ with path.open("r", encoding="utf-8", newline="") as fh:
228
+ for row in csv.DictReader(fh):
229
+ rows.append([row.get(col, "") for col in columns])
230
+ if limit and len(rows) >= limit:
231
+ break
232
+ except Exception:
233
+ return []
234
+ return rows
235
+
236
+
237
+ def _report_image(name: str):
238
+ path = REPORT_DIR / name
239
+ return str(path) if path.exists() else None
240
+
241
+
242
  @lru_cache(maxsize=1)
243
  def _predictor() -> AspectPredictor:
244
  return AspectPredictor(checkpoint_dir=CHECKPOINT_DIR)
 
314
  return f'<div class="overall-card"><div class="small-label">Overall sentiment</div><div class="overall-main">{_chip(label)} <span class="conf">confidence {conf:.2f}</span></div>{"".join(bars)}</div>'
315
 
316
 
317
+ def _join_aspects(items: List[str]) -> str:
318
+ if not items:
319
+ return "-"
320
+ if len(items) == 1:
321
+ return items[0]
322
+ if len(items) == 2:
323
+ return f"{items[0]} and {items[1]}"
324
+ return ", ".join(items[:-1]) + f", and {items[-1]}"
325
+
326
+
327
+ def _recommendation_sentence(result: Dict[str, Any]) -> str:
328
+ details = result.get("aspect_details", {})
329
+ positive = []
330
+ negative = []
331
+ low_risk = []
332
+ for aspect in ASPECTS:
333
+ d = details.get(aspect, {})
334
+ label = d.get("label", result.get("aspects", {}).get(aspect, "Unknown"))
335
+ conf = _safe_float(d.get("confidence"))
336
+ if label == "Positive":
337
+ positive.append(aspect)
338
+ elif label == "Negative":
339
+ negative.append(aspect)
340
+ elif label in {"Neutral", "Not_Mentioned"} or conf < 0.60:
341
+ low_risk.append(aspect)
342
+
343
+ if positive and negative:
344
+ return (
345
+ f"This product is recommended because {_join_aspects(positive[:3])} "
346
+ f"{'is' if len(positive[:3]) == 1 else 'are'} positive, while "
347
+ f"{_join_aspects(negative[:2])} should be checked as potential risk."
348
+ )
349
+ if positive:
350
+ remaining = [a for a in ASPECTS if a not in positive]
351
+ return (
352
+ f"This product is recommended because {_join_aspects(positive[:3])} "
353
+ f"{'is' if len(positive[:3]) == 1 else 'are'} positive, while "
354
+ f"{_join_aspects((low_risk or remaining)[:3])} has low risk."
355
+ )
356
+ if negative:
357
+ return (
358
+ f"This product is not a strong recommendation because "
359
+ f"{_join_aspects(negative[:3])} shows negative sentiment risk."
360
+ )
361
+ overall = result.get("overall", {}).get("label", "Neutral")
362
+ return f"This product is a cautious recommendation because the overall signal is {overall} and no strong aspect risk dominates."
363
+
364
+
365
+ def _recommendation_html(result: Dict[str, Any], product_name: str = "") -> str:
366
+ sentence = _recommendation_sentence(result)
367
+ title = f"Recommendation reason for {_esc(product_name)}" if product_name else "Recommendation reason"
368
+ return (
369
+ f'<div class="recommendation-card"><div class="small-label">{title}</div>'
370
+ f'<b>{_esc(sentence)}</b>'
371
+ f'<p class="muted">This explanation is generated from the live model output: overall sentiment, six aspect labels, and confidence scores.</p></div>'
372
+ )
373
+
374
+
375
  def _aspect_cards(result: Dict[str, Any], review: str, selected_aspect: str) -> str:
376
  details = result.get("aspect_details", {})
377
  sources = result.get("top_meta_source_by_aspect", {})
 
404
  result = _predict_product(product_name)
405
  except Exception:
406
  return _error_html(traceback.format_exc(limit=5)), "", "", []
407
+ detail = f'<div class="product-card"><h3>{_esc(product["name"])}</h3><p class="muted">{_esc(product["categories"])}</p><div class="meta-pills"><span>Source: {_esc(product.get("source", "demo"))}</span><span>Price: ${_safe_float(product["price"]):.2f}</span><span>Rating: {_safe_float(product["average_rating"]):.1f}</span><span>Reviews: {int(_safe_float(product["rating_number"]))}</span></div><p><b>Metadata:</b> {_esc(product["features"])}</p>{_recommendation_html(result, product["name"])}{_overall_html(result)}</div>'
408
  evidence = f'<h4>Key review evidence</h4>{_highlight_review(product["review"], selected_aspect)}'
409
  return detail, _aspect_cards(result, product["review"], selected_aspect), evidence, _aspect_rows(result, product["review"])
410
 
 
434
  rows.append([product["name"], product["category"], label, round(conf, 4), product["average_rating"], product["price"], product["features"]])
435
  score = conf + 0.03 * _safe_float(product["average_rating"])
436
  if best is None or score > best[0]:
437
+ best = (score, product["name"], label, conf, result)
438
  summary = '<div class="note-card">No product matched the current filters.</div>'
439
  if best:
440
+ summary = (
441
+ f'<div class="note-card"><b>Best match:</b> {_esc(best[1])} - '
442
+ f'{_esc(aspect)} is {_esc(best[2])} with confidence {best[3]:.2f}.'
443
+ f'{_recommendation_html(best[4], best[1])}</div>'
444
+ )
445
  return rows, summary
446
 
447
 
 
469
 
470
 
471
  def overall_metric_rows() -> List[List[Any]]:
472
+ csv_rows = _load_csv_rows("overall_model_comparison.csv", ["model", "macro_f1", "accuracy"])
473
+ if csv_rows:
474
+ return [[r[0], _num(r[1]), _num(r[2])] for r in csv_rows]
475
  cmp = _payload()["eval"].get("overall_3class_comparison", {})
476
  pairs = [("TF-IDF + Logistic Regression", "Baseline_1_TFIDF_LogReg"), ("BERT Overall Classifier", "Baseline_2_BERT_overall_3class"), ("Proposed BERT + Metadata Fusion", "Proposed_BERT_Meta_Fusion__overall_head")]
477
  return [[name, _num(cmp.get(key, {}).get("macro_f1")), _num(cmp.get(key, {}).get("accuracy"))] for name, key in pairs]
478
 
479
 
480
  def aspect_metric_rows() -> List[List[Any]]:
481
+ csv_rows = _load_csv_rows(
482
+ "aspect_level_proposed_vs_no_meta.csv",
483
+ ["aspect", "acsa_no_meta_macro_f1", "proposed_macro_f1", "delta_macro_f1", "acsa_no_meta_accuracy", "proposed_accuracy", "delta_accuracy"],
484
+ )
485
+ if csv_rows:
486
+ return [[r[0], _num(r[1]), _num(r[2]), f"{_safe_float(r[3]):+.4f}", _num(r[4]), _num(r[5]), f"{_safe_float(r[6]):+.4f}"] for r in csv_rows]
487
  data = _payload()
488
  proposed = data["proposed"].get("per_aspect", {})
489
  no_meta = data["no_meta"].get("per_aspect", {})
 
503
  return [[labels.get(k, k), _num(ab.get(k, {}).get("mean_macro_f1")), _num(ab.get(k, {}).get("mean_accuracy"))] for k in labels if k in ab]
504
 
505
 
506
+ def meta_source_rows() -> List[List[Any]]:
507
+ rows = _load_csv_rows(
508
+ "explanation_attention_meta_source_summary.csv",
509
+ ["aspect", "top_meta_source", "source_share", "mean_top_meta_weight", "mean_attention_focus"],
510
+ )
511
+ if not rows:
512
+ rows = _load_csv_rows(
513
+ "explanation_ig_meta_source_summary.csv",
514
+ ["aspect", "top_meta_source", "source_share", "mean_top_meta_weight", "mean_attention_focus"],
515
+ )
516
+ return [[r[0], r[1], _pct(r[2]), _num(r[3]), _num(r[4])] for r in rows]
517
+
518
+
519
+ def report_asset_rows() -> List[List[Any]]:
520
+ groups = [
521
+ ("Evaluation", "overall_model_comparison.csv, aspect_level_proposed_vs_no_meta.csv"),
522
+ ("Confusion matrices", "confusion_matrix_proposed_overall_head.png and per-aspect PNGs"),
523
+ ("Ablation", "ablation_summary.json, ablation_A1/A2/A3.json"),
524
+ ("Visualization", "aspect_distribution.png and category_aspect_*_heatmap.png"),
525
+ ("Explanation", "explanation_*_summary.csv and explanation_*_meta_source_summary.csv"),
526
+ ]
527
+ return [[name, assets] for name, assets in groups]
528
+
529
+
530
+ def refresh_research_outputs():
531
+ return (
532
+ research_cards_html(),
533
+ overall_metric_rows(),
534
+ aspect_metric_rows(),
535
+ ablation_rows(),
536
+ meta_source_rows(),
537
+ )
538
+
539
+
540
  def merchant_product_scores(metric: str) -> List[List[Any]]:
541
  rows = []
542
  for product in PRODUCTS:
 
605
  missing.append("data/meta_encoder.pkl")
606
  if missing:
607
  return '<div class="status bad"><b>Model artifacts missing:</b> ' + _esc(", ".join(missing)) + '</div>'
608
+ return '<div class="status ok"><b>Model ready.</b> 10W0716 checkpoint and metadata encoder are available.</div>'
609
 
610
 
611
  CSS = """
612
+ :root { --accent:#f97316; --ink:#0f172a; --muted:#475569; --line:#dbe3ef; --panel:#ffffff; }
613
  .gradio-container { max-width:1240px !important; margin:auto !important; color:var(--ink); }
614
+ #hero { border:1px solid #bfdbfe; background:#eff6ff; border-left:6px solid var(--accent); border-radius:8px; padding:18px 22px; margin:8px 0 14px; box-shadow:0 1px 6px rgba(15,23,42,.06); }
615
+ #hero .eyebrow { margin:0 0 7px; color:#9a3412; font-size:13px; font-weight:800; letter-spacing:.04em; text-transform:uppercase; }
616
+ #hero h1 { margin:0 0 8px; font-size:28px; line-height:1.15; color:#0f172a; font-weight:800; }
617
+ #hero p { margin:0; color:#1e3a8a; max-width:920px; }
618
+ #hero .hero-pills { display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
619
+ #hero .hero-pills span { color:#1e293b; background:#ffffff; border:1px solid #bfdbfe; border-radius:999px; padding:5px 10px; font-size:13px; font-weight:600; }
620
  button.primary, .gradio-button.primary { background:var(--accent) !important; border-color:var(--accent) !important; color:white !important; font-weight:700 !important; }
621
+ .status { border-radius:8px; padding:10px 13px; margin:6px 0 14px; border:1px solid var(--line); }
622
  .status.ok { background:#ecfdf5; border-color:#86efac; color:#065f46; }
623
  .status.bad { background:#fff1f2; border-color:#fda4af; color:#991b1b; }
624
  .product-card, .overall-card, .note-card { border:1px solid var(--line); border-radius:8px; padding:16px; background:white; }
625
+ .recommendation-card { border:1px solid #fed7aa; border-left:5px solid var(--accent); background:#fff7ed; border-radius:8px; padding:13px 14px; margin:12px 0; }
626
+ .recommendation-card p { margin:7px 0 0; }
627
  .muted { color:var(--muted); }
628
  .meta-pills { display:flex; flex-wrap:wrap; gap:8px; margin:10px 0; }
629
  .meta-pills span { background:#f1f5f9; border:1px solid #e2e8f0; border-radius:999px; padding:5px 9px; font-size:13px; }
 
633
  .prob-row { display:grid; grid-template-columns:82px 1fr 44px; gap:8px; align-items:center; font-size:13px; margin:6px 0; }
634
  .bar { height:8px; background:#e2e8f0; border-radius:999px; overflow:hidden; }
635
  .bar i { display:block; height:100%; background:var(--accent); }
636
+ .aspect-grid { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:10px; }
637
+ .aspect-card { border:1px solid var(--line); border-top:4px solid #64748b; border-radius:8px; padding:12px; background:white; min-height:145px; }
638
  .aspect-card.focus { border-top-color:var(--accent); box-shadow:0 2px 10px rgba(15,23,42,.08); }
639
  .aspect-card.dim { opacity:.66; }
640
  .aspect-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:8px; }
 
644
  .evidence-token { color:#1d4ed8; background:#eef2ff; border:1px solid #bfdbfe; border-radius:999px; padding:3px 8px; font-size:12px; }
645
  .review-box { border:1px dashed #cbd5e1; background:#f8fafc; border-radius:8px; padding:14px; line-height:1.6; }
646
  mark { background:#fde68a; color:#111827; border-radius:4px; padding:1px 3px; }
647
+ .metric-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:12px; margin:8px 0 12px; }
648
+ .metric { border:1px solid var(--line); border-radius:8px; padding:14px; background:white; }
649
  .metric span { display:block; color:#334155; font-size:13px; }
650
  .metric b { display:block; font-size:28px; margin:6px 0; }
651
  .metric small { color:#475569; }
 
653
  .kv-table { width:100%; border-collapse:collapse; }
654
  .kv-table td { border-bottom:1px solid #e2e8f0; padding:9px 12px; }
655
  .kv-table td:first-child { width:220px; color:#334155; font-weight:700; background:#f8fafc; }
656
+ .compact-note { color:#475569; font-size:13px; margin:4px 0 10px; }
657
  @media (max-width:860px) { .aspect-grid, .metric-grid { grid-template-columns:1fr; } }
658
  """
659
 
 
662
  categories = ["All"] + sorted({p["category"] for p in PRODUCTS})
663
  tags = sorted({tag for p in PRODUCTS for tag in p.get("tags", [])})
664
  with gr.Blocks(css=CSS, title="Clothing Sentiment Analysis") as demo:
665
+ gr.HTML('<div id="hero"><div class="eyebrow">BERT + Metadata Cross-Attention</div><h1>Clothing Review Sentiment Intelligence App</h1><p>Explore overall sentiment, six aspect-level opinions, metadata-driven risks, and updated 10W experiment reports in a compact customer decision-support prototype.</p><div class="hero-pills"><span>Consumer decision support</span><span>Merchant diagnostics</span><span>Research dashboard</span></div></div>')
666
  gr.HTML(_status_html())
667
  with gr.Tabs():
668
  with gr.Tab("Consumer Interface"):
 
675
  with gr.Column(scale=6):
676
  aspect_html = gr.HTML()
677
  consumer_table = gr.Dataframe(headers=["Aspect", "Prediction", "Confidence", "Key review evidence"], datatype=["str", "str", "number", "str"], label="Aspect-level result table", interactive=False)
678
+ with gr.Accordion("Product Finder filters", open=False):
679
+ gr.HTML('<div class="compact-note">Optional: filter products by aspect sentiment, category, tags, and minimum rating.</div>')
680
+ with gr.Row():
681
+ filter_aspect = gr.Dropdown(["Overall"] + ASPECTS, value="Overall", label="Target metric")
682
+ filter_sentiment = gr.Radio(["Any", "Positive", "Negative", "Not_Mentioned", "Neutral"], value="Any", label="Preferred prediction")
683
+ filter_category = gr.Dropdown(categories, value="All", label="Category")
684
+ with gr.Row():
685
+ filter_tags = gr.CheckboxGroup(tags, label="Required metadata tags")
686
+ min_rating = gr.Slider(3.0, 5.0, value=4.0, step=0.1, label="Minimum product rating")
687
+ filter_btn = gr.Button("Filter Products", variant="primary")
688
+ filter_summary = gr.HTML()
689
+ filter_table = gr.Dataframe(headers=["Product", "Category", "Prediction", "Confidence", "Rating", "Price", "Metadata"], datatype=["str", "str", "str", "number", "number", "number", "str"], interactive=False, label="Filtered product candidates")
690
  product_select.change(consumer_product_view, [product_select, consumer_aspect], [product_detail, aspect_html, evidence_html, consumer_table])
691
  consumer_aspect.change(consumer_product_view, [product_select, consumer_aspect], [product_detail, aspect_html, evidence_html, consumer_table])
692
  filter_btn.click(filter_products, [filter_aspect, filter_sentiment, filter_category, filter_tags, min_rating], [filter_table, filter_summary])
 
701
  merchant_metric = gr.Dropdown(["Overall"] + ASPECTS, value="Overall", label="Choose overall or aspect")
702
  merchant_scores = gr.Dataframe(headers=["Product", "Category", "Metric", "Prediction", "Confidence", "Price", "Rating"], value=[["Click Refresh Product Scores", "", "", "", 0.0, 0.0, 0.0]], datatype=["str", "str", "str", "str", "number", "number", "number"], interactive=False)
703
  refresh_scores = gr.Button("Refresh Product Scores", variant="primary")
704
+ with gr.Accordion("New Product Metadata Risk Screening", open=False):
705
+ with gr.Row():
706
+ new_features = gr.Textbox("Cotton Polyester Blend, Slim Fit, Graphic Print, Machine Wash", label="New product features")
707
+ new_categories = gr.Textbox("Clothing > Women > Tops > T-Shirts", label="New product categories")
708
+ with gr.Row():
709
+ new_price = gr.Number(29.99, label="Price")
710
+ new_rating = gr.Number(4.1, label="Expected or early average rating")
711
+ new_count = gr.Number(35, label="Expected or early rating count")
712
+ new_focus = gr.Dropdown(["All"] + ASPECTS, value="All", label="Focus aspect")
713
+ screen_btn = gr.Button("Predict Metadata Risk", variant="primary")
714
+ risk_summary = gr.HTML()
715
+ risk_table = gr.Dataframe(headers=["Aspect", "Risk Level", "Model Signal", "Confidence", "Reason"], value=[["Click Predict Metadata Risk", "", "", 0.0, ""]], datatype=["str", "str", "str", "number", "str"], interactive=False)
716
+ with gr.Accordion("External Review Prediction", open=False):
717
+ external_review = gr.Textbox("The fabric is soft and the color looks good, but it runs small and the zipper feels weak.", label="External customer review", lines=4)
718
+ with gr.Row():
719
+ ext_features = gr.Textbox("Cotton Blend, Slim Fit, Zipper Closure", label="Product features")
720
+ ext_categories = gr.Textbox("Clothing > Women > Jackets", label="Product categories")
721
+ with gr.Row():
722
+ ext_price = gr.Number(39.99, label="Price")
723
+ ext_rating = gr.Number(4.2, label="Average rating")
724
+ ext_count = gr.Number(312, label="Rating count")
725
+ ext_aspect = gr.Dropdown(["All"] + ASPECTS, value="All", label="Highlight aspect")
726
+ external_btn = gr.Button("Analyze External Review", variant="primary")
727
+ ext_overall = gr.HTML()
728
+ ext_aspects = gr.HTML()
729
+ ext_table = gr.Dataframe(headers=["Aspect", "Prediction", "Confidence", "Key review evidence"], value=[["Click Analyze External Review", "", 0.0, ""]], datatype=["str", "str", "number", "str"], interactive=False)
730
  refresh_scores.click(merchant_product_scores, merchant_metric, merchant_scores)
731
  merchant_metric.change(merchant_product_scores, merchant_metric, merchant_scores)
732
  screen_btn.click(screen_new_product, [new_features, new_categories, new_price, new_rating, new_count, new_focus], [risk_summary, risk_table])
733
  external_btn.click(external_review_predict, [external_review, ext_features, ext_categories, ext_price, ext_rating, ext_count, ext_aspect], [ext_overall, ext_aspects, ext_table])
734
 
735
  with gr.Tab("Research Metrics"):
736
+ gr.Markdown("Metrics are loaded from the updated 10W experiment reports. Tables use CSV outputs when available, with JSON fallback.")
737
  research_cards = gr.HTML(research_cards_html())
738
+ with gr.Accordion("Performance comparison", open=True):
739
+ overall_table = gr.Dataframe(headers=["Model", "Macro-F1", "Accuracy"], value=overall_metric_rows(), interactive=False)
740
+ aspect_table = gr.Dataframe(headers=["Aspect", "No-meta F1", "Proposed F1", "F1 Delta", "No-meta Acc", "Proposed Acc", "Acc Delta"], value=aspect_metric_rows(), interactive=False)
741
+ with gr.Accordion("Ablation and metadata source summary", open=False):
742
+ ablation_table = gr.Dataframe(headers=["Variant", "Mean Macro-F1", "Mean Accuracy"], value=ablation_rows(), interactive=False)
743
+ meta_source_table = gr.Dataframe(headers=["Aspect", "Top Metadata Source", "Source Share", "Mean Weight", "Mean Focus"], value=meta_source_rows(), interactive=False)
744
+ with gr.Accordion("Figures from updated reports", open=False):
745
+ with gr.Row():
746
+ gr.Image(value=_report_image("aspect_distribution.png"), label="Aspect sentiment distribution", interactive=False)
747
+ gr.Image(value=_report_image("category_aspect_negative_heatmap.png"), label="Negative share by category x aspect", interactive=False)
748
+ with gr.Row():
749
+ gr.Image(value=_report_image("category_aspect_positive_heatmap.png"), label="Positive share by category x aspect", interactive=False)
750
+ gr.Image(value=_report_image("confusion_matrix_proposed_overall_head.png"), label="Proposed overall confusion matrix", interactive=False)
751
+ with gr.Accordion("Report file groups", open=False):
752
+ gr.Dataframe(headers=["Group", "Files"], value=report_asset_rows(), interactive=False)
753
  refresh_research = gr.Button("Refresh Research Metrics", variant="primary")
754
+ refresh_research.click(refresh_research_outputs, outputs=[research_cards, overall_table, aspect_table, ablation_table, meta_source_table])
755
  demo.load(consumer_product_view, [product_select, consumer_aspect], [product_detail, aspect_html, evidence_html, consumer_table])
756
  demo.load(merchant_product_scores, merchant_metric, merchant_scores)
757
  demo.load(filter_products, [filter_aspect, filter_sentiment, filter_category, filter_tags, min_rating], [filter_table, filter_summary])
 
761
  demo = build_app()
762
 
763
  if __name__ == "__main__":
764
+ demo.launch(ssr_mode=False)
765
 
data/demo_products.json ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "Real Review 01 - Strands",
4
+ "category": "Strands",
5
+ "features": "TRENDY NECKLACES: Delicate layered chain necklace features mixed faceted beads, delicate stone accents, lovely flowers and heart embellished with woven mixed multi-colored charms. Hand crafted from polished gold-tone metal, glass and plastic LIGHTWEIGHT NECKLACES : Effortless and lightweight necklaces easy to put on and take off. Necklace has an adjustable lobster clasp closure MEASUREMENTS : 16in length with adjusta",
6
+ "categories": "Clothing, Shoes & Jewelry > Women > Jewelry > Necklaces > Strands",
7
+ "price": 35.99,
8
+ "average_rating": 4.4,
9
+ "rating_number": 4695.0,
10
+ "review": "Bad quality control I ordered despite all the bad reviews. Well that didn’t work as it was just pack in a baggie as like most of the reviews state. Then the blue and white flowers with charms were all attached backwards. I am in the process of returning it. I will not be asking for an exchange as I do not wish to keep returning this item until I get a good one. So very sad as this could have been a beautiful necklace. Plus with as expensive as this is you would think it would have better packaging. I have bought for much cheaper with nice packaging. Unfortunately I will not be buying any more of this brand as it had put a bad taste in my mouth. Do better!",
11
+ "source": "real held-out explanation example",
12
+ "tags": [
13
+ "jewelry"
14
+ ]
15
+ },
16
+ {
17
+ "name": "Real Review 02 - Rash Guard Shirts",
18
+ "category": "Rash Guard Shirts",
19
+ "features": "100% Polyester Pull On closure Machine Wash The fabric rating UPF 50+ protects your skin from the harmful UVA/UVB rays,keeping you cool while outdoors in the direct sunlight.Great for swimming as a cover shirt,light shirt for hiking. Technical fabric wicks moisture away from your skin and dries quickly for extra comfort, keep you cool and dry on running or workout. Raglan sleeves and no tag collar/flat-seam construct",
20
+ "categories": "Clothing, Shoes & Jewelry > Women > Clothing > Swimsuits & Cover Ups > Rash Guard Shirts",
21
+ "price": 19.99,
22
+ "average_rating": 4.4,
23
+ "rating_number": 2481.0,
24
+ "review": "Very small for size and returned Too tight for size and Iborderwd extra large.",
25
+ "source": "real held-out explanation example",
26
+ "tags": [
27
+ "polyester",
28
+ "shirt",
29
+ "jewelry"
30
+ ]
31
+ },
32
+ {
33
+ "name": "Real Review 03 - Identification",
34
+ "category": "Identification",
35
+ "features": "Medical Bracelets Size: Width 0.55 Inches(14mm), Length 6-8.2 inches(150-215mm). Material: 316L Stainless Steel O Chain, Never Rust, Sturdy and Durable, High Quality. PEOPLE WITH THE FOLLOWING CONDITIONS SHOULD WEAR A MEDICAL ID JEWELRY: Alzheimer's, Autism/Special Needs Children, Blood Disorders, Blood Thinners, Diabetes, Dementia, Drug Allergies (i.e. Penicillin, Morphine, Sulfa), Emphysema/Breathing Disorders, Epi",
36
+ "categories": "Clothing, Shoes & Jewelry > Women > Jewelry > Bracelets > Identification",
37
+ "price": 13.99,
38
+ "average_rating": 4.1,
39
+ "rating_number": 2743.0,
40
+ "review": "Not great Not comfortable to wear. The information portion of the bracelet has very sharp edges. Adjusting the length requires a tool. You can't push down the locking part by hand. So broken clasp after long wait. They did issue a refund without requiring me to return the item",
41
+ "source": "real held-out explanation example",
42
+ "tags": [
43
+ "jewelry"
44
+ ]
45
+ },
46
+ {
47
+ "name": "Real Review 04 - Wallets",
48
+ "category": "Wallets",
49
+ "features": "Aluminum lining Wet Wipe Clean High grade plastic wallet with aluminum shell, customed design. Integrated RFID repellant technology protects you from Credit-Card scanning thieves. Seven secure slots fold out accordion style and hold up to 9 cards. If there is any issue with quality of wallet, please contact us and we will replace it. Standard Size: 2.75\" x 4.25\" x 0.75\"",
50
+ "categories": "Clothing, Shoes & Jewelry > Men > Accessories > Wallets, Card Cases & Money Organizers > Wallets",
51
+ "price": 8.99,
52
+ "average_rating": 4.1,
53
+ "rating_number": 793.0,
54
+ "review": "Two Stars loved it until the pin fell out after having it only a month",
55
+ "source": "real held-out explanation example",
56
+ "tags": [
57
+ "wallet",
58
+ "jewelry"
59
+ ]
60
+ },
61
+ {
62
+ "name": "Real Review 05 - Cocktail",
63
+ "category": "Cocktail",
64
+ "features": "Fabric type: Great Elasticity, 69% Cotton, 26% Nylon, 5% Spandex. Hand Wash Only, Low Temperature for Ironing. Hidden back zipper closure Sweetheart neckline, above the knee, hidden back zipper, sexy v-back, cold shoulder, short sleeves A-line dress. A full skater skirt creates a flattering fit and flare silhouette make you look chic yet elegant. This semi-formal party dress suitable for cocktail party, wedding guest",
65
+ "categories": "Clothing, Shoes & Jewelry > Women > Clothing > Dresses > Cocktail",
66
+ "price": 0.0,
67
+ "average_rating": 4.2,
68
+ "rating_number": 4399.0,
69
+ "review": "Okay Not the best quality, pretty skimpy",
70
+ "source": "real held-out explanation example",
71
+ "tags": [
72
+ "cotton",
73
+ "dress",
74
+ "jewelry",
75
+ "formal"
76
+ ]
77
+ },
78
+ {
79
+ "name": "Real Review 06 - Aprons",
80
+ "category": "Aprons",
81
+ "features": "65% Polyester, 35% Cotton Imported waist tie closure Durable Cooking Apron - Chef Works aprons are pre-tested for strength and durability. Use as a waitress apron in front of house or chef apron in back of house. Comfortable Fit - Waist tie offers the ability to fit to various body sizes with comfort and versatility. This is a unisex apron women and men can both wear. Full-Body Coverage - 34-inch height by 27-inch wi",
82
+ "categories": "Clothing, Shoes & Jewelry > Uniforms, Work & Safety > Clothing > Food Service > Aprons",
83
+ "price": 16.99,
84
+ "average_rating": 4.6,
85
+ "rating_number": 2464.0,
86
+ "review": "Okay don't have very much to say about this on ipad version, other than its okay",
87
+ "source": "real held-out explanation example",
88
+ "tags": [
89
+ "cotton",
90
+ "polyester",
91
+ "jewelry"
92
+ ]
93
+ },
94
+ {
95
+ "name": "Real Review 07 - Shoe Horns & Boot Jacks",
96
+ "category": "Shoe Horns & Boot Jacks",
97
+ "features": "",
98
+ "categories": "Clothing, Shoes & Jewelry > Shoe, Jewelry & Watch Accessories > Shoe Care & Accessories > Shoe Horns & Boot Jacks",
99
+ "price": 0.0,
100
+ "average_rating": 3.9,
101
+ "rating_number": 29.0,
102
+ "review": "At the current price point, this is a decent shoe horn I was originally going to rate this 3 stars. However, for the current price of $7.99, I think this is a decent shoe horn. It is metal with a silicone covering on the upper part. It is also perfect for young children or adults who do not mind bending down to use a shoe horn. It is certainly better than plastic. This is packaged with a big cheap cinch-tie bag. I have no idea why this is included as probably 30 of these shoe horns could fit in that bag. This horn has the potential to bend because it is not super sturdy. I have a similar one with a wooden handle and that one is all bent just from use. My recommendation if you want a great shoe horn that is sturdier and can be used standing up, is to get this [[ASIN:B01M154SED 21\" heavy duty one]] for the current price of $20.99 plus 5% off. I own one of these and had I purchased that one first, I would have never ordered any other. Do note, however, that it is very large and comes up to one's knees but it is fantastic. In summary, this one is decent and functional at the low price point but for something more sturdy and that will last longer, look into the other one I recommended.",
103
+ "source": "real held-out explanation example",
104
+ "tags": [
105
+ "jewelry"
106
+ ]
107
+ },
108
+ {
109
+ "name": "Real Review 08 - T-Shirts",
110
+ "category": "T-Shirts",
111
+ "features": "100% Polyester Imported UA Base 2.0 Active Baselayer is lightweight, flexible & breathable for high activity performance in cool conditions UA Scent Control Technology to keep you undetected in all pursuits Soft, brushed grid interior traps air against your skin, closely managing your body's microclimate to keep you warm & comfortable Material wicks sweat & dries really fast 4-way stretch construction moves better in",
112
+ "categories": "Clothing, Shoes & Jewelry > Men > Clothing > Active > Active Shirts & Tees > T-Shirts",
113
+ "price": 49.99,
114
+ "average_rating": 4.8,
115
+ "rating_number": 911.0,
116
+ "review": "Good Base Layer This is a comfortable shirt. Ideal as a base layer it is made of soft, stretchy material. It is not too tight. It conforms to the body and keeps you warm and dry. Great for cold weather.",
117
+ "source": "real held-out explanation example",
118
+ "tags": [
119
+ "polyester",
120
+ "stretch",
121
+ "soft",
122
+ "breathable",
123
+ "warm",
124
+ "shirt",
125
+ "jewelry"
126
+ ]
127
+ },
128
+ {
129
+ "name": "Real Review 09 - Fashion Sneakers",
130
+ "category": "Fashion Sneakers",
131
+ "features": "Imported Synthetic sole TPR Outsole, Stretch Cotton Laces Closure, Removable Twill Covered EVA, Vegan YOUR NEW FAVORITE WOMEN'S SNEAKERS: Enjoy walking around with the Vegan Pismo Casual Sneakers with stretch laces, metal eyelets, and eco-friendly canvas uppers available in different colors to match your daily fashion mood. VIONIC WOMEN SHOES: Vionic brings together style and science, combining innovative biomechanic",
132
+ "categories": "Clothing, Shoes & Jewelry > Women > Shoes > Fashion Sneakers",
133
+ "price": 49.0,
134
+ "average_rating": 4.6,
135
+ "rating_number": 4004.0,
136
+ "review": "problem for people with a high instep i love the softness and flexibility of this shoe. i have a high instep, and these shoes have elastic laces. i ordered a wide (i do not have a wide foot) in order to not have the elastic laces cut off my circulation. you can cut the laces out and put in regular laces. shoes would look cute with pink, yellow, or orange laces. red even! feels good in my arch, and pretty comfy overall.",
137
+ "source": "real held-out explanation example",
138
+ "tags": [
139
+ "cotton",
140
+ "stretch",
141
+ "soft",
142
+ "sneakers",
143
+ "jewelry",
144
+ "casual"
145
+ ]
146
+ },
147
+ {
148
+ "name": "Real Review 10 - Board Shorts",
149
+ "category": "Board Shorts",
150
+ "features": "88% Polyester, 12% Spandex Imported Drawstring closure Machine Wash Kanu comfort tech qucik dry UPF 50+ Stretch Microfiber Cargo Pocket for storage.",
151
+ "categories": "Clothing, Shoes & Jewelry > Women > Clothing > Swimsuits & Cover Ups > Board Shorts",
152
+ "price": 0.0,
153
+ "average_rating": 4.1,
154
+ "rating_number": 4126.0,
155
+ "review": "Cool, relaxed comfort The Kanu Surf Women's plus size Marina solid stretch Boardshort is perfect for lounging around the house or walking the dog. It is exceptionally cool during the summer and has that extra stretch for comfort. Also, like the elastic waistband in the back.",
156
+ "source": "real held-out explanation example",
157
+ "tags": [
158
+ "polyester",
159
+ "stretch",
160
+ "shorts",
161
+ "jewelry",
162
+ "plus size"
163
+ ]
164
+ }
165
+ ]
reports/aspect_level_proposed_vs_no_meta.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ aspect,proposed_macro_f1,acsa_no_meta_macro_f1,delta_macro_f1,proposed_accuracy,acsa_no_meta_accuracy,delta_accuracy
2
+ SIZE,0.8688511032834313,0.783168541467604,0.08568256181582734,0.876,0.7674,0.10860000000000003
3
+ MATERIAL,0.8351109775214702,0.7558022811037001,0.07930869641777016,0.8648666666666667,0.7645333333333333,0.10033333333333339
4
+ QUALITY,0.7742721084444115,0.7099842589878541,0.06428784945655741,0.8063333333333333,0.718,0.08833333333333337
5
+ APPEARANCE,0.7866997719239698,0.6901346425171296,0.09656512940684014,0.8634666666666667,0.7409333333333333,0.12253333333333338
6
+ STYLE,0.7622600117091981,0.6849172239194514,0.07734278778974668,0.8287333333333333,0.7234666666666667,0.10526666666666662
7
+ VALUE,0.7179350422128157,0.7171099329708497,0.0008251092419659933,0.8483333333333334,0.8563333333333333,-0.007999999999999896
reports/explanation_attention.html CHANGED
The diff for this file is too large to render. See raw diff
 
reports/explanation_attention_meta_source_summary.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ aspect,top_meta_source,n_rows,mean_top_meta_weight,mean_attention_focus,mean_attention_margin,mean_attention_entropy,aspect_total,source_share
2
+ APPEARANCE,features,50,0.5535691463947296,0.3152554518269078,0.16856914888540328,0.6847445481730923,50,1.0
3
+ MATERIAL,features,50,0.5100441455841065,0.14035479778646262,0.20505228016477986,0.8596452022135374,50,1.0
4
+ QUALITY,features,50,0.5549998760223389,0.27058217949495345,0.2072079706295289,0.7294178205050466,50,1.0
5
+ SIZE,features,50,0.554997307062149,0.23750944781645117,0.23498356799885556,0.7624905521835488,50,1.0
6
+ STYLE,features,50,0.5321753132343292,0.2766912814375451,0.14888458367986146,0.7233087185624549,50,1.0
7
+ VALUE,features,50,0.5149888694286346,0.11744743360918963,0.2349888691830967,0.8825525663908104,50,1.0
reports/explanation_attention_summary.csv CHANGED
The diff for this file is too large to render. See raw diff
 
reports/explanation_ig.html CHANGED
The diff for this file is too large to render. See raw diff
 
reports/explanation_ig_meta_source_summary.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ aspect,top_meta_source,n_rows,mean_top_meta_weight,mean_attention_focus,mean_attention_margin,mean_attention_entropy,aspect_total,source_share
2
+ APPEARANCE,features,50,0.5535691463947296,0.3152554518269078,0.16856914888540328,0.6847445481730923,50,1.0
3
+ MATERIAL,features,50,0.5100441455841065,0.14035479778646262,0.20505228016477986,0.8596452022135374,50,1.0
4
+ QUALITY,features,50,0.5549998760223389,0.27058217949495345,0.2072079706295289,0.7294178205050466,50,1.0
5
+ SIZE,features,50,0.554997307062149,0.23750944781645117,0.23498356799885556,0.7624905521835488,50,1.0
6
+ STYLE,features,50,0.5321753132343292,0.2766912814375451,0.14888458367986146,0.7233087185624549,50,1.0
7
+ VALUE,features,50,0.5149888694286346,0.11744743360918963,0.2349888691830967,0.8825525663908104,50,1.0
reports/explanation_ig_summary.csv CHANGED
The diff for this file is too large to render. See raw diff
 
reports/overall_model_comparison.csv ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ model,macro_f1,accuracy
2
+ Baseline_2_BERT_overall_3class,0.7284109895875363,0.8962
3
+ Proposed_BERT_Meta_Fusion__overall_head,0.7176867208554908,0.8942666666666667
4
+ Baseline_1_TFIDF_LogReg,0.6227417071292987,0.8090666666666667
5
+ Proposed_BERT_Meta_Fusion__aggregated_to_overall_(reference),0.5224811910366102,0.6916666666666667
6
+ Baseline_3_BERT_ACSA_no_meta__aggregated_to_overall,0.503449963221516,0.6606
reports_for_frontend/01_evaluation/aspect_level_proposed_vs_no_meta.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ aspect,proposed_macro_f1,acsa_no_meta_macro_f1,delta_macro_f1,proposed_accuracy,acsa_no_meta_accuracy,delta_accuracy
2
+ SIZE,0.8688511032834313,0.783168541467604,0.08568256181582734,0.876,0.7674,0.10860000000000003
3
+ MATERIAL,0.8351109775214702,0.7558022811037001,0.07930869641777016,0.8648666666666667,0.7645333333333333,0.10033333333333339
4
+ QUALITY,0.7742721084444115,0.7099842589878541,0.06428784945655741,0.8063333333333333,0.718,0.08833333333333337
5
+ APPEARANCE,0.7866997719239698,0.6901346425171296,0.09656512940684014,0.8634666666666667,0.7409333333333333,0.12253333333333338
6
+ STYLE,0.7622600117091981,0.6849172239194514,0.07734278778974668,0.8287333333333333,0.7234666666666667,0.10526666666666662
7
+ VALUE,0.7179350422128157,0.7171099329708497,0.0008251092419659933,0.8483333333333334,0.8563333333333333,-0.007999999999999896
reports_for_frontend/01_evaluation/evaluation_comparison.json ADDED
@@ -0,0 +1,689 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "overall_3class_comparison": {
3
+ "Baseline_1_TFIDF_LogReg": {
4
+ "macro_f1": 0.6227417071292987,
5
+ "accuracy": 0.8090666666666667
6
+ },
7
+ "Baseline_2_BERT_overall_3class": {
8
+ "macro_f1": 0.7284109895875363,
9
+ "accuracy": 0.8962
10
+ },
11
+ "Baseline_3_BERT_ACSA_no_meta__aggregated_to_overall": {
12
+ "macro_f1": 0.503449963221516,
13
+ "accuracy": 0.6606
14
+ },
15
+ "Proposed_BERT_Meta_Fusion__overall_head": {
16
+ "macro_f1": 0.7176867208554908,
17
+ "accuracy": 0.8942666666666667
18
+ },
19
+ "Proposed_BERT_Meta_Fusion__aggregated_to_overall_(reference)": {
20
+ "macro_f1": 0.5224811910366102,
21
+ "accuracy": 0.6916666666666667
22
+ }
23
+ },
24
+ "proposed_per_aspect": {
25
+ "per_aspect": {
26
+ "SIZE": {
27
+ "macro_f1": 0.8688511032834313,
28
+ "accuracy": 0.876,
29
+ "confusion_matrix": [
30
+ [
31
+ 3919,
32
+ 392,
33
+ 177
34
+ ],
35
+ [
36
+ 650,
37
+ 6782,
38
+ 397
39
+ ],
40
+ [
41
+ 138,
42
+ 106,
43
+ 2439
44
+ ]
45
+ ],
46
+ "report": {
47
+ "Not_Mentioned": {
48
+ "precision": 0.8325897599320161,
49
+ "recall": 0.8732174688057041,
50
+ "f1-score": 0.8524197933659597,
51
+ "support": 4488.0
52
+ },
53
+ "Positive": {
54
+ "precision": 0.9315934065934066,
55
+ "recall": 0.8662664452675949,
56
+ "f1-score": 0.8977430670461315,
57
+ "support": 7829.0
58
+ },
59
+ "Negative": {
60
+ "precision": 0.8094922004646532,
61
+ "recall": 0.9090570257174805,
62
+ "f1-score": 0.8563904494382022,
63
+ "support": 2683.0
64
+ },
65
+ "accuracy": 0.876,
66
+ "macro avg": {
67
+ "precision": 0.857891788996692,
68
+ "recall": 0.8828469799302598,
69
+ "f1-score": 0.8688511032834313,
70
+ "support": 15000.0
71
+ },
72
+ "weighted avg": {
73
+ "precision": 0.8801316797760889,
74
+ "recall": 0.876,
75
+ "f1-score": 0.8767857386915525,
76
+ "support": 15000.0
77
+ }
78
+ }
79
+ },
80
+ "MATERIAL": {
81
+ "macro_f1": 0.8351109775214702,
82
+ "accuracy": 0.8648666666666667,
83
+ "confusion_matrix": [
84
+ [
85
+ 3525,
86
+ 486,
87
+ 247
88
+ ],
89
+ [
90
+ 577,
91
+ 7811,
92
+ 446
93
+ ],
94
+ [
95
+ 176,
96
+ 95,
97
+ 1637
98
+ ]
99
+ ],
100
+ "report": {
101
+ "Not_Mentioned": {
102
+ "precision": 0.8239831697054698,
103
+ "recall": 0.8278534523250353,
104
+ "f1-score": 0.8259137769447048,
105
+ "support": 4258.0
106
+ },
107
+ "Positive": {
108
+ "precision": 0.930767397521449,
109
+ "recall": 0.8841974190627122,
110
+ "f1-score": 0.9068849413677,
111
+ "support": 8834.0
112
+ },
113
+ "Negative": {
114
+ "precision": 0.7025751072961374,
115
+ "recall": 0.8579664570230608,
116
+ "f1-score": 0.7725342142520056,
117
+ "support": 1908.0
118
+ },
119
+ "accuracy": 0.8648666666666667,
120
+ "macro avg": {
121
+ "precision": 0.819108558174352,
122
+ "recall": 0.8566724428036028,
123
+ "f1-score": 0.8351109775214702,
124
+ "support": 15000.0
125
+ },
126
+ "weighted avg": {
127
+ "precision": 0.8714288554020935,
128
+ "recall": 0.8648666666666667,
129
+ "f1-score": 0.8668105143377094,
130
+ "support": 15000.0
131
+ }
132
+ }
133
+ },
134
+ "QUALITY": {
135
+ "macro_f1": 0.7742721084444115,
136
+ "accuracy": 0.8063333333333333,
137
+ "confusion_matrix": [
138
+ [
139
+ 6322,
140
+ 1106,
141
+ 462
142
+ ],
143
+ [
144
+ 958,
145
+ 4841,
146
+ 190
147
+ ],
148
+ [
149
+ 141,
150
+ 48,
151
+ 932
152
+ ]
153
+ ],
154
+ "report": {
155
+ "Not_Mentioned": {
156
+ "precision": 0.85190675111171,
157
+ "recall": 0.8012674271229404,
158
+ "f1-score": 0.8258115080660963,
159
+ "support": 7890.0
160
+ },
161
+ "Positive": {
162
+ "precision": 0.8075062552126773,
163
+ "recall": 0.8083152446151277,
164
+ "f1-score": 0.8079105473965287,
165
+ "support": 5989.0
166
+ },
167
+ "Negative": {
168
+ "precision": 0.5883838383838383,
169
+ "recall": 0.8314005352363961,
170
+ "f1-score": 0.68909426987061,
171
+ "support": 1121.0
172
+ },
173
+ "accuracy": 0.8063333333333333,
174
+ "macro avg": {
175
+ "precision": 0.7492656149027419,
176
+ "recall": 0.8136610689914882,
177
+ "f1-score": 0.7742721084444115,
178
+ "support": 15000.0
179
+ },
180
+ "weighted avg": {
181
+ "precision": 0.8144851674378932,
182
+ "recall": 0.8063333333333333,
183
+ "f1-score": 0.8084469162349509,
184
+ "support": 15000.0
185
+ }
186
+ }
187
+ },
188
+ "APPEARANCE": {
189
+ "macro_f1": 0.7866997719239698,
190
+ "accuracy": 0.8634666666666667,
191
+ "confusion_matrix": [
192
+ [
193
+ 7598,
194
+ 606,
195
+ 366
196
+ ],
197
+ [
198
+ 783,
199
+ 4841,
200
+ 131
201
+ ],
202
+ [
203
+ 118,
204
+ 44,
205
+ 513
206
+ ]
207
+ ],
208
+ "report": {
209
+ "Not_Mentioned": {
210
+ "precision": 0.893987527944464,
211
+ "recall": 0.886581096849475,
212
+ "f1-score": 0.8902689085476595,
213
+ "support": 8570.0
214
+ },
215
+ "Positive": {
216
+ "precision": 0.8816244764159534,
217
+ "recall": 0.8411815812337098,
218
+ "f1-score": 0.8609283300729148,
219
+ "support": 5755.0
220
+ },
221
+ "Negative": {
222
+ "precision": 0.5079207920792079,
223
+ "recall": 0.76,
224
+ "f1-score": 0.6089020771513353,
225
+ "support": 675.0
226
+ },
227
+ "accuracy": 0.8634666666666667,
228
+ "macro avg": {
229
+ "precision": 0.7611775988132085,
230
+ "recall": 0.8292542260277282,
231
+ "f1-score": 0.7866997719239698,
232
+ "support": 15000.0
233
+ },
234
+ "weighted avg": {
235
+ "precision": 0.8718712340607555,
236
+ "recall": 0.8634666666666667,
237
+ "f1-score": 0.8663503991933479,
238
+ "support": 15000.0
239
+ }
240
+ }
241
+ },
242
+ "STYLE": {
243
+ "macro_f1": 0.7622600117091981,
244
+ "accuracy": 0.8287333333333333,
245
+ "confusion_matrix": [
246
+ [
247
+ 6595,
248
+ 823,
249
+ 438
250
+ ],
251
+ [
252
+ 911,
253
+ 5219,
254
+ 235
255
+ ],
256
+ [
257
+ 115,
258
+ 47,
259
+ 617
260
+ ]
261
+ ],
262
+ "report": {
263
+ "Not_Mentioned": {
264
+ "precision": 0.8653719984254035,
265
+ "recall": 0.8394857433808554,
266
+ "f1-score": 0.8522323447696583,
267
+ "support": 7856.0
268
+ },
269
+ "Positive": {
270
+ "precision": 0.8571193956314666,
271
+ "recall": 0.8199528672427338,
272
+ "f1-score": 0.8381242974144854,
273
+ "support": 6365.0
274
+ },
275
+ "Negative": {
276
+ "precision": 0.4782945736434108,
277
+ "recall": 0.79204107830552,
278
+ "f1-score": 0.5964233929434509,
279
+ "support": 779.0
280
+ },
281
+ "accuracy": 0.8287333333333333,
282
+ "macro avg": {
283
+ "precision": 0.7335953225667603,
284
+ "recall": 0.8171598963097031,
285
+ "f1-score": 0.7622600117091981,
286
+ "support": 15000.0
287
+ },
288
+ "weighted avg": {
289
+ "precision": 0.8417679230461648,
290
+ "recall": 0.8287333333333333,
291
+ "f1-score": 0.8329608184437722,
292
+ "support": 15000.0
293
+ }
294
+ }
295
+ },
296
+ "VALUE": {
297
+ "macro_f1": 0.7179350422128157,
298
+ "accuracy": 0.8483333333333334,
299
+ "confusion_matrix": [
300
+ [
301
+ 10218,
302
+ 1191,
303
+ 372
304
+ ],
305
+ [
306
+ 511,
307
+ 2162,
308
+ 95
309
+ ],
310
+ [
311
+ 72,
312
+ 34,
313
+ 345
314
+ ]
315
+ ],
316
+ "report": {
317
+ "Not_Mentioned": {
318
+ "precision": 0.9460235163410795,
319
+ "recall": 0.8673287496816908,
320
+ "f1-score": 0.9049685590293154,
321
+ "support": 11781.0
322
+ },
323
+ "Positive": {
324
+ "precision": 0.6383229997047535,
325
+ "recall": 0.7810693641618497,
326
+ "f1-score": 0.7025182778229082,
327
+ "support": 2768.0
328
+ },
329
+ "Negative": {
330
+ "precision": 0.4248768472906404,
331
+ "recall": 0.7649667405764967,
332
+ "f1-score": 0.5463182897862233,
333
+ "support": 451.0
334
+ },
335
+ "accuracy": 0.8483333333333334,
336
+ "macro avg": {
337
+ "precision": 0.6697411211121578,
338
+ "recall": 0.8044549514733458,
339
+ "f1-score": 0.7179350422128157,
340
+ "support": 15000.0
341
+ },
342
+ "weighted avg": {
343
+ "precision": 0.8735733711550063,
344
+ "recall": 0.8483333333333334,
345
+ "f1-score": 0.8568263157087841,
346
+ "support": 15000.0
347
+ }
348
+ }
349
+ }
350
+ },
351
+ "overall": {
352
+ "mean_macro_f1": 0.790854835849216,
353
+ "mean_accuracy": 0.8479555555555556
354
+ }
355
+ },
356
+ "acsa_no_meta_per_aspect": {
357
+ "per_aspect": {
358
+ "SIZE": {
359
+ "macro_f1": 0.783168541467604,
360
+ "accuracy": 0.7674,
361
+ "confusion_matrix": [
362
+ [
363
+ 3891,
364
+ 414,
365
+ 183
366
+ ],
367
+ [
368
+ 2322,
369
+ 5203,
370
+ 304
371
+ ],
372
+ [
373
+ 169,
374
+ 97,
375
+ 2417
376
+ ]
377
+ ],
378
+ "report": {
379
+ "Not_Mentioned": {
380
+ "precision": 0.6096834848010029,
381
+ "recall": 0.8669786096256684,
382
+ "f1-score": 0.7159153633854646,
383
+ "support": 4488.0
384
+ },
385
+ "Positive": {
386
+ "precision": 0.9105705285264263,
387
+ "recall": 0.6645804061821433,
388
+ "f1-score": 0.7683674222845751,
389
+ "support": 7829.0
390
+ },
391
+ "Negative": {
392
+ "precision": 0.8323002754820936,
393
+ "recall": 0.900857249347745,
394
+ "f1-score": 0.8652228387327725,
395
+ "support": 2683.0
396
+ },
397
+ "accuracy": 0.7674,
398
+ "macro avg": {
399
+ "precision": 0.7841847629365075,
400
+ "recall": 0.8108054217185189,
401
+ "f1-score": 0.783168541467604,
402
+ "support": 15000.0
403
+ },
404
+ "weighted avg": {
405
+ "precision": 0.8065451857825834,
406
+ "recall": 0.7674,
407
+ "f1-score": 0.7699979717506622,
408
+ "support": 15000.0
409
+ }
410
+ }
411
+ },
412
+ "MATERIAL": {
413
+ "macro_f1": 0.7558022811037001,
414
+ "accuracy": 0.7645333333333333,
415
+ "confusion_matrix": [
416
+ [
417
+ 3138,
418
+ 882,
419
+ 238
420
+ ],
421
+ [
422
+ 1764,
423
+ 6721,
424
+ 349
425
+ ],
426
+ [
427
+ 205,
428
+ 94,
429
+ 1609
430
+ ]
431
+ ],
432
+ "report": {
433
+ "Not_Mentioned": {
434
+ "precision": 0.614450753867241,
435
+ "recall": 0.7369657116016909,
436
+ "f1-score": 0.6701548318206086,
437
+ "support": 4258.0
438
+ },
439
+ "Positive": {
440
+ "precision": 0.8731973496167338,
441
+ "recall": 0.7608105048675572,
442
+ "f1-score": 0.8131389510616418,
443
+ "support": 8834.0
444
+ },
445
+ "Negative": {
446
+ "precision": 0.732695810564663,
447
+ "recall": 0.8432914046121593,
448
+ "f1-score": 0.7841130604288499,
449
+ "support": 1908.0
450
+ },
451
+ "accuracy": 0.7645333333333333,
452
+ "macro avg": {
453
+ "precision": 0.7401146380162126,
454
+ "recall": 0.7803558736938024,
455
+ "f1-score": 0.7558022811037001,
456
+ "support": 15000.0
457
+ },
458
+ "weighted avg": {
459
+ "precision": 0.7818760202025543,
460
+ "recall": 0.7645333333333333,
461
+ "f1-score": 0.7688584324579294,
462
+ "support": 15000.0
463
+ }
464
+ }
465
+ },
466
+ "QUALITY": {
467
+ "macro_f1": 0.7099842589878541,
468
+ "accuracy": 0.718,
469
+ "confusion_matrix": [
470
+ [
471
+ 5799,
472
+ 1648,
473
+ 443
474
+ ],
475
+ [
476
+ 1797,
477
+ 4068,
478
+ 124
479
+ ],
480
+ [
481
+ 159,
482
+ 59,
483
+ 903
484
+ ]
485
+ ],
486
+ "report": {
487
+ "Not_Mentioned": {
488
+ "precision": 0.7477756286266924,
489
+ "recall": 0.7349809885931559,
490
+ "f1-score": 0.7413231064237775,
491
+ "support": 7890.0
492
+ },
493
+ "Positive": {
494
+ "precision": 0.7044155844155844,
495
+ "recall": 0.6792452830188679,
496
+ "f1-score": 0.6916014960897654,
497
+ "support": 5989.0
498
+ },
499
+ "Negative": {
500
+ "precision": 0.6142857142857143,
501
+ "recall": 0.8055307760927743,
502
+ "f1-score": 0.6970281744500193,
503
+ "support": 1121.0
504
+ },
505
+ "accuracy": 0.718,
506
+ "macro avg": {
507
+ "precision": 0.6888256424426636,
508
+ "recall": 0.7399190159015993,
509
+ "f1-score": 0.7099842589878541,
510
+ "support": 15000.0
511
+ },
512
+ "weighted avg": {
513
+ "precision": 0.7204872620429217,
514
+ "recall": 0.718,
515
+ "f1-score": 0.7181606168882454,
516
+ "support": 15000.0
517
+ }
518
+ }
519
+ },
520
+ "APPEARANCE": {
521
+ "macro_f1": 0.6901346425171296,
522
+ "accuracy": 0.7409333333333333,
523
+ "confusion_matrix": [
524
+ [
525
+ 6679,
526
+ 1462,
527
+ 429
528
+ ],
529
+ [
530
+ 1726,
531
+ 3941,
532
+ 88
533
+ ],
534
+ [
535
+ 146,
536
+ 35,
537
+ 494
538
+ ]
539
+ ],
540
+ "report": {
541
+ "Not_Mentioned": {
542
+ "precision": 0.7810782364635716,
543
+ "recall": 0.7793465577596266,
544
+ "f1-score": 0.7802114362478827,
545
+ "support": 8570.0
546
+ },
547
+ "Positive": {
548
+ "precision": 0.7247149687385068,
549
+ "recall": 0.6847958297132928,
550
+ "f1-score": 0.7041901188242652,
551
+ "support": 5755.0
552
+ },
553
+ "Negative": {
554
+ "precision": 0.4886251236399604,
555
+ "recall": 0.7318518518518519,
556
+ "f1-score": 0.5860023724792408,
557
+ "support": 675.0
558
+ },
559
+ "accuracy": 0.7409333333333333,
560
+ "macro avg": {
561
+ "precision": 0.6648061096140129,
562
+ "recall": 0.7319980797749238,
563
+ "f1-score": 0.6901346425171296,
564
+ "support": 15000.0
565
+ },
566
+ "weighted avg": {
567
+ "precision": 0.7462931393359925,
568
+ "recall": 0.7409333333333333,
569
+ "f1-score": 0.7423051829267658,
570
+ "support": 15000.0
571
+ }
572
+ }
573
+ },
574
+ "STYLE": {
575
+ "macro_f1": 0.6849172239194514,
576
+ "accuracy": 0.7234666666666667,
577
+ "confusion_matrix": [
578
+ [
579
+ 6020,
580
+ 1403,
581
+ 433
582
+ ],
583
+ [
584
+ 1958,
585
+ 4249,
586
+ 158
587
+ ],
588
+ [
589
+ 150,
590
+ 46,
591
+ 583
592
+ ]
593
+ ],
594
+ "report": {
595
+ "Not_Mentioned": {
596
+ "precision": 0.7406496062992126,
597
+ "recall": 0.7662932790224033,
598
+ "f1-score": 0.7532532532532532,
599
+ "support": 7856.0
600
+ },
601
+ "Positive": {
602
+ "precision": 0.7457002457002457,
603
+ "recall": 0.6675569520816967,
604
+ "f1-score": 0.7044682085716655,
605
+ "support": 6365.0
606
+ },
607
+ "Negative": {
608
+ "precision": 0.49659284497444633,
609
+ "recall": 0.748395378690629,
610
+ "f1-score": 0.5970302099334357,
611
+ "support": 779.0
612
+ },
613
+ "accuracy": 0.7234666666666667,
614
+ "macro avg": {
615
+ "precision": 0.6609808989913015,
616
+ "recall": 0.7274152032649096,
617
+ "f1-score": 0.6849172239194514,
618
+ "support": 15000.0
619
+ },
620
+ "weighted avg": {
621
+ "precision": 0.7301180798135848,
622
+ "recall": 0.7234666666666667,
623
+ "f1-score": 0.7244389492436237,
624
+ "support": 15000.0
625
+ }
626
+ }
627
+ },
628
+ "VALUE": {
629
+ "macro_f1": 0.7171099329708497,
630
+ "accuracy": 0.8563333333333333,
631
+ "confusion_matrix": [
632
+ [
633
+ 10588,
634
+ 815,
635
+ 378
636
+ ],
637
+ [
638
+ 786,
639
+ 1924,
640
+ 58
641
+ ],
642
+ [
643
+ 81,
644
+ 37,
645
+ 333
646
+ ]
647
+ ],
648
+ "report": {
649
+ "Not_Mentioned": {
650
+ "precision": 0.9243125272806635,
651
+ "recall": 0.8987352516764281,
652
+ "f1-score": 0.9113444654845929,
653
+ "support": 11781.0
654
+ },
655
+ "Positive": {
656
+ "precision": 0.6930835734870316,
657
+ "recall": 0.6950867052023122,
658
+ "f1-score": 0.6940836940836941,
659
+ "support": 2768.0
660
+ },
661
+ "Negative": {
662
+ "precision": 0.43302990897269183,
663
+ "recall": 0.738359201773836,
664
+ "f1-score": 0.5459016393442623,
665
+ "support": 451.0
666
+ },
667
+ "accuracy": 0.8563333333333333,
668
+ "macro avg": {
669
+ "precision": 0.683475336580129,
670
+ "recall": 0.7773937195508588,
671
+ "f1-score": 0.7171099329708497,
672
+ "support": 15000.0
673
+ },
674
+ "weighted avg": {
675
+ "precision": 0.8668718469501523,
676
+ "recall": 0.8563333333333333,
677
+ "f1-score": 0.8602649634961278,
678
+ "support": 15000.0
679
+ }
680
+ }
681
+ }
682
+ },
683
+ "overall": {
684
+ "mean_macro_f1": 0.7235194801610981,
685
+ "mean_accuracy": 0.7617777777777778
686
+ }
687
+ },
688
+ "note": "The Proposed model jointly trains per-aspect heads and an overall sentiment head on the shared fused representation. The overall_head result is the primary overall metric. The aggregated_to_overall result (voting from per-aspect predictions) is included for reference. Baseline 3 vs Proposed isolates the marginal value of metadata cross-attention fusion."
689
+ }
reports_for_frontend/01_evaluation/overall_model_comparison.csv ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ model,macro_f1,accuracy
2
+ Baseline_2_BERT_overall_3class,0.7284109895875363,0.8962
3
+ Proposed_BERT_Meta_Fusion__overall_head,0.7176867208554908,0.8942666666666667
4
+ Baseline_1_TFIDF_LogReg,0.6227417071292987,0.8090666666666667
5
+ Proposed_BERT_Meta_Fusion__aggregated_to_overall_(reference),0.5224811910366102,0.6916666666666667
6
+ Baseline_3_BERT_ACSA_no_meta__aggregated_to_overall,0.503449963221516,0.6606
reports_for_frontend/01_evaluation/per_aspect_acsa_no_meta.json ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "per_aspect": {
3
+ "SIZE": {
4
+ "macro_f1": 0.783168541467604,
5
+ "accuracy": 0.7674,
6
+ "confusion_matrix": [
7
+ [
8
+ 3891,
9
+ 414,
10
+ 183
11
+ ],
12
+ [
13
+ 2322,
14
+ 5203,
15
+ 304
16
+ ],
17
+ [
18
+ 169,
19
+ 97,
20
+ 2417
21
+ ]
22
+ ],
23
+ "report": {
24
+ "Not_Mentioned": {
25
+ "precision": 0.6096834848010029,
26
+ "recall": 0.8669786096256684,
27
+ "f1-score": 0.7159153633854646,
28
+ "support": 4488.0
29
+ },
30
+ "Positive": {
31
+ "precision": 0.9105705285264263,
32
+ "recall": 0.6645804061821433,
33
+ "f1-score": 0.7683674222845751,
34
+ "support": 7829.0
35
+ },
36
+ "Negative": {
37
+ "precision": 0.8323002754820936,
38
+ "recall": 0.900857249347745,
39
+ "f1-score": 0.8652228387327725,
40
+ "support": 2683.0
41
+ },
42
+ "accuracy": 0.7674,
43
+ "macro avg": {
44
+ "precision": 0.7841847629365075,
45
+ "recall": 0.8108054217185189,
46
+ "f1-score": 0.783168541467604,
47
+ "support": 15000.0
48
+ },
49
+ "weighted avg": {
50
+ "precision": 0.8065451857825834,
51
+ "recall": 0.7674,
52
+ "f1-score": 0.7699979717506622,
53
+ "support": 15000.0
54
+ }
55
+ }
56
+ },
57
+ "MATERIAL": {
58
+ "macro_f1": 0.7558022811037001,
59
+ "accuracy": 0.7645333333333333,
60
+ "confusion_matrix": [
61
+ [
62
+ 3138,
63
+ 882,
64
+ 238
65
+ ],
66
+ [
67
+ 1764,
68
+ 6721,
69
+ 349
70
+ ],
71
+ [
72
+ 205,
73
+ 94,
74
+ 1609
75
+ ]
76
+ ],
77
+ "report": {
78
+ "Not_Mentioned": {
79
+ "precision": 0.614450753867241,
80
+ "recall": 0.7369657116016909,
81
+ "f1-score": 0.6701548318206086,
82
+ "support": 4258.0
83
+ },
84
+ "Positive": {
85
+ "precision": 0.8731973496167338,
86
+ "recall": 0.7608105048675572,
87
+ "f1-score": 0.8131389510616418,
88
+ "support": 8834.0
89
+ },
90
+ "Negative": {
91
+ "precision": 0.732695810564663,
92
+ "recall": 0.8432914046121593,
93
+ "f1-score": 0.7841130604288499,
94
+ "support": 1908.0
95
+ },
96
+ "accuracy": 0.7645333333333333,
97
+ "macro avg": {
98
+ "precision": 0.7401146380162126,
99
+ "recall": 0.7803558736938024,
100
+ "f1-score": 0.7558022811037001,
101
+ "support": 15000.0
102
+ },
103
+ "weighted avg": {
104
+ "precision": 0.7818760202025543,
105
+ "recall": 0.7645333333333333,
106
+ "f1-score": 0.7688584324579294,
107
+ "support": 15000.0
108
+ }
109
+ }
110
+ },
111
+ "QUALITY": {
112
+ "macro_f1": 0.7099842589878541,
113
+ "accuracy": 0.718,
114
+ "confusion_matrix": [
115
+ [
116
+ 5799,
117
+ 1648,
118
+ 443
119
+ ],
120
+ [
121
+ 1797,
122
+ 4068,
123
+ 124
124
+ ],
125
+ [
126
+ 159,
127
+ 59,
128
+ 903
129
+ ]
130
+ ],
131
+ "report": {
132
+ "Not_Mentioned": {
133
+ "precision": 0.7477756286266924,
134
+ "recall": 0.7349809885931559,
135
+ "f1-score": 0.7413231064237775,
136
+ "support": 7890.0
137
+ },
138
+ "Positive": {
139
+ "precision": 0.7044155844155844,
140
+ "recall": 0.6792452830188679,
141
+ "f1-score": 0.6916014960897654,
142
+ "support": 5989.0
143
+ },
144
+ "Negative": {
145
+ "precision": 0.6142857142857143,
146
+ "recall": 0.8055307760927743,
147
+ "f1-score": 0.6970281744500193,
148
+ "support": 1121.0
149
+ },
150
+ "accuracy": 0.718,
151
+ "macro avg": {
152
+ "precision": 0.6888256424426636,
153
+ "recall": 0.7399190159015993,
154
+ "f1-score": 0.7099842589878541,
155
+ "support": 15000.0
156
+ },
157
+ "weighted avg": {
158
+ "precision": 0.7204872620429217,
159
+ "recall": 0.718,
160
+ "f1-score": 0.7181606168882454,
161
+ "support": 15000.0
162
+ }
163
+ }
164
+ },
165
+ "APPEARANCE": {
166
+ "macro_f1": 0.6901346425171296,
167
+ "accuracy": 0.7409333333333333,
168
+ "confusion_matrix": [
169
+ [
170
+ 6679,
171
+ 1462,
172
+ 429
173
+ ],
174
+ [
175
+ 1726,
176
+ 3941,
177
+ 88
178
+ ],
179
+ [
180
+ 146,
181
+ 35,
182
+ 494
183
+ ]
184
+ ],
185
+ "report": {
186
+ "Not_Mentioned": {
187
+ "precision": 0.7810782364635716,
188
+ "recall": 0.7793465577596266,
189
+ "f1-score": 0.7802114362478827,
190
+ "support": 8570.0
191
+ },
192
+ "Positive": {
193
+ "precision": 0.7247149687385068,
194
+ "recall": 0.6847958297132928,
195
+ "f1-score": 0.7041901188242652,
196
+ "support": 5755.0
197
+ },
198
+ "Negative": {
199
+ "precision": 0.4886251236399604,
200
+ "recall": 0.7318518518518519,
201
+ "f1-score": 0.5860023724792408,
202
+ "support": 675.0
203
+ },
204
+ "accuracy": 0.7409333333333333,
205
+ "macro avg": {
206
+ "precision": 0.6648061096140129,
207
+ "recall": 0.7319980797749238,
208
+ "f1-score": 0.6901346425171296,
209
+ "support": 15000.0
210
+ },
211
+ "weighted avg": {
212
+ "precision": 0.7462931393359925,
213
+ "recall": 0.7409333333333333,
214
+ "f1-score": 0.7423051829267658,
215
+ "support": 15000.0
216
+ }
217
+ }
218
+ },
219
+ "STYLE": {
220
+ "macro_f1": 0.6849172239194514,
221
+ "accuracy": 0.7234666666666667,
222
+ "confusion_matrix": [
223
+ [
224
+ 6020,
225
+ 1403,
226
+ 433
227
+ ],
228
+ [
229
+ 1958,
230
+ 4249,
231
+ 158
232
+ ],
233
+ [
234
+ 150,
235
+ 46,
236
+ 583
237
+ ]
238
+ ],
239
+ "report": {
240
+ "Not_Mentioned": {
241
+ "precision": 0.7406496062992126,
242
+ "recall": 0.7662932790224033,
243
+ "f1-score": 0.7532532532532532,
244
+ "support": 7856.0
245
+ },
246
+ "Positive": {
247
+ "precision": 0.7457002457002457,
248
+ "recall": 0.6675569520816967,
249
+ "f1-score": 0.7044682085716655,
250
+ "support": 6365.0
251
+ },
252
+ "Negative": {
253
+ "precision": 0.49659284497444633,
254
+ "recall": 0.748395378690629,
255
+ "f1-score": 0.5970302099334357,
256
+ "support": 779.0
257
+ },
258
+ "accuracy": 0.7234666666666667,
259
+ "macro avg": {
260
+ "precision": 0.6609808989913015,
261
+ "recall": 0.7274152032649096,
262
+ "f1-score": 0.6849172239194514,
263
+ "support": 15000.0
264
+ },
265
+ "weighted avg": {
266
+ "precision": 0.7301180798135848,
267
+ "recall": 0.7234666666666667,
268
+ "f1-score": 0.7244389492436237,
269
+ "support": 15000.0
270
+ }
271
+ }
272
+ },
273
+ "VALUE": {
274
+ "macro_f1": 0.7171099329708497,
275
+ "accuracy": 0.8563333333333333,
276
+ "confusion_matrix": [
277
+ [
278
+ 10588,
279
+ 815,
280
+ 378
281
+ ],
282
+ [
283
+ 786,
284
+ 1924,
285
+ 58
286
+ ],
287
+ [
288
+ 81,
289
+ 37,
290
+ 333
291
+ ]
292
+ ],
293
+ "report": {
294
+ "Not_Mentioned": {
295
+ "precision": 0.9243125272806635,
296
+ "recall": 0.8987352516764281,
297
+ "f1-score": 0.9113444654845929,
298
+ "support": 11781.0
299
+ },
300
+ "Positive": {
301
+ "precision": 0.6930835734870316,
302
+ "recall": 0.6950867052023122,
303
+ "f1-score": 0.6940836940836941,
304
+ "support": 2768.0
305
+ },
306
+ "Negative": {
307
+ "precision": 0.43302990897269183,
308
+ "recall": 0.738359201773836,
309
+ "f1-score": 0.5459016393442623,
310
+ "support": 451.0
311
+ },
312
+ "accuracy": 0.8563333333333333,
313
+ "macro avg": {
314
+ "precision": 0.683475336580129,
315
+ "recall": 0.7773937195508588,
316
+ "f1-score": 0.7171099329708497,
317
+ "support": 15000.0
318
+ },
319
+ "weighted avg": {
320
+ "precision": 0.8668718469501523,
321
+ "recall": 0.8563333333333333,
322
+ "f1-score": 0.8602649634961278,
323
+ "support": 15000.0
324
+ }
325
+ }
326
+ }
327
+ },
328
+ "overall": {
329
+ "mean_macro_f1": 0.7235194801610981,
330
+ "mean_accuracy": 0.7617777777777778
331
+ }
332
+ }
reports_for_frontend/01_evaluation/per_aspect_proposed.json ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "per_aspect": {
3
+ "SIZE": {
4
+ "macro_f1": 0.8688511032834313,
5
+ "accuracy": 0.876,
6
+ "confusion_matrix": [
7
+ [
8
+ 3919,
9
+ 392,
10
+ 177
11
+ ],
12
+ [
13
+ 650,
14
+ 6782,
15
+ 397
16
+ ],
17
+ [
18
+ 138,
19
+ 106,
20
+ 2439
21
+ ]
22
+ ],
23
+ "report": {
24
+ "Not_Mentioned": {
25
+ "precision": 0.8325897599320161,
26
+ "recall": 0.8732174688057041,
27
+ "f1-score": 0.8524197933659597,
28
+ "support": 4488.0
29
+ },
30
+ "Positive": {
31
+ "precision": 0.9315934065934066,
32
+ "recall": 0.8662664452675949,
33
+ "f1-score": 0.8977430670461315,
34
+ "support": 7829.0
35
+ },
36
+ "Negative": {
37
+ "precision": 0.8094922004646532,
38
+ "recall": 0.9090570257174805,
39
+ "f1-score": 0.8563904494382022,
40
+ "support": 2683.0
41
+ },
42
+ "accuracy": 0.876,
43
+ "macro avg": {
44
+ "precision": 0.857891788996692,
45
+ "recall": 0.8828469799302598,
46
+ "f1-score": 0.8688511032834313,
47
+ "support": 15000.0
48
+ },
49
+ "weighted avg": {
50
+ "precision": 0.8801316797760889,
51
+ "recall": 0.876,
52
+ "f1-score": 0.8767857386915525,
53
+ "support": 15000.0
54
+ }
55
+ }
56
+ },
57
+ "MATERIAL": {
58
+ "macro_f1": 0.8351109775214702,
59
+ "accuracy": 0.8648666666666667,
60
+ "confusion_matrix": [
61
+ [
62
+ 3525,
63
+ 486,
64
+ 247
65
+ ],
66
+ [
67
+ 577,
68
+ 7811,
69
+ 446
70
+ ],
71
+ [
72
+ 176,
73
+ 95,
74
+ 1637
75
+ ]
76
+ ],
77
+ "report": {
78
+ "Not_Mentioned": {
79
+ "precision": 0.8239831697054698,
80
+ "recall": 0.8278534523250353,
81
+ "f1-score": 0.8259137769447048,
82
+ "support": 4258.0
83
+ },
84
+ "Positive": {
85
+ "precision": 0.930767397521449,
86
+ "recall": 0.8841974190627122,
87
+ "f1-score": 0.9068849413677,
88
+ "support": 8834.0
89
+ },
90
+ "Negative": {
91
+ "precision": 0.7025751072961374,
92
+ "recall": 0.8579664570230608,
93
+ "f1-score": 0.7725342142520056,
94
+ "support": 1908.0
95
+ },
96
+ "accuracy": 0.8648666666666667,
97
+ "macro avg": {
98
+ "precision": 0.819108558174352,
99
+ "recall": 0.8566724428036028,
100
+ "f1-score": 0.8351109775214702,
101
+ "support": 15000.0
102
+ },
103
+ "weighted avg": {
104
+ "precision": 0.8714288554020935,
105
+ "recall": 0.8648666666666667,
106
+ "f1-score": 0.8668105143377094,
107
+ "support": 15000.0
108
+ }
109
+ }
110
+ },
111
+ "QUALITY": {
112
+ "macro_f1": 0.7742721084444115,
113
+ "accuracy": 0.8063333333333333,
114
+ "confusion_matrix": [
115
+ [
116
+ 6322,
117
+ 1106,
118
+ 462
119
+ ],
120
+ [
121
+ 958,
122
+ 4841,
123
+ 190
124
+ ],
125
+ [
126
+ 141,
127
+ 48,
128
+ 932
129
+ ]
130
+ ],
131
+ "report": {
132
+ "Not_Mentioned": {
133
+ "precision": 0.85190675111171,
134
+ "recall": 0.8012674271229404,
135
+ "f1-score": 0.8258115080660963,
136
+ "support": 7890.0
137
+ },
138
+ "Positive": {
139
+ "precision": 0.8075062552126773,
140
+ "recall": 0.8083152446151277,
141
+ "f1-score": 0.8079105473965287,
142
+ "support": 5989.0
143
+ },
144
+ "Negative": {
145
+ "precision": 0.5883838383838383,
146
+ "recall": 0.8314005352363961,
147
+ "f1-score": 0.68909426987061,
148
+ "support": 1121.0
149
+ },
150
+ "accuracy": 0.8063333333333333,
151
+ "macro avg": {
152
+ "precision": 0.7492656149027419,
153
+ "recall": 0.8136610689914882,
154
+ "f1-score": 0.7742721084444115,
155
+ "support": 15000.0
156
+ },
157
+ "weighted avg": {
158
+ "precision": 0.8144851674378932,
159
+ "recall": 0.8063333333333333,
160
+ "f1-score": 0.8084469162349509,
161
+ "support": 15000.0
162
+ }
163
+ }
164
+ },
165
+ "APPEARANCE": {
166
+ "macro_f1": 0.7866997719239698,
167
+ "accuracy": 0.8634666666666667,
168
+ "confusion_matrix": [
169
+ [
170
+ 7598,
171
+ 606,
172
+ 366
173
+ ],
174
+ [
175
+ 783,
176
+ 4841,
177
+ 131
178
+ ],
179
+ [
180
+ 118,
181
+ 44,
182
+ 513
183
+ ]
184
+ ],
185
+ "report": {
186
+ "Not_Mentioned": {
187
+ "precision": 0.893987527944464,
188
+ "recall": 0.886581096849475,
189
+ "f1-score": 0.8902689085476595,
190
+ "support": 8570.0
191
+ },
192
+ "Positive": {
193
+ "precision": 0.8816244764159534,
194
+ "recall": 0.8411815812337098,
195
+ "f1-score": 0.8609283300729148,
196
+ "support": 5755.0
197
+ },
198
+ "Negative": {
199
+ "precision": 0.5079207920792079,
200
+ "recall": 0.76,
201
+ "f1-score": 0.6089020771513353,
202
+ "support": 675.0
203
+ },
204
+ "accuracy": 0.8634666666666667,
205
+ "macro avg": {
206
+ "precision": 0.7611775988132085,
207
+ "recall": 0.8292542260277282,
208
+ "f1-score": 0.7866997719239698,
209
+ "support": 15000.0
210
+ },
211
+ "weighted avg": {
212
+ "precision": 0.8718712340607555,
213
+ "recall": 0.8634666666666667,
214
+ "f1-score": 0.8663503991933479,
215
+ "support": 15000.0
216
+ }
217
+ }
218
+ },
219
+ "STYLE": {
220
+ "macro_f1": 0.7622600117091981,
221
+ "accuracy": 0.8287333333333333,
222
+ "confusion_matrix": [
223
+ [
224
+ 6595,
225
+ 823,
226
+ 438
227
+ ],
228
+ [
229
+ 911,
230
+ 5219,
231
+ 235
232
+ ],
233
+ [
234
+ 115,
235
+ 47,
236
+ 617
237
+ ]
238
+ ],
239
+ "report": {
240
+ "Not_Mentioned": {
241
+ "precision": 0.8653719984254035,
242
+ "recall": 0.8394857433808554,
243
+ "f1-score": 0.8522323447696583,
244
+ "support": 7856.0
245
+ },
246
+ "Positive": {
247
+ "precision": 0.8571193956314666,
248
+ "recall": 0.8199528672427338,
249
+ "f1-score": 0.8381242974144854,
250
+ "support": 6365.0
251
+ },
252
+ "Negative": {
253
+ "precision": 0.4782945736434108,
254
+ "recall": 0.79204107830552,
255
+ "f1-score": 0.5964233929434509,
256
+ "support": 779.0
257
+ },
258
+ "accuracy": 0.8287333333333333,
259
+ "macro avg": {
260
+ "precision": 0.7335953225667603,
261
+ "recall": 0.8171598963097031,
262
+ "f1-score": 0.7622600117091981,
263
+ "support": 15000.0
264
+ },
265
+ "weighted avg": {
266
+ "precision": 0.8417679230461648,
267
+ "recall": 0.8287333333333333,
268
+ "f1-score": 0.8329608184437722,
269
+ "support": 15000.0
270
+ }
271
+ }
272
+ },
273
+ "VALUE": {
274
+ "macro_f1": 0.7179350422128157,
275
+ "accuracy": 0.8483333333333334,
276
+ "confusion_matrix": [
277
+ [
278
+ 10218,
279
+ 1191,
280
+ 372
281
+ ],
282
+ [
283
+ 511,
284
+ 2162,
285
+ 95
286
+ ],
287
+ [
288
+ 72,
289
+ 34,
290
+ 345
291
+ ]
292
+ ],
293
+ "report": {
294
+ "Not_Mentioned": {
295
+ "precision": 0.9460235163410795,
296
+ "recall": 0.8673287496816908,
297
+ "f1-score": 0.9049685590293154,
298
+ "support": 11781.0
299
+ },
300
+ "Positive": {
301
+ "precision": 0.6383229997047535,
302
+ "recall": 0.7810693641618497,
303
+ "f1-score": 0.7025182778229082,
304
+ "support": 2768.0
305
+ },
306
+ "Negative": {
307
+ "precision": 0.4248768472906404,
308
+ "recall": 0.7649667405764967,
309
+ "f1-score": 0.5463182897862233,
310
+ "support": 451.0
311
+ },
312
+ "accuracy": 0.8483333333333334,
313
+ "macro avg": {
314
+ "precision": 0.6697411211121578,
315
+ "recall": 0.8044549514733458,
316
+ "f1-score": 0.7179350422128157,
317
+ "support": 15000.0
318
+ },
319
+ "weighted avg": {
320
+ "precision": 0.8735733711550063,
321
+ "recall": 0.8483333333333334,
322
+ "f1-score": 0.8568263157087841,
323
+ "support": 15000.0
324
+ }
325
+ }
326
+ }
327
+ },
328
+ "overall": {
329
+ "mean_macro_f1": 0.790854835849216,
330
+ "mean_accuracy": 0.8479555555555556
331
+ }
332
+ }
reports_for_frontend/03_ablation/ablation_A1.json ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "per_aspect": {
3
+ "SIZE": {
4
+ "macro_f1": 0.8068747136235311,
5
+ "accuracy": 0.8090666666666667,
6
+ "confusion_matrix": [
7
+ [
8
+ 3382,
9
+ 875,
10
+ 231
11
+ ],
12
+ [
13
+ 1062,
14
+ 6319,
15
+ 448
16
+ ],
17
+ [
18
+ 151,
19
+ 97,
20
+ 2435
21
+ ]
22
+ ],
23
+ "report": {
24
+ "Not_Mentioned": {
25
+ "precision": 0.7360174102285092,
26
+ "recall": 0.7535650623885918,
27
+ "f1-score": 0.7446878784542552,
28
+ "support": 4488.0
29
+ },
30
+ "Positive": {
31
+ "precision": 0.866684954052942,
32
+ "recall": 0.8071273470430451,
33
+ "f1-score": 0.8358465608465608,
34
+ "support": 7829.0
35
+ },
36
+ "Negative": {
37
+ "precision": 0.7819524727039178,
38
+ "recall": 0.9075661572866195,
39
+ "f1-score": 0.8400897015697775,
40
+ "support": 2683.0
41
+ },
42
+ "accuracy": 0.8090666666666667,
43
+ "macro avg": {
44
+ "precision": 0.7948849456617896,
45
+ "recall": 0.8227528555727521,
46
+ "f1-score": 0.8068747136235311,
47
+ "support": 15000.0
48
+ },
49
+ "weighted avg": {
50
+ "precision": 0.8124334084433762,
51
+ "recall": 0.8090666666666667,
52
+ "f1-score": 0.8093308395121424,
53
+ "support": 15000.0
54
+ }
55
+ }
56
+ },
57
+ "MATERIAL": {
58
+ "macro_f1": 0.8128940857458821,
59
+ "accuracy": 0.8442,
60
+ "confusion_matrix": [
61
+ [
62
+ 3332,
63
+ 655,
64
+ 271
65
+ ],
66
+ [
67
+ 609,
68
+ 7698,
69
+ 527
70
+ ],
71
+ [
72
+ 185,
73
+ 90,
74
+ 1633
75
+ ]
76
+ ],
77
+ "report": {
78
+ "Not_Mentioned": {
79
+ "precision": 0.8075618031992244,
80
+ "recall": 0.7825270079849694,
81
+ "f1-score": 0.7948473282442748,
82
+ "support": 4258.0
83
+ },
84
+ "Positive": {
85
+ "precision": 0.9117612223143432,
86
+ "recall": 0.8714059316278017,
87
+ "f1-score": 0.8911269317589859,
88
+ "support": 8834.0
89
+ },
90
+ "Negative": {
91
+ "precision": 0.6717400246812012,
92
+ "recall": 0.8558700209643606,
93
+ "f1-score": 0.7527079972343858,
94
+ "support": 1908.0
95
+ },
96
+ "accuracy": 0.8442,
97
+ "macro avg": {
98
+ "precision": 0.7970210167315895,
99
+ "recall": 0.8366009868590439,
100
+ "f1-score": 0.8128940857458821,
101
+ "support": 15000.0
102
+ },
103
+ "weighted avg": {
104
+ "precision": 0.8516517842025958,
105
+ "recall": 0.8442,
106
+ "f1-score": 0.8461894731697476,
107
+ "support": 15000.0
108
+ }
109
+ }
110
+ },
111
+ "QUALITY": {
112
+ "macro_f1": 0.7185149356332249,
113
+ "accuracy": 0.7352666666666666,
114
+ "confusion_matrix": [
115
+ [
116
+ 5077,
117
+ 2322,
118
+ 491
119
+ ],
120
+ [
121
+ 755,
122
+ 5036,
123
+ 198
124
+ ],
125
+ [
126
+ 147,
127
+ 58,
128
+ 916
129
+ ]
130
+ ],
131
+ "report": {
132
+ "Not_Mentioned": {
133
+ "precision": 0.8491386519484864,
134
+ "recall": 0.6434727503168568,
135
+ "f1-score": 0.7321364193525128,
136
+ "support": 7890.0
137
+ },
138
+ "Positive": {
139
+ "precision": 0.6790722761596548,
140
+ "recall": 0.8408749373852062,
141
+ "f1-score": 0.7513614323013801,
142
+ "support": 5989.0
143
+ },
144
+ "Negative": {
145
+ "precision": 0.5707165109034268,
146
+ "recall": 0.8171275646743978,
147
+ "f1-score": 0.6720469552457814,
148
+ "support": 1121.0
149
+ },
150
+ "accuracy": 0.7352666666666666,
151
+ "macro avg": {
152
+ "precision": 0.6996424796705226,
153
+ "recall": 0.7671584174588203,
154
+ "f1-score": 0.7185149356332249,
155
+ "support": 15000.0
156
+ },
157
+ "weighted avg": {
158
+ "precision": 0.7604294023010981,
159
+ "recall": 0.7352666666666666,
160
+ "f1-score": 0.7353216402383209,
161
+ "support": 15000.0
162
+ }
163
+ }
164
+ },
165
+ "APPEARANCE": {
166
+ "macro_f1": 0.6981066845508933,
167
+ "accuracy": 0.7523333333333333,
168
+ "confusion_matrix": [
169
+ [
170
+ 6001,
171
+ 2111,
172
+ 458
173
+ ],
174
+ [
175
+ 837,
176
+ 4779,
177
+ 139
178
+ ],
179
+ [
180
+ 133,
181
+ 37,
182
+ 505
183
+ ]
184
+ ],
185
+ "report": {
186
+ "Not_Mentioned": {
187
+ "precision": 0.8608521015636207,
188
+ "recall": 0.7002333722287047,
189
+ "f1-score": 0.7722797760761856,
190
+ "support": 8570.0
191
+ },
192
+ "Positive": {
193
+ "precision": 0.6899090515374621,
194
+ "recall": 0.8304083405734144,
195
+ "f1-score": 0.7536666140987226,
196
+ "support": 5755.0
197
+ },
198
+ "Negative": {
199
+ "precision": 0.45825771324863884,
200
+ "recall": 0.7481481481481481,
201
+ "f1-score": 0.5683736634777715,
202
+ "support": 675.0
203
+ },
204
+ "accuracy": 0.7523333333333333,
205
+ "macro avg": {
206
+ "precision": 0.6696729554499071,
207
+ "recall": 0.7595966203167558,
208
+ "f1-score": 0.6981066845508933,
209
+ "support": 15000.0
210
+ },
211
+ "weighted avg": {
212
+ "precision": 0.7771502038960769,
213
+ "recall": 0.7523333333333333,
214
+ "f1-score": 0.7559627511972369,
215
+ "support": 15000.0
216
+ }
217
+ }
218
+ },
219
+ "STYLE": {
220
+ "macro_f1": 0.7065456106077872,
221
+ "accuracy": 0.7587333333333334,
222
+ "confusion_matrix": [
223
+ [
224
+ 5575,
225
+ 1794,
226
+ 487
227
+ ],
228
+ [
229
+ 922,
230
+ 5198,
231
+ 245
232
+ ],
233
+ [
234
+ 125,
235
+ 46,
236
+ 608
237
+ ]
238
+ ],
239
+ "report": {
240
+ "Not_Mentioned": {
241
+ "precision": 0.8418906674720629,
242
+ "recall": 0.7096486761710794,
243
+ "f1-score": 0.7701339964083437,
244
+ "support": 7856.0
245
+ },
246
+ "Positive": {
247
+ "precision": 0.738562091503268,
248
+ "recall": 0.8166535742340927,
249
+ "f1-score": 0.7756472431545176,
250
+ "support": 6365.0
251
+ },
252
+ "Negative": {
253
+ "precision": 0.4537313432835821,
254
+ "recall": 0.7804878048780488,
255
+ "f1-score": 0.5738555922605002,
256
+ "support": 779.0
257
+ },
258
+ "accuracy": 0.7587333333333334,
259
+ "macro avg": {
260
+ "precision": 0.6780613674196377,
261
+ "recall": 0.7689300184277403,
262
+ "f1-score": 0.7065456106077872,
263
+ "support": 15000.0
264
+ },
265
+ "weighted avg": {
266
+ "precision": 0.7778865008331158,
267
+ "recall": 0.7587333333333334,
268
+ "f1-score": 0.7622800589888922,
269
+ "support": 15000.0
270
+ }
271
+ }
272
+ },
273
+ "VALUE": {
274
+ "macro_f1": 0.7005200887779329,
275
+ "accuracy": 0.8372,
276
+ "confusion_matrix": [
277
+ [
278
+ 10197,
279
+ 1182,
280
+ 402
281
+ ],
282
+ [
283
+ 656,
284
+ 2019,
285
+ 93
286
+ ],
287
+ [
288
+ 72,
289
+ 37,
290
+ 342
291
+ ]
292
+ ],
293
+ "report": {
294
+ "Not_Mentioned": {
295
+ "precision": 0.9333638443935927,
296
+ "recall": 0.865546218487395,
297
+ "f1-score": 0.8981766933850084,
298
+ "support": 11781.0
299
+ },
300
+ "Positive": {
301
+ "precision": 0.6235330450895614,
302
+ "recall": 0.729407514450867,
303
+ "f1-score": 0.6723276723276723,
304
+ "support": 2768.0
305
+ },
306
+ "Negative": {
307
+ "precision": 0.40860215053763443,
308
+ "recall": 0.7583148558758315,
309
+ "f1-score": 0.531055900621118,
310
+ "support": 451.0
311
+ },
312
+ "accuracy": 0.8372,
313
+ "macro avg": {
314
+ "precision": 0.6551663466735962,
315
+ "recall": 0.7844228629380311,
316
+ "f1-score": 0.7005200887779329,
317
+ "support": 15000.0
318
+ },
319
+ "weighted avg": {
320
+ "precision": 0.8604118993000863,
321
+ "recall": 0.8372,
322
+ "f1-score": 0.8454619221967936,
323
+ "support": 15000.0
324
+ }
325
+ }
326
+ }
327
+ },
328
+ "overall": {
329
+ "mean_macro_f1": 0.7405760198232086,
330
+ "mean_accuracy": 0.7894666666666666
331
+ },
332
+ "variant": "A1",
333
+ "variant_name": "A1_no_text_meta",
334
+ "description": "Remove text-type metadata (TF-IDF on features/categories); keep numeric (price, ratings)."
335
+ }
reports_for_frontend/03_ablation/ablation_A2.json ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "per_aspect": {
3
+ "SIZE": {
4
+ "macro_f1": 0.8261798151548717,
5
+ "accuracy": 0.8282,
6
+ "confusion_matrix": [
7
+ [
8
+ 3667,
9
+ 626,
10
+ 195
11
+ ],
12
+ [
13
+ 1060,
14
+ 6325,
15
+ 444
16
+ ],
17
+ [
18
+ 140,
19
+ 112,
20
+ 2431
21
+ ]
22
+ ],
23
+ "report": {
24
+ "Not_Mentioned": {
25
+ "precision": 0.7534415450996507,
26
+ "recall": 0.8170677361853832,
27
+ "f1-score": 0.7839657936932122,
28
+ "support": 4488.0
29
+ },
30
+ "Positive": {
31
+ "precision": 0.8955118221718816,
32
+ "recall": 0.8078937284455231,
33
+ "f1-score": 0.8494493687886113,
34
+ "support": 7829.0
35
+ },
36
+ "Negative": {
37
+ "precision": 0.79185667752443,
38
+ "recall": 0.9060752888557585,
39
+ "f1-score": 0.8451242829827916,
40
+ "support": 2683.0
41
+ },
42
+ "accuracy": 0.8282,
43
+ "macro avg": {
44
+ "precision": 0.8136033482653208,
45
+ "recall": 0.8436789178288883,
46
+ "f1-score": 0.8261798151548717,
47
+ "support": 15000.0
48
+ },
49
+ "weighted avg": {
50
+ "precision": 0.8344639450659292,
51
+ "recall": 0.8282,
52
+ "f1-score": 0.8290830694389336,
53
+ "support": 15000.0
54
+ }
55
+ }
56
+ },
57
+ "MATERIAL": {
58
+ "macro_f1": 0.7622481835378002,
59
+ "accuracy": 0.7784666666666666,
60
+ "confusion_matrix": [
61
+ [
62
+ 3224,
63
+ 784,
64
+ 250
65
+ ],
66
+ [
67
+ 1499,
68
+ 6826,
69
+ 509
70
+ ],
71
+ [
72
+ 182,
73
+ 99,
74
+ 1627
75
+ ]
76
+ ],
77
+ "report": {
78
+ "Not_Mentioned": {
79
+ "precision": 0.6572884811416921,
80
+ "recall": 0.7571629873179897,
81
+ "f1-score": 0.7036996616828549,
82
+ "support": 4258.0
83
+ },
84
+ "Positive": {
85
+ "precision": 0.8854585549357893,
86
+ "recall": 0.7726964002716776,
87
+ "f1-score": 0.8252433053255154,
88
+ "support": 8834.0
89
+ },
90
+ "Negative": {
91
+ "precision": 0.681894383906119,
92
+ "recall": 0.8527253668763103,
93
+ "f1-score": 0.7578015836050302,
94
+ "support": 1908.0
95
+ },
96
+ "accuracy": 0.7784666666666666,
97
+ "macro avg": {
98
+ "precision": 0.7415471399945335,
99
+ "recall": 0.794194918155326,
100
+ "f1-score": 0.7622481835378002,
101
+ "support": 15000.0
102
+ },
103
+ "weighted avg": {
104
+ "precision": 0.7947953140997975,
105
+ "recall": 0.7784666666666666,
106
+ "f1-score": 0.7821625293473065,
107
+ "support": 15000.0
108
+ }
109
+ }
110
+ },
111
+ "QUALITY": {
112
+ "macro_f1": 0.7470141599939275,
113
+ "accuracy": 0.7757333333333334,
114
+ "confusion_matrix": [
115
+ [
116
+ 6275,
117
+ 1128,
118
+ 487
119
+ ],
120
+ [
121
+ 1346,
122
+ 4437,
123
+ 206
124
+ ],
125
+ [
126
+ 137,
127
+ 60,
128
+ 924
129
+ ]
130
+ ],
131
+ "report": {
132
+ "Not_Mentioned": {
133
+ "precision": 0.8088424851765919,
134
+ "recall": 0.7953105196451205,
135
+ "f1-score": 0.802019427402863,
136
+ "support": 7890.0
137
+ },
138
+ "Positive": {
139
+ "precision": 0.7888,
140
+ "recall": 0.7408582401068626,
141
+ "f1-score": 0.7640778370931635,
142
+ "support": 5989.0
143
+ },
144
+ "Negative": {
145
+ "precision": 0.5714285714285714,
146
+ "recall": 0.8242640499553969,
147
+ "f1-score": 0.674945215485756,
148
+ "support": 1121.0
149
+ },
150
+ "accuracy": 0.7757333333333334,
151
+ "macro avg": {
152
+ "precision": 0.7230236855350544,
153
+ "recall": 0.7868109365691267,
154
+ "f1-score": 0.7470141599939275,
155
+ "support": 15000.0
156
+ },
157
+ "weighted avg": {
158
+ "precision": 0.7830974557743159,
159
+ "recall": 0.7757333333333334,
160
+ "f1-score": 0.7773739356746052,
161
+ "support": 15000.0
162
+ }
163
+ }
164
+ },
165
+ "APPEARANCE": {
166
+ "macro_f1": 0.75832091109464,
167
+ "accuracy": 0.8269333333333333,
168
+ "confusion_matrix": [
169
+ [
170
+ 7190,
171
+ 983,
172
+ 397
173
+ ],
174
+ [
175
+ 928,
176
+ 4699,
177
+ 128
178
+ ],
179
+ [
180
+ 119,
181
+ 41,
182
+ 515
183
+ ]
184
+ ],
185
+ "report": {
186
+ "Not_Mentioned": {
187
+ "precision": 0.8728906155153575,
188
+ "recall": 0.838973162193699,
189
+ "f1-score": 0.855595882667936,
190
+ "support": 8570.0
191
+ },
192
+ "Positive": {
193
+ "precision": 0.821072863882579,
194
+ "recall": 0.8165073848827107,
195
+ "f1-score": 0.8187837602369751,
196
+ "support": 5755.0
197
+ },
198
+ "Negative": {
199
+ "precision": 0.4951923076923077,
200
+ "recall": 0.762962962962963,
201
+ "f1-score": 0.6005830903790087,
202
+ "support": 675.0
203
+ },
204
+ "accuracy": 0.8269333333333333,
205
+ "macro avg": {
206
+ "precision": 0.729718595696748,
207
+ "recall": 0.806147836679791,
208
+ "f1-score": 0.75832091109464,
209
+ "support": 15000.0
210
+ },
211
+ "weighted avg": {
212
+ "precision": 0.836013447620211,
213
+ "recall": 0.8269333333333333,
214
+ "f1-score": 0.8299967227089221,
215
+ "support": 15000.0
216
+ }
217
+ }
218
+ },
219
+ "STYLE": {
220
+ "macro_f1": 0.7282681172699741,
221
+ "accuracy": 0.7826,
222
+ "confusion_matrix": [
223
+ [
224
+ 6187,
225
+ 1221,
226
+ 448
227
+ ],
228
+ [
229
+ 1198,
230
+ 4937,
231
+ 230
232
+ ],
233
+ [
234
+ 112,
235
+ 52,
236
+ 615
237
+ ]
238
+ ],
239
+ "report": {
240
+ "Not_Mentioned": {
241
+ "precision": 0.8252634387088169,
242
+ "recall": 0.787550916496945,
243
+ "f1-score": 0.8059662606656679,
244
+ "support": 7856.0
245
+ },
246
+ "Positive": {
247
+ "precision": 0.7950080515297907,
248
+ "recall": 0.7756480754124117,
249
+ "f1-score": 0.7852087475149105,
250
+ "support": 6365.0
251
+ },
252
+ "Negative": {
253
+ "precision": 0.4756380510440835,
254
+ "recall": 0.7894736842105263,
255
+ "f1-score": 0.5936293436293436,
256
+ "support": 779.0
257
+ },
258
+ "accuracy": 0.7826,
259
+ "macro avg": {
260
+ "precision": 0.6986365137608971,
261
+ "recall": 0.7842242253732943,
262
+ "f1-score": 0.7282681172699741,
263
+ "support": 15000.0
264
+ },
265
+ "weighted avg": {
266
+ "precision": 0.7942678576164616,
267
+ "recall": 0.7826,
268
+ "f1-score": 0.7861307920272768,
269
+ "support": 15000.0
270
+ }
271
+ }
272
+ },
273
+ "VALUE": {
274
+ "macro_f1": 0.7116125464747367,
275
+ "accuracy": 0.8398666666666667,
276
+ "confusion_matrix": [
277
+ [
278
+ 10116,
279
+ 1291,
280
+ 374
281
+ ],
282
+ [
283
+ 540,
284
+ 2132,
285
+ 96
286
+ ],
287
+ [
288
+ 68,
289
+ 33,
290
+ 350
291
+ ]
292
+ ],
293
+ "report": {
294
+ "Not_Mentioned": {
295
+ "precision": 0.9433047370384186,
296
+ "recall": 0.8586707410236822,
297
+ "f1-score": 0.8990002221728505,
298
+ "support": 11781.0
299
+ },
300
+ "Positive": {
301
+ "precision": 0.6168981481481481,
302
+ "recall": 0.7702312138728323,
303
+ "f1-score": 0.6850899742930592,
304
+ "support": 2768.0
305
+ },
306
+ "Negative": {
307
+ "precision": 0.4268292682926829,
308
+ "recall": 0.7760532150776053,
309
+ "f1-score": 0.5507474429583006,
310
+ "support": 451.0
311
+ },
312
+ "accuracy": 0.8398666666666667,
313
+ "macro avg": {
314
+ "precision": 0.6623440511597498,
315
+ "recall": 0.8016517233247066,
316
+ "f1-score": 0.7116125464747367,
317
+ "support": 15000.0
318
+ },
319
+ "weighted avg": {
320
+ "precision": 0.8675431454082456,
321
+ "recall": 0.8398666666666667,
322
+ "f1-score": 0.8490558508690489,
323
+ "support": 15000.0
324
+ }
325
+ }
326
+ }
327
+ },
328
+ "overall": {
329
+ "mean_macro_f1": 0.7556072889209918,
330
+ "mean_accuracy": 0.8053
331
+ },
332
+ "variant": "A2",
333
+ "variant_name": "A2_no_numeric_meta",
334
+ "description": "Remove numeric metadata (price, ratings); keep text-type (TF-IDF on features/categories)."
335
+ }
reports_for_frontend/03_ablation/ablation_A3.json ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "per_aspect": {
3
+ "SIZE": {
4
+ "macro_f1": 0.8673939825303104,
5
+ "accuracy": 0.8746666666666667,
6
+ "confusion_matrix": [
7
+ [
8
+ 3888,
9
+ 411,
10
+ 189
11
+ ],
12
+ [
13
+ 671,
14
+ 6818,
15
+ 340
16
+ ],
17
+ [
18
+ 148,
19
+ 121,
20
+ 2414
21
+ ]
22
+ ],
23
+ "report": {
24
+ "Not_Mentioned": {
25
+ "precision": 0.8260038240917782,
26
+ "recall": 0.8663101604278075,
27
+ "f1-score": 0.8456769983686786,
28
+ "support": 4488.0
29
+ },
30
+ "Positive": {
31
+ "precision": 0.9276190476190476,
32
+ "recall": 0.8708647336824626,
33
+ "f1-score": 0.8983463996310692,
34
+ "support": 7829.0
35
+ },
36
+ "Negative": {
37
+ "precision": 0.8202514441046551,
38
+ "recall": 0.8997390980245993,
39
+ "f1-score": 0.8581585495911838,
40
+ "support": 2683.0
41
+ },
42
+ "accuracy": 0.8746666666666667,
43
+ "macro avg": {
44
+ "precision": 0.8579581052718269,
45
+ "recall": 0.8789713307116233,
46
+ "f1-score": 0.8673939825303104,
47
+ "support": 15000.0
48
+ },
49
+ "weighted avg": {
50
+ "precision": 0.878011287391081,
51
+ "recall": 0.8746666666666667,
52
+ "f1-score": 0.8753994479962278,
53
+ "support": 15000.0
54
+ }
55
+ }
56
+ },
57
+ "MATERIAL": {
58
+ "macro_f1": 0.8271559495053421,
59
+ "accuracy": 0.8584666666666667,
60
+ "confusion_matrix": [
61
+ [
62
+ 3464,
63
+ 526,
64
+ 268
65
+ ],
66
+ [
67
+ 588,
68
+ 7793,
69
+ 453
70
+ ],
71
+ [
72
+ 181,
73
+ 107,
74
+ 1620
75
+ ]
76
+ ],
77
+ "report": {
78
+ "Not_Mentioned": {
79
+ "precision": 0.8183321521379636,
80
+ "recall": 0.8135274776890559,
81
+ "f1-score": 0.815922741726534,
82
+ "support": 4258.0
83
+ },
84
+ "Positive": {
85
+ "precision": 0.9248753857108949,
86
+ "recall": 0.8821598369934345,
87
+ "f1-score": 0.9030127462340672,
88
+ "support": 8834.0
89
+ },
90
+ "Negative": {
91
+ "precision": 0.6920119607005554,
92
+ "recall": 0.8490566037735849,
93
+ "f1-score": 0.7625323605554248,
94
+ "support": 1908.0
95
+ },
96
+ "accuracy": 0.8584666666666667,
97
+ "macro avg": {
98
+ "precision": 0.8117398328498046,
99
+ "recall": 0.8482479728186917,
100
+ "f1-score": 0.8271559495053421,
101
+ "support": 15000.0
102
+ },
103
+ "weighted avg": {
104
+ "precision": 0.8650110854793437,
105
+ "recall": 0.8584666666666667,
106
+ "f1-score": 0.8604216918962055,
107
+ "support": 15000.0
108
+ }
109
+ }
110
+ },
111
+ "QUALITY": {
112
+ "macro_f1": 0.7772450897602642,
113
+ "accuracy": 0.8106,
114
+ "confusion_matrix": [
115
+ [
116
+ 6381,
117
+ 1044,
118
+ 465
119
+ ],
120
+ [
121
+ 964,
122
+ 4856,
123
+ 169
124
+ ],
125
+ [
126
+ 140,
127
+ 59,
128
+ 922
129
+ ]
130
+ ],
131
+ "report": {
132
+ "Not_Mentioned": {
133
+ "precision": 0.8525050100200401,
134
+ "recall": 0.808745247148289,
135
+ "f1-score": 0.8300487804878048,
136
+ "support": 7890.0
137
+ },
138
+ "Positive": {
139
+ "precision": 0.8149018291659674,
140
+ "recall": 0.8108198363666722,
141
+ "f1-score": 0.812855708068296,
142
+ "support": 5989.0
143
+ },
144
+ "Negative": {
145
+ "precision": 0.5925449871465296,
146
+ "recall": 0.8224799286351472,
147
+ "f1-score": 0.6888307807246918,
148
+ "support": 1121.0
149
+ },
150
+ "accuracy": 0.8106,
151
+ "macro avg": {
152
+ "precision": 0.753317275444179,
153
+ "recall": 0.8140150040500362,
154
+ "f1-score": 0.7772450897602642,
155
+ "support": 15000.0
156
+ },
157
+ "weighted avg": {
158
+ "precision": 0.8180636343016235,
159
+ "recall": 0.8106,
160
+ "f1-score": 0.8126304679241457,
161
+ "support": 15000.0
162
+ }
163
+ }
164
+ },
165
+ "APPEARANCE": {
166
+ "macro_f1": 0.7811169194295688,
167
+ "accuracy": 0.8627333333333334,
168
+ "confusion_matrix": [
169
+ [
170
+ 7589,
171
+ 576,
172
+ 405
173
+ ],
174
+ [
175
+ 785,
176
+ 4849,
177
+ 121
178
+ ],
179
+ [
180
+ 123,
181
+ 49,
182
+ 503
183
+ ]
184
+ ],
185
+ "report": {
186
+ "Not_Mentioned": {
187
+ "precision": 0.8931387548546545,
188
+ "recall": 0.8855309218203034,
189
+ "f1-score": 0.8893185679967188,
190
+ "support": 8570.0
191
+ },
192
+ "Positive": {
193
+ "precision": 0.8858238947753014,
194
+ "recall": 0.8425716768027802,
195
+ "f1-score": 0.8636566034375278,
196
+ "support": 5755.0
197
+ },
198
+ "Negative": {
199
+ "precision": 0.48882410106899904,
200
+ "recall": 0.7451851851851852,
201
+ "f1-score": 0.5903755868544601,
202
+ "support": 675.0
203
+ },
204
+ "accuracy": 0.8627333333333334,
205
+ "macro avg": {
206
+ "precision": 0.7559289168996517,
207
+ "recall": 0.824429261269423,
208
+ "f1-score": 0.7811169194295688,
209
+ "support": 15000.0
210
+ },
211
+ "weighted avg": {
212
+ "precision": 0.8721381274505217,
213
+ "recall": 0.8627333333333334,
214
+ "f1-score": 0.8660204934427743,
215
+ "support": 15000.0
216
+ }
217
+ }
218
+ },
219
+ "STYLE": {
220
+ "macro_f1": 0.7616829060410565,
221
+ "accuracy": 0.8259333333333333,
222
+ "confusion_matrix": [
223
+ [
224
+ 6512,
225
+ 911,
226
+ 433
227
+ ],
228
+ [
229
+ 894,
230
+ 5268,
231
+ 203
232
+ ],
233
+ [
234
+ 118,
235
+ 52,
236
+ 609
237
+ ]
238
+ ],
239
+ "report": {
240
+ "Not_Mentioned": {
241
+ "precision": 0.8654970760233918,
242
+ "recall": 0.8289205702647657,
243
+ "f1-score": 0.846814044213264,
244
+ "support": 7856.0
245
+ },
246
+ "Positive": {
247
+ "precision": 0.8454501685122773,
248
+ "recall": 0.8276512175962294,
249
+ "f1-score": 0.8364560177834233,
250
+ "support": 6365.0
251
+ },
252
+ "Negative": {
253
+ "precision": 0.4891566265060241,
254
+ "recall": 0.7817715019255456,
255
+ "f1-score": 0.6017786561264822,
256
+ "support": 779.0
257
+ },
258
+ "accuracy": 0.8259333333333333,
259
+ "macro avg": {
260
+ "precision": 0.7333679570138978,
261
+ "recall": 0.8127810965955136,
262
+ "f1-score": 0.7616829060410565,
263
+ "support": 15000.0
264
+ },
265
+ "weighted avg": {
266
+ "precision": 0.8374458909245736,
267
+ "recall": 0.8259333333333333,
268
+ "f1-score": 0.8296932838435613,
269
+ "support": 15000.0
270
+ }
271
+ }
272
+ },
273
+ "VALUE": {
274
+ "macro_f1": 0.7205236545514385,
275
+ "accuracy": 0.8497333333333333,
276
+ "confusion_matrix": [
277
+ [
278
+ 10185,
279
+ 1229,
280
+ 367
281
+ ],
282
+ [
283
+ 464,
284
+ 2224,
285
+ 80
286
+ ],
287
+ [
288
+ 77,
289
+ 37,
290
+ 337
291
+ ]
292
+ ],
293
+ "report": {
294
+ "Not_Mentioned": {
295
+ "precision": 0.9495618124184225,
296
+ "recall": 0.8645276292335116,
297
+ "f1-score": 0.9050517616741458,
298
+ "support": 11781.0
299
+ },
300
+ "Positive": {
301
+ "precision": 0.6372492836676218,
302
+ "recall": 0.8034682080924855,
303
+ "f1-score": 0.7107702141259188,
304
+ "support": 2768.0
305
+ },
306
+ "Negative": {
307
+ "precision": 0.4298469387755102,
308
+ "recall": 0.7472283813747228,
309
+ "f1-score": 0.545748987854251,
310
+ "support": 451.0
311
+ },
312
+ "accuracy": 0.8497333333333333,
313
+ "macro avg": {
314
+ "precision": 0.6722193449538515,
315
+ "recall": 0.8050747395669067,
316
+ "f1-score": 0.7205236545514385,
317
+ "support": 15000.0
318
+ },
319
+ "weighted avg": {
320
+ "precision": 0.8763036465787445,
321
+ "recall": 0.8497333333333333,
322
+ "f1-score": 0.8583973033670613,
323
+ "support": 15000.0
324
+ }
325
+ }
326
+ }
327
+ },
328
+ "overall": {
329
+ "mean_macro_f1": 0.7891864169696635,
330
+ "mean_accuracy": 0.8470222222222222
331
+ },
332
+ "variant": "A3",
333
+ "variant_name": "A3_concat_fusion",
334
+ "description": "Replace Cross-Attention fusion with [text;meta] concat + Linear; both meta sources kept."
335
+ }
reports_for_frontend/03_ablation/ablation_summary.json ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "Proposed": {
3
+ "mean_macro_f1": 0.790854835849216,
4
+ "mean_accuracy": 0.8479555555555556,
5
+ "per_aspect": {
6
+ "SIZE": {
7
+ "macro_f1": 0.8688511032834313,
8
+ "accuracy": 0.876
9
+ },
10
+ "MATERIAL": {
11
+ "macro_f1": 0.8351109775214702,
12
+ "accuracy": 0.8648666666666667
13
+ },
14
+ "QUALITY": {
15
+ "macro_f1": 0.7742721084444115,
16
+ "accuracy": 0.8063333333333333
17
+ },
18
+ "APPEARANCE": {
19
+ "macro_f1": 0.7866997719239698,
20
+ "accuracy": 0.8634666666666667
21
+ },
22
+ "STYLE": {
23
+ "macro_f1": 0.7622600117091981,
24
+ "accuracy": 0.8287333333333333
25
+ },
26
+ "VALUE": {
27
+ "macro_f1": 0.7179350422128157,
28
+ "accuracy": 0.8483333333333334
29
+ }
30
+ }
31
+ },
32
+ "A1_no_text_meta": {
33
+ "mean_macro_f1": 0.7405760198232086,
34
+ "mean_accuracy": 0.7894666666666666,
35
+ "per_aspect": {
36
+ "SIZE": {
37
+ "macro_f1": 0.8068747136235311,
38
+ "accuracy": 0.8090666666666667
39
+ },
40
+ "MATERIAL": {
41
+ "macro_f1": 0.8128940857458821,
42
+ "accuracy": 0.8442
43
+ },
44
+ "QUALITY": {
45
+ "macro_f1": 0.7185149356332249,
46
+ "accuracy": 0.7352666666666666
47
+ },
48
+ "APPEARANCE": {
49
+ "macro_f1": 0.6981066845508933,
50
+ "accuracy": 0.7523333333333333
51
+ },
52
+ "STYLE": {
53
+ "macro_f1": 0.7065456106077872,
54
+ "accuracy": 0.7587333333333334
55
+ },
56
+ "VALUE": {
57
+ "macro_f1": 0.7005200887779329,
58
+ "accuracy": 0.8372
59
+ }
60
+ }
61
+ },
62
+ "A2_no_numeric_meta": {
63
+ "mean_macro_f1": 0.7556072889209918,
64
+ "mean_accuracy": 0.8053,
65
+ "per_aspect": {
66
+ "SIZE": {
67
+ "macro_f1": 0.8261798151548717,
68
+ "accuracy": 0.8282
69
+ },
70
+ "MATERIAL": {
71
+ "macro_f1": 0.7622481835378002,
72
+ "accuracy": 0.7784666666666666
73
+ },
74
+ "QUALITY": {
75
+ "macro_f1": 0.7470141599939275,
76
+ "accuracy": 0.7757333333333334
77
+ },
78
+ "APPEARANCE": {
79
+ "macro_f1": 0.75832091109464,
80
+ "accuracy": 0.8269333333333333
81
+ },
82
+ "STYLE": {
83
+ "macro_f1": 0.7282681172699741,
84
+ "accuracy": 0.7826
85
+ },
86
+ "VALUE": {
87
+ "macro_f1": 0.7116125464747367,
88
+ "accuracy": 0.8398666666666667
89
+ }
90
+ }
91
+ },
92
+ "A3_concat_fusion": {
93
+ "mean_macro_f1": 0.7891864169696635,
94
+ "mean_accuracy": 0.8470222222222222,
95
+ "per_aspect": {
96
+ "SIZE": {
97
+ "macro_f1": 0.8673939825303104,
98
+ "accuracy": 0.8746666666666667
99
+ },
100
+ "MATERIAL": {
101
+ "macro_f1": 0.8271559495053421,
102
+ "accuracy": 0.8584666666666667
103
+ },
104
+ "QUALITY": {
105
+ "macro_f1": 0.7772450897602642,
106
+ "accuracy": 0.8106
107
+ },
108
+ "APPEARANCE": {
109
+ "macro_f1": 0.7811169194295688,
110
+ "accuracy": 0.8627333333333334
111
+ },
112
+ "STYLE": {
113
+ "macro_f1": 0.7616829060410565,
114
+ "accuracy": 0.8259333333333333
115
+ },
116
+ "VALUE": {
117
+ "macro_f1": 0.7205236545514385,
118
+ "accuracy": 0.8497333333333333
119
+ }
120
+ }
121
+ }
122
+ }
reports_for_frontend/04_visualization/category_aspect_aggregation.csv ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ category,aspect,n_total,n_mentioned,positive_share,negative_share
2
+ T-Shirts,SIZE,473,368,0.6739130434782609,0.32608695652173914
3
+ T-Shirts,MATERIAL,473,365,0.7863013698630137,0.2136986301369863
4
+ T-Shirts,QUALITY,473,241,0.7966804979253111,0.2033195020746888
5
+ T-Shirts,APPEARANCE,473,231,0.8484848484848485,0.15151515151515152
6
+ T-Shirts,STYLE,473,296,0.8141891891891891,0.1858108108108108
7
+ T-Shirts,VALUE,473,96,0.7291666666666666,0.2708333333333333
8
+ Casual,SIZE,425,317,0.694006309148265,0.305993690851735
9
+ Casual,MATERIAL,425,272,0.7867647058823529,0.21323529411764705
10
+ Casual,QUALITY,425,181,0.7845303867403315,0.2154696132596685
11
+ Casual,APPEARANCE,425,177,0.8700564971751412,0.12994350282485875
12
+ Casual,STYLE,425,230,0.8173913043478261,0.1826086956521739
13
+ Casual,VALUE,425,55,0.8545454545454545,0.14545454545454545
14
+ Slippers,SIZE,345,248,0.7056451612903226,0.29435483870967744
15
+ Slippers,MATERIAL,345,271,0.8191881918819188,0.18081180811808117
16
+ Slippers,QUALITY,345,189,0.783068783068783,0.21693121693121692
17
+ Slippers,APPEARANCE,345,133,0.8721804511278195,0.12781954887218044
18
+ Slippers,STYLE,345,174,0.8333333333333334,0.16666666666666666
19
+ Slippers,VALUE,345,76,0.75,0.25
20
+ Athletic Socks,SIZE,332,244,0.7745901639344263,0.22540983606557377
21
+ Athletic Socks,MATERIAL,332,279,0.8172043010752689,0.1827956989247312
22
+ Athletic Socks,QUALITY,332,212,0.8490566037735849,0.1509433962264151
23
+ Athletic Socks,APPEARANCE,332,116,0.9051724137931034,0.09482758620689655
24
+ Athletic Socks,STYLE,332,91,0.8241758241758241,0.17582417582417584
25
+ Athletic Socks,VALUE,332,109,0.926605504587156,0.07339449541284404
26
+ Jeans,SIZE,280,250,0.636,0.364
27
+ Jeans,MATERIAL,280,194,0.788659793814433,0.211340206185567
28
+ Jeans,QUALITY,280,172,0.8255813953488372,0.1744186046511628
29
+ Jeans,APPEARANCE,280,78,0.8461538461538461,0.15384615384615385
30
+ Jeans,STYLE,280,121,0.768595041322314,0.23140495867768596
31
+ Jeans,VALUE,280,45,0.8666666666666667,0.13333333333333333
32
+ Everyday Bras,SIZE,277,162,0.5802469135802469,0.41975308641975306
33
+ Everyday Bras,MATERIAL,277,148,0.581081081081081,0.4189189189189189
34
+ Everyday Bras,QUALITY,277,102,0.6372549019607843,0.3627450980392157
35
+ Everyday Bras,APPEARANCE,277,66,0.5909090909090909,0.4090909090909091
36
+ Everyday Bras,STYLE,277,86,0.4883720930232558,0.5116279069767442
37
+ Everyday Bras,VALUE,277,50,0.66,0.34
38
+ Wrist Watches,SIZE,271,99,0.7373737373737373,0.26262626262626265
39
+ Wrist Watches,MATERIAL,271,89,0.7303370786516854,0.2696629213483146
40
+ Wrist Watches,QUALITY,271,71,0.5774647887323944,0.4225352112676056
41
+ Wrist Watches,APPEARANCE,271,123,0.8455284552845529,0.15447154471544716
42
+ Wrist Watches,STYLE,271,100,0.87,0.13
43
+ Wrist Watches,VALUE,271,98,0.7040816326530612,0.29591836734693877
44
+ Socks,SIZE,270,195,0.7589743589743589,0.24102564102564103
45
+ Socks,MATERIAL,270,227,0.8281938325991189,0.17180616740088106
46
+ Socks,QUALITY,270,148,0.831081081081081,0.16891891891891891
47
+ Socks,APPEARANCE,270,131,0.8702290076335878,0.1297709923664122
48
+ Socks,STYLE,270,127,0.8582677165354331,0.14173228346456693
49
+ Socks,VALUE,270,103,0.8737864077669902,0.1262135922330097
50
+ Tunics,SIZE,254,201,0.6965174129353234,0.3034825870646766
51
+ Tunics,MATERIAL,254,207,0.7777777777777778,0.2222222222222222
52
+ Tunics,QUALITY,254,136,0.7573529411764706,0.2426470588235294
53
+ Tunics,APPEARANCE,254,165,0.8424242424242424,0.15757575757575756
54
+ Tunics,STYLE,254,188,0.8191489361702128,0.18085106382978725
55
+ Tunics,VALUE,254,32,0.5625,0.4375
56
+ Leggings,SIZE,235,181,0.6574585635359116,0.3425414364640884
57
+ Leggings,MATERIAL,235,181,0.7292817679558011,0.27071823204419887
58
+ Leggings,QUALITY,235,124,0.7983870967741935,0.20161290322580644
59
+ Leggings,APPEARANCE,235,99,0.8282828282828283,0.1717171717171717
60
+ Leggings,STYLE,235,123,0.8617886178861789,0.13821138211382114
61
+ Leggings,VALUE,235,69,0.8115942028985508,0.18840579710144928
reports_for_frontend/05_explanation/explanation_attention.html ADDED
The diff for this file is too large to render. See raw diff
 
reports_for_frontend/05_explanation/explanation_attention_meta_source_summary.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ aspect,top_meta_source,n_rows,mean_top_meta_weight,mean_attention_focus,mean_attention_margin,mean_attention_entropy,aspect_total,source_share
2
+ APPEARANCE,features,50,0.5535691463947296,0.3152554518269078,0.16856914888540328,0.6847445481730923,50,1.0
3
+ MATERIAL,features,50,0.5100441455841065,0.14035479778646262,0.20505228016477986,0.8596452022135374,50,1.0
4
+ QUALITY,features,50,0.5549998760223389,0.27058217949495345,0.2072079706295289,0.7294178205050466,50,1.0
5
+ SIZE,features,50,0.554997307062149,0.23750944781645117,0.23498356799885556,0.7624905521835488,50,1.0
6
+ STYLE,features,50,0.5321753132343292,0.2766912814375451,0.14888458367986146,0.7233087185624549,50,1.0
7
+ VALUE,features,50,0.5149888694286346,0.11744743360918963,0.2349888691830967,0.8825525663908104,50,1.0
reports_for_frontend/05_explanation/explanation_attention_summary.csv ADDED
The diff for this file is too large to render. See raw diff
 
reports_for_frontend/05_explanation/explanation_ig.html ADDED
The diff for this file is too large to render. See raw diff
 
reports_for_frontend/05_explanation/explanation_ig_meta_source_summary.csv ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ aspect,top_meta_source,n_rows,mean_top_meta_weight,mean_attention_focus,mean_attention_margin,mean_attention_entropy,aspect_total,source_share
2
+ APPEARANCE,features,50,0.5535691463947296,0.3152554518269078,0.16856914888540328,0.6847445481730923,50,1.0
3
+ MATERIAL,features,50,0.5100441455841065,0.14035479778646262,0.20505228016477986,0.8596452022135374,50,1.0
4
+ QUALITY,features,50,0.5549998760223389,0.27058217949495345,0.2072079706295289,0.7294178205050466,50,1.0
5
+ SIZE,features,50,0.554997307062149,0.23750944781645117,0.23498356799885556,0.7624905521835488,50,1.0
6
+ STYLE,features,50,0.5321753132343292,0.2766912814375451,0.14888458367986146,0.7233087185624549,50,1.0
7
+ VALUE,features,50,0.5149888694286346,0.11744743360918963,0.2349888691830967,0.8825525663908104,50,1.0
reports_for_frontend/05_explanation/explanation_ig_summary.csv ADDED
The diff for this file is too large to render. See raw diff