Data analyst portfolio
Seven data problems,
worked end to end.
I'm a data analyst who works across the full pipeline — raw files and SQL at one end, a dashboard someone actually opens at the other. SQL, PostgreSQL, Excel, Python, Databricks, Snowflake, Alteryx, Power BI and Tableau, applied to customer due diligence, payment fraud controls, data-quality automation, drug shortages, retail revenue, lending risk, and inventory data.
Noida, India · Open to relocation · Available to join immediately
Curious by nature. Analytical by training.
I graduated with a B.Tech in Computer Science in 2023 and I'm building my career in data analytics. I like connecting the technical work — cleaning data, writing queries, building models — to the actual business question it needs to answer.
I currently hold a contract role at Innodata evaluating AI-generated dashboards, charts and reports for accuracy — which has made me considerably more careful about the details in my own work.
I'm HackerRank certified in SQL (Advanced), Python (Basic) and R (Intermediate), with 5-star Gold badges in SQL and Python — verify on HackerRank.
I'm looking for a Data Analyst, BI Analyst, Tableau or Power BI Developer, CDD / KYC analytics, or risk and data-assurance analytics role where I can contribute with SQL, Python, Excel, Tableau, Power BI and reporting that people actually use.
Explore my GitHub-
01
Start with the business question
Define what matters, who needs the answer, and which metrics will help.
-
02
Make the numbers trustworthy
Validate the data, document assumptions, and reconcile results across tools.
-
03
Make the insight usable
Build clear dashboards and explain the decisions the analysis can support.
What I work with
Pulled straight from the tools actually used across the seven projects below — nothing listed here that isn't demonstrated in a repo.
Languages & querying
BI, visualization & tools
Data engineering
Applied methods
CDD & risk decisioning · PostgreSQL, Python, scikit-learn, pytest, GitHub Actions, Power BI
CDD Risk Decisioning & Model Monitoring
Which customers need enhanced due diligence or a review, can each decision be explained against UK regulation, and can a model rank review cases better than the rules without seeing anything that wasn't known on the review date? On a synthetic portfolio of 5,000 customers and 6,222 review cases in 2025, with the real FATF lists in force during 2025, I built the pipeline, the rules, a review queue, a validated model and its monitoring.




What this shows
- Built a PostgreSQL pipeline in three schemas: RAW as delivered, STAGING typed with nothing silently corrected, and ANALYTICS. Row counts reconcile between layers, and 11 KYC data-quality checks matched all 67 planted errors.
- Wrote 12 CDD rules, each mapped to its UK legal basis (Money Laundering Regulations 2017 regs. 5, 28, 33 and 35, and the UK sanctions regime) and labelled as statutory, bank judgement or an illustrative threshold. Since SI 2024/69, UK high-risk third countries follow the FATF lists, so country status is checked on each review date: Nigeria triggers enhanced due diligence before its removal on 24 October 2025, and not after.
- Ranked 2,438 flagged customers into P1 to P3 (every unresolved sanctions match is P1) and measured each rule's precision, recall and lift against analyst escalations. The activity rules reached lift above 2; the PEP rule stayed below 1 and stays in place, because enhanced due diligence for PEPs is required by law.
- Compared logistic regression, a random forest and the rules under a protocol fixed in advance: train January to June, choose the model and threshold on July and August, test once on September, monitor October to December. Rules, model inputs and the simulated analyst outcome share one information cutoff. In September the model flagged 173 cases against 257 for the rules, catching 63 of 92 escalations against 67.
- Monitored drift (PSI) and AUC every month. Online customers' cross-border activity moved from October (PSI 0.10 to 0.29) while the model's score and monthly AUC (0.785 to 0.813) held, so the pre-set rule called for investigation rather than retraining.
- Logged six defects, including PostgreSQL's GREATEST() turning missing history into "very low turnover" (caught when a drift alert fired before any drift existed) and a leak an independent review found in the rules baseline. Each was fixed, re-run and covered by a regression test.
What I'd recommend: Correct the 67 records, clear P1 cases first, use the model to order the queue alongside the statutory rules rather than replace them, and investigate the Online cross-border change before deciding on retraining.
Risk & data assurance · Databricks, SQL, Alteryx, Python, Power BI
Payment Transaction Controls & Fraud Risk Analytics
Can this payment data be trusted, how well do simple rule-based controls catch fraud, and does a model add anything the rules miss? Using the public PaySim synthetic mobile-money dataset (6,362,620 transactions, 8,213 of them fraud), I built the full trail: a reconciled cloud pipeline, data-assurance checks, five tested controls, and a leakage-aware model comparison.




