2020年1月アーカイブ

こんなチャットボットを作りたい

仕事の休み時間に料理好きのメンバーからこんな話を聞きました。「なんでもいいが一番困る!!」
なんの話か分かりますでしょうか?この記事にたどり着いたあなたなら分かるはず・・・。


そう、「晩ご飯何でも良い問題」です!


この問題、調べてみるとかなり多くの主婦の方々が悩んでいて、夫婦喧嘩の原因の1つでもあるようです。

奥さんは、洗濯をしたり、毎日食事を考えてたりでやることがいっぱい。
対して旦那さんは、仕事で疲れ果てて食事を考える元気もない。

最近は共働きの夫婦も増えています。仕事だけでも大変なのに料理のことも考えるなんて「辛いな・・・。」と思う日もありますよね。

でも栄養をしっかり取るために料理はしたい・・・。
どうすればこの問題を解決できるでしょうか?


「自動で献立を決めてもらおう!!!」


そうすれば、「今日の晩ごはん何にしよう・・・。昨日は麻婆豆腐、一昨日は八宝菜・・・。」と毎日考える必要はありません。

こんな不安もありますよね。
「できれば買い物行きたくない・・・。」
「食べたくない気分の料理も紹介されたくない!」
このような気持ちも理解して、献立を紹介してもらえれば、毎日楽ちんです!


晩ご飯何でも良い問題を解決します。

こんなことができます。

  • 冷蔵庫にある食材からおすすめのレシピを紹介

  • 栄養バランス・調理時間も教えてくれる

  • 気分に合わせたレシピを紹介


お料理ボットってどうやって使うの?
①冷蔵庫の食材を入力する
②おすすめのレシピが表示される
③リンクをタッチしてレシピの詳細を確認


お料理ボットの流れはこれだけ!左側がAIが送るチャット、右側が私達が送るチャットです。

①冷蔵庫の食材を入力する
今回は「豚バラ」と「はくさい」を入力しましたが、「鶏肉」「ひき肉」「ほうれんそう」など何を入力しても大丈夫です。

ffbed1a0ae2ef04e379f43984f1fb0f8da66251f.png


②おすすめの料理が表示される
先程2つの食材を入力したところで、チャットボットがおすすめの料理を5つまで表示してくれます。
適当にレシピを表示しているのではなく、2つの食材を用いたレシピで人気トップ5を表示しています。

5ca426918a68f93f92e89916aa8846e65403456f.png


③リンクをタッチしてレシピの詳細を確認
料理名は青色の文字で表示されています。
これはリンクになっていて、タッチすると料理の詳細を確認できます。

79f57ed3b9c2859eb2b1fef7d66405332ec1e3f2.png 8a50fcc5262bd189db12f82acd1b893efe2df2b3.png


もっと活用したい

なんとなく雰囲気はつかめましたか?
お料理ボットは冷蔵庫の食材を入力するだけで、その食材を使った人気料理とレシピを紹介します。

今の実装段階では「作れる人気なレシピの紹介」はできても、栄養バランスやあなたの気分を考えたレシピの紹介はできていません。
「気分や昨日の食事の内容をチャットボットに入力すると、栄養バランスを考えた料理を紹介してくれる機能」を実装中です。


お料理ボットを使うとこんな風に生活が変わります。

今まで

あなた「今日の晩ごはん何が良い?」
相手 「うーん、なんでもいいよ。」
あなた(何でも良いが一番困る!!)


お料理ボットを使うと

あなた「今日はどんな気分?」
相手 「うーん、仕事で疲れちゃったな〜。」
あなた「お疲れ様。(お料理ボットに気分を入力)」
ボット「お疲れ様!今日は豚汁なんてどうかな?温かいスープと、お肉でエネルギー補給ができるよ!」
あなた「ありがとう!助かったよ!」


お料理ボットとこんな風に会話をしながら献立を決められれば、もっと楽しくお料理生活を楽しめるようになると思いませんか?


  • 冷蔵庫にある食材からおすすめのレシピを紹介

  • 栄養バランス・調理時間も教えてくれる

  • 気分に合わせたレシピを紹介


これらの機能の他にも、お料理ボットには便利な機能を追加することができます。
例えば、「赤ちゃんのための食事が知りたい」や「好きな飲食店はココ!」などと言えば、それに合ったレシピを紹介してくれるなどなど・・・。


お料理ボットは、あなたの悩み・願いに合わせて料理生活をさらに楽しいものにすることができます。

  • チャットボットについてもっと知りたい!

  • 料理でこんな悩みがある!

  • こういうことできないの?

等、是非ご相談ください!


献立のリンク先

https://www.kyounoryouri.jp/recipe/3293_%E3%81%98%E3%82%83%E3%81%8C%E3%83%81%E3%82%B2.html


Twitter・Facebookで定期的に情報発信しています!

線形モデル(linear model)は、実用的に広く用いられており、入力特徴量の線形関数(linear function)を用いて予測を行うものです。
まず、説明に入る前に言葉の定義から紹介します。

線形回帰

データがn個あるとした時にデータの傾向をうまく表現することができるy=w_0×x_0+....+w_n×x_n というモデルを探し出すこと

正則化

過学習を防いで汎化性を高めるための技術で、モデルに正則化項というものを加え、モデルの形が複雑になりすぎないように調整している
 (モデルの係数の絶対値または二乗値が大きくなってしまうと、訓練データのモデルに適合しすぎて、テストデータのモデルの当てはまりが悪くなる過学習という現象が起こるので、過学習を避けるために正則化項をつけている)

重み

説明変数(求めたいものに作用する変数)が目的変数に与える影響度合いを表現したものです。例えば上の線形回帰モデルでいえばw1やw2など説明変数の係数が重みに当たる

コスト関数

構築したモデルがどれだけ悪いかを測定する関数
機械学習の分野ではコスト関数を最小化することがモデル構築では重要となる

モデルの比較

Ridge回帰とLasso回帰は大きな差があるわけではありません。
根本の考えは同じだが、視点を変えてみたようなものです。
まずは根本の考えについて(E:誤差関数 , λ:正則化パラメータ)
S=E+λ(Lpノルム) について考えます。


p=1の時がRidge回帰、p=2の時Lasso回帰である

ノルムの定義は以下の通りです。
images.png

unitball.gif.png

モデルの特徴をノルムの次元数から推測すると以下のことがわかります。


1.L1ノルムはパラメータの一部を完全に0にするため、モデルの推定と変数選択を同時に行うことができる
2.次元数>>データ数の状況で強力
3.L2ノルムは微分可能であり解析的に解けるが、L1ノルムは 解析的に計算出来ない
4.L1ノルムには様々な推定アルゴリズムが提案されている

以上のことから、常にどのノルムが一番優れているということはほとんどありません。

L1ノルムはパラメータが0になりやすく、正則化の影響が非常に強いことに対してL2ノルムは過学習になりやすく、正則化の影響が少し弱いです。
Ridge回帰は他と余りにもかけ離れたデータの重みを0にする事で、学習用データから削除するもの
Lasso回帰は他と余りにもかけ離れたデータの大きさに応じて0に近づけて、学習結果を滑らかにするもの
ということが分かりました。
つまりRidge回帰は訓練データに対する精度は高いですが、テストデータに対する精度は少し低くなります。
一方、Lasso回帰は訓練データに対する精度はRidge回帰に比べ低くなりますが、テストデータに対する精度はRidge回帰よりも高くなります。

実際に使う場合には、この 2 つのうちではRidge回帰をまず試してみると良いでしょう。しかし、特徴量が多く、そのうち重要なものは僅かしかないことが予測されるのであれば、Lasso が適しています。
同様に、解釈しやすいモデルが適している際は、重要な特徴量のサブセットを選ぶLasso のが理解しやすいモデルが得られます。

第1弾、第2弾に続き



 今回は第1弾で取り上げたこちらを検討していく。

課題①「電力需要量とのバランスが取りにくい」、課題③「無駄な待機運転の時間がある」への解決策

~発電量予測~
 


 ここでの「発電量予測」とは、発電装置周辺の気象・海象データを説明変数として発電量を予測することである。電力は常に需要量と供給量(発電量)が同量でなければ、停電を起こしてしまう。それを防ぐために発電量が予測されていれば、需要と供給のバランスを保ちやすくなる。また発電装置の無駄な待機時間も削減され、設備稼働率も向上する。このようにして、課題①「電力需要量とのバランスが取りにくい」、課題③「無駄な待機運転の時間がある」を解決する。

 更に第二弾で紹介した「電力需要量予測による制御」と組み合わせれば、発電量と需要量をより正確に一致させることができる。

 今回は発電方法を洋上風力発電としてこの「発電量予測」を実装する。

news4049_pic1.png

図1 ドイツの洋上風力発電


目次

  1. データセットについて
  2. 予測モデルについて
  3. 精度の向上
  4. 結果・考察・課題
  5. 参考文献


1. データセットについて

 1章でも述べたが、発電量予測は発電装置周辺の気象・海象データを説明変数とすべきだ。しかし、風速や天候などの気象データ、波高や波向などの海象データ、そして発電量の三つ揃ったデータセットを手に入れるには、造波装置を搭載する大型水槽での模型試験、または実海域での実証試験を行うしかない。大規模な装置を使わずに単純なモデルで模型試験を行い、そこからデータセットを得ようというアイデアもあるが、それは一度おいておき、今回は表1のようなデータの種類を用いることにした。表2がデータセットであり、2016年1月1日0時0分から2017年12月31日23時45分までの二年分のデータ値が記入されている。

表1 データの種類
スクリーンショット 2020-01-29 14.19.11.png


表2 データセット
スクリーンショット 2020-01-29 14.50.50.png

 訓練データとして表1のデータを三つとも全て用い、テストデータは発電量を予測したいので、「DE wind offshore generation actual」とする。


2. 予測モデルについて

 2章のデータセットは時系列データなので、時系列の分析に強いLSTMをモデルとして採用した。

 LSTMとは、ディープラーニングの一種であるが、過去の情報をモデル内に保持していることが一番の特徴である。過去の情報といっても、少し前からの情報(短期記憶)や、かなり前からの情報(長期記憶)がある。LSTMはそのどちらも必要な分保持し続けるような仕組みになっている。

 重みの更新の方法はディープラーニングの一種なので誤差逆伝播法となるのだが、LSTMの場合、誤差が時間を遡って逆伝播することから、「通時的誤差逆伝播法BPTT(Backpropagation Through Time)」と呼ばれる。

 ところが、長い時系列に対してこれを行うと、勾配が不安定になったり、計算量が膨大になり、分析に時間がかかってしまう。そこで、連なったLSTM層の逆伝播のつながりだけを適当な長さ(「ブロック長さ」)で切断することで、この問題を解決することができる。このようなBPTTを「Truncated BPTT」と言い、この切断した一つの単位を「LSTMブロック」と呼ぶ。そして、そして全てのLSTMブロックを最初から最後までまとめたものを「Time LSTM層」と呼ぶ。

 今回は過去の「DE wind offshore generation actual」(発電量)のデータ値とその他の二つの特徴量から、1時間後の「DE wind offshore generation actual」(発電量)を予測するというモデルになっている。


3. 精度の向上

 予測精度を向上させるために下記を実施した。

  • 「Time LSTM層」を増やす
  • 「Time LSTM層」のユニット数を増やす
  • 活性化関数を変える
  • 「ブロック長さ」を変える
  • 最適化アルゴリズムであるAdamの学習率を変える


 この中で特に精度に差が出たのは、「「ブロック長さ」を変える」ことであった。ブロック長さを5、10、20、30と変えていくと、二乗平均平方根誤差RMSEは表3のようになる。この時、「Time LSTM層」は1つ、「Time LSTM層」のユニット数は20つとした。

表3 ブロック長さと誤差
スクリーンショット 2020-01-29 15.08.25.png

 また、図3、4はそれぞれ最も誤差の大きい、ブロック長さが5の時と、最も誤差が小さい、ブロック長さが10の時の実測値(real)(黒い破線)と予測値(predicted)(赤い実線)のグラフである。但し、発電量の値は0から1に正規化してある。図4の方が、黒い破線が赤い実線と重なり消えていて、予測が正しいということが分かる。

スクリーンショット 2020-01-29 15.15.07.png

図3 ブロック長さが5の時


スクリーンショット 2020-01-29 15.16.28.png

図4 ブロック長さが10の時

 また、「最適化アルゴリズムであるAdamの学習率を変える」ことも精度を変化させた。結果的に、学習率が0.0007の時に最も精度がよくなった。(図3、4は学習率0.0007の場合)


4. 結果・考察・課題

 図4はブロック長さを10、Adamの学習率を0.0007とした結果であるが、これは私が今回実装した中で最も精度の高い結果である。全体的にかなりの精度で予測できていることが分かり、時系列データに非常に強いLSTMをモデルとして採用していることが大きな要因である。

 しかし、発電量が非常に多い時(発電量を0から1に正規化した時の0.95以上)の予測精度は、今後、発電量予測を実用化する場合には必ず解決しなければならない問題である。当然であるが沢山発電することができる時というのは非常に重要であるからだ。このような結果を招く理由として考えられることは、これらが挙げられる。

  • 訓練データとして気象・海象データがない(特徴量が足りない)
  • 何らかのパラメータのチューニングで失敗している
  • 測定期間が短すぎる


私としては、パラメータのチューニングについては非常に多くのパターンを試してみたので、それによってこれ以上大きく変化するとは思えない。やはり訓練データとして気象・海象データがないことが一番の原因ではないかと考えている。自然の力を利用して発電しているのにも関わらず、自然の力に関するデータなしに、過去の発電量、容量上限、シェア率だけから発電量を予測しては精度は期待できないであろう。もし気象・海象データ(具体的には、風速、風向き、天候、波高、波向など)と発電量のデータセットを手に入れることができれば、実用化も遠くない予測モデルが完成するかもしれない。1章でも触れたが、大規模な装置を使わずに単純なモデルで模型試験を行って、そこからデータセットを得ることについても今後模索してみようと思っている。


5.参考文献

  • 斎藤康毅『ゼロから作るDeep Learning ② ー自然言語処理編』株式会社オライリージャパン, 2018


Twitter・Facebookで定期的に情報発信しています!

このような課題はありませんか

  • 不良品検査の人員不足で外注しており、コストがかかっている...【コスト削減】
  • ノウハウが引き継げずにベテラン検査員が退職し、検査に膨大な時間がかかっている...【人依存の解消】
  • 利益率向上・働きやすい環境のために生産性を上げたい...【生産性の向上】
  • 人によって判定にばらつきがあるため、品質にもばらつきが出てしまう...【品質向上】


