• 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
 

 以前のエントリでProjectの作成まで書いたので、Entity作成についてのメモです。

以前のエントリはこちら
Spring Roo Install
[Spring Roo]プロジェクト作成, Logging&DB接続設定

  • roo shell上でentityコマンドを実行することでEntityが作成されます。下記はProjectというEntityを作成する例です。

   1  roo> entity --class ~.model.Project --testAutomatically
   2  Created SRC_MAIN_JAVA\com\example\model
   3  Created SRC_MAIN_JAVA\com\example\model\Project.java
   4  Created SRC_TEST_JAVA\com\example\model
   5  Created SRC_TEST_JAVA\com\example\model\ProjectDataOnDemand.java
   6  Created SRC_TEST_JAVA\com\example\model\ProjectIntegrationTest.java
   7  Created SRC_MAIN_JAVA\com\example\model\Project_Roo_Configurable.aj
   8  Created SRC_MAIN_JAVA\com\example\model\Project_Roo_Entity.aj
   9  Created SRC_MAIN_JAVA\com\example\model\Project_Roo_ToString.aj
  10  Created SRC_TEST_JAVA\com\example\model\ProjectDataOnDemand_Roo_Configurable.aj
  11  Created SRC_TEST_JAVA\com\example\model\ProjectDataOnDemand_Roo_DataOnDemand.aj
  12  Created SRC_TEST_JAVA\com\example\model\ProjectIntegrationTest_Roo_Configurable.aj
  13  Created SRC_TEST_JAVA\com\example\model\ProjectIntegrationTest_Roo_IntegrationTest.aj

  • com.exampleパッケージの下にmodelパッケージが作成され、その下にProjectクラス(Project.java)が作成されます。そしてそれに関連するjavaクラスファイル、AspectJのファイルやテストクラスが自動生成されます。

  • 続いてEntity内の各プロパティを追加していきます。Entity作成直後はそのEntityにフォーカスがあたっていますが、他のEntityの作業をしたあとなど、対象のEntityにフォーカスがあたっていない場合は、focusコマンドで対象のEntityにフォーカスを当てます。

   1  roo> focus --class ~.model.Project

  • チルダ(~)はベースのパッケージを表すので、ここではcom.exampleにあたります。roo shellのプロンプトが下記のようになっていればProject Entityにフォーカスがあたっています。

   1  ~.model.Project roo>

  • プロパティの追加はfieldコマンドで行います。下記は文字列型のnameというプロパティを追加する例です。

   1  ~.model.Project roo> field string --fieldName name
   2  Updated SRC_MAIN_JAVA\com\example\model\Project.java
   3  Created SRC_MAIN_JAVA\com\example\model\Project_Roo_JavaBean.aj
   4  Updated SRC_TEST_JAVA\com\example\model\ProjectDataOnDemand_Roo_DataOnDemand.aj
   5  Updated SRC_MAIN_JAVA\com\example\model\Project_Roo_ToString.aj

  • Project.javaがと関連するファイルが更新・作成されます。

  • プロパティに最大文字数やNull禁止の制約をつけたい場合には、プロパティ追加時に下記のようなオプションを追加します。

   1  ~.model.Project roo> field string --fieldName name --notNull --sizeMax 30
   2  Updated SRC_MAIN_JAVA\com\example\model\Project.java
   3  Updated SRC_TEST_JAVA\com\example\model\ProjectDataOnDemand_Roo_DataOnDemand.aj
   4  Created SRC_MAIN_JAVA\com\example\model\Project_Roo_JavaBean.aj
   5  Updated SRC_MAIN_JAVA\com\example\model\Project_Roo_ToString.aj

  • 上記の例は最大文字数は30文字でNullは禁止する例です。

  • 数値型のプロパティを追加する場合には型としてnumberを指定し、--typeオプションでJavaのクラスを指定します。

   1  ~.model.Project roo> field number --fieldName cnt --type java.lang.Integer

  • 日付型の場合もJavaのクラス名をあわせて指定します。

   1  ~.model.Project roo> field date --fieldName createdTime --type java.util.Date

  • 他のクラスへの関連をプロパティとして持つには、fieldコマンドの型の指定でsetを指定し、--typeで対象のクラス、--cardinalityオプションで関連の持ち方、--mappedByオプションでもう一方のEntityからこのEntityを参照するためのフィールド名を指定します。下記はProject EntityがSubProject Entityへの関連を一対多で持つ例です。SubProject Entityからはprojectというフィールド名でProject Entityを参照します。

   1  ~.model.Project roo> field set --fieldName subProjects --type ~.model.SubProject --cardinality ONE_TO_MANY --mappedBy project

  • 関連が多対一の場合には上記コマンドの--cardinalityをMANY_TO_ONEに、多対多の場合にはMANY_TO_MANYに変更します。

  • ここまでを必要なEntityとプロパティに対して実行すれば、アプリケーションの起動時に対応するテーブルがDBに作成されます。

posted by Png akanuma on Wed 30 Nov 2011 at 08:38

Mahout in Action Chapter 4 についてのメモ。

4.2 ユーザベースの推薦の詳細

4.2.1 アルゴリズム

  • ユーザにアイテムを推薦する処理は下記のとおり。ユーザは u で表されている

   1  for every item i that u has no preference for yet
   2    for every other user v that has a preference for i
   3      compute a similarity s between u and v
   4      incorporate preference of v for i, weighted by s, into a running average
   5  return the top items, ranked by weighted average

  • 外側のループはユーザがまだ嗜好度を持っていない、推薦対象になりうるアイテムすべてに対するもの

  • 内側のループはこの推薦対象になりうるアイテムについて嗜好度を持っているユーザに対するもので、その嗜好度を参照している

  • 最後にそれらの値の平均値を計算し、重み平均とする

  • それぞれの嗜好値はそのユーザがターゲットのユーザとどれぐらい類似しているかの平均値から重み付けされる

  • ユーザが類似しているほど、重みが嗜好度に加えられる

  • すべてのアイテムについて検証するのはひどく遅い。

  • 実際は最も類似しているユーザを計算した後、そのユーザに知られているアイテムのみについて検討される

   1  for every other user w
   2    compute a similarity s between u and w
   3    retain the top users, ranked by similarity, as a neighborhood n
   4  for every item i that some user in n has ap preference for, but that u has no preference for yet
   5    for every other user v in n that has a preference for i
   6      compute a similarity s between u and v
   7      incorporate preference of v for i, weighted by s, into a running averate

  • 一番の違いは最も類似しているユーザが何に興味を持っているかを探す前に、類似しているユーザを探している点

  • これは基本的なユーザベースの推薦アルゴリズムで、Mahoutにも実装されている

4.2.2 GenericUserBasedRecommenderによるアルゴリズムの実装

  • Mahoutは推薦エンジンを構築するためのコンポーネントの集合で、以下のようなコンポーネントから構成されている

   1  データモデル, DataModelによって実装される
   2  ユーザ同士の類似度, UserSimilarityによって実装される
   3  近隣者の定義, UserNeighborhoodによって実装される
   4  推薦エンジン, Recommenderによって実装される(ここではGenericUserBasedRecommender)

4.2.3 GroupLensによる探索

  • GroupLensのデータを処理するためにはGroupLensDataModelを使えばよい

   1  DataModel model = 
   2    new GroupLensDataModel(new File("ratings.dat"));
   3  UserSimilarity similarity = 
   4    new PearsonCorrelationSimilarity(model);
   5  UserNeighborhood neighborhood = 
   6    new NearestNUserNeighborhood(100, similarity, model);
   7  Recommender recommender = 
   8    new GenericUserBasedRecommender(model, neighborhood, similarity);
   9  LoadEvaluator.runLoad(recommender);

  • このコードを動かすと、OutOfMemoryErrorが発生するので、メモリを増やす必要がある