What this shows
- Built a Databricks Bronze → Silver → Gold pipeline, hashed account IDs with a salted SHA-256 in Silver, and reconciled row count, total amount and fraud count across every layer.
- Ran six data-assurance checks and logged exceptions instead of deleting rows. Two checks failed on 56.6% of transactions with almost no fraud (a simulator artifact), while receiver-balance mismatches carried a 1.57% fraud share — about 12× the baseline.
- Tested five rule-based controls for precision and recall: two caught about half of all fraud at 65–70% precision, while one caught 97.55% of fraud at only 0.67% precision. Rebuilt two controls in Alteryx and matched the SQL counts exactly.
- Trained logistic regression and a random forest on a time-based split and flagged the forest's perfect score as leakage from PaySim's balance logic. Re-testing the controls on the same test window changed the story: the two best rules reached 100% and 98.65% precision against 52.16% for logistic regression, but caught only about half the fraud the models did (97%+). The real trade-off is recall, not precision.
- Hand-reviewed a stratified sample of 25 flagged transactions in an Excel control-testing workpaper (7 were fraud, all from the two strongest rules), and back-tested an hourly fraud-count forecast: regression beat a seasonal baseline, MAE 4.38 vs 5.92.
- Wrote a one-page research memo on rules vs. machine learning, drawing on RBI's FAQ on the fraud risk management directions and its FREE-AI report (August 2025).
What I'd recommend: Keep the two strongest rules as primary controls, retire or redesign the rule that flagged 2.49M transactions for 45 frauds, and use logistic regression to prioritize alerts instead of the leaky random forest.
Data quality & automation · Python, YAML, pytest, Power Automate Desktop, Excel, Windows Task Scheduler
Business Data Quality Automation
Sales records collect errors over time: the same company under two IDs, blank required fields, statuses like "Actve", close dates before created dates, opportunities linked to accounts that don't exist. I built a rule-based check that runs every day without anyone starting it and writes an Excel report of exactly which rows to fix. The data is synthetic, with 90 planted errors kept as an answer key.




What this shows
- Built a validation engine in Python (pandas) that reads its checks from a YAML file: required fields, allowed values, patterns, ranges, duplicate keys and names, referential integrity and date order. Each run writes an Excel report with one sheet of failing rows per check, plus a history log.
- The run stops with exit code 2 and a clear log message if a config file, data file or column is missing, so the automation around it can react instead of carrying on with bad input.
- Built a Power Automate Desktop flow that runs the check, logs failures with their reason, files each report into a dated folder, reads the Excel summary and logs the result. The free version cannot schedule flows, so the Python check runs daily at 09:00 from Windows Task Scheduler, set to run on battery, wake the laptop and catch up after a missed run.
- Tested with 15 pytest tests (answer-key match, clean data, edge cases such as amount 0 vs 0.01 and probability 100 vs 101, missing files) and a 17-case test plan. Logged four defects, including pandas silently reading the text "N/A" as a blank value.
Healthcare data · PostgreSQL, Google Sheets, Excel, Python, local GenAI
FDA Drug Shortage Analysis
Which US drugs are in shortage, for how long, and can the data behind the answer be trusted? Using the FDA Drug Shortages list (1,605 records, public domain), I analysed it in Google Sheets, rebuilt it as a PostgreSQL database run like a small production system, tested how accurately a local AI model reads the list's free-text notes, and wrote an oncology brief that adds FDA's NDC Directory.




What this shows
- Cleaned the FDA list with formulas in a separate tab so the raw import was never edited, counted distinct drugs as well as product records, and logged every check. Counting records alone would have hidden that Pediatric medicines are the most widely affected area.
- Built a normalised PostgreSQL database: 6 tables with primary and foreign keys, CHECK rules and a natural-key UNIQUE constraint. PostgreSQL refused the raw file over blank lines and 4 unescaped inch marks that Google Sheets had accepted, so a script writes a corrected copy for loading.
- Ran 23 logged data-quality checks, set up a read-only analyst role limited to four reporting views, tested indexes with EXPLAIN ANALYZE, and verified a pg_dump backup by restoring it and comparing a checksum of every record.
- Applied a newer FDA download in one transaction with an audit trigger: 39 records updated, 2 deleted, and the database matched the new file exactly afterwards.
- Tested a local LLM (Qwen3 4B via Ollama) on 60 sampled notes: 57 of 60 recovery dates matched. A format check caught two broken dates, but only the comparison with a reference caught the date it missed.
- Ran Fisher's exact test at the drug level: pediatric drugs are not significantly more likely to have a fully unavailable product (p = 0.27).
- Built an oncology brief combining the shortage list with 216 marketed products from FDA's NDC Directory, in an Excel model with adjustable weights. Flurazepam, a sleep medicine tagged Oncology by FDA, was kept in the data but excluded from scoring.
What I'd recommend: Shortlist streptozocin and pentostatin, which have no generic supplier, for a feasibility study; in crowded markets such as carboplatin, compete on reliable supply rather than entry; and re-run the screen monthly as the list changes.
Retail analytics · Python, Snowflake, Tableau (LOD, data blending, Cloud), local GenAI
Customer Revenue & Retention Analytics
Using the public UCI Online Retail II dataset from a UK-based online retailer, I asked which customers actually drive revenue, how much cancellations cost, and whether first-time buyers come back. The project analyzes 1,033,036 cleaned transactions from December 2009 through December 2011 to answer it.