どれも製造業のお客様からよく聞くお困り事ですし、改善には時間もお金もかかります。しかし、改善しないと品質低下を招き、お客様に不満を持たれてしまう可能性もあります。
これらのお困り事を機械学習で解決する、機械学習を活用した物体判定をご紹介をします。


画像を用いた物体判定の仕組み

画像認識の際には「画像のどこに何が写っているのか」を認識するためのモデルが必要です。機械学習を用いて学習データからこのような検出・判別するモデルを構築します。モデルをあらかじめ構築しておいて、認識する画像に対して判別結果を出力する仕組みを作ります。

モデルで実際に画像を判別する際には、画像の中から 特徴抽出する必要があります。画像の局所的な特徴の抽出や画像に含まれるノイズの除去などを、画像処理の手法や統計的な手法によっておこないます。判別に必要のない情報を除いた上で、判別結果を計算することができます。

抽出した特徴はいくつかの一定の大きさの領域にまとめた後、プーリング と呼ばれる処理でまとめられた領域を1つの値で代表します。画像の空間的な情報を削除し、判別に必要な情報のみを残します。

特徴抽出・プーリングの実施後には、事前に用意していたモデルによって画像を判別します。

また、ディープラーニングに代表される学習手法は特徴抽出・プーリングの処理をひとまとめにして、それらの手順をさらに繰り返すことで認識精度を高めています。


▼画像撮影から物体判定、振り分けまでのイメージ
画像を撮影しどこに物体があるか認識し、物体が何であるか判定し、判定内容によって振り分け(行動)します。
スクリーンショット 2020-01-29 15.05.29.png 1.カメラを設置し、動画で物があることを認識・検出します。(物体検出技術)


2.学習時に付けたラベルをもとに、検出した物が何であるか判定します。

学習は画像に対してラベル(正解)をつけておこないます。実際の運用では、カメラで検出した物体が学習画像のどれに近しいかと判定します。


3.判定結果により適切な行動をします。

機械学習の範囲からは出ますが、判定した内容をもとに次の指示を出します。例えば、ベルトコンベアー上のものがA製品であれば右に振り分け、B製品であれば左に振り分ける、または不良品であればアラートを出すことができます。


課題別 機械学習事例 コスト削減

点検作業の自動化
カメラで撮影した建物画像からひび割れ等の老朽化箇所を検出します。人からシステムに役割を変えることができ、人件費削減だけではなくかかる時間も短縮することができています。

倉庫内配置の適切化
倉庫内にカメラを配置し、撮影することで作業社の行動や物の位置を把握し分析します。倉庫内の動線や配置の最適化によって業務を効率化し、コスト削減を実現します。

特定箇所への農薬散布
企業が農業へ参入したことで、日本では集約農業から大規模農業へと転換が進んでいます。広大な農地で作物を育成する際に、ドローン等で空撮したデータから必要な箇所を割り出して、病害虫が発生している箇所ピンポイントに農薬を散布します。農薬使用量を削減できるだけでなく、他作物へのダメージを減らすことができます。


人依存の解消

受注量予測
過去の受注量のメカニズムからどれだけの発注があるか予測します。ベテランにしかできなかった発注業務の敷居を下げることで、限られた人しかできなかった業務を分配することができます。

野菜収穫の自動化
ノウハウが重要な収穫時の見極めをAIがおこないます。AIが判断した後にロボットに信号を送ると自動で収穫をおこなうマシンも検討できます。


生産性の向上

問合せへの自動応答
社内からの問合せ件数は日にかなりものです。その問合せをチャットボットで自動応答にすることができます。質問者も作文に時間をかけずに気軽に質問することができます。

居眠り検知
同じ作業が続く検品等で、うとうとしそうになってしまうことがあります。目の開きがあまくなるとアラートが鳴り、目を覚ましてくれるシステムも構築できます。


品質向上

高解像度画像の作成
最新のAI技術では荒く見づらい画像を高解像度に直すことができます。品質で失注していた案件に、より良い提案が出来る可能性が上がります。

コンベア内の品質チェック
コンベアを流れる物体が良品か不良品かを判定します。不良品可能性のある物は人が見るまでもなく振り分けることで、人の疲労による見落としを減らすことができます。


機械学習検討の作業プロセス

▼機械学習を検討する際のプロセスです。
スクリーンショット 2020-01-29 15.21.39.png

・事前検証

対象/判断の基準/期待する精度を基に適切な学習手法・アルゴリズムを設定します。


・システム開発

画像処理及び画像判定システムの検証・開発をおこないます。モデルへ画像と正解ラベルを合わせて学習させ、テストデータで事前検証で決めた精度が出せるようにチューニングします。


・テスト運用

運用に限りなく近いデータでトライアル運用をおこない、運用面や精度面での問題や課題を発見し対処します。


・リリース

テスト運用終了後に正式リリースとなります。必要に応じて、判定の精度向上のための再学習や活用範囲拡大のための追加学習を実施します。



当社は機械学習を活用したソリューションをご提案しています。

  • 自社にあるデータを2次活用したい
  • 画像データを活用したAIを作成したい
  • 既にAIシステムを利用しているが思うような効果が得られていない
  • 機械学習ではなにが出来るのか興味がある


このようなご相談は画面右上の[お問い合わせ]までご相談ください。


acceluniverse


Twitter・Facebookで定期的に情報発信しています!

機械学習では、訓練データとテストデータの違いによって、一部のテストデータに対する精度が上がらないことがあります。

例えば、水辺の鳥と野原の鳥を分類するCUB(Caltech-UCSD Birds-200-2011)データセットに対する画像認識の問題が挙げられます。意図的にではありますが訓練データを、

  • 水辺の鳥が写っている画像は背景が水辺のものが90%、野原のものが10%
  • 野原の鳥が写っている画像は背景が水辺のものが10%、野原のものが90%

となるように分割します。このときに、訓練データの中で「背景が野原で水辺の鳥」の画像や「背景が水辺で野原の鳥」の画像が少なく、同じようなテストデータに対して精度が上がらないことがあります。

Alt text

以降では、テストデータ全体の精度をaverage accuracyと呼ぶのに対して、このようなデータに対する精度をrobust accuracyと呼ぶことにします。パラメータの数が訓練データの数よりも多い(overparameterized)ニューラルネットワークでは、モデルの複雑度が高いために過学習しやすく、average accuracyは高くともrobust accuracyは低くなりがちです。

論文"Distributionally Robust Neural Networks"では、上記のような訓練データとテストデータの分布が異なるときのrobust accuracyを上げる最適化手法について説明されています。パラメータの多いニューラルネットワークがよく使われる画像認識や自然言語処理などのタスクに対して同じような最適化手法を適用でき、今後も広く使われる手法かもしれません。

この記事では論文で説明されていた手法について、簡単に概要を説明しようと思います。

"distributionally robust optimization"とは?

訓練データよりも多くパラメータが存在するニューラルネットワークでは、学習データにおけるロスの消失による過学習が問題となっていました。そのようなときは一般には平均的に汎化誤差(generalization gap)が小さくなるように最適化するのですが、どうしてもロスが最も大きいworst-case groupに対しては、依然汎化誤差大きいままになってしまいます。

そこで考えられた手法がdistributionally robust optimization(以下DRO)です。DROは一言で言えば最も大きいロスでの最小化です。

\[ \min_{\theta \in \Theta} \sup_{Q \in \mathcal{Q}} {\rm E}_{(x,y)\sim Q}[l(\theta;(x,y))] \]

\( \sup {\rm E}[l(\theta;(x,y))]\)が表すのがworst-case groupの平均のロスとなります。\(Q\)が表すのが分類する各グループ\(g\)ごとの分布の線形結合となるのですが、最小化は線形計画法のアルゴリズム(単体法)で行われます。そのため、最適解は実行可能領域の頂点、すなわちworst-case groupのみの分布における最適解と一致します。

\[ \min_{\theta \in \Theta} \max_{g \in \mathcal{G}} {\rm E}_{(x,y)\sim P_{g}}[l(\theta;(x,y))] \]

worst-case groupの分布では平均のロスが最も大きくなります。DROはその分布でのロスの最小化を目的とするアルゴリズムだと言えます。これまでの機械学習は平均的な汎化誤差を正則化(regularization)などによって低減させていましたが、DROはworst-case groupの精度の向上、つまりrobust accuracyの向上が目的です。

では、実際にどのようにしてworst-case groupの精度を向上させているのでしょうか?次節からはその具体的な手法について説明します。

従来手法によるrobust accuracyの向上

DROで使われる正則化の1つとして重み減衰(weight decay)が挙げられます。すでに様々な機械学習の中で使われている手法であり、例えば有名なものではL2正則化が挙げられます。

\[ E(w) + \cfrac{\lambda ||w||^{2}_{2}}{2} \]

論文では、画像認識のモデルであるResNet50においてL2正則化をするとき、\(\lambda\)は通常小さな値\((\lambda=0.0001)\)が設定されるが、この値を大きくするとrobust accuracyが上がるということが述べられています。つまり、強い重み減衰(strong weight decay)が手法の1つとして考えられます。

また、もう1つの正則化としてearly stoppingが挙げられます。こちらも機械学習でよく使われる手法ですが、想定されるニューラルネットワークのパラメータ数が多く学習数が大きいとすぐに過学習するため、early stoppingが有効だと言えます。

検証

それではDROの検証結果について見てみましょう。ベンチマークとしてERMモデルとの比較を行います。最初に述べたCUBのWaterbirdsの分類タスク(ResNet50による)の他に、CelebAデータセットにおける髪色の分類タスク(ResNet50による)と、MultiNLIデータセットにおける自然言語推論タスク(BERTによる)で比較しています。一般的な正則化(Standard Regularization)と前節で述べた2つの手法を試したときのaverage accuracy、robust accuracyは以下のとおりです。

Alt text

この結果からどのタスクにおいても、ERMではaverage accuracyに比べてrobust accuracyが大幅に低下したのに対して、DROのstrong weight decayとearly stoppingによってrobust accuracyが大幅に低下するのを防いでいることが確認できると思います。

また、CelebAに関してaccuracyの収束性についても見てみましょう。

Alt text

worst-case groupである「Blondの髪で性別がmale」の判別において、strong weight decayを用いたDROがそれぞれのグループで他の手法よりも良い収束性を持つことが確認できます。

グループサイズを利用した正則化

今回の論文では分類するグループの大きさを利用したDRO(group-adjusted DRO)についても述べられています。グループ内のデータの数を\(n_{g}\)とすると、最適化するべき目的関数は、

\[ \min_{\theta \in \Theta} \max_{g \in \mathcal{G}} {\rm E}_{(x,y)\sim P_{g}}[l(\theta;(x,y))] + \cfrac{C}{\sqrt{n_{g}}} \]

となります。ハイパーパラメータ\(C\)を用いた正則化項を付け加えるアイディアです。\(n_{g}\)の平方根の逆数を掛けることで、グループごとのデータ数を考慮した汎化をおこなうことができるようです。このgroup-adjusted DROのaccuracyは以下のようになっています。

Alt text

robust accuracyにおいてさらなる改善が見られますね。バリデーションによって\(C\)の値さえうまく決めることができればかなり役に立つ手法だと言えます。

importance weightingとの比較

実は同じような解決策として、importance weightingという従来手法が存在します。これはロスに重み付けした上で最小化を行う手法です。これはミニバッチからデータを等確率でリサンプリング(RS)することでrobust accuracyを上げる手法だそうです。こちらについてもベンチマークを見てみましょう。

Alt text

ERMよりもrobust accuracyが上がっていますが、DROほどではありません。DROは従来手法よりもrobust accuracyの向上に有効だと言えます。

終わりに

今回紹介した論文では訓練データとテストデータの分布の違いを考慮した手法であるDROについて簡単に紹介しました。従来よりもrobust accuracyを大きく上げたという点でより注目される手法だと思います。

しかし、なぜこのように正則化をすると精度が向上するのかという問いに対する明確な答えがまだない状態です。この論文を足がかりにrobust accuracyが上がる数理的なメカニズムが解明されれば、様々なモデルで汎化性能の向上が期待できるでしょう。

参考文献

DISTRIBUTIONALLY ROBUST NEURAL NETWORKS


Twitter・Facebookで定期的に情報発信しています!

はじめに

昨日まで開催されていたKaggleの2019 Data Science Bowlに参加しました。結果から言いますと、public scoreでは銅メダル圏内に位置していたにも関わらず、大きなshake downを起こし3947チーム中1193位でのフィニッシュとなりました。今回メダルを獲得できればCompetition Expertになれたので悔しい結果となりましたが、このshake downの経験を通して学ぶことは多くあったので反省点も踏まえて今回のコンペを振り返っていきたいと思います。


コンペ概要

幼児用教育アプリを使う子ども達の能力を予測するコンペです。具体的な予測は次のようになります。
アプリ内でプレイ可能なゲームがそれぞれAssessment、Game、Activity、Clipの4つの分野に分類されます。そのうちAssessmentに分類されるゲームをプレイした際の問題の正解率を過去のプレイ履歴を元に0、1、2、3の4段階で予測します。モデルの評価指標はQuadratic Weighted Kappa (QWK)が採用されており、これがこのコンペで大きなshakeを生む原因の1つだったと言えます。
実際に多くの人がshake upまたはshake downし、private leaderboardにおいて1000位以上順位が動いた人もたくさんいました。


取り組み

以下で私がこのコンペで行った取り組みを記述していきます。


EDA

コンペの序盤は公開してくれているNotebookを元にEDAを行いました。
中盤以降はゲームの細かいプレイ履歴を見るためにテーブルデータそのものを見て、データ中の項目が何を示しているか注意深く観察するようにしました。


特徴量作成

特徴量は公開Notebookをベースとしました。そこにEDAやDiscussionを元に特徴量を作成して、モデルの精度が向上するかどうかトライアンドエラーを繰り返しました。


データの前処理

testデータの各特徴量の平均値をtrainデータに合わせて変換しているNotebookを見つけ、自分のパイプラインに取り込んだところ精度が大きく向上したのでそれ以降ずっとこの手法を取り入れていました。
しかし、正直なところ過学習の原因になりかねない危ない処理だとも考えていました。


モデル

今回はLGBMとXGBoostを試しました。それぞれのモデル単体ではLGBMが良い性能を示し、アンサンブルで2つのモデルを用いても性能の向上が見られなかったため最終的にはLGBMのみ使いました。
LGBM1つの時に比べて、Local CVのスコアが高くなるランダムシードを5つ選びseed averagingを行ったモデルがpublic scoreで少し良い結果でした。今回のコンペでは評価指標のQWKが原因でpublic scoreが不安定であったので、アンサンブルをせず1つのモデルの結果を提出しているチームも多かったです。しかし、private scoreではやはりアンサンブルを用いた方が結果が良かったようです。


