ぱたへね!

はてなダイアリーはrustの色分けができないのでこっちに来た

数理最適化: Optimization Night #3

数理最適化: Optimization Night #3 に参加してきました。 イベントもオンラインが当たり前になってきた感じがしますね。gdgdな懇親会ができるサービスが待たれます。 今回も非常に面白い話が聞けました。発表された方、運営の方、ありがとうございました。

optimization.connpass.com

(株)日立製作所におけるサプライ・チェーン・マネジメント分野への数理最適化適用事例 細田順子さん

日立製作所におけるいろんな最適化の話を聞けました。

www.hitachi-solutions.co.jp

全部面白かったのですが、精度と速度のトレードオフを見ながら手法を上手く組み合わせているところが面白かったです。

サプライチェーン全体を検討するときは、時間がかかっても良いので高精度な解を出す数理最適化を使いますが、実際の運用時にはヒューリスティックな手法に数理最適化を合わせてリアルタイムに解を出していくようです。リアルなナップサックや制約付き巡回セールスマンの問題が見れました。

関税の話も面白く、当然関税を掛ける側もここまで考えてルール決めてると思うと、関税って大事だなと思いました。(小学生並み・・)

発表の後のQandAというかFujiwaraさんとの座談会的な会話も面白く、数多の戦場を切り抜けてきた猛者感がありました。数理最適化の意義を伝えるために職人さんと勝負して倒していく話が良かったです。引き分けでもコスト削減になるだけで無く、職人さんがちょっとずる(例外な処理)を入れると、ソルバーのルールもあわせて変えて行くのがバトル漫画っぽいですね。職人さんのずるはギリで使うけど、いったんルールを弱めると制約ソルバーは全力でそのルールを使いそうで勝ち目がない気がします。

最初から最後まで、数理最適化への愛にあふれる発表でした。

LT1 cute_na_catさん

ハンカチ落としの話でした。ラグランジュの未定乗数法って、実際に手で解けるんだというが驚きでした。 命を賭けたハンカチ落としは嘘喰いという漫画で登場するらしく、そこでも同じ式がでてくるとのこと。読んででみようと思ったのですが、全49巻と知って自分との稟議中。

命を賭けたハンカチ落としに巻き込まれないようにしたい。

Graph Neural Networkと物流最適化 zs さん

グラフ構造に対してニューラルネットワークを使って、最適解を求める話。 業界的に盛り上がっているらしく、論文も玉石混合っぽい雰囲気でした。 聞いていて教師データをどうするのかが気になったのですが、ちょうど質問があって助かりました。みんな同じ事思っていたのかも。 教師データとして最適解を与えるやり方もあるし、そうでないやり方もあるとのこと。

GNNと最適化、どういう使い道があるのか注目したい技術でした。

Deep Learing以前の技術で瞳検出とトラッキング

REAL-TIME DETECTION AND TRACKING OF HUMAN EYES IN VIDEO SEQUENCES

前から読みたかった論文をようやく読めたので、軽く紹介します。 1ooページ越えの対策ですが、画像処理や機械学習の基礎的なところも書かれていて勉強には良いと思います。

https://etd.lib.metu.edu.tr/upload/12606459/index.pdf

内容はDeep Learning以前に使われていた顔検出や瞳検出等のテクニックを紹介しています。最終的には、瞳のリアルタイムトラッキングまでやりましたという内容になっています。この論文を読んで改めてDeep Learningってすごいなと思うと共に、Deep Learning以前の技術をちゃんと残しておかないと、技術が断絶しそうなそんな思いで読んでました。

一般的なコンセプトと画像処理の背景

最初に目の構造や、行列計算、色空間の話があります。ここが教科書としてよくまとまっている気がしました。

目の構造

言葉の定義も重要ですが、Deep Learning以前の物体検出では対象物の特徴をしっかりと掴むことが重要でした。見つけたいものがeyeなのか、pupilなのかでまたアルゴリズム変わってきます。

f:id:natsutan:20200705220029p:plain

線形代数

分散、共分散の話から、PCAまで軽く基本を押さえています。PCAが後で効いてくるのが伏線っぽくて良かったです。 Deep Learning以前の識別タスクというのは、基本的に次元削減の技術で、例えばエッジだけを見たり、ヒストグラムを取ったり、周波数領域に移したり、特徴量の抽出が大変でした。

色空間

ここが僕自身あんまり分かってなかったというか、使わない色空間の知識が全くなくて勉強になりました。 こんな感じで基本的な考え方から、RGBの変換式まで説明があります。

f:id:natsutan:20200705220055p:plain

グレイ、HSV、XYZ、CIELAB、YCbCrの五種類の色空間の説明があります。それぞれ、こういう色空間がある理由と、使い道(使い分け)について軽く書いてありました。

従来の領域検出

Deep Learning以前の領域検出のアルゴリズムとしてスネークアルゴリズム(動的輪郭モデル)が紹介されています。

本当はここをさくっと動かしてブログを書きたかったのですが、簡単には動かず諦めました。 アルゴリズムは、まず物体の外側に領域を作って、その領域がだんだん小さく丸くなるように狭めていきます。

f:id:natsutan:20200705220236p:plain

あとは、これが物体の領域に引っかかって小さくなるのが止まれば良いのですが、やってみるとこんな感じ。

f:id:natsutan:20200705220242p:plain

んー、アルゴリズムとしては動いてそうだが、もうちょっと絞って欲しい。そうだ、まず上の部分の領域を作っている点を増やそうと思ってやってみましがた、上手く行かず。

状況を知りたいので、対象物を無視してちょっと小さくなる雰囲気だけ見てみると。

f:id:natsutan:20200705220251p:plain

なるほど、小さくなるアルゴリズムは、領域を構成する点の重心を目指す事がわかりました(これは別のアルゴリズムもあるらしい)。見つけたい物の中心と領域の重心が合ってないと上手く行かない。こんな感じで、見るからに調整が面倒なアルゴリズムです。そもそも凸凹したものは駄目っぽいです。

こんな単純なレベルでもDeep Learningの方が簡単そうです。

スネークアルゴリズムに関しては、いろいろ派生のアルゴリズムがあるのですが、パラメータに敏感で試行錯誤大変そうでした。

従来の顔検出

ハールライク系列と、固有顔しかしらなかったですが、結構いろいろ紹介されていて面白かったです。

その中から隠れマルコフモデルを使った顔検出を紹介します。

f:id:natsutan:20200705220415p:plain

こういう使い方があるのかと驚きました。まあ、使う事は無さそうですが。

感想

使うかどうかは別にして、いろんなアルゴリズムを知れたのは良かったです。改めてDeep Learningのすごさを感じました。

一点収穫があり、eigenfaceの目版でeigeneyeが紹介されていました。eigeneyeの計算量が小さく済むのであれば、使い道がありそうです。 例えば、最初の物体検出で顔を見つけ、次にeigeneyeで目を見つけるのは意味があります。今のDeep Learningはどうしても入力画像を縮小することになるので、縮小した時点で潰れてしまう物を見つけるのは無理です。いったん縮小して対象物の外側を検出しそこから元の解像度に戻り従来手法で対象物を探す手法は、結果的に計算時間を減らせる可能性が有りそうです。

全体を通してReferencesが充実しているので、既存手法を今から押さえたい人には読む価値があると思いました。僕は楽しかったです。

F#でグラフに凡例を入れる。

統計的機械学習の数理100問 with Pythonに載っていたt分布をF#で書いてみました。

www.kyoritsu-pub.co.jp

今回は凡例が書けるようになりました。

Chart.XXXXの引数でNameを指定し、パイプライン演算子で Chart.WithLegend() に渡せばOKです。

Chart.Line( [for x in -10.0 .. 0.1 .. 10.0 -> x, Normal.PDF(0.0, 1.0, x) ], Color=System.Drawing.Color.Red, Name="Norm")
              |> Chart.WithLegend()

上手く凡例が入りました。

f:id:natsutan:20200628183210p:plain

以下ソース

open MathNet.Numerics.Distributions
open FSharp.Charting

let plot_student_t(path) =
    
    let mutable chart_list = []
    let chart = Chart.Line( [for x in -10.0 .. 0.1 .. 10.0 -> x, Normal.PDF(0.0, 1.0, x) ], Color=System.Drawing.Color.Red, Name="Norm")
              |> Chart.WithLegend()

    chart_list <- chart :: chart_list
        
    for v in 1 .. 10 do
        let chart = Chart.Line ( [for x in -10.0 .. 0.1 .. 10.0 -> x, StudentT.PDF(0.0, 1.0, double(v), x)] , Name=string(v))
                    |> Chart.WithLegend()
        chart_list <- chart :: chart_list


    let chart_comb = List.rev chart_list |> Chart.Combine 

    let output_file = path + @"t.png"
    Chart.Save output_file chart_comb

    None

F#でカイの二乗分布

統計的機械学習の数理100問 with Pythonに載っていたΧの二乗分布をF#で書いてみました。

www.kyoritsu-pub.co.jp

f:id:natsutan:20200627201237p:plain

Χの二乗分布はMathNet.Numerics.Distributionsの中に含まれいます。確率分布が欲しいときはPDFで計算できます。ここはPythonのscipi.statと同じです。

open MathNet.Numerics.Distributions
open FSharp.Charting
    
