Возможен ли основанный на контенте рекомендатель с составным элементом подобия объекта? - PullRequest
0 голосов
/ 22 октября 2018

Я хочу использовать Mahout в качестве системы рекомендаций.

В моем проекте есть содержимое, теги, реакции.Пользователь делится контентом после помеченного тегом, а другие пользователи могут читать его и давать ответы.

Я хочу рекомендовать контент, когда любой пользователь читает контент.

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

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

Если это правильный способ, который я объяснил выше, я думаю, использовать составной объект как ItemShoity, который обертывает реализацию сходства Mahout (например, TanimotoCoefficientShoity), затем добавить результат вычисления сходства с результатами сходства тегов и реакции.

Модель:

user_id    viewed_content_id
---------  -----------------
1             102
1             1032
2             105

content_id    reaction_id   reaction_count
----------    -----------   -------------
102             5              10000       
105             3              500
206             5              2000


content_id    tag_id
----------    ------
1              3
1              4   
1              3
2              3
2              1
3              3  
3              3

(Любой контент будет иметь около 5 вариантов реакции и около 5 тегов.)

Класс подобия предметов:

public class ContentSimilarity implements ItemSimilarity {

    private ItemSimilarity similarity;
    private FastByIDMap<ContentItem> map = new FastByIDMap<>();

    private ContentSimilarity() {
    }

    /**
     * 
     * @param dataModel
     * @param similarity
     *            ---> let assume that TanimotoCoefficientSimilarity
     * @return
     * @throws TasteException
     */
    public static ContentSimilarity createWith(DataModel dataModel, ItemSimilarity similarity) throws TasteException {
    ContentSimilarity customSimilarity = new ContentSimilarity();
    customSimilarity.setSimilarity(similarity);
    return customSimilarity;
    }

    @Override
    public void refresh(Collection<Refreshable> alreadyRefreshed) {
    similarity.refresh(alreadyRefreshed);

    }

    @Override
    public double itemSimilarity(long itemID1, long itemID2) throws TasteException {
    double similarityResult = similarity.itemSimilarity(itemID1, itemID2) + customSimilarity(itemID1, itemID2);
    return similarityResult;
    }

    int threshold = 10;

    public double customSimilarity(long itemID1, long itemID2) throws TasteException {
    ContentItem item1 = map.get(itemID1);
    ContentItem item2 = map.get(itemID2);
    double score = 0.0;
    try {
        // tag similarity
        int tagIntersection = item1.getTagsAsFastIDSet().intersectionSize(item2.getTagsAsFastIDSet());

        // reactionSimilarity
        FastByIDMap<Long> item1Map = item1.getReactionsAsFastByIDMap();
        FastByIDMap<Long> item2Map = item2.getReactionsAsFastByIDMap();
        LongPrimitiveIterator item1Itr = item1Map.keySetIterator();

        int reactionScore = 0;

        while (item1Itr.hasNext()) {
        long item1Key = item1Itr.next();
        long item1Val = item1Map.get(item1Key);
        Long item2ValO = item2Map.get(item1Key);
        if (item1Val > threshold && item2ValO > threshold) {
            reactionScore += item2ValO == null ? 0 : 1;
        }
        }
        score = tagIntersection + reactionScore; // max score is 10
    } catch (IOException e) {
        e.printStackTrace();
    }

    return score / 10;
    }

    @Override
    public double[] itemSimilarities(long itemID1, long[] itemID2s) throws TasteException {
    return similarity.itemSimilarities(itemID1, itemID2s);
    }

    @Override
    public long[] allSimilarItemIDs(long itemID) throws TasteException {
    return similarity.allSimilarItemIDs(itemID);
    }

    public ItemSimilarity getSimilarity() {
    return similarity;
    }

    public void setSimilarity(ItemSimilarity similarity) {
    this.similarity = similarity;
    }

}
...