IoT領域でのデータ分析セミナー

Sassorさんによる、「IoT領域におけるデータ分析の現状とこれから」というセミナーに行ってきました。 イベント概要はこちら。

atnd.org

Sassorさんは2010年に創業されて、IoTという言葉が言われ始めた頃から、デバイス作成からサービスまでワンストップで提供されているそうです。

sassor.com

セミナーは4つのセッションに分かれていました。それぞれの詳細は割愛しますが、気になったところをあげていきたいと思います。

データを活用しないと意味がない

 以前と比べてハードウェアは作りやすくなり、IoTデバイスを作ること自体は強みにはならなくなっているとのこと。また、デバイスとインターネットを連携させるだけでもダメで、データをためるだけでもダメ。私もどうしても目新しいデバイスに目が行きがちですが、結局は集めたデータを活用できなければ意味がないんですよね。Sassorさんへのデータ分析依頼は急増しているとのことで、各社ともデータの活用方法を模索している状況なのかもしれません。

IoT領域におけるデータ分析市場の動向

 IoTデバイス数は右肩上がりに増えており、2020年には530億デバイスに達する見込みとのこと。センサー単価は逆に右肩下がりに安くなっているそうです。2020年まで年間平均成長率16.9%で成長するという予測で、13.8兆円の市場に達する見込み。電力自由化やガス小売自由化などもこれに拍車をかける要因と見られているということで、データ分析市場の動向としても、2020年には280億円ぐらいという予測のようです。

IoTビジネスのステップアップ

 IoTビジネスは下記のステップを経ていくということでした。

  1. Monitoring: 電力モニタリング、ウェアブルデバイスなど
  2. Control: エアコン制御など
  3. Optimization: 製造業ロボットアーム、スマートハウスなど
  4. Autonomy: 自動運転車など

 ソリューションとしては製造業や小売業へのソリューションが多いそうですが、今後は家庭に入り込んでくるため、そのときのステップが課題ということでした。

RとPython

 データ分析といえばRとPythonですが、どっちがいいのか?ということで比較されていました。

  • Rの方がプログラミング経験がなくても使いやすい
  • Pythonの方が汎用のプログラミング言語なので発展性がある
  • 開発環境はPythonの方が使いやすい
  • 情報量はR
  • ライブラリや日本語対応はR
  • レポーティングはPython(Jupyter Notebook)

 これから始めるのであればまずは Notebook を覚えるのが良いとのことでした。また、それ以外の情報として、データマイニング関連の情報が豊富な KDnuggets というサイトや、ノンプログラミングでデータマイニングができる RapidMiner をご紹介いただきました。

 また、データがどんどん増えてくるとローカルPCではスペックが追いつかなくなってくるのですが、そういうケースでは EC2 と Jupyter Notebook を使うことで問題を解決できるということでした。

ディープラーニングの敷居は低くなった

 最近では TensorFlowChainerCaffe 等の登場で、誰でも簡単にディープラーニングを試せる時代になり、そこそこの精度も出るようになってきました。ただし良い結果を出すにはやはり経験が必要ということで、ここがプロの腕の見せ所ですね。

AIといっても切り口はたくさんある

 一口にAIといっても、その切り口としては下記のようなものがあります。

  • やりたいこと
  • 人工知能の分野
  • 使う道具 など

 また、人工知能の定義としても、下記のように主に二つの立場があるようです。

  • 人間の知能そのものをもつ機械を作ろうとする立場:強いAI
  • 人間が知能を使ってすることを機械にさせようとする立場:弱いAI

 前者は人間と同じことが汎用的になんでもできるロボットのようなイメージですね。データ分析については後者の話になります。