let plot_chi2(path) =
    let mutable chart_list = []
        
    for k in 1 .. 11 do
        let chart = Chart.Line [for x in 0.1 .. 0.01 .. 20.0 -> x, ChiSquared.PDF(float(k), x) ]
        chart_list <- chart :: chart_list
    
    let chart_comb = Chart.Combine chart_list
    
    let output_file = path + @"chi2.png"
    Chart.Save output_file chart_comb
    None

統計的機械学習の数理100問の図1.3はグラフが間違っている気がします。k=1.5くらいから始めると教科書の図になりますね。記載されているPythonコードを実行しても、本と同じグラフになりませんでした。

F#正規方程式をで解く(行列計算)

統計的機械学習の数理100問 with Pythonに載っていた正規方程式をF#で解いてみました。F#で行列計算をするサンプルとして。

www.kyoritsu-pub.co.jp

正規方程式はこういう式です。

\hat{\beta} = (X^ TX)^ {-1}X^ Ty

Python 実装

教科書にのっているPython実装です。

import numpy as np

n = 100
p = 2
beta = np.array([1, 2, 3])
x = np.random.randn(n, 2)

y = beta[0] + beta[1] * x[:, 0] + beta[2] * x[:, 1] + np.random.randn(n)

X = np.insert(x, 0, 1, axis=1) # 左にすべて1の列を置く
beta_hat = np.linalg.inv(X.T @ X) @ X.T @ y

print(beta_hat)

実行するとこのように表示され、β=(1,2,3)が求められているようです。詳細知りたい人は本買ってください。

[0.91691516 1.91218893 2.91793258]

F#実装

open MathNet.Numerics.Distributions
open MathNet.Numerics.LinearAlgebra

let randn():double = 
    Normal(mean=0.0, stddev=1.0).Sample()
 
let makedata (N:int) = 
     // 一番左だけ1.0、残りはランダム
     let X = DenseMatrix.init 3 N (fun i j -> if i = 0 then 1.0 else randn())
     let beta = vector  [1.0; 2.0; 3.0]
     let noise = Vector<double>.Build.Random(N)
 
     let y = X.Transpose() * beta + noise
 
     X.Transpose(), y
 
let lsm (X:Matrix<double>, y:Vector<double>) =
     //正規方程式
     let beta = (X.Transpose() * X).Inverse() * (X.Transpose() * y)
 
     beta

実行するとだいたい合ってる感じの数値が出てきます。

beta = seq [1.002078054; 2.040203715; 3.098223575]

行列の操作、Row、Column単位のイテレート、map等、出来そうなんだけどやり方が分からないことがいっぱいなので、ぼちぼち勉強していきたい。

Learn Power BI

かっこよいグラフを作りたくて、Learn Power BI を読みながら無料枠でいろいろやってみました。

https://www.packtpub.com/data/learn-power-bi

どんな本

Power BIでデータの前処理からPublishしてApp化まで一通り手を動かしながら学べる本です。ボリュームや難易度は、初めての人にもちょうど良い感じでした。 各章で手を動かしながらいろいろと作っていきます。各章の最初と終わりのPowerBIファイルがgithubからダウンロードできます。これがすごく便利で助かりました。

バージョンの問題か、言語の問題か、書籍に載っているボタンが見つからなかったりして章の途中で諦めても、次の章から引き続き手を動かせるのは良かったです。 こういうグラフを作る時にはこれを使うと言ったリファレンス的な本ではないです。

Power BI入門書にありがちなPower BI Desktopでグラフを出す所に大きなページを割かず、ライセンスの話から、データの整形、画面の作り方、シェアの仕方、セキュリティを考慮した画面の作り方など、実際に使うに当たり必要な事がバランス良く書かれていたように思います。

Power BI使ってみて

Power BI Desktopは、便利なところは便利ですが微妙に癖があって使いにく、慣れるまで実務で使ってみないと駄目そうでした。ゲートウェイの設定やセキュリティは、専門の人に相談しながら出ないと進められず、買い切りのPower BI Desktopが欲しい。ローコーディングは微妙で、肝の部分でコーディングしないといけないし、DAXという言語も覚えないと行けない。

なにより、絵心ない人がPower BI使っても全く駄目でした。

Learning Power BIのIsWorkDay

Learning Power BIのGenerating dataのページ。

稼働日を求める式が間違っている。

× IsWorkDay = IF([WeekdayNum]=5 ,1, 0)
○ IsWorkDay = IF([WeekdayNum]<=5 ,1, 0)

等号では無く不等号。初心者向けの本でこういう間違いは困る。PowerBIのこのIFの仕様がどこに書いてあるのか分からずだいぶ苦労した。