Apache Mahout: 万人のためのスケーラブルな機械学習

機能強化された Mahout の現状を知り、クラウドで Mahout をスケーリングする方法を学んでください

Apache Mahout のコミッターである Grant Ingersoll が、Mahout 機械学習ライブラリーの最新バージョンについて説明し、よく使われている Mahout のアルゴリズムをデプロイし、スケーリングする方法の一例を紹介します。

Grant Ingersoll, Chief Scientist, Lucid Imagination

Grant IngersollGrant Ingersoll は Lucid Imagination の共同設立者兼チーフ・サイエンティストであり、Apache Mahout プロジェクトの共同設立者の 1 人です。『Taming Text』(Manning Publication より出版予定) の共著者の 1 人でもあります。



2011年 12月 16日

ソフトウェアの世界では、2 年という月日は永遠のように感じられます。この 2 年の間に私たちが目にしたのは、ソーシャル・メディアの華々しい台頭と、(Amazon や RackSpace などの企業による) 大規模なクラスター・コンピューティングの一般商品化、そしてデータの膨大化とそれらのデータを解明する能力の大幅な向上です。「Apache Mahout の紹介」が developerWorks に掲載されてからもう 2 年が経ちました。当時と比べ、Mahout コミュニティー (そして、このプロジェクトのコード・ベースと機能) は大きく成長しています。また、Mahout は企業の規模を問わず、世界のさまざまな企業で導入されるようになっています。

Mahout に関する前回の記事では、機械学習のさまざまな概念と Mahout のアルゴリズム・スイートの基本的な使い方を紹介しました。当時紹介した概念は今でも有効ですが、アルゴリズム・スイートについてはかなり大きく変化しています。この記事では基本概念の説明を繰り返すことはせず、Mahout の現状を紹介し、Amazon の EC2 サービスと 700 万通の E メール文書からなるデータ・セットを例として使用し、Mahout をコンピューター・クラスターにわたってスケーリングする方法を説明します。基礎知識を復習するには、『Mahout in Action』という書籍をはじめ、「参考文献」に記載されている資料を調べてください。さらに、この記事では読者に Apache Hadoop および Map-Reduce パラダイムの基本知識があることを前提とします (Hadoop の詳細は、「参考文献」を参照してください)。

Grant Ingersoll による Apache Mahout の機械学習に関するポッドキャスト

このポッドキャストでは、Apache Mahout のコミッターおよび共同設立者である Grant Ingersoll が機械学習とこれに関連する概念を紹介し、機械学習が実際のアプリケーションにどのように適用されるかを説明しています。

Mahout の現状

Mahout は瞬く間に大きな成長を遂げました。このプロジェクトでは、私が「3 つの C」と呼ぶ、協調フィルタリング (レコメンダー)、クラスタリング、分類に焦点が置かれていることは今でも変わりませんが、プロジェクトにはこれ以外の機能も追加されています。この記事でスポットを当てるのは、機械学習のコア・アルゴリズム (実装)、そしてサポート・インフラストラクチャー (入出力ツール、他のライブラリーとの統合ポイント、および参照用のサンプルを含む) という 2 つの領域で行われた重要な機能強化と改善内容です。ただし注意する点として、この状況は最終的なものではありません。さらに、記事のスペースは限られているため、それぞれの改善内容については簡単に説明することしかできません。読者の皆さんには、Mahout Web サイトの「News」セクションと各 Mahout リリースのリリース・ノートでさらに詳しく調べることをお勧めします。

さらに追加されたアルゴリズム

機械学習の問題を解決しようと取り組んでいるうちに気付くことですが、万事に適したアルゴリズムというものは存在しません。このことから、Mahout にはいくつもの新しい実装が追加されています。表 1 に、私が Mahout で最も重要だと考える新規アルゴリズム実装とその使用例を記載します。記事の後半では、この表に記載するアルゴリズムのうちのいくつかを使用します。

表 1. Mahout に新しく追加されたアルゴリズム
アルゴリズム概略使用例
ロジスティック回帰 (確率的勾配降下法 (SGD) による解決)要求の厳しい環境でのオンライン学習に対応した、非常に高速で単純な逐次型分類器。ユーザーに対して広告のレコメンデーションをする際、あるいはテキストをカテゴリーに分類する際などに適用。
隠れマルコフ・モデル (HMM: Hidden Markov Models)従来の分類アルゴリズムの逐次型並列実装。どのような生成プロセスが使われているのか不明な場合に実際のプロセスをモデル化するために作られたモデル。テキストの音声部分のタグ付けや、音声認識などに適用。
特異値分解 (SVD: Singular Value Decomposition)大規模な行列に含まれるノイズを減らすことにより、行列のサイズを小さくして扱いやすくするために設計された手法。特徴の選択を自動的に行うために、クラスタリング、レコメンデーション、分類を行う前などに適用。
ディリクレ・クラスタリング使われているモデルにデータが適合するかどうかに応じてメンバーシップを判断する、モデル・ベースのクラスタリング手法。データが重複する場合、または階層を持つデータに有用。
スペクトラル・クラスタリンググラフ・ベースの手法でクラスターのメンバーシップを判断する、似たような手法の集まり。すべてのクラスタリング・アルゴリズムと同じく、大規模で全体を把握するのが困難なデータ・セットを探る際に有用。
Minhash クラスタリングハッシュ化ストラテジーを使用して同様のアイテムをグループ化することにより、クラスターを生成する手法。他のクラスタリング手法と同じような状況で適用。
レコメンダーに対する数々の改善分散型共起、SVD、交互最小二乗法。恋愛・結婚マッチング・サイト、e-コマース、映画または本のレコメンデーションなどに適用。
コロケーションMap-Reduce 対応のコロケーション実装。テキストに含まれる語句のなかから、統計的に興味深い語句を検出する際などに適用。

Mahout にはさらに、それほど重要ではないけれどもユーザーにとって有用な数学アルゴリズムがいくつも追加されています (math パッケージを参照)。その多くは表 1 に記載したアルゴリズムで使用されていますが、もともと一般的な用途で使用するために設計されているため、ユーザーの特定の要求に合う可能性もあります。

Mahout のインフラストラクチャーの改善および拡張

Mahout のコマンドライン

