Como aprendemos a recomendar filmes e por que você não deve confiar apenas nas classificações



Imagine que você deseja passar a noite assistindo a um filme, mas não sabe qual escolher. Os usuários do Yandex geralmente se encontram na mesma situação; portanto, nossa equipe desenvolve recomendações que podem ser encontradas no Search and Air. Parece que isso é complicado: recebemos classificações de usuários e, com a ajuda deles, treinamos o carro para encontrar filmes com probabilidade de dar 5 pontos, obtemos uma lista pronta de filmes. Mas essa abordagem não funciona. Por quê? É sobre isso que vou falar hoje.

Um pouco de história. Em 2006, a Netflix lançou o concurso de aprendizado de máquina do Prêmio Netflix. Se você se esqueceu de repente, a empresa ainda não está transmitindo na Internet, mas alugou filmes em DVD. Mas, mesmo assim, era importante para ela prever a classificação do usuário, a fim de recomendar algo a ele. Portanto, a essência da competição: prever as classificações dos espectadores é 10% melhor (de acordo com a métrica RMSE) que o Cinematch, o sistema de recomendação da Netflix. Essa foi uma das primeiras competições em massa desse tipo. O interesse aqueceu um enorme conjunto de dados (mais de 100 milhões de classificações), além de um prêmio de US $ 1 milhão.

A competição terminou em 2009. As equipes do Pragmatic Chaos da BellKor e do The Ensemble chegaram à linha de chegada com o mesmo resultado (RMSE = 0,8567), mas o The Ensemble ficou em segundo lugar porque enviou a solução 20 minutos depois dos concorrentes. Resultados e trabalho podem ser encontrados aqui . Mas a coisa mais interessante é diferente. Se você acredita nas histórias repetidas em conferências especializadas, os algoritmos vencedores não apareceram em produção no serviço de streaming de vídeo que foi lançado em breve. Não posso falar sobre os motivos das decisões de outras pessoas, mas vou lhe dizer por que fizemos o mesmo.

Classificação pessoal


Já há algum tempo, os usuários do Yandex podem classificar os filmes que assistiram. E não apenas no KinoPoisk, mas também nos resultados da pesquisa. Com o tempo, acumulamos centenas de milhões de estimativas de dezenas de milhões de pessoas. Em algum momento, decidimos usar esses dados para ajudar os usuários a entender o quanto eles gostariam de um filme. De fato, resolvemos o mesmo problema do concurso do Netflix, ou seja, previmos que classificação o usuário daria ao filme. Naquela época, as classificações KinoPoisk e IMDB já existiam, que foram construídas com base nas classificações das pessoas. Como construímos uma classificação pessoal, decidimos usar uma escala separada como uma porcentagem para evitar semelhanças visuais e confusão.



A propósito, a necessidade de correlacionar a escala de pontos e a porcentagem é uma dor de cabeça separada e não óbvia, por isso vou falar brevemente sobre isso. Parece que, para uma escala de 10 pontos, considere 10% para cada ponto - e o ponto está no chapéu. Mas não. A razão é psicologia e hábitos. Por exemplo, do ponto de vista dos usuários, uma classificação de 8/10 é muito melhor que 80%. Como correlacionar isso? Com crowdsourcing! E foi o que fizemos: lançamos a tarefa em Tolok, na qual os atiradores descreviam as expectativas dos filmes com uma certa pontuação ou porcentagem de classificação pessoal. Com base nessa marcação, selecionamos uma função que traduz a previsão da pontuação de ponto em porcentagem, para que as expectativas do usuário sejam mantidas.

Exemplo de missões em Tolok


Prever as expectativas do filme é útil, mas seria bom criar recomendações também. Ou seja, mostre imediatamente à pessoa uma lista de bons filmes. Nesse momento, muitos de vocês podem pensar: "E vamos classificar os filmes que o usuário não assistiu por classificação pessoal". Nós pensamos assim também no começo. Mas então eu tive que resolver dois problemas.

Problema da ferramenta


Quando um usuário procura um filme específico (ou deseja alugar um DVD específico), o serviço deve prever a classificação desse filme específico. Exatamente esse problema foi resolvido no concurso do Netflix, onde a métrica RMSE foi usada. Mas as recomendações resolvem um problema diferente: você não precisa adivinhar a nota, mas encontrar um filme que acabará sendo assistido. E a métrica RMSE faz um mau trabalho nisso. Por exemplo, a penalidade por prever uma classificação de 2 em vez de 1 é exatamente a mesma que para 5 em vez de 4. Mas nosso sistema nunca deve recomendar filmes nos quais o usuário coloca 2! As métricas baseadas em lista são muito mais adequadas para esta tarefa, como Precision @ K, Recall @ K, MRR ou NDCG. Não posso deixar de falar um pouco mais sobre eles (mas se você não estiver interessado nas métricas, pule o próximo parágrafo).

