2

a6347324、b7432408、f54789922 (数値以外) などのユーザー ID と、数値のアイテム ID があります。Myrrix で REST API を使用して、そのようなユーザーとアイテムのペアを挿入できるようにしたいと考えています。しかし/pref/a6347324/1234、エラーを返します。https://github.com/myrrix/myrrix-recommender/blob/master/web-common/src/net/myrrix/web/servlets/PreferenceServlet.javaparseLongの 74 行目 を考慮すると、これが予想されます。

バージョン0.11を使用しています。「タグ」機能は、同等の数値 ID のような文字列タグを返さないため、使用したくありませんbecause。API では機能しないと思います (タグが返されないため!)。これはすぐに修正されますか?すぐに使用または実装できる即時の回避策はありますか?

4

2 に答える 2

2

REST API 自体は、設計上、数値 ID に関して機能します。数値IDを作成するために、数値であるかどうかにかかわらず、他のIDのハッシュを潜在的に行うのはクライアントです。TranslatingClientRecommender元の ID への変換を管理するのに役立つ代わりに使用したいと考えています。

追加の利点として、ある程度のセキュリティが得られる可能性があります。実際のユーザー ID とアイテム ID を実際にサービスに送信する必要はありません。これは、Amazon EC2 などのサード パーティ クラウドでホストされる場合に重要になる場合があります。

于 2013-04-14T18:17:40.273 に答える
1

この回答に、実際に問題をどのように解決したかについての詳細を追加することにしました。後で大幅な変更を加え、コードをよりオブジェクト指向にしたことに注意してください。これは、理解を容易にするための単純な説明にすぎません。

WebClientRecommender基本的に a の小さなラッパーであるクラスを次に示しTranslatingClientRecommenderます。

package suggester.client.recommender;

import java.io.File;
import java.io.Reader;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import net.myrrix.client.MyrrixClientConfiguration;
import net.myrrix.client.translating.TranslatedRecommendedItem;
import org.apache.mahout.cf.taste.common.TasteException;

/**
 *
 * @author Nilesh Chakraborty
 */
public class WebClientRecommender extends AbstractClientRecommender {

    public WebClientRecommender(MyrrixClientConfiguration myrrixClientConfiguration) {
        super(myrrixClientConfiguration);
    }

    @Override
    public List<TranslatedRecommendedItem> recommend(String idListFile, String recommendTo, String recommendType, int howMany) throws TasteException {
        clientRecommender.addItemIDs(new File(idListFile));
        List<TranslatedRecommendedItem> recommendations = clientRecommender.recommend(recommendTo, howMany, false, new String[]{recommendType});
        return recommendations;
    }

    @Override
    public List<TranslatedRecommendedItem> recommendAnonymous(String idListFile, String recommendType, int howMany, String[] list) throws TasteException {
        clientRecommender.addItemIDs(new File(idListFile));
        float[] values = new float[list.length];
        Arrays.fill(values, 30);
        List<TranslatedRecommendedItem> recommendations = clientRecommender.recommendToAnonymous(list, values, howMany, new String[]{recommendType}, "testID");
        return recommendations;
    }

    public List<TranslatedRecommendedItem> recommendAnonymous(URI idListFile, String recommendType, int howMany, String[] list) throws TasteException {
        clientRecommender.addItemIDs(new File(idListFile));
        float[] values = new float[list.length];
        Arrays.fill(values, 30);
        List<TranslatedRecommendedItem> recommendations = clientRecommender.recommendToAnonymous(list, values, howMany, new String[]{recommendType}, "testID");
        return recommendations;
    }

    @Override
    public void ingest(Reader csvReader) throws TasteException {
        clientRecommender.ingest(csvReader);
    }
}

ここにあるAbstractClientRecommender

package suggester.client.recommender;

import java.io.IOException;
import java.io.Reader;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.myrrix.client.ClientRecommender;
import net.myrrix.client.MyrrixClientConfiguration;
import net.myrrix.client.translating.TranslatedRecommendedItem;
import net.myrrix.client.translating.TranslatingClientRecommender;
import org.apache.mahout.cf.taste.common.TasteException;

