「Azure ML Studioで機械学習」の要点
この本 →クラウドではじめる機械学習 改訂版 が簡素だけども難しすぎずに小綺麗にまとまっているので要点をまとめておく。
回帰による数値予測(サンプル:新車販売価格予測)
例:リテールでの販売予測(前年の販売数、曜日、天気、広告打った・打たない、などの相関項目をもとに解析し未来の販売数を予測。
線形回帰 (linear regression)
y : 予測日の販売数
x1~xm : 馬力、燃料タイプ、燃費、ホイールベース、ブランド価値、などの変数
w1~wm : 偏回帰係数(重みのこと. feature weight)
c : 定数項(Bias)
※ 変数が多すぎると過学習になる
精度評価
・MAE(Mean Absolute Error: 平均絶対誤差)・・・0に近いほどいい
予測値と正解値の差を平均したもの。
・RMSE(Root Mean Squared Error: 二乗平均平方根誤差):
・法定係数(Coerfficient of Determination)
予測値と正解値の相関係数の二乗。1に近くなるほどいい
データ分割
・ホールドアウト法
学習用データを学習用と評価用にランダムに分割
・交差検証(cross validation)
学習用データをk個分に分割。そしてk回評価
精度向上
・正規化(regularization)
変数が多すぎて重みパラメーターが大きくなりすぎ過学習するのをふせぐために重みパラメーターに比例するペナルティ値を加算する。
【数式】
予測値と正解値の誤差の二乗の和、に重みパラメーターの二乗の和をパラメーターとして加える。
ベイズ線形回帰 (bayesian linear regression)
計算式は線形回帰と同じ。ただ重みパラメーターが一定ではなく確率分布であるとするモデル。
最尤推定(MLE: Maximum Likelihood Estimation.誤差が0になるように重みパラメーターを定める方法)だけだと学習用データの数を考慮しない場合不正確になるところを、事象の起こった回数を考慮してくれる。(事前分布と事後分布)
クラス分類(サンプル:乳癌データから陽性陰性のクラス分類)
例:銀行での与信審査を職業、年収、預金額、延滞遅延などの相関項目を解析し支払い能力を予測。
ロジスティック回帰
x1~xm : 年齢、腫瘍の大きさ、腫瘍の悪性度、閉経したしない、などの変数
w1~wm : 偏回帰係数(重みのこと. feature weight)
c : 定数項(Bias)
P : 確率
確率の閾値をたとえば0.5にすることによって陽性陰性の推定をする
1対多分類器(one-vs.-rest classifier)
A~Eまでクラスを作ったとしたら、それぞれに対する判別式(上記数式)を用意し最も高い確率を示したクラスに該当データを割り当てる。
1対1分類器(one-vs.-one classifier)
A~Eまでクラスを作ったとしたら、A-B,A-C,A-D...とすべての1対1の組み合わせを試す。組み合わせ数k×(k-1)÷2
回。A~Eだったら10回。その10回のうち多数決で多かったクラスに該当データを割り当て。
精度評価
・正解率(Accuracy)・・・100%に近いほどいい
陽が9割あった場合、アホみたくぜんぶ正解にしてしまっても正解率90%になってしまう。
・真陽性率(TPR: True Positive Rate)・・・100%に近いほどいい
陽データだけを対象にどのくらい合っていたか
・偽陽性率(FPR: False Positive Rate)・・・0%に近いほどいい
陰データだけを対象にどのくらい誤って陽としてしまったか
・AUC(Area Under the Curve)・・・1.0に近いほどいい
偽陽性率と真陽性率とはトレードオフになる。そこで偽陽性率と真陽性率をROC曲線のグラフにしその曲線の下側の面積がAUC。
・適合率(Precision)・・・100%に近いほどいい
推測が陽としたデータを対象にどのくらい正解データも陽であるか
・再現率(Recall)・・・100%に近いほどいい
正解データの陽を対象にどのくらい推測データが正しくよう陽と判定できたか。
・F値(F1 score)・・・1.0に近いほどいい
再現率と適合率もトレードオフ。これを総合的に判断する指標
精度向上
ロジスティック回帰以外の手法を試す。サポートベクトルマシン(SVM)やDecision Forest、Boosted Decision Treeなど
クラスタリング(サンプル:アヤメの分類)
例:旅行代理店の顧客の志向を、近場志向、海外志向、温泉志向などのグループに分類しそれぞれの志向にもとづいた販促資料を配布。
k-means法
任意のクラスタ数k個の中心点データを選び、ユークリッド距離またはコサイン類似度を用いて他のデータを各クラスタに分類する
ユークリッド距離
簡単。グラフ上の点aと点bの距離。
変数がm個の場合は【数式】
コサイン類似度
ベクトルの向きの近さ。同じ方向向いてれば+1, 垂直なら0, 逆向きなら-1
【数式】
k-means++法
k-means法を改良。これが主流。
クラスタの中心点をできるだけ離れるように選ぶ。また少数の集団はかけ離れたデータは無視する。
精度評価
教師なし学習なので分析者が適当に見てみるしかない。
精度向上
・正規化
値のスケールが大きい変数xを平均値:0,標準偏差:1になるようにスケール変換する。z得点(z-score)とか呼ぶ。
異常検知(サンプル:クレジットカード使用データから異常支払い検知)
例:河川の上流、中流、下流の各水位センサーから鉄砲水のような災害前兆を検知する。
One-Class SVM
密度推定アルゴリズム。データの正常域を円で表しその円に入らないデータを異常と検知。以下の数式で求められる値を最小化するように学習する。
【数式】
R: 円の半径
n: データ件数
ζ: データが円をはみ出した長さ
ν: 分析者があたえるペナルティの重み(小さくすればより多くの学習データを正常域に含めようとする。νが0だと学習用データのすべてを円内に収めてしまう)
カーネルトリック
データの密集域が離れているときに、正常域を歪んだ曲線で囲ってくれる。
精度評価
・適合率(Precision)・・・大きいほど検知漏れが少ない
異常検知推測が「異常」としたデータを対象にどのくらい正解データも「異常」であるか
・再現率(Recall)・・・大きいほど検知漏れが少ない
正解データの「異常」を対象にどのくらい推測データが正しく「異常」と判定できたか。
・F値(F1 score)・・・1.0に近いほどいい
再現率と適合率もトレードオフ。これを総合的に判断する指標
精度向上
適合率と再現率はトレードオフ。異常事象の検知漏れを減らしたいか誤検知を減らしたいか。
νを大きくすると(0.5など)正常域は狭まる。逆に0.02などにするとだいぶ正常域に入ってしまう。ML Studioではηで設定する。
カーネル関数を変えてみる
カーネルトリックで使われるカーネル関数。
・RBFカーネル(ML Studioのデフォルト)
・多項式カーネル
・シグモイドカーネル
異常検知の手法を変えてみる
・主成分分析による異常検知(PCA-Based Anomaly Detection)
・Times Series Anomaly Detection(気温の変遷や株価推移など時系列データの場合)
レコメンデーション(サンプル:レストラン評価データよりユーザーにおすすめレストランを提示)
例:Amazonの「この商品を買った人は以下の商品も買ってます」みたいな
強調フィルタリング
自分が与えた評点(rating, preference)と他者が与えた評点を併用しておすすめ商品を推測。アイテムベースとユーザーベースがある。
アイテムベースレコメンド
ユーザーが高い評点を与えた商品と類似性の高い商品をレコメンド。
ユーザーベースレコメンド
ユーザーと類似度の高いユーザーを複数選び、それぞれが高い評点をつけた商品をレコメンド
MatchBox
強調フィルタリングでは初見ユーザーや新商品が蚊帳の外になる(コールドスタート問題(cold-start problem)。商品やユーザーの属性情報からレコメンドするようにしたマイクロソフト独自のアルゴリズム。さらに徐々に蓄積されていく評点も併用して使う。
【式】
κは属性の数
従って学習用データは評点データ、ユーザー属性データ、商品属性データの3種類用意する。
精度評価
・NDCG(Normarized Discounted Cumulative Gain)・・・1.0に近いほどいい
デフォルト
・MAE(Mean Absolute Error: 平均絶対誤差)・・・0に近いほどいい
予測値と正解値の差を平均したもの。
・RMSE(Root Mean Squared Error: 二乗平均平方根誤差):
精度向上
特徴ベクトルの長さ(κ)を調整する。MS Studioでは「Train Matchbox Recommender」の[Number of traits]
実用化
実戦モードに切り替え
1.Score Matchbox Recommenderの[Recommended item selection]を[From All Items]に変更する。→ 実戦モードに。
2. 入力ポートは利用者IDのみしか受け付けなくなるので、Manipulationから「Select Columns in Dataset」を追加してuserIDだけを出力するように設定。
3. RUN
Webサービスの発行
実戦モードにて
-
[SET UP WEB SERVICE]から[Predictive Web Service]をクリック
-
[Select Columns in Dataset]を外して[Web service input]を[Score Matchbox Recommender]の入力ポートに。
6.コードのapi_key = "abc123"
のabc123を自分用のに変更。以下のコードのvaluesを例えばUserID"U1048"に変更。
# 変更前
data = {
"Inputs": {
"input1":
{
"ColumnNames": ["userID"],
"Values": [ [ "value" ], [ "value" ], ]
}, },
# 変更後
data = {
"Inputs": {
"input1":
{
"ColumnNames": ["userID"],
"Values": [ [ "U1048" ] ]
}, },
PythonApplication.pyとかで保存。
- コマンドで
$ python PythonApplication.py
と打てば結果が返ってくる。
$ python PythonApplication.py
{"Results":{"output1":{"type":"table","value":{"ColumnNames":["User","Item 1","Item 2","Item 3","Item 4","Item 5"],"ColumnTypes":["String","String","String","String","String","String"],"Values":[["U1048","134986","135030","135052","135045","135025"]]}}}}
- 2019年11月現在Python2系のサンプルコードになっている。Python3系の場合は以下の通り。
import urllib.request
# If you are using Python 3+, import urllib instead of urllib2
import json
data = {
"Inputs": {
"input1":
{
"ColumnNames": ["userID"],
"Values": [ [ "U1048" ] ]
}, },
"GlobalParameters": {
}
}
body = str.encode(json.dumps(data))
url = 'https://japaneast.services.azureml.net/workspaces/0e3c5988af4b43d7ac14fa55244b9f9d/services/53da3266168a4c8a8814e3adac2a6821/execute?api-version=2.0&details=true'
api_key = '<APIキー>' # Replace this with the API key for the web service
headers = {'Content-Type':'application/json', 'Authorization':('Bearer '+ api_key)}
req = urllib.Request(url, body, headers)
try:
response = urllib.urlopen(req)
# If you are using Python 3+, replace urllib2 with urllib.request in the above code:
# req = urllib.request.Request(url, body, headers)
# response = urllib.request.urlopen(req)
result = response.read()
print(result)
except urllib.request.HTTPError, error:
print("The request failed with status code: " + str(error.code))
# Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure
print(error.info())
print(json.loads(error.read()))
urllib2
をurllib.request
に変えるだけ。
以上。