Инструменты и методы Data Science для медиакомпаний на примере издания "Ведомости"

Представление данных в нейронных сетях. Рекомендательная система New York Times. Проведение эксперимента Washington Post по предсказанию популярности статей. Применение методов Data Science в издании "Ведомости". Изучение сегментации на основе RFM.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 14.12.2019
Размер файла 320,4 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Алгоритм content based модели

1. Сбор текстовых данных

SQL запросом к базе документов издания «Ведомости» выгрузить из базы статей издания «Ведомости» тексты статей, опубликованных за последние шесть месяцев.

2. Удаление стоп-слов

Составить список стоп-слов. Удалить полученные слова из текстов, полученных в пункте 1.

3. Удаление высокочастотных и редких слов

Посчитать IDF всех слов в текстах и удалить слова с самым высоким IDF и c самым низким IDF. Таким образом избавившись от высокочастотных и редких слов.

4. Лемматизация

Привести все слова к их лемме - нормальной форме слова.

5. Векторизация

Удалить знаки пунктуации и цифры, токенизировать и подсчитать слова из текстов, представив их в виде терм-документной матрицы, используя Count Vectorizer.

6. Обучение модели латентного размещения Дирихле

Обучить модель латентного размещения Дирихле на векторизованных текстах, с предустановкой на разделение текстов на 60 тематик.

7. Определение тематик статей

Применить полученную в пункте 6 модель латентного размещения Дирихле для представления всех текстов и первого пункта в виде комбинации двух тематик.

8. Матрица пользовательских предпочтений

Используя тексты статей, прочитанных пользователями за последний месяц, представленных в виде комбинации двух тематик, определить десять наиболее читаемых пользователями тематик.

Рекомендация строится, считая оценку релевантности статьи пользователю по данным полученным из user based и contents based модели.

Программная реализация рекомендательной системы

Рекомендательная система каждый день автоматически генерирует 15 статей для рекомендации каждому из пользователей. Реализована как набор последовательно выполняющихся функций, каждая из которых, кроме get_stopwords выполняется ежедневно.

Функция get_stopwords(path) принимает на вход путь к директории, куда сохраняет файл со сгенерированным списком стоп-слов. Стоп-слова берутся из встроенных в библиотеку NLTK списков стоп-слов для русского и английского языков и вручную внесённых малоинформативных слов.

Функция download_texts(path) принимает на вход путь, по которому будет сохранён выходной файл. Скачивает тексты статей за последние шесть месяцев и сохраняет и в файл «texts.csv» в директорию, указанную входным параметром функции. Функция возвращает тексты статей в виде DataFrame.

Функция lda_learn(texts, path, model_path) принимает на вход тексты статей, путь к директории содержащий стоп слова, путь к директории, куда будут сохранены модели. Функция предобрабатывает текст, удаляя из него знаки препинания, стоп-слова, слишком часто и редко используемые слова, приводит слова к лемме, переводит тексты в векторный вид и обучает на них алгоритм латентного размещения Дирихле, реализованный в scikit-learn. Функция сохраняет модели векторизации и латентного размещения Дирихле в файлы «cv.pkl» и «lda.pkl» соответственно и возвращает модели.

Функция text_topics(lpath, model_path) принимает на вход путь к директории куда будет сохранён выходной файл и путь к директории содержащей модели векторизации и латентного размещения Дирихле. Функция представляет все тексты в виде комбинации двух тематик. Каждая тематика имеет определённую вероятность генерации каждого из слов, для большей наглядности приведу пример пяти тематик, выраженных как десять слов с наибольшей вероятностью генерации:

1. {представитель, мтс, оператор, tele2, ростелеком, гендиректор, рынок компания, интернет, мегфон}

2. {суд, решение, иск, представитель, адвокат, арбитражный, партнер, речь, право, юрист}

3. {порошенко, зеленский, президент, выборы, тимошенко, украина, владимир, политолог, дебаты, крым}

4. {нефть, опек, сутки, добыча, баррель, рост, аналитик, россия, производство, экспорт}

5. {ес, brexit, мэй, премьер, парламент, соглашение, правительство, министр, великобритания, голосование}

Функция возвращает DataFrame с уникальным идентификатором статьи, первой тематикой и второй тематикой. Также, функция сохраняет DataFrame в файл «text_topics.csv».

Функция create_user_matrix(path) считает индекс Жаккара между списками статей, прочитанных каждым из пользователей. Первоначально коэффициент Жаккара считался, обрабатывая DataFrame таблицы используя функции Pandas, такие вычисления занимали много времени. Перевод обработки DataFrame в обработку многомерные массивов Numpy и использование Just-in-time компилятора Numba позволило увеличить скорость вычислений матрицы коэффициентов Жаккара в 128 раз. Матрица имеет вид, представленный в таблице 5.

Таблица 5. Матрица коэффициентов Жаккара

USER_ID

1001

1002

...

N

1001

1

0.25

0.1

0.24

1002

0.25

1

...

0.33

...

0.1

...

...

...

N

