Esempio n. 1
0
def score_clusters(collection):
    """
    Считает среднeвзвешенные оценки для каждого кластера
    :param collection:
    :return:
    """
    db = connect_to_db()
    cluster_db = db[collection]
    logging.info('Database connected')
    clusters_pd = download_collection(collection)
    logging.info('Clusters downloaded')
    for topic_idx in clusters_pd.index:
        total_views = sum([db.dereference(lecture)['views'] for lecture in clusters_pd.loc[topic_idx, 'lectures']])
        logging.info('\tTotal views for {} topic counted'.format(topic_idx))

        score_result = defaultdict(float)
        for lecture in clusters_pd.loc[topic_idx, 'lectures']:
            lec_id = db.dereference(lecture)['_id']
            scores = db.dereference(lecture)['scores']
            views = db.dereference(lecture)['views']
            for key in scores:
                score_result[key] += scores[key] * views
            logging.info('\t\t Lecture {} in topic {} counted'.format(lec_id, topic_idx))
        for key in score_result:
            score_result[key] /= total_views
            logging.info("\t'{:^12}' score in  topic {} normalized".format(key, topic_idx))
        cluster_db.update({'_id': int(topic_idx)}, {'$set': {'scores': dict(score_result)}})
        logging.info('Topic {} dumped to db'.format(topic_idx))
Esempio n. 2
0
def lda_cluster_text(alpha: float, docs_topics: pd.DataFrame, dumb_to_db=True):
    """
    Формирует кластеры и записывает их в базу данных
    :param alpha: Порог
    :param docs_topics: Вероятностное распределение документов по темам
    :param dumb_to_db:
    :return:
    """
    clusters = defaultdict(list)
    topics_docs = docs_topics.T
    logging.info('Docs_topics transposed')
    for i in topics_docs.index:
        for col in topics_docs.columns:
            if topics_docs.loc[i, col] >= alpha:
                clusters[int(i)].append(int(col))
    logging.info('Clusters created')

    if dumb_to_db:
        lda_topics = connect_to_db()['lda_clusters']
        lda_topics.drop()
        logging.info('lda_topics connected')
        for topic_idx in clusters:
            lectures = [DBRef('lectures', id) for id in clusters[topic_idx]]
            lda_topics.update({"_id": topic_idx}, {"$set": {"lectures": lectures}})
            logging.info('{} topic dumped to db'.format(topic_idx))
    return clusters
Esempio n. 3
0
def lda_topics_modeling(n_topics: int,
                        id2text,
                        corpus,
                        id2word,
                        n_top_features=10,
                        dump_to_db=True):
    """
    Возвращает вероятностное распределение документов по темам

    :param n_topics: Число возможных тем (топиков)
    :param id2text: Список имен (индексов) текстов
    :param corpus: текстов
    :param id2word: Список слов
    :param n_top_features: Число выводимых слов, характеризующих кластер
    :param dump_to_db: True - записывает топики в базу данных, False - не записывает топики в базуданных
    :return: кортеж с распределений слов по темам и документов по темам
    """

    t0 = time()
    lda = LatentDirichletAllocation(n_topics=n_topics)
    logging.info('LDA created in {:.3} sec'.format(time() - t0))

    t0 = time()
    doc_topic_dist = lda.fit_transform(corpus)
    logging.info('LDA model fit-transformed in {:.3} sec'.format(time() - t0))

    # Загрузка полученных топиков в базу данных
    if dump_to_db:
        lda_topics = connect_to_db()['lda_clusters']
        lda_topics.drop()
        for topic_idx, topic_dist in enumerate(lda.components_):
            doc = {
                '_id':
                int(topic_idx),
                'terms': [
                    id2word[i]
                    for i in np.argsort(topic_dist)[:-n_top_features - 1:-1]
                ]
            }
            lda_topics.insert(doc)
            logging.info('Topic {} dumped to database'.format(topic_idx))

    # Нормализация весов (получение вероятностей)
    topic_word_dist = np.apply_along_axis(_normalize_weights, 1,
                                          lda.components_)
    doc_topic_dist = np.apply_along_axis(_normalize_weights, 1, doc_topic_dist)

    topic_word_dist = pd.DataFrame(topic_word_dist, index=id2word)
    doc_topic_dist = pd.DataFrame(doc_topic_dist, columns=id2text)

    return topic_word_dist, doc_topic_dist, lda
