<jupyter_start><jupyter_text>Iskanje besed specifičnih za dokumente z uporabo obogatitve besedV prejšnjem primeru smo iskali specifične besede za dokumente z vložitvami dokumentov. V tem primeru, pa bomo v ta namen uporabili metodo imenovano obgatitev besed (ang. Word enrichment).Obogatitev besed izračuna p-vrednost za vsako od besed v množici vseh besed. Nižja p-vrednost pomeni večjo verjetnost, da je beseda značilna za izbrani dokument.<jupyter_code>import string

import pandas as pd
import nltk
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
from lemmagen.lemmatizer import Lemmatizer
from lemmagen import DICTIONARY_SLOVENE
from IPython.display import display, Markdown
from sklearn.feature_extraction.text import TfidfVectorizer
from scipy.cluster.hierarchy import ward, dendrogram
from sklearn.metrics.pairwise import cosine_similarity
from matplotlib import pyplot as plt

from textsemantics.server_api import ServerAPI
from textsemantics.utils.word_enrichment import hypergeom_p_values, FDR<jupyter_output><empty_output><jupyter_text>Iz seznama predlogov vladi si izberimo zadnjih 100 dokumentov, jih predobdelajmo na isti način kot v prejšnjih primerih.<jupyter_code>nltk.download('stopwords', quiet=True)

def preprocess(corpus):
    stop_words = set(stopwords.words('slovene'))
    tokenizer = RegexpTokenizer("\w+")
    lemmatizer = Lemmatizer(dictionary=DICTIONARY_SLOVENE)
    
    preprocessed = list()
    for text in corpus:
        text = text.translate(text.maketrans({punct: " " for punct in string.punctuation}))
        tokens = tokenizer.tokenize(text.lower())
        tokens = [lemmatizer.lemmatize(token) for token in tokens if token not in stop_words 
                  and len(token) > 2 and not token.isnumeric()]
        preprocessed.append(tokens)
        
    return preprocessed

api = ServerAPI()
metadata = api.get_metadata(
    "predlogi-vladi", sample_size=100, sampling_strategy='latest'
)
metadata['text'] = api.get_texts(urls=metadata['text'])
metadata = metadata[metadata["text"].apply(lambda x: len(x) > 50)]
texts = metadata['text'].values
tokens_list = preprocess(texts)<jupyter_output><empty_output><jupyter_text>Najprej si izpišimo vse besede/izraze, ki smo jih dobili po preprocesiranju četrtega dokumenta.<jupyter_code>display(Markdown(", ".join(tokens_list[4])))<jupyter_output><empty_output><jupyter_text>V naslednjem koraku izračunamo značilke z metodo imenovano vreča based.<jupyter_code>joined_texts = [' '.join(tokens) for tokens in tokens_list]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(joined_texts)
words = vectorizer.get_feature_names()
display(Markdown(f"Število besed v slovarju: {len(words)}"))<jupyter_output><empty_output><jupyter_text>Ko imamo značilke lahko na podlagi teh najdemo značilne besede z metodo obogatitev besed. V prvem koraku bomo napisali funkcijo, ki izračuna p-vrednosti in FDR (popravljeno p-vrednost) za vsako besedo iz množice vseh besed za podani dokument. Funkcija vrne zgolj besede, ki imajo p-vrednosti manjše od 1.<jupyter_code>def specific_words(document_index):
    p_values = hypergeom_p_values(X, X[document_index])
    fdr = FDR(p_values)
    df = pd.DataFrame(
        {"Besede": words, "P-Vrednost": p_values, "FDR": fdr}
    ).sort_values("P-Vrednost", axis=0)
    return df[df["P-Vrednost"] < 1]<jupyter_output><empty_output><jupyter_text>Pokažimo besedilo in značilne besede za dva dokumenta.<jupyter_code>title = f"### {metadata.iloc[4]['title']}"
display(Markdown('\n'.join((title, texts[4]))))
specific_words(4)
title = f"### {metadata.iloc[13]['title']}"
display(Markdown('\n'.join((title, texts[13]))))
specific_words(13)<jupyter_output><empty_output><jupyter_text>Dendrogram z specifičnimi besedamiSedaj, ko imamo postopek za računanje specifičnih besed, lahko te prikažemo v dendrogramu, ki prikazuje podobnosti med dokumenti. Ker bi bil dendrogram z vsemi dokumenti preobsežen, se odločimo za dokuemnte, ki smo jih že obravnavali v zvezku `03_02_distances_and_similarities`.<jupyter_code>idx = [7, 18, 20, 30, 1, 2, 3, 4]

# dendrogram
plt.style.use('seaborn')
tfidf = X[idx, :]
dist_mat = 1 - cosine_similarity(tfidf)
linkage = ward(dist_mat)

# specific words
spec_words = [",".join(specific_words(i).iloc[:5]["Besede"].tolist()) for i in idx]
dendrogram(
    linkage, color_threshold=1.6, 
    labels=spec_words,
    orientation="left"
);<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10092571686610974, 'fraction_numerical': 0.009257168661097314, 'mean_word_length': 5.987381703470032, 'pattern_counts': {'":': 3, '<': 30, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '420119', 'license': 'MIT', 'n_tokens_mistral': 1696, 'n_tokens_neox': 1650, 'n_words': 385, 'path': 'examples/04_02_specific_words_with_enrichment.ipynb', 'repo_name': 'djukicn/text-semantics', 'size': '4429'}