What this shows
- Built a 3-layer Snowflake warehouse — RAW, STAGING, ANALYTICS — and reconciled row counts and revenue totals across every layer before building a single dashboard.
- Combined two overlapping source files (1,067,371 rows), removed 34,335 duplicates, and flagged a suspected £38,970 entry error instead of deleting it.
- Ran RFM segmentation on 5,852 identified customers; the "Champions" segment is 24.74% of them but generates 74.04% of identified-customer net revenue.
- Added a segment dashboard using all three LOD types: FIXED for revenue share and a country benchmark, INCLUDE for revenue per country, and EXCLUDE for UK share. High-Value Active is the only segment that earns most of its revenue outside the UK (54.30%).
- Blended the Python RFM table with the Snowflake segment mart in Tableau to reconcile revenue shares; every segment matched within 0.05 percentage points, the rounding in the export.
- Published the workbook to a Tableau Cloud developer site with Analyst and Viewer groups and locked project permissions, denied data downloads for viewers, and tested it by signing in as the viewer.
- Built monthly cohort retention curves — retention drops sharply after month 1, then stabilizes near 20–23% through month 12.
- Classified 4,725 products into 12 categories using a locally-hosted LLM (Qwen3:4B via Ollama), so no transaction data left the machine and no paid API was needed.
- Summarised the findings and recommendations in a 7-slide PowerPoint deck with native charts and speaker notes.
What I'd recommend: Weight retention effort toward Champions, test a follow-up within 30 days of the first order, and start capturing cancellation reason codes.
Credit risk analytics · Power BI, Power Query, DAX, row-level security
Loan Default Risk Analysis
A single blended default rate hides where the risk is. Using a public Kaggle loan-default dataset (via a Udemy course, with an added loan-date column), this dashboard asks which borrower segments carry the most risk and how much loan value that risk represents, breaking down 255,347 loans by credit score, income, employment, interest rate, and dependent status.






