Previsão de demanda de anúncios com o Catboost & LightGBM

Prever demanda para um anúncio classificado on-line, engenharia de recursos

Susan Li Blocked Desbloquear Seguir Seguindo 30 de dezembro

Avito.ru é um site de anúncios classificados russo com seções dedicadas ao bem geral para venda, empregos, imóveis, personals, carros para venda e serviços .

É o site de classificados mais popular da Rússia e é o terceiro maior site de classificados do mundo depois do Craigslist e do website chinês 58.com. Em dezembro de 2016, contava com mais de 35 milhões de visitantes únicos mensais. Em média, os usuários do Avito.ru postam mais de 500.000 novos anúncios por dia e os anúncios em geral são cerca de 30 milhões de anúncios ativos .

Gostaríamos de ajudar a Avito.ru a prever a demanda por um anúncio on-line com base em seus recursos, como categoria, título, imagem, seu contexto (geograficamente, onde foi publicado) e histórico de demanda por anúncios semelhantes em contextos semelhantes. Com essas informações, a Avito pode informar seus vendedores sobre a melhor forma de otimizar sua listagem e fornecer alguma indicação de quanto interesse eles devem esperar receber de forma realista.

Os dados

Os dados de treinamento contêm os seguintes recursos:

  • item_id – ID do anúncio.
  • user_id – ID do usuário.
  • regionregion anúncios.
  • citycity anúncio.
  • parent_category_name – categoria de anúncio de nível superior classificada pelo modelo de anúncio da Avito.
  • category_namecategory_name anúncio Fine grain classificada pelo modelo de anúncio da Avito.
  • param_1 – Parâmetro opcional do modelo de anúncios da Avito.
  • param_2 – Parâmetro opcional do modelo de anúncios da Avito.
  • param_3 – Parâmetro opcional do modelo de anúncios da Avito.
  • titletitle anúncio.
  • descriptiondescription anúncio.
  • priceprice anúncio.
  • item_seq_number – Número sequencial do anúncio para o usuário.
  • activation_date – O anúncio de data foi colocado.
  • user_type – tipo de usuário.
  • image – código de identificação da imagem. Gravatas para um arquivo jpg em train_jpg. Nem todo anúncio tem uma imagem.
  • image_top_1 – Código de classificação da Avito para a imagem.
  • deal_probability – A variável de destino. É a probabilidade de um anúncio realmente vender algo. O valor deste recurso pode ser qualquer flutuante de zero a um.
 df = pd.read_csv ('train_avito.csv', parse_dates = ['activation_date']) 
df.head ()

figura 1

Como deal_probability é nossa variável alvo, gostaríamos de examiná-la em mais detalhes.

 Importar seaborn como sns 
import matplotlib.pyplot como plt
pd.set_option (formato 'display.float_format', '{: .2f}'.)
plt.figure (figsize = (10, 4))
n, escaninhos, remendos = plt.hist (df ['deal_probability'], 100, facecolor = 'azul', alfa = 0,75)
plt.xlabel ('preço do anúncio')
plt.xlim (0, 1)
plt.title ('Histograma de probabilidade de negócio')
plt.show ();

Figura 2

 plt.figure (figsize = (10, 4)) 
plt.scatter (intervalo (df.shape [0]), np.sort (df ['deal_probability']. values))
plt.xlabel ('index')
plt.ylabel ('probabilidade de negócio')
plt.title ("Deal Probability Distribution")
plt.show ();

Figura 3

Quase um milhão de anúncios tem probabilidade 0, o que significa que não vendeu nada e poucos anúncios têm uma probabilidade de 1, o que significa que vendeu alguma coisa. Os outros anúncios têm uma probabilidade entre 0 e 1.

CatBoost

Desenvolvido por pesquisadores e engenheiros da Yandex , o CatBoost é um algoritmo de aprendizado de máquina que usa o aumento de gradiente em árvores de decisão. Está disponível como uma biblioteca de código aberto. Depois de ouvir muitas coisas boas sobre o CatBoost, devemos tentar.

Engenharia de recursos

Valores faltantes

A seguir, o número de valores ausentes nos recursos.

 null_value_stats = df.isnull (). sum () 
null_value_stats [null_value_stats! = 0]

Figura 4

Decidimos preencher esses valores omissos com -999, preenchendo valores ausentes de suas distribuições, o modelo seria capaz de distinguir facilmente entre eles e levá-lo em conta.

 df.fillna (-999, inplace = True) 

Recursos de data e hora

Criamos vários novos recursos de data e hora usando a coluna activation_date original antes de descartar essa coluna.

 df ['ano'] = df ['activation_date']. dt.ano 
df ['day_of_year'] = df ['activation_date']. dt.dayofyear
df ['dia da semana'] = f ['activation_date']. dt.weekday
df ['week_of_year'] = df ['activation_date']. dt.week
df ['day_of_month'] = df ['activation_date']. dt.day
df ['quarter'] = df ['activation_date']. dt.quarter
 df.drop ('activation_date', axis = 1, inplace = True) 

Nossos recursos são de tipos diferentes – alguns deles são numéricos, outros são categóricos e outros são texto, como title e description , e podemos tratar esses recursos de texto apenas como recursos categóricos.

 categorical = ['item_id', 'user_id', 'região', 'cidade', 'nome_da_categoria_criança', 'nome_da_categoria', 'param_1', 'parâmetro_2', 'parâmetro_3', 'título', 'descrição', 'item_seq_number' , 'user_type', 'image', 'image_top_1'] 

Não precisaremos codificar recursos categóricos. O CatBoost suporta recursos numéricos e categóricos. No entanto, precisamos identificar os índices de recursos categóricos.

 X = df.drop ('deal_probability', axis = 1) 