先日 Mahout は、クラス・パスや環境変数などのセットアップ項目を処理して Mahout プログラム (main() を使用したプログラム) を実行しやすくするためのシェル・スクリプトを公開しました。mahout と名付けられたこのスクリプトは、$MAHOUT_HOME/bin ディレクトリーにあります。

より多くの人たちがオープンソース・プロジェクトのコードを自分のコードと連動させようと取り組むようになるのに伴い、インフラストラクチャーは充実してくるものです。Mahout では、このようなインフラストラクチャーの進化が数々の改善をもたらしています。なかでも最も注目に値するのは、大幅に改善されて一貫性を持つようになったコマンドライン・インターフェースです。このコマンドライン・インターフェースを使用すれば、ローカルおよび Apache Hadoop 上でタスクを実行依頼あるいは実行するのが以前よりも簡単にできるようになります。この新しいスクリプトは、Mahout の最上位レベルのディレクトリー (以降、$MAHOUT_HOME と呼びます) 内にある bin ディレクトリーに置かれています (囲み記事「Mahout のコマンドライン」を参照)。

あらゆる機械学習ライブラリーに共通する 2 つの主要コンポーネントは、信頼性のある数学ライブラリーと効率的なコレクション・パッケージです。Mahout が提供する math ライブラリー ($MAHOUT_HOME/math に含まれています) には、ベクトルや行列を表現するデータ構造から、ベクトルや行列を操作するための演算子、さらには乱数や有用な統計 (対数尤度など) を生成するためのツールに至るまで広範な機能が含まれています (「参考文献」を参照)。Mahout の collections ライブラリーには、Java のコレクションで提供されているデータ構造 (MapList など) と同様のデータ構造が含まれていますが、Mahout でネイティブにサポートしているのは Java のプリミティブ型である intfloatdouble などであり、これらに相当する Java のオブジェクト型である IntegerFloatDouble などはサポートされていない点が Java とは異なります。この点は重要です。なぜなら、数百万もの特徴が含まれる可能性のあるデータ・セットを扱っている場合には、1 つひとつのことが無視できなくなる上に、大規模なデータ・セットでプリミティブ型からそれに相当するオブジェクト型へボクシング (boxing) 変換する処理は膨大なものになるからです。

Mahout は Mahout のコア機能を補足、あるいは拡張することを目的としたコードが含まれる integration モジュールも新たに導入していますが、このモジュールは、あらゆる状況のあらゆるユーザーに必要となるわけではありません。例えばレコメンダー (協調フィルタリング) コードには現在、そのモデルを (JDBC を使用して) データベース、MongoDB、または Apache Cassandra (「参考文献」を参照) に格納するためのサポートが追加されています。その一方、integration モジュールにはデータを Mahout のフォーマットに変換するためのメカニズム、結果を評価するためのメカニズムも数多く含まれています。例えば、テキスト・ファイルでいっぱいのディレクトリーを Mahout のベクトル・フォーマットに変換できるツールもあります (integration モジュールに含まれる org.apache.mahout.text パッケージを参照)。

最後に付け加える改善内容として、Mahout には Netflix データ・セットを用いてレコメンデーションを計算するサンプルや Last.fm が提供する音楽をクラスタリングするサンプルをはじめ、新しい多数のサンプルが追加されています。さらに、私がこの記事のために開発したサンプルも Mahout のコード・ベースに追加されています。examples モジュール ($MAHOUT_HOME/examples に含まれています) で詳細をじっくり調べてみることをお勧めします。

Mahout の現状を踏まえた上で、ここからは記事の本題である、Mahout をスケール・アウトする方法について詳しく探っていきます。


クラウドでの Mahout のスケーリング

Mahout を効果的にスケーリングするということは、Hadoop クラスターにノードを追加するだけの簡単な話ではありません。メモリー、帯域幅、プロセッサー速度といったお決まりの要因に加え、アルゴリズムの選択、ノードの数、特徴の選択、そしてデータのスパースネスなどの要因のすべてが、Mahout がいかに効果的にスケーリングできるかを決定します。Mahout を効果的にスケーリングする方法について検討するために、これから Amazon の EC2 コンピューティング・インフラストラクチャーと、必要に応じて Hadoop (「参考文献」を参照) を使用して、ASF (Apache Software Foundation) で一般に公開されているメール・アーカイブのデータ・セットに対して Mahout のアルゴリズムを実行する例を取り上げます。

「セットアップ」に続くサブセクションごとに、Mahout をスケール・アウトする上での主要な課題を取り上げ、EC2 でサンプルを実行するための構文を検討します。

セットアップ

サンプル・コードを実行するためのセットアップには、ローカルでのセットアップと EC2 (クラウド) のセットアップが必要です。サンプル・コードを実行するには以下の環境を用意する必要があります。

  1. Apache Maven 3.0.2 以上
  2. Git バージョン管理システム (Githubアカウントも必要です)
  3. *NIX ベースのオペレーティング・システム (Linux または Apple OS X など。Windows では Cygwin を使用できるはずですが、Cygwin ではテストしていません。)

ローカルでセットアップをするには、コマンドラインで以下のコマンドを実行します。

  1. mkdir -p scaling_mahout/data/sample
  2. git clone git://github.com/lucidimagination/mahout.git mahout-trunk
  3. cd mahout-trunk
  4. mvn install (Mahout のテストは実行に時間がかかるため、-DskipTests を追加してこのテストを省略しても構いません)
  5. cd bin
  6. /mahout (実行できる項目 (kmeans など) が一覧表示されます)

以上の操作によって、必要なコードがすべてコンパイルされて適切にインストールされます。この操作とは別に、サンプル・データをダウンロードして scaling_mahout/data/sample ディレクトリーに保存し、(tar -xf scaling_mahout.tar.gz を実行することで) 解凍しておいてください。これはテスト用のサンプル・データで、EC2 で使用するデータのほんの一部を抜粋したものです。

Amazon でのセットアップを行うには、AWS (Amazon Web Services) アカウント (シークレット・キー、アクセス・キー、およびアカウント ID) と、Amazon の EC2 および EBS (Elastic Block Store) サービスが機能する仕組みについての基本的な知識が必要です。必要なアクセス権を取得するには、Amazon Web サイトの説明に従ってください。

ここまでの準備が整ったら、今度はクラスターを起動します。それには、1 つのノードから始めて、必要に応じてノードを追加していくのがおそらく最善です。EC2 上のインスタンスをノードとして実行すると、当然お金がかかることにも注意が必要です。ノードを実行する必要がなくなったら、必ずそのインスタンスをシャットダウンするようにしてください。