Vamos começar com a métrica.MRR (classificação recíproca média). Veremos em que posição no ranking será o filme com o qual o usuário interagiu (por exemplo, assistiu ou elogiou) no período de teste. A métrica MRR é a posição reversa média do usuário de um filme. I.eMRR=1|U|u=1|U|1ranku. Essa métrica, ao contrário do RMSE, avalia a lista inteira, mas, infelizmente, analisa apenas o primeiro elemento adivinhado. No entanto, é fácil modificar a métrica para se livrar dessa desvantagem. Podemos calcular a soma das posições inversas de todos os filmes com os quais o usuário interagiu. Essa métrica é chamada Classificação Média de Acertos Recíprocos. Essa métrica leva em consideração todos os filmes adivinhados na edição. Observe que a posição k no pagamento recebe um peso de 1 / k para um filme adivinhado e um peso de 0 para outro filme. Freqüentemente, 1 / log (k) é usado em vez de 1 / k: é mais provável que corresponda à probabilidade de o usuário rolar para a posição k. O resultado é uma métrica DCG (ganho cumulativo descontado)DCG=1|U|u=1|U|pos=1Ngainposmax(1,log(pos)). Mas a contribuição de diferentes usuários para a métrica é diferente: para alguém que adivinhou todos os filmes, para alguém que não adivinhou nada. Portanto, como regra, essa métrica é normalizada. Divida o DCG de cada usuário no DCG de melhor classificação para esse usuário. A métrica resultante é denominada NDCG (ganho cumulativo com desconto normalizado). É amplamente utilizado para avaliar a qualidade da classificação.

Portanto, cada tarefa tem sua própria métrica. Mas o próximo problema não é tão óbvio.

Problema de escolha


Já é difícil descrever, mas vou tentar. Acontece que as pessoas não dão notas altas aos filmes que costumam assistir. Obras-primas raras de filmes, clássicos e obras de arte obtêm as notas mais altas, mas isso não impede as pessoas à noite após o trabalho com prazer de assistir a uma boa comédia, um novo filme de ação ou uma espetacular ópera espacial. Acrescente a isso que os usuários do Yandex não gostaram de todos os filmes que já assistiram em algum lugar. E se focarmos apenas nas classificações mais altas, corremos o risco de obter um feed de filme recomendado que pareça lógico, os usuários podem até reconhecer sua qualidade, mas no final eles não assistirão a nada.

Por exemplo, é assim que meu feed de filmes pode parecer se o classificássemos por classificação pessoal e não sabíamos nada sobre minhas visualizações no passado. Ótimos filmes. Mas não quero revisá-los hoje.



Acontece que, nas condições de classificações dispersas e na escassez de filmes com classificações altas, vale a pena olhar não apenas para a classificação. Bem, então treinamos o carro para prever a exibição do filme recomendado, e não a classificação. Parece lógico, porque o usuário quer isso. O que poderia dar errado? O problema é que a fita será preenchida com filmes, cada um dos quais é bastante adequado para um passatempo fácil à noite, mas sua classificação pessoal será baixa. Os usuários, é claro, prestarão atenção ao fato de que não há "obras-primas" no feed, o que significa que a credibilidade das recomendações será prejudicada, e eles não assistirão ao que verão.

Como resultado, chegamos ao entendimento de que é necessário um equilíbrio entre os dois extremos. É necessário treinar a máquina para que sejam levados em consideração o potencial de visualização e a percepção da recomendação por uma pessoa.

Como nossas recomendações funcionam


Nosso sistema faz parte da Pesquisa, portanto, precisamos criar recomendações muito rapidamente: o tempo de resposta do serviço deve ser inferior a 100 milissegundos. Portanto, tentamos realizar o maior número possível de operações pesadas offline, no estágio de preparação dos dados. Todos os filmes e usuários no sistema de recomendação são representados por perfis (é importante não confundir com a conta), que incluem chaves de objetos, contadores e incorporação (em outras palavras, vetores em um determinado espaço). Perfis de filmes são preparados todos os dias no YT ( lidos como "Yt" ) e carregados na RAM de máquinas que respondem a solicitações. Mas com os usuários, tudo é um pouco mais complicado.