/**
 *
 * @author nilesh
 */
abstract class AbstractClientRecommender {

    protected TranslatingClientRecommender clientRecommender;

    public AbstractClientRecommender(MyrrixClientConfiguration myrrixClientConfiguration) {
        try {
            clientRecommender = new TranslatingClientRecommender(new ClientRecommender(myrrixClientConfiguration));
        } catch (IOException ex) {
            Logger.getLogger(CLIClientRecommender.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public abstract List<TranslatedRecommendedItem> recommend(String idListFile, String recommendTo, String recommendType, int howMany) throws TasteException;

    public abstract List<TranslatedRecommendedItem> recommendAnonymous(String idListFile, String recommendType, int howMany, String[] list) throws TasteException;

    public void ingest(String csvFile) throws TasteException {
    }

    public void ingest(Reader csvReader) throws TasteException {
    }
}

現在、WebClientRecommenderカスタム サーブレットでクラスを使用しています。ここにありSuggesterServletます:

package suggester.client.servlets;

import com.google.common.base.Splitter;
import suggester.client.recommender.WebClientRecommender;
import java.io.IOException;
import java.net.URL;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.myrrix.client.MyrrixClientConfiguration;
import net.myrrix.web.servlets.AbstractMyrrixServlet;

/**
 *
 * @author nilesh
 */
public abstract class AbstractSuggesterServlet extends AbstractMyrrixServlet {

    static final Splitter SLASH = Splitter.on('/').omitEmptyStrings();
    private WebClientRecommender recommender;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        MyrrixClientConfiguration config = new MyrrixClientConfiguration();
        config.setHost(request.getServerName());
        config.setPort(request.getServerPort());
        recommender = new WebClientRecommender(config);
    }

    protected final WebClientRecommender getClientRecommender() {
        return recommender;
    }
}

では、次のようにしますSuggesterServlet

package suggester.client.servlets;

import com.google.common.collect.Iterables;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.util.List;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.myrrix.client.translating.TranslatedRecommendedItem;
import org.apache.mahout.cf.taste.common.TasteException;

/**
 *
 * @author nilesh
 */
public class SuggesterServlet extends AbstractSuggesterServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        super.doGet(request, response);

        String pathInfo = request.getPathInfo();
        String[] pathComponents = Iterables.toArray(SLASH.split(pathInfo), String.class);

        if (pathComponents.length == 0) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }

        try {
            List<TranslatedRecommendedItem> recommended = getClientRecommender().recommendAnonymous(getPropFilePath("proplist").toURI(), request.getParameter("type"), getHowMany(request), pathComponents);
            output(request, response, recommended);
        } catch (URISyntaxException use) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, use.toString());
        } catch (NamingException ne) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, ne.toString());
        } catch (TasteException te) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, te.toString());
        }
    }

    protected final void output(HttpServletRequest request,
            ServletResponse response,
            List<TranslatedRecommendedItem> items) throws IOException {

        PrintWriter writer = response.getWriter();
        // Always print JSON
        writer.write('[');
        boolean first = true;
        for (TranslatedRecommendedItem item : items) {
            if (first) {
                first = false;
            } else {
                writer.write(',');
            }
            writer.write("[\"");
            writer.write(item.getItemID());
            writer.write("\",");
            writer.write(Float.toString(item.getValue()));
            writer.write(']');
        }
        writer.write(']');
    }
}

カスタム サーブレット (HAS-A 関係) 内でそれを使用して、小道具ファイルを読み取り、文字列 ID をTranslatingClientRecommender(Myrrix REST サーブレットに接続する) に追加する - これは基本的に私が行った方法です。TranslatingClientRecommenderMyrrix の web.xml を変更して、カスタム サーブレットをリストに追加するだけで済み、Tomcat 上の単一のアプリケーション内ですべてを実行できます。

于 2014-01-16T15:40:23.070 に答える