Spaces:
Running
Running
Update app/services/classifier.py
Browse files- app/services/classifier.py +38 -0
app/services/classifier.py
CHANGED
|
@@ -71,6 +71,11 @@ CONTRAST_NOT_GAME_LABELS = [
|
|
| 71 |
"a screen being shared via Google Meet with a blue stop sharing button at the bottom",
|
| 72 |
"a full screen presentation with a meet.google.com sharing notification bar",
|
| 73 |
"a computer desktop being recorded or shared in a video meeting",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
]
|
| 75 |
|
| 76 |
NOT_GAME_LABELS = [
|
|
@@ -207,6 +212,22 @@ def _is_gallery_like_not_game(description: str) -> bool:
|
|
| 207 |
)
|
| 208 |
)
|
| 209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
logger = logging.getLogger(__name__)
|
| 211 |
|
| 212 |
SENSITIVE_KEYWORDS = {
|
|
@@ -545,6 +566,23 @@ def _classify_game_with_zero_shot(file_path: str, suspected_game: bool) -> dict[
|
|
| 545 |
"visual_summary": visual_summary,
|
| 546 |
}
|
| 547 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 548 |
# Clear game: high confidence
|
| 549 |
if game_score >= GAME_ZERO_SHOT_GAME_THRESHOLD:
|
| 550 |
return {
|
|
|
|
| 71 |
"a screen being shared via Google Meet with a blue stop sharing button at the bottom",
|
| 72 |
"a full screen presentation with a meet.google.com sharing notification bar",
|
| 73 |
"a computer desktop being recorded or shared in a video meeting",
|
| 74 |
+
|
| 75 |
+
# Text-heavy educational/article pages (common false-positive vs browser game labels)
|
| 76 |
+
"a Vietnamese educational article webpage with long text paragraphs and lesson navigation sidebar",
|
| 77 |
+
"an online lesson page with school grade menu and literary analysis text content",
|
| 78 |
+
"a reading article website with dense paragraphs and no gameplay controls or score HUD",
|
| 79 |
]
|
| 80 |
|
| 81 |
NOT_GAME_LABELS = [
|
|
|
|
| 212 |
)
|
| 213 |
)
|
| 214 |
|
| 215 |
+
|
| 216 |
+
def _is_text_heavy_not_game(description: str) -> bool:
|
| 217 |
+
text = description.lower()
|
| 218 |
+
return any(
|
| 219 |
+
token in text
|
| 220 |
+
for token in (
|
| 221 |
+
"educational",
|
| 222 |
+
"lesson",
|
| 223 |
+
"article",
|
| 224 |
+
"literary analysis",
|
| 225 |
+
"dense paragraphs",
|
| 226 |
+
"reading article",
|
| 227 |
+
"text paragraphs",
|
| 228 |
+
)
|
| 229 |
+
)
|
| 230 |
+
|
| 231 |
logger = logging.getLogger(__name__)
|
| 232 |
|
| 233 |
SENSITIVE_KEYWORDS = {
|
|
|
|
| 566 |
"visual_summary": visual_summary,
|
| 567 |
}
|
| 568 |
|
| 569 |
+
# Browser-game labels are also confused by text-heavy educational/article websites.
|
| 570 |
+
# If a strong text-page non-game label competes with broad browser-game cues, prefer not_game.
|
| 571 |
+
if (
|
| 572 |
+
top["index"] in GAME_ZERO_SHOT_BROWSER_GAME_LABEL_INDICES
|
| 573 |
+
and top_game_score < 0.90
|
| 574 |
+
and not_game_rows
|
| 575 |
+
and float(not_game_rows[0]["score"]) >= 0.12
|
| 576 |
+
and _is_text_heavy_not_game(str(not_game_rows[0]["description"]))
|
| 577 |
+
):
|
| 578 |
+
return {
|
| 579 |
+
"verdict": "not_game",
|
| 580 |
+
"confidence": float(not_game_rows[0]["score"]),
|
| 581 |
+
"reason": "text_article_conflict",
|
| 582 |
+
"source": f"zero-shot:{GAME_ZERO_SHOT_MODEL}",
|
| 583 |
+
"visual_summary": visual_summary,
|
| 584 |
+
}
|
| 585 |
+
|
| 586 |
# Clear game: high confidence
|
| 587 |
if game_score >= GAME_ZERO_SHOT_GAME_THRESHOLD:
|
| 588 |
return {
|