def lda_topics_modeling(n_topics: int, id2text, corpus, id2word, n_top_features=10, dump_to_db=True):
    """
    Возвращает вероятностное распределение документов по темам

    :param n_topics: Число возможных тем (топиков)
    :param id2text: Список имен (индексов) текстов
    :param corpus: текстов
    :param id2word: Список слов
    :param n_top_features: Число выводимых слов, характеризующих кластер
    :param dump_to_db: True - записывает топики в базу данных, False - не записывает топики в базуданных
    :return: кортеж с распределений слов по темам и документов по темам
    """

    t0 = time()
    lda = LatentDirichletAllocation(n_topics=n_topics)
    logging.info('LDA created in {:.3} sec'.format(time() - t0))

    t0 = time()
    doc_topic_dist = lda.fit_transform(corpus)
    logging.info('LDA model fit-transformed in {:.3} sec'.format(time() - t0))

    # Загрузка полученных топиков в базу данных
    if dump_to_db:
        lda_topics = connect_to_db()['lda_clusters']
        lda_topics.drop()
        for topic_idx, topic_dist in enumerate(lda.components_):
            doc = {'_id': int(topic_idx),
                   'terms': [id2word[i] for i in np.argsort(topic_dist)[:-n_top_features - 1:-1]]}
            lda_topics.insert(doc)
            logging.info('Topic {} dumped to database'.format(topic_idx))

    # Нормализация весов (получение вероятностей)
    topic_word_dist = np.apply_along_axis(_normalize_weights, 1, lda.components_)
    doc_topic_dist = np.apply_along_axis(_normalize_weights, 1, doc_topic_dist)

    topic_word_dist = pd.DataFrame(topic_word_dist, index=id2word)
    doc_topic_dist = pd.DataFrame(doc_topic_dist, columns=id2text)

    return topic_word_dist, doc_topic_dist, lda
Esempio n. 5
0
def kcluster_text(corpus, n_clusters: int, id2text: list, id2word: list, n_components: int, n_top_features=10,
                  dump_to_db=False) -> tuple:
    """
    Ф-ция проводит кластеризацию текстов методом k-средних и загружает полученные кластеры в базу данных

    :param id2text: Список имен (индексов) текстов
    :param n_clusters: Число кластеров
    :param n_components: Число самых важных слов, по которым проводится кластеризация
    :param id2word: Список слов
    :param corpus: Корпус текстов
    :param n_top_features: Число выводимых слов, характеризующих кластер
    :return: Словарь кластеров, а так же
    """

    # Понижение размерности матрицы при помощи латентно-семантического анализа
    # Выделяет n самых значимых слова (n_components), отбрасывая все остальные
    if n_components:
        t0 = time()
        svd = TruncatedSVD(n_components)
        lsa = make_pipeline(svd, Normalizer(copy=False))
        corpus = lsa.fit_transform(corpus)
        logging.info("LSA applied in {:.3}".format(time() - t0))

    # Кластеризация методом К-средних
    t0 = time()
    km_model = KMeans(n_clusters=n_clusters, verbose=-1)
    cluster_labels = km_model.fit_predict(corpus)
    logging.info('K-means performed in {0:.3}'.format(time() - t0))

    # Полученные кластеры упаковываются вместе с характерными для них лекциями в словарь
    clusters = defaultdict(list)
    for text_id, label in enumerate(km_model.labels_):
        clusters[label].append(id2text[text_id])

    # Выделяет центроиды для полученых кластеров
    if n_components:
        # Если был применен SVD метод, возвращает нормальную размерность
        original_space_centroids = svd.inverse_transform(km_model.cluster_centers_)
        order_centroids = original_space_centroids.argsort()[:, ::-1]
    else:
        order_centroids = km_model.cluster_centers_.argsort()[:, ::-1]

    # Каждому кластеру приписвыает n_top_features слов
    top_features = defaultdict(list)
    for cluster_id in range(n_clusters):
        for word_id in order_centroids[cluster_id, :n_top_features]:
            top_features[cluster_id].append(id2word[word_id])

    # Если в качестве id2text данны индексы, то происходит запись кластеров в базу данных
    if dump_to_db:
        collection = connect_to_db()['k_clusters']
        collection.drop()
        logging.info("Table '{0}_{1}' created ".format('clusters', n_clusters))
        for cluster_id in dict(clusters):
            doc = {'_id': int(cluster_id), 'top_words': top_features[cluster_id],
                   'lectures': [DBRef(collection='lectures', id=lect_id) for lect_id in clusters[int(cluster_id)]]}
            logging.info("Cluster {} dumped to database".format(int(cluster_id)))
            collection.insert(doc)

    # Сведение данных в один список
    result = [{'_id': int(cluster_id), 'top_words': top_features[cluster_id], 'titles': clusters[int(cluster_id)]}
              for cluster_id in clusters]

    return result, cluster_labels