記事のサンプル・コードで使用するクラスターを起動するには、以下の手順に従います。

  1. ASF のミラー・サイトから Hadoop 0.20.203.0 をローカルにダウンロードして、解凍します。
  2. cd hadoop-0.20.203.0/src/contrib/ec2/bin を実行します。
  3. エディターで hadoop-ec2-env.sh を開き、以下のように編集します。
    1. Amazon から取得した AWS_ACCOUNT_IDAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYEC2_KEYDIRKEY_NAMEPRIVATE_KEY_PATH を入力します。詳細については、Mahout ウィキの「Use an Existing Hadoop AMI」ページ (「参考文献」を参照) を参照してください。
    2. HADOOP_VERSION0.20.203.0 に設定します。
    3. S3_BUCKET490429964467 に設定します。
    4. ENABLE_WEB_PORTS=true を設定します。
    5. INSTANCE_TYPE を最低でも m1.xlarge に設定します。
  4. エディターで hadoop-ec2-init-remote.sh を開き、以下のように編集します。
    1. hadoop-site.xml を作成するセクションに、以下のプロパティーを追加します。
      <property>
      <name>mapred.child.java.opts></name>
      <value>-Xmx8096m></value>
      </property>
      注: 分類を実行する場合には、より大きなサイズのインスタンスとメモリーが必要です。私が使用したのは、「ハイメモリ ダブル エクストララージ」インスタンスと 12GB のヒープです。
    2. mapred.output.compressfalse に変更します。
  5. 以下のコードを実行してクラスターを起動します。
    ./hadoop-ec2 launch-cluster mahout-clustering X
    X は、起動するノードの数です (例えば、2、または 10 など)。まずは小さな値から始めて、使い慣れてくるに従ってノードを増やしていくことをお勧めします。このようにすることで、コストを管理しやすくなります。
  6. ASF の公開データ・セット (スナップショット: snap--17f7f476) 用の EBS ボリュームを作成し、それを /dev/sdh 上のマスター・ノード・インスタンス (mahout-clustering-master セキュリティ・グループ内のインスタンス) にアタッチします (「参考文献」に、EC2 オンライン・マニュアルで説明している詳しい手順へのリンクが記載されています)。
    1. EC2 コマンドライン API (「参考文献」を参照) を使用している場合には、以下の方法を使用することができます。
      1. ec2-create-volume --snapshot snap-17f7f476 --z ZONE を実行します。
      2. ec2-attach-volume $VOLUME_NUMBER -i $INSTANCE_ID -d /dev/sdh を実行します。ここで、$VOLUME_NUMBER は前のボリューム作成ステップによる出力、$INSTANCE_ID は launch-cluster コマンドで起動したマスター・ノードの ID です。
    2. この作業は、AWS Web コンソールで行うこともできます。
  7. setup-asf-ec2.sh スクリプト (「ダウンロード」を参照) をマスター・インスタンスにアップロードします。
    ./hadoop-ec2 push mahout-clustering $PATH/setup-asf-ec2.sh
  8. クラスターにログインします。
    ./hadoop-ec2 login mahout-clustering
  9. 以下のようにして、シェル・スクリプトを実行します。このスクリプトによって、システムが更新され、Git と Mahout がインストールされ、アーカイブの一部がクリーンアップされて実行しやすくなります。
    ./setup-asf-ec2.sh

これで、セットアップの作業が完了したので、次のステップは、よく使用されている Mahout のアルゴリズムを本番環境に適用してスケール・アウトするとはどういうことなのかを理解することです。この記事では主に、実際のスケール・アウト作業に重点を置いて説明しますが、これらのタスクを行う過程で、特徴の選択についての疑問点、そして私が特定の選択を行った理由を説明します。

レコメンデーション

協調フィルタリングは Mahout で最もよく使われていて、しかも簡単に使用できる機能の 1 つです。したがって、Mahout をスケール・アウトする方法について説明するには、協調フィルタリングから始めるのが妥当でしょう。ここで操作対象としているのは、ASF のメール・アーカイブであることを思い出してください。レコメンデーション・タスクの場合、その興味深い方法の 1 つとして考えられるのは、他のユーザーが読んだメールのスレッドに基づいて、ある特定のユーザーに対し、関心がありそうなメール・スレッドを推薦するシステムを作成することです。これを協調フィルタリングの問題としてセットアップするために、システムがメール・スレッドとして推薦するアイテムを、メールのヘッダーに含まれる Message-ID と References を基に定義します。ユーザーを定義するには、メール・メッセージに含まれる送信元 (From) アドレスを使用します。つまり、私が関心を持っているのは、メール・メッセージを発信または返信したユーザーであるということです。プリファレンスの値については、単純にメール・スレッドを操作したどうかをブール値プリファレンスとし、ユーザー X がスレッド Y を操作した場合は on、操作しなかった場合は off に設定します。ブール値プリファレンスを選択したことによって波及する影響の 1 つは、ブール値プリファレンスと連携する類似性測度 (Tanimoto 係数や対数尤度などによる類似度) を使用する必要が出てくることです。類似性測度を使用すると、通常は計算時間が短縮され、システム内のノイズの量が減る傾向がありますが、利用価値は人それぞれなので、別の重みで試すのでも構いません。

スレッド、メッセージ ID、そして次善の策

注意する点として、メッセージ・スレッドを処理するために私が採っている手法は完璧なものではありません。それは、メーリング・リストではいくぶん日常茶飯事となっている、スレッド乗っ取りが理由です。スレッド乗っ取りは、メーリング・リストの既存のメッセージに返信するという方法で新しいメッセージ (つまり、新しい件名/トピックのメッセージ) を始めた場合に発生します。これにより、元のメッセージ・リファレンスが新しいメッセージと一緒に渡されるためです。実際のソリューションではスレッド乗っ取りに真正面から取り組む必要がありますが、記事ではこの問題には対処せず、単に無視することにしました。したがって、ここでは完璧な手法の代わりに、「必要を満たすには十分な」手法を選んでいます。