データの後処理

予測結果としては問題の正答率から0、1、2、3のラベルに分類するタスクでした。しかし、多くの参加者がregressionを使って連続値で予測した後に閾値を決めてそれぞれのラベルに分類する手法を取り入れていました。
この閾値を決定する方法が2つありました。1つはvalidationスコアからQWKが最適化されるように閾値を決定する方法。もう1つはラベルの割合がtrainデータと一致するように閾値を決定する方法です。
trainデータとtestデータの分布が似ていると仮定し私は後者を選びました。


結果

冒頭でも述べましたが最終日に銅メダル圏内に突入したものの、モデルがpublic leaderboardに対してひどい過学習を起こしておりprivate leaderboardでは900位近く順位が下がり3947チーム中1193位となりました。


反省

自分なりに大きなshake downの原因が何だったかいくつか要因を考えてみました。

まず第一にデータの前処理でtestデータの各特徴量の平均値をtrainデータの平均値に合わせたことです。 この処理はtrainデータとtestデータの分布の差を少なくするためのものでした。しかし、testデータがtrainデータと同じ分布に由来していた場合に、平均値を調整することでpublic scoreが上がるのはpublic leaderboardに過学習していると考えられます。
上位陣がこの前処理を行っていないことから、実際にこの処理がpublic leaderboardに過学習する原因になっていると言えます。

次にshake downの原因として考え得るのは、予測ラベルの割合をtrainデータに合わせにいったことです。この処理ではtestデータの正解ラベルの割合がtrainデータの割合と似ていると仮定していますが、public testデータが少ない状況でこの処理は危険であったと思います。
上位陣の解法でもこの手法は使わずに、validationデータに対してQWKを最適化して閾値を決めていました。

コンペ終了後に最終のsubmissionとして選ばなかったものを見ると、過学習を起こしうる処理を使う前のものではメダル圏内のscoreのものもありました。
このコンペを通してpublic scoreを改善することよりもロジカルに考えてパイプラインを構築することが大切だと実感しました。特に今回はtestデータが非常に少なく大きなshakeが起きる可能性が高いと自覚しながら、また過学習になりかねない処理だとも自覚しながら、public scoreを追ってしまったことは反省しなければならないところです。


まとめ

銅メダル圏内から900位近くshake downするという悔しい経験ではありましたが、そこから学ぶこと多くありました。やはりモデル構築の際は論理的に筋の通った処理をする必要があるなと感じました。今回の反省を活かし上位陣の解法から学べることは吸収して精進していきたいと思います。


Twitter・Facebookで定期的に情報発信しています!

こんにちは。
今回は「アイトラッキング」について紹介します!

皆さんは「アイトラッキング」という技術をどのくらいご存知でしょうか?
「アイトラッキング」とは、人間の視線の動きを追跡・分析する手法であり、視線推定技術とも呼ばれます。
この技術により、これまで調査者側からではわからなかった被調査者の無意識の「本音」がわかるようになりました。

この記事ではそんな素晴らしい技術、「アイトラッキング」がどんな場所、場面で使われているのかを調査し、その可能性について探っていきます。

目次

1 なぜアイトラッキング技術?
2 アイトラッキング技術の活用
 A マーケティング
  B 防犯・事故防止
  C ユーザーインターフェイス
  D スポーツ
  E 都市環境
  F 学術・医療
3 まとめ

1 なぜアイトラッキング技術なの?

被調査者の意見を知りたいと思った時、例えば消費者に何か意見を求める時、アンケートやインタビューをしています。
しかし、これらは個人の意識が無意識で入り込んでしまうため、結果が正確であるとは断言できません。
とっさに見栄を張ってしまったり、質問者に求められている答えをしてしまったり(つまりは忖度ですね笑)、選択肢の番号の流れに乗って選んでしまったり...ということはないでしょうか?

アイトラッキング技術は被調査者の無意識の自然な目の動きを追うので、個人の意識的な介入が少なく、本音を読み取ることができます。

人は生活の中で自然と目を動かします。そこから得られる情報は、どんなものに目をつけたのか、何に興味を持ったのかなど、その人に関する詳細なデータです。
アイトラッキング技術はそれらの膨大な情報を読み取ることができ、それを分析し活用することができれば様々な分野で有効活用できるというわけです。

2 アイトラッキング技術の活用

アイトラッキングの技術は主に「業務効率化」のために利用されます。
ここでは各分野のアイトラッキング技術の活用事例を紹介し、今後の可能性について探っていきます。

A マーケティング

アイトラッキング技術はその特徴からマーケティングに活用されることが多いようです。
ここでは、顧客の注意や興味を知るためにアイトラッキング技術が使われています。

  • 興味検知
    スーパーではたくさんの商品が棚に陳列されています。
    ある特定のものを買いたいとしましょう。
    皆さんは何を基準に買う商品を決めますか?値段、ブランド、それともパッケージでしょうか?

    アイトラッキング技術は、顧客が商品を決める時の目の動きに着目し、「誰が何に興味を示したか」だけでなく、一番初めに見た要素、一番長く見られた要素、頻繁に見られた要素、あまり見られなかった要素、また他の商品のどこと比較されたのかなどを明らかにします。商品を作るメーカーは、デザインを変えるのが良いか、だとしたらどんなデザインが良いか、値段は適正かなどを検討することができます。

    また、店で商品を買う時、POPをみて興味を持ち、ついつい買ってしまった、または目につくところにあったから買ってしまった、なんてことはありませんか?
    アイトラッキング技術を使うことで、効果的なPOP・広告作りや、効果的な売り場づくりを人の目の動きというデータに基づいて行うことができます。
    これを真剣に行えば、売り上げアップが期待できそうですね。
    買い物.png

B 防犯・事故防止

  • 不審者検知
    明らかに不審な動きをしている人を検知します。例えば、必要以上にキョロ  キョロして周りを気にしていたり、監視カメラを必要以上に注視していたり...という人を認識します。
    顔認証を組み合わせればホームセキュリティに応用できたり、動きまで認識できれば万引きなどの犯罪防止に役立つとでしょう。

  • 運転中の事故防止
    近年では危険運転防止のため、ドライビングレコーダーの利用が増えています。ドライビングレコーダーは車の外側を見るものですが、ここでは車の内側を見ます。

    運転者の視線を見ることで、運転中の意識喪失や居眠りの検知をしたり、運転中の脇見を検知することができます。これはもし事故が起こった時、過失なのか、故意なのか判定するのに役立ちます。
    また、視線や顔の動きから運転を採点し、アドバイスしてくれる機能があったら楽しいですし、一方で、緊張感・危機感を持って運転できるかもしれません。
    事故防止だけでなく、運転中の姿勢変化により発生する視線の動きを観察することで、疲れにくい車の開発にも活用されています。

  • 検査の見落とし防止
    何かを検査する時、人間での検査だとら何かの拍子に見落としてしまうことがあります。視線を感知することで防止することが出来ます。見落としが起こった時にも、視線を確認することで何が起こっているか分析でき、再発防止に繋がります。

    居眠り運転.png

C ユーザーインターフェイス

  • 操作パネルのデザイン検証
    現在、何かサービスを受けるとき電子機器で操作が多くなりましたね。(例えば、飲食店の券売機、案内や空港での航空券発見など)。ちょっと見づらいなとか操作しづらいな、など感じたことはありませんか。
    アイトラッキングの技術は、人の視線の動きやどこに長く注目しているか(興味を持っているかもしれないし、わかりにくくてずっと見ているのかもしれない)を読み取ることによって、消費者が電子機器端末を快適に使えるようにするためのきっかけを与えてくれます。例えば、効果的な電子メニューの配置や見せ方、視線の動きから好みを分析しリコメンド、デザインは適切かの検証などがあります。

D スポーツ

プロ選手とアマチュア選手の視線を認識し、何を見てどんな動きをしているか分析をすることで、良い動きを見極めるヒントになり、選手のレベルアップのために役立ちます。
他分野でも熟練技術者の技術の継承にも同じように役立てられます。
フィギュアスケートなどの一部のスポーツでは、演技の出来栄えを審判が決定します。アイトラッキング技術を用いることで、審判が何を見て、どんな基準で点数をつけているのかを明らかにし、より良い演技のために活用されている事例もあります。

E 都市環境

人々がより快適な生活を送るためにも役立てられています。
近年、日本の都市に訪れる、もしくは居住している外国人の方々が増加しています。彼らが国内を移動する際、きちんと地図を読めているのか、標識を認識しているのかなどを視線の動きから分析し、改善に役立てます。
また、避難訓練時に視線計測を行うことで、避難者にとって標識や案内が正しく、そしてわかりやすいものであるかを検証し、その結果をもとに改善をすることで効果的な標識のデザインや設置場所を検討することができます。室内でも避難誘導標識や消火器標識の設置位置が適切かどうかをあらかじめアイトラッキング 技術を用いて検証することで、非常時の被害を最小限に抑えることができます。

F 学術・医療

心理学や脳神経学において、人間の思考・言動における視覚情報の影響や、認知プロセスの究明に利用されています。また、医療の分野では眼球疾患や精神・神経疾患の研究にも利用され始めているようです。

3 まとめ

今回はアイトラッキング技術の活用事例とその可能性について紹介しました。この他にも、パソコンやゲームを視線だけで操作することもアイトラッキング技術を用いることでできるようになるようです。また、子供の学習時、どこをどのくらい見ているかを分析することで、優秀な子が何に着目するのかや、きちんと見るべきポイントを抑えられているのかを明らかにすることで、勉強時間からではわからない学習の詳細な部分が見えてくるでしょう。

ただ、アイトラッキングは技術にすぎません。得られたデータ、事実からその裏にあるもの(その行動の背景)について考えることが必要不可欠です。技術が進歩しても人間が考え、検証する必要があります。
アイトラッキング技術は今後ますます活用されていくでしょう。将来性があるので、今後ますます活用されていくのではないでしょうか。


Twitter・Facebookで定期的に情報発信しています!

はじめに

KaggleのNFLコンペで2038チーム中118位となり、銅メダルをとることができました。以下に、参加してからの取り組みや、反省点を書いていきたいと思います。

コンペ参加前の状況

10ヶ月ほど前にTitanicコンペに参加してから、「Predicting Molecular Properties」と「IEEE-CIS Fraud Detection」というコンペに参加してみましたが、公開されているカーネルを少しいじってみた程度でメダルには到底届きませんでした。

コンペ概要

簡潔に書くと、アメフトのワンプレーごとに、ボール保持者がランプレーでいくらヤードを稼げるか?を予測するコンペです。しかしアメフトのルールを知らないため、はじめは全くわからなかったです。

アメリカンフットボールでは、野球のようにプレーごとにチームが攻撃と守備にきっちり分かれているようなのですが、今回の予測はこの攻撃側のランプレーに関係します。

攻撃側のチームはボールを保持し、相手陣地にできるだけ深く攻め込もうとするのですが、その方法が2パターンあります。パスプレーとランプレーです(パスプレーは省略します)。ランプレーは攻撃開始直後に、クォーターバックが走ってくる味方にすれ違いざまにパスを出し、そのボール保持者は相手を交わしながらできるだけ相手陣地の深いところまで、すなわちヤードを稼ごうとします。

今回予想するのは、このボール保持者が稼いだヤードが可能性のあるヤードそれぞれ以下である確率です。

例)3ヤード以下である確率:0.3、 4ヤード以下である確率:0.35、5ヤード以下である確率:0.38 .......

取り組み

以下では自分の取り組みを説明していきます。始めたのは、締め切りの約1ヶ月前からです。

コンペ概要理解とEDAなど

アメリカンフットボールの理解
アメフトのルールを知らなかったため、ここから始めました。サイトや動画を参考に進めました。

予測するものの理解
ランプレー時にオフェンスが得たヤードに関するもので、それぞれのヤード以下である確率を求めなければならないということをなんとか理解しました。ここからは、アメフトの動画はランプレーに絞って見ていました。

与えられたデータの内容
プレーごとのデータでした。まずそのプレーの情報で、日付と時刻、スタジアムの状態、天気と風速など。また、プレーに出場している22人それぞれの情報で、名前、身長体重、出身大学、ポジション、位置情報、進行方向や速度と加速度、背番号などが与えられていました。

モデル

多層ニューラルネットワーク(以下DNN)を使いました。今まではLGBMを使ってきたため、DNNを本格的に使うのは初めてでした。このカーネルと同じものです。

特徴量エンジニアリング

ベースのモデルができてからは、データ分析→そこから得られたアイデアを元に特徴量作る→スコア上がるかどうか?→データ分析 といったように仮説と検証の繰り返しでした。うまくいった特徴量を具体的に書いていきます。

攻撃チーム、守備チーム、ボール保持者(Rusher)、守備チームの前線選手などのそれぞれの戦績をランク付け
やはりアメフトにも強いチーム、弱いチームが存在し、同様にボール保持者の能力にも差があります。これを単純にターゲットエンコーディングしても良かったのですが、それは避けました。他の競技にも言えることですが、チームも選手も年によってかなり調子が上下します。そのままターゲットエンコーディングすると与えられたデータに過学習してしまうと思い、5つにランク分けし、エンコーディングしました。これは、リーダーボードのPublicからPrivateで、順位が約70位上がった要因にもなっていると思います。

ボロノイ図の面積を用いる
ボロノイ図というのは、平面上に配置された点に大して、その平面内の点を、どの点に最も近いかによって分割してできる図のことで、今回のコンペではこの記事でPythonで実装してくれています。僕はここから着想を得て、ボロノイ図によって分割された部分の面積を特徴量として加えてみることにしました。面積が無限大となってしまうのを防ぐため、うまくミラーリングを使う必要があるのですが、実装力不足のため数日を費やすこととなりました。しかし、この面積を標準化して特徴量として加えると期待以上にスコアがよくなったので達成感も十分にありました。ここで出した面積を元に、ある特定のポジションの選手の面積を利用するなど、さらに試行錯誤をしました。

選手同士の距離感
これは多くの方がされていると思います。ボール保持者と相手ディフェンスとの距離感を計算し、その平均や最小値、最大値などを利用しました。

上手くいかなかったこと

CNNを用いる
上記のことはコンペ終了1週間前には出来ており、銅メダル圏内にも入っていました。しかし、さらに順位をあげたいと思い、残り1週間は新しいことにチャレンジしました。そもそも僕が上記で作った特徴量は、主に選手の戦績と位置情報に関したものです。その位置情報を最もシンプルに用いることができるのはCNNではないか?と考えました。
つまり、選手の戦績やプレー時の状況、スタジアムなどプレー情報はシンプルなDNNにいれ、選手の位置情報と進行方向のベクトル、速度、加速度などはCNNに入れ、それをくっつけてしまい、最終的な出力を得ようというものです。題の通り、この試みは失敗しました。lossが全く下がらず、それまでのモデルより悪いスコアとなってしまいました。DNNの使用経験が少ないことによる安直な考えが原因ではないかと考えています。しかし、このコンペで1位であったチームはCNNを用いていたため、アイデア自体は悪くなかったのでは?とも思います。

