<jupyter_start><jupyter_text>RTL Wiki. Building Topic ModelAn example of a two-staged TopicNet's experiment (with some models' properties exploration).* Related notebook (with experiment for another dataset): [PScience-Building-Topic-Model.ipynb](./PScience-Building-Topic-Model.ipynb)  Contents* [Data](data)* [Inital ARTM Model](artm-model)* [Root TopicModel and Experiment](topic-model)* [Looking at trained models](trained-models)* [Exploring a model using viewers](some-model)* [Improving document-topic distribution](improving-distribution)* [Exploring a model after experiment improvement](some-model2)<jupyter_code>import numpy as np

from IPython.display import display, display_html
import matplotlib.pyplot as plt
%matplotlib inline

from matplotlib import cm
import artm

from topicnet.cooking_machine import Dataset
from topicnet.cooking_machine.cubes import (
    CubeCreator,
    GreedyStrategy,
    PerplexityStrategy,
    RegularizersModifierCube,
)
from topicnet.cooking_machine.experiment import Experiment
from topicnet.cooking_machine.model_constructor import init_simple_default_model
from topicnet.cooking_machine.models.topic_model import TopicModel
from topicnet.cooking_machine.pretty_output import make_notebook_pretty
from topicnet.viewers.top_documents_viewer import TopDocumentsViewer
from topicnet.viewers.top_tokens_viewer import TopTokensViewer
make_notebook_pretty()<jupyter_output><empty_output><jupyter_text>DataBack to Contents Loading, filtering<jupyter_code>demo_data = Dataset('wiki_data.csv', internals_folder_path="./wiki_batches")
demo_data._cached_dict = demo_data.get_dictionary().filter(
    min_df=5.0, min_tf=5.0, max_df_rate=0.9
)
demo_data.get_dataset().head()<jupyter_output><empty_output><jupyter_text>Inital ARTM ModelBack to Contents<jupyter_code>model_artm = init_simple_default_model(
    dataset=demo_data,
    modalities_to_use={'@lemmatized': 1.0, '@bigram': 1.0},
    main_modality='@lemmatized',
    specific_topics=15,
    background_topics=1,
)

model_artm.scores<jupyter_output><empty_output><jupyter_text>Root TopicModel and ExperimentBack to Contents Creating topic model around ARTM model:<jupyter_code>tm = TopicModel(model_artm)
specific_topics = [t for t in tm.topic_names if "background" not in t]
model_artm.regularizers
model_artm.scores
experiment = Experiment(
    experiment_id="wiki_experiment",
    save_path="rtl_wiki/experiments",
    topic_model=tm
)
my_first_cube = RegularizersModifierCube(
    num_iter=10,
    regularizer_parameters=[
        {
            'regularizer': artm.DecorrelatorPhiRegularizer(
                name='decorrelation_phi', 
                class_ids="@lemmatized", 
                topic_names=specific_topics
            ),
            'tau_grid': [0, 0.005, 0.01, 0.015, 0.02, 0.025]
        },
        {
            'regularizer': artm.SmoothSparsePhiRegularizer(
                name="smsp_phi_specific",
                class_ids="@lemmatized", 
                topic_names=specific_topics
            ),
            'tau_grid': [-0.05, 0, 0.05]
        },
        {
            'name': "smooth_phi_bcg",
            'tau_grid': [0.1]
        },
    ],
    verbose=True
)

my_first_cube(tm, demo_data)
experiment.show()<jupyter_output><empty_output><jupyter_text>Looking at trained modelsBack to Contents<jupyter_code>tms = experiment.models
colors = np.linspace(0, 0.65, len(tms))

plt.figure(figsize=(8,8))

for i, tm in enumerate(list(tms.values())[1:]):
    score = tm.scores['PerplexityScore@all']
    plt.plot(score[1:], color=cm.Blues(colors[i]))

plt.show()
tms = experiment.models
colors = np.linspace(0, 0.65, len(tms))

plt.figure(figsize=(8,8))

for i, tm in enumerate(list(tms.values())[1:]):
    score = tm.scores['TopicKernel<EMAIL>.average_purity']
    plt.plot(score, color=cm.Blues(colors[i]))

    score = tm.scores['TopicKernel@lem<EMAIL>ized.average_contrast']
    plt.plot(score, color=cm.Reds(colors[i]))

plt.show()
query = (
    "<EMAIL>_contrast > 0.7 * MAXIMUM(Topic<EMAIL>.average_contrast) "
    "and <EMAIL>_purity > 0.7 * MAXIMUM(TopicKernel@<EMAIL>ized.average_purity) "
    "and PerplexityScore@all < 1.1 * MINIMUM(PerplexityScore@all) "
)
models = experiment.select(query)

models = experiment.select(query + " COLLECT all")

print(len(models))
def describe_model(model):
    for reg_name, reg in model.regularizers._data.items():
        print(reg_name, reg.tau)

    print(model.scores["PerplexityScore@all"][-1])
    print(model.scores["<EMAIL>"][-1])
    print(model.scores["<EMAIL>urity"][-1])
    print("------")
for model in models:
    describe_model(model)<jupyter_output>smooth_phi_bcg 0.1