協調フィルタリング (ユーザー、アイテム、オプションのプリファレンス) に関しては、特徴の選択は単純明快なので、まだ何も処理していないメール・アーカイブからコンテンツを取得するステップを始めとし、ローカルでの実行ステップ、クラウドでの実行ステップまでを駆け足で説明します。ただし多くの環境で、最後のステップはほとんど必要ないことに注意してください。この一連のステップに Hadoop の複雑な処理を含めなくても、1 台のマシンで十分迅速に結果を出せるからです。概算として、Mahout コミュニティーのベンチマークには、単一のノードでも最大 1 億人のユーザーに無理なくレコメンデーションを提供できることが示唆されています。ただし、この E メール・データの例では、アイテムの数はそれほど多くはありませんが (約 700 万件のメッセージ)、Hadoop で実行することにします。

コードの処理内容を確認できるように、必要なステップをまとめて 1 つのシェル・スクリプトにパッケージ化しておきました。このシェル・スクリプトは、$MAHOUT_HOME/examples/bin/build-asf-email.sh ファイルに含まれています。以下のように入力データの場所と結果の出力先をパラメーターとして渡して、シェル・スクリプトを実行してください。

./build-asf-email.sh ./scaling_mahout/data/sample/content ./scaling_mahout/output/

プロンプトが出されたら、recommender (オプション 1) を選択します。後はゆったりくつろいで、Mahout と Hadoop の詳細なログ出力を眺めてください。シェル・スクリプトの実行が完了すると、リスト 1 のような結果が表示されます。

リスト 1. レコメンダー・コードの実行による出力例
11/09/08 09:57:37 INFO mapred.JobClient: Reduce output records=2072
11/09/08 09:57:37 INFO mapred.JobClient: Spilled Records=48604
11/09/08 09:57:37 INFO mapred.JobClient: Map output bytes=10210854
11/09/08 09:57:37 INFO mapred.JobClient: Combine input records=0
11/09/08 09:57:37 INFO mapred.JobClient: Map output records=24302
11/09/08 09:57:37 INFO mapred.JobClient: SPLIT_RAW_BYTES=165
11/09/08 09:57:37 INFO mapred.JobClient: Reduce input records=24302
11/09/08 09:57:37 INFO driver.MahoutDriver: Program took 74847 ms

このジョブの実行結果として、入力データに含まれるすべてのユーザーに対するすべてのレコメンデーションが生成されます。結果の格納先は、指定した出力ディレクトリー内に作成される prefs/recommendations という名前のサブディレクトリーです。結果として生成されるファイルのなかには、名前が part-r- で始まるテキスト・ファイルが 1 つ以上あります (Hadoop はこのようなファイルを出力として生成します)。これらのファイルのいずれかを調べると、レコメンデーションのフォーマットは以下のようになっているはずです (ただし、1 つの注意点があります)。

user_id [item_id:score, item_id:score, ...]

例えば、ユーザー ID 25 に対して、E メール ID 26295 および 35548 がレコメンデーションされているとします。注意点とは単純に、user_iditem_id は元の ID ではなく、元の ID から整数へマッピングしたものであることです。なぜこのようなことが行われるのかを理解できるように、このシェル・スクリプトが実行されると実際にどのような処理が行われるのかを説明します。

レコメンデーションは、以下の 3 つのステップで生成されます。

  1. Mahout の SequenceFilesFromMailArchives を使用して、まだ処理する前の mbox ファイルが Hadoop の SequenceFile フォーマットに変換されます。
  2. メッセージからメッセージ ID と送信元シグニチャーが抽出され、Mahout が理解できるフォーマットで結果が出力されます。
  3. Mahout の RecommenderJob クラスが実行されます。

ステップ 1 については、ここでは説明しませんので、興味のある読者の方はコードを参照してください。

ステップ 2 には、ファイルから関連する情報 (メッセージ ID、返信リファレンス、送信元アドレス) を抽出し、これらの情報を RecommenderJob で使用できる 3 つのセット (From ID、Message-ID、プリファレンス) として保存するための処理も含まれます。そのためのプロセスは、以下の 3 つの Map-Reduce ジョブで構成された MailToPrefsDrive によって実行されます。

  1. ストリング・ベースのメッセージ ID と固有 long との辞書マッピングを作成します。
  2. ストリング・ベースの送信元 E メール・アドレスと固有 long との辞書マッピングを作成します。
  3. メッセージ ID、リファレンス、送信元を抽出し、ステップ 1 とステップ 2 で作成した辞書を使用して、そのそれぞれを long にマッピングし、テキスト・ファイルに出力します。

以上の処理が完了した後、レコメンデーションの生成段階に入ります。図 1 に、レコメンデーションを作成するために RecommenderJob が行うステップを示します。

図 1. レコメンダー・ジョブのフロー
レコメンダー・ジョブのフロー

このワークフローのなかで大変な処理を行う主要なステップは、「共起の計算 (Calculate co-occurrences)」のステップです。このステップは行列全体で一対比較を行い、類似性を探します。余談ですが、(Mahout の RowSimilarityJob が実行する) このステップは一般に、行列内の 2 つの行の間 (評価/レビューだけでなく、あらゆる行の間) で対ごとに計算する際にも役立ちます。

RecommenderJob は、シェル・スクリプト内で以下のコマンドによって呼び出されます。

bin/mahout recommenditembased --input $PREFS_REC_INPUT --output $RECS_OUT --tempDir
    $PREFS_TMP --similarityClassname SIMILARITY_LOGLIKELIHOOD

最初の引数は、Mahout に対し、実行するコマンド (RecommenderJob) を指示します。残りの引数の多く (inputoutputtempDir) は名前から明らかです。similarityClassname は、Mahout に対し、共起を計算するときにアイテム間の類似性をどのように計算するかを指示します。私はその単純さ、速度、品質から、類似性の計算に対数尤度を使用することにしました。

結果が得られたら、それを評価します。Mahout には、結果の品質を検査するのに役立つツールを集めた評価用パッケージ (org.apache.mahout.cf.taste.eval) が付属しています。このパッケージのツールは Hadoop ベースのアルゴリズムでは機能しませんが、それ以外の場合には役に立つはずです。これらのツールは一定の割合のデータをテスト・データとして差し出し、そのテスト・データをシステムが生成した結果と比較して、結果の品質を判定します。

