0

Pig での解決方法がわからない問題があります。製品カテゴリごとの製品タイトルを含む Hadoop のデータセット (約 400 万レコード) があります。各タイトルにはNo. Webページに表示された回数はありませんでした。クリックして商品詳細ページに移動した回数。いいえ。製品カテゴリ内のタイトルの数は異なる場合があります。

サンプルデータ -

ビデオ ゲーム|Halo 4|5400|25
ビデオ ゲーム|Forza Motorsport 4 リミテッド コレクターズ エディション|6000|10
ビデオ ゲーム|Marvel Ultimate Alliance|2000|55
カメラと写真|Pro Steadicam for GoPro HD|12000|250
カメラと写真|Hero GoPro Motorsports 1080P ワイド HD 5MP ヘルメット カメラ|10000|125

3 番目の列 (Web ページでの表示) に基づいて、各製品カテゴリ内の上位 N % のレコードを取得したいと考えています。ただし、N % は、カテゴリの重み/重要性に基づいて変更する必要があります。例えば。ビデオ ゲームの場合、上位 15 % のレコードを取得したいと考えています。カメラと写真の場合、上位 5 % などを取得したいのですが、Pig のネストされた FOREACH コード ブロック内の LIMIT 句で % または整数値を動的に設定する方法はありますか?

PRODUCT_DATA = LOAD '<PRODUCT FILE PATH>' USING PigStorage('|') AS (categ_name:chararray, product_titl:chararray, impression_cnt:long, click_through_cnt:long);

GRP_PROD_DATA = GROUP PRODUCT_DATA BY categ_name;

TOP_PROD_LIST = FOREACH GRP_PROD_DATA {

                  SORTED_TOP_PROD = ORDER PRODUCT_DATA BY impression_cnt DESC;
                  SAMPLED_DATA = LIMIT SORTED_TOP_PROD <CATEGORY % OR INTEGER VALUE>;
                  GENERATE flatten(SAMPLED_DATA);
                }

STORE TOP_PROD_TITLE_LIST INTO '<SOME PATH>' USING PigStorage('|');

特定のグループの % または整数値を動的に (カテゴリ別に) 設定するにはどうすればよいですか? MACRO を使用することを考えましたが、NESTED FOREACH ブロック内から MACROS を呼び出すことはできません。カテゴリ名をパラメーターとして取り、% OR INTEGER 値を出力する UDF を作成し、この UDF を LIMIT 操作から呼び出すことはできますか?

SAMPLED_DATA = LIMIT SORTED_TOP_PROD categLimitVal(categ_name);

助言がありますか?Pig のバージョン 0.10 を使用しています。

4

2 に答える 2

0

少し違うアプローチで解決したと思います。スクリプトを整理/最適化するためのより良い方法があるかもしれません。基本的には、各カテゴリ内の商品タイトルASCをインプレッション数順に並べて、カテゴリがRANK<=SAMPLE LIMITの場合にフィルターをかけると、ダイナミック サンプリングをシミュレートできます。は、カテゴリごとに定義された * カテゴリごとのタイトルの にSAMPLE LIMIT他なりません。タプルには、 UDFを提供する LinkedIn の DataFu オープン ソース jar を利用しています。COUNTPERCENT WEIGHTRANKENUMERATE

繰り返しになりますが、コードの改善/整理に関する提案があれば、私はすべて耳にします:) ご意見をお寄せいただきありがとうございます Cabad、本当に役に立ちました!

脚本:

REGISTER '/tmp/udf/datafu-1.0.0.jar';
define Enumerate datafu.pig.bags.Enumerate('1');
set default_parallel 10;

LKP_DATA = LOAD '/tmp/lkp.dat' USING PigStorage('|') AS (categ_name:chararray, perc:float);
PRODUCT_DATA = LOAD '/tmp/meta.dat' USING PigStorage('|') AS (categ_name:chararray, product_titl:chararray, impression_cnt:long, click_through_cnt:long);

GRP_PROD_DATA = GROUP PRODUCT_DATA BY categ_name;

CATEG_COUNT = FOREACH GRP_PROD_DATA generate FLATTEN(group) AS categ_name, COUNT(PRODUCT_DATA) as cnt;

CATEG_JOINED = JOIN CATEG_COUNT BY categ_name, LKP_DATA BY categ_name USING 'replicated';

CATEG_PERCENT = FOREACH CATEG_JOINED GENERATE CATEG_COUNT::categ_name AS categ_name, CATEG_COUNT::cnt AS record_cnt, LKP_DATA::perc AS  percentage;

PRCNT_PROD_DATA = JOIN PRODUCT_DATA BY categ_name, CATEG_PERCENT BY categ_name;

PRCNT_PROD_DATA = FOREACH PRCNT_PROD_DATA GENERATE PRODUCT_DATA::categ_name AS categ_name, PRODUCT_DATA::product_titl AS product_titl, PRODUCT_DATA::impression_cnt AS impression_cnt, PRODUCT_DATA::click_through_cnt AS click_through_cnt,  CATEG_PERCENT::record_cnt*CATEG_PERCENT::percentage AS sample_size;

GRP_PRCNT_PROD_DATA = GROUP PRCNT_PROD_DATA BY categ_name;

ORDRD_PROD_LIST = FOREACH GRP_PRCNT_PROD_DATA {
                             SORTED_TOP_PROD = ORDER PRCNT_PROD_DATA BY impression_cnt DESC;
                             GENERATE flatten(SORTED_TOP_PROD);
                          }

GRP_PROD_LIST = GROUP ORDRD_PROD_LIST BY categ_name;

GRP_PRCNT_PROD_DATA = FOREACH GRP_PROD_LIST GENERATE flatten(Enumerate(ORDRD_PROD_LIST)) AS (categ_name, product_titl, impression_cnt, click_through_cnt,  sample_size, rnk);

SAMPLED_DATA = FILTER GRP_PRCNT_PROD_DATA BY rnk <= sample_size;

SAMPLED_DATA = FOREACH SAMPLED_DATA GENERATE categ_name, product_titl, impression_cnt, click_through_cnt, rnk;

DUMP SAMPLED_DATA;
于 2013-10-04T22:35:27.767 に答える