orizuru

つながる.見える.わかる IoTソリュ-ション

main_contents

更新情報

製造現場向けIoTソリューション

自社のIoTシステムを利用した製造業向けソリューション「Orizuru」は、工場内の各種設備からデータを収集するゲートウェイの提供、収集したデータ処理をするシステムを備えるトータルソリューションになります。

IoTソリューション全体像

  • 設備のデータ収集
  • 設備の制御
  • クラウドシステムとのデータ送受信
  • リアルタイム通信
  • 表示データの生成
  • 集められたデータの統計処理と機械学習
  • システムの処理結果を表示する
  • 設備の状態を表示する
  • 設備をコントロールする
  • ユーザー間のコミュニケーション
  • 3Dデータの各種表示
  • 3Dデータの360°ビュー

IoTソリューションの特徴

製造現場との双方向コミュニケーション
製造工場の現場担当者とサポート担当者とのコミュニケーションを、製造現場の映像やデータを画面で共有することで円滑なコミュニケーションを可能にします。今後の機能追加でビデオ通話など、双方向コミュニケーション機能が充実していきます。
リアルタイムデータの見える化
工作機器の温度や音圧、振動、電流値などのセンサーを3Dで確認しつつ、それらのデータをリアルタイムにグラフで表示するなど、機器の状態を把握するのに役立つ機能です。
CNCを扱えるGateway
NCプログラミングを扱えるGatewayの開発と提供を行えます。これによりメーカーを問わず、工作機器のデータ取得が可能になりますので、IoT促進の一躍を担っています。
WebGLを応用し、異常箇所を3DCADで特定
WebGL技術を応用し、工作機器のCADデータと各センサーの3D座標を設定することで、Webブラウザ上で様々な角度から工作機器を3Dで見ることができるので、異常があるセンサーの位置を特定し、アラートを表示することが可能です。
全国の工場内設備をカメラでモニタリング
各工場の機器や生産ラインにカメラを設置することで、全国の工場内設備をモニタリングできます。モニタリングできることで、工場内の状況把握を瞬時に行えます。
Webブラウザからの設備の制御が可能
異常などが発生した場合、webブラウザから設備の制御が可能です。稼働中設備の停止・再稼働などの制御からNCプログラムの送信が可能となります。

IoTソリューション紹介動画

IoTのお悩み解決

 お客様からIoTに関する様々なお悩みをご相談いただいております。IoTの導入に関することやデータの取得方法、取得したデータの活用方法や見える化など多岐にわたります。このようなお悩みごとに対して弊社としてもなんとか解決したく、日々ご提案をしています。こちらでは、その内容の一部をご紹介します。

パートナー

三菱電機のe-F@ctoryパートナー

e-F@ctory Allianceとは、弊社FA機器との接続親和性の良いソフトウェア・機器を提供するパートナーとそれらを活用しシステムを構築するシステムインテグレーションパートナーとの強力な連携により、お客様に最適なソリューションを提供するためのFAパートナープログラムです。

  • e-F@ctory Allianceの詳細は、こちら をご覧ください。

e-F@ctory Alliance

Aras社の公認パートナー

Aras Innovator®は米国Aras社が開発・提供している、ライセンスフリーのエンタープライズPLM(Production Lifecycle Management)ソリューションです。製品の企画・設計から生産・保守までの製品ライフサイクル全体の管理が行えます。

  • Aras Innovatorの詳細は、Aras PLMソフトウェア をご覧ください。
  • Aras®およびAras Innovator®は、Aras Corporationの登録商標または商標です。

Aras AUTHORIZED Partner 2017

BECKHOFF社の開発パートナー

BECKHOFF社 の開発パートナーとして、弊社はソフトウエアの開発をサポートさせていただいております。

BECKHOFF

Variational Auto Encoder 〜外れ値検知への応用〜

はじめに

 今回は、Variational Auto Encoder(VAE)を外れ値検知に応用した例を示し、その可能性について議論したい。

Variational Auto Encoderとは

 詳細な理論はここここで述べたので、今回は概略だけを示す。
 観測値X=\{\vec{x}_1,\cdots,\vec{x}_N\}が与えられとき、未観測の値\vec{x}_*を生成する確率分布p(\vec{x}_*|X)を求めたい。これを求めるためBayes推論で使われる変分推論(Variational Inference)を用いると、以下のような処理の流れを得る。

図の「NN」はニューラルネットワークを表す。また、標準正規分布からサンプリングしている部分を赤で示した。入力Xを隠れ変数\vec{z}に射影し(Encoder)、\vec{z}からXを復号する(Decoder)構造を持つ。復号されたX\tilde{X}と記した。この処理の流れをVariational Auto Encoder(VAE)と呼ぶ。「Variational」は変分推論の「変分」から来た言葉である。
 Encoder側の2つのNNでパラメータ\vec{\mu}_\phi(X)\Sigma_\phi(X)を計算する。後者は行列である。これらは正規分布のパラメータである。一方、Decoder側のNNではパラメータ\vec{\eta}_\theta(\vec{z})を算出する。これはモデル尤度(確率分布)のパラメータに相当する。EncoderとDecoderの2つを含む全手順を最適化する損失関数には、\vec{\mu}_\phi(X)を0に、\Sigma^{1/2}_\phi(X)を単位行列に近づけるような正則化項が含まれるので、\vec{z}の分布は標準正規分布に近い形状となる。すなわち、任意の変数Xがほぼ標準正規分布に従う確率変数\vec{z}に射影されることになる。これとよく似た手法としてAuto Encoderがあるが、収斂進化のようなものであり、理論的背景は別物である。