y = df.deal_probability
 def column_index (df, query_cols): 
cols = df.columns.values
sidx = np.argsort (cols)
return sidx [np.searchsorted (cols, query_cols, classificador = sidx)]
 categorical_features_indices = column_index (X, categórico) 

Treinamento do Modelo CatBoost

 X_train, X_valid, y_train, y_valid = train_test_split ( 
X, y, test_size = 0,25, random_state = 42)
 model = CatBoostRegressor (iterações = 50, profundidade = 3, learning_rate = 0.1, loss_function = 'RMSE') 
model.fit (X_train, y_train, cat_features = categorical_features_indices, eval_set = (X_valido, y_valido), plot = Verdadeiro);

Figura 6

Um modelo básico oferece uma solução justa e o erro de treinamento e teste está bastante sincronizado. Vamos tentar os parâmetros do modelo de ajuste, recursos para melhorar os resultados.

Ajuste do modelo CatBoost

  • iterations é o número máximo de árvores que podem ser construídas ao resolver problemas de aprendizado de máquina.
  • learning_rate é usado para reduzir o gradiente.
  • depth é a profundidade da árvore. Qualquer inteiro até 16 ao usar CPU.
  • Calculamos o RMSE como métrica.
  • bagging_temperature define as configurações do bootstrap bayesiano, quanto maior o valor, mais agressivo é o bagging. Nós não queremos isso alto.
  • Usaremos o detector de sobrecaptação, portanto, se ocorrer um overfitting, o CatBoost poderá interromper o treinamento antes do que os parâmetros de treinamento determinam. E o tipo do detector de overfitting é “Iter”.
  • metric_period é a frequência de iterações para calcular os valores de objetivos e métricas.
  • od_wait , considere o modelo od_wait e pare o treinamento após o número especificado de iterações (100) desde a iteração com o valor da métrica ideal.
  • eval_set é o conjunto de dados de validação para o overfitting do detector, a melhor seleção de iteração e as alterações nas métricas de monitoramento.
  • use_best_model=True se um conjunto de validação for inserido (o parâmetro eval_set é definido) e pelo menos um dos valores de rótulo dos objetos neste conjunto for diferente dos outros.

CatBoost.pyFigure 7

Importância do recurso CatBoost

 fea_imp = pd.DataFrame ({'imp': model.feature_importances_, 'col': X.columns}) 
fea_imp = fea_imp.sort_values (['imp', 'col'], ascendente = [Verdadeiro, Falso]). iloc [-30:]
fea_imp.plot (tipo = 'barh', x = 'col', y = 'imp', figsize = (10, 7), legenda = Nenhum)
plt.title ('CatBoost - Importância de recursos')
plt.ylabel ('Recursos')
plt.xlabel ('Importância');

Figura 8

Os resultados do ranking de importância do recurso CatBoost mostram que o atributo “preço” tem o impacto mais significativo na probabilidade de transação. Por outro lado, os recursos de data e hora têm impactos mínimos na probabilidade de transação.

LightGBM

O LightGBM é um framework impulsionador de gradiente rápido, distribuído e de alto desempenho baseado em algoritmos de árvore de decisão. Está sob o guarda-chuva do projeto DMTK da Microsoft.

Vamos treinar um modelo LightGBM para prever probabilidades de negociação. Passaremos pelo processo semelhante de engenharia de recursos, como fizemos quando treinamos o modelo CatBoost; além disso, também codificaremos recursos categóricos.

Engenharia de recursos

lightGBM_feature_engineering.py

Converta dados em formato de conjunto de dados LightGBM. Isso é obrigatório para o treinamento LightGBM.

 X_train, X_valid, y_train, y_valid = train_test_split ( 
X, y, test_size = 0,25, random_state = 42)

# Formatação do conjunto de dados LightGBM
lgtrain = lgb.Dataset (X_train, y_train,
feature_name = feature_names,
categorical_feature = categórico)
lgvalid = lgb.Dataset (X_valid, y_valid,
feature_name = feature_names,
categorical_feature = categórico)

Treinamento do modelo LightGBM

  • num_leaves é o principal parâmetro para controlar a complexidade do modelo de árvore. ao tentar ajustar o num_leaves , devemos deixá-lo menor que 2^(max_depth) (225).
  • Usamos max_depth para limitar a árvore profunda crescente.
  • para uma melhor precisão, nós somos pequenos learning_rate com grandes num_iterations .
  • Para acelerar o treinamento e lidar com overfitting, definimos feature_fraction=0.6 , ou seja, selecionando 60% dos recursos antes de treinar cada árvore.
  • Definir verbosity = -1 , a métrica de eval no conjunto de eval é impressa em cada estágio de aprimoramento detalhado.
  • early_stopping_rounds = 500 , o modelo treinará até que a pontuação de validação pare de melhorar. A pontuação de validação precisa melhorar pelo menos a cada 500 rodadas para continuar o treinamento.
  • verbose_eval = 500 , uma métrica de avaliação é impressa a cada 500 estágios de reforço.

lightGBM_model_training.pyFigura 8

Importância do recurso LightGBM

 fig, ax = plt.subplots (figsize = (10, 7)) 
lgb.plot_importance (lgb_clf, max_num_features = 30, ax = ax)
plt.title ("LightGBM - Importância do Recurso");

Figura 9

Não é surpreendente ver que o preço ainda está no topo. É interessante ver que item_seq_number tem o impacto mais significativo na probabilidade de transação no modelo lightGBM, no entanto, no modelo CatBoost, é apenas o 12º recurso.

Por hoje, o notebook Jupyter pode ser encontrado no Github . Feliz Ano Novo!

Referência: Kaggle