【问题标题】:Recommending Movie with java用java推荐电影
【发布时间】:2019-04-10 23:31:41
【问题描述】:

我正在制作一个程序,可以根据用户之前看过的电影(存储在数据库中)向用户推荐一些新电影。在这种情况下,我考虑了过去电影的类型,然后将其用于查找新电影(具有相似类型)。我现在遇到的问题是实现算法,这是我到目前为止的代码

MovieWatchedDao.java

public Movie recommendMovie(String username) throws DaoException {

        Connection con = null;
        PreparedStatement ps = null;

        Movie m = null;
        String jsonStr = m.getGenre();
        String[] temp;
        String delimiter = ",";

        temp = jsonStr.split(delimiter);
        String genre = temp [0];
        String genre1 = temp [1];
        String genre2 = temp[2];

        try {
            String query = "SELECT * FROM MOVIES WHERE GENRE LIKE ? OR GENRE LIKE ? OR GENRE LIKE ? ";
            ps = con.prepareStatement(query);
            ps.setString(1, genre);
            ps.setString(2, genre1);
            ps.setString(3, genre2);
            ps.execute();

            System.out.println(query);
            System.out.println("Recommend movies");

        }catch (SQLException e)
        {
            throw new DaoException(e.getMessage());
        }

        return m;

    }

server.java

                    else if ("recommend".equals(command))
                    {
                        String username = tokens[1];
                        try {
                            Movie m = IMovieWatched.findMovieByUser(username);

                            //Get the genres
                            String jsonStr = m.getGenre();
//                          socketWriter.println(jsonStr);

                            String[] items = jsonStr.split(",");
                            List<String> itemList = Arrays.asList(items);
                            socketWriter.println(itemList);

                        }catch(DaoException e)
                        {
                            e.printStackTrace();
                        }
                    }

这里的想法是让用户输入 recommend tommy,算法将从数据库中取出 Tommy 看过的电影列表并收集这些电影的类型。然后,返回给用户 3 部相似类型的电影。

【问题讨论】:

  • 指定。您在实现类/接口/其他方面有什么困难?
  • 用语言来解释是相当复杂的。我的代码是根据存储在数据库中的用户名推荐电影(我有一个 watched 表,其中存储了用户名和电影 ID)。我还有一个单独的表格,专门用于存储所有电影数据的电影。
  • 我想从特定用户的观看表中获取电影 ID,假设电影 ID 为 55 的 Tommy。然后我从电影表中获取 ID 为 55 的电影并获取该电影的流派.
  • 最后,我想向 Tommy 推荐一份与他已经看过的电影类型相似的电影列表
  • 但是您的代码没有得到推荐的电影吗?还有什么要补充的?也许您需要将结果保存到类内部/外部的变量中。

标签: java


【解决方案1】:

如果我这样做,我会列出汤米看过的电影列表,然后通过计算汤米看过的每种类型的电影的数量来浏览列表。他看过最多的电影类型,然后我会从该类型的“数据库”中随机挑选 3 部电影。如果随机选择的电影在他的观看列表中,请选择另一部该类型的随机电影。当您选择了 3 部电影时,将电影归还。有多种方法可以做到这一点,我建议查找 Netflix 的算法来推荐电影以获得想法。

【讨论】:

  • 是的,这是我的计划,但实施起来非常混乱
【解决方案2】:

根据观看一部甚至两部特定电影,您不会对用户的电影喜欢不喜欢有太多了解。显然,您只能根据之前观看过的电影类型来推荐您的建议。您对数据库中的电影和用户观看的电影的信息越多,您的推荐就越准确。您不想仅根据流派提出所有建议,在我认为重要的事情中需要考虑很多事情:

Genre
Genre Type 
Lead Actor
Year Created
Rating (Rotten Tomatoes Critics Consensus)
Director
Run Time
Watch time
Other cast members
Distributed by

例如,假设用户观看了名为 壮志凌云 的电影(与汤姆克鲁斯一起)。这将是用户观看此热门电影之前之后的可能数据列表。

Data Field       Before              After
==========================================
Title            Top Gun             Top Gun
Genre            Action              
Genre Type       Military Drama               
Lead Actor       Tom Cruise          
Year Created     1986                
Rating           83%                 
Director         Tony Scott          
Run Time         110 Minutes         
Watch Time (In User Table)           105 Minutes
Other Members    Kelly McGillis,     
                 Tom Skerritt,       
                 Val Kilmer,         
                 Anthony Edwards     
