In [1]:
import pandas as pd
# pd.options.display.max_colwidth = 200

import numpy as np
from collections import defaultdict

import matplotlib
import matplotlib.pyplot as plt

import seaborn as sns
sns.set_style("white")

from pymystem3 import Mystem; mystem = Mystem()
from functools import lru_cache


from tqdm import tqdm
tqdm.pandas()

%matplotlib inline


/home/sweetsteam/anaconda3/lib/python3.5/site-packages/matplotlib/__init__.py:878: UserWarning: axes.color_cycle is deprecated and replaced with axes.prop_cycle; please use the latter.
  warnings.warn(self.msg_depr % (key, alt_key))

In [2]:
data = []
DATA_PATH = '../../NewsParser/data/'
for csv_name in ['recent_news.csv']:
    data.append(pd.read_csv(DATA_PATH + csv_name))
data = pd.concat(data)

In [3]:
data.head()


Out[3]:
date text title url
0 2017-04-18 19:41:14 КИЕВ, 18 апреля. /ТАСС/. "Дочка" российского С... "Дочка" Сбербанка может оспорить запрет на исп... http://tass.ru/ekonomika/4192151
1 2017-04-18 19:47:54 ПАРИЖ, 18 апреля. /Корр. ТАСС Сергей Щербаков/... Саркози призвал французских избирателей голосо... http://tass.ru/mezhdunarodnaya-panorama/4192155
2 2017-04-18 19:37:26 ЭЛЬ-КУВЕЙТ, 18 апреля. /Корр. ТАСС Павел Проко... В Мосуле ликвидирован "главный снайпер" ИГ http://tass.ru/mezhdunarodnaya-panorama/4192145
3 2017-04-18 19:59:38 КИЕВ, 18 апреля. /ТАСС/. Национальный банк Укр... Нацбанк Украины рассматривает документы от Nor... http://tass.ru/ekonomika/4192182
4 2017-04-18 19:15:21 РИМ, 18 апреля. /Корр.ТАСС Алексей Букалов/. Р... Сильвио Берлускони потеснил "Молодого папу" в ... http://tass.ru/kultura/4192052

In [4]:
class Pipeline(object):
    def __init__(self, *args):
        self.transformations = args
    def __call__(self, x):
        res = x
        for f in self.transformations:
            res = f(res)
        return res

from nltk.corpus import stopwords
from stop_words import get_stop_words
en_sw = get_stop_words('en')
ru_sw = get_stop_words('ru')
STOP_WORDS = set(en_sw) | set(ru_sw)
STOP_WORDS = STOP_WORDS | set(stopwords.words('russian')) | set(stopwords.words('english'))
STOP_WORDS = STOP_WORDS | set(['лента', 'новость', 'риа', 'тасс', 'редакция'])

def get_lower(text):
    return str(text).lower().strip()

def remove_punctuation(text):
    return ''.join([c if c.isalpha() or c in ['-',"'"] else ' ' for c in text])

@lru_cache(maxsize=None)
def get_word_normal_form(word):
    return ''.join(mystem.lemmatize(word)).strip().replace('ё', 'е').strip('-')

def lemmatize_words(text):
    res = []
    for word in text.split():
        norm_form = get_word_normal_form(word)
        if len(norm_form) > 2 and norm_form not in STOP_WORDS:
            res.append(norm_form)
    return ' '.join(res)

TEXT_PIPELINE = Pipeline(get_lower, remove_punctuation, lemmatize_words)

In [5]:
%%time
data.text = data.text.progress_apply(TEXT_PIPELINE)
data.title = data.title.apply(lambda x: x.strip())
data['title_norm'] = data.title.progress_apply(TEXT_PIPELINE)


100%|██████████| 927/927 [00:03<00:00, 246.18it/s]
100%|██████████| 927/927 [00:00<00:00, 11976.53it/s]
CPU times: user 1.58 s, sys: 240 ms, total: 1.82 s
Wall time: 3.85 s


In [6]:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

In [7]:
trainX = data['title_norm'] + ' ' + data.text
# print(trainX)
trainX = trainX.values

In [8]:
trainX.shape


Out[8]:
(927,)

In [9]:
import pickle

In [10]:
with open('count_vectorizer.bin', 'rb') as pickle_file:
    tfidf_vectorizer = pickle.load(pickle_file)

In [11]:
%%time
# tfidf_vectorizer = TfidfVectorizer(min_df=5, ngram_range=(1,2), lowercase=False).fit(trainX)


CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 7.63 µs

In [12]:
len(tfidf_vectorizer.vocabulary_)


Out[12]:
1025216

In [13]:
tfidf_matrix = tfidf_vectorizer.transform(trainX)

KMeans


In [14]:
from sklearn.cluster import KMeans
# from spherecluster import SphericalKMeans

In [15]:
kmeans = KMeans(n_clusters=30, random_state=42).fit(tfidf_matrix)
# kmeans = SphericalKMeans(n_clusters=K).fit(tfidf_matrix)

In [16]:
clasters = kmeans.predict(tfidf_matrix)
c_list = [ [] for i in range(30) ]
for i, claster in enumerate(clasters):
    tfidf_news = tfidf_matrix[i,:]
#     print(kmeans.cluster_centers_[claster].reshape(1, -1).shape, tfidf_news.shape)
    if cosine_similarity(tfidf_news, kmeans.cluster_centers_[claster].reshape(1, -1))[0][0] > 0.65:
        c_list[claster].append(i)

In [17]:
c_list


Out[17]:
[[102],
 [23, 527, 697],
 [],
 [35],
 [413, 592],
 [31],
 [269, 295],
 [10],
 [189, 282, 291],
 [304],
 [22],
 [310],
 [262, 316],
 [300, 626],
 [19, 225],
 [311],
 [51, 496, 574, 718, 896],
 [318, 353, 562, 646],
 [299],
 [84, 92, 111, 471, 903],
 [63, 164, 563, 598],
 [580],
 [],
 [236],
 [176],
 [283],
 [0, 29],
 [133],
 [322],
 [203]]

In [18]:
for i, group in enumerate(c_list):
    if len(group) < 3:
        continue
    print('Topic', i)
    for id_ in group:
        print(data.title[id_],data.url[id_])
    print()


Topic 1
Подразделения ПВО Москвы подняты по тревоге в рамках проверки http://tass.ru/armiya-i-opk/4191986
Соединение ПВО Москвы подняли по тревоге https://lenta.ru/news/2017/04/18/pvo/
Минобороны: подразделения ПВО Москвы подняты по тревоге в рамках проверки https://www.gazeta.ru/army/news/9939659.shtml

Topic 8
Москалькова: данные о похищении геев в Чечне пока не подтвердились http://tass.ru/obschestvo/4190260
КЗЖ высказался за проведение расследования в связи с угрозами журналистам "Новой газеты" http://tass.ru/obschestvo/4189588
Постпред США при ООН призвала власти Чечни расследовать сообщения о притеснениях геев http://tass.ru/mezhdunarodnaya-panorama/4189602

Topic 16
Путин назвал процентщицу из романа Достоевского более скромной, чем нынешние МФО http://tass.ru/ekonomika/4191531
Путин сравнил процентщицу из Достоевского и микрофинансовые организации https://lenta.ru/news/2017/04/18/dostoevsky/
Путин предложил ужесточить наказание за мошенничество в сфере предоставления займов http://www.vedomosti.ru/finance/news/2017/04/18/686262-putin-uzhestochit-nakazanie-moshennichestvo-zaimov
Путин сравнил старушку-процентщицу Достоевского и современные МФО https://www.gazeta.ru/business/news/2017/04/18/n_9938765.shtml
Путин сравнил выдающих микрозаймы со старухой-процентщицей Достоевского https://www.novayagazeta.ru/news/2017/04/18/130829-putin-nazval-staruhu-protsentschitsu-dostoevskogo-skromnee-vydayuschih-mikrokredity-bankirov

Topic 17
"Победа" уволит сотрудника, не обеспечившего посадку на борт ребенка с ДЦП http://tass.ru/proisshestviya/4189442
«Победа» уволит сотрудника из-за улетевшего без ребенка-инвалида самолета https://lenta.ru/news/2017/04/18/pobeda/
Росавиация назвала незаконной причину недопуска ребенка-инвалида на рейс «Победы» http://www.vedomosti.ru/business/news/2017/04/18/686273-rosaviatsiya-prichinu-nedopuska
Инцидентом с недопуском ребенка с ДЦП на рейс «Победы» занялась прокуратура http://www.vedomosti.ru/business/news/2017/04/18/686181-dtsp-pobedi

Topic 19
Эксперт заявил об "отсечении" в американских соцсетях позитивного для РФ контента http://tass.ru/politika/4191160
Депутат предложил разобраться в конкретных случаях воздействия США на выборы в России http://tass.ru/politika/4191019
Эксперты нашли следы вмешательства США в выборы в России 2016 года http://tass.ru/politika/4191121
В Госдуме заподозрили американские СМИ во влиянии на выборы в России https://lenta.ru/news/2017/04/18/proverka/
В Госдуме предложили разобраться в случаях «воздействия» США на выборы в России https://www.novayagazeta.ru/news/2017/04/18/130824-v-gosdume-predlozhili-razobratsya-v-sluchayah-vozdeystviya-ssha-na-vybory-v-rossii

Topic 20
Холдинг "Просвещение" Ротенберга может вложить до 1,5 млрд руб. в покупку IT-компаний http://tass.ru/ekonomika/4191818
Издательство "Просвещение" Аркадия Ротенберга рассматривает IPO в Лондоне и России http://tass.ru/ekonomika/4190640
«Просвещение» Ротенберга может вложить до 1,5 млрд рублей в покупку IT-компаний http://www.vedomosti.ru/technology/news/2017/04/18/686285-prosveschenie
Издательство «Просвещение» с долей Аркадия Ротенберга готовит IPO в Лондоне и России http://www.vedomosti.ru/business/news/2017/04/18/686212-izdatelstvo-prosveschenie


In [17]:
kmeans.cluster_centers_


Out[17]:
array([[ 0.00021113,  0.        ,  0.00305723, ...,  0.00121998,
         0.00235024,  0.        ],
       [ 0.00171598,  0.0005434 ,  0.        , ...,  0.        ,
         0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        , ...,  0.        ,
         0.        ,  0.00743105],
       [ 0.00377684,  0.00134598,  0.        , ...,  0.        ,
         0.        ,  0.0012463 ],
       [ 0.        ,  0.0010983 ,  0.        , ...,  0.00031296,
         0.        ,  0.        ]])

Graphs


In [24]:
cosines = []
for tfidf_news in tfidf_matrix:
    cosine = cosine_similarity(tfidf_news, tfidf_matrix)
    cosines.append(cosine.tolist()[0])

In [31]:
COS_THRESHOLD = 0.75
themes = [ -1 for _ in range(len(cosines)) ]
themes_ids = [ [] for _ in range(len(cosines)) ]
curr_theme = 0
for v, theme in enumerate(themes):
    if theme == -1:
        curr_theme += 1
        Q = []
        Q.append(v)
        themes[v] = curr_theme
        themes_ids[curr_theme].append(v)
        while Q:
            curr_v = Q.pop(0)
            for u, cos in enumerate(cosines[curr_v]):
                if cos >= COS_THRESHOLD and themes[u] == -1:
                    themes[u] = curr_theme
                    themes_ids[curr_theme].append(u)
                    Q.append(u)

In [32]:
# themes_ids

In [33]:
groups = sorted(themes_ids, key=lambda x: -len(x))

In [34]:
for i, group in enumerate(groups):
    if len(group) < 2:
        break
    print('Topic', i)
    for id_ in group:
        print(data.title[id_],data.url[id_])
    print()


Topic 0
Чистая прибыль банка «Россия» выросла на 75% за январь – март http://www.vedomosti.ru/finance/news/2017/04/18/686211-pribil-banka-rossiya
Квартальная прибыль «ВТБ 24» выросла в 3,9 раза http://www.vedomosti.ru/finance/news/2017/04/18/686204-pribil-vtb-24
Россельхозбанк снизил чистую прибыль в 7,6 раза за I квартал http://www.vedomosti.ru/finance/news/2017/04/18/686207-rosselhozbank-snizil-pribil

Topic 1
"Дочка" Сбербанка может оспорить запрет на использование своих торговых марок на Украине http://tass.ru/ekonomika/4192151
Киевский суд лишил Сбербанк доменного имени и запретил использовать торговую марку http://tass.ru/ekonomika/4192017

Topic 2
Хлебопеки не нуждаются в законодательном запрете на возврат непроданного хлеба http://tass.ru/ekonomika/4191387
"Пятерочка" уйдет от практики возврата непроданного хлеба производителям  c 1 июня http://tass.ru/ekonomika/4191118

Topic 3
Греф: бумажные трудовые книжки мешают работодателям и Пенсионному фонду http://tass.ru/ekonomika/4190698
Греф раскритиковал бумажные трудовые книжки http://www.vedomosti.ru/finance/news/2017/04/18/686226-gref-trudovie-knizhki