0.24

033

...

1

После расчета коэффициента Жаккара, функция находит для каждого пользователя 10 пользователей с наибольшим коэффициентом Жаккара и сохраняет в файл «matrix.csv» и возвращает как DataFrame таблицу.

Функция user_topics(path) принимает на вход путь к директории, где находятся файлы «matrix.csv» и «text_topics.csv». Функция считает для каждого пользователя 10 наиболее близких ему тематик и сохраняет их в файл «user_topics.csv».

Функция recommendation_matrix(path) принимает на вход путь к директории, где расположены файлы «text_topics.csv» и «user_topics.csv». Функция находит для каждого пользователя 15 статей, перебирая все непрочитанные пользователем статьи вышедшие за последние полгода, и проверяя для каждой статьи входят ли её тематики в топ-10 тематик пользователя и читали ли статью пользователи с высоким коэффициентом Жаккара для этого пользователя. Функция сохраняет получившуюся таблицу в файл «arr.csv». Файл содержит уникальные идентификаторы пользователя и 15 уникальных идентификаторов статей для каждого, из пользователей. Таблица имеет вид, представленный в таблице 6.

Таблица 6. Матрица рекомендаций

User_id

Doc_id 1

Doc_id 2

Doc_id 3

Doc_id 4

Doc_id 5

Doc_id 6

Doc_id 15

1

24214124

2319915

1231412

5234024

4423444

3424242

3675928

2

23423421

2554303

1012341

4240414

4201113

1201444

5400034

3

72035339

1240251

3223421

2342342

2342423

2420023

4534452

Код рекомендательной модели приведён в приложении 4. Из кода удалены подключение и запросы к базам данных издания «Ведомости».

Заключение

В данной работе была представлена разработка трёх систем для издания «Ведомости»:

1. Система сегментации пользователей, основанная на RFM анализе

2. Две модели предсказания оттока, основанные на градиентном бустинге над решающими деревьями и на сетях долговременной краткосрочной памяти

3. Система рекомендации статей пользователям

Все три системы были внедрены в издание «Ведомости». Для RFM сегментации было написано веб-приложение и размещено на локальном сервере. Веб-приложение позволяет маркетологам одним нажатием на кнопку получать файлы с сегментами для рассылок.

Обе модели предсказания оттока показали хорошие результаты, но точность модели LSTM оказалась большей чем у Catboost, что оказалось решающим фактором при выборе модели для использования. В отличии от многих работ модели строились не на искусственных данных, а на настоящих данных издания «Ведомости», обладающих большим количеством шумов, пропусков и выбросов, что усложнило разработку и не позволяло сделать простую модель с малым количеством признаков.

Скрипт рекомендательной системы размещён на сервере издания «Ведомости» и ежедневно автоматически генерирует индивидуальные рекомендации для каждого из пользователей сайта, основываясь на его прошлых прочтениях и прочтениях похожих по интересам пользователей.

Все вычисления производились на сервере под операционной системой Ubuntu 16.04.2 с двенадцатью процессорами Intel(R) Xeon(R) CPU E5-1650 v4 и восемью гигабайтами оперативной памяти.

Данная работа может быть полезна для компаний, имеющих сайты со статьями, блогами, новостями и собирающих данные о взаимодействии пользователей с сайтом, поскольку в работе приведены рабочие модели сегментации пользователей, предсказания оттока и рекомендательной системы. Для каждой модели приведён код в приложении.

Ключевым направлением дальнейшего развития данного проекта является совершенствование модели предсказания оттока, путём добавления новых признаков и экспериментируя с архитектурой модели и совершенствование рекомендательной системы путём добавления новых стоп-слов для более точного моделирования тематик и добавлением новых признаков оценки сходства предпочтений пользователей. Ожидаемые результаты от дальнейшей работы связаны с увеличением точности и полноты результатов модели предсказания оттока и большей персонифицированности рекомендательной системы.

Cписок использованной литературы и источников

1 Chong Wang, David M. Blei, Collaborative topic modeling for recommending scientific articles // 17th ACM SIGKDD international conference on Knowledge discovery and data mining. New York: ACM, 2011. С. 448-456.

2 Yaser Keneshloo, Shuguang Wang, Eui-Hong Sam Han, Naren Ramakrishnan, Predicting the Popularity of News Articles // 2016 SIAM International Conference on Data Mining. 2016. С. 441-449.

3 T. Chen, C. Guestrin, XGBoost: A Scalable Tree Boosting System // KDD '16 Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining. New York: ACM, 2016. С. 785-794.

4 K. Guolin, M. Qi, et al. LightGBM: A highly efficient gradient boosting decision tree. In NIPS, pages 3149-3157, 2017.

5 Huan Zhang, Si Si, Cho-Jui Hsieh, GPU-acceleration for Large-scale Tree Boosting // SysML Conference. 2017.

6 A. Dorogush, V. Ershov, et al. CatBoost: Gradient boosting with categorical features support // ML Systems Workshop, NIPS. 2017. С. 1-7.

