Я работаю над вариантом использования механизма рекомендаций mahout. Я предварительно вычислил рекомендации и сохранил их в базе данных. теперь я планирую предоставить со вкусом остальные услуги для .net. у меня было ограниченное количество клиентов и продуктов. это пример использования рекомендаций на уровне дистрибьютора. мой вопрос: если появится новый дистрибьютор, как бы я предложил ему рекомендации. Я предлагаю количество рекомендуемых продуктов каждому дистрибьютору. Не могли бы вы, люди, дать мне некоторые рекомендации. Я столкнусь с проблемами производительности ..?
Механизм Mahout Recomendaton, рекомендующий продукты и их количество клиенту
Ответы (2)
Один из способов — когда приходит новый пользователь, предварительно вычислить рекомендации с нуля для всех пользователей или только для этого пользователя. Вы должны знать, что этот пользователь может изменить рекомендации и для других. Часто ли вы хотите выполнить предварительные вычисления, зависит от ваших потребностей.
Однако, если у вас ограниченное количество пользователей и элементов, другой способ — использовать онлайн-рекомендатор, который вычисляет рекомендации в режиме реального времени. Если вы используете FileDataModel
, есть способ периодически получать данные от нового пользователя (см. книгу Mahout в действии). а>). Если вы используете более быструю модель данных в памяти, вы можете переопределить методы: setPreference(long userID, long itemID, float value)
и removePreference(long userID, long itemID)
, и всякий раз, когда новый пользователь приходит и любит или удаляет некоторые элементы, вы должны вызывать эти методы в своей модели данных.
EDIT: в основном вы можете получить GenericDataModel
и добавить его к методам setPreference
и removePreference
. Это будет ваша модель данных более низкого уровня. Затем вы можете обернуть его с помощью ReloadFromJDBCDataModel
, установив свою модель данных в методе reload()
следующим образом:
DataModel newDelegateInMemory = delegate.hasPreferenceValues() ? новая модель MutableDataModel (delegate.exportWithPrefs()): новая модель MutableBooleanPrefDataModel (delegate.exportWithIDsOnly());
Переопределенные методы:
@Override
public void setPreference(long userID, long itemID, float value) {
userIDs.add(userID);
itemIDs.add(itemID);
setMinPreference(Math.min(getMinPreference(), value));
setMaxPreference(Math.max(getMaxPreference(), value));
Preference p = new GenericPreference(userID, itemID, value);
// User preferences
GenericUserPreferenceArray newUPref;
int existingPosition = -1;
if (preferenceFromUsers.containsKey(userID)) {
PreferenceArray oldPref = preferenceFromUsers.get(userID);
newUPref = new GenericUserPreferenceArray(oldPref.length() + 1);
for (int i = 0; i < oldPref.length(); i++) {
//If the item does not exist in the liked user items, add it!
if(oldPref.get(i).getItemID()!=itemID){
newUPref.set(i, oldPref.get(i));
}else{
//Otherwise remember the position
existingPosition = i;
}
}
if(existingPosition>-1){
//And change the preference value
oldPref.set(existingPosition, p);
}else{
newUPref.set(oldPref.length(), p);
}
} else {
newUPref = new GenericUserPreferenceArray(1);
newUPref.set(0, p);
}
if(existingPosition == -1){
preferenceFromUsers.put(userID, newUPref);
}
// Item preferences
GenericItemPreferenceArray newIPref;
existingPosition = -1;
if (preferenceForItems.containsKey(itemID)) {
PreferenceArray oldPref = preferenceForItems.get(itemID);
newIPref = new GenericItemPreferenceArray(oldPref.length() + 1);
for (int i = 0; i < oldPref.length(); i++) {
if(oldPref.get(i).getUserID()!=userID){
newIPref.set(i, oldPref.get(i));
}else{
existingPosition = i;
}
}
if(existingPosition>-1){
oldPref.set(existingPosition, p);
}else{
newIPref.set(oldPref.length(), p);
}
} else {
newIPref = new GenericItemPreferenceArray(1);
newIPref.set(0, p);
}
if(existingPosition == -1){
preferenceForItems.put(itemID, newIPref);
}
}
@Override
public void removePreference(long userID, long itemID) {
// User preferences
if (preferenceFromUsers.containsKey(userID)) {
List<Preference> newPu = new ArrayList<Preference>();
for (Preference p : preferenceFromUsers.get(userID)) {
if(p.getItemID()!=itemID){
newPu.add(p);
}
}
preferenceFromUsers.remove(userID);
preferenceFromUsers.put(userID, new GenericUserPreferenceArray(newPu));
}
if(preferenceFromUsers.get(userID).length()==0){
preferenceFromUsers.remove(userID);
userIDs.remove(userID);
}
if (preferenceForItems.containsKey(itemID)) {
List<Preference> newPi = new ArrayList<Preference>();
for (Preference p : preferenceForItems.get(itemID)) {
if(p.getUserID() != userID){
newPi.add(p);
}
}
preferenceForItems.remove(itemID);
preferenceForItems.put(itemID, new GenericItemPreferenceArray(newPi));
}
if(preferenceForItems.get(itemID).length()==0){
//Not sure if this is needed, but it works without removing the item
//preferenceForItems.remove(itemID);
//itemIDs.remove(itemID);
}
}
Если под «новым дистрибьютором» вы подразумеваете, что у вас нет данных о них, нет исторических данных. Тогда вы не сможете давать рекомендации, используя рекомендателей Mahout.
Вы можете предложить другие предметы, как только они выберут один. Используйте драйвер «itemssimilarity» Mahout, чтобы вычислить похожие товары для всего в вашем каталоге. Затем, если они выберут что-то, вы можете предложить аналогичные предметы.
Элементы, поступающие из драйвера itemsimilarity, могут храниться в вашей БД в виде значения столбца, содержащего идентификаторы похожих элементов для каждого элемента. Затем вы можете проиндексировать столбец с помощью поисковой системы и использовать первый заказ пользователя в качестве запроса. Это вернет персонализированные рекомендации в реальном времени и является самым современным методом, предложенным людьми из Mahout.
См. описание того, как это сделать, в этой книге Теда Даннинга, одного из ведущих специалистов по данным Mahout. http://www.mapr.com/practical-machine-learning