赤ちゃんが学ぶ過程はAIと同じ:ママだと泣かなくて、パパだと泣く

 面白かったのは、赤ちゃんが生まれてからいろいろな情報を元に自分の中に判定ロジックを作っていくのは、AIがデータを元に学習していくのと同じだという話でした。赤ちゃんは嗅覚、触覚、聴覚、味覚、視覚というセンサーから大量のデータを入力していきます。そしてよくありがちな、「ママだと泣かなくて、パパだと泣く」という状況になったりします。これは赤ちゃんが、ママがミルクをくれたり様々な世話をしてくれたりという状況から得た情報を元に人間を「ママ」と「それ以外」というモデルに分類し、「ママ」はいい人、というような判定になるためです。パパにとってはこの状況は当然よろしくないので、パパとしては自分が「それ以外」にカテゴライズされないよう、「ママ」と「それ以外」とは別に「パパ」という区分を認識してもらえるよう、様々な働きかけをする(データを入力する)必要があるというわけです。

AIにおいて重要なこと:サービスとして何をやるのかを決める

 最近では様々なフレームワークなどが出てきたことで、道具としてはなんでもできる環境が整ってきました。

  • Microsoft Azure, IBM Watson
  • R, Python, Ruby, MATLAB
  • Spicy, Numpy, TensorFlow, Chainer
  • Tableau, Power BI, SAS etc..

 ただやはり重要なのは、サービスとして何をするのか、目的関数を設定することとのこと。決め方としては TopDown か BottomUp。 TopDown はトップのニーズから実現したいサービスを決定し、その実現方法を人工知能、データ解析の言葉にしていくことです。逆にBottomUp は現状で持っているデータを簡易に分析してみてデータの特徴を見ながらできそうなサービスを想定してトップニーズ、ユースケースとリンクさせる決め方です。これはどちらがいいというわけではなく、状況に応じて使い分けが必要ということでした。

データを持っている人の勝ち?

 第3次AIブームにおいては、データさえあれば一般的な人工知能が作れる状況になってきました。ということは大量のデータを持っている会社、Amazon、Facebook、Google、IBM、Microsoft等の大企業が当然有利であり、さらに最近この5社がAI領域において提携するという発表がありました。

jp.techcrunch.com

 これはもう普通の会社ではディープラーニング分野では到底勝ち目がありません。じゃあどうするのか。これに対抗するのは、パーソナライズ:個別適応とのことでした。一般的なセグメントのモデルを利用して、個別データで再学習し、各個人が外に出さないような情報で、各個人専用にパーソナライズしていくということです。私のイメージとしては、大手が狙うボリュームゾーンを外した領域を狙うイメージかと思っています。これによってある領域のエキスパートの思考をAI化することができれば、大手とは違う領域で勝負ができるのではないかと思いました。

グラフィカルモデル

 最後に、これから重要になるのはグラフィカルモデルということで、私はまだグラフィカルモデルってどういうものかわかっていないのですが、今度の11月の人工知能学会では確率的グラフィカルモデルがテーマになっているそうです。

数学協働プログラム「確率的グラフィカルモデルの産業界への応用」

 平日なのと、まだあんまり知識のない状態で行って話が理解できるのかというところがあるのですが、都合がつきそうだったら少し行ってみたいと思っています。

メッセンジャー・チャットUI系スタートアップのピッチイベント

Chat UI Campという、メッセンジャー・チャットUI系のサービスを提供するスタートアップのピッチイベントに行ってきました。 イベントの詳細はこちら

www.asahi.com

内容としては、

  • スタートアップ13社がそれぞれ持ち時間5分でのピッチ&質疑応答
  • その中から3社のエンジニアによる対談
  • 懇親会

となっていました。

各社の個別のピッチ内容等の紹介は割愛しますが、全体通して思ったこと、感じたことをいくつか。

提供するサービスのカテゴリ

 今回は13社のピッチを聞いたわけですが、幾つかのカテゴリに分けられるなと思いました。

  1. 元々ユーザデータを取得できるサービスを展開していて、そのデータをもとに広範囲向けにチャット系サービスを展開している
  2. ある特定の業界向けのサービスを提供していて、そのためにデータを集めている
  3. 自社ではデータを持たずに、クライアントが持っているデータを解析するために技術基盤を提供している

 今回登壇された中だと、ユーザローカルさんは1に該当するかなと。PFIさんは3ですね。大部分は2に該当するかと思います。 データのボリュームや技術料という点で、この二社が突出してるのかなという印象でした。 ユーザーローカルさんはサイト解析ツールを提供していますので、1,000億PVというデータをもっているそうで、なかなかここまでのボリュームのデータを収集するのは難しいでしょうね。