数秒後の選手の位置を利用する
選手の進行方向のベクトル、速度、加速度が与えられているため、未来の選手の位置が求められると思い1秒後と0.5秒後の選手の位置を求め、それを用いて特徴量を作ったのですが、精度の向上には繋がりませんでした。他の参加者にはこの特徴量が効いたとコンペ後におしゃっていた方もいたので不思議です。

上位陣の解法

1st place solution
このチームは2位に大差をつけて1位となったのですが、とてもシンプルな解法で驚きました。選手の位置情報と速度、加速度をディフェンスとボール保持者、オフェンスとボール保持者、ディフェンスとオフェンスなどに分けた上で特徴量とし、モデルとしてCNNを使っていました。また、有用なCVを見つけたようで、CVのスコアをよくすることに注力することが出来たようです。

2nd place solution
Transformerという、主に自然言語処理で使われる手法があるのですがこの方はそれを使っています。上位の方の多くはこの手法を使っているようなので、僕もこの手法を理解したいと思います。

4th place solution
上記のTransformerは、Attentionという仕組みを用いているのですが、このチームはこのAttentionをDNNと組み合わせているようです。

ちなみにAttentionについてはこちらで解説しています。

まとめ

今回のコンペでは、データ分析→生まれたアイデアを元に特徴量作成→精度をあげる、という基本的な流れはうまくいきました。しかし、データ分析によって生まれたアイデアをモデルに反映させることはできず、それが上位陣との差であると感じました。もちろん、自力でメダル圏内に入れるようになったのは大きな成長であると思いますし、この経験と学びを生かして次回は銀メダルを狙いたいと思います。

その他Kaggle関連の記事

地震コンペをやってみた

インタビュー|Kaggle Expertまでの道のり

Adversarial Validationとは

Attentionモデルの解説

アクセルユニバース株式会社(以下当社)では、人が対応している業務を画像認識、音声認識、文字認識等を活用して効率化する機械学習ソリューション開発をおこなっています。


インターン生は業務の一環としてKaggleに取り組んでおり、先日のASHRAE - Great Energy Predictor IIIにて銅メダルを獲得しました。


メダルを獲得した田村くんのコメントです。

今回は、他の方が提出したもののブレンド(混ぜる)の仕方を工夫しました。
まずはなるべく違う解法を混ぜる対象として選定しました。その後は、混ぜ方が良い悪いの指標も評価できたので良かったです。

先日のアメフトのコンペ(NFL Big Data Bowl)も同様のことが言えますが、暫定順位(public leaderboard)を上げることだけを考えていると、private leaderboardの順位が下がる可能性が大きいので次のコンペでは十分に気をつけたいです。


その他当社インターンでは技術ブログを作成しています。

▼Kaggle

▼論文解説

▼新技術の実装


その他、随時紹介していくので是非ご覧ください!


Twitter・Facebookで定期的に情報発信しています!

業種別 機械学習導入・検討状況

2018年にIBMがおこなった調査によると、企業の82%はAIの導入を検討しており、金融サービス業界では既に16%の企業がAI システムを運用または最適化し、製造業がそれを追いかけるように導入・検討が進んでいます。

例えば、シーメンス、ジェネラルエレクトリック(GE)、ボッシュ、マイクロソフトなどの業界大手企業は、既に製造業のあらゆる部分を後押しするための機械学習アプローチによるAIの製造に多額の投資をおこなっているようです。

また、Google Trendsでも現在までの検索数の増加から、世の中の関心の高まりが伺えます。

スクリーンショット 2020-01-20 11.55.34.png

本記事では、製造業でのさらなるAI・機械学習活用のために3つの活用例をご紹介します。


製造業での機械学習活用例

メンテナンス時期予知

機器を使った製造行程がある場合、機器のメンテナンスが必須になりコストがかかることは避けられません。 また、製造行程において、想定外のダウンタイムは世界中の工場で起こっており、その約42%が機器の故障によるものだそうです。

そのため、メンテナンス時期の予測にAIを活用することが注目されています。 測定できる機器の状態データをAI・機械学習を使って、機器の状態を予測、推定します。メンテナンスが必要となるまでの機器の寿命が大幅に長くなります。 担当者は、機器があとどれくらいで交換/修理が必要になるか事前に知ることができ、またそのための対策を前もってとることが可能になります。


不良品検知

製造過程で発生する不良品はごく少数の割合でしか発生しませんが、不良品チェックは省くことの出来ない工程です。

そこで、人が目で確認している不良品のチェックを段階的にシステムがおこない、不良品可能性のあるものだけを人がチェックをするように役割分担をすることで、人の業務負担を軽減することが出来ます。

良品・不良品の画像等のデータを学習させ、不良品可能性の高いものにアラートを出します。不良品と断定するのではなく、あくまでも可能性とすることで、不良品の見逃しを防ぎます。


需要予測による市場適応

今後の需要を知ることで経営者はもちろん、現場担当者も適切に準備をすることで過不足なく対応することが出来ます。機会損失や過剰に在庫を抱えることを避けられます。

何をいつどのくらい受注したかの受注情報とその要因になるデータを学習させることで、未来の需要(受注)を予測します。

スクリーンショット 2020-01-20 13.16.20.png


今まで人がおこなってきた業務をシステムが代替することでこのようなメリットがあります。

AI・機械学習活用のメリット

  • 需要への調整
  • 運用コスト削減
  • 生産性向上
  • ダウンタイム削減
  • 商品力/競争力強化



AI・機械学習の浸透

今後も業種を問わずAIの活用は進み、とりわけ製造業での活用は急速に進んでいくと予想できます。


2019年12月に株式会社アイ・ティ・アールが以下のように調査報告しています。

2018年度のAI主要6市場の売上金額は199億5,000万円、前年度比53.5%増と大幅な伸びとなり、今後も継続的な伸びが見込まれることから、CAGR(2018~2023年度)は26.5%、2023年度には640億円に達すると予測している。 また、AI主要6市場の中で最も高い伸びを示したのが画像認識市場である。画像認識は工場などで行っている製品の外観検査や作業員の安全管理業務で導入が進んできたが、現在、道路や橋などの社会インフラ、各種建造物の保全業務での利用も急速に進んでいる。また、顔認証や車両の自動運転など、活用シーンの多様化により、今後も継続的な導入拡大が見込まれます。

上記報告から、AIはその技術進歩と相まって、私達の生活に浸透し始めていることがわかります。


当社も機械学習を活用したソリューションをご提案しています。
例えば、動画を用いた物体検出や、電力需要の予測が一例です。このような技術を用いて、お客様それぞれの課題解決へ取り組んでいます。

  • 自社にあるデータを活用したい
  • 自社に親しい業種の活用例を知りたい
  • AI・機械学習を活用したいが、方法に困っている
  • 機械学習ではなにが出来るのか興味がある


上記のようなご相談は画面右上の[お問い合わせ]までご相談ください。


当社、アクセルユニバースのご紹介

私達はビジョンに『社会生活を豊かにさせるサービスを提供する。』ことを掲げ、このビジョンを通して世界を笑顔にしようと機械学習・深層学習を提案しています。

  • ミッション(存在意義)
    私達は、情報通信技術を使って万物(全ての社会、生物)の暮らしをよりよくすることに貢献し、 それを加速させることを使命とします。

  • ビジョン(目標とする姿)
    社会生活を豊かにさせるサービスを提供する。

  • バリュー(行動規範)

    1. 変化を求め、変化を好み、変化する
    2. 自分の高みを目指してどんどん挑戦する
    3. お客様と一蓮托生でプロジェクトを進める



acceluniverse


Twitter・Facebookで定期的に情報発信しています!

はじめに

多くの機械学習モデルにおいて注意することの一つとして過学習(overfitting)があります。過学習は学習データに適合しすぎて未知のデータに適合できずに、汎化性能が低下してしまう現象のことを指します。DNNを例に取ると、モデルサイズを大きくしたり、エポック(epoch)及びイテレーション(iteration)を大きくしすぎるとモデルが過学習しすぎてテストエラー(汎化誤差)が大きくなってしまいます。ですが最近になって、一定以上を超えて上記のパラメータを大きくしていくとテストエラーが減少する"Double Descent"という現象が報告されているようです。今回はこの現象が起きている要因を解析している論文"Deep Double Descent: Where Bigger Models and More Data Hurt"の要約をしていこうと思います。

"Double Descent"とは

[The Elements of Statistical Learning]
この文献で述べられているように、従来ではモデルの複雑度(complexity)がある閾値を超えるとテストエラーが大きくなり続けるということが言われていました。一方で、ここ最近では100万を超えるパラメータを持つ巨大なモデルを構築する、学習回数を増やす、データを増やすことでテストエラーが改善していくという論文がここ5年の間に次々と報告されてきています。以下の図のように一度降下して再度降下していく現象を"Double Descent"と名付けられています。

スクリーンショット 2020-01-15 17.34.36.png

このグラフの特性は2つの領域に大別できます。上記で述べたテストエラーが悪くなり続けるという話は" Classical regime"のことを示しており、複雑度(モデルの構造や学習量)を一定以上に大きくすると再度降下していく"Modern regime"がその後に続いています。例えばシンプルな構造のニューラルネットワークと複雑なニューラルネットワークがあったとします。前者については従来から言われているように"under-fitting"と"over-fitting"からなるU字型の特性が観測できますが、後者は複雑にしていくとある閾値(図でいうinterpolation threshhold)で再度降下していくという具合です。
さて"Double Descent"についてはなんとなくわかりましたが、どのような要因によってこのような特性となるのでしょうか。次に論文の主軸であるEMCという指標について述べていきます。

EMCについて

EMCとは"トレーニングエラーがほぼ0になるときのサンプルの最大値"で定義されています。もちろんですがtraining errorが0になる時点というのは使用するモデルや学習方法や量、問題によって異なってきます。筆者はこのEMCという指標でDouble Descentを説明できるという仮設を立てています。
上記の文を式にすると以下のようになります。
スクリーンショット 2020-01-15 18.44.49.pngただし、
S:入力データ
D:データの分布
T:学習手順
n:サンプル数
ε:トレーニングエラー


上記の定義式を元に以下の図のように3つの領域に分けられます。

criteria.png

1. Uner-parameterized regime

EMCが大幅にnより小さいとき、複雑度が増加すると同時にテストエラーは減少する(EMC<n)

2. Critically parameterized regime

EMCがnにほぼ等しいとき、複雑度が増加すると同時にテストエラーは減少する若しくは増加する(EMC>n)

3. Over-parameterized regime

EMCが大幅にnより大きいとき、複雑度が増加すると同時にテストエラーは減少する(EMC≒n)

まだ分かりづらいと思うので補足します。横軸をsample数としてCritically parameterized regimeの部分に注目したグラフが以下のようになっています。
スクリーンショット 2020-01-16 14.14.48.png
定義通り捉えるとトレーニングエラーεが0付近の中でもサンプル数が最大となるのはおよそ1000となっているのでEMCは1000となります。この場合ではテストエラーのグラフのinterpolation threshholdはこの値付近に存在するということになります。もちろんこのグラフ特性は入力データSと分布D、学習手順T(これはモデルサイズは最適化アルゴリズムを含む)によって変化します。が、それぞれのパターン毎において求められるEMCの値付近にこのinterpolation threshholdが「経験則的に」存在している、つまりEMCとinterpolation threshholdは何かしらの相関が存在しているため、その延長線上に有るDouble DescentはEMCによって説明出来るという仮説が本論文の趣旨です。

 あくまでも仮説なので、EMC=nとなる付近でinterpolation threshholdが存在するということを以下の理論解析で説明しています。また、εの値は経験則的に決められており(ε= 0.1)、原則が存在するわけではないようです。図から分かるようにCritically parameterized regimeでは過学習のような振る舞いをしているため、汎化性能が劣化している領域です。そのため、予めこの領域を把握していれば汎化性能の劣化を防ぐことが出来るということですね。ということで以降はEMCに相関のあるモデルサイズ、学習量等を評価軸としてDouble Descentの振る舞いを見ていきます。

その前に

理論解析で採用されているLabel Noiseについて説明します。これは教師データの正解ラベルをpの割合で誤った正解ラベルに置き換えることでデータ分布を強制的に変えている雑音のことを指します。(以下イメージ図)Label Noiseを付加することでモデルが誤って学習をすすめるため、過学習のような特性になることが予想できます。また、εが非常に小さくなるまで学習をすすめることで テストエラーの理論限界はpになることも予想できます。
図1.png

それでは各種評価について見ていきます。今回評価軸は3つに大別できます。

・Model-wise Double Descentーモデル構造(モデルサイズ、最適化アルゴリズム)の変更やデータの水増しによるDouble Descentの特性(エポック固定)
・Epoch-wise Double Descentーいわゆる学習曲線(モデル構造固定)
・Sample-wise Non monotonicityーサンプル数変化によるDouble Descentの振る舞い及びCritically parameterized regime付近での特性

それぞれ多角的に評価しており、その一部を記載していきます。

1.Model-wise Double Descent

スクリーンショット 2020-01-16 11.09.06.png○諸元
モデル:ResNet18
最適化アルゴリズム:Adam(learning rate:0.0001)
エポック数:4000
その他:データ水増し
データセット:左 CIFAR-100、右 CIFAR-10
上記はモデルサイズ毎のテストエラー、トレーニングエラーの特性を示しています。両者グラフの違いとして左の結果はLabel Noiseを付加していない場合でも"Double Descent"のような振る舞いをしていることがわかります。また、Label Noiseが大きくなるにつれてinterpolation threshholdにおけるピーク値が大きくなり、左にシフトしていっていることも読み取れます。

2.Epoch-wise Double Descent

図2.png

○諸元
モデル:ResNet18
最適化アルゴリズム:Adam(learning rate:0.0001)
Label Noise:20%
その他:データ水増し
データセット:CIFAR-10
次に学習量に応じたテストエラーを見ていきます。左のグラフが馴染みのある学習曲線、右はテストエラーを深さとしたデプスマッピングです。学習量が多くなるにつれてEMCが大きくなることから、モデルサイズが大きくなるにつれてDouble Descentのような振る舞いが顕著に現れていることがわかります。また他のサイズでは範囲内の学習量ではUner-parameterized regimeの領域に属していることからモデルが小さい場合は引き続き学習を続け、その間のサイズであれば早期終了するなどして学習を止めたほうが良い事が読み取れます。