4.2.5 サイズ固定のneighborhood

  • 類似度が高い順にN個のデータが使われる

4.2.6 閾値ベースのneighborhood

  • 類似度の閾値を決めてそれ以上の類似度を持つユーザを取り出すことが可能

4.3 類似度の測定方法の詳細

  • ユーザベースの推薦で他に重要なのはUserSimilarity実装。ユーザベースの推薦の大部分はこのコンポーネントに依存している

4.3.1 ピアソン相関ベースの類似度

  • ピアソン相関は -1 から 1 までの数値で、2組の配列の傾向を測定するもので、線形の関係になる

  • この傾向が高い場合は相関係数は1に近づく

  • すべての値において関連が小さい場合は、相関係数は0に近づく

  • 関連がまったく逆の場合、一方の組の値が高くなるときに他方の値が小さくなるようなケースでは、相関係数は-1に近づく

  • 類似度の計算は双方のユーザがそのアイテムに対して嗜好度を持っている場合のみ可能

4.3.2 ピアソン相関の問題点

  • ユーザ間で一致するアイテムの数を評価に加えないことが、推薦エンジンとしては欠点

  • ユーザ間で一致するアイテムがひとつしかない場合、相関は計算されない

  • 全ての嗜好度が同一のユーザについては相関が計算されない

4.3.3 重み付けを使う

  • PearsonCorrelationSimilarityは重みを追加して、ピアソン相関の問題点を軽減する

  • PearsonCorrelationSimilarityのコンストラクタの第二引数にWeighting.WEIGHTEDを渡すことができ、これによってデータ数が多い場合には1.0方向へ、少ない場合には-1.0方向へ補正される

ユークリッド距離による類似度の定義

  • 前述のサンプルコードのUserSimilarity実装部分を変更してEuclideanDistanceSimilarityを使用する

   1  new EuclideanDistanceSimilarity(model)

  • この実装はユーザ間の距離を基にしている

  • ユーザがより類似している場合にこの値は小さくなる

  • この実装が実際に戻す値は 1 / (1 + distance)

コサイン測定による類似性の適用

  • 空間にポイントされ可視化された嗜好度データによる類似度計測方法

  • ユーザ間の類似度が低い場合、それぞれの嗜好度を表す線の距離は広がり、角度も大きくなる

  • この角度のコサインが類似度を導く

  • コサイン値は常に -1 から 1 の間で、小さい角度の場合は 1 に近づき、180度近い大きい角度の場合は -1 に近づく

  • これは良いことで、小さい角度の場合は類似度が高いということで 1 に近く、大きい角度の場合は -1 に近づくということだからである

  • コサイン測定による類似度の測定はよく強調フィルタリングによる調査と関連付けられる

  • この類似度測定法を使用するにはPearsonCorrelationSimilarityを使うだけでよい

スピアマン相関での相対的階級による類似度定義

  • スピアマン相関はわれわれの目的にとってはピアソン相関の興味深い変種

  • オリジナルの相関嗜好度データの相関ではなく、嗜好度データの相対ランクに基づいて相関を計算する

  • このプロセスはいくつかの情報を失うが、嗜好度データの本質である順位付けは維持され、正確な嗜好度合いについての情報は失われる

  • SpearmanCorrelationSimilarityはこの考えを実装する

  • 前出のサンプルコードのUserSimilarityの実装でSpearmanCorrelationalSimilarityを使うことで試すことができる

  • この実装は計算のために簡単ではない処理を行いランクを保存しなければならないため、かなり遅い

  • しかしながら小さいデータセットに対しては向いているかもしれない

  • CachingUserSimilarityは他のUserSimirality実装をラップするUserSimilarity実装で、その実行結果をキャッシュする

  • 計算処理はラップしているUserSimilarity実装に委譲し、その結果を内部的に保持しておく

   1  UserSimilarity similarity = new CashingUserSimilarity(
   2      new SpearmanCorrelationSimilarity(model), model)

  • evaluate()のtrainingPercentage引数を0.95から0.99に増やすことで、テストデータの量を5%から1%に減らすことで計算量を減らすことができる

  • これによって計算にかかる時間を数十分にすることができる

谷本係数により類似度の中の嗜好度データを無視する

  • おもしろいことに、嗜好度をすべて無視するUserSimilarity実装がある

  • TanimotoCoefficientSimilarityはその実装のひとつで、谷本係数を基にしている。この値はジャカール係数としても知られている

  • この値は嗜好性のあるアイテムの集合のうち、共通する部分の比率になる

  • 二人のユーザのアイテムが完全に一致するとき、結果は1.0になり、共通部分がないとき、0.0になる。結果がマイナスになることはないが問題ない

  • 結果を次の簡単な計算によって -1 から 1 の範囲に拡張することが出来る
     similarity = 2・similarity - 1

  • この計測方法は両方のユーザが嗜好度を持っているアイテムだけでなく、一方が嗜好度をもっているアイテムにも依存することに注意

  • この類似度計測方法を使う場合は、基になるデータにはブール値(Boolean)の嗜好度データのみを含める

対数尤度によるよりスマートな類似度の計算

  • 対数尤度による類似度は、谷本係数のように二人のユーザに共通するアイテムの数を基にしているが、その他に多くの重複がある可能性がどれくら低いか、アイテムの総数、それぞれのユーザが嗜好性を持っているアイテムの数も含んでいる

  • 二人のユーザ間での偶然による重複がどれくらい起こり得ないかを評価しようとするもの。すなわち、類似しないユーザ間で同じ映画に対する評価をもつことはあるが、類似しているユーザが全くありそうもない共通点を見せることがあるということ。

  • いくつかの統計的検定で、この類似度計測手法は二人のユーザ間でどれぐらい強く類似することがありそうもないかを断定しようと試みる。

  • 結果の類似度の値は二人のユーザ間で偶然ではない重複がおこるとみなされる値

  • 汎用化は難しいが、対数尤度による類似度は谷本係数による類似度より性能が優れている

嗜好度の推測

  • ときどき少なすぎるデータが問題になることがある。いくつかのケースにおいて、例えば、ピアソン相関はユーザ間で重複しているアイテムが一つの場合には類似度を計算することができない

  • データが欠損している部分にデフォルト値が挿入されるとどうか。この戦略はPreferenceInferrerインタフェースにより可能になっており、現在はAveragingPreferenceInferrerという実装がある

  • この実装はそれぞれのユーザの平均嗜好度を計算し、この平均値をまだユーザと関連のないアイテムの嗜好度として挿入する

  • UserSimilarityのsetPreferenceInferrer()メソッドを呼ぶことで使用可能

  • 原則として実際のデータを元に純粋に情報を作るには何も加えないが、これは計算を急激に遅くする

  • Mahoutはアイテム間の類似度という概念も提供する。ユーザ間だけでなくアイテム間の類似度についても同様の計算が適用される

アイテムベースの推薦

  • アイテムベースの推薦は、ユーザとユーザの代わりに、アイテムとアイテムがどれだけ類似しているかによって行われる。Mahoutでは、UserSimilarityの代わりにItemSimilarityを基にすることを意味する

