Инструменты и методы 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.2011Data 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.2010A 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