← Work / IntegrityCheck
Academic project 2026

IntegrityCheck

Dual-signal plagiarism detection combining from-scratch lexical shingling with SBERT semantic similarity — catches paraphrasing, not just copy-paste.

IntegrityCheck — main interface

Overview

The problem

Traditional plagiarism checkers rely on exact phrase matching, so a submission that's been reworded — same ideas, different words — sails through undetected, even though the copying is just as real.

What it is

Standard plagiarism detection catches copy-paste but misses paraphrasing entirely — if the wording changes, exact-match methods find nothing. IntegrityCheck combines two independently-built signals: n-gram shingling with Jaccard similarity for verbatim overlap, and Sentence-BERT embeddings with cosine similarity for semantic meaning. A submission that shares zero exact phrases with a source can still be flagged if the underlying ideas match — which is exactly the case exact-match tools miss.

My role & approach

Solo academic project (final-semester) — I implemented both similarity algorithms from scratch, built the FastAPI scoring service, and designed the full Laravel platform including the role-based review workflow.

Both similarity algorithms were implemented from scratch rather than pulled from a library — the shingling/Jaccard lexical scorer and the cosine similarity function both hand-written, with only the SBERT embedding model itself pretrained. The two scores are combined into a single weighted result per comparison, tuned against real test cases (verbatim, paraphrased, and unrelated text) to confirm each signal was catching what the other missed. The system checks submissions against both other student work and the open web, using the Google Custom Search API to find candidate sources and a scraping pipeline to extract comparison text — routed through the same scoring pipeline either way. A Laravel frontend handles the role-based workflow (student, teacher, admin) with a queued job pipeline so similarity checks run asynchronously against the Python FastAPI scoring service.

System flow

Student Submission
Laravel
Queued Job
FastAPI Scoring Service
Similarity Report

FastAPI Scoring Service branches by role

Lexical (Shingling + Jaccard) Semantic (SBERT + Cosine) Web Search + Scrape
2 independent similarity signals combined into one score

Stack

Laravel PHP Python FastAPI Sentence-BERT MySQL Tailwind CSS Alpine.js Google Custom Search API BeautifulSoup

Impact

2

similarity signals — lexical (from scratch) and semantic (SBERT + custom cosine)

3

user roles — student, teacher, admin

Checks against both peer submissions and the open web

Next project

Traffic Accident Hotspot Detection

Live ML system that clusters 1,498 real accident records to identify hazard zones and predict risk by time, weather, and road type.