test build
Some checks failed
Deploy / deploy (push) Has been cancelled

This commit is contained in:
jze9
2026-05-18 01:14:40 +05:00
commit 2a14350ee3
46 changed files with 3620 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
import xxhash
from typing import Set, Tuple, List
from datasketch import MinHash, MinHashLSH
import numpy as np
class WinNowing:
def __init__(self, k: int = 5, window_size: int = 4):
self.k = k
self.window_size = window_size
def get_kgrams(self, text: str) -> List[str]:
words = text.split()
kgrams = []
for i in range(len(words) - self.k + 1):
kgram = ' '.join(words[i:i+self.k])
kgrams.append(kgram)
return kgrams
def fingerprint(self, text: str) -> Set[int]:
kgrams = self.get_kgrams(text)
hashes = []
for kgram in kgrams:
h = int(xxhash.xxh64(kgram).hexdigest(), 16)
hashes.append(h)
if not hashes:
return set()
fingerprints = set()
for i in range(len(hashes) - self.window_size + 1):
window = hashes[i:i+self.window_size]
min_hash = min(window)
fingerprints.add(min_hash)
return fingerprints
def compare(self, fp1: Set[int], fp2: Set[int]) -> float:
if not fp1 or not fp2:
return 0.0
intersection = len(fp1 & fp2)
union = len(fp1 | fp2)
return intersection / union if union > 0 else 0.0
class MinHashLSHIndex:
def __init__(self, num_perm: int = 128, threshold: float = 0.5):
self.num_perm = num_perm
self.threshold = threshold
self.lsh = MinHashLSH(threshold=threshold, num_perm=num_perm)
self.documents = {}
def add_document(self, doc_id: str, text: str):
kgrams = self._get_kgrams(text)
m = MinHash(num_perm=self.num_perm)
for kgram in kgrams:
m.update(kgram.encode())
self.lsh.insert(doc_id, m)
self.documents[doc_id] = m
def query(self, text: str, top_k: int = 10) -> List[Tuple[str, float]]:
kgrams = self._get_kgrams(text)
query_m = MinHash(num_perm=self.num_perm)
for kgram in kgrams:
query_m.update(kgram.encode())
candidates = self.lsh.query(query_m)
results = []
for doc_id in candidates:
similarity = query_m.jaccard(self.documents[doc_id])
results.append((doc_id, similarity))
results.sort(key=lambda x: x[1], reverse=True)
return results[:top_k]
def _get_kgrams(self, text: str, k: int = 5) -> List[str]:
words = text.split()
kgrams = []
for i in range(max(1, len(words) - k + 1)):
kgram = ' '.join(words[i:i+k])
kgrams.append(kgram)
return kgrams