7 Andreea Anghel, Nikolaos Papandreou, Thomas Parnell Alessandro de Palma, Haralampos Pozidis, Benchmarking and Optimization of Gradient Boosting Decision Tree Algorithms // Workshop on Systems for ML and Open Source Software at NeurIPS 2018.

8 Y. Bengio, P. Simard, P. Frasconi, Learning long-term dependencies with gradient descent is difficult // IEEE Transactions on Neural Networks. 1994. №5. С. 157-166.

9 Sepp Hochreiter, Jurgen Schmidhuber Long Short-term Memory // Neural Computation. 1997. №9(8). С. 1735 - 1780.

Приложение

Листинг программы RFM сегментации

import pandas as pd

import sqlalchemy

import datetime as dt

query = #тут запрос к базе

NOW =dt.datetime.now().date()

rfmTable = data.groupby('customer_id').agg({'date': lambda x: (NOW - x.max()).days, # Recency

'customer_id': lambda x: len(x), # Frequency

'amount': lambda x: x.nunique()}) # Количество прочитанных статей

rfmTable.rename(columns={'date': 'recency',

'customer_id': 'frequency',

'amount': 'monetary_value'}, inplace=True)

quantiles = rfmTable.quantile(q=[0.25,0.5,0.75])

segmented_rfm_table = rfmTable

def RecencyScore(value,name,d):

if value <= d[name][0.25]:

return 1

elif value <= d[name][0.50]:

return 2

elif value <= d[name][0.75]:

return 3

else:

return 4

def FrequencyMonetaryScore(value,name,d):

if value <= d[name][0.25]:

return 4

elif value <= d[name][0.50]:

return 3

elif value <= d[name][0.75]:

return 2

else:

return 1

segmented_rfm_table['r_quartile'] = segmented_rfm_table['recency'].apply(RecencyScore, args=('recency',quantiles,))

segmented_rfm_table['f_quartile'] = segmented_rfm_table['frequency'].apply(FrequencyMonetaryScore, args=('frequency',quantiles,))

segmented_rfm_table['m_quartile'] = segmented_rfm_table['monetary_value'].apply(FrequencyMonetaryScore, args=('monetary_value',quantiles,))

segmented_rfm_table['RFMScore'] = segmented_rfm_table.r_quartile.map(str) + segmented_rfm_table.f_quartile.map(str) + segmented_rfm_table.m_quartile.map(str)

segmented_rfm_table.to_csv('RFMScore')

Листинг программы создания Catboost модели

import os, sys

import datetime as dt

from dateutil.relativedelta import relativedelta

import pandas as pd

import numpy as np

global data

from tqdm import tqdm_notebook

from sklearn.preprocessing import normalize

import pandahouse, sqlalchemy, pandasql

pysql = lambda q: pandasql.sqldf(q, globals())

import dateutil.relativedelta as relativedelta

import dateutil.rrule as rrule

from keras.preprocessing import sequence

import tensorflow as tf

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

import keras.metrics

from keras.optimizers import Adam

from keras.models import load_model

from keras.callbacks import ModelCheckpoint

from sklearn.metrics import roc_auc_score

from sklearn.metrics import accuracy_score

from sklearn.metrics import confusion_matrix

from tensorflow.keras.optimizers import Adam

from tensorflow.keras import layers

from tensorflow.keras.callbacks import EarlyStopping

from catboost import CatBoostClassifier

rr = rrule.rrule(rrule.WEEKLY,byweekday=relativedelta.MO, dtstart=pd.to_datetime('2010.01.01'))

def download_data():

# Здесь запросы к базам данных

data.to_csv('data.csv')

return data

def generate_futures(data)

def static_computing(matrix):

train_row = []

fourier = np.fft.fft(matrix)

real = np.real(fourier)

imag = np.imag(fourier)

train_row.append(real.mean())

train_row.append(real.std())

train_row.append(real.max())

train_row.append(real.min())

train_row.append(imag.mean())

train_row.append(imag.std())

train_row.append(imag.max())

train_row.append(imag.min())

train_row.append(matrix.mean())

train_row.append(matrix.std())

train_row.append(matrix.min())

train_row.append(matrix.max())

train_row.append(matrix.kurtosis())

train_row.append(matrix.skew())

train_row.append(np.quantile(matrix,0.01))

train_row.append(np.quantile(matrix,0.05))

train_row.append(np.quantile(matrix,0.95))

train_row.append(np.quantile(matrix,0.99))

train_row.append(np.abs(matrix).max())

train_row.append(np.abs(matrix).mean())

train_row.append(np.abs(matrix).std())

return pd.Series(strain)

user_list = data['user_id'].unique()

now = dt.date.today()

train_data = data[(data['date']>=pd.to_datetime(now - dt.timedelta(90)).date()) & (data['date']<pd.to_datetime(now - dt.timedelta(30)).date())]

test_data = data[(data['date']>=pd.to_datetime(now - dt.timedelta(60)).date()) & (data['date']<pd.to_datetime(now).date())]

train_data_edited = []