業界によるデータ傾向の違い

 対象とする業界によって、データの特性はかなり違うようでした。ファッションやEC業界であれば、ユーザ数も多く、一人当たりの購入データも多いので、Amazonとかでよく見る、「これを買った人はこれも買ってます」というようなデータ(共起データと言っていた気がします)が取りやすいのですが、Iettyさんのように不動産業界を対象とする場合、ほとんどの人は家は一回しか買いませんし、商品情報としても基本的にはそれぞれ一点ものなので、これを買った人はこれも買ってますデータはなかなか取れないそうで、購入というコンバージョン以外にも、「いいね」等を用いてデータが作れるように工夫しているそうです。

各社とも人の手が入っている

 チャットボットというと全自動でAIが応答するというイメージですが、各社とも提供するサービスには少なからず人の手が入っているようです。AI関連技術が主に担っているのは、入力内容の解析、入力内容にマッチするデータの検索、オペレータへの提案というところまでで、そのデータをもとにしてオペレータが最終的にユーザに応答を返しているというパターンが多いようです。やはりAIが作成する文章だと不自然な部分があったりで、人と同じような応答が返せるようになるまでにはまだ少し時間がかかるようです。

Chat UI サービスの利点

 検索したい情報を入力して結果を返してくれるという点では、Google等の検索エンジンもChat UIのサービスも一緒だと思うのですが、下記のような点はChat UIの利点なのかなと思いました。

ユーザ情報の入力を促しやすい

 対話形式でユーザに情報の入力を求めることで、ユーザ情報の入力へのハードルを下げることができ、ユーザデータの蓄積が行いやすくなるかと思います。

能動的にユーザに働きかけることができる

 検索エンジンでは基本的にはユーザが動いてくれないとサービスを利用してもらえませんが、Chat UIサービスでは、LINE等でアカウント登録がされれば、Push通知等で能動的に働きかけることができると思います。

 ペコッターの方がピッチの中でお話しされてましたが、チャットボット等のAI関連サービスだとそのロジックが重要と思われがちですが、実はどうやってユーザに情報を入力してもらえるかが大事なんですね。情報を入力してもらえないことにはユーザデータの蓄積もできないので、ロジックにも活かしていけないわけです。

チャットボットに必要な技術

 対談の中でIettyの大浜さんが、チャットボットに必要な技術として下記3点を挙げられていました。

  • ユーザに文字や画像、音声を入力してもらうための技術
  • ユーザの質問・要求を理解する技術
  • ユーザの意図に応じて適切な回答を返す技術

前項でも書きましたが、AI関連技術だけではなく、ユーザに情報を入力してもらう部分もやはり大事ですね。

最初は人力+気合

 ピッチの中で面白かったのがペコッターさんのピッチで、サービス開始から今年の8月ぐらいまでは、サービスはほとんど自動化されておらず、人力+気合でオペレーションされていたそうです。ユーザからのチャットでの入力も代表の方が自分で応答して、お店を検索して、応答用のアカウントに切り替えて応答していたりとか。技術も大事ですが、こういったサービスへの情熱も大事ですね。

自社サービスへの活かし方を考える

 今回は自社のサービスにChat UIのサービスを活かせないかということでイベントに参加させてもらいました。チャット系サービスにはあまり詳しくなかったのですが、いろいろ勉強になりました。自社でサービス提供している業界はまだデータの収集があまり行われていないので、どうデータを収集していくのか、どうやって入力してもらいやすいUIを作っていくのかというところを、今回聞いた話を参考に考えていきたいと思います。

to_travel は DateTime.now に対応してない

 RSpecで現在時刻に関連するテストをするときに、Rails4.1からはTimecopを使わなくても ActiveSupport::Testing::TimeHelpers の to_travel というメソッドを使って現在時刻を設定することができます。

 たとえば、下記のように現在時刻を返すメソッドがあるとします。

