Gerar recomendações usando o Apache Mahout no Azure HDInsight

Saiba como usar a biblioteca de aprendizado de máquina Apache Mahout com o Azure HDInsight para gerar recomendações de filmes.

Mahout é uma biblioteca de aprendizado de máquina para Apache Hadoop. Mahout contém algoritmos para processar dados, como filtragem, classificação e clustering. Neste artigo, você usa um mecanismo de recomendação para gerar recomendações de filmes baseados em filmes que seus amigos viram.

Pré-requisitos

Um cluster Apache Hadoop no HDInsight. Consulte Introdução ao HDInsight no Linux.

Compreender as recomendações

Uma das funções que é fornecida pelo Mahout é um motor de recomendação. Este mecanismo aceita dados no formato de userID, itemIde prefValue (a preferência pelo item). Mahout pode então realizar a análise de coocorrência para determinar: os usuários que têm preferência por um item também têm preferência por esses outros itens. Mahout então determina os usuários com preferências de itens semelhantes, que podem ser usados para fazer recomendações.

O fluxo de trabalho a seguir é um exemplo simplificado que usa dados de filme:

  • Coocorrência: Joe, Alice e Bob gostaram de Star Wars, O Império Contra-Ataca e O Retorno do Jedi. Mahout determina que os usuários que gostam de qualquer um desses filmes também gostam dos outros dois.

  • Coocorrência: Bob e Alice também gostaram de A Ameaça Fantasma, Ataque dos Clones e A Vingança dos Sith. Mahout determina que os usuários que gostaram dos três filmes anteriores também gostam desses três filmes.

  • Recomendação de similaridade: Como Joe gostou dos três primeiros filmes, Mahout olha para filmes que outros com preferências semelhantes gostaram, mas Joe não assistiu (curtiu/avaliou). Neste caso, Mahout recomenda A Ameaça Fantasma, Ataque dos Clones e A Vingança dos Sith.

Compreender os dados

Convenientemente, o GroupLens Research fornece dados de classificação para filmes em um formato compatível com o Mahout. Esses dados estão disponíveis no armazenamento padrão do cluster em /HdiSamples/HdiSamples/MahoutMovieData.

Há dois arquivos moviedb.txt e user-ratings.txt. O arquivo é usado durante a user-ratings.txt análise. O moviedb.txt é usado para fornecer informações de texto amigáveis ao visualizar os resultados.

Os dados contidos em user-ratings.txt tem uma estrutura de userID, , , e , movieIDuserRatingtimestampque indica o quão alto cada usuário classificou um filme. Aqui está um exemplo dos dados:

    196    242    3    881250949
    186    302    3    891717742
    22     377    1    878887116
    244    51     2    880606923
    166    346    1    886397596

Executar a análise

  1. Use o comando ssh para se conectar ao cluster. Edite o seguinte comando substituindo CLUSTERNAME pelo nome do cluster e digite o comando:

    ssh sshuser@CLUSTERNAME-ssh.azurehdinsight.net
    
  2. Use o seguinte comando para executar o trabalho de recomendação:

    mahout recommenditembased -s SIMILARITY_COOCCURRENCE -i /HdiSamples/HdiSamples/MahoutMovieData/user-ratings.txt -o /example/data/mahoutout --tempDir /temp/mahouttemp
    

Nota

O trabalho pode levar vários minutos para ser concluído e pode executar vários trabalhos do MapReduce.