レコメンデーションを生成するためのプロセスは、これだけです。そして、このプロセスの素晴らしさは、クラスターで直接実行できるところにあります。クラスターで実行するには、事前にセットアップしておいた EC2 クラスターにログインし、ローカルで実行するときと同じシェル・スクリプト (/mnt/asf-email/mahout-trunk/examples/bin 内にあります) を同じ方法で実行します。クラスターにノードを追加していくと、その分、レコメンデーションの生成ステップの所要時間が短くなっていくことがわかります。一例として、全データ・セットを 1 台のローカル・マシンで実行すると、完了するまでに 3 日かかります。EC2 の 10 のノードからなるクラスターで実行した場合には、メインのレコメンデーション・タスクだけでなく、E メールを使用可能なフォーマットに変換する準備作業を入れても、所要時間はわずか 60 分ほどです。

最後の作業は、読者の皆さんの演習用に残しておきます。それは、レコメンデーションをアプリケーションの一部として使用することです。一般には、システムのアイテムとユーザーが相当な数に達すると、レコメンデーションは定期的に生成されるようになります。ビジネスのニーズにもよりますが、通常は 1 時間ごと、あるいは毎日 1 回という間隔です。結局のところ、システムが特定の量のユーザーおよびレコメンデーションに達すれば、生成されるレコメンデーションの違いはごくわずかなものになります。

次は、E メール・メッセージの分類に目を向けます。場合によっては、分類はコンテキストに依存したレコメンデーション・システムであると考えられます。

分類

Mahout にはいくつかの分類アルゴリズムがあり、そのほとんどは Hadoop で実行するように作成されています (その例外として、確率的勾配降下法は注目に値します)。この記事では、単純ベイズ分類器を使用します。単純ベイズ分類器は多くの人々が始めに取り掛かる分類器で、大抵は妥当な結果を出すだけでなく、効果的なスケーリングを行うからです。その他の分類器についての詳細は、『Mahout in Action』の該当する章、あるいはMahout ウィキの「Algorithms」セクション (「参考文献」を参照) を読んでください。

E メール文書は Apache プロジェクト別 (Lucene、Mahout、Tomcat など) に分かれています。それぞれのプロジェクトには、通常、複数のメーリング・リスト (ユーザー用メーリング・リスト、開発用メーリング・リストなど) があります。ASF の E メール・データ・セットがプロジェクトごとに区分されていることを考えると、論理的な分類の問題となるのは、新着メッセージの配信先プロジェクトを予測することです。例えば、新しいメッセージが Lucene メーリング・リストに属するのか、あるいは Tomcat メーリング・リストに属するのかを予測します。

Mahout の分類アルゴリズムを機能させるには、識別するパターンを表現するようにモデルを訓練してから、そのモデルをデータのサブセットに対してテストする必要があります。ほとんどの分類の問題では、1 人以上の担当者がデータを調べ、訓練で使用するデータのサブセットに手作業でアノテーションを付けますが、ありがたいことに、この場合のデータ・セットはすでにプロジェクト別に分けられているので、手作業でアノテーションを付ける必要はありません。ここでは、人々が E メールを送信するときに通常は正しいメーリング・リストを選ぶことを前提としますが、ご存知のとおり、常に正しいメーリング・リストが選択されるとは限りません。

レコメンダーの場合と同じく、必要なステップは build-asf-email.sh スクリプトにあらかじめパッケージされています。メニューからオプション 3 を選択すると (そして、2 番目のプロンプトで標準の単純ベイズに対応するオプション 1 を選択すると)、このスクリプトが実行されます。レコメンデーションと同じように、コードをスケール・アウトする際の作業には、使用するデータの準備も含まれます。テキストの分類の場合、データの準備とは、主に特徴をエンコードして、これらの特徴からベクトルを作成することを意味しますが、訓練用セットとテスト用セットのセットアップもこの準備作業の 1 つです。以下に、実行されるステップをひと通り示します。

  1. Mahout の SequenceFilesFromMailArchives によって、まだ処理する前の mbox ファイルが Hadoop の SequenceFile フォーマットに変換されます (ランタイム・オプションがレコメンデーションの場合と多少異なっていることに注意してください)。
    bin/mahout org.apache.mahout.text.SequenceFilesFromMailArchives --charset "UTF-8" 
        --body --subject --input $ASF_ARCHIVES --output $MAIL_OUT
  2. SequenceFile のエントリーをスパース・ベクトルに変換し、以下のようにラベルを変更します。
    1. bin/mahout seq2sparse --input $MAIL_OUT --output $SEQ2SP --norm 2 --weight TFIDF --namedVector --maxDFPercent 90 --minSupport 2 --analyzerName org.apache.mahout.text.MailArchivesClusteringAnalyzer
    2. bin/mahout org.apache.mahout.classifier.email.PrepEmailDriver --input $SEQ2SP --output $SEQ2SPLABEL --maxItemsPerLabel 1000
  3. 入力を訓練用セットとテスト用セットに分割します。
    bin/mahout split --input $SEQ2SPLABEL --trainingOutput $TRAIN --testOutput $TEST
        --randomSelectionPct 20 --overwrite --sequenceFiles
  4. 単純ベイズ分類器を実行して、訓練およびテストを行います。
    1. bin/mahout trainnb -i $TRAIN -o $MODEL -extractLabels --labelIndex $LABEL
    2. bin/mahout testnb -i $TEST -m $MODEL --labelIndex $LABEL

注目すべき主な 2 つのステップは、ステップ 2 とステップ 4 です。ステップ 2a は、主要な特徴を選択してエンコードするステップであり、数々の入力パラメーターによって、ベクトル内で入力テキストを重みとして表現する方法が制御されます。表 2 に、ステップ 2 での特徴の選択に関連するオプションのそれぞれについて説明します。

表 2. ベクトルを作成するための特徴の選択オプション
オプション説明例および注記
--normノルムは、ベクトルの長さ (ノルム) を計算する関数によって、すべてのベクトルを変更します。1: ノルム = マンハッタン距離、2: ノルム = ユークリッド距離
--weight特定の特徴の重みを、TF-IDF (Term Frequency, Inverse Document Frequency: 単語の出現頻度と逆文書頻度) として計算するか、あるいは TF (Term Frequency: 単語の出現頻度 ) としてだけ計算します。テキストをベクトルとして表現する検索および機械学習では、重み付け方式として TF-IDF が共通して使用されています。
--maxDFPercent, --minSupport文書の集合全体で出現頻度が高すぎる用語 (max) または低すぎる用語 (min) を破棄するためのオプションです。計算にとってほとんど価値のない一般的な用語や出現頻度が低すぎる用語を自動的に破棄するのに役立ちます。
--analyzerName文書内の単語のトークン化、語幹処理、削除、またはその他の変更を行うために使用できる Apache Lucene アナライザー・クラスを指定します。Lucene についての詳細は、「参考文献」を参照してください。