アルゴリズム

   1  for every item i that u has no preference for yet
   2    for every item j that u has a preference for
   3      compute a similarity s between i and j
   4      add preference of u for j, weighted by s, to a running average
   5  return the top items, ranked by weighted average

  • アイテムベースの推薦を選択した方がよい理由の一つとしては、アイテムの数がユーザの数と比べて少ないとき、パフォーマンスの優位性はかなり大きくなるということ

  • また、一般的にアイテムはユーザよりも変更される点が少ない

  • 事前に類似度を計算しておくことは、実行時の推薦スピードを速くする

  • Mahoutでは、GenericItemSimilarityクラスが事前の計算とItemSimilarityクラスからの結果を格納するのに使われる。これは今までに出てきたいずれの実装にも適用することが可能

アイテムベースの推薦の詳細

  • GenericUserBasedRecommenderではなくGenericItemBasedRecommenderを使うコードは下記のとおり

   1  public Recommender buildRecommender(DataModel model)
   2      throws TasteException {
   3    ItemSimilarity similarity = new PearsonCorrelationSimilarity(model);
   4    return new GenericItemBasedRecommender(model, similarity);
   5  }

  • PearsonCorrelationSimilarityはItemSimilarityインタフェースを実装しているのでここでも使用しており、これはUserSimilarityインタフェースについても同様

  • GenericItemBasedRecommenderはシンプルで、DataModelとItemSimilarityのみ必要。ItemNeighborhoodは不要。

  • すべてのUserSimilarityがItemSimilarityも実装しているわけではない

  • アイテムベースの推薦は一般的にアイテム数がユーザ数より少ないときはユーザベースの推薦より速い

スロープワンアルゴリズムによる推薦

  • 新しいアイテムとその他のユーザの嗜好性のあるアイテムの嗜好度の差の平均を基に嗜好度を評価する

アルゴリズム

  • スロープワンという名前は推薦アルゴリズムが一つのアイテムとその他のアイテムの嗜好度の間にいくつかの直線関係があるという仮説から来ており、Yというアイテムの嗜好度を、Y=mx+bという式で表されるXの嗜好度を基にするのは妥当である

  • ここでスロープワンによる推薦は単純化するためのm=1:という仮説を追加する。この場合、b=y-xのみ残り、これはすべてのアイテムのペアの間での嗜好度の差

  • これはアルゴリズムは下記の様に、すべてのアイテム間の嗜好度の差を計算する大量の事前計算フェーズから成ること意味する

   1  for every item i
   2    for every other item j
   3      for every user u expressing preference for both i and j
   4        add the difference in preference of u for i and j to an average

  • そして、推薦アルゴリズムは下記のとおり

   1  for every item i the user u express no preference for
   2    for every item j that user u expresses a preference for
   3      find the average preference difference between j and i
   4      add this diff to preference of u value for j
   5      add this to a running average
   6  return the top items, ranked by these averages

  • アイテムベースの推薦のように、そのパフォーマンスはデータモデル内のユーザ数には依存せず、事前に計算されるすべてのアイテムのペアの間の嗜好度の平均との差のみに依存する

  • すべてのアイテム間の嗜好度の差を格納するために必要なメモリはアイテム数の二乗で増えていく。アイテム数が2倍になればメモリは4倍必要

スロープワンの実践

  • 類似度の計測方法は不要で必要なのは下記のみ

   1  new SlopeOneRecommender(model)

  • ピアソン相関のように、スロープワンアルゴリズムのもっともシンプルな形は脆弱性を持っている。アイテム間の差はそれがどのぐらい信頼できるか、どれくらいの量のデータに基づいているかということに関係なく重みとして与えられるということ

  • SlopeOneRecommenderは2種類の重み付けを提供する。アイテム数と標準偏差に基づいた重み付けである

  • スロープワンはすべてのユーザの現在の嗜好度に差を加えて評価されたものの平均で評価を形成する

  • アイテム数による重み付けはより多くのデータに基づく時に重みをさらに重くする

  • 同じように、標準偏差による重み付けは、嗜好度の標準偏差の差に基づき重み付けを行う。標準偏差が小さい場合には重み付けは重くなる

  • もし二つの映画の間の嗜好度の差が多くのユーザについて矛盾がないのであれば、それは信頼できると思われるためより多くの重みを与えられる

  • もしそれがユーザ間の場合とかなり異なってしまうのであれば、それは強調されるべきではない

  • この効果を無効にするには下記のようにする

   1  DiffStorage diffStorage = new MemoryDiffStorage(
   2      model, Weighting.UNWEIGHTED, Long.MAX_VALUE));
   3  return new SlopeOneRecommender(
   4      model,
   5      Weighting.UNWEIGHTED,
   6      Weighting.UNWEIGHTED,
   7      diffStorage);

DiffStorageとメモリの検討

  • スロープワンはメモリ消費の代償を伴う

  • MySQLJDBCDiffStorageなどの実装は、データベースからの差異データの計算や更新を可能にする

  • これはMySQLJDBCDataModelのようなJDBCに基づくDataModel実装の中で使われる必要がある

   1  AbstractJDBCDataModel model = new MySQLJDBCDataModel();
   2  DiffStorage diffStorage = new MySQLJDBCDiffStorage(model);
   3  Recommender recommender = new SlopeOneRecommender(
   4      model, Weighting.WEIGHTED, Weighting.WEIGHTED, diffStorage);

事前計算の分離

  • Hadoopによる差異の計算がサポートされている

新しい実験的な推薦手法

特異値分解による推薦

  • SVDRecommenderは特異値分解に基づいている

  • これは線形代数では重要な技術

  • SVDは独立したアイテムへのユーザの嗜好度の世界を、より汎用的であまり多くない数の特徴(例えばジャンルなど)の世界に要約する

  • この処理はいくつかの情報を失うが、推薦結果を改善することが可能なことがある。入力データを有効な方法で整形する

  • SVDRecommenderの使い方はシンプルで下記のとおり

   1  new SVDRecommender(model, new ALSWRFactorizer(model, 10, 0.05, 10))

  • SVDRecommenderはFactorizerを使用し、ここではALSWRFactorizer実装を使用している

  • 最初の数値の引数はSVDが対象とする特質の数で、正解は存在しない

  • 二つ目の引数はラムダでこれはfactorizerの正規化機能を制御する

  • 最後の引数はトレーニングステップ数

  • この実装の大きな問題点はSVDの計算がメモリ上で行われるということ

  • これはデータセットのすべてをメモリ上に格納する必要があるが、それはアピールするポイントではなく、それは出力の質を大きく低下させることなく入力データを減らすことができるためである

直線補間によるアイテムベースの推薦

  • 直線補間は幾分異なるアイテムベースの推薦方法で、KnnItemBasedRecommenderとして実装されている

  • Knnはk nearest neighborsの略で、NearestNUserNeighborhoodとしても具体化されている

  • 直線補間アルゴリズムはuser neighborhoodのコンセプトを用いているが、方法は異なる

  • このアルゴリズムはいくつかの線形代数の手法によりすべてのアイテムのペアの最適な重みのセットを計算し、ここに直線補間が用いられる

  • KnnItemBasedRecommenderの使い方は下記のとおり

   1  ItemSimilarity similarity = new LogLikelihoodSimilarity(model);
   2  Optimizer optimizer = new NonNegativeQuadraticOptimizer();
   3  return new KnnItemBasedRecommender(model, similarity, optimizer, 10);

  • このコードではもっとも近い10アイテムを計算するのに対数尤度による類似度の測定手法を用いている

  • この実装はとても機能的だが、現在の形ではほどよいサイズのデータセットにおいても遅い

集団ベースの推薦

  • 推薦はそれぞれの集団に行われ、推薦されたアイテムは最大のユーザ数に対してもっとも興味のあるものである

  • この手法の良い点としては実行時の推薦処理が速いことで、それはほとんどが事前に計算されるためである

  • この方法では個人ではなくグループに対しての推薦が計算されるため、個人性は少なくなる

  • この手法は嗜好度データが少ない新しいユーザに対して推薦を行う場合により効果的である

  • 集団化には長時間かかり、この案を実装したTreeClusteringRecommenderを用いた下記の例を実行する場合にもそれがわかる

   1  UserSimilarity similarity = new LogLikelihoodSimilarity(model);
   2  ClusterSimilarity clusterSimilarity = 
   3      new FarthestNeighborClusterSimilarity(similarity);
   4  return new TreeClusteringRecommender(model, clustersimilarity, 10);

  • 2つのSimilarity実装を用いており、ひとつは二人のもっとも類似しているユーザのペアの類似度として集団の類似度を定義し、もうひとつはもっとも類似していないユーザの類似度として集団の類似度を定義する

  • いずれのケースでも集団の端の一つの外れ値が集団の意味合いをゆがめるリスクがある

  • メンバー間の距離が平均的な二つの集団でも、一方の端に近づくとNearestNeighborClusterSimilarityにより実装されたmost-similar-userルールにより極めて近いとみなされる

  • 上記のコードでFarthestNeighborClusterSimilarityにより実装されたleast-similar-userルールも同じように、他方の集団から遠く離れた外れ値を含んでいる場合、近い集団でも距離があるとみなされてしまう

  • 三つ目のアプローチは集団の距離を中心値の距離により定義する方法で、どちらにたいしても使用可能であるがまだMahoutでは実装されていない

他の推薦手法との比較

コンテンツベースの技術をMahoutに導入する

  • アイテムベースの推薦の類似度はItemSimilarity実装にカプセル化されているが、アイテムの属性に基づいた実装にできない理由はない

  • 例えば映画の類似度をジャンルやディレクター、出演者、発売年などの関数として定義するかも知れず、この実装を従来のアイテムベースの中で使用することはコンテンツベースの推薦の例

コンテンツベースの推薦をより深く見る

  • 協調フィルタリングではユーザとアイテム間の関連の嗜好度に基づいて計算される

  • 関連を発見することとアイテムの属性を発見することで、よりユーザとアイテムの関連の意味合いに基づいた推薦エンジンを構築することが可能になる

  • Mahoutの推薦はまだこれらの技術を取り入れていないが、将来のバージョンで扱われる流れである

モデルベースの推薦との比較

  • この技術は既存の嗜好度データに基づきいくつかのユーザの嗜好度モデルを構築し、新しい嗜好度データを推測しようとするもの

  • これらは通常ユーザの嗜好度からのみ導き出されるので、この技術は一般的には協調フィルタリングのカテゴリに含まれる

  • このアルゴリズムは全てのユーザの嗜好度からアイテムが好まれる確率を判定しようとし、結果的に推薦のランク付けを行う

  • データから「ユーザがアイテムXとYを好むとき、アイテムZも好まれる」というようなルールを学習し、そのルールの信頼性を判断することで、最も新しく嗜好性のあるアイテムを推薦することが出来る

  • 集団はどのユーザがグループを形成し、それゆえに嗜好性の方向もおなじであるというモデルを表す。Mahoutはこの狭義のモデルベースの推薦をサポートしているが、その範囲は執筆時点では開発中である

posted by Png akanuma on Tue 29 Nov 2011 at 08:48

 Hadoop World NYC 2011の参加レポートがあるということをTwitterで発見して、Hadoopソースコードリーディング第7回に行ってきました。

アジェンダは下記の3つ

  • Hadoop World NYC 2011 参加レポート Part.1
  • Hadoop Troubleshooting 101 セッションレポート
  • Hadoop World NYC 2011 参加レポート Part.2

それぞれで気になったところをメモ。

Hadoop World NYC 2011 参加レポート Part.1

 Hadoop World NYC 2011の概要紹介と基調講演の内容の紹介といった感じ。会場の様子の紹介を聞く限りは盛況だったようですね。

 参加者についてのトピックとしては、

  • 利用者の平均Hadoopクラスタは120ノード
  • 12.8%は1PB以上のデータ量

だとか。

 基調講演の内容としては事例紹介が多かったようで、その中でおもしろそうだと思ったのはWibiDataとThe Walt Disney Companyの話。

 WibiDataはHBaseを使ったアプリの実装例で、Androidの通知バーにパーソナライズしたレコメンドを表示するサービスで、Wikipediaなどがすでに顧客になっているそう。ちょっとググってみましたがまだあんまり情報がなさそうなところをみると、始まったばかりなんですかね。

 The Walt Disney Companyではテーマパークの交通流解析などにHadoopを使っているのだとか。ディズニーランドとかは徹底的に裏側を隠してイメージさせないようになってるので、こういうところで裏側がちょっとのぞける気分になるのはおもしろい。データ的にも膨大なデータをもってそうなので分析するのもおもしろそうです。

 全体的なトピックとしては、HBaseの利用が増加しているそうです。一時期HBaseを業務で利用することを検討していた自分としては興味深いですね。AWSがHBaseのサービスとかやってくれないでしょうか。でもEC2は結構高くつきそうなので、EC2上で動くとなると気軽に使うわけにはいかないかな。

 あとはHadoop自体だけでなく、そのエコシステムが占める割合はどんどん増えていそうです。確かにHadoop本体だけではできることの幅は狭いので、エコシステムをいかにうまく使うか次第でHadoopはいいものにも悪いものにもなりそうだと思いました。

 そしてMapReduce技術者やHadoop関連の技術者が足りていないということは色々なところでいわれているようです。今Hadoop周りの技術を身につければしばらく仕事に困らないですかね?もう遅い?

Hadoop Troubleshooting 101 セッションレポート

 「Hadoopクラスタを壊す7つの設定ミス」ということで、代表的な7つのエラーについて現象や解決策の紹介がありました。パラメータの数字はどのぐらいにするのがいいかといったような細かいところも聞けたので、実際に運用する場合にはとても役に立ちそうです。

 「コミュニティはバグを直せるが設定を直せるのは自分だけ」という言葉が印象的でした。確かにそうですね。

 あと、これは重要なので机に貼っておくこと↓

   1  Total RAM = (Mappers + Reducers)Child Task Heap
   2  + DN heap
   3  + TT heap
   4  + 3GB
   5  + RS heap
   6  + Other Services' heap

Hadoop World NYC 2011 参加レポート Part.2

 こちらはいくつかのセッションをピックアップして紹介。

 「RとHadoopの融合」は、統計解析言語であるRをHadoop上で、Hadoopの中身を意識せずに動かせるように、rhdfs、rhbase、rmrを開発したという内容。Javaで書くよりはシンプルで、Hive、Pigほどシンプルではないけど汎用的に書けるそうです。MapReduceの中身の処理を書くことが可能で、多段にMapReduceを動かすことも可能だそうです。「Hadoopの中身を意識せずに」という割にはこの辺は意識する必要があるよなぁと思ったりもしますが。。。すでにR言語を使ってる人には良いかもしれませんね。

 「Hadoopを使った衛星画像解析」は、タスクの中でネイティブコード(C言語)を呼び出す仕組みを構築したという話でした。これによって既存の画像解析ライブラリをJavaで再実装することなく使用可能になったということです。個人的にはネイティブコードを呼び出すとかは敬遠しがちですが、今後Hadoopを様々なフレームワークと連携させたり、既存のライブラリを使うケースが増えてくるとこういった使い方も増えてくるんでしょうか。

 あとはHadoopを仮想環境で動かすというセッションの紹介もありました。個人的にはAWSとかがもっとHadoop関連のサービスを充実させてくると、運用の手間とかを考えるともっとAWSへ流れていくんじゃないかなぁと思ってたりします。

 また、Hadoopのトレンドとして、Hadoopはインフラとなりつつあり、MapReduceで計算して終わり、というのはもう古くて、目的としてではなく手段として、大量データを分析して役立てるためにHadoopを使いましょう、ということでした。最近のHadoop関連の話題を見ているとHadoop単体で扱われることは少なくて、エコシステムを組み合わせてどう問題を解決していくか、という内容になってきてるように思えるのもそうしたことの表れなのかな、と思いました。

posted by Png akanuma on Tue 29 Nov 2011 at 01:07

前のエントリでRooのインストールが終わったので、プロジェクトを作成します。

  • まず作業ディレクトリを作成し、コマンドプロンプトを起動してそのディレクトリへ移動します。

  • roo shell を起動します。

   1  >roo
   2  ____ ____ ____
   3  / __ \/ __ \/ __ \
   4  / /_/ / / / / / / /
   5  / _, _/ /_/ / /_/ /
   6  /_/ |_|\____/\____/ 1.1.5.RELEASE [rev d3a68c3]
   7  
   8  
   9  Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.
  10  roo>

  • プロジェクトを作成します。projectコマンドの--topLevelPackageでベースとなるパッケージ名を指定します。生成されるクラスはこのパッケージの下に作成されることになります。--projectNameオプションではプロジェクト名を指定します。

   1  roo> project --topLevelPackage com.example --projectName example
   2  Created ROOT\pom.xml
   3  Created SRC_MAIN_JAVA
   4  Created SRC_MAIN_RESOURCES
   5  Created SRC_TEST_JAVA
   6  Created SRC_TEST_RESOURCES
   7  Created SRC_MAIN_WEBAPP
   8  Created SRC_MAIN_RESOURCES\META-INF\spring
   9  Created SRC_MAIN_RESOURCES\log4j.properties
  10  Created SRC_MAIN_RESOURCES\META-INF\spring\applicationContext.xml
  11  com.example roo>

  • ロギングのレベルをWARNに設定しておきます。loggingコマンドを実行することでlog4j.propertiesの内容が変更されます。

   1  com.example roo> logging setup --level WARN
   2  Updated SRC_MAIN_RESOURCES\log4j.properties
   3  com.example roo>

  • データベースの設定もしてしまいます。persistence setupでDBへの接続設定が作成されます。ここではPostgresqlとHibernateを使う設定です。

   1  com.example roo> persistence setup --provider HIBERNATE --database POSTGRES --userName appuser --password apppwd --databaseName example
   2  Created SRC_MAIN_RESOURCES\META-INF\spring\database.properties
   3  Please update your database details in src/main/resources/META-INF/spring/database.properties.
   4  Updated ROOT\pom.xml [added dependencies postgresql:postgresql:8.4-702.jdbc3, org.hibernate:hibernate-core:3.6.4.Final,
   5  org.hibernate:hibernate-entitymanager:3.6.4.Final, org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final, or
   6  g.hibernate:hibernate-validator:4.1.0.Final, javax.validation:validation-api:1.0.0.GA, cglib:cglib-nodep:2.2, javax.tran
   7  saction:jta:1.1, org.springframework:spring-jdbc:${spring.version}, org.springframework:spring-orm:${spring.version}, co
   8  mmons-pool:commons-pool:1.5.4, commons-dbcp:commons-dbcp:1.3; added repository https://repository.jboss.org/nexus/conten
   9  t/repositories/releases]
  10  Updated SRC_MAIN_RESOURCES\META-INF\spring\applicationContext.xml
  11  Created SRC_MAIN_RESOURCES\META-INF\persistence.xml
  12  com.example roo>

  • database properties listコマンドで設定内容が確認できます。

   1  com.example roo> database properties list
   2  database.driverClassName = org.postgresql.Driver
   3  database.password = appuser
   4  database.url = jdbc:postgresql://localhost:5432/example
   5  database.username = apppwd
   6  com.example roo>

  • デフォルトでは persistence.xml 内の hibernate.hbm2ddl.auto の値は create になっていますが、これだとアプリケーションを起動するたびにDBスキーマが再作成されてしまうので、エディタでpersistence.xmlを開いて update に変更しておきます。

  • これでひとまずアプリケーションのベースが作成されたので、次のエントリでEntityの作成について書きたいと思います。

posted by Png akanuma on Fri 18 Nov 2011 at 08:29

仕事で Spring Roo を使う機会が増えてきたので、チュートリアル的な内容をメモ。まずはRooのインストールについてです。

Rooインストール

  • Spring Rooのサイト から下記ファイルをダウンロードします。

    ・spring-roo-1.1.5.RELEASE.zip

  • 解凍して任意のディレクトリに配置します。

  • 上記ディレクトリを環境変数 ROO_HOME に設定し、 %ROO_HOME%\bin を環境変数 PATH に追加します。

  • コマンドプロンプトから roo と入力して実行することで roo shell が起動します。

   1  >roo
   2  ____ ____ ____
   3  / __ \/ __ \/ __ \
   4  / /_/ / / / / / / /
   5  / _, _/ /_/ / /_/ /
   6  /_/ |_|\____/\____/ 1.1.5.RELEASE [rev d3a68c3]
   7  
   8  
   9  Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.
  10  
  11  At this time you have not authorized Spring Roo to download an index of
  12  available add-ons. This will reduce Spring Roo features available to you.
  13  Please type 'download status' and press ENTER for further information.
  14  
  15  roo>

  • リソースのダウンロードに同意するために、download status と入力して実行します。

   1  roo> download status
   2  
   3  **** DOWNLOAD CONSENT REQUIRED ****
   4  
   5  Spring Roo needs to download resources from VMware domains to improve your
   6  experience. We include anonymous usage information as part of these downloads.
   7  
   8  The Spring team gathers anonymous usage information to improve your Spring
   9  experience, not for marketing purposes. For example, we collect anonymous
  10  information about the usage of public Roo add-ons. This lets us offer you
  11  higher quality add-on search results, highlighting the add-ons which are most
  12  popular in the Roo community. We also use this information to help guide our
  13  roadmap, prioritizing the features most valued by the community and enabling
  14  us to optimize the compatibility of technologies frequently used together.
  15  
  16  Please see the Spring User Agent Analysis (UAA) Terms of Use at
  17  http://www.springsource.org/uaa/terms_of_use for more information on what
  18  information is collected and how such information is used. There is also an
  19  FAQ at http://www.springsource.org/uaa/faq for your convenience.
  20  
  21  To consent to the Terms of Use, please type 'download accept terms of use' at
  22  the command prompt and press ENTER. If you do not type 'download accept terms
  23  of use' to indicate your consent, Spring Roo add-on discovery features will
  24  not be available and anonymous data collection will remain disabled.
  25  
  26  Next steps:
  27  
  28  * To enable downloads, type 'download accept terms of use' and press ENTER
  29  
  30  * To disable downloads, type 'download reject terms of use' and press ENTER
  31  
  32  If you don't type either command, Roo will remind you next time it loads.
  33  
  34  roo>

  • download accept terms of use を実行することでリソースのダウンロードに同意できます。

   1  roo> download accept terms of use
   2  Thank you. All Spring Roo download features have now been enabled.

  • roo shell ではhintコマンドを実行することで次にやるべきことのヒントが表示されます。

   1  roo> hint
   2  Welcome to Roo! We hope you enjoy your stay!
   3  
   4  Before you can use many features of Roo, you need to start a new project.
   5  
   6  To do this, type 'project' (without the quotes) and then hit TAB.
   7  
   8  Enter a --topLevelPackage like 'com.mycompany.projectname' (no quotes).
   9  When you've finished completing your --topLevelPackage, press ENTER.
  10  Your new project will then be created in the current working directory.
  11  
  12  Note that Roo frequently allows the use of TAB, so press TAB regularly.
  13  Once your project is created, type 'hint' and ENTER for the next suggestion.
  14  You're also welcome to visit http://forum.springframework.org for Roo help.

  • roo shell の終了は quitコマンドです。

   1  roo> quit

  • これでひとまずRooを使う環境が作成できました。
posted by Png akanuma on Thu 17 Nov 2011 at 08:41

Mahout in ActionのChapter3についての自分の理解をメモ。


嗜好データの表現


Preferenceオブジェクト

  • Preferenceオブジェクトは最も基本的な概念で、一つのユーザID、アイテムID、嗜好値で嗜好性を表す
  • 一つのオブジェクトが一人のユーザの一つのアイテムに対する嗜好性を表している
  • 一つのGenericPreferenceは20バイトの有用なデータを保持しており、8バイトのユーザID(Javaのlong型)、8バイトのアイテムID(long)、4バイトの嗜好値(float)から成っている
  • オブジェクトが存在するためには上記以外に28バイトものオーバーヘッドがかかる

PreferenceArrayと実装

  • PreferenceArrayはPreferenceのコレクションを配列のように扱うためのインタフェース
  • 例としてGenericUserPreferenceArrayは一つのユーザIDにアイテムIDの配列と嗜好値の配列を持つ
  • 必要なメモリはわずか12バイト(8バイトのアイテムID、4バイトの嗜好値の配列)
  • Preferenceオブジェクトと比べてメモリは節約できるがパフォーマンスの改善効果は少ない
  • これはPreferenceArrayでは要素が分散されて配置され、ガベージコレクタによって評価されるため

FastByIDMapとFastIDSet

  • Mahoutはmapやsetのようなデータ構造を使用するが、JavaのコレクションであるTreeSetやHashMapではなく、FastMap、FastByIDMap、やFastDISetを使用する
  • これらはMapやSetのようなものであるが、MahoutのRecommenderが必要なものだけのために特化されている
  • パフォーマンスの劇的な改善というよりむしろメモリの使用量を削減する
  • Javaのコレクションとの違いは下記のような点
    ・FastByIDMapはHashMapと同じようにハッシュベースで、ハッシュの衝突の解決には分離連鎖法ではなく線形探査法を使う
    ・MahoutのRecommenderではキーとメンバーは常にlong型のプリミティブ型でオブジェクトではない。
    ・longのキーを使うことでメモリの使用量を抑えパフォーマンスを改善する。
    ・FastByIDMapは最大サイズという考え方があるためキャッシュの様に使用することができ、このサイズを越えた場合は、新しい要素を追加する際に使われていない要素が削除される

  • FastIDSetは一つの要素ごとに平均14バイト使用する。HashSetは84バイト。

  • FasByIDMapはエントリごとに28バイト使用する

インメモリデータモデル


GenericDataModel

  • 最もシンプルなインメモリのDataModel実装はGenericDataModel
  • GenericDataModelは嗜好度の入力としてユーザIDとPreferenceArrayのFastByIDMapを受け取る

   1  FastByIDMap<PreferenceArray> preferences = 
   2      new FastByIDMap<PreferenceArray>();
   3  PreferenceArray prefsForUser1 = 
   4      new GenericUserPreferenceArray(10);
   5  
   6  prefsForUser1.setUserID(0, 1L);
   7  prefsForUser1.setItemID(0, 101L);
   8  prefsForUser1.setValue(0, 3.0f);
   9  prefsForUser1.setItemID(1, 102L);
  10  prefsForUser1.setValue(1, 4.5f);
  11  ... (8 more)
  12  
  13  preferences.put(1L, prefsForUser1);
  14  
  15  DataModel model = new GenericDataModel(preferences);

  • メモリの使用量は格納される嗜好データの数によるが、いくつかのテストの結果から、嗜好データ1つごとに28バイトのJava heap spaceが使われる。これにはすべてのデータとインデックスなどのデータ構造を含む。

ファイルベースのデータ

  • FileDataModelはファイルからデータを読み込み、GenericDataModelとしてメモリに格納する
  • CSVの他にTSVも使用可能。ファイル名の拡張子が.zipや.gzになっていればzipやgzipの圧縮ファイルも使用可能

コンポーネントのリフレッシュ

  • データをリフレッシュするためには refresh(Collection) というメソッドを使用する。
  • このメソッドは最新のデータを元にコンポーネントの再読み込み、再計算、状態のリフレッシュを行う
  • FileDataModelはその時点のファイルを読み込むだけで、パフォーマンスの問題で自動的にデータをリロードするようなことはしないため、refresh()メソッドを使用する

ファイルの更新

  • FileDataModelはファイルの更新をサポートしている。メインのファイルを読み込んだ後でさらにファイルを読み込むことで先に読み込まれたデータを上書きする
  • 削除は空の嗜好値データを渡すことによって行われる

   1  1,108,3.0
   2  1,103,

  • 上記のデータではユーザ1のアイテム108についての嗜好度データが作成または更新されて嗜好度3.0がセットされ、ユーザ1のアイテム103についての嗜好度データが削除される
  • このためにはメインのデータファイルと同じディレクトリに格納し、最初のピリオドまでのファイル名を同じにしておく必要がある

DBベースのデータ

  • MahoutではRDBから嗜好度データを読み込むことができる
  • DBからデータを読み込んでRecommenderを動かすのはかなり遅い
  • データの抽出、並び替え、シリアライズ、転送、結果セットのデシリアライズのオーバーヘッドは依然として最適化されたインメモリ構造からデータを読み込むよりかなり大きい

JDBCとMySQL

  • 嗜好度データにはJDBCDataModelの実装を通してJDBCでアクセスする
  • JDBCDataModelのプライマリサブクラスはMySQL5.x用のMySQLJDBCDataModel
  • Mahoutの開発バージョンにはPostgreSQL用のJDBCDataModel実装がある
  • デフォルトではすべての嗜好度データはtaste_preferencesというテーブルに、ユーザIDが格納されるuser_idカラム、アイテムIDが格納されるitem_idカラム、嗜好度データが格納されるpreferenceカラムとともに格納されているとみなされる
  • このテーブルにはJavaのlong型と互換性のあるtimestampカラムを含むことができる

JNDIによる設定

  • JDBCDataModelはJNDIにjdbc/tasteという名前で登録されているDataSourceでアクセスできるものとみなされる

プログラムでの設定

  • JNDIを直接使わなくても、MySQLJDBCDataModelのコンストラクタにDataSourceを直接渡すことができる

   1  MysqlDataSource dataSource = new MysqlDataSource();
   2  dataSource.setServerName("my_database_host");
   3  dataSource.setUser("my_user");
   4  dataSource.setPassword("my_password");
   5  dataSource.setDatabaseName("my_database_name");
   6  JDBCDataModel dataModel = new MySQLJDBCDataModel(
   7      dataSource, "my_prefs_table", "my_user_column",
   8      "my_item_column", "my_pref_value_column");

  • 上記がデータベース内のデータをレコメンドに使うためのすべて
  • MySQLJDBCDataModelのドキュメントが明確にしているように、効率的にレコメンドを提供するには下記のようなデータベースやドライバに対するコンフィギュレーションが求められる
    ・ユーザIDとアイテムIDカラムはnullを許容せず、インデックスされていること
    ・プライマリキーはユーザIDとアイテムIDの複合値であること
    ・カラムのデータ型はJavaのlongとfloatに対応していること
    ・バッファやクエリキャッシュのチューニングのためにはMySQLJDBCDataModelのJavadocを参照
    ・MySQLのConnector/Jドライバを使う場合は、cache-PreparedStatementsパラメータをtrueに設定する