外れ値検知の問題設定

 今回取り上げるデータセットは、MNISTである。MNISTは下図に示すような手書き数字の画像を集めたものである(下図はhttp://ainow.ai/2017/03/29/110012/から引用した)。

これらの数字の内、「0」を正常データ、「6」を外れ値データとみなす。正常データだけでVAEを訓練し、この訓練済みモデルで外れ値を検出できるか否かを検証する。

ソースコード

 今回のコードはここにある。

訓練

 6万枚の全画像の中に「0」画像は6903枚ある。この内、5923枚を訓練データ、残りをテストデータとした。mnistの画像はグレイ画像である。今回のVAEの実装では、Decoderの部分に、2値画像を想定したBernoulli分布を用いている。従って、あらかじめ、全画像を2値に変換する処理を行った(make_binarized_mnist.py)。そのあと、train_vae_with_specified_label.pyで訓練を行った。また、ネットワーク構造はnet_2.pyに記載されている。\vec{z}の次元数をD\vec{\mu}_\phi(X)=(\mu_{\phi,1},\cdots,\mu_{\phi,D})\Sigma^{1/2}_\phi(X)=\mathrm{diag}(\sigma_{\phi,1},\cdots,\sigma_{\phi,D})とした。D=100、エポック数を100として訓練を行ったときの損失関数の学習曲線を以下に示す。描画時に使用したファイルは、draw_results_with_specified_label.ipynbである。

 訓練後の\vec{\mu}_\phi(X)\Sigma^{1/2}_\phi(X)のそれぞれの全要素の平均値は以下のようになる。

先に説明したように、\mu_\phiは0に近い値に、\sigma_\phiは1に近い値となっていることが分かる。すなわち、近似的に標準正規分布に従う隠れ変数\vec{z}が得られたことになる。

データの分布

 訓練済みモデルのEncoder部分を用いて、正常画像(0画像)と外れ値画像(6画像)を隠れ変数に変換した結果が下図である。ただし、t-SNEを用いて100次元を2次元に削減した。正常画像は1000枚、外れ値画像は100枚である。

図の楕円は、Mahalanobis距離の等高線である。内側から1,2,3,4の値を持つ。

しきい値の決定

 \vec{z}はほぼ正規分布に従う変数であるから、Mahalanobis距離を用いてしきい値を決定すれば良い。しきい値と各種指標の関係を以下に示す(detect_anomaly.py)。

F値はthresholdが2.7のとき最大値0.97となる。このときのPrecisionとRecallの値はそれぞれ0.95と0.99である。

まとめ

 今回は、VAEによる外れ値検知の可能性を探った。正常データで訓練されたVAEのEncoderは正常データを標準正規分布に従う変数に変換する。一方、訓練時に使用しなかった異常データはこの分布から外れた場所に射影されると期待される。この識別はMahalanobis距離を用いれば容易に実現できることを示した。
 隠れ変数の次元Dを今回は100とした。最適な次元数については時間をかけてもう少し検討した方が良い。これは今後の課題である。また、しきい値を決定する際に2次元に次元を圧縮したが、これについてもまだ検討の余地はある。

ロボットアームさん参画!センシングチーム発足!

センシングサイエンティストのもってぃです。
先月は3回秋葉原に行ってました。
回路基板、もっとたくさんAmazon Prime Nowで取り扱ってほしいです。

センシングチーム発足

最近もってぃと一緒に働いて頂ける仲間が1台が増えました。
他に既にセンサ3個もありますので、そろそろチーム化しようと思います。
チーム名候補は
・センシングチーム
・チーム・センシング
・チーム・もってぃ
とりあえず、わかりやすく
「センシングチーム」
と名乗ってみます。

ちなみに現在の参画メンバーは
・もってぃ
・温度センサ
・加速度センサ
・一眼レフカメラ
・ロボットアーム

えっ?
人間は一人しかいないだろですって?

フフフフ。

そういう時代に入ってきたんですよー。

6月より参画!ロボットアームさん

今回は、6月に参画したメンバーを紹介します。

ロボットアームさん

かっこいいでしょ?

ロボットアームさんの初仕事は
「第29回 設計・製造ソリューション展(DMS)」で3日連続休みなく動き続けること。
MONOistさんの記事では、なんと写真の中心に写っており、
頑張って動いている様子がみてとれます。

ワォ♪

ついにロボットアームと人間が一緒に働く時代になったのです。
特に、センシングにはロボットさんの存在がかかせません。

おどろき~♪

ちなみに今日の業務の一コマ。

ロボットアームの基本はモータを駆動させること!

このロボットアームには6個のモータがついており、
このモータをくるくる回転させることにより関節が動き、
いろいろな運動を表現できます。

青色矢印、青丸はモータ位置。

モータってどうやって回転するのでしょうか?
ここでは、
「ブラシ付DCモータ」と呼ばれる種類のモータを
例にとって説明します。

その前に、
もっていの左手を使って、
みんな大好き「フレミングの左手の法則」
を復習しましょう。

フレミングの左手の法則とは、
電流、磁場(磁界)、力のそれぞれの方向の関係を現わす法則です。

中指:電流の方向
人差し指:磁場(磁界)の方向
親指:力の方向

モータの構造は超簡単にすると、こんな感じ。

ブラシ、永久磁石、整流子、コイル
で構成されています。

整流子とブラシが接触していますので、
コイルに電流が流れます。
また、磁場(磁界)の向きはN→Sとなります。
このとき、
左半分のコイルにフレミングの法則を適用すると、力は上方向に、
右半分のコイルに適用すると、力は下方向に働くことがわかります。
つまり、コイルは時計回りに回転し始めます。

回転し始めると、整流子とブラシが接触しなくなりますが、
コイルはそのままのいきおいで回転します。

そのうち、整流子とブラシが接触し、コイルに電流が流れ、
先ほどと同じ仕組みで力が働き、
時計回りに回転するのです。

こんな感じでコイルが回転することによりモータは回転します。

モータのしくみがわかったところで、
次回はモータを駆動し、ロボットアームさんを動かす方法を紹介します。

では。

TOEICの呪縛

TOEICの呪縛

こんにちは!
採用担当の池田です。

7月に入り、弊社でも新卒採用が徐々に落ち着いてきまして、非常に優秀な方々に入社承諾を頂いています。

新卒の採用に従事する中で、考えがしっかりしているなーと思わされるのは、大手志向の方が意外に少ないということ。もちろん弊社の説明会に来る時点で元々大手志向ではないので一概には言えないかもしれませんが、

  • 確かなスキルを身に付けたい
  • 会社に依存しないキャリアを築きたい

と本気で考えて就活している方が多いことに驚かされます。

今私が大学生に戻っても、同じ考えを持てるかどうかは大いに疑問なので、恥ずかしい限りです。

弊社を選んで頂いた方には、決して損をさせない魅力的な会社であり続けたいと思いますが、知名度だけで集客できていた企業は、真剣に採用を考えないと優秀層が徐々に来なくなる時代も近い将来あり得るので、「人」に対しては真剣に向き合いたいなと思う今日この頃です。

さて、今回は就活になるとなぜか話題になる、TOEICについて述べたいと思います。

「就活=TOEIC」という概念

私の就活時代にもあったのですが、
大学3年生になってそろそろ就活だ。まずはTOEICの点数を取ろう
という良く分からない風潮、皆さんは感じたことありますか?

企業のエントリーシートにもTOEICの点数を記入する欄が設けられているので、就活生からすると必須に思えても仕方ないですよね。

いつの時代も、「今後はグローバル」と言われ続けているので、英語力が求められるのは分かります。ただ、就活になると一斉にTOEICの教材が売れ出す今の状況に違和感を覚えるのは私だけでしょうか?

なぜこのような状況になったのか。それを紐解くカギとして、就職氷河期が関係していると私は考えています。

企業が大幅に採用を控えた時代

「就職氷河期」という言葉は、もしかすると今の学生は知らないかもしれませんね。今は「超売り手市場」と言われているように、求職者(新卒であれば学生)側にとって非常に有利な採用市場となっています。
ただ、一昔前にはそれとは大きく異なる市況だったことがあり、企業側が採用を大きく控えたことから、中々内定がもらえない状況が社会問題化しました。

就職氷河期のきっかけはもちろん、景気の低迷。

バブル崩壊の1991年から経済が停滞していた2000年前半までの約10年
リーマンショックが起きた2009年から2013年

この時期は高学歴と言われている方でも内定を中々獲得できなかったと言われ、その結果多くの非正規雇用を生んだとされています。

そのような採用を控えた状況の中で、企業側の採用基準が上がるのは当然のことでしょう。

そして採用基準を上げる中で、当時の人事部が注目したポイントが「英語力」だと私は考えています。

採用基準を上げると言っても様々なポイントがあると思いますが、皆さんは何を想像されますか?

  • サークルやアルバイトでリーダー経験のある方?
  • 部活に入っている方?
  • 学歴?
  • 美男美女(笑)?

上記はもちろん重要な要素だと思いますが、当時の大手企業は上記をしっかり満たした人の中からさらに半数以下にしなければいけない状況だったので、非常に苦しいですよね。

そうなると、当時から言われているグローバル化に照準を合わし、英語力にフォーカスするのは当然のことだと思っています。

とは言え、上記は私の勝手な予想でしかないですが、私の高校受験時の英語の先生(上智出身)で、今ではテレビに出演しているほど有名な方ですが、その先生がご自身の就活について下記のように伝えていました。

俺の時代は就活氷河期だったからかなり“周り”は大変だったんだよねー。俺はめちゃくちゃ余裕でさ。
なんでかっていうと、英検1級、国連英検特A級、TOEIC900点持ってるやつなんて当時いなかったから、どこの企業もめちゃくちゃ優秀そうな目で見てくるのよ。
ちなみに英検は当時から有名だったけど、TOEICについてはまだ認知されていなかったんだよね。だから普通にTOEICの説明すると、とりあえず何だか凄そうな試験だと思ってくれたらしくてさ。
良く分からないけど、とんでもなく英語ができるやつだと。
就活っぽいことなんて全くしなくても、超がつくほど有名企業3社から早々に内定もらったよ。でも俺は英語が好きだったから、結局英語の先生になる道を選んだんだけどね。

上記から分かるように、現代以上に英語ができる人が少なかった時代ですし、当時グローバル展開を掲げていた大企業は、
英語ができる人材=優秀な人材
と一括りに判断していたことでしょう。

結局TOEICって必要なの?

必要なくはない
という答えが圧倒的に多いのではないでしょうか。おそらく就活を終えた先輩や人事担当者に聞いても上記の答えが最も多いと思います。

私自身もそれには賛同していまして、内定が100点満点だとすると、せいぜい5点ぐらい加算される感じでしょうか。

特に今の時代の就活はTOEICがあまりに広まり過ぎて、900点以上がゴロゴロいるので希少価値はなくなっていると思います。

月並みなアドバイスですが、英語勉強の結果の1つとしてTOEICがあるのは良いですが、それ目的では全く意味を成しません。

それでもTOEICにこだわりたい方は、最低でも800点は目指しましょう。
私の就活時代は最低でも600点、出来れば700点あると良いと言われていましたが、上述したように基準が大幅に上がっている背景があるので、600点レベルだと「あなた英語できないね」と思われるかもしれません(笑)

900点と895点に大きな差はない

ちなみに、、、私もTOEICを勉強していた時代があったのですが、当時から今でも言われていることとして、「900点の壁」があります。
区切りの良い数字として、なぜか900点が基準となっていますよね。

ただ、正直そこの差って英語力に大きな違いは一切ないと思っています。というのも、800点以上の戦いって、細かいミスをいかにしないか、引っかけに惑わされないかの勝負になってくるためです。

私自身も800点後半で停滞した時期もありましたが、そこを踏ん張って900点の大台に乗せることに本質的価値があったと言えばNOで、120%自己満足でした(笑)

就活のために資格勉強は必要ない

就活に有利になる資格を挙げるとすれば、弁護士や公認会計士と言ったものぐらいでしょうか。
資格シリーズでいえば、簿記やFP、秘書検定も就活時代に流行りますが、打算で勉強するぐらいなら今すぐに止めることをお勧めします。

TOEICもそうですが、資格勉強は仕事の能力に関係なく、単純に「時間とちょっとしたテクニック」があれば一定数以上の方は取得できるものだと思っています。

そんなくだらないことに費やしてしまう人ほど、就活は失敗します。
資格ハンターほど、人事から見ていて残念な人はいません。

今すぐに止めて、自分が心から熱中できるものに取り組みましょう。その方があなたの人生には必ずプラスに生きてくるはずですので、貴重な学生生活を有効に活用して下さいね。

線形回帰をPythonで数式から逃げずに実装してみた

こんにちは、エンジニアのBBです。

皆さんは線形回帰と聞いてどのようなものか明確に説明できるでしょうか。
なんとなくのイメージは出来るけど……と、明後日のほうを見ながら言う方を対象にちょっと前までそんな感じだった僕が説明していきます。

線形回帰とはなにか

まずはこの図を見てください。

あなたは左下から右上にかけてまっすぐに線を引きたくなったのではないでしょうか。こんな具合に。

このいい感じに線を引く操作を一定のルールに従って行うことを線形回帰といいます。いい感じに引かれた線は、未知の値(横軸)に対しておおよその答え(縦軸)がどのあたりに位置するかを予想してくれたり、変な値を見つけることに役立ちます。今回は線形回帰について数式を解きつつ、pythonのオープンソース機械学習ライブラリscikit-learn(通称:sklearn)に入っている線形回帰用のツール、LinearRegressionの偉大さを感じていきたいと思います。

機械学習はこの手順が基本!

さて、いきなり話がそれますが機械学習における基本的な手順を説明させてください。手順を把握しておくことで、テクニカルワードや数式の位置づけを体系的に理解する道しるべになると思います。機械学習の手順は大雑把に分けて3つです。

  1. データを用意する
  2. モデルを訓練する
  3. モデルを評価する

この3つを繰り返してモデルの精度を改善していきます。上記手順のそれぞれにそれっぽい名前の手法や言い回しがあり、慣れないうちはすぐ迷子になるので意識的に自分がどの位置にいるのかを確認しておくといいと思います。

1.データを用意する

機械学習にはもちろん解析対象になるデータが必要になります。冒頭の図に使ったx, yのデータもそうですし、画像や文章も解析対象データとなります。解析対象のデータは必ず数値や数値の並び(行列やベクトルなど)に落とし込む必要があります。現実世界の現象をいかに数値に落とし込むかが機械学習の成功のカギとなり、データ活用の全行程の約8割をつぎ込む重要手順となっています。

2.モデルを訓練する

機械学習の名前の通り「機械」に手順1で用意したデータを「学習させる(訓練する)」工程です。モデルと一口に言っても様々あり、解析対象によっては自作する必要があるかもしれません。今回のテーマである線形回帰もこのモデルの一つとなります。

3.モデルを評価する

モデルで計算した結果(これもモデルによって形式はイロイロ)を評価する工程です。評価が悪かった場合は、手順1に戻ってデータを加工したり、手順2でモデルのチューニングやモデル自体を変更したりと頑張ります。

線形回帰でボストンの住宅価格データをみてみよう

ここからは数式の説明を交えつつ、線形回帰をpythonを使って実装していきます。また、線形回帰用ツール、LinearRegressionとの計算結果と比較して「やっぱ出来合いのツールスゲーわ」という感じで締めくくります。先述に合わせ、手順3つでこれからすることをざっくり説明します。

1.データを用意する
sklearnが用意してくれているサンプルデータ、ボストンの住宅価格データを使います。
データは、住宅価格とその他その住宅に関するステータス13項目がひとまとめになっており、それが約500軒分あります。イメージとしては横軸にステータス13項目(一気に図示できませんが。。)、縦軸に住宅価格をとって線形回帰をする感じです。住宅のステータス13項目を使って住宅価格を求めるとすると、ステータス13項目を説明変数、住宅価格を目的変数といいます。

2.モデルを訓練する
モデルは宣言した通り、線形回帰を実装します。比較対象のツールはsklearnのLinearRegressionを使います。

3.モデルを評価する
結果の評価についてはRMSEをいう指標を使いますが、細かいことは後で記載します。

1.データを用意する

今回は出来合いのデータを用いるのでこのステップは飛ばしてステップ2から始めましょう。

2.モデルを訓練する

ここでは主に式を交えつつの説明をしていきますが、ここでの最終目標をまず見ておきましょう。

(1)   \begin{eqnarray*} \vec{\hat{y}}= X\vec{w} \end{eqnarray*}

これです。このパラメータ\vec{w}を求めることがゴールです。Xは物件のステータス、\vec{\hat{y}}は予想された物件価格を表し、「ステータスから物件価格を予想する」式となります。このような関係を\vec{\hat{y}}はパラメータ\vec{w}に対して線形であるといいます。式(1)は行列、ベクトルが使われているので正直、慣れていないと何を言っているのかわからないと思いますので次の3ステップで考えていきましょう。

  1. ステータス1項目、1軒分のデータを使う
  2. ステータス1項目、全軒分のデータを使う
  3. ステータス13項目、全軒分のデータを使う


徐々に、データ構造を複雑にしていっているのがわかると思います。

1.ステータス1項目、1軒分のデータを使う

ステップ1では式(1)はこんな感じになります。

(2)   \begin{eqnarray*} \hat{y}= w_{0} + w_{1}x \end{eqnarray*}

式(2)が意味するところは\hat{y}(予想の住宅価格)はx(ステータス1)にw_{1}を掛けたものと定数w_{0}を足したものということです。これを図に起こすとこうなります。

そもそも点が1つしかなくこの点さえ通っていればなんでもよいので、いい感じの線は決められそうにありません。なので式(2)の出番はなさそうです。

2.ステータス1項目、全軒分のデータを使う

ステップ2では式(1)はこんな感じになります。

(3)   \begin{eqnarray*} \vec{\hat{y}}=w_{0} + w_{1}\vec{x} \end{eqnarray*}

式に使われている文字の頭に矢印がっくついてがなにやら不穏な感じになっていますがこれはベクトルといいます。身構える必要はなく、単純に全軒分のデータに対してステップ1の式を書くのが面倒なのでこのように表記した単なる省略記法とかそんな感じにとらえてもらえるとわかりやすいと思います。実際はこんな感じの式が隠れているのです。

    \begin{eqnarray*} \begin{bmatrix} \hat{y}_{1} \\ \vdots \\ \hat{y}_{n}\end{bmatrix} =  \begin{bmatrix}w_{0} + w_{1}x_{1} \\  \vdots  \\w_{0} + w_{1}x_{n} \end{bmatrix}\nonumber \end{eqnarray}

文字をベクトルとして表記するとこんな感じになります。

    \begin{eqnarray*} \vec{x} = \begin{bmatrix} x_{1} \\  \vdots  \\  x_{506} \end{bmatrix}\nonumber , \vec{y} = \begin{bmatrix} y_{1} \\  \vdots  \\  y_{506} \end{bmatrix}\nonumber \end{eqnarray}

今回使うデータは506軒分ありますのでn = 506となります。506個のxに対して、予想住宅価格\hat{y}も506個ありますのでベクトルとなります。ここまで省略すると欲が出てきます。式(3)にはw_{0}w_{1}という似たような表記が出てきています。まあ、こちらのさじ加減なのですが、この2つも下のようなベクトルを使って省略することができます。

    \begin{eqnarray*} \vec{w}=\binom{w_{0}}{w_{1}} \nonumber\end{eqnarray}

省略するためにここで\vec{x}にちょっと下に示すような細工をしておきます。

    \begin{eqnarray*} X = \begin{bmatrix} 1 & x_{1}\\  \vdots  & \vdots \\  1 & x_{506} \end{bmatrix} \nonumber\end{eqnarray}

このようなベクトルのレベルアップ版を行列といいます。読んで字の通り行と列を持っています。このX\vec{w}を使って式を変形するのですが、行列とベクトルの掛け算はちょっと複雑です。こちらの図がわかりやすかったので拝借します。


引用:Math03 行列と座標変換

この図にあるような順で掛け算が行われるため、追加した1を並べた列がw_{0}を作ってくれます。
式(3)はこんな感じに変形されます。

(4)   \begin{eqnarray*} \begin{split} \vec{\hat{y}}&=\begin{bmatrix} w_{0}+w_{1}x_{1} \\  \vdots  \\  w_{0}+w_{1}x_{506} \end{bmatrix}\\ &=\begin{bmatrix} 1 & x_{1}\\  \vdots & \vdots\\  1 & x_{506} \end{bmatrix} \begin{bmatrix} w_{0} \\  w_{1} \end{bmatrix}\\ &= X\vec{w} \end{split} \end{eqnarray*}

式の変形が完了しましたので今度は\vec{w}を求める作業に入っていきましょう。\vec{w}を決定するには式(4)で引かれる線が最も「いい感じの線」になることが条件ですが、「いい感じの線」とはそもそも何でしょうか。「いい感じ」を考えるにあたり最小二乗法という手法を引っ張ってきます。最小二乗法を今回に当てはめると、\vec{w}をいろいろ変えて全ての「計測された住宅価格y」と「予測された住宅価格\hat{y}」の差を2乗した値の和が最も小さくなった時に「最もいい感じの線」が決まります。上記を式にするとこうなります。

(5)   \begin{eqnarray*} \begin{split} E&=\frac{1}{2n}\sum_{i=1}^{n}(y_{i}-\hat{y}_{i})^{2}\\ &=\frac{1}{2n}\sum_{i=1}^{n}(y_{i}-\vec{w}^{T}\vec{x}_{i})^{2} \end{split} \end{eqnarray*}

式(5)に出てきたnは先述と同じくデータの数を示しています。506軒分のデータがありますので今回はn=506となります。\sum_{i=1}^{n}は右にくっついてる式をi=1~nまで足し続けなさいという意味です。シグマと読みます。式の右側はある数値の2乗なので常に正の値になります。ある数値は実数値の前提です。ちなみに機械学習の教科書等ではある数値aが実数であることを示すときa\in \mathbb{R}のように表記されることがあります。不意をついて現れるため慣れない人にとっては恐怖の対象だったかもしれませんが、こういった意味で使われているだけなのでもう怖がる必要はありません。

ここで興味があるのは式(5)ではなく、式(5)の左側が最も小さくなる\vec{w}のみです。そんなもんわかるかいと思われるかもしれませんが、右側は\vec{w}の2次関数になっているので求めることができます。2次関数はある\vec{w}で最小値となるのですが、2次関数の形がわからない方はこちらのサイトが役に立ちます。このサイトの式の入力欄に「x^2」と入力するとよいでしょう。もし式(5)を分解して\vec{w}の2乗項と\vec{w}の項が混在しているのが不安で本当に最小値をとる\vec{w}は一つに求まるのか僕のように確信が持てない方は上記サイトに「x^2+x」と入力し、xの係数を気が済むまで変更してみるとよいと思います。

\vec{w}に関しての関数である式(5)が最小値をとることはわかりましたが、ではどのように求めるのかというと皆さん大好きな微分を敢行します。微分はある\vec{w}でのグラフの傾きに相当しますので、最小値をとる\vec{w}での微分は0になるわけです。式(5)の微分は以下の通りです。

(6)   \begin{eqnarray*} \begin{split} \frac{dE}{d\vec{w}}&=\frac{1}{d\vec{w}}\left[\frac{1}{2n}\left \{ \left ( y_{1}-\vec{w}^{T}\vec{x}_{1} \right )^{2}+\dots + \left ( y_{n}-\vec{w}^{T}\vec{x}_{n} \right )^{2}\right \}\right]\\ &=\frac{1}{2n}\left \{ 2\left ( y_{1}-\vec{w}^{T}\vec{x}_{1} \right )\left(- \vec{x}_{1}\right )+\dots + 2\left ( y_{n}-\vec{w}^{T}\vec{x}_{n} \right )\left(- \vec{x}_{i}\right )\right \}\\ &=-\frac{1}{n}\sum_{i=1}^{n}\left \{ \left( y_{i}-\vec{w}^{T}\vec{x}_{i}\right ) \vec{x}_{i} \right \} \\ &=-\frac{1}{n}X^{T}\left(\vec{y}-\vec{\hat{y}} \right ) \end{split} \end{eqnarray*}

式(6)は\vec{w}をちょっと動かしたときの変化量でもあり、グラフの傾きです。最小値をとる\vec{w}の左では微分はマイナスになり、右側では微分はプラスになります。

なので適当に決めた\vec{w}に対して式(6)を何度も何度も引き算していくと最小値をとる\vec{w}に収束していく訳ですね。ちょうどボールの中にパチンコ玉を入れたかのように自分で移動していくイメージです。このとき使う式が式(7)です。

(7)   \begin{eqnarray*} \begin{split} \vec{w}&\leftarrow \vec{w}-\alpha \frac{dE}{d\vec{w}}\\ &=\vec{w}+\frac{\alpha}{n}X^{T}\left(\vec{y}-\vec{\hat{y}} \right ) \end{split} \end{eqnarray*}

ここで突然現れた\alphaですが、\vec{w}をいかにちょっとずつ進めるかの度合いになります。\alphaを大きくすれば少ない計算量で\vec{w}を収束できますが、答えの精度が落ちることが感覚的にわかりますね。長くなりましたがようやく\vec{w}を求めるための式がわかりました。
あとはプログラムに落として計算させてみましょう。

↓実行結果

ちょっと動かす回数を変化させて図にしてみましたが、いかがでしょうか。
回数が多くなるにつれ少しずつ「いい感じの線」になってきていることが感覚的にもわかると思います。
最終的に100000回実行した結果はsklearnのツールを使った線と重なっていますので、よい結果が出ているのだと思います。

3.ステータス13項目、全軒分のデータを使う

いよいよステップ3です。
ここまでお付き合いいただいた方はうんざりしているころだと思いますが、安心してください!
ここで使う式(1)は式(4)として既にステップ2で出てきてしまっています!もう式を追わなくてもよいのですよかった!
さて、使う式が同じだというのならステップ2とステップ3はどう違うのでしょうか。
答えは\vec{w}Xの中身になります。といってもxの量に応じて\vec{w}も増えるだけですが。

    \begin{eqnarray*} X=\begin{bmatrix} 1 &x_{11}&\dots &x_{1p} \\  \vdots &\vdots &\ddots &\vdots \\  1 &x_{n1}&\dots &x_{np}  \end{bmatrix}, \vec{w}=\begin{bmatrix} w_{0} \\  \vdots \\  w_{p} \end{bmatrix}\nonumber \nonumber\end{eqnarray}

ここで新たな添え字pが登場しますがこれはxに含まれるステータスの数になります。要するにこの場合は13です。
ステップ3をプログラムに起こすとほぼステップ2と同じですがXに値を格納する箇所が異なっていますのでコードを載せておきます。また、使用するステータスが増えましたので「いい感じの線」を作図によって目視することができませんので作図の箇所も不要です。

さて、残念なこと全項目を読み込んでプログラムを実行するとエラーが続発してしまい、うまく計算できなかったのではないでしょうか。
どうやら使用しているステータスのスケールががまちまちだった為、\vec{w}がうまく収束してくれなかった項目があったことが原因のようです。ここでいうスケールというのはあるステータスAは0~1に分布しているのに、ステータスBは100~200に分布していたりすることを指します。個別に回帰するのであれば\alphaやループ回数を調整してやればよさそうですが、全部の項目に対応できる値となると見当もつきません。。

3.モデルを評価する

前章の最後の最後で手詰まりが起きてしまい、解析がうまくいきませんでしたね!この章では計算結果を評価するはずでしたが……細かいことは気にせずどうにか計算できるようにしてから結果を解析していきましょう。
ステップ3では項目間のスケールの違いがエラーの原因となっていましたのでどうにかしたいものです。こんな時に役に立つのが正規化です。
ここでの正規化というのはデータの平均値からのばらつき(偏差)を、ばらつきの平均値(標準偏差)で割ってやることで、項目間のスケールが違っても平等に評価できるようにする処理を指します。標準化とも呼ばれ、式でいうと以下のようになります。

(8)   \begin{eqnarray*} {x}'=\frac{x-\bar{x}}{\sigma } \end{eqnarray*}

ここで\bar{x}xの平均値、\sigmaを標準偏差といいます。この処理を全項目について適応するには以下のコードを追加します。

これで何とか無事、\vec{w}を求めることができましたので、さっそく結果の評価をしていきましょう。今回はRMSE(Root Mean Square Error):平均二乗誤差を使って結果を評価していきます。比較対象はライブラリsklearnのツールを使って計算した結果のRMSEです。RMSEは以下の式で計算できます。

(9)   \begin{eqnarray*} RMSE=\sqrt{\frac{1}{n}\sum_{i=1}^{n}\left(\hat{y}_{i}-y_{i} \right )^{2}} \end{eqnarray*}

RMSEは予想した住宅価格と本来の住宅価格の差に関連する値のようですね。予測と実際の値に差異が少なければ0に近づき、差異が大きいほど0から離れていきます。そのためRMSEが小さいほど「いい感じの線」であるといえます。では早速プログラムを使って計算してみましょう!

ループ回数が多ければ多いほど徐々に値が小さくなっていき、10000回を超えたあたりからほぼ値が変わらなくなっています。\vec{w}が収束していっていることが実感できますね。さらに100000回の結果はsklearnで計算した結果とぴたりと同じになっています!
本来はこの結果をもとに良い悪いの評価を行い、データの変更や、モデルの調整を行います。ちょうどこの章の冒頭で行った正規化がデータの変更に対応しています。

まとめ

今回は線形回帰についてまとめてきました。個人的には計算を繰り返すことで\vec{w}が収束していく様子が実感できたのが非常に面白かったです。この\vec{w}が収束する過程が機械学習の学習の部分です。sklearnに代表されるツールは便利ですが、実際に数式をコードに落とし込む工程は勉強になることが多く苦労する価値はあると感じています。
軽い気持ちで書いてきた今回の記事ですが、長文になってしまいました。ここまでお付き合いいただいた方はありがとうございます。線形回帰で躓いている方の助けになれば幸いです!

【Vue.jsでSPAへの移行】Vue.jsに触れてみよう

こんにちは、新入社員のNakataです。入社するまでは生物系の研究をしていましたが、この度Orizuru開発に携わることになりました。そんな私の初めての実務として、既存のアプリケーションをシングルページアプリケーション(SPA)に移行する作業を行いました。実装には、SPAを効率的に開発するためのフレームワークVue.jsを使いました(Vue.js公式サイト)。
今回はそもそもSPAとは、Vue.jsとはどんなものなのかを、私自身の理解のため、これからSPA開発や Vue.jsを学ぶ人たち向けに、簡単にまとめました。また、SPA移行で役に立った機能(vue-router)の紹介もしたいと思います。

SPAとは

SPA(Single Page Application)とは、名前の通り単一のページで構成されるアプリケーションになります。SPAではない webアプリケーションでは、ページ遷移を行う度サーバーからHTMLを取得し、それを表示することで画面を書き換えていました。SPAでは、サーバーからHTMLを受け取るのは最初だけで、それ以降はAjaxでデータをやり取りし、JavaScriptでDOM(HTML文書やXML文書を書き換える機能を使用するための仕組み)を操作することで画面を書き換えます。初期ページのローディングには時間がかかりますが、それ以降はAjax通信のみで画面の書き換えを行うため、ページ遷移が早くなりサーバーへの負荷も減ります。

なぜVue.js?

Vue.jsには、コンポーネント指向や双方向データバインディングのように、SPAの開発を進めやすい特徴があります。また、公式のAPIリファレンスや使用例が充実しているため、開発に必要なものを効率よく学習できます。そこで今回はVue.jsを使用しました。

Vue.jsの特徴

コンポーネント指向

コンポーネント指向
必要なUIをコンポーネント化し、それを組み合わせることでアプリケーションを作成できるというのが、Vue.jsの特徴の一つです。一度コンポーネントを作成すると、そのUIが必要になる場面で再利用することができます。Vue.jsには、コンポーネントを作成するための様々な機能が備わっています。
双方向データバインディング

双方向データバインディング
双方向データバインディングとは、データの変更があればリアルタイムでUIを更新し、UIの変更があればデータの更新を自動的に行う機能です。双方向データバインディングは他のフレームワークにも備わってる機能ですが、Vue.jsでは、その双方向データバインディングを簡潔に実装することが可能です。

画像引用元:Vue.jsの作者Evan氏によるスライド資料

実際に触ってみる

環境設定

今回はVue.jsを使ってみるため、プロジェクトのテンプレートを自動で作成してくれる、vue-cliを使用します。
vue-cliを使用するためにはNode.jsが必要です。Node.jsをインストールしておいてください。準備ができたら以下のコマンドでvue-cliをインストールします。

様々なテンプレートが用意されていますが、今回はwebpack(複数のファイルを1つにまとめて出力するツールの一種)でプロジェクトを作成します。途中、設定を確認されますがEnterで進めます。

これで設定完了です。実際にサーバを動かしてみましょう。

データバインディングを使ってみる

Vue.jsでは、v-modelディレクティブを用いることで、input要素に対して、双方向データバインディングが可能となります。ディレクティブとは、 DOM要素に対して何かを実行するコマンドの役割をもつトークンで、HTMLのタグ内に記述します。
実際に使ってみるため、今回作成したプロジェクト内に作成された、srcディレクトリ内のファイルを見ていきましょう。
まずは、src/components/HelloWorld.vueのtemplateタグ内を、以下のサンプルコードに置き換えてみてください。

サンプルコード

src/components/HelloWorld.vue内のscriptタグ内は以下のようになっています。
Vueコンポーネント内のdataはオブジェクトではなく、オブジェクトを返す関数として定義します。

コードの置き換えと確認が終わったら保存を行い、実際にフォームから値を入力してみましょう。

vue画面1
vue画面2

data.msgとinputの要素が、v-modelディレクティブで紐付けされていることで、動的にUIが更新されることが確認できたでしょうか。このようにVue.jsでは、双方向データバインディングを簡潔に実装することが可能です。

vue-routerを使ってみる

Vue.jsでは画面描画のために、URLを変える必要はありません。しかし、URLの変化と画面の書き換えを対応させておくことで以下のようなメリットもあります。

  • 対応するURLをブックマークとして保存可能
  • SPAでないアプリケーションをSPAへ移行する際、元々のURLごとに画面を対応させることが可能
  • URLごとにコンポーネント単位で開発を進めることが可能

vue-routerを使用することで、ページ間の遷移および、それに対応するURLの変更が可能となります。では、vue-router使ってURLを変化させ画面の書き換えを行ってみましょう。src/router/index.jsを、以下のサンプルコードに書き換えてみてください。

サンプルコード

importでコンポーネントの読み込み、pathでコンポーネントごとにルートを設定しています。pathで設定したURLにアクセスすることで、そのコンポーネントの画面が表示されるようになります。propsについては後ほど説明します。
次にvueファイルを作成します。src/components以下にHelloWorld.vueをコピーして、PageA.vue、PageB.vueを作成し、templateとscriptタグ内を以下のサンプルコードに置き換えてみてください。HelloWorld.vueについても同様に置き換えてください。

サンプルコード

PageA.vue

PageB.vue

HelloWorld.vue

コードの置き換えと確認が終わったら保存を行い、リンク部分をクリックして画面とURLが変化しているか確認してみましょう。

Props
PageB

router-linkタグでリンクの設定をすることが可能です。toでrouter/index.jsのpathで設定したリンク先を指定します。aタグのような感覚で使えますが、サーバーからのHTMLの取得は行われません。
次にpropsについてですが、propsとは子コンポーネントで親のデータを参照したい時に、データを子コンポーネントに渡すためのオプションです。router-linkタグ内のtoの前に:を付けバインディングされたデータの値を渡すことができます。router/index.jsのpathで’/PageB/:msg’と定義していますが、/PageB/以下の値をPageBコンポーネントでmsgの値として受け取るという設定です。PageB.vueのscriptタグ内でprops: [ ‘msg’ ]を定義することでPageBコンポーネント内で受け取ったmsgの値が利用できます。
router-link props
このようにvue-routerを利用することでURLごとに画面を書き換えることができます。

最後に

今回はVue.jsやその一部機能について簡単に紹介させていただきました。私自身もVue.jsを触り始めたばかりですので、学習やアプリケーションの開発を通して、より理解を深めていきたいです。次回以降は、SPA開発で役に立つ、コンポーネントの作成方法や、各ディレクティブの機能等について紹介できればと思います。