ステップ 2a の分析プロセスは、特徴を選択するために必要とされる大変な処理のほとんどを行うことから、もう少し詳しく説明しておく価値があります。Lucene の AnalyzerTokenizer クラスのみからなるか、もしくは Tokenizer クラスと 1 つ以上の TokenFilter クラスからなります。Tokenizer の役目は、元の入力をゼロまたは 1 つ以上のトークン (単語など) に分割することです。Tokenizer によって生成されたトークンは、1 つに連結された TokenFilter インスタンスによって変更されます。例えば、この例で使用している Analyzer は以下の処理を行います。

  1. ホワイト・スペース (さらには、句読点に対するいくつかのエッジ・ケース) を基準にトークン化します。
  2. すべてのトークンを小文字にします。
  3. 非 ASCII 文字を ASCII 文字に変換します (音声区別符号などを変換することによって変換可能な場合)。
  4. 40 文字を超えるトークンを破棄します。
  5. ストップ・ワードを削除します (ストップ・ワードの一覧はここに記載するには長すぎるため、コードを参照してください)。
  6. Porter ステマー (「参考文献」を参照) を使用してトークンの語幹処理を行います。

この分析によって、最終的には各文書のベクトルが大幅に小さくなるだけでなく、分類器を混乱させる一般的な「ノイズ」語 (the、a、an など) がベクトルから削除されます。この Analyzer は、E メールのサンプルを調べ、その E メールに対して処理を行って出力を調べ、次の処理として最善の方法を判断するための呼び出しを行うという作業を繰り返すように作られています。このプロセスは科学的ではありますが、一方では残念ながら (経験的で) 直観的なものです。このプロセスとその結果は完璧には程遠いとは言え、おそらく必要を満たすには十分でしょう。

ステップ 2b では、データを処理できるようにマイナーな変換を行うと同時に、各種のラベルが同じように訓練用データで表現されるように一部のコンテンツを破棄します。これは重要な点です。私が最初にこのデータで実験したときに、機械学習ではよくありがちな問題が起こりました。それは、ラベルがあまりにも多くの訓練用サンプルと一致するという問題です。実のところ、クラスターで完全なデータ・セットを使用して実行する際には、--maxItemsPerLabel の設定を 1000 まで下げても、優れた結果を出すには十分でありません。メーリング・リストのなかには、投稿数が 1000 件を下回るリストもあるからです。これはおそらく、コミュニティーが現在調査している Mahout のバグが原因であると思われます。

モデルを作成し、作成したモデルが有効であるかどうかをテストするための実際の作業は、ステップ 4 で行われます。ステップ 4a では、--extractLabels オプションが Mahout に対し、入力から訓練用ラベルを見つけるように指示しているだけです (あるいは、ラベルを渡すという方法もあります)。このステップによる出力は 1 つのファイルで、そのファイルは org.apache.mahout.classifier.naivebayes.NaiveBayesModel クラスによって読み取ることができます。ステップ 4b ではモデルとテスト・データの両方をパラメーターとして取り、訓練の成果を確認します。その出力は、「Apache Mahout の紹介」で説明した混同行列です。サンプル・データで実行した場合、出力はリスト 2 のようになります。

リスト 2. 分類器コードの実行による出力例
Correctly Classified Instances : 41523 61.9219%
Incorrectly Classified Instances : 25534 38.0781%
Total Classified Instances : 67057
=======================================================
Confusion Matrix
-------------------------------------------------------
a b c d e f ><--Classified as
190440 12 1069 0 0 | 20125 a= cocoon_apache_org_dev
2066 0 1 477 0 0 | 2544 b= cocoon_apache_org_docs
165480 2370 704 0 0 | 19622 c= cocoon_apache_org_users
58 0 0 201090 0 | 20167 d= commons_apache_org_dev
147 0 1 4451 0 0 | 4599 e= commons_apache_org_user

この出力を見てわかるとおり、(推測よりはましとは言え) これは分類器としてはかなり振るわない結果です。このお粗末な結果の原因としては、指定された Apache プロジェクトのユーザー用メーリング・リストと開発用メーリング・リストが用語の点であまりにも密接に関連していることから、単にこの 2 つを区別しきれなかったことが考えられます。それを裏付けるのは、16,548 件の cocoon_user メッセージが誤って cocoon_dev として分類されている事実です。実際、サンプル・データのユーザー用メーリング・リストと開発者用メーリング・リストを区別せずに、プロジェクト名だけを使ってもう一度タスクを実行すると、リスト 3 の結果になります。

リスト 3. プロジェクト名だけを使用して分類器コードをもう一度実行した場合の出力例
Correctly Classified Instances : 38944 96.8949%
Incorrectly Classified Instances : 1248 3.1051%
Total Classified Instances : 40192

=======================================================
Confusion Matrix
-------------------------------------------------------
a b c ><--Classified as
18733 1241 0 | 19974 a = cocoon_apache_org
7 20211 0 | 20218 b = commons_apache_org

おそらく同意してもらえると思いますが、96 パーセントという分類の精度は、61 パーセントに比べてちょっと出来すぎです。実際、これが正しい結果であるならば、あまりにも良すぎるかもしれません。このような値になったのは、この特定の小さなデータ・セットが持つ特性によるものか、そうでなければ、調査が必要な難解な問題が潜んでいる可能性があります。実際、このように出来すぎた結果となった場合には、さらに詳しく調査するために、データを追加したり、結果を生成するコードを見直したりする必要があります。ここでは、どのような結果になるかを説明する一例として、このコードのままで妥協しますが、精度を上げるためには、他の手法を試したり、より良い特徴を選択したり、訓練用のデータを増やしたりすることになるでしょう。また、結果の交差畳み込み検証 (cross-fold validation) を行うのも一般的です。交差畳み込み検証では、訓練用サンプルからデータの一部を取得して、それをテスト用サンプルに組み込むか、あるいは除外するかのいずれかの処理を行って、コードを実行するという作業を繰り返します。そして最後に、システムが 1 回の実行結果のみからではなく、すべての実行結果の品質に基づいて判断をします。

