Shingle yöntemiyle kopya içeriği bulmak

İki sayfanın "neredeyse aynı" olduğunu nasıl ölçersin? Arama motorlarının da kullandığı eski ama etkili bir yöntem var: metni ardışık kelime gruplarına (shingle) bölüp iki kümenin ne kadar örtüştüğüne bakmak.

shingles.py
import re
from itertools import combinations

def shingles(text: str, k: int = 5) -> set[str]:
    words = re.findall(r"\w+", text.lower())
    return {" ".join(words[i:i + k]) for i in range(len(words) - k + 1)}

def jaccard(a: set, b: set) -> float:
    return len(a & b) / len(a | b) if a and b else 0.0

sayfalar = {
    "/urun/mavi-tisort": "Pamuklu mavi tişört, rahat kesim, 4 beden seçeneği ...",
    "/urun/kirmizi-tisort": "Pamuklu kırmızı tişört, rahat kesim, 4 beden seçeneği ...",
    "/blog/tisort-secimi": "Doğru tişörtü seçerken kumaş ve kesim en önemli iki konu ...",
}

s = {url: shingles(metin) for url, metin in sayfalar.items()}
for a, b in combinations(s, 2):
    oran = jaccard(s[a], s[b])
    if oran > 0.5:
        print(f"{oran:.0%} benzer: {a} ↔ {b}")

Eşik seçimi

BenzerlikYorum
%90+Pratikte aynı sayfa. Birini canonical yap ya da birleştir
%60-90Şablon ağır basıyor, özgün içerik az
< %40Genelde sorun yok

Karşılaştırmadan önce menü, alt bilgi ve kenar çubuğu gibi her sayfada ortak olan bölümleri çıkar. Yoksa her sayfa birbirine benzer çıkar.

Binlerce sayfada her ikiliyi karşılaştırmak yavaşlar. O noktada MinHash gibi yaklaşık yöntemlere geçmek gerekiyor, ama birkaç yüz sayfa için bu betik fazlasıyla yeterli.

Comments / questions

There's no comment section here. If you have a question or want to add something, message me on Telegram or send an email to [email protected]. Thanks!

Related pages