What this shows
- Modeled a star schema (date and loan-purpose dimensions), a centralized measures table, and time-intelligence DAX (YTD, YoY) rather than relying on flat aggregates.
- Added static and dynamic row-level security (USERPRINCIPALNAME with a security table) and tested both roles in Power BI Desktop with View as. The report is not published to the Power BI Service, which needs a work account.
- Compared loan purposes with ALLSELECTED, REMOVEFILTERS and RANKX measures, plus a measure that writes the page's takeaway sentence, so it stays correct when slicers or security change what a user sees.
- Built a field-parameter so one visual pivots between co-signer, mortgage, and dependent status without duplicating pages.
- Used a decomposition tree so a viewer can investigate defaulted exposure by any borrower characteristic themselves.
- Separated default rate (by loan count) from defaulted amount share (by loan value): 11.61% vs 13.15%, so counting loans alone understates the value at risk.
- Caught a wrong denominator in my own first version (each group's defaults divided by all loans), rebuilt it as one reusable default-rate measure, and checked every KPI against the source data.
What I'd recommend: Size exposure by loan value, not only by count, and test tighter approval criteria or risk-based pricing for the highest-risk segments.
Inventory analytics · SQL Server, MySQL, Power BI
Inventory Demand & Supply Analysis
Before this could be a Power BI story, it was a data-trust problem: could the inventory data even be relied on? The project validates the data first, simulates a reporting migration from SQL Server to MySQL, then quantifies exactly where shortages are costing revenue.



What this shows
- In a simulated production environment, caught a referential data-quality issue — two product IDs that didn't exist in the product master — and followed a documented detect → investigate → escalate → confirm → correct → validate workflow before touching the report.
- Simulated a migration of the reporting pipeline from SQL Server to MySQL, reapplied every data-quality correction, and re-validated that the numbers still matched.
- Modeled fulfillment rate, revenue at risk, and value fulfillment rate as DAX measures, not simple row counts.
- Showed that the products with the highest unfulfilled demand aren't always the ones with the highest revenue at risk — shortage quantity and financial exposure need to be prioritized separately.
What I'd recommend: Set reorder points for the top 10 products by revenue at risk, and track demand and value fulfillment together as paired KPIs.
Compare the work
The same skill set applied seven different ways — a tested CDD decisioning and model-monitoring pipeline, a cloud risk-and-controls pipeline, an automated data-quality check, a PostgreSQL database built around public health data, cloud warehousing plus Tableau, the Microsoft BI stack, and a migration bridging both.
Click a project name to isolate what it actually used.
| Skill / technique | CDD Risk | Fraud Controls | Data Quality Automation | Drug Shortages | Revenue & Retention | Loan Default Risk | Inventory |
|---|---|---|---|---|---|---|---|
| Python & Pandas | ✓ | ✓ | ✓ | ✓ | ✓ | — | — |
| SQL (Databricks / Snowflake / SQL Server / MySQL / PostgreSQL) | ✓ | ✓ | — | ✓ | ✓ | — | ✓ |
| Power BI & DAX | ✓ | ✓ | — | — | — | ✓ | ✓ |
| Power BI row-level security & star schema | — | — | — | — | — | ✓ | — |
| Tableau | — | ✓ | — | — | ✓ | — | — |
| Tableau LOD expressions & data blending | — | — | — | — | ✓ | — | — |
| Tableau Cloud publishing & permissions | — | — | — | — | ✓ | — | — |
| Cloud data warehousing (layered / medallion) | — | ✓ | — | — | ✓ | — | — |
| Database migration | — | — | — | — | — | — | ✓ |
| Local GenAI / LLM classification & extraction | — | — | — | ✓ | ✓ | — | — |
| RFM & cohort retention analysis | — | — | — | — | ✓ | — | — |
| Data-quality remediation (simulated production) | — | — | — | — | — | — | ✓ |
| Excel workpaper | — | ✓ | — | — | — | — | — |
| Databricks & PySpark | — | ✓ | — | — | — | — | — |
| Alteryx | — | ✓ | — | — | — | — | — |
| Control testing & data assurance | ✓ | ✓ | ✓ | — | — | — | — |
| Machine learning (scikit-learn) | ✓ | ✓ | — | — | — | — | — |
| Time-series forecasting | — | ✓ | — | — | — | — | — |
| PostgreSQL design, roles, backup & audit trail | — | — | — | ✓ | — | — | — |
| Google Sheets analysis & Excel scoring model | — | — | — | ✓ | — | — | — |
| Hypothesis testing | — | — | — | ✓ | — | — | — |
| Automated testing (pytest) & CI (GitHub Actions) | ✓ | — | ✓ | — | — | — | — |
| Workflow automation (Power Automate Desktop, Task Scheduler) | — | — | ✓ | — | — | — | — |
| Rules mapped to regulation (UK MLR 2017, FATF lists) | ✓ | — | — | — | — | — | — |
| Model validation, drift & performance monitoring | ✓ | — | — | — | — | — | — |
At a glance
| Project | Business question | Dataset | Primary tool | Headline result |
|---|---|---|---|---|
| CDD Risk Decisioning | Which customers need review, why, and does a model rank cases better than the rules? | Synthetic CDD portfolio · 5,000 customers, 6,222 review cases; real FATF lists for 2025 | PostgreSQL + Python + Power BI | 67 of 67 planted errors found; on an untouched month the model flagged 173 cases vs 257 for the rules, catching 63 of 92 escalations vs 67 |
| Payment Fraud Controls | Can the data be trusted, and do the fraud controls work? | PaySim (public, synthetic) · 6,362,620 transactions, 8,213 frauds | Databricks + SQL + Alteryx | Best control reached 70.46% precision against a 0.13% baseline; a perfect-scoring model was flagged as leakage, not reported as a win |
| Data Quality Automation | Can business-record errors be found every day without anyone starting the check? | Synthetic CRM data · 514 accounts, 1,505 opportunities, 90 planted errors | Python + Power Automate + Task Scheduler | All 90 planted errors found with nothing else flagged; runs daily and files an Excel exception report |
| FDA Drug Shortages | Which drugs are short, for how long, and can the data and an AI model be trusted? | FDA Drug Shortages list (public) · 1,605 records; FDA NDC Directory for the oncology brief | PostgreSQL + Google Sheets + Excel | 69 drugs in current shortage, median 4.9 years on the list; the local LLM matched 57 of 60 recovery dates |
| Revenue & Retention | Who drives revenue, and who comes back? | UCI Online Retail II (public) · 1,033,036 transactions, 5,852 customers | Snowflake + Tableau | 72.35% of identified customers are repeat buyers, driving 96.74% of identified-customer sales |
| Loan Default Risk | Which borrower segments actually carry default risk? | Public loan dataset · 255,347 loans | Power BI + DAX | 11.61% default rate overall, up to 19.71% in the riskiest segment |
| Inventory Demand & Supply | Where does unmet demand become a business risk? | 99 product-level inventory records | SQL Server → MySQL + Power BI | $97.37K in revenue at risk identified down to the SKU |