"Построение рекомендательной системы на python"...

22
Построение рекомендательной системы на Python Python Data Science meetup @ Avito Лексин Василий 13 августа 2016 г. 0

Upload: avitotech

Post on 16-Jan-2017

384 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Построение рекомендательнойсистемы на PythonPython Data Science meetup @ Avito

Лексин Василий

13 августа 2016 г.

0

Page 2: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

План презентацииВыгрузка данных

Типы данных

Выгрузка данных из хранилища

Предобработка данных

Фильтрация данных

Предобработка поисковых запросов

Обучение модели

Параметры модели и обучение

Оценка качества модели

1

Page 3: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Типы данныхДанные по пользователям

Профиль интересов по категориям и регион

Согласен ли получать рекомендации

Данные по объявлениям

Микрокатегория

Местоположение

Действия пользователей

Items search, item view

Item view phone, item send message

Favorites item add

2

Page 4: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Выгрузка данных изхранилища (SQL)

Один месяц click stream

Фильтруем офисные IP

Фильтруем ботов (ноу хау)

Только посление сессии от каждого пользователя

От каждой сессии берем максимум случайных событий

каждого типа

Привязываем действия от неавторизованных

пользователей к user_id

Отдельно выгружаем поисковые запросы

Ns

Ne

2 - 1

Page 5: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Статистика по выгруженнымданным

853M событий

13M пользователей

32M объявлений

77M поисковых запросов

4M уникальных текстов запросов

2 - 2

Page 6: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

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

3

Page 7: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Пример поисковых запросовIn [73]:

Out[73]: ext_user_id microcat_id location_id searchquery_id

110046 -6474078695648370021 2744 3960 NaN

528990 3115636 2679 1344 9955361

770905 90352811 1776 3953 8285511

1081196 79333327 3718 2142 2608148

473135 29970120 5779 1344 NaN

3099378 -5360608040238233550 5250 3856 NaN

665866 24882994 259 1261 NaN

1368309 3202041 3718 2885 NaN

1659277 89384896 1989 3953 12435410

1841537 13939317 66 1261 NaN

import pandas as pd df_queries.sample(10)

4

Page 8: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Пример текстов запросовIn [81]:

Out[81]: searchquery_id query

128240 59238250342 кожаный кошклек

139772 234299750143 batyka

18635 4411625 медсестра

202708 1040250002 кукла новая испания

149424 234267250442 детские вещи емле

214063 233309500285 зимний комбинезон мальчикучика 86-92

51753 5599527 tally weijl

6267 6729157 туфли 39

69994 133827 плащ пиджак

39963 1008632 doctor e

df_searchquery.sample(10)

4 - 1

Page 9: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Пример лога событийIn [87]:

Out[87]: ext_user_id ext_item_id

0 269878 778223165

1 269878 820358781

2 269878 804777863

3 93940783 602550035

4 93940783 793828222

5 93940783 811076220

6 93940783 651115689

7 93940783 211688068

8 93940783 807188069

9 93940783 762847248

df_data.sample(10)

4 - 2

Page 10: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Нормализация текстаIn [ ]:

In [ ]:

from nltk.corpus import stopwords as swimport pymorphy2import restopwords= set(sw.words("russian"))

morph = pymorphy2.MorphAnalyzer()token_pattern = re.compile(r'\b[\w\.\/]+\b')tokenize = lambda doc: token_pattern.findall(doc) badlist = set(['отличный', 'идеальный', 'состояние', 'продажа', 'продавать', 'обменять', 'москва', 'продать', 'хороший', 'продаваться', 'супер']) def get_tokens(line): cur_line = tokenize(line) normalized_tokens = [morph.parse(x)[0].normal_form for x in cur_line] filtered_tokens = [token for token in normalized_tokens if not token in badlist and not token in stopwords] return filtered_tokens

5

Page 11: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Параллельная обработкаIn [1]:

In [24]:

. . .

from multiprocessing import Pool

pool = Pool()df_searchquery['norm_query'] = pool.map(get_tokens, df_searchquery['query'].values)pool.terminate()

5 - 1

Page 12: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Биграммы, фильтрацияIn [2]:

In [25]:

In [78]:

. . .

. . .

. . .

from gensim.models.phrases import Phrasesfrom gensim.corpora import Dictionary

bigram_transformer = Phrases(df_searchquery['norm_query'].values)df_searchquery['norm_query'] = [bigram_transformer[q] for q in df_searchquery['norm_query']]

id2word = Dictionary(df_searchquery['norm_query'].values)id2word.filter_extremes(no_below=5) df_searchquery['norm_query'] = [[w for w in q if w in id2word.token2id] for q in df_searchquery['norm_query']]

6

Page 13: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Пример нормализованных запросовIn [88]:

Out[88]: searchquery_id query norm_query

11363 40583250271 куртка на осень стильная [куртка, осень, стильный]

30231 8776934 памперсы меррис [памперс]