嗜好度データ無しの対処


  • ユーザとアイテムの関連はあるがつながりの強さを表す値がない嗜好度データを扱うことがある
  • Mahout-speakではこのようなデータはBoolean preferencesと呼ばれ、”存在する” または ”存在しない” のいずれかの値を持つ
  • これは”yes”、”no”を表すのではなく、全ての有効なユーザとアイテムの関連において、”好き”、”好きではない”、”なし”の3つの状態を設定する

データを無視する場合

  • 好む、好まないというのが相対的に似たような状態の場合、少なくとも関連が全くないものと比較するケースでは、嗜好度データを無視することは有益である

嗜好度なしのインメモリ表現

  • 嗜好度を持たないことは嗜好データの表現を劇的に単純化し、パフォーマンスの改善と、メモリ使用量の大幅な削減を可能にする
  • 嗜好度を持たないことで一つの嗜好度データごとに4バイト抑えられるはずであるが、実際にテストをした結果では4バイトから24バイト削減された
  • GenericBooleanPrefDataModelはGenericDataModelとは別のDataModel実装であるが、嗜好度を内部に保持せず、FastIDSetsのように関連のみを保持する
  • DataModelのgetItemIDsForUser()などのいくつかのメソッドは速くなる
  • getPreferencesFromUser()などのいくつかのメソッドは遅くなる。
  • getPreferenceValue()メソッドは全てのケースにおいて1.0を返す。
  • GenericBooleanDataModelの便利なメソッドであるtoDataMap()を使ってPreferenceArraysを要素としてもつFastByIDMapを、FastIDSetsを要素としてもつFastByIDMapに変換して、GenericBooleanDataModelの入力として渡すことが可能

互換性のある実装の選択

  • EuclideanDistanceSimilarityなどは嗜好度なしで動かしても役に立つ結果は得られないため、嗜好度無しのデータでは動作しない
  • 二つのデータが同じ値である場合、これらのピアソン相関は定義されない
  • LogLikelihoodSimilarityは実際の嗜好度データに基づかない実装
  • FileDataModelは入力データが嗜好度を含まない場合、自動的にGenericBooleanPrefDataModelを使用する
  • MySQLBooleanPrefDataModelは嗜好度カラムを持たないデータベーステーブルを使用する場合に適している
posted by Png akanuma on Tue 8 Nov 2011 at 08:29

 Mahout in ActionのChapter2についての自分の理解をメモ。

推薦の定義

  • ユーザベース
    ・ユーザとアイテムの関連に基づく推薦。
    ・嗜好の似ている人が好きそうなものを推薦する。
    ・属性は考慮しない。
    ・Mahoutで適切に表現可能

  • アイテムベース
    ・ユーザとアイテムの関連に基づく推薦。
    ・好きなアイテムに似ているアイテムを推薦する。
    ・属性は考慮しない。
    ・Mahoutで適切に表現可能

  • コンテンツベース
    ・アイテムの属性に基づく推薦。
    ・Mahoutはあまりサポートしない。
    ・Mahoutと組み合わせて実現可能。

初めての推薦エンジン

  • ここではユーザベースの推薦アルゴリズムを使用
  • MahoutのインプットデータのIDは常に数字(整数)。嗜好度は大きい値がより嗜好度が強いことを意味すればどのような値でもよい。
  • CSV形式でインポートデータを用意。

  • Recommenderの作成
    ・DataModel:データの保持、データへのアクセス
    ・UserSimilarity:ユーザ間の類似度
    ・UserNeighborhood:ユーザの類似グループ
    ・Recommender:上記コンポーネントを元に推薦アイテムを抽出

  • 結果の分析
    ・現実はデータ量が膨大でノイズも含んでいる
    ・膨大なデータから正しい結果を素早く抽出することは重要

Recommenderの評価

  • 実際のデータの一部を元にシミュレート可能
  • 評価された結果と実際のデータの間での平均値の違いを計算可能
  • 上記評価の値は小さいほど良い
  • 上記値が0.0の場合、評価された値と本番データの差はないということ
  • RecommenderEvaluatorはデータを評価用に分割し、DataModelとRecommenderを生成し、評価された値を実際のデータと比較する
  • 例でevaluate()メソッドにRecommenderが渡されていないのは、メソッド内部で新たに作られたDataModelについてRecommenderを生成する必要があるため
  • メソッドの呼び出し元からDataModelからRecommenderを生成するためのRecommenderBuilderを渡す必要がある。
  • ここではこの章で前出の実装と同じものが生成される
  • RandomUtils.useTestSeed()では毎回同じランダム値を取得する。本番コードで使ってはいけない。
  • プログラム2.3の例では実行結果は1.0が返ってくるが、この値の意味は実装に寄って異なり、ここではAverageAbsoluteDefferenceRecommenderEvaluatorが使われている。
  • 実行結果が異なるかもしれないが、それはデータセットの分割がランダムであり、実行の度にトレーニングセットの内容が異なることによるもの。
  • root-means-square(二乗平均平方根)によるスコアリングに変更する場合は、AverageAbsoluteDifferenceRecommenderEvaluatorをRMSRecommenderEvaluatorに置き換える
  • evaluate()メソッドにnullの代わりにDataModelBuilderを渡すことができ、それによってトレーニングデータからどのようにDataModelが作られるかを制御することが出来る。通常はデフォルトが良い。
  • 例でevaluate()メソッドに渡されている1.0という値は入力データのどれぐらいの割合が使われるかということで、ここでは100%とという意味。

正確さと再現度の評価

  • 正確さは上位の推薦結果の中の良い推薦の割合。
  • 再現度は良い推薦の中の上位の推薦結果に含まれる割合。
  • Mahoutはこれらの計算を極めて簡潔な方法で行うことが出来る。
  • RandomUtils.useTestSeed()を使わない場合、ここではデータセットが小さいので、結果はデータセットのランダムな抽出に大きな影響を受ける。
  • 推薦結果の良し悪しを分ける明確な境界が与えられていない場合、フレームワークがユーザごとに嗜好の平均に標準偏差を加算したものを使用する。

GroupLensのデータセットを評価する

  • GroupLensとは実際のユーザの映画に対する評価のリサーチプロジェクトで、いくつかの種類の大きさのデータセットを提供している
  • ここでは 100Kデータセットを使用 http://www.grouplens.org/node/73
  • ダウンロードしたファイルを解凍した中に含まれている ua.base はタブ区切りのユーザID、アイテムID、評価、その他の追加の情報のファイル
  • FileDataModelで扱うことができる。前出のintro.csvの代わりに使用
  • Slope One Recommenderを使用してみる
  • RecommenderBuilderでSlopeOneRecommenderを使用するようにすることで利用可能
  • サンプルを実行すると非常に高速だが、Slope Oneアルゴリズムが常に高速というわけではない
  • 計算の前処理に非常に時間がかかる場合がある
  • この違いは実際のデータでテスト・評価することの大切さと、Mahoutを使うと比較的簡単に行えることを示している
posted by Png akanuma on Sun 6 Nov 2011 at 22:18 with 2 comments

 会社の同僚とMahout in Actionの勉強会を始めたので、Chapter1についての自分の理解をメモ。

Mahoutとは?

  • インドの像使いという意味の言葉
  • Apacheプロジェクトのオープンソース機械学習ライブラリ
  • 主要テーマは推薦エンジン(協調フィルタリング)、集団形成(clustering)、分類(classification)
  • スケーラブル
  • Javaで書かれたJavaライブラリ
  • Hadoopの上で動かすように作られている
  • Apache Luceneのサブプロジェクトとしてスタートして2010年にトップレベルプロジェクトになった