class Foo
  def now
    Time.now
  end
end

 正しく現在時刻を返しているかのテストは下記のように書けます。

travel_to Time.new(2014, 11, 24, 9, 30, 0) do
  foo = Foo.new
  expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
end

 travel_toで現在時刻を設定しているので、expectで評価するときに決まった時間を書いて比較できます。

 ですがもしnowメソッドでDateTime.nowを返していると、to_travelでは対応できません。

class Foo
  def now
    DateTime.now # <- to_travelで設定した時間ではなく現在時刻が返る
  end
end

 その場合にはやはりTimecopを使う必要があります。Gemfileには下記のようにgemを追加。

group :test do
  gem 'timecop'
end

 テストは下記のように記述します。

Timecop.freeze(Time.new(2014, 11, 24, 9, 30, 0)) do
  foo = Foo.new
  expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
end

 travel_to が対応しているのは Time.now と Date.today のみのようです。

 travel_to(date_or_time, &block)
 rails4.1からのtravel_toをrspecで使う

RailsアプリにPassengerから環境変数を渡す

環境変数によってRailsアプリの動作を切り替えたいことがあって、
nginx + Passenger で動かしているRailsアプリに環境変数を渡す方法を調べました。

nginx の起動スクリプト(/etc/init.d/nginx)に書いても、
/etc/default/nginx に書いてもうまくいかなかったのですが、
nginx の設定ファイルの location ブロックで
passenger_set_cgi_param で設定することで環境変数が設定できます。

passenger_set_cgi_param HOGE fuga;

これでRailsアプリの中で ENV['HOGE'] で "fuga" という値が取得できるように なります。

参考ページ
16.3.5. Phusion Passengerが提供するアプリケーション
8.6.1. passenger_set_cgi_param

Rails4 で datetimepicker を使う

Rails4で入力フォームから日時を選択できるように datetimepicker を使ったのですがちゃんと動くまでに軽くはまったのでメモ。

bootstrap3-datetimepicker-rails

まずはGemfileに下記エントリを追加して bundle install

gem 'momentjs-rails'
gem 'bootstrap3-datetimepicker-rails'

moment と datetimepicker のJavaScriptファイルを読み込むための設定を追加します。 私は coffeescript を使っているので application.js.coffee に下記エントリ を追加します。 bootstrapの設定が入っていない場合はあわせて追加します。

#= require bootstrap
#= require moment
#= require bootstrap-datetimepicker

続いてstylesheetの設定も追加します。 私の場合は scss を使っているので、application.css.scss に下記を追加。 ちなみに順番もこの通りじゃないとちゃんと動きません。

@import "bootstrap-sprockets";
@import "bootstrap";
@import "bootstrap-datetimepicker";

ここまででひとまずの下準備は終了なので、実際にdatetimepickerを適用したい部分の作業をします。 今回の対象のView部分は下記のような感じです。

<div class="form-group">
  <div class="col-md-2">
    <%= f.text_field :start_datetime, value: @user.start_datetime, class:
"form-control", id: "user_start_datetime" %>
  </div>
</div>

f.text_field で出力される input タグに対して datetimepicker() メソッドを 実行します。 下記内容でcoffeescriptのファイルを別途作成して読み込みます。

$ ->
  $('#user_start_datetime').datetimepicker()

これで入力ボックスを選択した時に日時選択用のポップアップが表示されるようになります。 また、日付のフォーマットのデフォルトは MM/DD/YYYY hh:mm A/PM なので、日本の形式に変更します。 inputタグに data-date-format 属性で指定するのですが、rails の text_field タグでは追加の属性を指定できないため、先ほどのcoffeescriptを変更して動的に属性を追加します。

$ ->
  date_format = {'data-date-format': 'YYYY/MM/DD HH:mm'}
  $('#user_start_datetime').attr(date_format)
  $('#user_start_datetime').datetimepicker()

これで日付フォーマットが変更されます。 今回は一番シンプルな形で datetimepicker を使いましたが、オプションの指定で表示形式などは色々変更できますので、試してみてもらえると良いかと思います。

