#java
#java
Вопрос:
Я нахожусь в процессе создания программы, в которой пользователю могут быть рекомендованы некоторые новые фильмы на основе предыдущих просмотренных им фильмов (сохраненных в базе данных). В этом случае я принимаю во внимание жанр прошлого фильма, который затем используется для поиска новых фильмов (с аналогичным жанром). Проблема, с которой я сейчас сталкиваюсь, заключается в реализации алгоритма, вот код, который у меня есть до сих пор
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();
}
}
Идея здесь заключается в том, чтобы пользователь набрал «рекомендовать Томми«, и алгоритм возьмет список фильмов, которые Томми смотрел, из базы данных и соберет жанры этих фильмов. Затем возвращает пользователю 3 фильма с похожими жанрами.
Комментарии:
1. Укажите. Какие у вас проблемы с реализацией вашего класса / интерфейса / чего угодно?
2. Это довольно сложно объяснить словами. Код, который у меня есть, заключается в том, чтобы рекомендовать фильмы на основе имени пользователя, хранящегося в базе данных (там у меня есть просмотренная таблица, в которой хранится имя пользователя и идентификатор фильма). У меня также есть отдельная таблица специально для фильмов, в которой хранятся все данные фильмов.
3. Я хотел взять идентификатор фильма из просмотренной таблицы для определенного пользователя, скажем, Tommy с MovieID 55. Затем я получаю фильм с идентификатором 55 из таблицы movies и получаю жанры этого фильма.
4. Наконец, я хочу порекомендовать Томми со списком фильмов, жанры которых похожи на тот, который он уже смотрел
5. Но разве у вас нет рекомендуемых фильмов с вашим кодом? Что еще можно добавить? Возможно, вам нужно сохранить результаты в переменной внутри / вне класса.
Ответ №1:
Ну, если бы я делал это, я бы взял список фильмов, которые смотрел Томми, а затем просмотрел список, подсчитав, сколько фильмов в каждом жанре посмотрел Томми. Какой жанр фильма он смотрел больше всего, я бы тогда случайным образом выбрал 3 фильма из «базы данных» этого жанра. Если фильм, который был выбран случайным образом, находится в его списке просмотра, выберите другой случайный фильм этого жанра. Когда у вас будет выбрано 3 фильма, верните фильмы обратно. Вы можете сделать это несколькими способами, я рекомендую посмотреть алгоритм Netflix для рекомендации фильмов для идеи.
Комментарии:
1. Да, это мой план, но его очень сложно реализовать
Ответ №2:
Вы не получите много информации о том, нравится или не нравится фильм пользователям, основываясь на просмотре одного или даже двух конкретных фильмов. Очевидно, что вы можете основывать свои рекомендации только на том, какой тип или типы фильмов были просмотрены ранее. Чем больше у вас информации о ваших фильмах в базе данных и фильмах, просмотренных пользователем, тем точнее могут быть ваши рекомендации. Вы не хотите основывать все свои рекомендации только на одном жанре, есть много вещей, которые следует учитывать в том, что я считаю важным:
Genre
Genre Type
Lead Actor
Year Created
Rating (Rotten Tomatoes Critics Consensus)
Director
Run Time
Watch time
Other cast members
Distributed by
В качестве примера предположим, что пользователь смотрит фильм под названием Top Gun (с Томом Крузом). Здесь будет возможный список данных для этого популярного фильма до и после того, как пользователь его посмотрел.
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
Поля данных — это поля таблицы фильмов базы данных, перед которыми находятся данные в таблице фильмов, а после — связанные поля в таблице пользователей базы данных. В приведенном выше примере мы можем ясно видеть, что пользователь смотрел фильм под названием «Top Gun» 10 апреля 2019 года и в основном смотрел его вплоть до титров, что означает, что ему / ей, скорее всего, понравился фильм. Если время просмотра = время выполнения, то существует вероятность того, что пользователь отошел от мультимедийного устройства, воспроизводящего фильм, или заснул во время просмотра фильма. Если таблица показывает, что фильм был просмотрен дважды, то вероятность может быть уменьшена путем сравнения времени просмотра и может показать более вероятный результат, что пользователю понравился фильм.
У всех разные вкусы в фильмах, которые им понравятся, и чем больше фильмов они смотрят и чем больше данных вы можете отслеживать, тем, очевидно, более точными будут ваши рекомендации.
В данный конкретный момент вы хотите сохранить это простым и просто основывать свои рекомендации только на жанре. Для начала вам нужно будет поддерживать таблицу базы данных пользователей, в которой хранятся имя пользователя и названия фильмов, которые они смотрят, которые также содержатся в вашей базе данных в таблице Movies:
Таблица пользователей:
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 = ?;"
Поместите результирующий набор в массив строк (watchedMovies[] ). Теперь запросите таблицу Movies в базе данных, чтобы получить все разные жанры для просмотренных пользователем фильмов:
// 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 "';";
Поместите результирующий набор в массив строк и отобразите его пользователю. Вы можете сделать это с большинством полей в вашей таблице Movies, если хотите, просто добавив оператор AND в ваше предложение WHERE . Чем больше критериев вы используете в своем предложении WHERE, тем точнее будет ваша рекомендация фильма.
Чем больше фильмов смотрит пользователь, тем больше база данных узнает о том, что нравится Пользователю. В конце концов можно определить, что пользователь смотрит фильмы только с Томом Крузом (по какой-то неизвестной причине). 🙂