Как ускорить работу рекомендателя Mahout?

Привет, сообщество Mahout на SO!

У меня есть пара вопросов об ускорении расчета рекомендаций. На моем сервере установлен Mahout без Hadoop. Также jRuby используется для рекомендательного скрипта. В базе данных у меня 3 тыс. пользователей и 100 тыс. элементов (270 тыс. элементов в таблице соединений). Итак, когда пользователь запрашивает рекомендации, начинает работать простой скрипт:

Сначала он устанавливает соединение с БД, используя PGPoolingDataSource следующим образом:

  connection = org.postgresql.ds.PGPoolingDataSource.new()
  connection.setDataSourceName("db_name");
  connection.setServerName("localhost")
  connection.setPortNumber(5432)
  connection.setDatabaseName("db_name")
  connection.setUser("mahout")
  connection.setPassword("password")
  connection.setMaxConnections(100)
  connection

Я получаю это предупреждение:

WARNING: You are not using ConnectionPoolDataSource. Make sure your DataSource pools connections to the database itself, or database performance will be severely reduced.

Есть идеи, как это исправить?

После этого я создаю рекомендации:

model = PostgreSQLJDBCDataModel.new(
    connection,
    'stars',
    'user_id',
    'repo_id',
    'preference',
    'created_at'
  )

  similarity = TanimotoCoefficientSimilarity.new(model)
  neighborhood = NearestNUserNeighborhood.new(5, similarity, model)
  recommender = GenericBooleanPrefUserBasedRecommender.new(model, neighborhood, similarity)
  recommendations = recommender.recommend user_id, 30

На данный момент для создания рекомендации для одного пользователя требуется около 5-10 секунд. Вопрос в том, как делать рекомендации быстрее (200 мс было бы неплохо)?


person makaroni4    schedule 22.10.2012    source источник


Ответы (1)


Если вы знаете, что используете источник данных пула, вы можете игнорировать это предупреждение. Это означает, что реализация не реализует обычный интерфейс для пула реализаций, ConnectionPoolDataSource.

Вы никогда не сможете сделать это быстро, если попытаетесь запустить непосредственно из базы данных. Слишком много доступа к данным. Оберните JDBCDataModel в ReloadFromJDBCDataModel, и он будет кэширован в памяти, что должно работать буквально в 100 раз быстрее.

person Sean Owen    schedule 22.10.2012
comment
Шон, я надеялся на ваш ответ, большое спасибо - ReloadFromJDBCDataModel был именно тем, что мне было нужно. Без перезагрузки для пользователя требуется 8 секунд, а с перезагрузкой я обработал 119 пользователей за 18 секунд. Это ускорение в 53 раза! - person makaroni4; 23.10.2012