3.Sample-wise Non monotonicity

スクリーンショット 2020-01-16 12.11.32.png
○諸元
モデル:5-layers CNN
最適化アルゴリズム:SGD(learning rate:0.0001)
データセット:CIFAR-10
最後にサンプル数変化によるDouble Descentの振る舞いを見ていきます。サンプル数を増やすことでEMCが増加するため、interpolation threshholdが右にシフトします。そのため、モデル固定の場合にCritically parameterized regimeをサンプル数によって調整出来るため、汎化性能が劣化することを予め回避することができます。(例えばoverfitting に位置するモデルのサンプル数を増やすことでunderfittingの位置にシフト出来る)個人的に気になったのですが、Label Noiseが小さい上のグラフのほうがテストエラーが大きくなっているのが疑問に思いました。

結果まとめ

スクリーンショット 2020-01-16 12.32.19.png

終わりに

Fully understanding the mechanisms behind model-wise double descent in deep neu- ral networks remains an important open question. However, an analog of model-wise double descent occurs even for linear models. A recent stream of theoretical works analyzes this setting (Bartlett et al. (2019); Muthukumar et al. (2019); Belkin et al. (2019); Mei & Montanari (2019); Hastie et al. (2019)). We believe similar mechanisms may be at work in deep neural networks.

今回、"Double Descent"をEMCという指標で説明出来るという仮説を立てた事、またその根拠を理論解析で提示した論文の紹介をしました。上記の引用からも論理的な証明はまだできておらず発展途上ということだそうです。この"Double Descent"を解明することで、どれくらいの学習をさせるべきなのか事前に把握することができると同時に、モデルチューニングの最適化などにも貢献する重要なテーマであると思いました。

参考文献
・Trevor Hastie, Robert Tibshirani, Jerome Friedman"The Elements of Statistical Learning Data Mining, Inference, and Prediction,"Available:https://openreview.net/forum?id=B1g5sA4twr
・Preetum Nakkiran, Gal Kaplun, Yamini Bansal, Tristan Yang, Boaz Barak, Ilya Sutskever "DEEP DOUBLE DESCENT: WHERE BIGGER MODELS AND MORE DATA HURT," ICLR 2020 Conference Blind Submission, Available:https://openreview.net/attachment?id=B1g5sA4twr&name=original_pdf


Twitter・Facebookで定期的に情報発信しています!

リモートワーク・業務効率化を阻む紙

このようなことはありませんか?

  • お客様アンケートを手集計している。
  • 見積作成のために出社しないといけない。
  • 紙の伝票処理に時間がかかっている。


コロナウイルスの影響もあり、リモートワーク化が進む中、上司のハンコを貰うのでリモートワークできない。という声も少なからずあるようです。紙書類の作業のために出社をしなけばいけない...。リモートワークに限らず、営業が業務日報や見積り作成で会社に戻ることは業務効率を大きく下げる要因です。
2019年4月1日に改正された労働基準法では残業時間の上限が定められ、中小企業も2020年4月1日から規制の対象となりました。働き方関連法では有給休暇取得の義務化がはじまっており、少ない時間で現在の業務を遂行することの重要度がますます高まっています。


書類の電子化で期待できる効果

  • いつでも欲しい情報が引き出せ、編集できるのでリモートワークが促進する
  • 移動時間削減で業務時間が短縮
  • 現行の書類保管場所の省スペース化
  • 書類の内容をデータ化することで分析可能になり、二次活用できる
  • スムーズな情報の検索、共有で業務が効率化


書類データ化ソリューションの背景

MM総研が2019年7月30日に『AIを活用した手書き文字認識のAI-OCR(光学文字認識)サービスの利用実態』を調査しました。抽出した国内企業1000社のうち、9.6%の企業がAI-OCRを導入済みという結果が出ました。また、企業規模が大きいほど導入率が高く、1000人以上の大企業だけでみると13.2%が導入済みという結果です。
※AI OCRとは、手書きの書類や帳票を読み取りデータ化するOCRへ、AI技術を活用する新たなOCR処理をいいます。

スクリーンショット 2020-01-16 11.27.03.png
AI-OCRサービスの導入していない企業も、サービス利用への関心は高く、51.9%が「利用に関心がある」と回答しました。こちらも大企業を中心に関心が高く、1000人以上の大企業では導入済みを含めると72.7%がAI-OCRを利用することに関心があります。

業種別で見ると、卸売業・小売業や製造業、官公庁など、大量の手書き帳票が発生する業種でより強い導入意向がみられています。
また、導入企業のうち85.7%が「データ作成に要する時間を削減できた」と回答し、82.1%は「ミスの発生率」を、78.6%は「当該業務に必要な人員数」を改善できたと回答しています。


一方、AIを使わない既存技術のOCRは、全体の85.8%が「活用できていない」と回答しています。手書き文字やフォントの文字認識能力の低さが理由としてあげられており、調査では「手書き文字の識字率が低い」という回答が全体の41.6%、「フォントの識字率が低い」が31.8%という結果でした。
精度が求められる「文字の読み取り」にはAIは欠かせない存在となり始めています。

AIを活用した書類データ化の仕組み


スクリーンショット 2020-01-16 10.43.11.png
【文字認識】では文字の特徴を理解し、何の文字かAIが判定します。

文字の特徴を理解させるために、多くの画像をAIに学習させます。
「あ」であれば「中央に十字線がある」、「下に楕円がある」、「楕円は右で切れていて払いがある」のような特徴があり、新しく読み込んだ文字が「その特徴にどれだけ当てはまるか」でどの文字であるかを判定します。

文字ごとに判定していくとどうしても似た文字を誤判定してしまいます。
また書き癖の強い文字やつなげ字の判定は難しいとされています。


スクリーンショット 2020-01-16 10.43.51.png
そのため、【修正】では文字として判定した後に文章としても適切かチェックし、修正します。
そうすることでより高い精度で書類を認識することが可能です。


書類データ化活用シーン

大量の紙書類の存在はバックオフィス業務の生産性向上を妨げます。
帳票を種類毎に仕分け、記載内容の入力漏れや誤字脱字を確認し、あとは間違いに気をつけながらPCにデータを入力していく...。このような作業をシステムが代替する例を紹介します。


アンケートの集計

セミナー後や購入後にお客様にアンケートをとりますよね。
その場で回収することもあれば、後日郵送してもらうこと、様々ですが、お客様の声を反映させるためにスピード感が大切です。
また、見込みのお客様の場合はよりスピード感のある対応が必要となるので、手書きのアンケートでも即座にデータ化出来ることは初期対応を早めるために効果的です。


過去書類のデータ化

書類を探したいのに探せない...。重要な書類も倉庫の中やキャビネットに眠り、『書類探し』が業務になっていませんか?
過去書類をデータ化することで、検索性の向上による業務時間の短縮はもちろん、今までの保管場所をなくすこともできます。


営業メモの共有

敏腕営業マンが客先でどんな会話をし、売上を上げているか...。は永遠のテーマです。
そのノウハウを共有したいが、商談メモや勉強ノートを共有するのは難しく、経験と勘だよりの営業活動となるケースが多くあります。
メモやノートをデータ化することでノウハウの共有だけでなく、受注までのシナリオや商談の傾向を分析することで「勝ちパターン」を確立することができます。


テスト答案の読み取り

テスト答案を読み取り分析することで、問題に対する正解不正解以上に「どの問題はどう間違えるのか」を分析できます。
誤答率の高い問題がどのように間違えられたのかを知ることで「なぜ間違えたのか」を分析し、より効果的な教育をおこなうことができます。


申込書のデータ化

お客様からの申込書、事務所で転記していませんか?
転記作業の手間や誤入力も削減することが出来ます。大切なお客様データだからこそ、早く正確にデータ化をする管理をおすすめします。


まとめ

手書き書類をデータ化することで業務効率化を進めることはもちろん、たまったノウハウを共有したり、分析したり、有効活用できます。
ノウハウを共有することで新人の教育コストを削減するだけではありません。データを参照する仕組みを作れば「質問しにくさ」も解消でき、副次効果としてストレスやミスの軽減も見込めるでしょう。


当社ではみなさまの課題やお困り事を一緒に解決していきます。
問い合わせ口からご連絡ください。

  • 書類のデータ化が自社でも活用できるか知りたい
  • その他活用例を知りたい
  • 困っていることを相談したい
  • 機械学習・深層学習は他になにが出来るのか興味ある


アクセルユニバースのご紹介

私達はビジョンに『社会生活を豊かにさせるサービスを提供する。』ことを掲げ、このビジョンを通して世界を笑顔にしようと機械学習・深層学習を提案しています。
例えば、現在人がおこなっている作業をシステムが代わることで、人はより生産性の高い業務に携わることができます。


acceluniverse


Twitter・Facebookで定期的に情報発信しています!

概要

AI技術の発展が進み、今や私たちの身の回りでも当たり前のようにAIが生活をより便利にしてくれています。この夢のような技術を支えているのは研究者の方たちによる地道な努力です。では、最近はどのような研究が行われているのでしょうか?

研究の成果は論文という形で公開されますが、世界中で活発に研究されているAI関連の論文は1日に数十~百本もの論文が出ています。そのためこれらの論文を読んで最新の研究動向をつかむことは難しいでしょう。

そこで今回はテキストマイニングと呼ばれる技術を用いて20年前から現在までに出版された大量の論文を自動で分析し、大まかでよいので、今流行っている研究や過去のトレンドを調べてみたいと思います。

目次

テキストマイニング

テキストマイニングって?

インターネットやSNSが発達し、個人が自分の考えを自由に発信できる今、膨大な量の文章データがネット上に集積していきます。こういった「生の」情報を集めることは簡単ですが、この中から本当に意味のある情報を引き出すことは容易ではありません。例えば数値データであるならば、平均値を求めたりすることで、大体の状況を把握することができますが、文章の場合にはこういった処理ができないからです。

テキスト(文章)マイニング(採掘)は、こういった問題に対処する一つの方法で、「膨大な文章の中から自分にとって価値のある情報を抽出する技術」のことです。最近よく見かける、ワードクラウド(下の図)もテキストマイニングを用いたものです。

wordcloud.png

一体どのような方法で文章から情報を抽出するのでしょうか?

それを見る前に、テキストマイニングの便利さを実感するために1つ例を考えてみます。
仮に洋服屋に勤務しているとして、売り上げがなかなか伸びなかったとします。あなたはその原因を探るべく、お客様アンケートを行いました。
従来の方法では

Q、品ぞろえに満足していますか?

  • 満足
  • 普通
  • 不満

のように選択式でないと定量的に扱うことができず、さらにセーターの品ぞろえが悪いのか、パーカーの品ぞろえが悪いのか、あるいはそれ以外なのか、区別がつきません。
これでは質問を作るのは手間だし、的確な情報も得ることは難しいです。

テキストマイニングを使えば、

Q、品ぞろえに関して不満な点はありますか?

のような自由記述で回答してもらい、これを分析にかけることで、「パーカー」「品ぞろえ」「悪い」といった大まかな回答の傾向をつかむことができ、適切な対処をとることができるでしょう。

このような利点からテキストマイニングは、SNSを対象にした商品のレビュー調査、新聞記事を対象にした社会学、対話型AI等、様々な用途に利用されいます。膨大なデータから何か新しい情報を抽出したい際にきっと強力な道具となるはずです。

分析方法

ここではテキストマイニングの流れについて説明したいと思います。あくまでテキストマイニングを利用した分析を述べることが主眼なので統計学的な詳細については省略します。
例として、2019年9月に環境活動家のグレタ・トゥンベリさんが国連で行ったスピーチの一部を見てみましょう。

This is all wrong. I shouldn't be up here. I should be back in school on the other side of the ocean. Yet you all come to us, young people, for hope? How dare you! You have stolen my dreams and my childhood with your empty words. And yet I'm one of the lucky ones. People are suffering. People are dying. Entire ecosystems are collapsing. We are in the beginning of a mass extinction. And all you can talk about is money and fairytales of eternal economic growth. How dare you!

このスピーチは環境問題に真剣に取り組まない各国の首脳らに向けた怒りのメッセージで、" How dare you! "「よくもそんなことができるものだ!」というフレーズが特徴的で話題を集めました。実際このフレーズは全スピーチ中で4回繰り返されています。

このスピーチ全文を分析にかけた場合には、ネガポジ分析(テキストマイニングを利用した分析の一つで、その文章全体がネガティブな内容なのか、ポジティブな内容なのかを判断する)では「ネガティブ」と判断され、よく出てくる単語として dareや, air (大気), fail (失敗する), solution (解決策), emission (排出)のような環境問題系の言葉が現れるはずです。また、語同士のつながりは、How, dare, you の3語のつながりが明確に出るはずです。

それでは分析の流れを順を追って説明していきます。(実際にはソフトの「実行」ボタン一つで完了します)

1、まず、文章を一文ごとに区切ります。英語の場合はピリオド(.)で区切ればよいのですが、 U.S.AMr. Tanaka のような例外もあるので、こういった例外を集めた一種の「辞書」が必要です。ソフトはこの「辞書」を参照しつつ全文を区切っていきます。今回用いるソフトウェアKH Coderではこの作業をPearlのモジュールを使って行っているようです。
例えば上のスピーチの一文

I shouldn't be up here.  私は今ここにいるべきじゃない 。

をとってきたとしましょう。

2、区切った一文を今度は単語ごとに区切ります。英語の場合スペースで区切ればよいです。ただし shouldn't = should not のような例外もあるので、これも「辞書」を参照しつつ行います。
上の例では

I, should, not, be, up, here

となります。

3,取り出した単語一つ一つについて、基本形に直します。過去形を現在形に直したり、複数形を単数形にしたりするということです。そうすることで carscar 等の二種類の単語を一つにまとめて扱うことができ、分析が楽になるからです。この作業をステミング(stemming)と呼びます。これにも「辞書」が必要です。英語の場合には "Stanford POS Tagger"、 "FreeLing"、 "SnowBall" といった辞書が公開されています。今回は2、および3の作業には "Standard POS Tagger"を用います。
この作業を行うと上の例では

I, shell, not, be, up, here

となります。

4,次に stop word を削除します。これは英語の場合 be動詞や前置詞など、どんな文章にも頻繁に現れる、重要ではない語のことです。何をstop word とするかは分析者が自分で定義します。
上の例では

not, here

のようになるかもしれませんし、何も残らないかもしれません。