train_target=[]

for user_id in user_list:

if len(data[(data['date']>=pd.to_datetime(now - dt.timedelta(30)).date() - dt.timedelta(14)) & (data['date']<=pd.to_datetime(now - dt.timedelta(30)).date()) & (data['user_id']==user_id)])>0:

train_data_edited.append(train_data[train_data['user_id'] == user_id].iloc[:,2:].apply(gen_features).values.flatten())

if len(test_data[test_data['user_id']==user_id]) > 2:

train_target.append(0)

else:

train_target.append(1)

test_data_edited = []

test_target=[]

for user_id in user_list:

test_data_edited.append(test_data[test_data['user_id'] == user_id].iloc[:,2:].apply(gen_features).values.flatten())

return train_data_edited, train_target, test_data_edited

def build_catboost_model(train, train_target):

modl = CatBoostClassifier(iterations=100, learning_rate = 0.01,

eval_metric ='AUC', loss_function = 'Logloss', boosting_type='Ordered')

modl.fit(train, train_target,

logging_level = 'Silent')

return modl

def make_prediciton(model, matrix):

prediction = model.predict(matrix)

return prediciton

Листинг программы создания LSTM модели

import os, sys

import datetime as dt

from dateutil.relativedelta import relativedelta

import pandas as pd

import numpy as np

global data

from tqdm import tqdm_notebook

from sklearn.preprocessing import normalize

import pandahouse, sqlalchemy, pandasql

pysql = lambda q: pandasql.sqldf(q, globals())

import dateutil.relativedelta as relativedelta

import dateutil.rrule as rrule

rr = rrule.rrule(rrule.WEEKLY,byweekday=relativedelta.MO, dtstart=pd.to_datetime('2010.01.01'))

from keras.preprocessing import sequence

import tensorflow as tf

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

import keras.metrics

from keras.optimizers import Adam

from keras.models import load_model

from keras.callbacks import ModelCheckpoint

from sklearn.metrics import roc_auc_score

from sklearn.metrics import accuracy_score

from sklearn.metrics import confusion_matrix

from tensorflow.keras.optimizers import Adam

from tensorflow.keras import layers

from tensorflow.keras.callbacks import EarlyStopping

def download_data():

# Здесь запросы к базам данных

mailing_data = pd.read_sql_query(query, con=clickhouse)

data = pd.merge(data,mailing_data, on = ['user_id','week'], how='left').fillna(0)

return data, data_per_day

#data.to_csv('data.csv')

def train_validation_test(data, data_per_day):

now = dt.date.today()

last_monday = now-dt.timedelta(now.weekday())

t_monday_start = (last_monday-dt.timedelta(91))

t_monday_end = (last_monday-dt.timedelta(42))

t_validate_start = (last_monday-dt.timedelta(77))

t_validate_end = (last_monday-dt.timedelta(28))

users = data['user_id'].unique()

train_data = []

train_target = []

train_users = []

monday_list=rr.between(t_monday_start,t_monday_end,inc=True)

monday_list = [i.date() for i in monday_list]

monday_list = pd.DataFrame(monday_list, columns=['week']).sort_values('week')

t_monday_start = t_monday_start.date()

t_monday_end = t_monday_end.date()

for user in users:

temp = data[data['user_id']==user]

temp_day = data_per_day[data_per_day['user_id']==user]

target = temp_day[(temp_day['date']>=t_monday_end) & (temp_day['date']<=t_monday_end+dt.timedelta(28))]

target = len(target)

temp = temp[(temp['week']>=t_monday_start) & (temp['week']<=t_monday_end)]

if len(temp[(temp['week']>=t_monday_end-dt.timedelta(14)) & (temp['week']<=t_monday_end)])>0:

temp = pd.merge(monday_list, temp,how='left').fillna(0)

train_data.append(normalize(temp.sort_values('week').iloc[:,2:].values,axis=1))

if target >= 2:

train_target.append(0)

else:

train_target.append(1)

validate_data = []

validate_target = []

validate_users = []

validate_list=rr.between(t_validate_start,t_validate_end,inc=True)

validate_list = [i.date() for i in validate_list]

validate_list = pd.DataFrame(validate_list, columns=['week']).sort_values('week')

t_validate_start = t_validate_start.date()

t_validate_end = t_validate_end.date()

for user in users:

temp = data[data['user_id']==user]

temp_day = data_per_day[data_per_day['user_id']==user]

target = temp_day[(temp_day['date']>=t_validate_end) & (temp_day['date']<=t_validate_end+dt.timedelta(28))]

target = len(target)

temp = temp[(temp['week']>=t_validate_start) & (temp['week']<=t_validate_end)]

if len(temp[(temp['week']>=t_validate_end-dt.timedelta(14)) & (temp['week']<=t_validate_end)])>0:

temp = pd.merge(validate_list, temp,how='left').fillna(0)

alidate_data.append(normalize(temp.sort_values('week').iloc[:,2:].values,axis=1))

if target >= 2:

validate_target.append(0)

else:

