def classifier(dir, _iter, type=None):
    """Filenames = category names(replace spaces with underscores"""
    global cat_lookup
    global cat_index
    doc = EntitiesTokenizer(_iter)
    doc_bow = CorpusBOW(doc)
    if not cat_index:
        cnt = 0
        raw_texts = []
        for file in os.listdir(dir):
            if not ".DS_Store" in file:
                cat_lookup[cnt] = file.replace("_", " ")
                cnt += 1
                text = open(dir + file, "r")
                raw_texts.append(''.join([
                    line.strip().decode("utf8").encode("ascii", "ignore")
                    for line in text.readlines()
                ]))
        corpus = EntitiesTokenizer(iter(raw_texts))
        corpus_bow = CorpusBOW(corpus)
        corpus_file = corpus_bow.serialize(
            os.path.join(lda_output, 'cat_corpus.mm'))
        corpusMM = gensim.corpora.MmCorpus(
            os.path.join(lda_output, 'cat_corpus.mm'))
        cat_index = gensim.similarities.docsim.Similarity(
            lda_output, corpusMM,
            num_features=corpusMM.num_terms)  # build the index
    return cat_lookup[np.argmax(cat_index[doc_bow][0])]
def run_topic_model(output_dir,
                    n_topics,
                    content_fields,
                    field_filters=None,
                    field_filter_vals=None,
                    seed=42):

    np.random.seed(seed)
    # documents = iter_elastic_query(ES_INSTANCE + ES_INDEX, "abstract", "", query=None)
    documents = read_bulk_index(elastic + "original/", content_fields,
                                field_filters, field_filter_vals)

    corpus = EntitiesTokenizer(
        documents)  #receives a generator of strings (content for each doc)

    # if os.path.isdir(output_dir):
    #     shutil.rmtree(output_dir)

    # os.makedirs(output_dir)

    corpus_bow = CorpusBOW(corpus)

    corpus_dict = corpus_bow.save_dict(os.path.join(output_dir, 'corpus.dict'))
    # Serialize and store the corpus
    corpus_file = corpus_bow.serialize(os.path.join(output_dir, 'corpus.mm'))
    # Create LDA model from corpus and dictionary

    topik_lda = LDA(os.path.join(output_dir, 'corpus.mm'),
                    os.path.join(output_dir, 'corpus.dict'),
                    n_topics,
                    update_every=1,
                    passes=5)

    topik_lda.save(os.path.join(output_dir, 'model.gensim'))

    # Generate the input for the termite plot
    topik_lda.termite_data(os.path.join(output_dir, 'termite.csv'))
    # Get termite plot for this model
    termite = Termite(os.path.join(output_dir, 'termite.csv'), "Termite Plot")
    termite.plot(os.path.join(output_dir, 'termite.html'))

    df_results = generate_csv_output_file(documents, corpus, corpus_bow,
                                          topik_lda.model)

    to_r_ldavis(corpus_bow,
                dir_name=os.path.join(output_dir, 'ldavis'),
                lda=topik_lda)
    os.environ["LDAVIS_DIR"] = os.path.join(output_dir, 'ldavis')
    try:
        subprocess.call(
            ['Rscript',
             os.path.join(BASEDIR, 'topic-space/R/runLDAvis.R')])
    except ValueError:
        logging.warning("Unable to run runLDAvis.R")
Example #3
0
    def test_corpus_bow(self):
        doc_text = iter_document_json_stream(os.path.join(module_path, 'data/test-data-1'), "text")
        my_corpus = SimpleTokenizer(doc_text)
        corpus_bow = CorpusBOW(my_corpus)
        dict_fname = 'test-data-1.dict'
        corpus_fname = 'test-data-1.mm'
        corpus_bow.save_dict(os.path.join(module_path, dict_fname))
        corpus_bow.serialize(os.path.join(module_path, corpus_fname))

        self.assertEqual(head(corpus_bow, 2), self.corpus_bow_head_2_simple_test_data_1)

        self.assertTrue(os.path.isfile(os.path.join(module_path, dict_fname)))
        self.assertTrue(os.path.isfile(os.path.join(module_path, corpus_fname)))

        self.assertTrue(head(corpus_bow.dict, 2), self.dictionary_values_simple_test_data_1)