89102 6296057 stig []

102222 13296939 пакетом 2-3 [пакет, 2_3]

33406 5522081 casadei балетки [casadei, балетки]

194946 234467250136 комбенизон reima ноаые [комбенизон, reima, ноаый]

42300 2691799 пастельное белье детское [пастельный_бельё, детский]

108060 136389 ecco демисезон [ecco, демисезон]

82151 5960365 кукла германия [кукла, германия]

92853 69941250025 на мальчика размер 80 [мальчик, размер, 80]

df_searchquery.sample(10)

6 - 1

Page 14: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Комбинация запроса смикрокатегорией

In [89]:

Out[89]: ext_user_id microcat_id location_id searchquery_id norm_query

2768669 79821794 2744 1403 NaN [2744:]

2716176 -3322596449809766062 3718 406 NaN [3718:]

2349895 930812 847 2187 NaN [847:]

3180239 -4757589830893039331 6232 4111 NaN [6232:]

2122630 46977773 6670 4499 NaN [6670:]

2023443 48879590 5250 2643 NaN [5250:]

1492290 87985326 7188 2885 NaN [7188:]

2452980 -8482002081938376691 5428 3960 2.339135e+11

[5428:lps,5428:петшоп,5428:литло_петь,5428:...

1795200 1431139 3718 3976 5.659923e+06 [3718:крокс_crocs]

951770 3471714 7382 3953 5.589893e+06 [7382:шуба_мутон]

df_queries.sample(10)

6 - 2

Page 15: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Признаки пользователяIn [90]:

Out[90]: ext_user_id norm_query location_id

723827 56908675 [7382:, 478:, 3718:, 1675:, 149:] [2430]

7962 -9019847421690666119[2744:сумка, 1860:, 5250:, 2744:женский,2744:...

[230]

1020309 95760508 [2744:стрип, 2744:] [992]

297934 -1603932776056930038 [5250:] [4181]

494505 11949033 [2868:, 4488:, 6875:, 4243:, 3478:, 5938:] [926]

150433 -5371442050781010156 [4814:] [3610]

552456 19578840 [6797:, 5513:] [3953]

223287 -3517260670980945043 [2744:] [2885]

811247 76406847 [259:bugaboo] [2885]

843402 80272837 [259:] [642, 44]

df_user_query.sample(10)

7

Page 16: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Фильтрация лога событийIn [ ]: import graphlab as gl

# Generate bipartite user-item graphg = gl.SGraph()g = g.add_edges(training_data, src_field='ext_user_id', dst_field='ext_item_id') k_value = 10 # Compute the N-core decomposition of the graphkc = gl.kcore.create(g, kmin=k_value-1, kmax=k_value) # Filtering eventstraining_filtered = g.get_neighborhood(kc.core_id.filter_by( k_value, 'core_id')['__id'], radius=0) training_filtered = gl.SFrame(training_filtered.edges).rename({ '__src_id': 'ext_user_id', '__dst_id': 'ext_item_id'})

8

Page 17: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Factorization Machine - общая идея

9

Page 18: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Factorization Machine - генеративнаямодель

- пользователь

- объявление

- global bias term

и - weight terms

и - side feature vectors

и - weight vectors for side features

и - latent factors

p(i, j) = μ + + + + + ,wi wj aTxi bTyj uTi vj

i

j

μ

wi wj

xi yj

a b

ui vj

9 - 1

Page 19: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Обучение моделиIn [67]:

. . .

(training_data, validation_data) = gl.recommender.util.random_split_by_user( gl.SFrame(df_data)) train_settings = dict( regularization=1e-07, linear_regularization=1e-07, side_data_factorization=True, num_factors=100, num_sampled_negative_examples=4, max_iterations=25) model_fr = gl.ranking_factorization_recommender.create( training_filtered, user_id = 'ext_user_id', item_id = 'ext_item_id', user_data=transformed_user_data, **train_settings)

9 - 2

Page 20: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Оценка качества моделиIn [77]:

cutoff precision recall1 0.022 0.0082 0.018 0.0103 0.016 0.0125 0.014 0.019

10 0.011 0.029

. . .

prec_rec_data = model_fr.evaluate_precision_recall(validation_data)

10

Page 21: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

Время обученияОдин сервер 56 потоков, 256 Гб

Сбор данных из хранилища ~1 часа

Предобработка данных ~30 минут

Обучение модели ~4 часов

11

Page 22: "Построение рекомендательной системы на Python" Василий Лексин (Avito)

РесурсыPython: http://www.python.org/ (http://www.python.org/)

IPython: http://ipython.org/ (http://ipython.org/)

Pandas: http://pandas.pydata.org/ (http://pandas.pydata.org/)

Gensim: https://radimrehurek.com/gensim/

(https://radimrehurek.com/gensim/)

GraphLab Create: https://turi.com/products/create/

(https://turi.com/products/create/)

12