validate_target.append(1)

t_test_start = (last_monday-dt.timedelta(49))

t_test_end = last_monday

test_data = []

test_target = []

test_users = []

test_list=rr.between(t_test_start,t_test_end,inc=True)

test_list = [i.date() for i in test_list]

test_list = pd.DataFrame(test_list, columns=['week']).sort_values('week')

t_test_start = t_test_start.date()

t_test_end = t_test_end.date()

for user in users:

temp = data[data['user_id']==user]

temp_day = data_per_day[data_per_day['user_id']==user]

target = temp_day[(temp_day['date']>=t_test_end) & (temp_day['date']<=t_test_end+dt.timedelta(28))]

target = len(target)

temp = temp[(temp['week']>=t_test_start) & (temp['week']<=t_test_end)]

if len(temp[(temp['week']>=t_test_end-dt.timedelta(14)) & (temp['week']<=t_test_end)])>0:

temp = pd.merge(test_list, temp,how='left').fillna(0)

est_data.append(normalize(temp.sort_values('week').iloc[:,2:].values,axis=1))

return train_data, train_target, validae_data, validate_target, test_data

def build_model(train_data, train_target, validae_data, validate_target):

clas_weight = {1:0.8,

0:0.2}

model = tf.keras.Sequential([

layers.LSTM(64, return_sequences=True, input_shape=(train.shape[1], train.shape[2])),

layers.LSTM(64, return_sequences=True),

layers.LSTM(64),

layers.Dropout(0.2),

layers.Dense(64,activation='relu'),

layers.Dropout(0.2),

layers.Dense(1, activation='sigmoid')

])

model.compile(optimizer=Adam(learning_rate=0.001), loss='binary_crossentropy', metrics=['acc'])

model.fit(train, train_target, epochs=10, batch_size=128,

validation_data=(validation,validation_target),

class_weight=clas_weight)

Листинг программы рекомендательной системы

#1 Скачивание текстов

def download_texts(path):

# здесь запросы к базам данных

return(docs)

#2 Обучение LDA

def lda_learn(texts, path, model_path):

import pickle

from sklearn.externals import joblib

from pymystem3 import Mystem

import re

import pandas as pd

import numpy as np

from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer

from sklearn.decomposition import LatentDirichletAllocation as LDA

with open(path+'stopwords.pkl', 'rb') as f:

stopwords = pickle.load(f)

texts.dropna(inplace = True)

texts = texts['text'].values

tf_idf = TfidfVectorizer(stop_words=stopwords,

smooth_idf=False)

tf_idf.fit(texts)

frequent_mask = tf_idf.idf_ > 3.

rare_mask = tf_idf.idf_ < 6.

mask = frequent_mask * rare_mask

temp_words = np.array(tf_idf.get_feature_names())[mask]

word_list = []

for word in temp_words:

word = re.sub("^(\d+\w*$|_+)", "", word)

if len(word) != 0:

word_list.append(word)

print("Словарь до фильтрации: ", tf_idf.idf_.shape[0],

"\nСловарь после фильтрации: ", len(word_list))

stemmer = Mystem()

word_list.reverse()

voc = list({stemmer.lemmatize(word)[0] for word in word_list})

voc = {word : i for i,word in enumerate(voc)}

cv = CountVectorizer(stop_words=stopwords,

vocabulary=voc)

data = cv.fit_transform(texts)

lda = LDA(n_components = 60, max_iter=10, n_jobs=1, learning_method='batch', verbose=1)

lda.fit(data)

joblib.dump(lda, model_path+'lda.pkl')

joblib.dump(cv, model_path+'cv.pkl')

joblib.dump(tf_idf, model_path+'tf_idf.pkl')

return(lda, cv)

#3 классификация статей с помощью LDA

def text_topics(path, model_path):

import numpy as np

import pandas as pd

import pickle

from sklearn.externals import joblib

cv = joblib.load(model_path+'cv.pkl')

lda = joblib.load(model_path+'lda.pkl')

def predict_topic(text, cv=cv, lda=lda):

cv.input = 'content'

vectorized = cv.transform([text])

topics = lda.transform(vectorized)

topics = np.squeeze(topics, axis=0)

indexes = topics.argsort()[-2:][::-1]

return indexes

def df_lda(row):

row['t1'], row['t2'] = predict_topic(row['text'])

return row

texts = pd.read_csv(path+'texts.csv')

texts.dropna(inplace = True)

texts['t1'],texts['t2'] = '',''

texts = texts.apply(df_lda, axis=1)

texts.drop('text',axis=1,inplace=True)

texts['published_at'] = pd.to_datetime(texts['published_at']).dt.date

texts.to_csv(path+'text_topics.csv',index=False)

def create_user_matrix(path):

import sqlalchemy

from scipy.spatial import distance

import numba as nb

import pandas as pd

import numpy as np

def top_10_similar(row):

row = pd.Series(row.sort_values(ascending = False)[1:11].index)

return row

def to_matrix(data):

#Функция приводит списки прочитанных статей юзерами к одной длинне

n = len(data)

lengths = np.array([len(i) for i in data]) # Количество статей у каждого user

matrix = np.zeros((n, max(lengths)), dtype=int) # Создаём списков из n списков, по max_len из нулей

for i in range(n):

matrix[i, :lengths[i]] = data[i] #заполняем список данными оставшиеся места остаются нулями

return matrix, lengths

@nb.jit(nopython=True, cache=True)

def jaccard_ind(user1, user2, matrix, lengths):

user1, user2 = user1[0], user2[0]

intersection = 0

if(matrix[user2][:lengths[user2]][-1] > matrix[user1][:lengths[user1]][-1]):

user1, user2 = user2, user1

i=0

j=0

while j<lengths[user2]:

if matrix[user1][i] == matrix[user2][j]:

i+=1

j+=1

intersection+=1

elif matrix[user1][i] < matrix[user2][j]:

i+=1

else:

j+=1

union=lengths[user1]+lengths[user2]-intersection

jaccard = intersection/union

return jaccard

def get_distances(df):

users_encode, user = pd.factorize(df["user_id"])

docs_encode, docs = pd.factorize(df["doc_id"])

docs_in_user = [np.unique(docs_encode[users_encode==x]) for x in range(len(user))]

matrix, lengths = to_matrix(docs_in_user)

_user = np.arange(len(user))[:, np.newaxis] #Добавляем новое измерение (n,) -> (n,1) (column vector)

distances = distance.cdist(_user, _user, jaccard_ind, matrix=matrix, lengths=lengths)

distances = pd.DataFrame(distances, columns=user, index=user)

return distances

query = #здесь запрос к бд статей прочитанных за последний месяц по пользователям

user_list = users.groupby('user_id').count()

user_list = user_list[user_list['doc_id']>=15]

users = users[users['user_id'].isin(user_list.index)]

distances = get_distances(users)

top_10 = distances.apply(top_10_similar, axis=1)

pd.DataFrame(top_10).to_csv(path+'matrix.csv')

def user_topics(path):

#Создание топа топиков для каждого из юзеров

import sqlalchemy

import collections

import numpy as np

import pandas as pd

def to_matrix(data):

n = len(data)

lengths = np.array([len(i) for i in data])

matrix = np.full((n, max(lengths)), fill_value=99, dtype=int)

for i in range(n):

matrix[i, :lengths[i]] = data[i]

return matrix

text_topics = pd.read_csv(path+'text_topics.csv')

matrix = pd.read_csv(path+'matrix.csv', index_col = 0)

#определение top 10 topic для юзеров из матрицы

users = #здесь запрос из БД 10 самых популярных статей у бользователя

user_topics = []

for user_id in matrix.index:

doc_ids = users[users['user_id']==user_id].doc_id.values

temp_topics = text_topics[text_topics['doc_id'].isin(doc_ids)][['t1','t2']].values.flatten()

user_words = np.array([x[0] for x in collections.Counter(temp_topics).most_common(10)], dtype=int)

user_topics.append(np.hstack([user_id, user_words]))

user_topics = to_matrix(user_topics)

user_topics = pd.DataFrame(user_topics)

user_topics.to_csv(path+'user_topics.csv', index=False)

def reccomendation_matrix(path):

import pandas as pd

import sqlalchemy

import numba as nb

import numpy as np

from sklearn.preprocessing import MinMaxScaler

matrix = pd.read_csv(path+'matrix.csv', index_col=0)

users = matrix.index.values

text_topics = pd.read_csv(path+'text_topics.csv')

user_topics = pd.read_csv(path+'user_topics.csv', index_col=0)

def get_score(row, user_topics, user_id):

score = 0

t1 = 0

t2 = 0

if row['t1'] in user_topics.loc[user_id].values:

t1 = 11 - user_topics.loc[user_id][user_topics.loc[user_id]==row['t1']].index.values.astype(int)[0]

if row['t2'] in user_topics.loc[user_id].values:

t1 = 11 - user_topics.loc[user_id][user_topics.loc[user_id]==row['t2']].index.values.astype(int)[0]

row['score'] = t1*0.6+t2*0.45+row['user_id']

return row

query = #здесь запрос к бд

top15 = pd.merge(text_topics,user_docs, on = 'doc_id', how='inner')

top15 = top15.groupby('doc_id')['user_id'].count().reset_index().sort_values('user_id',

ascending = False)[:15]

top15['user_id']=0

top15 = top15.set_index('doc_id')

top15_docid = top15.index.values

query = #здесь запрос к бд

top15_arr = pd.read_sql_query(query, con = snipe)

top15_arr.to_csv(path+'top15.csv', index=False)

#версия с Pandas

def build_reccomendation(users,user_docs, user_topics, text_topics, matrix, top15): arr =np.empty(shape = (0,16), dtype=int)

for user_id in users:

#Похожие юзеры

su = matrix.loc[user_id].values

#Статьи прочитанные пользователем

ud = user_docs[user_docs['user_id'] == user_id].doc_id.values

docs = user_docs[(~user_docs['doc_id'].isin(ud)) & (user_docs['user_id'].isin(su))].groupby('doc_id').count()

merged = pd.merge(text_topics,docs, on = 'doc_id', how='inner')

if len(merged)<15:

docs = pd.concat([docs,top15])

merged = pd.merge(text_topics,docs, on = 'doc_id', how='inner')

min_max_scalar = MinMaxScaler([1,10])

erged['user_id']=min_max_scalar.fit_transform(merged['user_id'].values.reshape(-1,1)) score = merged.apply(get_score,user_topics=user_topics,user_id = user_id,axis=1)

score = score.sort_values('score', ascending=False)[:15]

arr = np.vstack([arr,np.hstack([user_id, score['doc_id'].values])])

return arr

import numba as nb

#версия с numba

@nb.jit

def build_reccomendation2(users,user_docs, user_topics, text_topics, matrix, top15):

matrix_indexes = matrix.index.values

matrix_arr = matrix.values

#top15 = top15['user_id'].values

top15_values_doc_id = top15.index.values

user_docs_user_id = user_docs['user_id'].values

user_docs_doc_id = user_docs['doc_id'].values

text_topics_topics = text_topics.drop(['published_at', 'doc_id'],axis=1).values

text_topics_doc_id = text_topics['doc_id'].values

arr =np.empty(shape = (0,16), dtype=int)

for user_id in users:

#Похожие юзеры

su = matrix_arr[np.where(matrix_indexes==user_id)][0]

#Статьи прочитанные пользователем

ud = user_docs_doc_id[np.where(user_docs_user_id==user_id)]

docs = user_docs_doc_id[np.where(np.isin(user_docs_user_id, su))]

docs = docs[~np.isin(docs, ud)]

docs, docs_counts = np.unique(docs, return_counts=True)

#docs = pd.DataFrame({'doc_id':docs, 'user_id':docs_counts})

merged_docs_counts = docs_counts[np.isin(docs,text_topics_doc_id)]

merged_docs = docs[np.isin(docs,text_topics_doc_id)]

merged_topics = text_topics_topics[np.isin(text_topics_doc_id, merged_docs)]

merged = np.append(merged_topics, merged_docs_counts[:, np.newaxis], axis=1)

if len(merged)<15:

docs = np.append(docs, top15_values_doc_id)

docs_counts = np.append(docs_counts, top15_values)

merged_docs_counts = docs_counts[np.isin(docs,text_topics_doc_id)]

merged_docs = docs[np.isin(docs,text_topics_doc_id)]

merged_topics = text_topics_topics[np.isin(text_topics_doc_id, merged_docs)]

merged = np.append(merged_topics, merged_docs_counts[:, np.newaxis], axis=1)

merged = pd.DataFrame({'t1':merged[:,0],

't2':merged[:,1],

'user_id':merged[:,2],

'doc_id':merged_docs},dtype=int)

score = merged.apply(get_score,user_topics=user_topics,user_id = user_id,axis=1)

score = score.sort_values('score', ascending=False)[:15].astype(int)

arr = np.vstack([arr,np.hstack([user_id, score['doc_id'].values])])

return arr.astype(int)

arr = build_reccomendation2(users,user_docs, user_topics, text_topics, matrix, top15)

pd.DataFrame(arr).to_csv(path+'arr.csv', index=False)

def get_title_href(path):

import pandas as pd

import numpy as np

import sqlalchemy

arr = pd.read_csv(path+'arr.csv',index_col=0)

uniq_docs = set(arr.values.flatten())

query = #здесь запрос к бд

out.to_csv(path+'title_url.csv', index=False)

def replace_files(path, app_path):

import pandas as pd

arr = pd.read_csv(path+'arr.csv', index_col = False)

title_url = pd.read_csv(path+'title_url.csv', index_col = False)

top15 = pd.read_csv(path+'top15.csv', index_col = False)

arr.to_csv(app_path+'arr.csv', index = False)

title_url.to_csv(app_path+'title_url.csv', index = False)

top15.to_csv(app_path+'top15.csv', index = False)

Размещено на Allbest.ru

...