5,ここまでの作業はどのテキストマイニングのソフトにも共通の前処理でした。ここからどのように分析を行っていくのかがそのソフトの特徴となります。分析の方向性には以下のように大きく二つあります。

  • 分析者があらかじめ指定した単語を中心にコンピュータが分析する手法
    • 例えば地球温暖化についての新聞記事を対象としている際に、分析者が「火力発電」という切り口で分析を進めたい場合、コンピューターは指定された「火力発電」を含む文章を集め、多変量解析の手法で分析します。(単語の出現回数を数えたり、一緒に現れやすい単語の組を探したりします)
    • 分析者の問題意識が反映されやすい一方で、客観性に問題があるかもしれません。

  • 分析者が何の条件も指定せず、バイアスなしでコンピュータが分析する手法
    • 初めから全データをコンピュータが多変量解析の手法で分析し、得られた結果から何が言えるのかを考えます。
    • 上の例だと、地球温暖化に関する記事を全て分析にかけ、その中で「火力発電」がどのくらいのウエイトを占めているのかなどを調べます。
    • 結果があいまいになる(ほかのデータの中に埋もれやすい)恐れがある一方で客観性は保証されます。

今回用いるKH Coderはどちらのアプローチでも分析できるのが特徴です。

実際に後者の方法で上のスピーチ全文についての分析を行い、「共起ネットワーク」(語の出現回数を丸の大きさで表し、語同士のつながりを線の太さで表した図)を描いたものが次の図です。

example.png

中心付近で、 How, dare, youの3語が強く結びついているのが分かります。ただ、頻出の単語は come, people, say 等、環境問題特有のものではなく、一般的に多くの文章でよく使う単語が目立ちます。このスピーチは短いのでまだマシですが、大量の文章を分析するとこの傾向がさらに強まると考えられます。そのため、こういった単語はstop wordにしてしまうか、あるいは表示する単語の出現回数に上限を設けるなどの対策が必要です。


データの収集

arXiv

論文の収集には、物理、数学、情報科学といった分野の論文が保存・公開されている、arXivというサイトを使います。arXivは時間のかかる査読(提出した論文を他の専門家がチェックする過程)を経ずに論文を無料で投稿できるため、多くの論文が集積しています。今回は分野を機械学習分野に絞り、論文の最初に書かれている、Summary(要約)を集めて分析したいと思います。Summaryは短いので大量の論文から集めても計算時間がそれほど長くはならず、また論文全体の内容が凝縮されているので、機械学習に関係のない単語の割合が少なく、分析しやすいと考えたからです。

スクレイピング

大量の論文を集めるにはスクレイピングという手法を用います。いちいち自分で該当するwebサイトにアクセスせずに、自動でダウンロードしてくれる便利な方法です。arXivはスクレイピング用のAPIを用意してくれているのでこれを利用します。今回は2019年、2018年、2017年、2016年、~2009年、~1999年に出版された論文を集めます。

※以下のコードは Google Colaboratory で動作確認済みです。

まずは必要なライブラリをインポートします。

import arxiv
import pandas as pd

※ arxivが入っていない場合は、次のように打ってインストールしてください。

! pip install arxiv


このarxivというAPIを使えば、検索条件を指定するだけで自動で論文名、著者、日付、要約などをダウンロードできます。
今回は、「機械学習分野(LG)で2019年に出版されたもののうち、最大10,000件を提出日の新しい順に」取得します。それが以下のコードです。

latestQuery = arxiv.query(query='cs.LG AND submittedDate:[20190101 TO 20191231]', max_results=10000, sort_by='submittedDate', sort_order='descending')

得られるデータは辞書形式で見にくいのでデータフレーム形式(エクセルのような表形式)に直します。

df_latest = pd.io.json.json_normalize(latestQuery)
print(df_latest)

以下のような表が得られます。

スクリーンショット 2019-12-27 17.49.22.png

ここから Summary(要約)だけ取り出します。

df_latest_s = df_latest[['summary']]
df_latest_s.index.name='index' #後でつかうソフトに合わせるためのもので特に意味はありません。 

最後に、得られたデータを同じディレクトリにcsvファイルとして保存します。

df_latest_s.to_csv('./latest_data.csv')

全く同様に、2018年、2017年...の論文を集めます。

# 検索条件を指定
oneoldQuery = arxiv.query(query='cs.LG AND submittedDate:[20180101 TO 20181231]', max_results=10000, sort_by='submittedDate', sort_order='descending')
twooldQuery = arxiv.query(query='cs.LG AND submittedDate:[20170101 TO 20171231]', max_results=10000, sort_by='submittedDate', sort_order='descending')
throldQuery = arxiv.query(query='cs.LG AND submittedDate:[20160101 TO 20161231]', max_results=10000, sort_by='submittedDate', sort_order='descending')
tenoldQuery = arxiv.query(query='cs.LG AND submittedDate:[20000101 TO 20091231]', max_results=10000, sort_by='submittedDate', sort_order='descending')
tweoldQuery = arxiv.query(query='cs.LG AND submittedDate:[19900101 TO 19991231]', max_results=10000, sort_by='submittedDate', sort_order='descending')

# データフレーム型に変換
df_oneold = pd.io.json.json_normalize(oneoldQuery)
df_twoold = pd.io.json.json_normalize(twooldQuery)
df_throld = pd.io.json.json_normalize(throldQuery)
df_tenold = pd.io.json.json_normalize(tenoldQuery)
df_tweold = pd.io.json.json_normalize(tweoldQuery)

# Summaryだけ抜き取る
df_oneold_s = df_oneold[['summary']]
df_oneold_s.index.name='index'
df_twoold_s = df_twoold[['summary']]
df_twoold_s.index.name='index'
df_throld_s = df_throld[['summary']]
df_throld_s.index.name='index'
df_tenold_s = df_tenold[['summary']]
df_tenold_s.index.name='index'
df_tweold_s = df_tweold[['summary']]
df_tweold_s.index.name='index'

# csvファイルに保存
df_oneold_s.to_csv('./oneold_data.csv')
df_twoold_s.to_csv('./twoold_data.csv')
df_throld_s.to_csv('./throld_data.csv')
df_tenold_s.to_csv('./tenold_data.csv')
df_tweold_s.to_csv('./tweold_data.csv')

これでデータの準備は整いました。なお2009年、1999年に出版された論文は少なすぎたので、前10年分をとりました。

分析

今回テキストマイニングに用いるソフトはKH Coderです。これは日本人の方が開発されたソフトで、英語だけでなく日本語や中国語にも対応しています。

KH Coderのインストール

ここからダウンロードできます。Windowsの場合はダウンロードしたファイルを実行するだけですが、MacやLinuxの場合、MySQLやPearl、Rの設定などを自分で行わなければいけないので環境構築が大変です(インストールを自動化してくれる有償サポートもあります)。基本的には このサイト に従えばよいですが、それでもエラーが頻発すると思います(私はいやというほどしました)。どうしても解決しない場合は、製作者の方が質問を受け付けてくださっているので ここで質問してみるのも手です。

私が詰まったエラーを二つ書いておきます。

・MySQLの「LOAD DATA LOCAL INFILE」コマンドでエラー

err2.png

↓エラーメッセージ

SQL Input:
LOAD DATA LOCAL INFILE '/Applications/khcoder-master/config/khc26/khc26_ch.txt' INTO TABLE rowdata CHARACTER SET utf8mb4
Error:
The used command is not allowed with this MySQL version
```

これはKH Coderの開発時からMySQLのバージョンが新しくなったことによる問題です。まずターミナルで

mysql -uroot

と打ってMySQLにログインします。その状態で次のようにコマンドを打てば解決するはずです。

SET PERSIST local_infile= 1;

・MySQLの「GROUP BY」でエラー

error1.png

↓エラーメッセージ

SQL Input:
INSERT INTO hgh2 (genkei, sum, h_id, h_name)
SELECT hgh.genkei, SUM(num), hinshi.id, hinshi.name
FROM hgh, hinshi
WHERE hgh.hinshi=hinshi.name
GROUP BY hgh.genkei, hgh.hinshi

Error:
Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'khc25.hinshi.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
```

これも 開発時からMySQLのバージョンが更新されたことによる問題です。MySQLにログインした状態で以下のコマンドを打てば解決します。

mysql> set global sql_mode=(selectreplace(@@sql_mode,'only_full_group_by',''));

KH Coderの設定

上述したように、文章から単語を取り出して基本形に直すには「辞書」が必要です。また、stop wordの削除を行うには、自分でstop wordを定義しなければいけません。

まず、今回使う辞書 "Standard POS Tagger" をダウンロードして適当な場所に保存しましょう。ここからダウンロードします。
KH Coder のメニューバーから、【プロジェクト】→【設定】→【語を抽出する方法】→【Standard POS Tagger】→【*. TAGGER file path】に先ほど保存した場所を指定します。また、同時に【Stop words】も定義します。KH Coderをダウンロードしたときに一緒にダウンロードされる、sample fileをそのままコピペすればよいでしょう。

また、【その他】の「前処理効率化のためにデータをRAMに読み出すを選択しておくと前処理が早くなるのでチェックしておくと良いです。

前処理の実行

設定が終われば、【プロジェクト】→【新規】から先ほどスクレイピングで集めたファイルを指定します。「分析対象とする列」にはindexではなく、 **summaryを指定** するようにしましょう。また「言語」は英語、Standard POS Tagger となっていることも確認しましょう。

次に前処理をします。メニューバーから【前処理】→【前処理の実行】を押し、現れるダイアログは「OK」を選択し、しばらく待ちます(私の場合1~10分ほどでした。)
初めのうちはここで山ほどエラーが出ると思いますが一つ一つつぶしていきましょう。

結果

結果の表示にはその分析法に応じて複数の描画の方法があります。「対応分析」と「共起ネットワーク」が視覚的にわかりやすいので今回はこれを使いました。他にも多くの方法があるので詳しくはKH Coderのマニュアルを参照しましょう。マニュアルは、メニューバーから【ヘルプ】→【マニュアル】で見ることができます。

まずは、古い順に共起ネットワークを描いていきます。共起ネットワークは、語の出現回数を丸の大きさで表し、語同士のつながりを線で表しています。また、語の色分けについては、「サブグラフ検出」と呼ばれる方法で比較的強くお互いに結びついている部分を自動で検出してグループ分けを行った結果です。ただし、マニュアルにも書かれている通り、

あくまで機械的な処理の結果であるから,色分けには必ず重要な意味があるはずだと考えて深読みをするのではなく,グラフを解釈する際の
補助として利用することが穏当であろう

とのことなので注意します。
語同士のつながりには実線と破線がありますが、同じサブグラフに属する語同士は実線、そうでなければ破線という意味です。

まずは一番古い1990 - 1999年まで(実際にあったのは1997/12 - 1999/12)に出た全論文33本について分析を行ったのが以下の図です。

twenty.png

algorithmという単語が最もよく出てきていることからもわかるように、この時期は基礎的な研究が主だったことがうかがえます。
reinforcement, agent, maxq, corpus, natural, language 等の単語から、強化学習や自然言語処理の研究がすでに始まっていたこともわかります。


続いて2000 - 2009年にかけて出版された全論文762本について分析したのが以下の図です。

ten.png

依然 algorithm が最頻出単語です。 vector - machine はいわゆる SVM(サポートベクターマシン)、 decision - tree は決定木、 classification = 分類、など今につながる具体的な手法が目につきます。 time - algorithm や、 model - learning のつながりが現れたことから、機械学習の原理の研究から、現実的な問題解決の方法論へと研究が移行していったのがこの時期だと考えられます。


続いて2016年に出版された全論文3568本について分析した結果が以下です。

throld_100-1500.png

上述のように機械学習に関係のない語をはじくために、出現回数が100回以上1500回以下の単語に絞って書いてあります。この対処法は感覚的なもので、これが最も適切な処理である根拠はありません。実際機械学習の中心的な単語であるはずの algorithm model が出てきていないのは出現回数が大きすぎたためです。これがテキスト分析の難しいところですが、これ以上ソフトで分析を進めるのは難しいので、あとは注意深く結果を見て、何かしらの傾向をつかめるように頑張ります。

左にある緑色の大きなグループは、 task を中心として image, classification, dataset, frameworkのような単語が並んでいることから、画像分類の内容であると推測できます。ディープラーニングによって画像分類の精度が飛躍的に高まり、話題を集めたのが2012年のことなので、これは比較的新しい話題で、研究のフロンティアだったのだと考えられます。
右の方には reinforcementを中心にした強化学習、下の方には wordを中心にした自然言語処理が20年前から依然としてあり、この二分野は長らく、よく研究されていることが言えます。
上の方には optimization(最適化), gradient(勾配)などのやや基礎的な研究内容があります。
また、教師なし学習の代表格 clusteringも目につきます。


続いて2017年に出版された52381本の論文について。

twoold_200-1000.png

出現回数が200回以上1000回以下の単語に絞った描画です。
この年に特徴的なのは、reinforcementを中心とする強化学習に関連する単語群の出現数がほかの分野に比べて相対的にずっと多くなったことです。前年のグラフと比べてみれば一目瞭然です。
この時期に強化学習関連で目立ったことがあったのかどうか調べてみると...ありました!
2016年3月に GoogleのAlphaGoが韓国のトップ棋士李世乭さんに5番勝負で4勝1敗にて勝利し、2017年5月には中国のトップ棋士柯潔さんにも3局全勝を上げていました。ニュースでも大々的に取り上げられましたね。

将棋やチェスなど数あるボードゲームの中でも、囲碁はそのありうる盤面の数が際立って大きいです。そのためコンピュータの得意とする全探索手法が使えないために、人間に勝利することは難しいと考えられていたために、AIに詳しい人ほど、この対局は衝撃的だったのでしょう。これを機に研究者たちの中でも強化学習の可能性に注目が集まり、よく研究されるようになったのだと推測されます。

左上の方には RNN, LSTM, GAN といったディープラーニングに関する話題が多く出てきています。以前にもあったけれども、ほかの語に埋もれていたのかもしれないので、この時期にはやったのかどうかは何とも言えません。

左の方には language, textなどの自然言語処理の話題があり、前年に比べ相対的に大きくなっています。また、 speechが新たに自然言語処理に加わっているのも面白いですね。


続いて2018年に出版されたもののうち5600本(「うち」と書いているのは、APIの仕様のせいか、全ての論文を集めることができなかったためです)。

oneold_200-1000.png

出現回数が200回以上1000回以下の単語に絞った描画です。
下の方にある optimization, gradientはアルゴリズムの研究のような基礎的な話題でしょう。
左の方にある青い大きなグループは layerがハブになっていて、また雑多な単語がつながっていることからディープニューラルネットワークを用いた応用的な話題かと思われます。
上の方にあるオレンジ色のグループは強化学習、右の方にある紫色のグループは自然言語処理の話題でしょう。

