ReviewScope hunts for anomalies in reviews using embeddings and graphs across 21,000 texts
After moving to a new city, a Habr user went looking for a good bakery through reviews and started noticing suspicious-looking texts — ones that seemed either AI-generated or copy-pasted. That led him to build a tool for catching weirdness in reviews: unusual activity spikes, sharp rating shifts, repeated texts, and rating manipulation. ReviewScope runs locally, stores data in DuckDB, and analyzes CSV and JSON files. The code is open source. • **Four levels of similar-review detection**: Exact (exact matches), Fuzzy (lexically close matches via RapidFuzz), Near (strong lexical similarity via MinHash/LSH), Semantic (meaning-based similarity via embeddings) • **Burst detection**: rolling median + MAD (median absolute deviation) instead of mean and standard deviation • **Rating-shift analysis**: Jensen–Shannon divergence to measure changes in the distribution of 1-to-5-star ratings
AI-processed from Хабр: Машинное обучение; edited by Hamidun News
After relocating, Ziverpup did what he always does: started browsing maps to find places to eat and things to check out. Almost everywhere has a rating above four stars, so he filters by negative reviews — that's where the picture changes. At one bakery, he noticed a strange review: instead of describing an actual experience, the text read like a canned AI response. He started looking for similar cases and found more than one. For instance, a review of a shawarma spot opened with the telltale "This is just a bomb!" followed by a formulaic rundown: lavash, meat, sauce, vegetables, portion size, a promise to become a regular customer.
One example proves nothing on its own, but the idea stuck: build a tool to find anomalies in reviews. Ziverpup had run into this problem before — as a manager, he used to sift through negative reviews and sometimes traced them back to competitors. What interested him more, though, was the authors themselves: someone who's written five reviews about different bars seems like a more useful source of information than someone whose history consists of a tire shop near Tolyatti and a bookstore in Voronezh.
But building logic around reviewer trust turned out to be trickier than expected: the sheer number of reviews doesn't make someone competent. A change of city could just be a trip, and one detailed review can say more than a hundred generic phrases.
Architecture and data
The result is ReviewScope — an open-source tool for analyzing reviews, finding anomalies and duplicate texts, and digging into reviewer history. GitHub: https://github.com/zinverno/reviewscope, demo: https://reviewscope-demo.streamlit.app/.
The tool doesn't pull reviews from Yandex Maps itself. Analysis requires a pre-prepared CSV or JSON export. The app normalizes the data and saves it to DuckDB — everything runs locally, with no separate server needed. A single review record includes the fields: review_id, place_id, place_name, place_category, reviewer_id, reviewer_name, rating, text, published_at, city, region, country, latitude, longitude. Not all fields are required. The Streamlit-based interface shows N/A when data is missing.
The pipeline runs: CSV/JSON → Normalization → DuckDB → AnalysisEngine → Streamlit UI. The AnalysisEngine comprises four modules.
Four layers of anomaly analysis
Burst detection (activity spikes). A given bakery might normally get one or two reviews a week. If thirty show up in a single day, nearly all five-star — that's suspicious. But for a restaurant getting fifty reviews a day, those same thirty mean nothing. The solution: rolling median + MAD (median absolute deviation). MAD measures how far typical values deviate from the norm. A single extreme day barely moves this estimate — unlike the mean and standard deviation, which get pulled by outliers. The modified z-score threshold is set at 3.5, with a 30-day history window.
Rating-shift anomalies. Say you've found a day with an unusually high number of reviews. Are they all five stars? Or mostly ones? For this, Jensen–Shannon divergence comes in — a way to measure the difference between two probability distributions. It compares the share of 1-to-5-star ratings over a historical period against the period around the event. The algorithm catches positive and negative spikes equally well.
Duplicate detection works across four levels of matching: Exact (identical normalized texts), Fuzzy (lexically close matches via RapidFuzz), Near (strong lexical similarity via MinHash/LSH), Semantic (meaning-based matches via embeddings). The first three seemed sufficient at first, but when an author fully rephrased a sentence, lexical methods failed. Embeddings solved that problem.
Reviewer metrics, text scoring, and topic clustering round out the picture. The author added separate metrics: reviewer activity, category-specific experience, text informativeness, and unusual patterns in a reviewer's history.
Testing was done on 21,000 real-world reviews. Some hypotheses didn't survive the test, and one seemingly convincing result turned out to be a calculation error in the growth-rate metric when the baseline was zero. The app now handles such cases by showing the actual number of reviews and noting that the growth rate is meaningless in that context.
Key Questions Answered
What are the key details on Architecture and data?
The result is ReviewScope — an open-source tool for analyzing reviews, finding anomalies and duplicate texts, and digging into reviewer history. GitHub: https://github.com/zinverno/reviewscope, demo: https://reviewscope-demo.streamlit.app/. The tool doesn't pull reviews from Yandex Maps itself. Analysis requires a pre-prepared CSV or JSON export. The app normalizes the data and saves it to DuckDB — everything runs locally, with no separate server needed. A single review record includes the fields: review_id, place_id, place_name, place_category, reviewer_id, reviewer_name,
What are the key details on Four layers of anomaly analysis?
Burst detection (activity spikes). A given bakery might normally get one or two reviews a week. If thirty show up in a single day, nearly all five-star — that's suspicious. But for a restaurant getting fifty reviews a day, those same thirty mean nothing. The solution: rolling median + MAD (median absolute deviation). MAD measures how far typical values deviate from the norm. A single extreme day barely moves this estimate — unlike the mean and standard deviation, which get pulled by outliers. The modified z-score threshold is set at 3.5, with a 30-day history window. Rating
Build & Ship Production AI Apps with Vibe Coding
Join Zhemal Khamidun's hands-on Vibe Coding Intensive at hamidun.com/vibecoding — master Claude Code, Cursor, and autonomous agentic workflows.
The AI world, distilled — once a week
Seven stories that actually mattered, hand-picked. No noise, no reposts, no press releases.
Done! Check your inbox for a confirmation.