Подобные документы

  • Совершенствование технологий записи и хранения данных. Специфика современных требований к переработке информационных данных. Концепция шаблонов, отражающих фрагменты многоаспектных взаимоотношений в данных в основе современной технологии Data Mining.

    контрольная работа [565,6 K], добавлен 02.09.2010

  • Проблемы оценки клиентской базы. Big Data, направления использования. Организация корпоративного хранилища данных. ER-модель для сайта оценки книг на РСУБД DB2. Облачные технологии, поддерживающие рост рынка Big Data в информационных технологиях.

    презентация [3,9 M], добавлен 17.02.2016

  • Описание функциональных возможностей технологии Data Mining как процессов обнаружения неизвестных данных. Изучение систем вывода ассоциативных правил и механизмов нейросетевых алгоритмов. Описание алгоритмов кластеризации и сфер применения Data Mining.

    контрольная работа [208,4 K], добавлен 14.06.2013

  • Основы для проведения кластеризации. Использование Data Mining как способа "обнаружения знаний в базах данных". Выбор алгоритмов кластеризации. Получение данных из хранилища базы данных дистанционного практикума. Кластеризация студентов и задач.

    курсовая работа [728,4 K], добавлен 10.07.2017

  • Классификация задач DataMining. Создание отчетов и итогов. Возможности Data Miner в Statistica. Задача классификации, кластеризации и регрессии. Средства анализа Statistica Data Miner. Суть задачи поиск ассоциативных правил. Анализ предикторов выживания.

    курсовая работа [3,2 M], добавлен 19.05.2011

  • Data mining, developmental history of data mining and knowledge discovery. Technological elements and methods of data mining. Steps in knowledge discovery. Change and deviation detection. Related disciplines, information retrieval and text extraction.

    доклад [25,3 K], добавлен 16.06.2012

  • Изучение возможностей AllFusion ERwin Data Modeler и проектирование реляционной базы данных (БД) "Санатория" на основе методологии IDEF1x. Определение предметной области, основных сущностей базы, их первичных ключей и атрибутов и связи между ними.

    лабораторная работа [197,5 K], добавлен 10.11.2009

  • Анализ проблем, возникающих при применении методов и алгоритмов кластеризации. Основные алгоритмы разбиения на кластеры. Программа RapidMiner как среда для машинного обучения и анализа данных. Оценка качества кластеризации с помощью методов Data Mining.

    курсовая работа [3,9 M], добавлен 22.10.2012

  • Понятие информационных систем и принципы их проектирования. Изучение различных методов извлечения знаний, построение оптимальной информационной системы Data Mining, позволяющей разбивать набор данных, представленных реляционными базами данных на кластеры.

    аттестационная работа [4,7 M], добавлен 14.06.2010

  • A database is a store where information is kept in an organized way. Data structures consist of pointers, strings, arrays, stacks, static and dynamic data structures. A list is a set of data items stored in some order. Methods of construction of a trees.

    топик [19,0 K], добавлен 29.06.2009

  • Перспективные направления анализа данных: анализ текстовой информации, интеллектуальный анализ данных. Анализ структурированной информации, хранящейся в базах данных. Процесс анализа текстовых документов. Особенности предварительной обработки данных.

    реферат [443,2 K], добавлен 13.02.2014

  • Роль информации в мире. Теоретические основы анализа Big Data. Задачи, решаемые методами Data Mining. Выбор способа кластеризации и деления объектов на группы. Выявление однородных по местоположению точек. Построение магического квадранта провайдеров.

    дипломная работа [2,5 M], добавлен 01.07.2017

  • Информатика как наука о способах получения, накопления, хранения, преобразования, передачи и использования информации. История возникновения информатики. Первая программа обучения с получением степени Computer Science. Основные свойства информации.

    презентация [960,5 K], добавлен 09.12.2013

  • Історія виникнення комерційних додатків для комп'ютеризації повсякденних ділових операцій. Загальні відомості про сховища даних, їх основні характеристики. Класифікація сховищ інформації, компоненти їх архітектури, технології та засоби використання.

    реферат [373,9 K], добавлен 10.09.2014

  • Изучение методов разработки систем управления на основе аппарата нечеткой логики и нейронных сетей. Емкость с двумя клапанами с целью установки заданного уровня жидкости и построение нескольких типов регуляторов. Проведение сравнительного анализа.

    курсовая работа [322,5 K], добавлен 14.03.2009

  • Определение программы управления корпоративными данными, ее цели и предпосылки внедрения. Обеспечение качества данных. Использование аналитических инструментов на базе технологий Big Data и Smart Data. Фреймворк управления корпоративными данными.

    курсовая работа [913,0 K], добавлен 24.08.2017

  • Применение нейрокомпьютеров на российском финансовом рынке. Прогнозирование временных рядов на основе нейросетевых методов обработки. Определение курсов облигаций и акций предприятий. Применение нейронных сетей к задачам анализа биржевой деятельности.

    курсовая работа [527,2 K], добавлен 28.05.2009

  • Алгоритмы кластеризации данных, отбора факторов, построения множественной линейной регрессии, оценки параметров процесса на скользящем постоянном интервале. Решение задач анализа данных на нейронных сетях и результаты моделирования нелинейных функций.

    контрольная работа [1,5 M], добавлен 11.01.2016

  • Резервные базы данных под управлением Oracle Data Guard. Создание физической резервной базы. Защита резервных копий баз данных и базы данных разработчиков. Восстановление базы данных на удаленной машине. Стратегия резервирования и восстановления.

    дипломная работа [499,7 K], добавлен 04.06.2013

  • Разработка информационной системы управления, ориентированной на учет закупленного товара, работу с историческими данными компании и анализ данных для принятия стратегически верных решений. Хранилище данных в 3NF Билла Инмона. Компоненты Data Vault.

    дипломная работа [3,6 M], добавлен 22.09.2016

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.