Iz spletnega portala kopiramo nekaj člankov, in besedilo vsakega od teh shranimo v svojo datoteko v direktoriju text-data
. Taki zbirki besedil pravimo korpus. Korpus shranimo v slovar, besedila pretvorimo v množico terk ter podobnost med besedili ocenimo z mero po Jaccardu.
import glob
import os.path
from collections import Counter
from itertools import combinations
corpus = {}
for file_name in glob.glob("text-data/*"):
name = os.path.splitext(os.path.basename(file_name))[0]
text = " ".join([line.strip() for line in open(file_name).readlines()])
text = text.lower()
corpus[name] = text
corpus.keys()
dict_keys(['potop', 'snaga', 'opel', 'audi', 'očistimo'])
corpus['potop'][:100]
'odpadno embalažo in odpadne sveče bi lahko na podlagi interventnega zakona, ki je od petka v javni o'
def kmers(s, k=3):
"""Generates k-mers for an input string."""
for i in range(len(s)-k+1):
yield s[i:i+k]
set(kmers("modra modrina neba"))
{' mo', ' ne', 'a m', 'a n', 'dra', 'dri', 'eba', 'ina', 'mod', 'na ', 'neb', 'odr', 'ra ', 'rin'}
Dela! Spodaj iz slovarja besedil sestavimo slovar množice terk za vsako od slovarjev
data = {k: set(kmers(corpus[k], 3)) for k in corpus}
def jaccard(data, a, b):
"""Jaccard distance between two sets."""
return len(data[a] & data[b]) / len(data[a] | data[b])
test = {'a': {1,2,3,4}, 'b': {1, 3, 4}}
jaccard(test, 'a', 'b')
0.75
Tudi podobnost po Jaccardu dela (za zgornja dva niza je podobnost enaka 3/4). Spodaj zmerimo podobnost za naše članke iz spletnega portala in razmislimo, ali je izračun smiselen.
sorted([(jaccard(data, a, b), a, b)
for a, b in combinations(data.keys(), 2)])
[(0.28112449799196787, 'opel', 'očistimo'), (0.28206896551724137, 'snaga', 'opel'), (0.30111306385471587, 'potop', 'opel'), (0.3038309114927345, 'snaga', 'audi'), (0.310999441652708, 'audi', 'očistimo'), (0.32602423542989034, 'snaga', 'očistimo'), (0.326519023282226, 'potop', 'audi'), (0.37184115523465705, 'potop', 'očistimo'), (0.38333333333333336, 'opel', 'audi'), (0.4154798761609907, 'potop', 'snaga')]