分類のプロセスをクラウドに適用するのは、レコメンダーの場合と同じく簡単です。スクリプトを適切なパスに渡すだけで、完全なスクリプトがクラスター内で実行されます。このスクリプトを EC2 の 10 のノードからなるクラスターで実行した結果、訓練とテスト、さらに通常の準備作業にかかったのは、ほんの数分だけでした。けれども残念なことに、クラウドで完全なデータ・セットに対してスクリプトを実行する場合、実行品質は劣化します。この問題は、一部のメーリング・リストにはわずかな数のデータ・ポイントしかないことが原因となっているため、検討事項には入れなくてもよいはずです。

アルゴリズムを本番環境に適用するための次のステップでは、モデルをランタイム・システムの一部として使用できるようにするとともに、システムからフィードバックを取得した時点でモデルが更新されるようにワークフローをセットアップするという作業が必要になります。次は、クラスタリングに話題を移します。

クラスタリング

Mahout には、分類の場合と同じく、それぞれに異なる特性を持つ多数のクラスタリング・アルゴリズムがあります。例えば、K 平均法はスケーラビリティーの面で優れていますが、必要なクラスターの数を前もって指定しなければなりません。一方、ディリクレ・クラスタリングでは、必要なクラスターの数だけでなく、モデル分布も選定する必要があります。クラスタリングには分類と共通する部分がかなりあるため、クラスターを分類処理のなかで使用することで、所々でこの 2 つを連動させることが可能です。さらに、分類でのデータ準備作業のほとんどは、クラスタリングでのデータ準備作業と共通しているため (まだ処理する前のコンテンツをシーケンス・ファイルに変換してからスパース・ベクトルに変換するなど)、クラスタリングでの準備作業については「分類」セクションを参照してください。

クラスタリングで第 1 に答えを出さなければならない問題は、プロジェクトとは関係なく、コンテンツの類似性を基にすべてのメッセージを論理的にグループ化できるかどうかです。例えば、Apache Tomcat を Web コンテナーとして使用する方法についての Apache Solr メーリング・リストのメッセージは、元のプロジェクトである Apache Solr に対するメッセージというよりも、Tomcat プロジェクトに対するメッセージに近くなります。

この例での初めのほうのステップは分類とほとんど同じで、クラスタリング固有のステップに分岐するのは、スパース・ベクトルへの変換が完了した後です。以下に、具体的なステップを説明します。

  1. スタップ 1 とステップ 2 は、分類でのステップと同じです。
  2. $ bin/mahout kmeans --input "$SEQ2SP/tfidf-vectors" --output $CLUST_OUT -k 50 --maxIter 20 --distanceMeasure org.apache.mahout.common.distance.CosineDistanceMeasure --clustering --method mapreduce --clusters "$CLUST_OUT/clusters"

この例では、K 平均法を実行してクラスタリングを行いますが、このシェル・スクリプトはディリクレ・クラスタリングの実行もサポートします (スクリプトを実行すると、適用するアルゴリズムを選択するよう求めるプロンプトが出されます)。上記の例で詳しく説明する価値があるのは、以下のパラメーターです。

  1. -k: 作成するクラスターの数。私は無作為に 50 としましたが、当然、他の値にすることできます。
  2. --maxIter: K 平均法は繰り返し型のアルゴリズムであり、繰り返しごとに処理のなかでクラスターの重心が更新されていきます。場合によっては、このアルゴリズム自体が完了することは保証されないため、このパラメーターによって確実に完了するようにします。
  3. --distanceMeasure: 距離測度によって、クラスターの現在の重心と検討対象としているポイントとの類似性が判断されます。この例では、ほとんどのテキスト・データにとって最適な選択であるコサイン類似度を使用しています。Mahout には他にも多数の実装があるので、データを使用してさまざまな実装を試してみるとよいでしょう。
  4. --clustering: Mahout に、どのポイントがどの重心に属しているのかを出力するように指示します。ほとんどの場合には重心を計算するだけでよいので、デフォルトでは、Mahout は単に重心を計算するだけです。

スクリプトの実行が完了した後にクラスターの重心 (および関連するポイント) をダンプ出力するには、Mahout の ClusterDump プログラムを使用します。最終結果は、kmeansディレクトリー内の名前が clusters- で始まり、-final で終わるサブディレクトリーに格納されます。このサブディレクトリーの正確な名前は、タスクを実行するために繰り返し処理が何回行われたかによって決まります。例えば、3 回目の繰り返し処理からの出力は、clusters-2-final となります。一例として、以下のコマンドは、小さなサンプル・データを実行した後にクラスターをダンプするためのコマンドです。

bin/mahout clusterdump --seqFileDir ../output/ibm/clustering/kmeans/clusters-2-final
    --pointsDir ../output/ibm/clustering/kmeans/clusteredPoints/

--seqFileDir は作成された重心を指します。-pointsDir は、クラスタリングされたポイントのディレクトリーです。リスト 4 に、結果の一部を抜粋します。

