協調フィルタリングFLINKに基づいて、

最近の火の上にFLINK、FLINKをしようとすることを推奨機能を使用してみてください、FLINK-mlの水を言って、先に行き、実際に含まれる比較的少数のアルゴリズムであり、かつ唯一のScalaのバージョンをサポートしているだけでなく、flink1.9はFLINK-mlの削除されて、それは大きな動きをする準備ができているように見えますが、後でリアルタイム勧告、FLINKは便利になることができます。幸いなことに、それらを達成するために、比較的簡単に基づいてアイテム協調フィルタリングアルゴリズムは難しいことではありません。現在推奨アーキテクチャ全体を見てください。

協調フィルタリングFLINKに基づいて、

私が使用し同様のアルゴリズムについてお話しましょう:
X- =(X1、X2、X3、... Xnの)、Y- =(Y1、Y2、Y3、... Ynの)
その後、ユークリッド距離は、次のとおりです。

協調フィルタリングFLINKに基づいて、

明らかに、類似度悪化、値が大きいほど、両者が同一であれば、次に距離はゼロです。

次のようにデータを準備するための最初のステップは、フォーマットのデータです。

協調フィルタリングFLINKに基づいて、

actionObjectは、家の番号で、actionTypeがでそうに、クリックをクリックし、収集及びませんでしたエクスポージャーを含め、ユーザの行動です。

次のコードは、スコアにHDFSからのデータ、データおよびイベントのクリアな視界、またはその他の行為を得ることです


public static DataSet<Tuple2<Tuple2<String, String>, Float>> getData(ExecutionEnvironment env, String path) {
        DataSet<Tuple2<Tuple2<String, String>, Float>> res= env.readTextFile(path).map(new MapFunction<String, Tuple2<Tuple2<String, String>, Float>> (){

            @Override
            public Tuple2<Tuple2<String, String>, Float> map(String value) throws Exception {
                    JSONObject jj=JSON.parseObject(value);
                    if(RecommendUtils.getValidAction(jj.getString("actionType"))) {                     
                        return new Tuple2<>(new Tuple2<>(jj.getString("userId"),jj.getString("actionObject")),RecommendUtils.getScore(jj.getString("actionType")));                 
                    }else {
                        return null;
                    }

                }   
            }).filter(new FilterFunction<Tuple2<Tuple2<String, String>, Float>>(){
                @Override
                public boolean filter(Tuple2<Tuple2<String, String>, Float> value) throws Exception {           
                    return value!=null;
                }       
            });

           return res;
    }

簡単な洗浄のデータの後に、次の形式に変換します

協調フィルタリングFLINKに基づいて、

重合に従って最初の2つの列、

groupBy(0).reduce(new ReduceFunction<Tuple2<Tuple2<String, String>, Float>>() { 

                @Override
                public Tuple2<Tuple2<String, String>, Float> reduce(Tuple2<Tuple2<String, String>, Float> value1,
                        Tuple2<Tuple2<String, String>, Float> value2) throws Exception {
                    // TODO Auto-generated method stub
                    return new Tuple2<>(new Tuple2<>(value1.f0.f0, value1.f0.f1),(value1.f1+value2.f1)); 
                }

            })

構造はなり

協調フィルタリングFLINKに基づいて、

このとき、理論BJCY56167779_03で、BJCY56167779_04類似性(4-3)^ 2 +(5-2)^ 2に、その後、処方して移動します。

最初の列を除去し、フォーマット

協調フィルタリングFLINKに基づいて、

以降
(X1-Y1)^ 2 +(X2-Y2)= 2 ^ 2 ^ X1 + 1 Y1 + 1 X2 2-2x1y1 ^ ^ 2 ^ 2-2x2y2 + Y2 + Y1 = X1 ^ 2 ^ 2 ^ 2 + X2 + Y2 ^ 2-2(X1Y1 + X2Y2) 、それでは、X1 ^ 2 +×2 ^ 2の値、アイテムテーブルとして登録見つけてみましょう


.map(new MapFunction<Tuple2<String, Float>, Tuple2<String, Float>>() {
                @Override
                public Tuple2<String, Float> map(Tuple2<String, Float> value) throws Exception {
                    return new Tuple2<>(value.f0, value.f1*value.f1);
                }  
            }).
groupBy(0).reduce(new ReduceFunction<Tuple2<String, Float>>(){

                @Override
                public Tuple2<String, Float> reduce(Tuple2<String, Float> value1, Tuple2<String, Float> value2)
                        throws Exception {
                     Tuple2<String, Float> temp= new Tuple2<>(value1.f0, value1.f1 +  value2.f1);
                     return temp;
                }

}).map(new MapFunction<Tuple2<String, Float>, ItemDTO> (){

                @Override
                public ItemDTO map(Tuple2<String, Float> value) throws Exception {
                    ItemDTO nd=new ItemDTO();
                    nd.setItemId(value.f0);
                    nd.setScore(value.f1);
                    return nd;
                }

}); 

tableEnv.registerDataSet("item", itemdto); // 注册表信息

上記の変換後、値の前半部分は既に、以下の要件(X1Y1 + X2Y2)の値を決定します

