Project Record
X Account Profiler
Full-stack prototype that scores public X accounts on a transparent 0–100 scale from official API data, with categorized evidence and a shareable report UI.
Executive Summary
Public X profiles expose raw counts — followers, bio text, verification badges — but those numbers alone do not answer whether an account is credible, intentional, or actively engaged. Anyone screening candidates, reviewing token-sale applicants, or comparing thought leaders needs a synthesized view with an audit trail, not a profile clone.
I built X Profiler, a full-stack prototype that fetches official X API v2 data and produces a continuous 0–100 account intelligence report. Twenty-one weighted components roll up into five interpretable categories: identity, profile completeness, network, trust status, and recent activity. Each score point links back to raw evidence in an expandable report UI with breakdown charts, insight cards, and posting cadence visualizations. A bundled demo mode lets reviewers explore the report format without live API calls.
The scorer is deliberately heuristic and transparent — every formula is documented and testable — not a trained ML model. It is prototype-grade: mathematically coherent and explainable, but not validated for high-stakes decisions. The honest scope is an intelligence layer that makes weak signals comparable, not an automated verdict engine.
This demonstrates feature engineering from API-constrained data, weighted scoring model design, missing-data handling with completeness transparency, and full-stack delivery (Python scoring engine, CLI, serverless API, React report UI).
Problem
Given a public X handle, synthesize heterogeneous profile and activity signals into one comparable score on a 0–100 scale, with per-component evidence that a reviewer can inspect. The system must work under real API constraints: optional fields go missing, impressions are not always available, and only a bounded sample of recent posts can be fetched.
The output must be consistent across entry points (CLI, API, UI) and must not hide data gaps behind a confident-looking number.
Scoring Model
Signals are grouped into five categories aligned with account credibility and intentionality:
| Category | Components | Approx. weight share |
|---|---|---|
| Identity | age, premium, identity verified, verified followers | ~21% |
| Completeness | description, location, profile picture, banner, url, entities, pinned tweet, recent tweet reference | ~25% |
| Network | followers, following | ~14% |
| Trust status | protected, parody, withheld, affiliation, subscription | ~19% |
| Activity | posting frequency, engagement | ~30% |
Each component is normalized to using a transform matched to the signal shape: log scaling for heavy-tailed counts (followers), exponential saturation for account age (365-day half-life), binary flags for platform status, and linear-to-target ratios for activity benchmarks (14 posts/week and 2% engagement rate as full-score targets).
The final score rescales over available evidence rather than treating missing components as zero:
where the sum runs only over components with non-missing scores and configured weights . Completeness is reported separately:
Completeness measures data coverage, not statistical confidence. A high with low means the score rests on thin evidence.
Post-level raw metrics are derived from up to 100 recent original public posts (replies and retweets excluded): total engagement (likes + replies + retweets + quotes), average engagements, average impressions (over posts where impressions exist), engagement rate, and posts per week from the sampled time span.
Implementation
The pipeline is a strict three-layer contract:
- Ingestion —
x_api.pyfetches profile fields and paginated posts via X API v2, deriving raw metrics. - Scoring —
scoring.pyapplies 21 component functions and weighted aggregation;config.pycentralizes weights and targets. - Presentation —
presentation.pybuilds the canonical JSON payload consumed by the React report UI.
A provider abstraction decouples scoring from the data source, enabling fixture-based tests and a demo path that serves bundled data for a fixed handle. The same score_handle() entry point powers the CLI, Vercel serverless API, and UI fetch path. The frontend owns display helpers (interpretation sentences, chart labels) but does not redefine scoring formulas.
Trade-offs
A rule-based scorer trades empirical calibration for full explainability — weights encode product priors, not learned relationships. Missing-data rescaling avoids punishing accounts for API field gaps, but a strong-looking score can mislead unless completeness is read alongside it. Engagement scoring uses rate-based efficiency when impressions exist and falls back to average interaction volume otherwise, so the same component name measures different concepts depending on data availability. Following is scored by distance from a manually chosen sweet spot (500), reflecting intuition about curated versus spammy behaviour rather than empirical fitting. Only original public posts are scored, which gives a cleaner publishing signal but ignores reply and retweet activity. The model was reviewed as robust enough for prototype use — internally consistent and resilient to missing data — but not for production decision-support without further validation.