Similarity search for deduplication
NearestNeighbors without any prediction task attached. This is the core of complaint deduplication and entity matching.
from sklearn.neighbors import NearestNeighbors
from sklearn.feature_extraction.text import TfidfVectorizer
vec = TfidfVectorizer(analyzer="char_wb", ngram_range=(3, 5))
X = vec.fit_transform(complaint_texts)
nn = NearestNeighbors(n_neighbors=5, metric="cosine").fit(X)
distances, indices = nn.kneighbors(X)
# Skip column 0 - every row is its own nearest neighbour
THRESHOLD = 0.25 # cosine distance; tune against human judgement
for i, (d, idx) in enumerate(zip(distances, indices)):
dupes = [(j, dist) for j, dist in zip(idx[1:], d[1:]) if dist < THRESHOLD]
if dupes:
print(f"\nrow {i}: {complaint_texts[i][:60]}")
for j, dist in dupes:
print(f" ~{dist:.3f} {complaint_texts[j][:60]}")
# The threshold IS the job here. There is no principled way to set it
# without labelled pairs, so budget time for tuning it.