参考ページ http://eonasdan.github.io/bootstrap-datetimepicker/

Vagrant VM上のUbuntuから名前解決できない

 VagrantUbuntu環境を立ち上げようとするとChefでのProvision中にabortするというのが発生していてしばらく原因が分からなかったのですが、名前解決できなかったのが問題だったようです。

 私のケースでは config.vm.box に chef/ubuntu-14.04 を指定して、 chef.run_list では apt, sqlite, redisio などの cookbook を指定した状態で vagrant up すると、下記のようにProvision中にabortしていました。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'chef/ubuntu-14.04'...
==> default: Matching MAC address for NAT networking...
〜〜〜中略〜〜〜
==> default: [2014-11-16T11:51:03+00:00] WARN: Cloning resource attributes for package[tar] from prior resource (CHEF-3694)
==> default: [2014-11-16T11:51:03+00:00] WARN: Previous package[tar]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/redisio/recipes/default.rb:23:in `block in from_file'
==> default: [2014-11-16T11:51:03+00:00] WARN: Current  package[tar]: /tmp/vagrant-chef-3/chef-solo-1/cookbooks/ruby_build/recipes/default.rb:34:in `block in from_file'

 このときVMの状態は abort になります。

$ vagrant status
Current machine states:

default                   aborted (virtualbox)

 provisionなしでの起動はできるので、試しに再度 vagrant up したあとに vagrant ssh してUbuntuにログインし、 sudo apt-get update してみました。

vagrant@vagrant:~$ sudo apt-get update
0% [Connecting to us.archive.ubuntu.com] [Connecting to security.ubuntu.com]Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.

 securiy.ubuntu.com に接続しようとしているときに終了してしまっているようです。このときVMはまたaborted状態になります。VM上からインターネットへのアクセスはできていたのですが、どうも名前解決あたりが怪しそうだと思って調べていたところ、下記記事を発見。

Virtual Box ゲストから外部ネットワークにつながらない(解決済み)

 上記サイトで紹介されている通り、config.vm.provider の設定にNAT接続時のDNSの挙動に関連する、natdnshostresolver1、natdnsproxy1 を追加します。

  config.vm.provider :virtualbox do |vb|
    vb.gui = false
    vb.customize ['modifyvm', :id, '--memory', '1024']
    vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
    vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
  end

 この設定を追加することで、VM上での名前解決要求がホストマシンのDNSサーバによって行われるようになります。

9.11.5. Enabling DNS proxy in NAT mode

9.11.6. Using the host's resolver as a DNS proxy in NAT mode

 上記設定を追加して一旦 vagrant destroy したあとに vagrant up し直したところ、無事Provisionが完了するようになりました。

Passengerがgitからinstallしたgemを認識しない

 Passenger + Nginx でアプリケーションを起動しようとしたときに、下記のようなエラーが出ました。

git://github.com/nzifnab/msgpack-rails.git (at master) is not checked out. Please run `bundle install` (Bundler::GitError)

 もちろん bundle install は実行済みです。msgpack-rails を使用するために、Gemfile に下記のような記述をしてあるのですが、色々調べたところ、Passenger が git からインストールした gem を認識してくれないようです。

gem 'msgpack-rails', :git => 'git://github.com/nzifnab/msgpack-rails.git'

 bundle install --deployment で解決するという情報も見つけたのですが、これは vendor ディレクトリにgemを持ってくるため結構な時間がかかります。デプロイでは世代管理していて、デプロイ時に新しいディレクトリを作成してデプロイしているので、開発環境のサーバへデプロイするたびに時間がかかるのはちょっと困るので他の方法を探したところ、bundle package でOKという情報を見つけました。これはgemのキャッシュを vendor ディレクトリに持つもので、すぐに終わります。ただオプションで --all を指定しないと git 経由のgemをキャッシュしてくれないようです。

bundle package --all

とすることで、git からの gem も見つけてくれるようになりました。

(参考サイト)deploying rails3 apps with bundler and phusion passenger: .bundle dir not found