Product Analyst — for hiring
Role, stack and metrics — to match against a vacancy.
Analysis
Visualization
Experiments
Retention and segmentation
Infra
All projects
No projects with this tool in this category.
-
Volta Neobank — Product Analytics
Experiments
- Situation
- 'Volta' is a fictional neobank losing users during onboarding: every team had its own number, and none explained where the money leaked
- Task
- Find the critical onboarding step and prove it so the conclusion cannot be dismissed as a convenient sample
- Action
- One discover → validate → measure → optimize loop: funnel, KYC progress-bar A/B, cohorts, KMeans segmentation, DiD causality check
- Result
- KYC fix: +5.72pp conversion (p<0.0001) → €208.5K over 12 months at 13.9× ROI; M3 retention +9.2pp
Python · pandas / NumPy · SciPy / Statsmodels · scikit-learn
-
A/B Testing Methodology Toolkit
Experiments
- Situation
- An A/B method is only as good as its Type I error under the null and its power under a real effect
- Task
- Make the method guarantees verifiable, backed by a simulation run rather than by a citation
- Action
- Modules from the primary literature — SRM, CUPED, delta method, mSPRT, HTE, BH — each calibrated by simulation
- Result
- CUPED cuts variance 17.7% (SE 0.00360 → 0.00327) and the delta method finds a +0.51 pp CTR lift at p < 0.0001 with SRM p = 0.8376 — all 18 modules calibrated by simulation
Python · NumPy / SciPy · pytest · uv
-
Browser Mini-Games — Analytics Arcade
Experiments
- Situation
- Analytics concepts are abstract: a recruiter or student can't feel them from text
- Task
- Make a metric's meaning obvious from the action itself, not from an explanation
- Action
- Self-contained SVG games: A/B test, funnel drop, cohort catch, retention day, SQL and metric match
- Result
- 10 games: 7 analytics and 3 arcade, one file with no server; Playwright smoke tests catch load failures
SVG · JavaScript · Astro · Playwright
-
- Situation
- Analytics portfolios show metrics on a clean CSV; the hard part is analytics embedded in a real multi-tenant product
- Task
- Own the multi-tenant setup end to end: auth, per-org isolation, event ingest, and the experiment result computed in the database
- Action
- SQL views compute funnel, cohort, MRR, and DAU; v_results computes A/B in the DB; RLS isolates rows per organization
- Result
- A/B concluded on a seeded stream: control 29.6% vs treatment 40.7%, +11.1pp at p ≈ 1.7e-10 (chi-square); metrics computed in the live DB for any client
Python · Streamlit · Supabase (Postgres + RLS + Edge Functions) · SQL
-
- Situation
- An analytics portfolio usually starts from a ready-made CSV; this one starts earlier — with instrumenting the app
- Task
- Define events without PII leaks, get them into the analytics tool, and turn raw events into decisions
- Action
- Typed event catalog, PII scrubbing; A/B with chi-square, uplift, Wilson CI, SRM; SQL mirror, Streamlit dashboard, CI, Docker
- Result
- Onboarding test on a seeded stream: completion 55.9% → 70.8% (+26.6%, χ² = 40.10, p < 0.0001, SRM p = 0.90), and 6.3% of completed signups reach a paid upgrade
Python · PostHog · FastAPI · Streamlit
-
- Situation
- The portfolio shows the whole AARRR cycle on one dataset of 8,000 synthetic users, not one metric in isolation
- Task
- Build the metrics so they read as one coherent story rather than a set of disconnected charts
- Action
- Deterministic seed and shared cache: one base for Funnel, Retention, Revenue, and Segments; 5 Streamlit pages
- Result
- Funnel, Retention, Revenue, and Segments read from one consistent base; the same UI became the Supabase project's presentation layer
Python · Streamlit · pandas / NumPy
-
Sales Calls Analytics Dashboard
Analytics
- Situation
- An AI call flow is a 4-step funnel over 16,891 synthetic calls; the export does not say which step loses the client
- Task
- Take call breakdown off manual review and name the funnel step that loses the most clients
- Action
- Step labels from templated script markers, leak broken down by type, weighted contact loss, engagement by hour
- Result
- An answer in a minute: which step loses the client and what to fix; the funnel yields weighted contact loss and a first A/B scenario
Python · Streamlit · pandas
-
SQL Analytics Case Study
Analytics
- Situation
- No production data, and textbook exercises do not show systems thinking: 25 cases on a synthetic dataset
- Task
- Build cases where every query answers a product question and reproduces with one command
- Action
- One self-contained .sql per case, data generator on DuckDB, dbt staging → marts layer, regression tests, live report on Pages
- Result
- The funnel drops 78% at add-to-cart → checkout (54% is the view→cart step); retention falls from ~19.5% (D1) to ~4% (D30); only 3.5% repeat; on real data 72.4% return
SQL · dbt · DuckDB · Python
-
ClickHouse — ten SQL cases on 50M rows
Engineering
- Situation
- ClickHouse cases were checked by eye: the result snapshot was not bound to the SQL files, and the optimisation win mixed a rewritten query with a schema change
- Task
- I needed a lab where every case is scored against a snapshot and an independent engine, and the optimisation win is measured with the query text held constant
- Action
- 50M synthetic events in MergeTree, ten cases from windowFunnel to RFM, DuckDB twins for seven of them, a projection on product_id, and a test asserting the slow and fast SQL are byte-identical
- Result
- The snapshot and seven DuckDB twins agree, slow and fast SQL are pinned as identical by a test, and the projection clears the ≥10× speed-up threshold the suite asserts on a full scan
ClickHouse · DuckDB · SQL · Python
-
Delivery Control Tower
Analytics
- Situation
- Delivery is measured as one average time, while the real question — where time is lost and whether capacity matches the forecast — needs a split by category, channel and city
- Task
- Build a reproducible loop: ETL, marts, order forecast, bottleneck analysis, testable hypotheses and a SQL layer with measured optimizations
- Action
- DuckDB star schema, rolling-origin backtest of four models, time decomposition and load curve, Mann-Whitney with bootstrap CIs, 14 window queries and 3 optimization pairs under EXPLAIN ANALYZE
- Result
- Best WAPE 6.01% at h=7 with seasonal_naive; delivery time barely moves with load (rho = −0.092), yet snacks take 40.0 min against 26.6 min for pizza; the mp channel share grew 5.7 pp
python · sql · duckdb · superset
-
GMV Drop RCA — root cause on real data
Analytics
- Situation
- A 'GMV dropped 10%' alert does not say where the money went: the same total is equally consistent with a collapse in one segment and with a broad decline
- Task
- I needed to decompose the drop down to a concrete segment and prove the attribution was complete rather than a convenient slice
- Action
- Metric tree GMV = users × orders_per_user × AOV on the named population, country × decile decomposition, a separate guest addend, Shapley contributions, an executive dashboard
- Result
- UK decile-1 explains 56.2% of the named drop (−£195,218.25); the full attribution reconciles to £0.00 against an overall −10.0% decline
Python · pandas · DuckDB · Plotly
-
- Situation
- The platform never sees the sale: it closes off-platform, so liquidity is counted from the seller's self-report rather than from an actual transaction
- Task
- I needed to measure how far the proxy drifts from the planted truth per category, and to test whether a paid-visibility decision survives that correction
- Action
- A synthetic log of 6,000 listings and 40,000 sessions with a planted answer key, an EM sold/unsold mixture over observable reply signals, a per-category correction, and a randomised holdout with guardrails
- Result
- The proxy reads 0.2413 against a truth of 0.3070, an error of −0.0657 (−21.4%); after correction the worst category misses by 1.61 pp, and paid visibility yields −2.47% contacts per session at p = 0.308
Python · pandas · DuckDB · SciPy
-
RFM Analysis of Bank Clients
Analytics
- Situation
- The bank accumulates client transactions, but marketing sends everyone the same offer
- Task
- Replace the single offer with targeted segments, each with its own retention strategy
- Action
- Cleaned the transactions, scored Recency, Frequency and Monetary, segmented clients, visualized the distribution in Tableau
- Result
- Six named segments; the top 20% of clients hold 38.2% of revenue (Gini 0.324), and Champions — 6.4% of the base — drive 12.1% of revenue
Python · SQL · Tableau
-
Cohort Analysis Dashboard
Analytics
- Situation
- Cohort retention and LTV on synthetic data: average retention hides the per-cohort dynamics
- Task
- Make retention and LTV readable per acquisition cohort rather than as a single average
- Action
- Retention matrix, ARPU and LTV by cohort, observation-age caveat, Tableau export (CSV + Hyper)
- Result
- Python inside Tableau: 4 cohort calculations on a TabPy server and 65 tests; the cohort matrix replaces average retention and shows churn speed and where monetization diverges
Python · pandas · matplotlib / seaborn · Jupyter Notebook
-
- Situation
- A churn model for a subscription product: a random split leaks future activity into training
- Task
- Score the model so its offline quality is not an artifact of leakage
- Action
- As-of features, a future inactivity label, a chronological split, decisions driven by recall@top-decile and lift
- Result
- The top 10% riskiest catches 54.4% of churners at 5.44x lift, but only 1.75x on the at-risk subgroup: 69.7% of the cohort is a near-guaranteed negative by construction.
Python · LightGBM · scikit-learn · pandas / NumPy
-
- Situation
- A two-sample t-test ignores the pre-period: experiments ask for more traffic than needed and retention offers go to everyone
- Task
- Implement CUPED and uplift modeling and prove neither is biased where the true answer is known in advance
- Action
- CUPED on a pre-period covariate and T-/S-learners on LightGBM; checked against ground truth with AUUC and QINI
- Result
- CUPED cuts the standard error 26% (5.5k users per arm instead of 10k), and a pre-registered break-even threshold of 0.05 ships the campaign to new users only.
Python · LightGBM · scikit-learn · pandas / NumPy
-
- Situation
- Product A/B habits ported into CRM break randomization: users are bucketed at first exposure instead of when the campaign segment is built
- Task
- I needed a lab where every CRM experiment stage is checked against data with a known answer and can be made to fail visibly
- Action
- Simulator over 20,000 users and 12 campaigns: segment-stage randomization, a global control group, a send balancer, and the net effect of unsubscribes
- Result
- Segment-stage randomization holds SRM at p=0.266, GCG uplift is +0.9968 [0.9433, 1.0502], and the net effect is +50.5 per 1,000 treated — positive, but the unsubscribe guardrail breaches.
Python · pandas / NumPy · SciPy · statsmodels
-
- Situation
- A RAG demo is easy to show and hard to measure: you cannot tell whether the retrieval or the generation is failing, or whether the result reproduces at all
- Task
- Build a pipeline with an offline eval harness that separates retrieval from generation metrics and runs without API keys
- Action
- A TF-IDF index over the concept corpus, cosine top-k, a deterministic extractive answerer; Claude plugs in behind a --llm flag and the harness stays the same
- Result
- recall@5 and MRR = 1.00 over 20 questions and 0.00 on an 11-question control set of retrieval misses (MRR@all 0.12) — the metric can fall; correctness 0.37 for the offline baseline (faithfulness ≡1.00 is an extractive invariant); retrieval and generation scored separately
Python · scikit-learn · pandas / NumPy · TF-IDF
-
Python Analytics Playground
Analytics
- Situation
- In product analytics most tasks start the same way: load an export, clean it, check distributions, chart it — from scratch each time
- Task
- Turn the routine into shared modules that teammates can extend without fear of breaking existing behavior
- Action
- load / clean / EDA / viz / pipeline modules mapped to PRD requirements; tests in tests/ check those requirements; uv + ruff tooling
- Result
- pytest coverage ≥80%; modules stay small and single-purpose, requirements live in the PRD, and the tool extends without breakage
Python · pandas / NumPy · Matplotlib · pytest
-
Data Analyst Telegram Bot
Experiments
- Situation
- PMs and analysts often have no BI access: checking an A/B hypothesis waits for a dashboard, and the exported CSV sits there without statistics
- Task
- Check a hypothesis right in Telegram — get a correct result with guardrails from a CSV, without BI and without a notebook
- Action
- Bot on aiogram, pandas, scipy and statsmodels: 12 commands, Welch t-test or chi-square, SRM and power guardrails, analytics as pure modules, pytest + ruff + mypy in CI
- Result
- From a CSV — p-value, lift and 95% CI in under 30 seconds, plus a power note and a chart; /export returns a standalone HTML report
Python · aiogram · pandas · SciPy / statsmodels
-
Scrolly English Speaking
Engineering
- Situation
- Workplace English (A2–B1) stalls for many Russian-speaking specialists: the grammar is there, coherent speech is not
- Task
- Close the gap between grammar and live speech: give learners situations where phrases are used, not recognized
- Action
- Single ScrollyLayout, MDX narrative sections, typed data module for viz props, IntersectionObserver with lazy imports
- Result
- Narrative and visualization in sync: the chart changes as the reader reaches a paragraph; a new scene is just a data file plus MDX
Astro · TypeScript · MDX · D3
-
Digital Garden — EQ in IT
Engineering
- Situation
- Chronological posts age and lose connections; a digital garden links notes with wikilinks instead
- Task
- Publish a personal Zettelkasten as a static site where the links between notes are visible to the reader
- Action
- Atomic notes in Obsidian-flavored Markdown; Quartz: TypeScript plugins, backlinks, graph view, static output
- Result
- Links over chronology: backlinks make each note a node, and the graph turns note accumulation into a navigable structure
TypeScript · Quartz v4 · Markdown · Obsidian
-
SERP Rank Lab
Analytics
- Situation
- A metasearch product earns on the position an offer occupies, so ranking and monetisation are not measured by the same number
- Task
- Find out how much revenue ranking for money produces, and what that revenue is paid for in clicks
- Action
- Two feasible policies on one information set, a user_id rollout with guardrails and a stopping rule, then a diagnosis through the signal source
- Result
- On a synthetic log: +34.45% revenue per search for −16.84% CTR; the rollout returns −14.26% (p = 0.11) and −16.05% conversion → do not ship
Python · DuckDB · Streamlit · NumPy / SciPy
-
Airflow DAG Platform
Engineering
- Situation
- A hand-run report from Postgres into Google Sheets produced delays, copy errors and no reproducibility at all
- Task
- Replace the manual export with a reproducible, idempotent pipeline with DQ validation, failure alerts and run metrics
- Action
- A platform on Airflow 3: the DAG template fetch → validate → write → record_metrics and the shared modules config, dq, alerts, metrics, output, windows
- Result
- Three DAGs on one shared template and 72 tests without Airflow services or a DB; the full DAG runs in 440 s, 413 s of it in the forecast task
Python · Apache Airflow 3 · PostgreSQL · Docker Compose
-
ML Fundamentals — scikit-learn Pipeline
Analytics
- Situation
- Preprocessing is the foundation of all later ML work: a test leak into training or hand-rolled imputation invalidates every model above it
- Task
- Build preprocessing correctly for modern scikit-learn: no leakage, no reliance on a random seed, reproducible at every pipeline stage
- Action
- ColumnTransformer (SimpleImputer → StandardScaler for numerics, OneHotEncoder for categoricals) fit on train only; a deterministic split by sorting on (Country, Age); a dataset generator and EDA plots
- Result
- A split reproducible without a seed (Train (8, 5), Test (2, 5)), four synthetic datasets and 21 tests (7 + 9 + 5) that keep the pipeline runnable
Python · scikit-learn · pandas · matplotlib
-
LinkedIn Content Analytics
Analytics
- Situation
- A format ranking whose confidence interval covers the whole field is not an answer: showing it as one is worse than showing nothing
- Task
- Answer not 'how many impressions did I get' but 'which format to write next — and is the difference even established'
- Action
- One workbook-parsing core, four renderers (markdown report, HTML dashboard, SVG chart, vault note) and per-post bootstrap intervals instead of a point ranking
- Result
- 50,101 impressions, 9,440 reach, 1.71% ER over 12.10.2025 — 11.10.2026; three of four comparisons landed inside the noise, and that is recorded as the result
Python · openpyxl · uv · bootstrap
-
- Situation
- Offline retail measures promo against a pre-period average and picks the discount depth without pricing cannibalisation or margin
- Task
- Measure promo in margin roubles and choose depth and store set under a budget so that the numbers can be re-checked
- Action
- Synthetic panel with known truth, counterfactual, four-bucket ledger, P&L, breakeven, cluster test validated by simulation, Qini against policy value, budget allocation
- Result
- Promo returns +68.5 m RUB of revenue and −24.4 m RUB of profit; 97.9% of waves lose money at a breakeven depth of 1.0–19.5% against 25.4% actual, and on one budget the optimiser earns +231 496 ₽ versus +136 648 ₽ for top-15%
Python · pandas · scikit-learn · PySpark
-
- Situation
- A subscription B2C service must decide whether to roll out a new onboarding flow and cannot say which lever drives more revenue
- Task
- Tie the experiment result to the funnel, cohort retention and unit economics, then issue one management verdict
- Action
- A/B with SRM, ITT and power checks, a funnel down to payment, cohorts and LTV, and a conversion-versus-retention comparison at an equal step
- Result
- SHIP: activation → paid +19.59% (p=0.000946) with no guardrail degradation; at an equal step conversion adds +10.00% to LTV versus +8.65% for retention
Python · pandas / NumPy · DuckDB · SciPy
-
OSS catalog — 47 projects from one source
Engineering
- Situation
- The project catalog was maintained by hand: cards drifted from GitHub, and metadata and links had to be updated in two places
- Task
- I needed a catalog where the data comes from one machine-owned source, pages are built from it, and a repeated sync does not overwrite authored edits
- Action
- Astro 7 with content collections, a Python sync from the GitHub API into TOML, a frontmatter generator with an ownership marker, a notes validator and 26 tests, and CI ordered from the cheap gate to the build
- Result
- 47 project pages and 15 metadata fields are built from one TOML file; a repeated render is idempotent, and 26 tests cover all three record-matching branches
Astro · TypeScript · Bun · Python
-
Matemarketing 2026 Programme — a static replica
Engineering
- Situation
- A conference programme page is a Vue SPA: the data lives in an API and the layout in a bundle, so 'make it the same' usually means 'make it look similar'
- Task
- Take a third-party interface apart down to measurable quantities and rebuild it with no build step and no backend
- Action
- Pulled the programme from the public API, measured the grid on the rendered DOM, rebuilt it in plain HTML/CSS/JS, then ran four independent passes: code review, security audit, browser tests, visual audit
- Result
- The grid matches the original to the pixel: 99 px time column, 420 px hall column, 391 px card, 550 px row, grid top at y = 414; tests catch data and layout drift
HTML · CSS · JavaScript · Python
-
This Portfolio Site
Engineering
- Situation
- A static portfolio on GitHub Pages: projects and posts are edited in Markdown, not in component markup
- Task
- Make publishing a project a content change, not a code change: a new Markdown file, then a push
- Action
- Content collections with Zod schemas, withBase() for the base path, no-flash inline theme script, SEO set, push-to-Pages deploy
- Result
- Invalid frontmatter breaks the build, not the deploy; no link hardcodes the base; adding a project needs no code changes
Astro · TypeScript · Markdown · CSS custom properties