元のテーブルトップ、以下の形式に再びそれを回します

協調フィルタリングFLINKに基づいて、

コードは以下の通りであります:

.map(new MapFunction<Tuple2<String,List<Tuple2<String,Float>>>, List<Tuple2<Tuple2<String, String>, Float>>>() {

                @Override
                public List<Tuple2<Tuple2<String, String>, Float>> map(Tuple2<String,List<Tuple2<String,Float>>> value) throws Exception {
                    List<Tuple2<String, Float>> ll= value.f1;                   
                    List<Tuple2<Tuple2<String, String>, Float>> list = new ArrayList<>();
                    for (int i = 0; i < ll.size(); i++) {
                        for (int j = 0; j < ll.size(); j++) {
                            list.add(new Tuple2<>(new Tuple2<>(ll.get(i).f0, ll.get(j).f0),
                                    ll.get(i).f1 * ll.get(j).f1));
                        }
                    }
                    return list;        
                }

            })

tableEnv.registerDataSet("item_relation", itemRelation); // 注册表信息

以下は、最終的な計算を完了するために一緒に入れ、全体の式です。

Table similarity=tableEnv.sqlQuery("select ta.firstItem,ta.secondItem,"
        + "(sqrt(tb.score + tc.score - 2 * ta.relationScore)) as similarScore from item tb " +
        "inner join item_relation ta  on tb.itemId = ta.firstItem and ta.firstItem <> ta.secondItem "+
        "inner join item tc on tc.itemId = ta.secondItem "          
        );

DataSet<ItemSimilarDTO> ds=tableEnv.toDataSet(similarity, ItemSimilarDTO.class);

今構造になります

協調フィルタリングFLINKに基づいて、

遠く離れた端から気軽に、上記の構造は、我々が望むものはまだないが、我々はより明確に構造化したい、次のフォーマット

協調フィルタリングFLINKに基づいて、

コードは以下の通りであります:

DataSet<RedisDataModel> redisResult= ds.map(new MapFunction<ItemSimilarDTO, Tuple2<String, Tuple2<String, Float>>> (){

            @Override
            public Tuple2<String, Tuple2<String, Float>> map(ItemSimilarDTO value) throws Exception {               
                return new Tuple2<String, Tuple2<String, Float>>(value.getFirstItem(), new Tuple2<>(value.getSecondItem(), value.getSimilarScore().floatValue()));
            }
        }).groupBy(0).reduceGroup(new GroupReduceFunction<Tuple2<String, Tuple2<String, Float>> , Tuple2<String, List<RoomModel>>>() { 

            @Override
            public void reduce(Iterable<Tuple2<String, Tuple2<String, Float>>> values,
                    Collector<Tuple2<String, List<RoomModel>>> out) throws Exception {

                List<RoomModel> list=new ArrayList<>();
                String key=null;
                for (Tuple2<String, Tuple2<String, Float>> t : values) {
                    key=t.f0;
                    RoomModel rm=new RoomModel();
                    rm.setRoomCode(t.f1.f0);
                    rm.setScore(t.f1.f1);
                    list.add(rm);
                }       

                //升序排序
                Collections.sort(list,new Comparator<RoomModel>(){
                    @Override
                    public int compare(RoomModel o1, RoomModel o2) {                                            
                        return o1.getScore().compareTo(o2.getScore());                      
                    }
                 });

                out.collect(new Tuple2<>(key,list));            
            }

        }).map(new MapFunction<Tuple2<String, List<RoomModel>>, RedisDataModel>(){

            @Override
            public RedisDataModel map(Tuple2<String, List<RoomModel>> value) throws Exception {
                RedisDataModel m=new RedisDataModel();
                m.setExpire(-1); 
                m.setKey(JobConstants.REDIS_FLINK_ITEMCF_KEY_PREFIX+value.f0);      
                m.setGlobal(true);
                m.setValue(JSON.toJSONString(value.f1));
                return m;
            }

        });

これらのデータは、最終的には便利なクエリ、Redisの中に保存されます

RedisOutputFormat redisOutput = RedisOutputFormat.buildRedisOutputFormat()
                    .setHostMaster(AppConfig.getProperty(JobConstants.REDIS_HOST_MASTER))
                    .setHostSentinel(AppConfig.getProperty(JobConstants.REDIS_HOST_SENTINELS))
                    .setMaxIdle(Integer.parseInt(AppConfig.getProperty(JobConstants.REDIS_MAXIDLE)))
                    .setMaxTotal(Integer.parseInt(AppConfig.getProperty(JobConstants.REDIS_MAXTOTAL))) 
                    .setMaxWaitMillis(Integer.parseInt(AppConfig.getProperty(JobConstants.REDIS_MAXWAITMILLIS)))
                    .setTestOnBorrow(Boolean.parseBoolean(AppConfig.getProperty(JobConstants.REDIS_TESTONBORROW)))
                    .finish();   
            redisResult.output(redisOutput);

            env.execute("itemcf");

想像通り完了、実際には、それほど難しいことではありません。もちろん、ここでのデモ、だけでなく、実際のデータのフィルタリングである、マルチテーブルは、最適化に参加します。

おすすめ

転載: blog.51cto.com/12597095/2433875