ElasticsearchのプラグインはMahout Taste(協調フィルタリングの実装)です。 このプラグインは、Elasticsearchのレコメンドエンジンの次の機能を提供します。
- 利用者/商品/嗜好のデータ管理
- 商品ベースのレコメンダ
- 利用者ベースのレコメンダ
- 類似利用者/コンテンツ
- テキスト解析
Taste | Elasticsearch |
---|---|
master | 1.5.X |
1.5.0 | 1.5.1 |
0.4.0 | 1.4.0 |
0.3.1 | 1.3.1 |
このプラグインはJava8以上でサポートされていることに注意して下さい。 Elasticsearch Taste 0.4.0.の下のREADME_river.mdを参照してください。
何かあれば、課題を報告してください。 (日本語はここです。)
$ $ES_HOME/bin/plugin --install org.codelibs/elasticsearch-taste/1.5.0
このセクションでは、MovieLensデータセットを使用して、Tasteプラグインについて学ぶことができます。 MovieLensの詳細についてはMovieLensを見てください。 データセットu.dataを利用します。これには利用者ID、商品ID、評価、タイムスタンプが含まれています。 それをダウンロードし、Event APIによってデータを挿入して下さい。
curl -o u.data http://files.grouplens.org/datasets/movielens/ml-100k/u.data
cat u.data | awk '{system("curl -XPOST localhost:9200/movielens/_taste/event?pretty -d \"{\\\"user\\\":{\\\"id\\\":" $1 "},\\\"item\\\":{\\\"id\\\":" $2 "},\\\"value\\\":" $3 ",\\\"timestamp\\\":" $4 "000}\"")}'
上記の要求により、優先度の値は"movielens"インデックスに格納されます。 データを挿入した後、インデックスにあるのを確認してください。
curl -XGET "localhost:9200/movielens/_search?q=*:*&pretty"
利用者からのレコメンドされた商品を計算するには、次のリクエストを実行します。
curl -XPOST localhost:9200/_taste/action/recommended_items_from_user -d '{
"num_of_items": 10,
"data_model": {
"cache": {
"weight": "100m"
}
},
"index_info": {
"index": "movielens"
}
}'
計算結果は movielens/recommendation に格納されます。 上記リクエストのレスポンスの"name"プロパティにaction名が含まれます。 計算が終わったかどうかを確認するには、GETリクエストを送信します。
curl -XGET "localhost:9200/_taste/action?pretty"
応答にアクション名が含まれている場合は、リクエストがまだ完了していません。
結果を確認するため、次のクエリを送信します。
curl -XGET "localhost:9200/movielens/recommendation/_search?q=*:*&pretty"
"user_id"プロパティの値は、対象の利用者です。"items"プロパティは、"item_id"と"values"プロパティを含むレコメンドされた商品です。. "value"プロパティは、類似の値です。
計算は長い時間がかかるかもしれません… もし停止したいなら、以下を実行してください。
curl -XDELETE localhost:9200/_taste/action/{action_name}
次の"evaluate_items_from_user"アクションでは、類似性やneighborhoodのようなパラメータを評価することが出来ます。
curl -XPOST localhost:9200/_taste/action/evaluate_items_from_user -d '{
"evaluation_percentage": 1.0,
"training_percentage": 0.9,
"margin_for_error": 1.0,
"data_model": {
"cache": {
"weight": "100m"
}
},
"index_info": {
"index": "movielens"
},
"neighborhood": {
"factory": "org.codelibs.elasticsearch.taste.neighborhood.NearestNUserNeighborhoodFactory",
"neighborhood_size": 100
},
"evaluator": {
"id": "movielens_result",
"factory": "org.codelibs.elasticsearch.taste.eval.RMSEvaluatorFactory"
}
}'
結果はreportタイプに格納されます。
curl -XGET "localhost:9200/movielens/report/_search?q=evaluator_id:movielens_result&pretty"
{
"_index": "movielens",
"_type": "report",
"_id": "COscswwlQIugP2Rf0XKH-w",
"_version": 1,
"_score": 1,
"_source": {
"evaluation": {
"score": 1.0199981244413419,
"preference": {
"total": 10092,
"no_estimate": 178,
"success": 6671,
"failure": 3243
},
"time": {
"average_processing": 18,
"total_processing": 184813,
"max_processing": 22881
}
"target": {
"test": 915,
"training": 943
}
}
"@timestamp": "2014-05-07T21:15:43.948Z",
"evaluator_id": "movielens_result",
"report_type": "user_based",
"config": {
"training_percentage": 0.9,
"evaluation_percentage": 1,
"margin_for_error": 1
}
}
}
類似利用者をを割り当てるには、下のリクエストを実行します。
curl -XPOST localhost:9200/_taste/action/similar_users -d '{
"num_of_users": 10,
"data_model": {
"cache": {
"weight": "100m"
}
},
"index_info": {
"index": "movielens"
}
}'
利用者ID1の類似利用者を確認する場合は、以下を入力して下さい。
curl -XGET "localhost:9200/movielens/user_similarity/_search?q=user_id:1&pretty"
このプラグインは、user_idやitem_idのようなIDを所有しています。 自分のシステムIDにアクセスする場合は、次の検索APIを使用します。
curl -XGET "localhost:9200/{index}/{type}/_taste/{user|item}/{your_user_or_item_id}?pretty"
たとえば、IDが115の類似利用者を取得したい場合は以下のようにします。
curl -XGET localhost:9200/movielens/recommendation/_taste/user/1
"term_vector"を含むフィールドを持つインデックスから用語ベクターを作成できます。 次の例では、テキストデータは"ap"インデックスの"description"フィールドに格納されています。
curl -XPOST localhost:9200/ap?pretty
curl -XPOST localhost:9200/ap/article/_mapping?pretty -d '{
"article" : {
"properties" : {
"id" : {
"type" : "string",
"index" : "not_analyzed"
},
"label" : {
"type" : "string",
"index" : "not_analyzed"
},
"description" : {
"type" : "string",
"analyzer" : "standard",
"term_vector": "with_positions_offsets_payloads",
"store" : true
}
}
}
}'
curl -o ap.txt http://mallet.cs.umass.edu/ap.txt
sed -e "s/[\'\`\\]//g" ap.txt | awk -F"\t" '{sub(" ","",$1);system("curl -XPOST localhost:9200/ap/article/" $1 " -d \"{\\\"id\\\":\\\"" $1 "\\\",\\\"label\\\":\\\"" $2 "\\\",\\\"description\\\":\\\"" $3 "\\\"}\"")}'
用語ベクターを作成するには、下記を実行します。
curl -XPOST localhost:9200/_taste/action/generate_term_values?pretty -d '{
"source": {
"index": "ap",
"type": "article",
"fields": ["description"]
},
"event": {
"user_index": "ap_term",
"user_type": "doc",
"item_index": "ap_term",
"item_type": "term",
"preference_index": "ap_term",
"preference_type": "preference"
}
}'
sourceプロパティは、インデックス、タイプ、source情報などのフィールドを指定し、eventプロパティはuser/item/preferenceフォーマットである出力情報です。
このプラグインは、Elasticsearch上でUsers、Items、Preferencesのデータを管理しています。 これらのデータは、それぞれのindexやtypeに格納されています。 デフォルトでは、以下のようになっています。
Data | Index | Type |
---|---|---|
User | (Any) | user |
Item | (Any) | item |
Preference | (Any) | preference |
Userインデックスは、自身のidと情報を管理しています。 Userインデックスは、以下の属性を含んでいます。
Name | Type | Description |
---|---|---|
system_id | string | 固有のID。 システムが利用者IDを持つ場合には、これを使います。 |
user_id | long | このプラグインのための固有の利用者ID。 |
@timestamp | date | 作成/更新 された時間。 |
(Any) | (any) | age,tel,…などの他の情報を使用できる。 |
Itemインデックスはitem情報を管理し、以下を含んでいます。
Name | Type | Description |
---|---|---|
system_id | string | 固有のID。 システムが商品IDを持つ場合には、これを使います。 |
item_id | long | このプラグインのための固有の商品ID。 |
@timestamp | date | 作成/更新 された時間。 |
(Any) | (any) | price, publish date,...などの他の情報を使用できる。 |
Preferenceインデックスは、商品の利用者による評価値を管理します。
Name | Type | Description |
---|---|---|
user_id | long | このプラグインのための固有の利用者ID。 |
item_id | long | このプラグインのための固有の商品ID。 |
value | float | item_idのuser_idによる評価値。 |
@timestamp | date | 作成/更新 された時間。 |
Elasticsearchの作法を使用し、上記のインデックスおよびドキュメントを作成/更新/削除することが出来ます。
Tasteプラグインは、preference値を登録するための有用なAPIを提供します。 それを http://.../{index}/_taste/event に送信する場合、user_idとitem_idは生成され、preference値は挿入されます。 途中に改行を挟むことで、一度のリクエストで複数個の値を登録することができます。
例えば、利用者IDが"U0001"、商品IDが"I1000"、preference値が10.0のデータを登録する場合、要求は以下の通りです。
curl -XPOST localhost:9200/sample/_taste/event -d '{ user: { id: "U0001" }, item: { id: "I1000" }, value: 10.0 }'
複数個の値を登録する場合、次のように要求します。
curl -XPOST localhost:9200/sample/_taste/event -d \
'{ user: { id: "U0001" }, item: { id: "I1000" }, value: 10.0 }
{ user: { id: "U0002" }, item: { id: "I1001" }, value: 15.0 }'
user_id、item_id、@timestampは自動的に生成されます。 これらは"sample"インデックスに保存されます。 そのインデックス名は任意の名前に変更することが出来ます。
利用者のレコメンドされた商品は、類似利用者から算出されます。 演算処理は、riverの設定することにより開始されます。 10個のレコメンドされた商品が類似利用者から生成される場合は、riverの構成は次のとおりです。
curl -XPOST localhost:9200/_taste/action/recommended_items_from_user -d '{
"num_of_items": 10,
"max_duration": 120,
"data_model": {
"class": "org.codelibs.elasticsearch.taste.model.ElasticsearchDataModel",
"scroll": {
"size": 1000,
"keep_alive": 60
},
"cache": {
"weight": "100m"
}
},
"index_info": {
"preference": {
"index": "sample",
"type": "preference"
},
"user": {
"index": "sample",
"type": "user"
},
"item": {
"index": "sample",
"type": "item"
},
"recommendation": {
"index": "sample",
"type": "recommendation"
},
"field": {
"user_id": "user_id",
"item_id": "item_id",
"value": "value",
"items": "items",
"timestamp": "@timestamp"
}
},
"similarity": {
"factory": "org.codelibs.elasticsearch.taste.similarity.LogLikelihoodSimilarityFactory"
},
"neighborhood": {
"factory": "org.codelibs.elasticsearch.taste.neighborhood.NearestNUserNeighborhoodFactory",
"min_similarity": 0.9,
"neighborhood_size": 10
}
}'
設定
Name | Type | Description |
---|---|---|
num_of_items | int | レコメンドされた商品の数。 |
max_duration | int | コンピューティングのための最大時間(分)。 |
data_model.class | string | DataModel実装のためのクラス名。 |
data_model.scroll | object | Elasticsearchスクロールパラメータ。 |
data_model.cache | string | データモデルのためのキャッシュサイズ。 |
index_info | object | インデックス情報(index/type/property name)。 |
similarity.factory | string | 類似実装のためのFactroy名。 |
neighborhood.factory | string | Neighborhood実装のためのFactroy名。 |
レコメンドされた商品は、sample/recommendationに格納される。 結果を以下のようにして見ることができる。
curl -XGET "localhost:9200/sample/recommendation/_search?q=*:*&pretty"
"items"プロパティの値は、レコメンドされた商品です。
レコメンドされた商品を生成するためのパラメータを評価するには、以下の "evaluate_items_from_user" を使用することができます。.
curl -XPOST localhost:9200/_taste/action/evaluate_items_from_user -d '{
"evaluation_percentage": 0.5,
"training_percentage": 0.9,
"data_model": {
"class": "org.codelibs.elasticsearch.taste.model.ElasticsearchDataModel",
"scroll": {
"size": 1000,
"keep_alive": 60
},
"cache": {
"weight": "100m"
}
},
"index_info": {
"preference": {
"index": "sample",
"type": "preference"
},
"user": {
"index": "sample",
"type": "user"
},
"item": {
"index": "sample",
"type": "item"
},
"report": {
"index": "sample",
"type": "report"
},
"field": {
"user_id": "user_id",
"item_id": "item_id",
"value": "value",
"timestamp": "@timestamp"
}
},
"similarity": {
"factory": "org.codelibs.elasticsearch.taste.similarity.LogLikelihoodSimilarityFactory"
},
"neighborhood": {
"factory": "org.codelibs.elasticsearch.taste.neighborhood.NearestNUserNeighborhoodFactory"
}
}'
Name | Type | Description |
---|---|---|
evaluation_percentage | float | データモデルのためのサンプリングレート。0.5なら50%のデータを使用。 |
training_percentage | float | サンプリングされたデータモデルのトレーニングデータセットに対するレート。0.9の場合、90%のデータは試験データで10%のデータはテスト用です。 |
その結果はreportインデックスに保存されます。(この例はsample/reportです。)
商品のレコメンドされた商品は、類似商品から算出されます。 その演算処理は、riverの設定をすることにより開始されます。 10個のレコメンドされた商品が類似商品から生成される場合は、riverの構成は以下のとおりです。
curl -XPOST localhost:9200/_taste/action/recommended_items_from_item -d '{
"num_of_items": 10,
"max_duration": 120,
"data_model": {
"class": "org.codelibs.elasticsearch.taste.model.ElasticsearchDataModel",
"scroll": {
"size": 1000,
"keep_alive": 60
},
"cache": {
"weight": "100m"
}
},
"index_info": {
"preference": {
"index": "sample",
"type": "preference"
},
"user": {
"index": "sample",
"type": "user"
},
"item": {
"index": "sample",
"type": "item"
},
"item_similarity": {
"index": "sample",
"type": "item_similarity"
},
"field": {
"user_id": "user_id",
"item_id": "item_id",
"value": "value",
"items": "items",
"timestamp": "@timestamp"
}
},
"similarity": {
"factory": "org.codelibs.elasticsearch.taste.similarity.LogLikelihoodSimilarityFactory"
}
}'
そのレコメンドされた商品はsample/item_similarityに保存されます。 以下のようにして結果を見ることができます。
curl -XGET "localhost:9200/sample/item_similarity/_search?q=*:*&pretty"
"items"プロパティの値は、レコメンドされた商品です。