The Setup
The dataset: 112 products scraped from Jumia Kenya, with fields for current price, old price, discount percentage, review count, and customer rating. The goal was to clean it, analyze it, and turn it into an interactive Excel dashboard — the kind with slicers and pivot charts, not just static tables.
Cleaning: The Unglamorous Part That Actually Matters
Before any analysis, I had to fix:
Prices stored as text — Excel treats "KSh 1,499" as a string, not a number, so no math works until you strip the formatting
Ratings buried in descriptive text — extracting a clean numeric rating from messy scraped fields
Invalid negative review counts — clearly a scraping artifact, not real data
55 of 112 products (49%) with no review or rating data at all
That last one was the decision point that shaped everything after it. I could have dropped those 55 rows. Instead, I labeled them explicitly — "No reviews" and "Not Rated" — rather than treating them as noise. That turned out to matter a lot, because half the catalog having zero customer feedback is itself one of the most important findings in the whole project, not something to clean away.
Feature Engineering: Building Categories for Pivot Analysis
To make pivot tables and slicers actually useful, I added four calculated columns:
Review_Category — Low / Medium / High / No reviews
Rating_category — Poor / Average / Excellent / Not Rated
Discount_category — Low / Medium / High Discount
price_category — Low / Medium / High / Premium (quartile-based bands)
This is the part that felt most like actual data engineering rather than spreadsheet work — deciding on thresholds, handling edge cases (blank cells silently evaluating as 0 in Excel formulas, which almost mislabeled every unrated product as "Poor" quality), and making sure every downstream pivot table had clean, consistent categories to group by.
Building the Dashboard
I built 8 pivot tables from a single shared table (tblCleaned), which turned out to be the key technical decision: every pivot table needs to come from the same source table for slicers to control all of them simultaneously. Miss this, and you end up with a slicer that only filters one chart instead of your whole dashboard — a mistake I made and had to fix along the way.
The dashboard includes:
5 KPI cards (total products, average price, average discount, average rating, total reviews)
3 top-10 bar charts (by rating, by reviews, by discount)
3 trend charts (discount vs. reviews, rating vs. reviews, price vs. rating)
2 pie charts (rating breakdown, discount breakdown)
3 slicers (rating category, discount category, price category) connected across all 8 pivots
What the Data Actually Said
Discount % vs. Review count: correlation ≈ -0.14
Higher discounts do not lead to more reviews. If anything, there's a very weak negative relationship.
Rating vs. Review count: correlation ≈ +0.06
Essentially zero relationship. Highly-rated products don't get meaningfully more reviews than mediocre ones.
Price vs. Rating: correlation ≈ +0.15
Barely positive. Expensive products are not reliably rated higher than cheap ones — though mid-to-upper-priced items (KSh 1,190–1,820) did show the best average rating (~4.2) of any price tier.
Only 16 of 112 products (14%) hit "strong engagement" (14+ reviews)
90% of heavily discounted products (40%+ off) show low or no engagement
49% of the entire catalog has zero reviews, regardless of discount or price
The product that stuck with me most: a 120W Cordless Vacuum Cleaner with 69 reviews — the most of any product in the dataset — sitting at just 2.8★. High visibility, low satisfaction. That's a much bigger red flag than a discount that didn't move the needle.
Repo & Full Breakdown
Full project, including the cleaned dataset, the Excel workbook (raw data → cleaned data → pivot tables → dashboard), and a detailed README with all findings:https://github.com/kimutaikoros/jumia-product-performance-dashboard
Over the past several weeks, I kept seeing something unusual in my GitHub followers.
Not one suspicious account.
Not even one suspicious batch.
Repeated waves of accounts would appear with remarkably similar characteristics:
dozens of newly generated repositories
thousands of outbound follows
r
Error: model 'Natuworkguy/flash-onyx-2.2:31b' not found (status code: 404)
I never built :31b.
I built :31b-cloud. I asked for :31b-cloud. Ollama went looking for something else, didn't find it, and told me so, using a name that existed nowhere on my machine, in my registry, or in my head.
T