MahoutとHadoopで大規模データに取り組む

  • 機械学習技術は大規模なデータを基に使われる
  • パワフルなコンピュータでさえ1台で処理するのは難しい
  • Mahoutのような実装がなければ困難
  • スケーラブルな分散環境はHadoopにより実現

Mahoutセットアップ

  • Java6以上が必要
  • IDEの使用をオススメ(Eclipse, NetBeans, IntelliJ IDEAなど)
  • Mavenをインストールする
  • Mahoutはまだ開発中で、執筆時のバージョンは0.5
  • ダウンロードサイトからダウンロード可能
  • もしくはSubversionから最新のコードを取得可能
    https://cwiki.apache.org/confluence/display/MAHOUT/Version+Control
  • 取得したソースからIDEでMavenプロジェクトを作成(方法はIDEによって異なる)
  • Hadoopを擬似分散モードでインストールする(本書ではVersion 0.20.2を使用)
  • ちょっと違う方法で自分なりに環境を作ってみたエントリはこちら
posted by Png akanuma on Sat 5 Nov 2011 at 09:57

 Google Developer Day 2011 Japanに行ってきたので会場の様子をちょっと紹介。

 基調講演やブレイクアウトセッションについては前のエントリで少し書いたのでそちらをどうぞ。

 エントランスロビー。オブジェは正二十面体にGDDの開催地がマッピングされた展開図になってるらしいです。

 デベロッパーサンドボックスのコーナー。芝浦工業大学とco-meetingの説明を聞いてきました。

 NFCを使ったスタンプラリー的なもので、「NFC QUEST」。会場内のいろんなところにNFCのチェックポイントがあって、入場時に配布されたカードでタッチするようになってました。右下の写真はBar Androidの出張店舗。

 こちらはGTUGコーナー。

 Chrome Bookも展示されていました。ちょっとしか触ってないですが、普通のノートPCとすごく違うような印象は受けませんでしたね。

 さらにGoogle TVも。今度docomoから出るGalaxyも展示されてたらしいのですが、私は見てきませんでした。

 こちらはAndroid関連の展示。

 パノラマなGoogle Earth。

 メディアラボとGooglerによるパフォーマンス。メディアラボはGoogleとのコラボでWebサイトへアクセスすることによる観客参加型のセッション。Node.jsとWeb Audio APIを使った仕組みだそうです。Googlerは須藤元気のWORLD ORDERと同じダンスパフォーマンス。ダンス経験者はほとんどいなかったそうですがそうとは思えないなかなかすごいものでした。

 「あなたが書いた自慢のコードは何ですか?GDD会場に刻みつけよう!」ということで参加者が自由にコードを書き込めるボード。右は終了後に会場外で取った夜景です。

 GDD Tシャツ。洗うとすごく色落ちしますw 缶バッジは入場時に一人当たり同じものが10個ずつ配られて、他の参加者と交換してコンプリートしてくださいということでした。参加者間の交流を促すための取り組みですね。私は知らない人に話しかけるのが苦手なので集まったのはこれだけw

 こちらも全員に配布されたzeemoteのBluetooth接続のジョイスティック。Android端末でゲームをやるときに使えます。ゲーム以外にもBluez IMEというIMEアプリを入れるとキーボード入力代わりにつかえるので、プレゼンでスライド送ったりとかにも使えていい感じです。3Dメガネはクロージングで動画を見るのに使う予定だったらしいのですが、Igniteが長引いたことで割愛されてしまったそうで。。。出番ありませんでした。

 全体的な感想としては、入場時の配布物とか昼のお弁当配布とかはもうちょっとスムーズにならないかなぁという感じです。だいぶ並んで待っている時間が長かったので。。
 セッションをしっかり聞こうと思うとバッジの交換とかブースを回ったりとかっていう時間はあんまり取れないのが残念なところですね。
 あとはセッション会場でも電源が取れると良かったんですが。。

posted by Png akanuma on Sat 5 Nov 2011 at 00:10

 Google Developer Day 2011 Japan に行ってきました。

 午前中の基調講演については前のエントリで感想等書いたので、今度は午後のブレイクアウトセッションについて少し。

「App Engine最新機能」

 今回のGDDでは自分としてはクラウド関係の情報に触れたいと思っていたので、主にクラウドトラックのセッションに参加してきました。中でもやっぱりGAEのセッション、「App Engine最新機能」を楽しみにしていました。

 セッションで使われたスライドはこちら。  http://goo.gl/2pNfD

 サイト上のセッション紹介ではMapReduce APIについても紹介がありそうに書かれていたので期待していたのですが、残念ながらセッションでの紹介はありませんでした。
 セッション冒頭で会場にアンケートを取ったところ、GAEを使っている人は6割程度、Java版とPython版が半々、Go版は3名ほどという感じ。自分のイメージではJava版を使っている人が多いと思っていたのですが、Python版を使っている方も多いんですね。

 自分はGAEについてはかなり前にチュートリアルをやった程度で今まで足りなかった機能とか最新機能としてこれが追加されてすごく良くなったとかはまりピンと来ていないのですが、いろいろなAPIがあったり、セキュリティやパフォーマンスの改善が行われていたり、トランザクションがサポートされるようになったり(XG Transaction)と最近追加されている内容だけでも盛りだくさんの様です。
 GAEのチームでは公約はしていないものの毎月リリースをする方針の様で、どんどん改善されていっている様ですね。ただ開発する側は大変だそうですw
 自分としては最近HadoopやAWSを触る機会が多かったので、比較できるように色々調べてみたいと思っています。

 そのほかに参加したセッションとしては、

「クラウド上でイケてるゲームを構築しよう」

 つかわれた資料はこちら

 ゲーム開発をほとんどしたことがない自分としては新鮮でした。PlanNというフレームワークを紹介していて、セッション内でバグレポートを実際に投稿したりw、その場でどんどんゲームの画面を作っていってしまうところがおもしろかったですが、なんと20分ぐらいでセッション終了。。

「今までにないサイトを作る:HTML5 による最新ウェブアプリ」

 Power of Cloud + Rich Front End でWebアプリを構築していくという内容で、「とにかくユーザの参入障壁を低くすることが重要」で、ユーザがサービスを使い始めるまでに必要な手間を極力減らすべきというようなことを言っていました。この点はすごく共感できますね。
 業務でWebアプリ開発をやっていると、サービス提供側としてはいろいろな情報を取りたくなってしまいますが、やっぱりそれではユーザがなかなか使い始めてくれないので、まずは使ってもらうことを意識することが必要ですね。

行っときゃ良かったと思ったセッション

 他のセッションとかぶっていたので出なかったんですが、Chromeのデベロッパーツールのセッションには行っておけば良かったと思ってます。他の方のTweetを見ていてもかなり良かったようで、実はこの一番日々の開発にすぐに活かせる内容だったのではないかと思ってます。

DevQuizの解説

 Igniteの最後にDevQuizの解説がありました。今回のボーダーラインは100.56点。自分は100.8点だったのでやっぱりギリギリ。。危なかった~。

 1400人以上が100点以上を獲得して、出題チームの意図に反して最後のスライドパズルの問題が決戦の場になってしまったようです。スライドパズル5000問のうち4000問目以上はそこまでより一気に難易度が上がっていた様で、解けた人は解けなかった人の1000倍速いアルゴリズムを組んでいたとのことです。自分は力づくのやり方しかできなかったので足元にも及びませんね。。

posted by Png akanuma on Thu 3 Nov 2011 at 13:49