リスト 4. ClusterDumper の実行による出力例
:VL-337881{n=4420 c=[
  Top Terms:
    user                                    =>0.060885823267350335
    mailscann                               => 0.05059369006868677
    cocoon                                  =>0.048781178576134204
    virus                                   => 0.04285897589148712
    derek                                   => 0.04084340722527813
    legal                                   =>0.040052624979813184
    scan                                    => 0.03861016730680097
    danger                                  => 0.03848600584647758
    csir                                    => 0.03712359352614157
    transtec                                => 0.03388019099942435
  Weight : [props - optional]:  Point:
  1.0 : [distance=0.888270593967813]: 
  /cocoon.apache.org/dev/200004.gz/NBBBIDJGFOCOKIOHGDPBKEPPEEAA.XXXXX = 
  [ag:0.165, briefli:0.250, chang:0.075, close:0.137, cocoon:0.060, 
  cocoon1:0.226, cocoon2:0.218, concept:0.277, develop:0.101, differ:0.144, 
  explain:0.154, greet:0.197, klingenderstrass:0.223, langham:0.223, look:0.105, 
  mailserv:0.293, matthew:0.277, mlangham:0.240, paderborn:0.215, processor:0.231, 
  produc:0.202, put:0.170, scan:0.180, tel:0.163, understand:0.127, virus:0.194]

リスト 4 の出力には、アルゴリズムがこのクラスターで最も代表的であると判断した用語がリストアップされていることに注目してください。このリストは、本番環境で使用するラベルを生成する際にも、準備ステップで特徴の選択を調整する際にも役立ちます。なぜなら、最初に何回かデータを実行して試してみることで、リスト内にストップ・ワード (この例では、例えば user がこれに該当するはずです) が現れる場合が多々あるためです。

すでにお察しのことと思いますが、このスクリプトをクラスターに対して実行するのは、ローカルで実行する場合や他の 2 つの例の場合と同じように簡単です。10 のノードを使用したテストでは、コンテンツを変換する時間 (約 150 分) とは別に、実際のクラスタリング・ジョブにかかった時間は約 40 分でした。

クラスタリングでは、結果を評価する作業が「嗅覚テスト」になりがちですが、Mahout には評価のために利用できるツールがいくつか用意されています (CDbwEvaluator、および上位用語を出力するための ClusterDumper オプションを参照)。嗅覚テストでは、クラスターを可視化することが最も効果的な方法となる場合がよくありますが、残念ながら多くのグラフ表示ツールキットは大規模なデータ・セットに対応しきれないため、独自のデバイスを使用して可視化しなればならないこともあります。

レコメンデーションや分類の場合と同じく、アルゴリズムを本番環境に適用するステップには、データを取得するためのワークフローと処理回数の決定、そしてもちろん、ビジネス環境で活用できるようにすることが関連します。さらに、各種のアルゴリズムに取り組んで、データに最も有効に作用するアルゴリズムを調べる必要もあるでしょう。


Mahout の今後

Apache Mahout は多くの点で進化を続けています。現在、コミュニティーでは 1.0 リリースを主眼に、パフォーマンス・テスト、ドキュメントの作成、API の改善、そして新しいアルゴリズムの追加を推し進めています。次回の 0.6 がリリースされるのは、2011年の終わりか、その少し先ぐらいになりそうです。より深いレベルでは、コミュニティーは分散メモリーを使用するインメモリーの手法で機械学習の問題を解決する方法について調査を開始しています。多くの場合、機械学習の問題は 1 台のマシンで対処するには大きすぎますが、Hadoop ではディスク I/O によってあまりにも大きなオーバーヘッドが生じます。どの手法を採るかに関わらず、現在最も切迫しているビッグ・データの問題解決を支援するために、Mahout はスケーラビリティーに重点を置き、複雑な機械学習アルゴリズムを簡単に使用できるように体制を整えています。

謝辞

AMI パッケージの作成を支援してくれた Timothy Potter 氏、そしてテクニカル・レビューを行ってくれた Mahout のコミッターである同僚の Sebastian Schelter 氏、Jake Mannix 氏、Sean Owen 氏に深く感謝いたします。この研究の一部は、Amazon Apache Testing Program によってサポートされています。


ダウンロード

内容ファイル名サイズ
Shell scriptj-mahout-scaling.zip2KB

参考文献

学ぶために

  • Apache Mahout の紹介」(Grant Ingersoll 著、developerWorks、2009年9月): Mahout プロジェクトの共同設立者の 1 人、Ingersoll が機械学習の基本的な概念を紹介し、Mahout を使って文書をクラスタリングする方法、レコメンデーションを行う方法、コンテンツを構成する方法を説明しています。
  • Apache Mahout: Apache Mahout のホーム・ページを常時チェックして、最新のニュース、資料、新しいダウンロードを入手してください。
  • Powered By Mahout」: Mahout を支えているのは、リンク先のページに記載した、Mahout のアルゴリズムを使用していることを進んで宣言している会社です。
  • Taming Text』(Grant S. Ingersoll、Thomas S. Morton、Andrew L. Farris 共著、Manning Publications、2011年): Mahout および関連するオープンソース技術によるテキスト・ベースのアプリケーション構築を取り上げた一冊です。
  • Mahout in Action』(Sean Owen、Robin Anil、Ted Dunning、Ellen Friedman 共著、Manning Publications、2011年): この本は、Mahout を理解する上で最も信頼の置けるガイドとなります。
  • Apache Hadoop: Hadoop について学んでください。
  • Algorithms: Mahout ウィキで、Mahout が実装するアルゴリズム、そしてコミュニティーにとって興味深い分野に関する詳細を読んでください。
  • Surprise and Coincidence」: Mahout のコミッターである Ted Dunning のブログで、対数尤度測定の有用性についての詳細を読んでください。
  • MongoDB: MongoDB の Web サイトで MongoDB の詳細を調べてください。
  • Apache Cassandra: Apache Cassandra の Web サイトをブラウズして、Cassandra の詳細を調べてください。Cassandra を Mahout で使用する場合については、Sean Owen のブログ投稿「Recommending (from) Cassandra」で詳しく説明しています。
  • EC2 を含む Amazon Web サービス: Amazon の EC2 インフラストラクチャーについて詳しく学んでください。
  • Use an Existing Hadoop AMI: Mahout ウィキのこのページで、EC2 で Hadoop クラスターを起動するプロセスが詳しく解説されています。
  • Amazon EC2 User Guide: この記事の「セットアップ」ステップについては、EC2 User Guide を参照してください。
  • Message-ID: メール・ヘッダーと Message-ID の詳細を学んでください。
  • Apache Lucene: Apache Lucene の Web サイトで Lucene の詳細を調べてください。
  • Dr. Martin Porter の Snowball ステマー: これらのステマーは、検索および機械学習プロジェクトでテキストを処理する際に役立つことがよくあります。
  • Technology bookstore で、この記事で取り上げた技術やその他の技術に関する本を探してください。
  • developerWorks Java technology ゾーン: Java プログラミングのあらゆる側面を網羅した記事が豊富に用意されています。

製品や技術を入手するために

議論するために

  • Mahout ユーザー・メーリング・リスト: メーリング・リストに登録して、質問を投稿し、知識を共有し、問題を話し合ってください。
  • developerWorks コミュニティーに参加してください。ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者が主導するブログ、フォーラム、グループ、ウィキを調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology
ArticleID=780416
ArticleTitle=Apache Mahout: 万人のためのスケーラブルな機械学習
publish-date=12162011