BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2,或任何藍牙控制器搭配 MyWhoosh、Rouvy、Zwift 等。可於 iOS、Android、Windows 與 macOS 免費試用。
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
ML-powered UFC fight analytics. Scrapes every UFC event from UFCStats.com, trains machine learning models on historical outcomes, and publishes weekly predictions for upcoming cards with a full transparency scorecard.檢視完整 README ↗ML-powered UFC fight analytics. Scrapes every UFC event from UFCStats.com, trains machine learning models on historical outcomes, and publishes weekly predictions for upcoming cards with a full transparency scorecard.
Live site: kabes-maybes.vercel.app
text(), no ORM model layer)kabes-maybes-api, us-central1)@theme block in index.css)main)All endpoints versioned under /api/v1. Swagger docs at /docs.
| Method | Path | Description |
|---|---|---|
| GET | /health | Liveness check |
| GET | /health/db | DB readiness (503 if unreachable) |
| GET | /api/v1/fighters | Paginated fighter list (?search=, ?page=, ?page_size=) |
| GET | /api/v1/fighters/{id} | Fighter profile + physical stats + career record |
| GET | /api/v1/fights | Paginated fight list (filters: event, fighter, weight class, method) |
| GET | /api/v1/fights/{id} | Fight detail + round-by-round stats |
| GET | /api/v1/events | Paginated event list (?year=) |
| GET | /api/v1/events/{id} | Event detail + full fight card |
| POST | /api/v1/predictions/fight-outcome | Win probability + method breakdown |
| POST | /api/v1/chat | Natural-language Q&A — converts question to SQL, executes, returns formatted answer (Groq/gpt-oss-120b) |
| GET | /api/v1/analytics/style-evolution | Finish rates, output metrics, and physical stats by year (?weight_class=) |
| GET | /api/v1/analytics/fighter-endurance/{id} | Round-by-round performance profile |
| GET | /api/v1/analytics/betting-insights | Model vs Vegas ROI summary, strategy leaderboard, calibration data |
| GET | /api/v1/analytics/betting-insights/fights | Fight-level model vs Vegas breakdown (filterable by conviction, weight class) |
| GET | /api/v1/analytics/betting-roi | Aggregated ROI by strategy and conviction bucket |
| GET | /api/v1/upcoming/events | Upcoming UFC events ordered by date |
| GET | /api/v1/upcoming/events/{id} | Upcoming event card + pre-computed predictions |
9 GitHub Actions workflows keep everything current:
Daily 03:00 UTC → daily-keepalive ping Supabase to prevent free tier pause
Daily 06:00 UTC → pipeline-health open a GitHub issue if a pipeline run failed
or a finished card's predictions were not archived
Saturday 15:00 UTC → upcoming-predictions scrape announced fights + compute predictions
Sunday 14:00 UTC → weekly-ufc-scraper scrape completed events from UFCStats
→ post-scrape-clean ETL (FK resolution, type parsing, derived cols)
+ archive pre-fight predictions before features change
(runs even if validation fails)
→ feature-engineering rebuild training_data.parquet
→ retrain retrain models + commit artefacts
→ deploy-backend build Docker image + deploy to Cloud Run
Every push / PR → pipeline-check run the pipeline's gates against live data
scripts/check-pipeline.sh is the same check, runnable locally and wired into a pre-push hook (git config core.hooksPath .githooks).
| Subset | Accuracy | Fights |
|---|---|---|
| All fights (test set) | 63.57% | 958 |
Test period: Apr 2024 - Jun 2026. Model: the win/loss classifier is re-selected on every retrain by validation AUC from three candidates - logistic regression, random forest, and gradient boosting (XGBoost). The three sit within noise of each other, so the selected model varies retrain to retrain.
Features: 30 differentials across physical attributes, rolling striking/grappling metrics, experience, and time-based features. Full per-event and conviction-bucket breakdowns are live on the Betting Insights page.
git clone https://github.com/kibbbles/ufc_analytics_platform.git
cd ufc_analytics_platform
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r backend/requirements.txt
Create .env in the project root:
DATABASE_URL=postgresql://...
ENVIRONMENT=development
LOG_LEVEL=DEBUG
ALLOWED_ORIGINS=["http://localhost:3000"]
cd backend && python run_dev.py
# API: http://localhost:8000
# Docs: http://localhost:8000/docs
cd frontend && npm install
npm run dev # http://localhost:3000 (proxies /api → :8000)
npm run build # production build
npm run type-check
npm run lint
ufc_analytics_platform/
├── backend/
│ ├── api/
│ │ ├── main.py # FastAPI app, CORS, middleware, exception handlers
│ │ ├── dependencies.py # get_db() session dependency
│ │ ├── routers/health.py # /health, /health/db
│ │ └── v1/endpoints/ # fighters, fights, events, predictions, upcoming,
│ │ # past_predictions, analytics, chat
│ ├── core/ # config, logging, middleware
│ ├── db/ # SQLAlchemy engine + SessionLocal
│ ├── features/ # Feature engineering pipeline
│ │ ├── pipeline.py # build_prediction_features(fighter_a_id, fighter_b_id, as_of)
│ │ ├── extractors.py # get_fights_long_df(), get_stats_df()
│ │ ├── rolling_metrics.py # 3/5/7-fight rolling averages + EWA
│ │ └── run_build.py # Entry point → training_data.parquet
│ ├── ml/ # Models + evaluation
│ │ ├── win_loss_v1.joblib # Win/loss classifier (best of LR / RF / XGBoost by val AUC)
│ │ ├── method_v1.joblib # Method classifier (KO/TKO, Sub, Dec)
│ │ ├── metrics.json # Test set metrics
│ │ └── run_train.py # Entry point
│ ├── schemas/ # Pydantic v2 request/response models
│ ├── scraper/
│ │ ├── live_scraper.py # Weekly scraper — all 6 core tables
│ │ ├── upcoming_scraper.py # Upcoming events + fighter matching
│ │ ├── run_upcoming.py # Entry point for upcoming scraper
│ │ ├── compute_past_predictions.py # Retroactive scorecard backfill
│ │ ├── archive_completed_predictions.py # Freeze pre-fight snapshots (Task 26)
│ │ ├── post_scrape_clean.py # ETL orchestrator (4 phases)
│ │ └── validate_etl.py # Data quality validation
│ ├── db/migrations/ # SQL migration files
│ ├── run_dev.py # Dev server launcher
│ └── gunicorn.conf.py # Production server config (reads $PORT)
├── frontend/
│ └── src/
│ ├── components/ # common/, layout/, features/
│ ├── hooks/ # useApi, useDarkMode, useDebounce
│ ├── pages/ # One file per route (lazy-loaded)
│ ├── router/index.tsx # createBrowserRouter
│ ├── services/ # Axios client + API service classes (chatService, etc.)
│ ├── types/api.ts # TypeScript interfaces mirroring Pydantic schemas
│ └── utils/ # Pure helpers
├── .github/workflows/ # 9 automation workflows
├── Dockerfile # Python 3.12-slim, Gunicorn
├── render.yaml # Render IaC (fallback config)
└── docs/ # project_history.ipynb, project_writeup.ipynb
Kabe (kay-bee) — @kibbbles
Last Updated: 2026-07-03
| GET | /api/v1/upcoming/fights/{id} | Single upcoming fight + full feature differentials |
| GET | /api/v1/past-predictions | Model scorecard — summary stats + recent outcomes |
| GET | /api/v1/past-predictions/events | Paginated past events with per-event accuracy |
| GET | /api/v1/past-predictions/events/{id} | All predictions for a specific past event |
| GET | /api/v1/past-predictions/fights | Fight-level search across all past predictions |
| GET | /api/v1/past-predictions/fights/{id} | Single past prediction by fight ID |