Package: tomotopy
What is tomotopy?tomotopyis a Python extension oftomoto(Topic Modeling Tool) which is a Gibbs-sampling based topic model library written in C++.
It utilizes a vectorization of modern CPUs for maximizing speed.
The current version oftomotosupports several major topic models includingLatent Dirichlet Allocation (tomotopy.LDAModel)Labeled LDA (tomotopy.LLDAModel)Partially Labeled LDA (tomotopy.PLDAModel)Supervised LDA (tomotopy.SLDAModel)Dirichlet Multinomial Regression (tomotopy.DMRModel)Generalized Dirichlet Multinomial Regression (tomotopy.GDMRModel)Hierarchical Dirichlet Process (tomotopy.HDPModel)Hierarchical LDA (tomotopy.HLDAModel)Multi Grain LDA (tomotopy.MGLDAModel)Pachinko Allocation (tomotopy.PAModel)Hierarchical PA (tomotopy.HPAModel)Correlated Topic Model (tomotopy.CTModel)Dynamic Topic Model (tomotopy.DTModel)Pseudo-document based Topic Model (tomotopy.PTModel).Getting StartedYou can install tomotopy easily using pip. (https://pypi.org/project/tomotopy/)$ pip install --upgrade pip
$ pip install tomotopyThe supported OS and Python versions are:Linux (x86-64) with Python >= 3.6macOS >= 10.13 with Python >= 3.6Windows 7 or later (x86, x86-64) with Python >= 3.6Other OS with Python >= 3.6: Compilation from source code required (with c++14 compatible compiler)After installing, you can start tomotopy by just importing.import tomotopy as tp
print(tp.isa) # prints 'avx2', 'avx', 'sse2' or 'none'Currently, tomotopy can exploits AVX2, AVX or SSE2 SIMD instruction set for maximizing performance.
When the package is imported, it will check available instruction sets and select the best option.
Iftp.isatellsnone, iterations of training may take a long time.
But, since most of modern Intel or AMD CPUs provide SIMD instruction set, the SIMD acceleration could show a big improvement.Here is a sample code for simple LDA training of texts from ‘sample.txt’ file.import tomotopy as tp
mdl = tp.LDAModel(k=20)
for line in open('sample.txt'):
    mdl.add_doc(line.strip().split())

for i in range(0, 100, 10):
    mdl.train(10)
    print('Iteration: {}\tLog-likelihood: {}'.format(i, mdl.ll_per_word))

for k in range(mdl.k):
    print('Top 10 words of topic #{}'.format(k))
    print(mdl.get_topic_words(k, top_n=10))

mdl.summary()Performance of tomotopytomotopyuses Collapsed Gibbs-Sampling(CGS) to infer the distribution of topics and the distribution of words.
Generally CGS converges more slowly than Variational Bayes(VB) that [gensim’s LdaModel] uses, but its iteration can be computed much faster.
In addition,tomotopycan take advantage of multicore CPUs with a SIMD instruction set, which can result in faster iterations.[gensim’s LdaModel]:https://radimrehurek.com/gensim/models/ldamodel.htmlFollowing chart shows the comparison of LDA model’s running time betweentomotopyandgensim.
The input data consists of 1000 random documents from English Wikipedia with 1,506,966 words (about 10.1 MB).tomotopytrains 200 iterations andgensimtrains 10 iterations.↑ Performance in Intel i5-6600, x86-64 (4 cores)↑ Performance in Intel Xeon E5-2620 v4, x86-64 (8 cores, 16 threads)↑ Performance in AMD Ryzen7 3700X, x86-64 (8 cores, 16 threads)Althoughtomotopyiterated 20 times more, the overall running time was 5~10 times faster thangensim. And it yields a stable result.It is difficult to compare CGS and VB directly because they are totaly different techniques.
But from a practical point of view, we can compare the speed and the result between them.
The following chart shows the log-likelihood per word of two models’ result.The SIMD instruction set has a great effect on performance. Following is a comparison between SIMD instruction sets.Fortunately, most of recent x86-64 CPUs provide AVX2 instruction set, so we can enjoy the performance of AVX2.Vocabulary controlling using CF and DFCF(collection frequency) and DF(document frequency) are concepts used in information retreival,
and each represents the total number of times the word appears in the corpus
and the number of documents in which the word appears within the corpus, respectively.tomotopyprovides these two measures under the parameters ofmin_cfandmin_dfto trim low frequency words when building the corpus.For example, let’s say we have 5 documents #0 ~ #4 which are composed of the following words:#0 : a, b, c, d, e, c
#1 : a, b, e, f
#2 : c, d, c
#3 : a, e, f, g
#4 : a, b, gBoth CF ofaand CF ofcare 4 because it appears 4 times in the entire corpus.
But DF ofais 4 and DF ofcis 2 becauseaappears in #0, #1, #3 and #4 andconly appears in #0 and #2.
So if we trim low frequency words usingmin_cf=3, the result becomes follows:(d, f and g are removed.)
#0 : a, b, c, e, c
#1 : a, b, e
#2 : c, c
#3 : a, e
#4 : a, bHowever whenmin_df=3the result is like :(c, d, f and g are removed.)
#0 : a, b, e
#1 : a, b, e
#2 : (empty doc)
#3 : a, e
#4 : a, bAs we can see,min_dfis a stronger criterion thanmin_cf.
In performing topic modeling, words that appear repeatedly in only one document do not contribute to estimating the topic-word distribution.
So, removing words with lowdfis a good way to reduce model size while preserving the results of the final model.
In short, please prefer usingmin_dftomin_cf.Model Save and Loadtomotopyprovidessaveandloadmethod for each topic model class,
so you can save the model into the file whenever you want, and re-load it from the file.import tomotopy as tp

mdl = tp.HDPModel()
for line in open('sample.txt'):
    mdl.add_doc(line.strip().split())

for i in range(0, 100, 10):
    mdl.train(10)
    print('Iteration: {}\tLog-likelihood: {}'.format(i, mdl.ll_per_word))

# save into file
mdl.save('sample_hdp_model.bin')

# load from file
mdl = tp.HDPModel.load('sample_hdp_model.bin')
for k in range(mdl.k):
    if not mdl.is_live_topic(k): continue
    print('Top 10 words of topic #{}'.format(k))
    print(mdl.get_topic_words(k, top_n=10))

# the saved model is HDP model,
# so when you load it by LDA model, it will raise an exception
mdl = tp.LDAModel.load('sample_hdp_model.bin')When you load the model from a file, a model type in the file should match the class of methods.See more attomotopy.LDAModel.saveandtomotopy.LDAModel.loadmethods.Documents in the Model and out of the ModelWe can use Topic Model for two major purposes.
The basic one is to discover topics from a set of documents as a result of trained model,
and the more advanced one is to infer topic distributions for unseen documents by using trained model.We named the document in the former purpose (used for model training) asdocument in the model,
and the document in the later purpose (unseen document during training) asdocument out of the model.Intomotopy, these two different kinds of document are generated differently.
Adocument in the modelcan be created bytomotopy.LDAModel.add_docmethod.add_doccan be called beforetomotopy.LDAModel.trainstarts.
In other words, aftertraincalled,add_doccannot add a document into the model because the set of document used for training has become fixed.To acquire the instance of the created document, you should usetomotopy.LDAModel.docslike:mdl = tp.LDAModel(k=20)
idx = mdl.add_doc(words)
if idx < 0: raise RuntimeError("Failed to add doc")
doc_inst = mdl.docs[idx]
# doc_inst is an instance of the added documentAdocument out of the modelis generated bytomotopy.LDAModel.make_docmethod.make_doccan be called only aftertrainstarts.
If you usemake_docbefore the set of document used for training has become fixed, you may get wrong results.
Sincemake_docreturns the instance directly, you can use its return value for other manipulations.mdl = tp.LDAModel(k=20)
# add_doc ...
mdl.train(100)
doc_inst = mdl.make_doc(unseen_doc) # doc_inst is an instance of the unseen documentInference for Unseen DocumentsIf a new document is created bytomotopy.LDAModel.make_doc, its topic distribution can be inferred by the model.
Inference for unseen document should be performed usingtomotopy.LDAModel.infermethod.mdl = tp.LDAModel(k=20)
# add_doc ...
mdl.train(100)
doc_inst = mdl.make_doc(unseen_doc)
topic_dist, ll = mdl.infer(doc_inst)
print("Topic Distribution for Unseen Docs: ", topic_dist)
print("Log-likelihood of inference: ", ll)Theinfermethod can infer only one instance oftomotopy.Documentor alistof instances oftomotopy.Document.
See more attomotopy.LDAModel.infer.Corpus and transformEvery topic model intomotopyhas its own internal document type.
A document can be created and added into suitable for each model through each model’sadd_docmethod.
However, trying to add the same list of documents to different models becomes quite inconvenient,
becauseadd_docshould be called for the same list of documents to each different model.
Thus,tomotopyprovidestomotopy.utils.Corpusclass that holds a list of documents.tomotopy.utils.Corpuscan be inserted into any model by passing as argumentcorpusto__init__oradd_corpusmethod of each model.
So, insertingtomotopy.utils.Corpusjust has the same effect to inserting documents the corpus holds.Some topic models requires different data for its documents.
For example,tomotopy.DMRModelrequires argumentmetadatainstrtype,
buttomotopy.PLDAModelrequires argumentlabelsinList[str]type.
Sincetomotopy.utils.Corpusholds an independent set of documents rather than being tied to a specific topic model,
data types required by a topic model may be inconsistent when a corpus is added into that topic model.
In this case, miscellaneous data can be transformed to be fitted target topic model using argumenttransform.
See more details in the following code:from tomotopy import DMRModel
from tomotopy.utils import Corpus

corpus = Corpus()
corpus.add_doc("a b c d e".split(), a_data=1)
corpus.add_doc("e f g h i".split(), a_data=2)
corpus.add_doc("i j k l m".split(), a_data=3)

model = DMRModel(k=10)
model.add_corpus(corpus)
# You lose `a_data` field in `corpus`,
# and `metadata` that `DMRModel` requires is filled with the default value, empty str.

assert model.docs[0].metadata == ''
assert model.docs[1].metadata == ''
assert model.docs[2].metadata == ''

def transform_a_data_to_metadata(misc: dict):
    return {'metadata': str(misc['a_data'])}
# this function transforms `a_data` to `metadata`

model = DMRModel(k=10)
model.add_corpus(corpus, transform=transform_a_data_to_metadata)
# Now docs in `model` has non-default `metadata`, that generated from `a_data` field.

assert model.docs[0].metadata == '1'
assert model.docs[1].metadata == '2'
assert model.docs[2].metadata == '3'Parallel Sampling AlgorithmsSince version 0.5.0,tomotopyallows you to choose a parallelism algorithm.
The algorithm provided in versions prior to 0.4.2 isCOPY_MERGE, which is provided for all topic models.
The new algorithmPARTITION, available since 0.5.0, makes training generally faster and more memory-efficient, but it is available at not all topic models.The following chart shows the speed difference between the two algorithms based on the number of topics and the number of workers.Performance by VersionPerformance changes by version are shown in the following graph.
The time it takes to run the LDA model train with 1000 iteration was measured.
(Docs: 11314, Vocab: 60382, Words: 2364724, Intel Xeon Gold 5120 @2.2GHz)Pining Topics using Word PriorsSince version 0.6.0, a new methodtomotopy.LDAModel.set_word_priorhas been added. It allows you to control word prior for each topic.
For example, we can set the weight of the word ‘church’ to 1.0 in topic 0, and the weight to 0.1 in the rest of the topics by following codes.
This means that the probability that the word ‘church’ is assigned to topic 0 is 10 times higher than the probability of being assigned to another topic.
Therefore, most of ‘church’ is assigned to topic 0, so topic 0 contains many words related to ‘church’.
This allows to manipulate some topics to be placed at a specific topic number.import tomotopy as tp
mdl = tp.LDAModel(k=20)

# add documents into `mdl`

# setting word prior
mdl.set_word_prior('church', [1.0 if k == 0 else 0.1 for k in range(20)])Seeword_prior_exampleinexample.pyfor more details.ExamplesYou can find an example python code of tomotopy athttps://github.com/bab2min/tomotopy/blob/main/examples/.You can also get the data file used in the example code athttps://drive.google.com/file/d/18OpNijd4iwPyYZ2O7pQoPyeTAKEXa71J/view.Licensetomotopyis licensed under the terms of MIT License,
meaning you can use it for any reasonable purpose and remain in complete ownership of all the documentation you produce.History0.12.7 (2023-12-19)New featuresAdded Topic Model Viewertomotopy.viewer.open_viewer()Optimized the performance oftomotopy.utils.Corpus.process()Bug fixesDocument.spannow returns the ranges in character unit, not in byte unit.0.12.6 (2023-12-11)New featuresAdded some convenience features totomotopy.LDAModel.trainandtomotopy.LDAModel.set_word_prior.LDAModel.trainnow has new argumentscallback,callback_intervalandshow_progresto monitor the training progress.LDAModel.set_word_priornow can acceptDict[int, float]type as its argumentprior.0.12.5 (2023-08-03)New featuresAdded support for Linux ARM64 architecture.0.12.4 (2023-01-22)New featuresAdded support for macOS ARM64 architecture.Bug fixesFixed an issue wheretomotopy.Document.get_sub_topic_dist()raises a bad argument exception.Fixed an issue where exception raising sometimes causes crashes.0.12.3 (2022-07-19)New featuresNow, inserting an empty document usingtomotopy.LDAModel.add_doc()just ignores it instead of raising an exception. If the newly added argumentignore_empty_wordsis set to False, an exception is raised as before.tomotopy.HDPModel.purge_dead_topics()method is added to remove non-live topics from the model.Bug fixesFixed an issue that prevents setting user defined values for nuSq intomotopy.SLDAModel(by @jucendrero).Fixed an issue wheretomotopy.utils.Coherencedid not work fortomotopy.DTModel.Fixed an issue that often crashed when callingmake_dic()before callingtrain().Resolved the problem that the results oftomotopy.DMRModelandtomotopy.GDMRModelare different even when the seed is fixed.The parameter optimization process oftomotopy.DMRModelandtomotopy.GDMRModelhas been improved.Fixed an issue that sometimes crashed when callingtomotopy.PTModel.copy().0.12.2 (2021-09-06)An issue where callingconvert_to_ldaoftomotopy.HDPModelwithmin_cf > 0,min_df > 0orrm_top > 0causes a crash has been fixed.A new argumentfrom_pseudo_docis added totomotopy.Document.get_topicsandtomotopy.Document.get_topic_dist.
This argument is only valid for documents ofPTModel, it enables to control a source for computing topic distribution.A default value for argumentpoftomotopy.PTModelhas been changed. The new default value isk * 10.Using documents generated bymake_docwithout callinginferdoesn’t cause a crash anymore, but just print warning messages.An issue where the internal C++ code isn’t compiled at clang c++17 environment has been fixed.0.12.1 (2021-06-20)An issue wheretomotopy.LDAModel.set_word_prior()causes a crash has been fixed.Nowtomotopy.LDAModel.perplexityandtomotopy.LDAModel.ll_per_wordreturn the accurate value whenTermWeightis notONE.tomotopy.LDAModel.used_vocab_weighted_freqwas added, which returns term-weighted frequencies of words.Nowtomotopy.LDAModel.summary()shows not only the entropy of words, but also the entropy of term-weighted words.0.12.0 (2021-04-26)Nowtomotopy.DMRModelandtomotopy.GDMRModelsupport multiple values of metadata (seehttps://github.com/bab2min/tomotopy/blob/main/examples/dmr_multi_label.py)The performance oftomotopy.GDMRModelwas improved.Acopy()method has been added for all topic models to do a deep copy.An issue was fixed where words that are excluded from training (bymin_cf,min_df) have incorrect topic id. Now all excluded words have-1as topic id.Now all exceptions and warnings that generated bytomotopyfollow standard Python types.Compiler requirements have been raised to C++14.0.11.1 (2021-03-28)A critical bug of asymmetric alphas was fixed. Due to this bug, version 0.11.0 has been removed from releases.0.11.0 (2021-03-26) (removed)A new topic modeltomotopy.PTModelfor short texts was added into the package.An issue was fixed wheretomotopy.HDPModel.infercauses a segmentation fault sometimes.A mismatch of numpy API version was fixed.Now asymmetric document-topic priors are supported.Serializing topic models tobytesin memory is supported.An argumentnormalizewas added toget_topic_dist(),get_topic_word_dist()andget_sub_topic_dist()for controlling normalization of results.Nowtomotopy.DMRModel.lambdasandtomotopy.DMRModel.alphagive correct values.Categorical metadata supports fortomotopy.GDMRModelwere added (seehttps://github.com/bab2min/tomotopy/blob/main/examples/gdmr_both_categorical_and_numerical.py).Python3.5 support was dropped.0.10.2 (2021-02-16)An issue was fixed wheretomotopy.CTModel.trainfails with large K.An issue was fixed wheretomotopy.utils.Corpusloses theiruidvalues.0.10.1 (2021-02-14)An issue was fixed wheretomotopy.utils.Corpus.extract_ngramscraches with empty input.An issue was fixed wheretomotopy.LDAModel.inferraises exception with valid input.An issue was fixed wheretomotopy.HLDAModel.infergenerates wrongtomotopy.Document.path.Since a new parameterfreeze_topicsfortomotopy.HLDAModel.trainwas added, you can control whether to create a new topic or not when training.0.10.0 (2020-12-19)The interface oftomotopy.utils.Corpusand oftomotopy.LDAModel.docswere unified. Now you can access the document in corpus with the same manner.__getitem__ oftomotopy.utils.Corpuswas improved. Not only indexing by int, but also by Iterable[int], slicing are supported. Also indexing by uid is supported.New methodstomotopy.utils.Corpus.extract_ngramsandtomotopy.utils.Corpus.concat_ngramswere added. They extracts n-gram collocations using PMI and concatenates them into a single words.A new methodtomotopy.LDAModel.add_corpuswas added, andtomotopy.LDAModel.infercan receive corpus as input.A new moduletomotopy.coherencewas added. It provides the way to calculate coherence of the model.A paramterwindow_sizewas added totomotopy.label.FoRelevance.An issue was fixed where NaN often occurs when trainingtomotopy.HDPModel.Now Python3.9 is supported.A dependency to py-cpuinfo was removed and the initializing of the module was improved.0.9.1 (2020-08-08)Memory leaks of version 0.9.0 was fixed.tomotopy.CTModel.summary()was fixed.0.9.0 (2020-08-04)Thetomotopy.LDAModel.summary()method, which prints human-readable summary of the model, has been added.The random number generator of package has been replaced with [EigenRand]. It speeds up the random number generation and solves the result difference between platforms.Due to above, even ifseedis the same, the model training result may be different from the version before 0.9.0.Fixed a training error intomotopy.HDPModel.tomotopy.DMRModel.alphanow shows Dirichlet prior of per-document topic distribution by metadata.tomotopy.DTModel.get_count_by_topics()has been modified to return a 2-dimensionalndarray.tomotopy.DTModel.alphahas been modified to return the same value astomotopy.DTModel.get_alpha().Fixed an issue where themetadatavalue could not be obtained for the document oftomotopy.GDMRModel.tomotopy.HLDAModel.alphanow shows Dirichlet prior of per-document depth distribution.tomotopy.LDAModel.global_stephas been added.tomotopy.MGLDAModel.get_count_by_topics()now returns the word count for both global and local topics.tomotopy.PAModel.alpha,tomotopy.PAModel.subalpha, andtomotopy.PAModel.get_count_by_super_topic()have been added.[EigenRand]:https://github.com/bab2min/EigenRand0.8.2 (2020-07-14)New propertiestomotopy.DTModel.num_timepointsandtomotopy.DTModel.num_docs_by_timepointhave been added.A bug which causes different results with the different platform even ifseedswere the same was partially fixed.
As a result of this fix, nowtomotopyin 32 bit yields different training results from earlier version.0.8.1 (2020-06-08)A bug wheretomotopy.LDAModel.used_vocabsreturned an incorrect value was fixed.Nowtomotopy.CTModel.prior_covreturns a covariance matrix with shape[k, k].Nowtomotopy.CTModel.get_correlationswith empty arguments returns a correlation matrix with shape[k, k].0.8.0 (2020-06-06)Since NumPy was introduced in tomotopy, many methods and properties of tomotopy return not justlist, butnumpy.ndarraynow.Tomotopy has a new dependencyNumPy >= 1.10.0.A wrong estimation oftomotopy.HDPModel.inferwas fixed.A new method about converting HDPModel to LDAModel was added.New properties includingtomotopy.LDAModel.used_vocabs,tomotopy.LDAModel.used_vocab_freqandtomotopy.LDAModel.used_vocab_dfwere added into topic models.A new g-DMR topic model(tomotopy.GDMRModel) was added.An error at initializingtomotopy.label.FoRelevancein macOS was fixed.An error that occured when usingtomotopy.utils.Corpuscreated withoutrawparameters was fixed.0.7.1 (2020-05-08)tomotopy.Document.pathwas added fortomotopy.HLDAModel.A memory corruption bug intomotopy.label.PMIExtractorwas fixed.A compile error in gcc 7 was fixed.0.7.0 (2020-04-18)tomotopy.DTModelwas added into the package.A bug intomotopy.utils.Corpus.savewas fixed.A new methodtomotopy.Document.get_count_vectorwas added into Document class.Now linux distributions use manylinux2010 and an additional optimization is applied.0.6.2 (2020-03-28)A critical bug related tosaveandloadwas fixed. Version 0.6.0 and 0.6.1 have been removed from releases.0.6.1 (2020-03-22) (removed)A bug related to module loading was fixed.0.6.0 (2020-03-22) (removed)tomotopy.utils.Corpusclass that manages multiple documents easily was added.tomotopy.LDAModel.set_word_priormethod that controls word-topic priors of topic models was added.A new argumentmin_dfthat filters words based on document frequency was added into every topic model’s __init__.tomotopy.label, the submodule about topic labeling was added. Currently, onlytomotopy.label.FoRelevanceis provided.0.5.2 (2020-03-01)A segmentation fault problem was fixed intomotopy.LLDAModel.add_doc.A bug was fixed thatinferoftomotopy.HDPModelsometimes crashes the program.A crash issue was fixed oftomotopy.LDAModel.inferwith ps=tomotopy.ParallelScheme.PARTITION, together=True.0.5.1 (2020-01-11)A bug was fixed thattomotopy.SLDAModel.make_docdoesn’t support missing values fory.Nowtomotopy.SLDAModelfully supports missing values for response variablesy. Documents with missing values (NaN) are included in modeling topic, but excluded from regression of response variables.0.5.0 (2019-12-30)Nowtomotopy.PAModel.inferreturns both topic distribution nd sub-topic distribution.New methods get_sub_topics and get_sub_topic_dist were added intotomotopy.Document. (for PAModel)New parameterparallelwas added fortomotopy.LDAModel.trainandtomotopy.LDAModel.infermethod. You can select parallelism algorithm by changing this parameter.tomotopy.ParallelScheme.PARTITION, a new algorithm, was added. It works efficiently when the number of workers is large, the number of topics or the size of vocabulary is big.A bug whererm_topdidn’t work atmin_cf< 2 was fixed.0.4.2 (2019-11-30)Wrong topic assignments oftomotopy.LLDAModelandtomotopy.PLDAModelwere fixed.Readable __repr__ oftomotopy.Documentandtomotopy.Dictionarywas implemented.0.4.1 (2019-11-27)A bug at init function oftomotopy.PLDAModelwas fixed.0.4.0 (2019-11-18)New models includingtomotopy.PLDAModelandtomotopy.HLDAModelwere added into the package.0.3.1 (2019-11-05)An issue whereget_topic_dist()returns incorrect value whenmin_cforrm_topis set was fixed.The return value ofget_topic_dist()oftomotopy.MGLDAModeldocument was fixed to include local topics.The estimation speed withtw=ONEwas improved.0.3.0 (2019-10-06)A new model,tomotopy.LLDAModelwas added into the package.A crashing issue ofHDPModelwas fixed.Since hyperparameter estimation forHDPModelwas implemented, the result ofHDPModelmay differ from previous versions.If you want to turn off hyperparameter estimation of HDPModel, setoptim_intervalto zero.0.2.0 (2019-08-18)New models includingtomotopy.CTModelandtomotopy.SLDAModelwere added into the package.A new parameter optionrm_topwas added for all topic models.The problems insaveandloadmethod forPAModelandHPAModelwere fixed.An occassional crash in loadingHDPModelwas fixed.The problem thatll_per_wordwas calculated incorrectly whenmin_cf> 0 was fixed.0.1.6 (2019-08-09)Compiling errors at clang with macOS environment were fixed.0.1.4 (2019-08-05)The issue whenadd_docreceives an empty list as input was fixed.The issue thattomotopy.PAModel.get_topic_wordsdoesn’t extract the word distribution of subtopic was fixed.0.1.3 (2019-05-19)The parametermin_cfand its stopword-removing function were added for all topic models.0.1.0 (2019-05-12)First version oftomotopy