最後に2019年に出版されたもののうち3000本です。

latest_200-1000.png

出現回数が200回以上1000回以下の単語に絞った描画です。
アルゴリズム(赤)、強化学習(青)、自然言語処理(オレンジ)、画像認識(黄緑)など、今よく聞く話題がよく研究されていることがわかります。また、突出して出現頻度が多い語はなく、色分けされたグループもだいたい同じ規模です。これが出現回数の制限によるものかどうか調べるため、試しに2000回以下、及び制限なしの場合に同じ図を描いたのが次の図です。

latest_2000.png

latest_max.png

やはり同じ傾向が見られます。このことから、現在の研究は、アルゴリズム、強化学習、自然言語処理、画像認識がどれも活発に研究されていると言えるでしょう。


これまで出版年ごとに共起ネットワークを出してきました。各年ごとの特徴はよく分かるのですが、時間変化はわかりにくくなっています。
時間変化をメインに共起ネットワークを描くには、すべての論文データを出版年とSummaryだけ残して一つのCSVファイルに統合し、これを前処理します。そして共起ネットワークを描く際のオプションとして、「共起パターンの変化を探る(相関)」にチェックを入れます。こうすると、以下の図が得られます。

change_100_1000-5000.png

この図は、赤い線ほど、最近出版された論文に特徴的なつながり、青い線ほど古い論文に特徴的な論文に特徴的なつながりを表します。例えば、下の方にある rewardは古い論文では regretとよくつながっていましたが新しい論文では reinforcementとよくつながっているようです。これは強化学習における rewardに対する考え方が変化したことを表している可能性があります。
他にも、右の方にある languageは、よく共起する単語が wordから textへと変化していることもわかります。これは自然言語処理の発展により、研究対象が wordから textへと移り変わったことを示していると推測することもできます。

共起ネットワーク以外の表現方法もあります。以下の図は対応分析と呼ばれる手法を用いて分析した結果です。

unified_taiou.png

この図では出版年が書いてある赤四角の領域に近い言葉ほど、その年に特徴的な言葉であることを意味します。
例えば2018年と2019年の四角は領域がほとんどかぶっていて、出てくる主要な語に変化が少なかったことを意味します。ただ、出てきている語を見ると、 CNN, reinforcementのような機械学習の具体的な手法や分野を表す語がなく、抽象的な語ばかりなので、ここからトレンドの変化を探ることはできませんでした。描く対象になる語の出現回数を制限するなど、パラメータを適切な値にできればそういったことが可能であったかもしれません。


参考文献


Twitter・Facebookで定期的に情報発信しています!

今回は「じゃらんの口コミをスクレイピングしてみた」ということで紹介していきます。
※この記事はスクレイピング初心者向けに書いています。

目次

 1はじめに
 2スクレイピング
 3可視化
 4分析・まとめ
 5注意すること
 6終わりに

はじめに

 皆さんは今年の冬をどのように過ごす予定でしょうか?
 今回は「冬」「雪」といえば「スキー」「温泉」ということで、この二つのキーワードに関連するホテル・旅館の口コミを分析しました。LINEトラベルのサイトによると、温泉が楽しめるスキー場1位は「山形蔵王温泉スキー場」のようです。
 このエリアの口コミ評価今現在第一位のホテルについてスクレイピングさせていただきました。

 今回は特定のホテルの口コミをスクレイピングし、どんな人が口コミを投稿し、どんな評価をつけているのかをグラフを表示しながら分析しました。

スクレイピング

 今回取得する情報

 ・性別
 ・年齢
 ・評価
 ・いつ宿泊したか
 ・誰と旅行したか
 ・価格帯

 この記事は初心者向けに書いていますので、コードを初めから紹介したいと思います。
 ここではスクレイピングからデータフレームを作るところまでを紹介しています。
 
 まずはじめに必要なものをインポートします。

 
from bs4 import BeautifulSoup import urllib
import pandas as pd 
import requests

 

取得したいホテル口コミページのURLを取得します。

html = requests.get('https://www.jalan.net/yad309590/kuchikomi/')
soup = BeautifulSoup(html.content,'html.parser')

このホテルの口コミページは3ページあったので、それぞれのURLをリストに入れておきます。

 url_list = ['https://www.jalan.net/yad309590/kuchikomi/?screenId=UWW3701&idx=0&smlCd=060203&dateUndecided=1&yadNo=309590&distCd=01',
'https://www.jalan.net/yad309590/kuchikomi/2.HTML?screenId=UWW3701&idx=30&smlCd=060203&dateUndecided=1&yadNo=309590&distCd=01',
'https://www.jalan.net/yad309590/kuchikomi/3.HTML?screenId=UWW3701&idx=60&smlCd=060203&dateUndecided=1&yadNo=309590&distCd=01']

ここから本題に入っていきます。
まず、口コミ投稿者の性別と年代を取得し、綺麗な形にします。

valuer = []
    for row in url_list:
row = str(row) html = urllib.request.urlopen(row) soup = BeautifulSoup(html) valuer.append(soup.find_all("span", class_='jlnpc-kuchikomi__cassette__user__name')) continue valuer_list = valuer[0]+valuer[1]+valuer[2] new_valuer_list = [] for row in valuer_list: row = str(row) new_valuer_list.append(row.split('(')1.split(')')0)

このようになります。


スクリーンショット 2019-12-27 15.22.27.png

性別・年代をそれぞれデータフレームに入れます。


data = pd.DataFrame()
sex = []  
age = []  
for row in new_valuer_list:
  row = str(row)
  sex.append(row.split(' / ')[0])
  age.append(row.split(' / ')[1])
 new_age = []
 for row in age:
   row = str(row)
   new_age.append(row.replace("代","'s")) 
 data['sex'] = sex
 data['age'] = new_age

スクリーンショット 2019-12-27 15.33.04.png

次に、口コミ評価を取得します。


value = []
for row in url_list:
    row = str(row)
    html = urllib.request.urlopen(row)
    soup = BeautifulSoup(html)
    value.append(soup.find_all("span", class_='jlnpc-kuchikomi__cassette__rating__em'))
    continue
value = value[0]+value[1]+value[2]
new_value = []
for row in value:
    row = str(row)
    new_value.append(row.split('')[1].split('')[0])
data['value'] = new_value

最後に、いつ・誰と・どのくらいの価格帯で利用したのか取得します。


what = []
 for row in url_list:
 row = str(row)
 html = urllib.request.urlopen(row)
 soup = BeautifulSoup(html)
 what.append(soup.find_all("div", class_='jlnpc-kuchikomi__cassette__attribute1 styleguide-scope'))
 continue
 
 what = what0+what1+what2
 
 new_what = []
 for row in what:
 row = str(row)
 new_what.append(row.split('')1.split('')0)
 
 date = []
 trip = []
 for row in new_what:
 row = str(row)
 date.append(row.split('【')1.split('宿泊')0)
 trip.append(row.split('\xa0\xa0')1.split('】')0)
 
 data['date'] = date
 data['trip'] = trip

 price = []
 for row in what:
 row = str(row)
  price.append(row.split('【宿泊価格帯】')1.split('(大人1人あたり/税込)')0)

 data['price'] = price

データフレームが完成しました。


スクリーンショット 2019-12-27 15.52.35.png

可視化

ここでは先ほどスクレイピングした口コミ投稿者のデータについて可視化し、簡単に考察します。
まずはじめに、取得したデータについて簡単に見ていきましょう。


性別

スクリーンショット 2019-12-27 16.09.00.png

年代


スクリーンショット 2019-12-27 16.18.32.png

口コミ評価


スクリーンショット 2019-12-27 16.27.10.png

いつ利用したか


スクリーンショット 2019-12-27 16.30.44.png

誰と利用したか


スクリーンショット 2019-12-27 16.34.27.png

価格帯


スクリーンショット 2019-12-27 17.35.14.png

分析・まとめ

データからわかること
・口コミ投稿者は50代が一番多く、60代、40代と続く。
若い層(20代、30代)よりも多いのは、お金に余裕があるからなのか、あるいは温泉地ということが関係しているのか。
  ・今回「スキー」と「温泉」というキーワードで探したが、2019年8月の投稿が多い。夏でも人気のある観光地なのかもしれない。
・大人1人あたり1万円を超え、高いものは3万円を超えるものもあることがわかる。夫婦旅行が多いことにも関係していそう。


 

仮説:蔵王には、お金に比較的余裕があり、子育ても終わった50代の夫婦が旅行に来ることが多いのでしょうか。8月に口コミが多かったのも、冬に体力の必要なスキーを楽しむのではなく、ゆったりと自然を感じたいという人が多いのかもしれません。もしかすると、今回、「スキー」「温泉」で蔵王が出てきたのは、スキーで有名という理由だけではなく、体力のある若い世代に冬の時期に多く来て欲しいという地域の狙いがあるのかもしれません。


今回取得した口コミの数は74件と少なく、取得したデータの種類も少ないため、事実に対して理由を断定することはできません。しかし、だからこそ上記の仮説のように想像を膨らませ、いろいろなことに思いを巡らせることができるのかもしれませんね。


注意すること

口コミを分析する際にはいくつか気をつけなければいけないことがあります。
・口コミ分析は、宿泊者全員について分析できるというわけではなく、あくまで「口コミをした人」のみに対する分析となります。もしかしたら、男性よりも女性の方が口コミをするのが好きかもしれないし、年齢層が高めの人より若い人の方が口コミを投稿するということもあり得ます(その逆も然り)。
 口コミを分析している時点で情報を限定してしまっているということに気をつける必要があります。
・上と似ているのですが、口コミを投稿する人はどんな人かを考える必要があります。
 口コミを通して伝えたい!という人はどんな人でしょうか?宿泊にとても満足してお礼を伝えたい、良さを伝えたいという人や、何か不満があって意見を言いたい、改善策を伝えたいという人が想定されます(不満だった人は関わりたくないから口コミを投稿しないということも考えられます)。可もなく不可もなく感じている人は、口コミ投稿するのが好きという人を除き、わざわざ口コミを投稿するでしょうか?
・口コミは利用した人の感想ですから、主観が入り、その情報が正確かを確かめることは難しいでしょう。もしかしたら嘘をついている人や誇張して書いている人、あるいはサクラがいるという可能性も0ではありません。完全ではないということを意識する必要があります。
・今回は、口コミ評価が高評価に著しく偏っているため、どんな人が高評価・低評価をするのか明らかにすることはできませんでした。「口コミ評価が高評価に著しく偏っている」のは、このホテルに限ることなのか、もしくはエリア全体、口コミ全体でそういう傾向があるのかを明らかにすると、今後の口コミ分析の役に立つかもしれません。

終わりに

今回は特定のホテルの口コミをスクレイピングし、投稿者についての分析を行いました。
 次回は、今回のスクレイピングの手法を活かして、どこかの「エリア」のホテル・旅館についてスクレイピングし、そのホテル・旅館ごとの傾向や、どんな人がそのホテル・旅館に向いているかなどを考察していこうと思います。
 後々、機械学習を用いて、旅行しようと思っている人に最適なホテルをオススメできる機能を作りたいと考えています。



Twitter・Facebookで定期的に情報発信しています!

アクセルユニバース株式会社(以下当社)では、人が対応している業務を画像認識、音声認識、文字認識等を活用して効率化する機械学習ソリューション開発をおこなっています。


インターン生は業務の一環としてkaggleに取り組んでおり、先日のNFL Big Data Bowlコンペにて銅メダルを獲得しました。
こちらのコンペは、アメリカンフットボールのランプレイにおいて、攻撃側が進むヤード数を予測するコンペです。


メダル獲得した小野くんのコメントです。
ーーー
主な勝因は特徴量エンジニアリングの部分だと考えています。
調子に波があるだろうと考えたので選手やチームの情報は極力使わず、選手の位置情報や進行方向のベクトルを用いて様々な切り口で特徴量を作ることに注力しました。

その他、今回はカーネルコンペであったため、以前よりコーディング力がつき、メモリやコードの実行時間に対する意識も増しました。
また過学習を防ぐことの重要性を再認識しました。
ーーー


現在、解法を詳しく解説したものを公開できるように準備を進めています。


その他当社インターンでは論文のまとめ記事論文 Attention Is All You Need から Attentionモデルの解説を書いたり、実際にTensorFlowでVGG19を使ったインスタ映え画像の生成実装をしています。 随時紹介していくので是非ご覧ください!


Twitter・Facebookで定期的に情報発信しています!

はじめに

この記事では物体検出に興味がある初学者向けに、最新技術をデモンストレーションを通して体感的に知ってもらうことを目的としています。今回紹介するのはAAAI19というカンファレンスにて精度と速度を高水準で叩き出した「M2Det」です。one-stage手法の中では最強モデル候補の一つとなっており、以下の図を見ても分かるようにYOLO,SSD,Refine-Net等と比較しても同程度の速度を保ちつつ、精度が上がっていることがわかります。
M2Det

https://arxiv.org/pdf/1811.04533.pdfより引用

物体検出デモ

それではM2Detでの物体検出をしていきたいのですがひとつ問題が
著者がgithubに公開しているソースコードはCUDAを使用する前提のため、NVIDIAのGPUが搭載していない私のPCではすぐに動かす事ができません。
そのため今回はGPUなしでも動かせる環境を提供してくれるGoogle先生の力をお借りします!
ということでGoogle Colaboratoryを使ってM2Detを動かしていきます。
例のごとくqijiezhao/M2Detの説明を参考に進めていきます。


Step1.前準備

Google Colaboratoryを開いたら先ずハードウェアのアクセラレータをGPUに設定しましょう。メニューバーの「ランタイム」→「ランタイムのタイプを変更」をクリック。「ハードウェア アクセラレータ」のプルダウンからGPUを選択して「保存」します。これで設定は完了です。
M2Det
それではコードを書いていきます。必要なモジュールをインストールし、上記githubからクローンを作成します。M2Detファイルに移動したらシェルを以下のように実行します。

!pip install torch torchvision
!pip install opencv-python tqdm addict
!git clone https://github.com/qijiezhao/M2Det.git
%cd M2Det
!sh make.sh

Step2.学習済モデルをGoogle Driveからダウンロードする(引用)

次に学習済モデルを入手します(とてつもなく学習に時間がかかるので出来合いのものを使用させていただきます)。githubの説明にも書いてあるようにbackbornはVGG-16とし、指定のGoogle Driveからダウンロードしてきます。ダウンロードが簡単にできる便利なもの(nsadawi/Download-Large-File-From-Google-Drive-Using-Python)を見つけたので引用させていただきます。