Todos os dias, também criamos o perfil principal do usuário no YT e o enviamos para a loja Yandex, a partir da qual você pode obter o perfil em algumas dezenas de milissegundos. Mas os dados ficam desatualizados rapidamente se uma pessoa assiste e avalia ativamente o vídeo. Não é bom se as recomendações começarem a ficar abaixo. Portanto, lemos o fluxo de eventos do usuário e formamos a parte dinâmica do perfil. Quando uma pessoa entra em uma solicitação, combinamos o perfil do repositório com um perfil dinâmico e obtemos um único perfil, que pode ficar para trás da realidade por apenas alguns segundos.

Isso acontece offline (ou seja, com antecedência) e agora vamos diretamente para o tempo de execução. Aqui, o sistema de recomendação consiste em duas etapas. A classificação de todo o banco de dados de filmes é muito longa; portanto, na primeira etapa, simplesmente selecionamos várias centenas de candidatos, ou seja, encontramos filmes que podem ser de interesse do espectador. Isso inclui pinturas populares e aquelas próximas ao usuário em alguns embeddings. Existem vários algoritmos para encontrar rapidamente os vizinhos mais próximos, usamos o HNSW (Hierarchical Navigable Small World). Com ele, encontramos os filmes mais próximos do usuário em apenas alguns milissegundos.

Na segunda etapa, extraímos recursos (às vezes também chamados de fatores) por filmes, pares de usuários e usuários / filmes e classificamos candidatos usando o CatBoost. Deixe-me lembrá-lo: já percebemos que precisamos nos concentrar não apenas nas visualizações, mas também em outras características de qualidade das recomendações, portanto, para a classificação, chegamos a uma combinação de vários modelos CatBoost treinados para vários objetivos.

Para encontrar candidatos, usamos incorporação de várias decomposições matriciais: da versão clássica do ALS, que prevê a avaliação, a variações mais complexas baseadas no SVD ++. Como recursos para classificação, são utilizados contadores e filmes simples de eventos do usuário, CTRs para vários eventos, bem como modelos pré-treinados mais complexos. Por exemplo, a previsão do ALS também atua como um recurso. Um dos modelos mais úteis é a rede neural DSSM do Recomendador, da qual provavelmente falarei um pouco mais.

Recomendador DSSM


DSSM é uma rede neural de duas torres. Cada torre constrói sua própria incorporação, então a distância do cosseno é considerada entre as incorporações, esse número é a saída da rede. Ou seja, a rede aprende a avaliar a proximidade de objetos nas torres esquerda e direita. Redes neurais semelhantes são usadas, por exemplo, em uma pesquisa na web para encontrar documentos relevantes para uma consulta. Para a tarefa de pesquisa, uma solicitação é enviada para uma das torres e um documento para a outra. Para nossa rede, o papel da solicitação é desempenhado pelo usuário, e os filmes atuam como documentos.

A torre do filme constrói a incorporação com base nos dados do filme: este é o título, descrição, gênero, país, atores etc. Essa parte da rede é bastante semelhante à da pesquisa. No entanto, para o espectador, queremos usar a história dele. Para isso, agregamos a incorporação de filmes da história com o desaparecimento do tempo desde o momento do evento. Em seguida, além da incorporação total, aplicamos várias camadas da rede e, como resultado, obtemos uma incorporação de tamanho 400.



Se você considerar imediatamente todo o histórico do usuário na incorporação, isso reduzirá bastante o treinamento. Portanto, vamos ao truque e aprendemos a rede em duas etapas. Primeiro, aprenda o InnerDSSM mais simples. Na entrada, ele recebe apenas os últimos 50 eventos da história do usuário, sem se dividir em tipos de eventos (visualizações, classificações ...). Em seguida, treinamos novamente o InnerDSSM resultante ao longo do histórico do usuário, mas detalhando os tipos de eventos. Então, obtemos o OuterDSSM, que é usado em tempo de execução.

Usar uma rede de tempo de execução na testa requer muitos recursos de computação. Portanto, salvamos os incorporações da torre de filmes no banco de dados, e os casamentos de acordo com o histórico do usuário são atualizados quase em tempo real. Assim, durante o processamento da solicitação, você precisa aplicar apenas uma pequena parte do OuterDSSM e calcular os cossenos, isso não leva muito tempo.

Conclusão


Agora, nossas recomendações já estão disponíveis em nossa pesquisa (por exemplo, mediante solicitação [o que ver] ), no serviço Yandex.Air, e uma versão adaptada dessa tecnologia também é usada no Yandex.Stations. Mas isso não significa que possamos relaxar. Treinamos constantemente novos modelos, aplicamos mais e mais dados, tentamos novas abordagens de treinamento e novas métricas de qualidade. Na minha opinião, quanto mais antiga a área, mais difícil é se desenvolver. Mas este é o principal interesse dos especialistas.

All Articles