Ver a saída

  1. Quando o trabalho for concluído, use o seguinte comando para exibir a saída gerada:

    hdfs dfs -text /example/data/mahoutout/part-r-00000
    

    A saída aparece da seguinte forma:

    1    [234:5.0,347:5.0,237:5.0,47:5.0,282:5.0,275:5.0,88:5.0,515:5.0,514:5.0,121:5.0]
    2    [282:5.0,210:5.0,237:5.0,234:5.0,347:5.0,121:5.0,258:5.0,515:5.0,462:5.0,79:5.0]
    3    [284:5.0,285:4.828125,508:4.7543354,845:4.75,319:4.705128,124:4.7045455,150:4.6938777,311:4.6769233,248:4.65625,272:4.649266]
    4    [690:5.0,12:5.0,234:5.0,275:5.0,121:5.0,255:5.0,237:5.0,895:5.0,282:5.0,117:5.0]
    

    A primeira coluna é a userID. Os valores contidos em '[' e ']' são movieId:recommendationScore.

  2. Você pode usar a saída, juntamente com o moviedb.txt, para fornecer mais informações sobre as recomendações. Primeiro, copie os arquivos localmente usando os seguintes comandos:

    hdfs dfs -get /example/data/mahoutout/part-r-00000 recommendations.txt
    hdfs dfs -get /HdiSamples/HdiSamples/MahoutMovieData/* .
    

    Este comando copia os dados de saída para um arquivo chamado recomendações.txt no diretório atual, juntamente com os arquivos de dados do filme.

  3. Use o seguinte comando para criar um script Python que procure nomes de filmes para os dados na saída de recomendações:

    nano show_recommendations.py
    

    Quando o editor abrir, use o seguinte texto como conteúdo do arquivo:

    #!/usr/bin/env python
    
    import sys
    
    if len(sys.argv) != 5:
         print "Arguments: userId userDataFilename movieFilename recommendationFilename"
         sys.exit(1)
    
    userId, userDataFilename, movieFilename, recommendationFilename = sys.argv[1:]
    
    print "Reading Movies Descriptions"
    movieFile = open(movieFilename)
    movieById = {}
    for line in movieFile:
        tokens = line.split("|")
        movieById[tokens[0]] = tokens[1:]
    movieFile.close()
    
    print "Reading Rated Movies"
    userDataFile = open(userDataFilename)
    ratedMovieIds = []
    for line in userDataFile:
        tokens = line.split("\t")
        if tokens[0] == userId:
            ratedMovieIds.append((tokens[1],tokens[2]))
    userDataFile.close()
    
    print "Reading Recommendations"
    recommendationFile = open(recommendationFilename)
    recommendations = []
    for line in recommendationFile:
        tokens = line.split("\t")
        if tokens[0] == userId:
            movieIdAndScores = tokens[1].strip("[]\n").split(",")
            recommendations = [ movieIdAndScore.split(":") for movieIdAndScore in movieIdAndScores ]
            break
    recommendationFile.close()
    
    print "Rated Movies"
    print "------------------------"
    for movieId, rating in ratedMovieIds:
        print "%s, rating=%s" % (movieById[movieId][0], rating)
    print "------------------------"
    
    print "Recommended Movies"
    print "------------------------"
    for movieId, score in recommendations:
        print "%s, score=%s" % (movieById[movieId][0], score)
    print "------------------------"
    

    Pressione Ctrl-X, Y e, finalmente , Enter para salvar os dados.

  4. Execute o script Python. O comando a seguir pressupõe que você esteja no diretório onde todos os arquivos foram baixados:

    python show_recommendations.py 4 user-ratings.txt moviedb.txt recommendations.txt
    

    Este comando analisa as recomendações geradas para o ID de utilizador 4.

    • O arquivo de classificações de usuário.txt é usado para recuperar filmes que foram classificados.

    • O arquivo moviedb.txt é usado para recuperar os nomes dos filmes.

    • As recomendações.txt é usado para recuperar as recomendações de filmes para este usuário.

      A saída deste comando é semelhante ao seguinte texto:

      Seven Years in Tibet (1997), score=5.0
      Indiana Jones and the Last Crusade (1989), score=5.0
      Jaws (1975), score=5.0
      Sense and Sensibility (1995), score=5.0
      Independence Day (ID4) (1996), score=5.0
      My Best Friend's Wedding (1997), score=5.0
      Jerry Maguire (1996), score=5.0
      Scream 2 (1997), score=5.0
      Time to Kill, A (1996), score=5.0
      

Excluir dados temporários

Os trabalhos do Mahout não removem dados temporários criados durante o processamento do trabalho. O --tempDir parâmetro é especificado no trabalho de exemplo para isolar os arquivos temporários em um caminho específico para facilitar a exclusão. Para remover os arquivos temporários, use o seguinte comando:

hdfs dfs -rm -f -r /temp/mahouttemp

Aviso

Se você quiser executar o comando novamente, você também deve excluir o diretório de saída. Use o seguinte para excluir este diretório:

hdfs dfs -rm -f -r /example/data/mahoutout

Próximos passos

Agora que você aprendeu a usar o Mahout, descubra outras maneiras de trabalhar com dados no HDInsight: