
Hoje, estamos lançando o Rekko Challenge 2019 , um concurso de aprendizado de máquina do cinema online Okko .
Sugerimos que você crie um sistema de recomendação com dados reais de um dos maiores cinemas online russos. Temos certeza de que essa tarefa será interessante tanto para iniciantes quanto para especialistas experientes. Tentamos manter o escopo máximo da criatividade, sem sobrecarregá-lo com conjuntos de dados de gigabytes com centenas de recursos pré-calculados.
Leia mais sobre Okko, a tarefa, dados, prêmios e regras - abaixo.
Desafio
Você tem acesso a dados de todas as exibições, classificações e acréscimos aos filmes e séries “Memorizados” pelo usuário por um período de N dias (N> 60), além de todas as meta-informações sobre o conteúdo. É necessário prever quais filmes e séries o usuário comprará ou assistirá por assinatura nos próximos 60 dias.
Na próxima seção, tentamos descrever o mínimo do que você precisa saber sobre cinemas on-line para entender rapidamente os dados e começar a analisá-los. Se essas informações não forem relevantes para você, você pode prosseguir imediatamente para a descrição dos dados .
Sobre o nosso serviço
Se um usuário deseja assistir legalmente a um filme na Internet, ele tem três maneiras principais.
A primeira maneira é assistir gratuitamente, interrompendo constantemente os comerciais ( AVOD , Advertising Video On Demand). O segundo é comprar um filme para sua coleção ou aluguel ( TVOD , Transactional Video On Demand). O terceiro é se inscrever por um determinado período ( SVOD , Subscription Video On Demand).
Okko funciona apenas nos modelos TVOD e SVOD. Não há publicidade alguma em nosso serviço.
No total, o serviço conta com pouco mais de 10 mil filmes e séries, cerca de 6 mil deles estão disponíveis por assinatura, o restante é apenas para compra ou aluguel. Ao mesmo tempo, quase qualquer conteúdo de assinatura pode ser comprado. Uma exceção é, por exemplo, os programas de TV da Amediateka , que podem ser assistidos apenas por assinatura.

De acordo com o modelo que o filme estará disponível, depende em grande parte do estúdio que detém os direitos. Eles concluem um contrato com os cinemas on-line, que estipula quando e por quais direitos o filme estará disponível. Como regra, as condições são as mesmas para todos os participantes do mercado, mas às vezes os estúdios fazem concessões a alguns cinemas ou oferecem condições mais favoráveis por mais dinheiro. Portanto, existem exclusivos.
Por exemplo, grandes inovações globais não entram na assinatura imediatamente, mas somente após 2-3 meses após a exibição no serviço. Além disso, nas primeiras semanas eles nem sequer podem ser alugados, apenas a oportunidade de comprar para sempre está disponível. Mas os filmes russos podem estar disponíveis por assinatura imediatamente após o lançamento e, às vezes, até simultaneamente com o início da locação nos cinemas offline.
Quando o contrato expira, o filme fica indisponível - até a extensão do contrato expirado ou a conclusão de um novo.

Períodos de falta de direitos ao conteúdo são claramente visíveis nos gráficos do número de visualizações. Abaixo, por exemplo, há um gráfico para o filme "John Wick 2". Primeiro de tudo, pode parecer que a confusão tenha descansado por alguns meses, mas não: os direitos acabaram.

O pico mais alto no gráfico acima (marcado com uma linha vertical) coincide com a data em que o filme foi adicionado à assinatura: esse é um comportamento muito característico para novidades de alto perfil. Nosso serviço tem 12 assinaturas:
- Oito temáticas
- Série de televisão Amediateka,
- Série de TV ABC,
- Filmes e séries russos do serviço START,
- Filmes em 4K.
E dois pacotes de assinatura: Optimal, que inclui todas as assinaturas temáticas, e Optimal + Amediateka.

Os mais populares, é claro, são os meta-pacotes. Das assinaturas temáticas, os usuários preferem World Cinema e Our Cinema.

Poucos usuários assistem a filmes apenas por assinatura, a maioria apenas compra filmes ou compra além da assinatura.
Na maioria das vezes, os usuários escolhem comprar novos itens para o aluguel atual e as principais estreias do ano passado.
A fonte mais popular de compras no aplicativo é a seção "Recomendações", seguida de "Pesquisa", "Notícias" e "Catálogo". Os usuários compram parte dos filmes de "Similar" e "Memorized".