smooth_theta_bcg 0.0
decorrelation_phi 0
smsp_phi_specific 0.0
11431396.0
0.49426960945129395
0.19459345936775208
------
smooth_phi_bcg 0.1
smooth_theta_bcg 0.0
decorrelation_phi 0.005
smsp_phi_specific 0.0
11433357.0
0.49436870217323303
0.195402130484581
------
smooth_phi_bcg 0.1
smooth_theta_bcg 0.0
decorrelation_phi 0.01
smsp_phi_specific 0.0
11436253.0
0.49431541562080383
0.1962587833404541
------
smooth_phi_bcg 0.1
smooth_theta_bcg 0.0
decorrelation_phi 0.015
smsp_phi_specific 0.0
11440095.0
0.4943116009235382
0.19706884026527405
------
smooth_phi_bcg 0.1
smooth_theta_bcg 0.0
decorrelation_phi 0.02
smsp_phi_specific 0.0
11444871.0
0.4941447973251343
0.19780972599983215
------
smooth_phi_bcg 0.1
smooth_theta_bcg 0.0
decorrelation_phi 0.025
smsp_phi_specific 0.0
11450295.0
0.49418962001800537
0.19877628982067108
------<jupyter_text>The models are really close. However, last 2 look better. Let's take a closer look at one of them.<jupyter_code>query = (
    "Topic<EMAIL>_contrast > 0.7 * MAXIMUM(Topic<EMAIL>contrast) "
    "and <EMAIL>purity > 0.7 * MAXIMUM(Topic<EMAIL>.average_purity) "
    "and PerplexityScore@all < 1.1 * MINIMUM(PerplexityScore@all) "
    "and <EMAIL> -> max"    
)

models = experiment.select(query + " COLLECT 2")

print(len(models))
last_model = models[-1]<jupyter_output><empty_output><jupyter_text>This is optional, but encouraged: let's log our selection criteria, so Experiment "knows" how exactly models were chosen.<jupyter_code>experiment.set_criteria(cube_index=1, criteria=query + " COLLECT 2")
experiment.show()<jupyter_output><empty_output><jupyter_text>Looks better this way, doesn't it?  Exploring a model using viewersBack to Contents<jupyter_code>last_model_top_tok = TopTokensViewer(last_model, num_top_tokens=10, method='phi')
last_model_html = last_model_top_tok.to_html()
last_model_top_doc = TopDocumentsViewer(last_model, dataset=demo_data).view()
n=7

for topic_name, topic_docs in list(zip(last_model.topic_names, last_model_top_doc))[:n]:
    last_model_html = last_model_top_tok.to_html(topic_names=[topic_name])
    display_html(last_model_html, raw=True)
    display(topic_docs)<jupyter_output><empty_output><jupyter_text>The topics aren't ideal, but adequate.We see topics related to kings (and Muslim rulers), religious figures (and sportsmen: `'jordan'` refers both to <NAME> and <NAME>), emperors, writers, composers, mathematicians/philosophers/scientists.<jupyter_code>last_model_html = last_model_top_tok.to_html(topic_names=['background_15'])
display_html(last_model_html, raw=True)
    
topic_docs = last_model_top_doc[-1]
topic_docs = [str(topic) for topic in topic_docs]

for doc_id in topic_docs:
    print(doc_id)<jupyter_output><empty_output><jupyter_text>Improving document-topic distributionBack to Contents<jupyter_code>theta_cube = RegularizersModifierCube(
    num_iter=10,
    regularizer_parameters=[
        {
            'regularizer': artm.SmoothSparseThetaRegularizer(
                name="smsp_theta_specific",
                topic_names=specific_topics
            ),
            'tau_grid': [-0.05, -0.01]
        },
        {
            'name': "smooth_theta_bcg",
            'tau_grid': [0.01, 0.1]
        },
    ],
    verbose=True
)

theta_cube(models, demo_data)
experiment.show()
query = (
    "<EMAIL> > 0.95 * MAXIMUM(<EMAIL>) "
    "and Topic<EMAIL>.average_purity > 0.95 * MAXIMUM(TopicKernel<EMAIL>.average_purity) "
    "and PerplexityScore@all < 1.1 * MINIMUM(PerplexityScore@all) "
    "and SparsityThetaScore > MEDIAN(SparsityThetaScore)"
)
models = experiment.select(query)

print(len(models))
for model in models:
    describe_model(model)
best_model = models[0]<jupyter_output><empty_output><jupyter_text>Exploring a model after experiment improvementBack to Contents<jupyter_code>first_model_top_tok = TopTokensViewer(best_model, num_top_tokens=10, method='phi')
first_model_html =  first_model_top_tok.to_html()
first_model_top_doc = TopDocumentsViewer(best_model, dataset=demo_data).view()
n=7

for topic_name, topic_docs in list(zip(best_model.topic_names, first_model_top_doc))[:n]:
    best_model_html = first_model_top_tok.to_html(topic_names=[topic_name])
    display_html(best_model_html, raw=True)
    display(topic_docs)<jupyter_output><empty_output><jupyter_text>The topics are slightly better: `m<NAME>` is gone from top documents for religion.<jupyter_code>experiment.set_criteria(cube_index=2, criteria=query)
experiment.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11444201312910285, 'fraction_numerical': 0.04715536105032823, 'mean_word_length': 5.005913272010512, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 76, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '246200', 'license': 'MIT', 'n_tokens_mistral': 3547, 'n_tokens_neox': 3228, 'n_words': 566, 'path': 'topicnet/demos/RTL-Wiki-Building-Topic-Model.ipynb', 'repo_name': 'machine-intelligence-laboratory/topicnet', 'size': '9452'}