#引用開始
import requests
def download_file_from_google_drive(id, destination):
  URL = "https://docs.google.com/uc?export=download"
  session = requests.Session()
  response = session.get(URL, params = { 'id' : id }, stream = True)
  token = get_confirm_token(response)
  if token:
    params = { 'id' : id, 'confirm' : token }
    response = session.get(URL, params = params, stream = True)
  save_response_content(response, destination)
def get_confirm_token(response):
  for key, value in response.cookies.items():
    if key.startswith('download_warning'):
      return value
    return None
def save_response_content(response, destination):
  CHUNK_SIZE = 32768
  with open(destination, "wb") as f:
    for chunk in response.iter_content(CHUNK_SIZE):
      if chunk: # filter out keep-alive new chunks
        f.write(chunk)
#引用終了
%mkdir weights
directory = '1NM1UDdZnwHwiNDxhcP-nndaWj24m-90L'
adress = './weights/m2det512_vgg.pth'
download_file_from_google_drive(directory, adress)

これでM2Detフォルダの中に学習済モデルm2det512_vgg.pthがダウンロードできました。


Step3.判別の閾値を設定する(任意)

ここで一旦パラメータの調整を挟みます。YOLOでは判別の閾値が0.5以上の時にアノテーションすることにしていたのでM2Detでも同じ値にします。demo.pyの63行目を確認すると

def draw_detection(im, bboxes, scores, cls_inds, fps, thr=0.2):

thrの値がデフォルトで0.2になっているのでこの値を0.5に以下のように書き換えます。

!sed -i -e "63c def draw_detection(im, bboxes, scores, cls_inds, fps, thr=0.5):" demo.py

Step4.Google Driveにアップロードした動画ファイルをM2Detフォルダの指定ディレクトリにコピーする

後は判別させたい画像または動画をGoogle Driveからimgsフォルダに移動させてきましょう。なのでご自分で予めGoogle Driveに画像または動画をアップロードしておきましょう。今回は動画を使用しているので以下のようにマウントした後、任意の動画をコピーします。実行の際にオースコード(Auth code)が要求されるのでURLをクリックして表示されるコードを貼り付けます。

from google.colab import drive
drive.mount('/content/drive')
!cp /content/drive/My\ Drive/*.mp4 ./imgs #動画用

M2Det
これで必要なものは全て揃いました。

Step5.デモ

ここでdemo.pyの引数について確認してみます。demo.pyの17行目から24行目を確認すると以下のように記述されています。

parser = argparse.ArgumentParser(description='M2Det Testing')
parser.add_argument('-c', '--config', default='configs/m2det320_vgg.py', type=str)
parser.add_argument('-f', '--directory', default='imgs/', help='the path to demo images')
parser.add_argument('-m', '--trained_model', default=None, type=str, help='Trained state_dict file path to open')
parser.add_argument('--video', default=False, type=bool, help='videofile mode')
parser.add_argument('--cam', default=-1, type=int, help='camera device id')
parser.add_argument('--show', action='store_true', help='Whether to display the images')
args = parser.parse_args()

parser.add_argumentの直後に記述されている引数を実行の際に記述することで様々な使い方ができるようです。別途ダウンロードしてきた学習済モデルで動画を判別させるので以下のように実行します。

!python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --video VIDEO #動画用

実行すると動画のディレクトリを指定するように出てくるのでディレクトリを指定します(Step4でimgsフォルダにコピーしたならimgs/(ファイル名))
後は各フレーム毎に物体検出をしてくれるので待ちましょう。
M2Det

Step6.ファイルをダウンロードする

残念ながらmp4をchrome上で再生する術を知らないため、ローカルにダウンロードして再生することにします。以下のように2行で簡単にファイルのダウンロードができます。

from google.colab import files
files.download('imgs/<ファイル名>')

実装例

おわりに

今回M2Detを使用して動画の物体検出を行ってみました。リアルタイムの識別を検討する場合は限られた時間内に一定以上の精度を保証する信頼性がより重要となり、M2Detはこれを達成する一歩になるのでは無いかと思いました。YOLOやSSDについてもまだまだ改良されていくと予想しているので、引き続きリサーチしたいと思います。また、物体検出を利用した異常検知や店の空席率把握などに使えそうなので実装できたらまたブログ書こうと思います。

実装コード

https://colab.research.google.com/drive/1oSPhiGmZC-IeLnyoR2l-UIKIquP1i51g

その他、ドーナツを検知し、無人レジの実現に向けて検証もしており、現在、当社では技術の実用化に向けて様々な検証をしています。


Twitter・Facebookで定期的に情報発信しています!

概要

Adversarial ValidationはTrainデータとTestデータの分布が異なる際に、Testデータに似たValidationデータを作成するのに使われる手法です。
Kaggleなどのデータ分析コンペではTrainデータとTestデータの一部が与えられ、コンペ終了まではこの一部のTestデータに対するスコアのみ知ることができます。一部のTestデータだけを見てモデルを評価していると、全体のテストデータに対しては良いスコアが出ずに最終的に低い順位に終わることがあります。ですのでCross Validationなどを用いて求めたValidationデータに対するのスコアと一部のTestデータに対するスコアに相関があることが望ましい状態です。そのために重要なことはTestデータに似た分布を持つValidationデータを作成することです。


手法

最終的な目標はTrainデータとTestデータを分類するモデルを作成することです。

まずどちらのデータセットからのデータかをラベル付けするために、TrainデータとTestデータにそれぞれ新しい目的変数を与えます。例えばTrainデータには "1"を、Testデータには"0"を与えます。そしてTrainデータとTestデータを結合して、データがどちら由来か予測するモデルを作成します。
もしTrainデータとTestデータが同じ分布を持つとするとどちら由来かを予測できないはずです。逆にTrainデータとTestデータの分布が異なる場合は予測は容易になります。
予測結果からTrainデータとTestデータの分布が異なるようであれば、Testデータの分布に似たValidationデータを作成する必要があります。これはTrainデータのうち、モデルがTestデータに由来する確率が高いと予測したデータを選ぶことで作成できます。


それでは必要なライブラリをインポートして実装に進みましょう。

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
warnings.filterwarnings('ignore')
from tqdm import tqdm_notebook as tqdm

from sklearn.preprocessing import LabelEncoder
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
import lightgbm as lgb


TrainデータとTestデータの分布が同じ場合

まずデータセットを作成し、プロットしてみます。

X, y = make_classification(
    n_samples=10000,
    n_features=2,
    n_informative=1,
    n_redundant=0, 
    n_classes=2,
    n_clusters_per_class=1,
    class_sep=2.0,
    random_state=42
)

plt.scatter(X[y == 0, 0], X[y == 0, 1], s=10, alpha=0.5, label='class A')
plt.scatter(X[y == 1, 0], X[y == 1, 1], s=10, alpha=0.5, label='class B')
plt.legend(loc='upper right')
plt.show()

plot of dataset


このデータセットをTrainデータとTestデータに分け、Trainデータには "1"を、Testデータには"0"をそれぞれ新しく目的変数として与えます。その後、TrainデータとTestデータを結合して1つのデータセットに戻します。

X_train, X_test = train_test_split(X, test_size=0.33, random_state=42)

y_train = np.zeros(len(X_train))
y_test = np.ones(len(X_test))

X_all = np.concatenate([X_train, X_test], axis=0)
y_all = np.concatenate([y_train, y_test], axis=0)


これでTrainデータとTestデータが混ざったデータセットが出来上がりました。ここから新たに与えた目的変数を元にTrainデータとTestデータを分類するモデルを作成していきます。

X_train_adv, X_valid_adv, y_train_adv, y_valid_adv = \
    train_test_split(X_all, y_all, test_size=0.33, random_state=42, shuffle=True)

model = lgb.LGBMClassifier(
    n_estimators=1000,
    random_state=42)

model.fit(
    X_train_adv,
    y_train_adv,
    eval_set=[(X_train_adv, y_train_adv), (X_valid_adv, y_valid_adv)],
    eval_names=['train', 'valid'],
    eval_metric='auc',
    verbose=100)


このときのValidationデータを作成しモデルの性能を評価します。 ではモデルのパフォーマンスを見てみましょう。

ax = lgb.plot_metric(model.evals_result_, metric='auc')
plt.show()

plot of learing curve


結果を見ると、Validationデータに対してAUCはほぼ0.5あたりを示しています。AUCが0.5を示すということはモデルのパフォーマンスがランダムに分類するのと変わらないことを意味しています。これはモデルがTrainデータとTestデータをうまく分類できてないということです。つまりTrainデータとTestデータの分布が同じであることがわかります。


TrainデータとTestデータにの分布が異なる場合

次にTrainデータとTestデータの分布が異なる場合を見ていきましょう。

データはKaggleの2019 Data Science Bowlのデータを引っ張ってきました。データの中身や特徴量作成に関して、ここではコードだけにして割愛させていただきます。

test = pd.read_csv("../input/data-science-bowl-2019/test.csv")
train = pd.read_csv("../input/data-science-bowl-2019/train.csv")


def get_data(user_sample, test_set=False):
    all_assessments = []
    type_count = {'Clip':0, 'Activity': 0, 'Assessment': 0, 'Game':0}

    for i, session in user_sample.groupby('game_session', sort=False):
        session_title = session['title'].iloc[0]
        session_type = session['type'].iloc[0]

        if (session_type == 'Assessment') and (test_set or len(session) > 1):
            event_code = 4110 if session_title == 'Bird Measurer (Assessment)' else 4100
            all_attempts = session.query(f'event_code == {event_code}')
            num_correct = all_attempts['event_data'].str.contains('true').sum()
            num_incorrect = all_attempts['event_data'].str.contains('false').sum()

            features = {}
            features['installation_id'] = session['installation_id'].iloc[-1]
            features['title'] = session_title
            features['num_correct_attempts'] = num_correct

            features.update(type_count.copy())

            if test_set:
                all_assessments.append(features)
            elif num_correct + num_incorrect > 0:
                all_assessments.append(features)

        type_count[session_type] += 1

    if test_set:
        return all_assessments[-1]

    return all_assessments


compiled_train = []
for ins_id, user_sample in tqdm(train.groupby('installation_id', sort=False), total=17000):
    compiled_train += get_data(user_sample)

compiled_test = []
for ins_id, user_sample in tqdm(test.groupby('installation_id', sort=False), total=1000):
    test_data = get_data(user_sample, test_set=True)
    compiled_test.append(test_data)

X_train = pd.DataFrame(compiled_train)
X_test = pd.DataFrame(compiled_test)


特徴量作成の後にできたTrainデータとTestデータは次のようになっています。

display(X_train.head())
display(X_test.head())

heading of training and test dataframes


余分なinstallatio_idカラムは削除して、titleカラムのエンコーディングを行っておきましょう。

X_train = X_train.drop(['installation_id'], axis=1)
X_test = X_test.drop(['installation_id'], axis=1)

le = LabelEncoder()
le.fit(list(X_train['title'].values) + list(X_test['title'].values))
X_train['title'] = le.transform(list(X_train['title'].values))
X_test['title'] = le.transform(list(X_test['title'].values))


ここから先は上記のプロセスと同じくTrainデータとTestデータに新たな目的変数を与えて結合した後、TrainデータとTestデータが混ざったデータからそれぞれを分類していきます。

X_train['adv_target'] = 0
X_test['adv_target'] = 1
train_test_adv = pd.concat([X_train, X_test], axis=0).reset_index(drop=True)

train_adv, valid_adv = train_test_split(train_test_adv, test_size=0.33, random_state=42)
X_train_adv = train_adv.drop(['adv_target'], axis=1)
y_train_adv = train_adv['adv_target']
X_valid_adv = valid_adv.drop(['adv_target'], axis=1)
y_valid_adv = valid_adv['adv_target']

model = lgb.LGBMClassifier(
    n_estimators=1000,
    random_state=42)

model.fit(
    X_train_adv,
    y_train_adv,
    eval_set=[(X_train_adv, y_train_adv), (X_valid_adv, y_valid_adv)],
    eval_names=['train', 'valid'],
    eval_metric='auc',
    verbose=100)


ではモデルのパフォーマンスを見てみましょう。

ax = lgb.plot_metric(model.evals_result_, metric='auc')
plt.show()

plot of learing curve


Validationデータに対するAUCはおよそ0.93あたりで、TrainデータとTestデータの分布が同じ場合に比べモデルのパフォーマンスが良いことがわかります。これは今回用いたTrainデータとTestデータの分布が異なるため、モデルが容易に分類できるからです。

このようにして得られた結果から、TrainデータのうちTestデータである確率が高いと予測されたデータを取り出すことでTestデータに似たValidationデータを作成することが可能になります。またTrainデータとTestデータの分布が異なるかどうか見分ける指標としてAdversarial Validationを使うこともできます。


特徴量選択への応用

最後にAdversarial Validationを応用して特徴量選択を行う方法を紹介します。

まず先程のTrainデータとTestデータの分布が異なる場合に、予測に寄与した特徴量の重要度を見てみましょう。

plot of feature importance


これを見ると num correct attempts の重要度が高くなっています。これは num correct attempts がTrainデータかTestデータかの分類に大きく寄与していることを示しています。つまりTrainデータとTestデータの間でこの特徴量に乖離があることを意味しています。

これを受けて num correct attempts のカラムを削除してTrainデータとTestデータの分類を行ってみると、

new_X_train_adv = train_adv.drop(['num_correct_attempts'], axis=1)
new_X_valid_adv = valid_adv.drop(['num_correct_attempts'], axis=1)

model = lgb.LGBMClassifier(
    n_estimators=2000,
    random_state=42)

model.fit(
    X_train_adv,
    y_train_adv,
    eval_set=[(new_X_train_adv, y_train_adv), (new_X_valid_adv, y_valid_adv)],
    eval_names=['train', 'valid'],
    eval_metric='auc',
    verbose=100)

ax = lgb.plot_metric(model.evals_result_, metric='auc')
plt.show()

plot of learing curve


たしかにAUCスコアが低くなりTrainデータとTestデータの分類がしづらくなっていることがわかります。

このようにしてAdversarial Validationを応用することによって、TrainデータとTestデータで乖離している特徴量を見つけることができます。


まとめ

今回はKaggleなどの機械学習コンペで注目されているAdversarial Validationを紹介しました。Kaggleにおいて手元のバリデーションスコアとLeader Boardのスコアに乖離がある際に、適切なValidation setの作成や特徴量選択に役立ちます。実際に私もコンペで利用しており、今後ますます注目を浴びるのではないかと思われます。


Twitter・Facebookで定期的に情報発信しています!

このアーカイブについて

このページには、2020年1月に書かれた記事が新しい順に公開されています。

前のアーカイブは2019年12月です。

次のアーカイブは2020年2月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。