Um dos principais problemas que estamos enfrentando ativamente na Okko é o problema dos usuários escolherem o conteúdo. Se você olhar para o gráfico da probabilidade de fazer uma compra versus o tempo gasto no serviço (dados do ano anterior), verá que os usuários estão prontos para escolher e comprar um filme nos primeiros 10 minutos, então a probabilidade de uma compra está caindo rapidamente. Ao mesmo tempo, permanece uma parte bastante grande de usuários que passam no serviço de meia hora a uma hora e não podem escolher o conteúdo adequado para si.
10 minutos - nem tanto. Durante esse período, o usuário não pôde estudar fisicamente o catálogo em detalhes e selecionar o conteúdo de que gosta.
É aqui que entra o Rekko, o sistema interno de recomendações para o cinema online Okko. Atualmente, a Rekko opera em duas seções do serviço - "Recomendações" e "Similar".


Para avaliar a satisfação do usuário com o conteúdo, analisamos o fato da compra, as visualizações por assinatura, o tempo de exibição e as classificações memorizadas e dos usuários.
A escala de classificação em Okko é representada por cinco asteriscos com meias divisões: leva valores inteiros de 0 a 10.

O usuário pode classificar o filme a qualquer momento, independentemente da compra ou visualização. A pontuação pode ser alterada um número ilimitado de vezes, mas não pode ser desfeita.
Você pode "lembrar" de um filme a qualquer momento e, em seguida, ele aparecerá no "lembrado" no perfil do usuário. Da mesma maneira, ele pode ser removido de lá.


O trabalho no Rekko começou há exatamente um ano e, de acordo com os testes A / B, nos permitiu aumentar o número médio de compras em 4%, a receita da transação em 3%, a conversão em assinatura em 5% e os usuários começaram a escolher filmes 18% mais rápido .

Dados
Todos os dados, exceto o tempo de exibição e as classificações, são anonimizados ou distorcidos. O tempo é expresso em unidades abstratas para as quais a relação de ordem e distância é preservada.
transaction.csv
Registros de todas as transações e visualizações de conteúdo nelas durante o período de treinamento. A transação aqui é a compra de um filme para sempre, para aluguel ou para iniciar a exibição por assinatura.
element_uid
- identificador do elementouser_uid
- ID do usuárioconsumption_mode
- tipo de consumo ( P
- compra, R
- aluguel, S
- visualizar por assinatura)ts
- tempo de transaçãowatched_time
- o número de segundos assistidos pelo usuário por essa transação segundosdevice_type
- tipo de dispositivo anônimo do qual a transação foi feitadevice_manufacturer
- fabricante anônimo do dispositivo a partir do qual a transação foi feita

ratings.csv
Informações sobre classificações de usuários para o período de treinamento. As informações são agregadas, ou seja, se o usuário alterou sua classificação, apenas o último valor será apresentado na tabela.
element_uid
- identificador do elementouser_uid
- ID do usuáriorating
- rating
definida pelo usuário (de 0
a 10
)ts
- hora do ranking

bookmarks.csv
Os fatos que os usuários adicionam um filme ao "lembrado". As informações são agregadas, ou seja, se o usuário excluiu o filme de "Salvo", não haverá registro de adicioná-lo à tabela.
element_uid
- identificador do elementouser_uid
- ID do usuáriots
- hora de adicionar o filme ao item "lembrado"
catalogue.json
Meta-informações sobre todos os elementos recomendados: filmes, séries e filmes em série.
{ "1983": { "type": "movie", "availability": ["purchase", "rent", "subscription"], "duration": 140, "feature_1": 1657223.396513469, "feature_2": 0.7536096584, "feature_3": 39, "feature_4": 1.1194091265, "feature_5": 0.0, "attributes": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...] }, "2166": { "type": "movie", "availability": ["purchase", "rent"], "duration": 110, "feature_1": 36764165.87817783, "feature_2": 0.7360206399, "feature_3": 11, "feature_4": 1.1386044027, "feature_5": 0.6547073468, "attributes": [16738, 13697, 1066, 1089, 7, 5318, 308, 54, 170, 33, ...] }, ... }
type
- pega os valores de movie
, movie
multipart_movie
ou series
duration
- a duração em minutos, arredondada para dezenas (a duração da série para séries e filmes em série)availability
- direitos disponíveis para o conteúdo (podem conter os valores de purchase
, rent
e subscription
)attributes
- um conjunto de alguns atributos anônimosfeature_1..5
- cinco materiais anônimos e recursos ordinais
Os direitos disponíveis são indicados no final do período de treinamento e no início do teste.
Importante: no json, as chaves do dicionário podem ser apenas cadeias de caracteres, portanto, lance-as para um número se você ler identificadores nas tabelas como números (faça isso para economizar memória).