Distributed by   Paramount Pictures  
Date Watched (In User Table Only)    April 10, 2019
Times Watched (In User Table Only)   1

Data Fields是数据库Movies表字段,Before是Movies表中的数据,After是数据库中的相关字段用户表。在上面的示例中,我们可以清楚地看到用户在 2019 年 4 月 10 日观看了名为“壮志凌云”的电影,并且基本上一直观看到片尾,这意味着他/她很可能喜欢这部电影。如果观看时间 = 运行时间,则用户有可能离开正在播放电影的媒体设备或在电影期间睡着了。如果表格显示电影被观看了两次,则可以通过比较观看时间来降低概率,并且可以显示用户喜欢这部电影的可能性更大。

每个人对他们喜欢的电影都有不同的品味,他们观看的电影越多,您可以跟踪的数据越多,那么您的推荐显然就越准确。

在这个特定的时刻,您希望保持简单,仅根据流派提出建议。首先,您需要维护一个用户数据库表,其中存储用户名和他们观看的电影名称,这些名称也包含在电影表中的数据库中:

用户表:

RowID        Long (Unique - AutoIncrement)
UserName     Text
UserID       Text
MovieName    Text
ReleaseDate  Date
DateWatched  Date
TimeStarted  Long
TimeEnded    Long

您现在需要在数据库中查询用户并检索他/她观看的所有电影:

String sql = "SELECT DISTINCT MovieName From UsersTable WHERE UserName = ?;"

将 ResultSet 放入字符串数组 (watchedMovies[])。现在查询数据库中的电影表以检索用户观看的电影的所有不同类型:

// This is just a quick example....
StringBuilder criteria = new StringBuilder();
for (int i = 0; i < watchedMovies.length; i++) {
    criteria.append("MovieName = '").append(watchedMovies[i]).append("'");
    if (i != (watchedMovies.length - 1)) {
        criteria.append(" OR ");
    }
}

sql = "SELECT Genre FROM MoviesTable WHERE " + criteria.toString() + ";"

再次,将来自上述查询结果集中的所有不同流派放入一个字符串数组 (watchedGenres[])。 找出最受关注的流派。使用以下方法从字符串数组中获取:

public static String mostFrequentElementInArray(String[] arr) {
    // Method returns the String element with highest frequency 

    // Create HashMap to store string elements and thier frequency 
    HashMap<String, Integer> hs = new HashMap<String, Integer>(); 

    // Iterate through array of strings 
    for (int i = 0; i < arr.length; i++) { 
        // If word already exist in HashMap then increase it's count by 1 
        if (hs.containsKey(arr[i])) { 
            hs.put(arr[i], hs.get(arr[i]) + 1); 
        } 
        // Otherwise add String element to HashMap 
        else { 
            hs.put(arr[i], 1); 
        } 
    } 

    // Create set to iterate over HashMap 
    Set<Map.Entry<String, Integer> > set = hs.entrySet(); 
    String key = ""; 
    int value = 0; 

    for (Map.Entry<String, Integer> me : set) { 
        // Check for String having highest frequency 
        if (me.getValue() > value) { 
            value = me.getValue(); 
            key = me.getKey(); 
        } 
    } 

    // Return String having highest frequency 
    return key; 
}

并使用此方法:

String recommendedGenre = mostFrequentElementInArray(watchedGenres);

现在您可以在数据库电影表中查询该特定类型的所有(或部分)电影:

sql = "SELECT * FROM MoviesTable WHERE Genre = '" + recommendedGenre + "';";

您想要的推荐有多准确取决于您存储的电影数据类型以及您在 WHERE 子句标准中使用的内容,例如:

sql = "SELECT * FROM MoviesTable WHERE Genre = '" + recommendedGenre + "' AND GenreType = 'Military Drama';";

如果这未能产生所需的结果数量,则将其降级为:

sql = "SELECT * FROM MoviesTable WHERE Genre = '" + recommendedGenre + "';";

将 ResultSet 放入字符串数组并将其显示给用户。如果您愿意,只需在 WHERE 子句中添加 AND 语句,即可对 Movies 表中的大多数字段执行此操作。您在 WHERE 子句中使用的标准越多,您的电影推荐就越准确。

用户观看的电影越多,数据库就越了解用户喜欢什么。最终可以确定用户只观看有汤姆克鲁斯的电影(出于某种未知原因)。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 2011-07-12
    • 1970-01-01
    • 2017-03-26
    • 2020-04-14
    • 1970-01-01
    相关资源
    最近更新 更多