Example #4
0
def run_topic_model(field, subfield, output_dir, n_topics, seed=42):

    np.random.seed(seed)

    documents = iter_elastic_query(ES_INSTANCE, ES_INDEX, field, subfield)

    corpus = EntitiesTokenizer(documents)

    if os.path.isdir(output_dir):
        shutil.rmtree(output_dir)

    os.makedirs(output_dir)

    # Create dictionary
    corpus_bow = CorpusBOW(corpus)
    corpus_dict = corpus_bow.save_dict(os.path.join(output_dir, 'corpus.dict'))
    # Serialize and store the corpus
    corpus_file = corpus_bow.serialize(os.path.join(output_dir, 'corpus.mm'))
    # Create LDA model from corpus and dictionary
    lda = LDA(os.path.join(output_dir, 'corpus.mm'),
              os.path.join(output_dir, 'corpus.dict'),
              n_topics,
              update_every=1,
              chuncksize=10000,
              passes=1)
    # Generate the input for the termite plot
    lda.termite_data(os.path.join(output_dir, 'termite.csv'))
    # Get termite plot for this model

    termite = Termite(os.path.join(output_dir, 'termite.csv'), "Termite Plot")
    termite.plot(os.path.join(output_dir, 'termite.html'))

    df_results = generate_csv_output_file(documents, corpus, corpus_bow,
                                          lda.model)

    to_r_ldavis(corpus_bow,
                dir_name=os.path.join(output_dir, 'ldavis'),
                lda=lda)
    os.environ["LDAVIS_DIR"] = os.path.join(output_dir, 'ldavis')
    try:
        subprocess.call(['Rscript', os.path.join(BASEDIR, 'R/runLDAvis.R')])
    except ValueError:
        logging.warning("Unable to run runLDAvis.R")
Example #5
0
 def setUp(self):
     id_documents =  iter_document_json_stream(
             os.path.join(module_path,'data/test-data-1'), "text")
     ids, doc_text = unzip(id_documents)
     my_corpus = SimpleTokenizer(doc_text)
     corpus_bow = CorpusBOW(my_corpus)
     corpus_bow.save_dict(os.path.join(module_path, 'test.dict'))
     corpus_bow.serialize(os.path.join(module_path, 'test.mm'))
Example #6
0
def run_topic_model(field, subfield, output_dir, n_topics, seed=42):

    np.random.seed(seed)

    documents = iter_elastic_query(ES_INSTANCE, ES_INDEX, field, subfield)

    corpus = EntitiesTokenizer(documents)

    if os.path.isdir(output_dir):
        shutil.rmtree(output_dir)

    os.makedirs(output_dir)

    # Create dictionary
    corpus_bow = CorpusBOW(corpus)
    corpus_dict = corpus_bow.save_dict(os.path.join(output_dir, 'corpus.dict'))
    # Serialize and store the corpus
    corpus_file = corpus_bow.serialize(os.path.join(output_dir, 'corpus.mm'))
    # Create LDA model from corpus and dictionary
    lda = LDA(os.path.join(output_dir, 'corpus.mm'), os.path.join(output_dir,'corpus.dict'), n_topics,
              update_every=1, chuncksize=10000, passes=1)
    # Generate the input for the termite plot
    lda.termite_data(os.path.join(output_dir,'termite.csv'))
    # Get termite plot for this model

    termite = Termite(os.path.join(output_dir,'termite.csv'), "Termite Plot")
    termite.plot(os.path.join(output_dir,'termite.html'))

    df_results = generate_csv_output_file(documents, corpus, corpus_bow, lda.model)

    to_r_ldavis(corpus_bow, dir_name=os.path.join(output_dir, 'ldavis'), lda=lda)
    os.environ["LDAVIS_DIR"] = os.path.join(output_dir, 'ldavis')
    try:
        subprocess.call(['Rscript', os.path.join(BASEDIR,'R/runLDAvis.R')])
    except ValueError:
        logging.warning("Unable to run runLDAvis.R")
def doc_topics(content_fields):
    """Returns dictionary of topic probabilities for each doc in the corpus. 
    Key is document number (in order), val is list of probabilities."""
    lookup = {}
    documents = read_bulk_index(elastic + "original/", content_fields)
    corpus = EntitiesTokenizer(documents)
    corpus_bow = CorpusBOW(corpus)
    cnt = 0
    if os.path.isfile(BASEDIR + "/lda_output/model.gensim"):
        lda = gensim.models.LdaModel.load(BASEDIR + "/lda_output/model.gensim")
        for doc in corpus_bow:
            lookup[cnt] = lda[doc]
            cnt += 1
    else:
        raise ValueError("No model found")
    return lookup
Example #8
0
    def test_corpus_bow(self):
        fullpath = os.path.join(module_path, 'data/test-data-1.json')
        id_documents = iter_document_json_stream(fullpath, "text")
        ids, doc_text = unzip(id_documents)
        ids, texts = unzip(doc_text)
        my_corpus = SimpleTokenizer(texts)
        corpus_bow = CorpusBOW(my_corpus)
        dict_fname = 'test-data-1.dict'
        corpus_fname = 'test-data-1.mm'
        corpus_bow.save_dict(os.path.join(module_path, dict_fname))
        corpus_bow.serialize(os.path.join(module_path, corpus_fname))

        #self.assertEqual([next(corpus_bow), next(corpus_bow)],
        #                 self.corpus_bow_head_2_simple_test_data_1)

        self.assertTrue(os.path.isfile(os.path.join(module_path, dict_fname)))
        self.assertTrue(os.path.isfile(os.path.join(module_path,
                                                    corpus_fname)))

        self.assertTrue(next(corpus_bow.dict.values()),
                        self.dictionary_values_simple_test_data_1)
Example #9
0
def run_model(data, format='json_stream', tokenizer='simple', n_topics=10, dir_path='./topic_model',
                    model='lda_batch', termite_plot=True, output_file=False, r_ldavis=False,  prefix_value=None,
                    event_value=None, field=None, query='*:*', index=None, subfield=None, seed=42):
    """Run your data through all topik functionality and save all results to a specified directory.

    Parameters
    ----------
    data: string
        Input data (e.g. file or folder or solr/elasticsearch instance).

    format: {'json_stream', 'folder_files', 'json_large', 'solr', 'elastic'}.
        The format of your data input. Currently available a json stream or a folder containing text files. 
        Default is 'json_stream'

    tokenizer: {'simple', 'collocations', 'entities', 'mixed'}
        The type of tokenizer to use. Default is 'simple'.
    
    n_topics: int
        Number of topics to find in your data
        
    dir_path: string
        Directory path to store all topic modeling results files. Default is `./topic_model`.

    model: {'lda_batch', 'lda_online'}.
        Statistical modeling algorithm to use. Default 'lda_batch'.

    termite_plot: bool
        Generate termite plot of your model if True. Default is True.

    output_file: bool
        Generate a final summary csv file of your results. For each document: text, tokens, lda_probabilities and topic.

    r_ldavis: bool
        Generate an interactive data visualization of your topics. Default is False.

    prefix_value: string
        For 'large json' format reader, the prefix value to parse.

    event_value: string
        For 'large json' format reader, the event value to parse.

    field: string
        For 'json_stream', 'solr' or 'elastic' format readers, the field to parse.

    solr_instance: string
        For 'solr' format reader, the url to the solr instance.

    query: string
        For 'solr' format reader, an optional query. Default is '*:*' to retrieve all documents.

    seed: int
        Set random number generator to seed, to be able to reproduce results. Default 42.

    """
    np.random.seed(seed)

    if format == 'folder_files':
        documents = iter_documents_folder(data)
    elif format == 'large_json' and prefix_value is not None and event_value is not None:
        documents = iter_large_json(data, prefix_value, event_value)
    elif format == 'json_stream' and field is not None:
        documents = iter_document_json_stream(data, field)
    elif format == 'solr' and field is not None:
        documents = iter_solr_query(data, field, query=query)
    elif format == 'elastic' and field is not None:
        documents = iter_elastic_query(data, index, field, subfield)
    else:
        raise Exception("Invalid input, make sure your passing the appropriate arguments for the different formats")

    if tokenizer == 'simple':
        corpus = SimpleTokenizer(documents)
    elif tokenizer == 'collocations' :
        corpus = CollocationsTokenizer(documents)
    elif tokenizer == 'entities':
        corpus = EntitiesTokenizer(documents)
    elif tokenizer == 'mixed':
        corpus = MixedTokenizer(documents)
    else:
        print("Processing value invalid, using simple")
        corpus = SimpleTokenizer(documents)

    if os.path.isdir(dir_path):
        shutil.rmtree(dir_path)

    os.makedirs(dir_path)

    # Create dictionary
    corpus_bow = CorpusBOW(corpus)
    corpus_dict = corpus_bow.save_dict(os.path.join(dir_path, 'corpus.dict'))
    # Serialize and store the corpus
    corpus_file = corpus_bow.serialize(os.path.join(dir_path, 'corpus.mm'))
    # Create LDA model from corpus and dictionary
    if model == 'lda_batch':
        # To perform lda in batch mode set update_every=0 and passes=20)
        # https://radimrehurek.com/gensim/wiki.html#latent-dirichlet-allocation
        lda = LDA(os.path.join(dir_path, 'corpus.mm'), os.path.join(dir_path,'corpus.dict'), n_topics, update_every=0,
                  passes=20)
    elif model == 'lda_online':
        # To perform lda in online mode set variables update_every, chuncksize and passes.
        lda = LDA(os.path.join(dir_path, 'corpus.mm'), os.path.join(dir_path,'corpus.dict'), n_topics, update_every=1,
                  chuncksize=10000, passes=1)
    else:
        logging.warning('model provided not valid. Using lda_batch.')
        lda = LDA(os.path.join(dir_path, 'corpus.mm'), os.path.join(dir_path,'corpus.dict'), n_topics, update_every=0,
                  passes=20)
    # Generate the input for the termite plot
    lda.termite_data(os.path.join(dir_path,'termite.csv'))
    # Get termite plot for this model
    if termite_plot:
        termite = Termite(os.path.join(dir_path,'termite.csv'), "Termite Plot")
        termite.plot(os.path.join(dir_path,'termite.html'))

    if output_file:

        if format == 'folder_files':
            documents = iter_documents_folder(data)
        elif format == 'large_json':
            documents = iter_large_json(data, prefix_value, event_value)
        else:
            documents = iter_document_json_stream(data, field)

        df_results = generate_csv_output_file(documents, corpus, corpus_bow, lda.model)

    if r_ldavis:
        to_r_ldavis(corpus_bow, dir_name=os.path.join(dir_path, 'ldavis'), lda=lda)
        os.environ["LDAVIS_DIR"] = os.path.join(dir_path, 'ldavis')
        try:
            subprocess.call(['Rscript', os.path.join(BASEDIR,'R/runLDAvis.R')])
        except ValueError:
            logging.warning("Unable to run runLDAvis.R")
        os.chdir(os.path.join(dir_path, 'ldavis', 'output'))
        sp = subprocess.Popen(['python', '-m', 'SimpleHTTPServer', '8000'])
        webbrowser.open_new_tab('127.0.0.1:8000')
        time.sleep(30)
        sp.kill()
Example #10
0
def run_model(data,
              format='json_stream',
              tokenizer='simple',
              n_topics=10,
              dir_path='./topic_model',
              model='lda_batch',
              termite_plot=True,
              output_file=False,
              r_ldavis=False,
              prefix_value=None,
              event_value=None,
              field=None,
              query='*:*',
              index=None,
              subfield=None,
              seed=42):
    """Run your data through all topik functionality and save all results to a specified directory.

    Parameters
    ----------
    data: string
        Input data (e.g. file or folder or solr/elasticsearch instance).

    format: {'json_stream', 'folder_files', 'json_large', 'solr', 'elastic'}.
        The format of your data input. Currently available a json stream or a folder containing text files. 
        Default is 'json_stream'

    tokenizer: {'simple', 'collocations', 'entities', 'mixed'}
        The type of tokenizer to use. Default is 'simple'.
    
    n_topics: int
        Number of topics to find in your data
        
    dir_path: string
        Directory path to store all topic modeling results files. Default is `./topic_model`.

    model: {'lda_batch', 'lda_online'}.
        Statistical modeling algorithm to use. Default 'lda_batch'.

    termite_plot: bool
        Generate termite plot of your model if True. Default is True.

    output_file: bool
        Generate a final summary csv file of your results. For each document: text, tokens, lda_probabilities and topic.

    r_ldavis: bool
        Generate an interactive data visualization of your topics. Default is False.

    prefix_value: string
        For 'large json' format reader, the prefix value to parse.

    event_value: string
        For 'large json' format reader, the event value to parse.

    field: string
        For 'json_stream', 'solr' or 'elastic' format readers, the field to parse.

    solr_instance: string
        For 'solr' format reader, the url to the solr instance.

    query: string
        For 'solr' format reader, an optional query. Default is '*:*' to retrieve all documents.

    seed: int
        Set random number generator to seed, to be able to reproduce results. Default 42.

    """
    np.random.seed(seed)

    if format == 'folder_files':
        id_documents = iter_documents_folder(data)
    elif format == 'large_json' and prefix_value is not None and event_value is not None:
        id_documents = iter_large_json(data, prefix_value, event_value)
    elif format == 'json_stream' and field is not None:
        id_documents = iter_document_json_stream(data, field)
    elif format == 'solr' and field is not None:
        id_documents = iter_solr_query(data, field, query=query)
    elif format == 'elastic' and field is not None:
        id_documents = iter_elastic_query(data, index, field, subfield)
    else:
        raise Exception(
            "Invalid input, make sure your passing the appropriate arguments for the different formats"
        )
    ids, documents = unzip(id_documents)

    if tokenizer == 'simple':
        corpus = SimpleTokenizer(documents)
    elif tokenizer == 'collocations':
        corpus = CollocationsTokenizer(documents)
    elif tokenizer == 'entities':
        corpus = EntitiesTokenizer(documents)
    elif tokenizer == 'mixed':
        corpus = MixedTokenizer(documents)
    else:
        print("Processing value invalid, using simple")
        corpus = SimpleTokenizer(documents)

    if os.path.isdir(dir_path):
        shutil.rmtree(dir_path)

    os.makedirs(dir_path)

    # Create dictionary
    corpus_bow = CorpusBOW(corpus)
    corpus_dict = corpus_bow.save_dict(os.path.join(dir_path, 'corpus.dict'))
    # Serialize and store the corpus
    corpus_file = corpus_bow.serialize(os.path.join(dir_path, 'corpus.mm'))
    # Create LDA model from corpus and dictionary
    if model == 'lda_batch':
        # To perform lda in batch mode set update_every=0 and passes=20)
        # https://radimrehurek.com/gensim/wiki.html#latent-dirichlet-allocation
        lda = LDA(os.path.join(dir_path, 'corpus.mm'),
                  os.path.join(dir_path, 'corpus.dict'),
                  n_topics,
                  update_every=0,
                  passes=20)
    elif model == 'lda_online':
        # To perform lda in online mode set variables update_every, chuncksize and passes.
        lda = LDA(os.path.join(dir_path, 'corpus.mm'),
                  os.path.join(dir_path, 'corpus.dict'),
                  n_topics,
                  update_every=1,
                  chunksize=10000,
                  passes=1)
    else:
        logging.warning('model provided not valid. Using lda_batch.')
        lda = LDA(os.path.join(dir_path, 'corpus.mm'),
                  os.path.join(dir_path, 'corpus.dict'),
                  n_topics,
                  update_every=0,
                  passes=20)
    # Generate the input for the termite plot
    lda.termite_data(os.path.join(dir_path, 'termite.csv'))
    # Get termite plot for this model
    if termite_plot:
        termite = Termite(os.path.join(dir_path, 'termite.csv'),
                          "Termite Plot")
        termite.plot(os.path.join(dir_path, 'termite.html'))

    if output_file:

        if format == 'folder_files':
            id_documents = iter_documents_folder(data)

        elif format == 'large_json':
            id_documents = iter_large_json(data, prefix_value, event_value)
        else:
            id_documents = iter_document_json_stream(data, field)

        ids, documents = unzip(id_documents)
        df_results = generate_csv_output_file(documents, corpus, corpus_bow,
                                              lda.model)

    if r_ldavis:
        to_r_ldavis(corpus_bow,
                    dir_name=os.path.join(dir_path, 'ldavis'),
                    lda=lda)
        os.environ["LDAVIS_DIR"] = os.path.join(dir_path, 'ldavis')
        try:
            subprocess.call(
                ['Rscript', os.path.join(BASEDIR, 'R/runLDAvis.R')])
        except ValueError:
            logging.warning("Unable to run runLDAvis.R")
        os.chdir(os.path.join(dir_path, 'ldavis', 'output'))
        sp = subprocess.Popen(['python', '-m', 'SimpleHTTPServer', '8000'])
        webbrowser.open_new_tab('127.0.0.1:8000')
        time.sleep(30)
        sp.kill()