Métrica
Como métrica, usamos Média Média de Precisão (MAP) para 20 elementos, mas ligeiramente modificada. Durante o período de teste, o usuário pode consumir menos de 20 filmes. Se neste caso considerarmos um MAP honesto, o limite superior da métrica será menor que um e os valores serão pequenos. Portanto, se o usuário consumiu menos de 20 elementos, normalizamos pelo número e não por 20.
- está localizado th predito elemento no conjunto de elementos consumidos durante o período de teste pelo usuário , É o tamanho deste conjunto. Se de repente as métricas de qualidade de classificação forem esquecidas, há um excelente artigo sobre elas no hub
Código métrico no Cython def average_precision( dict data_true, dict data_predicted, const unsigned long int k ) -> float: cdef: unsigned long int n_items_predicted unsigned long int n_items_true unsigned long int n_correct_items unsigned long int item_idx double average_precision_sum double precision set items_true list items_predicted if not data_true: raise ValueError('data_true is empty') average_precision_sum = 0.0 for key, items_true in data_true.items(): items_predicted = data_predicted.get(key, []) n_items_true = len(items_true) n_items_predicted = min(len(items_predicted), k) if n_items_true == 0 or n_items_predicted == 0: continue n_correct_items = 0 precision = 0.0 for item_idx in range(n_items_predicted): if items_predicted[item_idx] in items_true: n_correct_items += 1 precision += <double>n_correct_items / <double>(item_idx + 1) average_precision_sum += <double>precision / <double>min(n_items_true, k) return average_precision_sum / <double>len(data_true) def metric(true_data, predicted_data, k=20): true_data_set = {k: set(v) for k, v in true_data.items()} return average_precision(true_data_set, predicted_data, k=k)
Prêmios e regras
O fundo do prêmio é de 600 mil rublos:
- 300 mil receberão o vencedor,
- 200 mil - o participante em segundo lugar
- 100 mil - um participante em terceiro lugar.
As regras são padrão: não perturbe a plataforma, use apenas uma conta, evite a troca privada de códigos com outros participantes e não seja funcionário da Okko e da Rambler.
Como começar
Pode ser difícil até mesmo para profissionais experientes começarem a participar da competição: você precisa descobrir rapidamente uma nova área de domínio, entender e analisar dados e classificar novas bibliotecas.
Esperamos que, neste artigo, possamos mergulhá-lo no assunto do cinema on-line e descrever os dados com detalhes suficientes. No arquivo com a tarefa, você encontrará o arquivo baseline.ipynb
, que contém o código para carregar dados e um exemplo de solução simples usando o algoritmo K vizinhos mais próximos.
Se algum ponto da descrição dos dados e do domínio do domínio permanecer incerto, teremos o maior prazer em responder suas perguntas nos comentários. Você também pode fazer perguntas no canal de telegrama @boosterspro - a principal discussão da competição será realizada lá.
Então, como começar:
- Inscreva-se no boosters.pro e junte - se ao @boosterspro ;
- Faça o download dos dados na página da competição ou aqui ;
- Abra o
baseline.ipynb
, instale os pacotes necessários, execute todo o código e faça o download da sua primeira solução; - Tente modificar a linha de base para melhorar o desempenho;
- Experimente!
O Rekko Challenge começa hoje, 18 de fevereiro. As decisões são tomadas até 18 de abril, 23:59:59, horário de Moscou.
Estamos esperando por todos e boa sorte!
By the way, estamos à procura de funcionários . Incluindo o desenvolvedor de sistemas de recomendação.
UPD 26/02/2019: Foi encontrado um erro na formação dos dados de teste, eles foram substituídos e o arquivo test_users.json . Todos os participantes recebem tentativas adicionais.