Topic 4
Сбербанк стал самым дорогим российским брендом http://tass.ru/ekonomika/4190690
Сбербанк стал самым дорогим российским брендом – Brand Finance http://www.vedomosti.ru/finance/news/2017/04/18/686217-sberbank-samim-dorogim-brendom

Topic 5
Издательство "Просвещение" Аркадия Ротенберга рассматривает IPO в Лондоне и России http://tass.ru/ekonomika/4190640
Издательство «Просвещение» с долей Аркадия Ротенберга готовит IPO в Лондоне и России http://www.vedomosti.ru/business/news/2017/04/18/686212-izdatelstvo-prosveschenie

Topic 6
Президент Грузии призывает Россию к конструктивному диалогу http://tass.ru/mezhdunarodnaya-panorama/4190194
Президент Грузии встревожен действиями российской стороны https://www.gazeta.ru/politics/news/2017/04/18/n_9936959.shtml

Topic 7
Прокуратура проверит отказ "Победы" пустить на борт ребенка с ДЦП http://tass.ru/proisshestviya/4190027
Прокуратура проверит отказ авиакомпании «Победа» пустить на борт ребенка с ДЦП https://www.gazeta.ru/social/news/2017/04/18/n_9936731.shtml

Topic 8
Частица Благодатного огня впервые в истории доставлена в США из России http://tass.ru/obschestvo/4189844
Благодатный огонь впервые в истории доставили в США из России https://www.gazeta.ru/social/news/2017/04/18/n_9936491.shtml

Topic 9
Минобрнауки по итогам конкурсного отбора назвало 22 опорных вуза http://tass.ru/obschestvo/4189779
Минобрнауки выбрало еще 22 опорных вуза https://lenta.ru/news/2017/04/18/22plus/

Topic 10
Медведев подписал документ, направленный на увеличение инвестиций в сферу теплоснабжения http://tass.ru/ekonomika/4189754
Медведев подписал постановление об увеличении инвестиций в сферах водоснабжения и тепла https://www.gazeta.ru/business/news/2017/04/18/n_9936269.shtml

Topic 11
Пентагон начал оценку ядерного потенциала США на предмет соответствия угрозам http://tass.ru/mezhdunarodnaya-panorama/4189640
Глава Пентагона поручил оценить ядерный потенциал США http://tass.ru/mezhdunarodnaya-panorama/4189511

Topic 12
Черчесов: текущий уровень футболиста Кокорина не до конца устраивает штаб сборной РФ http://tass.ru/sport/4189609
Черчесов: текущий уровень Кокорина не устраивает штаб сборной России https://www.gazeta.ru/sport/news/2017/04/18/n_9935939.shtml

Topic 13
Россельхознадзор обеспокоен ростом поставок мяса и масла с Украины http://tass.ru/ekonomika/4189409
Россельхознадзор обеспокоен ростом поставок мяса с Украины из-за АЧС https://www.gazeta.ru/business/news/2017/04/17/n_9935129.shtml

Topic 14
Котировки РБК растут более чем на 8% после новостей о возможной покупке группой ЕСН http://www.vedomosti.ru/technology/news/2017/04/18/686269-kotirovki-rbk-rastut-esn
Березкин подтвердил планы купить РБК http://www.vedomosti.ru/technology/news/2017/04/18/686197-berezkin-rbk

Topic 15
Более 70% региональных дорог Новгородской области не соответствует нормативу – Путин http://www.vedomosti.ru/realty/news/2017/04/18/686246-regionalnih-dorog-ne-sootvetstvuet
Путин призвал обратить внимание на состояние дорог в Новгородской области https://www.gazeta.ru/auto/news/2017/04/18/n_9938321.shtml

Topic 16
Многие работы на «Зенит-арене» потребуют переделки – ФАС http://www.vedomosti.ru/realty/news/2017/04/18/686192-raboti-zenit-arene-potrebuyut-peredelki
УФАС: многие работы на стадионе на Крестовском острове потребуют переделки https://www.gazeta.ru/sport/news/2017/04/18/n_9937253.shtml

Topic 17
Фондовый рынок США открылся падением https://www.gazeta.ru/business/news/2017/04/18/n_9938777.shtml
Фондовый рынок США закрылся ростом https://www.gazeta.ru/business/news/2017/04/17/n_9935699.shtml

Topic 18
Мировые цены на нефть не определились с динамикой https://www.gazeta.ru/business/news/2017/04/18/n_9936377.shtml
Мировые цены на нефть снижаются https://www.gazeta.ru/business/news/2017/04/17/n_9935627.shtml


In [ ]: