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_USERNAMEYOUR_PASSWORDは、「サービス資格情報」にあるものを使用します。
    %e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-20-12-32-17

    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\"]"
            ]
          }
        }
      ]
    }
    
    広告ここから
    広告ここまで
    Home
    Search
    Bookmark