watsonのTradeoff Analyticsをcurlでためしてみる
概要 Tradeoff Analytics APIを使うことで、複数の条件からなる選択肢のうち、ベターなものが何かを調べることができます 条件と候補をまとめたJSONをPOSTするだけで、結果を返してくれます 無料枠もあ […]
目次
概要
- Tradeoff Analytics APIを使うことで、複数の条件からなる選択肢のうち、ベターなものが何かを調べることができます
- 条件と候補をまとめたJSONをPOSTするだけで、結果を返してくれます
- 無料枠もあるので、比較的気軽に試せます。
Tradeoff Analytics | IBM Watson Developer Cloud
APIの呼び出し方
もっともシンプルなのはcurlでPOSTリクエストを投げるだけです。
$ curl -X POST --user YOUR_USERNAME:YOUR_PASSWORD --header "Content-Type: application/json" --data @problem.json "https://gateway.watsonplatform.net/tradeoff-analytics/api/v1/dilemmas?generate_visualization=false" | jq .
YOUR_USERNAME
とYOUR_PASSWORD
は、「サービス資格情報」にあるものを使用します。
problem.json
というファイルをPOSTしていますので、ここからはJSONファイルの中身をざっと紹介します。
Request body(JSON)
problem.json
の中には以下のキーが含まれます。
- subject
- タイトル
- columns
- 選択の条件ための
- options
- 選択候補
これらの3つを含めたJSONファイルを生成して、POSTします。
例
from:チュートリアル
7種類のスマートフォンから、自分の条件に合うものを探すというクエリです。
{ "subject": "phones", "columns": [ { "key": "price", "type": "numeric", "goal": "min", "is_objective": true, "full_name": "Price", "range": { "low": 0, "high": 400 }, "format": "number:2" }, { "key": "weight", "type": "numeric", "goal": "min", "is_objective": true, "full_name": "Weight", "format": "number:0" }, { "key": "brand", "type": "categorical", "goal": "min", "is_objective": true, "full_name": "Brand", "range": [ "Apple", "HTC", "Samsung", "Sony" ], "preference": [ "Samsung", "Apple", "HTC" ] }, { "key": "rDate", "type": "datetime", "goal": "max", "full_name": "Release Date", "format": "date: 'MMM dd, yyyy'" } ], "options": [ { "key": "1", "name": "Samsung Galaxy S4", "values": { "price": 249, "weight": 130, "brand": "Samsung", "rDate": "2013-04-29T00:00:00Z" } }, { "key": "2", "name": "Apple iPhone 5", "values": { "price": 349, "weight": 112, "brand": "Apple", "rDate": "2012-09-21T00:00:00Z" } }, { "key": "3", "name": "HTC One", "values": { "price": 299, "weight": 112, "brand": "HTC", "rDate": "2013-03-01T00:00:00Z" } }, { "key": "4", "name": "Samsung Galaxy S5", "values": { "price": 349, "weight": 135, "brand": "Samsung", "rDate": "2014-04-29T00:00:00Z" } }, { "key": "5", "name": "Apple iPhone 6", "values": { "price": 399, "weight": 118, "brand": "Apple", "rDate": "2013-09-21T00:00:00Z" } }, { "key": "6", "name": "Apple iPhone 7", "values": { "price": 499, "weight": 118, "brand": "Apple", "rDate": "2014-09-21T00:00:00Z" } }, { "key": "7", "name": "Sony Xperia", "values": { "price": 199, "weight": 120, "brand": "Sony", "rDate": "2014-08-21T00:00:00Z" } } ] }
columns
の中身をざっくりとまとめるとこんな感じです。
項目 | 条件 |
---|---|
価格 | 0 ~ 400の間 |
重さ | できるだけ軽いもの |
ブランド | サムスン・アップル・HTCのどれか |
リリース日 | できるだけ新しいもの |
戻り値
リクエストが成功した場合、以下のようなJSONが返ってきます。
{ "problem": { "columns": [ { "type": "numeric", "key": "price", "full_name": "Price", "range": { "low": 0, "high": 400 }, "format": "number:2", "goal": "min", "is_objective": true }, { "type": "numeric", "key": "weight", "full_name": "Weight", "format": "number:0", "goal": "min", "is_objective": true }, { "type": "categorical", "key": "brand", "full_name": "Brand", "range": [ "Apple", "HTC", "Samsung", "Sony" ], "goal": "min", "preference": [ "Samsung", "Apple", "HTC" ], "is_objective": true }, { "type": "datetime", "key": "rDate", "full_name": "Release Date", "format": "date: 'MMM dd, yyyy'", "goal": "max", "is_objective": false } ], "subject": "phones", "options": [ { "key": "1", "name": "Samsung Galaxy S4", "values": { "price": 249, "weight": 130, "brand": "Samsung", "rDate": "2013-04-29T00:00:00Z" } }, { "key": "2", "name": "Apple iPhone 5", "values": { "price": 349, "weight": 112, "brand": "Apple", "rDate": "2012-09-21T00:00:00Z" } }, { "key": "3", "name": "HTC One", "values": { "price": 299, "weight": 112, "brand": "HTC", "rDate": "2013-03-01T00:00:00Z" } }, { "key": "4", "name": "Samsung Galaxy S5", "values": { "price": 349, "weight": 135, "brand": "Samsung", "rDate": "2014-04-29T00:00:00Z" } }, { "key": "5", "name": "Apple iPhone 6", "values": { "price": 399, "weight": 118, "brand": "Apple", "rDate": "2013-09-21T00:00:00Z" } }, { "key": "6", "name": "Apple iPhone 7", "values": { "price": 499, "weight": 118, "brand": "Apple", "rDate": "2014-09-21T00:00:00Z" } }, { "key": "7", "name": "Sony Xperia", "values": { "price": 199, "weight": 120, "brand": "Sony", "rDate": "2014-08-21T00:00:00Z" } } ] }, "resolution": { "solutions": [ { "solution_ref": "1", "status": "FRONT" }, { "solution_ref": "2", "status": "FRONT" }, { "solution_ref": "3", "status": "FRONT" }, { "solution_ref": "4", "status": "EXCLUDED" }, { "solution_ref": "5", "status": "EXCLUDED" }, { "solution_ref": "6", "status": "INCOMPLETE", "status_cause": { "message": "A column of a option is out of range. Option \"6\" has a value in column \"price\" which is:\"499\" while the column range\" is: [0.0,400.0]", "error_code": "RANGE_MISMATCH", "tokens": [ "price", "499", "[0.0,400.0]" ] } }, { "solution_ref": "7", "status": "DOES_NOT_MEET_PREFERENCE", "status_cause": { "message": "Option \"7\" has a value that does not meet preference for column \"brand\"", "error_code": "DOES_NOT_MEET_PREFERENCE", "tokens": [ "brand" ] } } ] } }
どこを見ればいいか?
code>resolutionという値がJSONの中に含まれています。
この値の中に、それぞれのoptions
が条件に一致するものか否かが格納されています。
resolutionのみjqでピックアップした例
$ curl -X POST --user YOUR_USERNAME:YOUR_PASSWORD --header "Content-Type: application/json" --data @problem.json "https://gateway.watsonplatform.net/tradeoff-analytics/api/v1/dilemmas?generate_visualization=false | jq ".resolution" { "solutions": [ { "solution_ref": "1", "status": "FRONT" }, { "solution_ref": "2", "status": "FRONT" }, { "solution_ref": "3", "status": "FRONT" }, { "solution_ref": "4", "status": "EXCLUDED" }, { "solution_ref": "5", "status": "EXCLUDED" }, { "solution_ref": "6", "status": "INCOMPLETE", "status_cause": { "message": "A column of a option is out of range. Option \"6\" has a value in column \"price\" which is:\"499\" while the column range\" is: [0.0,400.0]", "error_code": "RANGE_MISMATCH", "tokens": [ "price", "499", "[0.0,400.0]" ] } }, { "solution_ref": "7", "status": "DOES_NOT_MEET_PREFERENCE", "status_cause": { "message": "Option \"7\" has a value that does not meet preference for column \"brand\"", "error_code": "DOES_NOT_MEET_PREFERENCE", "tokens": [ "brand" ] } } ] }
各項目のstatus
というパラメータを確認することで、検索条件に一致するものか否かを確認できます。
- Front
- 条件に一致する選択肢
- Excluded
- 条件に一致しない選択肢
- Incomplete / DOES_NOT_MEET_PREFERENCE
- optionsのパラメータに問題があり、判定できなかった選択肢
上記の例の場合、以下の3台が検索候補に一致すると判断されています。
- ID:1 – Samsung Galaxy S4
- ID:2 – Apple iPhone 5
- ID:3 – HTC One
日本語は使えるのか?
「すごいのはわかったけど、日本語認識しないなら用はないかな」という人もいるんじゃないでしょうか。安心してください。日本語もちゃんと動きます。
SamsungとAppleを日本語表記にしたサンプル
念のため、存在しない値をわざと追加しておきます。
{ "subject": "phones", "columns": [ { "key": "price", "type": "numeric", "goal": "min", "is_objective": true, "full_name": "Price", "range": { "low": 0, "high": 400 }, "format": "number:2" }, { "key": "weight", "type": "numeric", "goal": "min", "is_objective": true, "full_name": "Weight", "format": "number:0" }, { "key": "brand", "type": "categorical", "goal": "min", "is_objective": true, "full_name": "Brand", "range": [ "アップル", "HTC", "サムスン", "Sony" ], "preference": [ "サムスン", "アップル", "HTC" ] }, { "key": "rDate", "type": "datetime", "goal": "max", "full_name": "Release Date", "format": "date: 'MMM dd, yyyy'" } ], "options": [ { "key": "1", "name": "サムスン Galaxy S4", "values": { "price": 249, "weight": 130, "brand": "サムスン", "rDate": "2013-04-29T00:00:00Z" } }, { "key": "2", "name": "アップル iPhone 5", "values": { "price": 349, "weight": 112, "brand": "アップル", "rDate": "2012-09-21T00:00:00Z" } }, { "key": "3", "name": "HTC One", "values": { "price": 299, "weight": 112, "brand": "HTC", "rDate": "2013-03-01T00:00:00Z" } }, { "key": "4", "name": "サムスン Galaxy S5", "values": { "price": 349, "weight": 135, "brand": "サムスン", "rDate": "2014-04-29T00:00:00Z" } }, { "key": "5", "name": "アップル iPhone 6", "values": { "price": 399, "weight": 118, "brand": "アップル", "rDate": "2013-09-21T00:00:00Z" } }, { "key": "6", "name": "アップル iPhone 7", "values": { "price": 499, "weight": 118, "brand": "アップル", "rDate": "2014-09-21T00:00:00Z" } }, { "key": "7", "name": "Sony Xperia", "values": { "price": 199, "weight": 120, "brand": "Sony", "rDate": "2014-08-21T00:00:00Z" } }, { "key": "8", "name": "失敗するサンプル", "values": { "price": 199, "weight": 120, "brand": "エラー", "rDate": "2014-08-21T00:00:00Z" } } ] }
日本語が混ざった場合の結果
ちゃんと日本語を認識して、columnsで定義されていないbrandを指定した8番目のアイテムにはエラーを返しています。
$ curl -X POST --user YOUR_USERNAME:YOUR_PASSWORD --header "Content-Type: application/json" --data @problem.json "https://gateway.watsonplatform.net/tradeoff-analytics/api/v1/dilemmas?generate_visualization=false | jq ".resolution" { "solutions": [ { "solution_ref": "1", "status": "FRONT" }, { "solution_ref": "2", "status": "FRONT" }, { "solution_ref": "3", "status": "FRONT" }, { "solution_ref": "4", "status": "EXCLUDED" }, { "solution_ref": "5", "status": "EXCLUDED" }, { "solution_ref": "6", "status": "INCOMPLETE", "status_cause": { "message": "A column of a option is out of range. Option \"6\" has a value in column \"price\" which is:\"499\" while the column range\" is: [0.0,400.0]", "error_code": "RANGE_MISMATCH", "tokens": [ "price", "499", "[0.0,400.0]" ] } }, { "solution_ref": "7", "status": "DOES_NOT_MEET_PREFERENCE", "status_cause": { "message": "Option \"7\" has a value that does not meet preference for column \"brand\"", "error_code": "DOES_NOT_MEET_PREFERENCE", "tokens": [ "brand" ] } }, { "solution_ref": "8", "status": "INCOMPLETE", "status_cause": { "message": "A column of a option is out of range. Option \"8\" has a value in column \"brand\" which is:\"エラー\" while the column range\" is: [\"アップル\",\"HTC\",\"サムスン\",\"Sony\"]", "error_code": "RANGE_MISMATCH", "tokens": [ "brand", "エラー", "[\"アップル\",\"HTC\",\"サムスン\",\"Sony\"]" ] } } ] }