Download src/scoring.py from Corin1998/QRcheckin: direct link, hf CLI and curl.
- Browser
- Download file 1.53 kB
-
https://huggingface.co/spaces/Corin1998/QRcheckin/resolve/main/src/scoring.py
- Command line
-
hf download hf://spaces/Corin1998/QRcheckin/src/scoring.py
-
curl -L -o scoring.py https://huggingface.co/spaces/Corin1998/QRcheckin/resolve/main/src/scoring.py
1.53 kB
| from datetime import datetime, timedelta | |
| from sqlmodel import select | |
| from .models import Visit, TokenBalance | |
| from .db import get_session | |
| # 重みは適宜調整 | |
| W_RECENCY = 0.5 | |
| W_FREQUENCY = 0.3 | |
| W_POINTS = 0.2 # 総ポイント寄与(名称だけ修正) | |
| def calc_score(user_id: int) -> float: | |
| now = datetime.utcnow() | |
| with get_session() as s: | |
| visits = s.exec( | |
| select(Visit).where(Visit.user_id == user_id).order_by(Visit.created_at.desc()) | |
| ).all() | |
| if not visits: | |
| return 0.0 | |
| last_visit = visits[0].created_at | |
| days_since = (now - last_visit).days | |
| # 最近度:30日で線形減衰(0〜1) | |
| recency_score = max(0.0, 1.0 - days_since / 30.0) | |
| # 頻度:直近90日で10回来店で満点(0〜1) | |
| recent_90 = now - timedelta(days=90) | |
| freq_score = min( | |
| 1.0, | |
| len([v for v in visits if v.created_at > recent_90]) / 10.0 | |
| ) | |
| # ポイント寄与:合計1000ptで満点(0〜1) | |
| balances = s.exec(select(TokenBalance).where(TokenBalance.user_id == user_id)).all() | |
| points_amount = sum(tb.amount for tb in balances) | |
| points_score = min(1.0, points_amount / 1000.0) | |
| return W_RECENCY * recency_score + W_FREQUENCY * freq_score + W_POINTS * points_score | |
| def segment(score: float) -> str: | |
| if score >= 0.75: | |
| return "loyal" | |
| if score >= 0.4: | |
| return "active" | |
| if score > 0.0: | |
| return "at-risk" | |
| return "new" | |