データ分析エンジニアのブログ

日常のことからプログラミングや機械学習まで@六本木

オンライン学習とPassiveAggressiveアルゴリズム

今回はオンライン学習と呼ばれる機械学習の学習方法についてです。


PassiveAggressiveというオンライン学習のアルゴリズム(以下PAアルゴリズム)はGmailの優先トレイにも使われているのですが、2006年に発表された比較的新しい手法だからでしょうか、、ネットで検索しても情報がそんなにありませんでした。

オンライン学習

まずはオンライン学習(逐次学習)について説明します。
オンライン学習とは訓練データを1つずつ読み込み、モデルを更新する学習方法です。


特徴としては以下のようなことが挙げられます。

  • 訓練時にデータ全体をメモリに載せる必要がない
  • 1つの訓練データからの学習だけなら高速
  • ロバストでノイズに強い

PAアルゴリズム

そして本題のPAアルゴリズムですが、これはオンライン線形分類器のアルゴリズムの1種で、オンライン学習という名のごとく、訓練データが1つ与えられるごとに重みを更新していきます。


その際、常に重みを更新するのではなく、下記の通りAggressiveの時のみ、重みを更新します。

Passive

訓練事例を正しく分類できた → 重みは更新しない

Aggressive

訓練事例を正しく分類できなかった → 重みを更新


f:id:ishitsukajun:20141130223341p:plain:w400
こちらが重みの更新式です。


Lは損失関数なので、制約条件は新しく与えた訓練データを正しく分類することです。
その制約を満たしつつ、元の重みベクトルW(old)に最も近いWを新しい重みベクトルW(new)とするというのがこの数式の意味です。

参考サイト

機械学習超入門II 〜Gmailの優先トレイでも使っているPA法を30分で習得しよう!〜 - EchizenBlog-Zwei
・数式は完全に省かれていますが、とてもわかりやすく書かれています。


テキストマイニングで始める実践Hadoop活用(最終回):Hadoopによるテキストマイニングの精度を上げる2つのアルゴリズム (1/3) - @IT
・こちらは数式もありますが、丁寧で簡単に説明されています。


オンライン学習による線形識別器 - kisa12012の日記
・数式による説明が詳しいです。

意外と知らないMySQLの機能まとめ・3選

MySQLはかれこれ2年くらい使っていますが、意外に知らない機能がまだまだあるなと感じたので、最近使い方を知った以下の3つの機能についてまとめてみました。

  • 同じMySQL上の別データベースにあるテーブルをJOIN
  • 複数テーブル(3つ以上のテーブル)をJOIN
  • 条件付きSUM、COUNT

同じMySQL上の別データベースにあるテーブルをJOIN

別のデータベース上にあるテーブル2つをJOINしたいと思い、どうやるのかなと調べてみたのですが、かなり簡単でした。


(ユーザーに両方のDBへのアクセス権限がないと、もちろんエラーが発生します。)

SELECT
    *
FROM
    database_a.table_a as a
LEFT JOIN
    database_b.table_b as b
ON
    a.id = b.id;

複数テーブル(3つ以上のテーブル)をJOIN

データ量が多いテーブルを複数に分けていて、それらのテーブルたちを一気にJOINする際に使いました。


こちらも直感的でわかりやすいと思います。

SELECT
    u.*, a.*, b.*
FROM
   users as u
LEFT JOIN
   table_a as a
ON
    u.id = a.id
LEFT JOIN
   table_b as b
ON
    u.id = b.id;

条件付きSUM、COUNT

普通MySQLのSUMなどで条件を設定する場合はWHERE句で書くことが多いですが、複数のSUMやCOUNTがあり、WHERE句では対応しきれない場合があります。


そんな場合はこちらの方法を使うとすっきりSQLを書くことができます。

# 100円以上の商品の合計金額を求める
SELECT
    SUM(CASE WHEN price > 100 THEN price ELSE 0 END)
FROM
    items;

ネットワークの中心性の話


久々のブログ更新です。
最近は、卒論と機械学習やアドテク周りの勉強をやっていて中々ブログを書く時間が取れていませんでした。


卒論ではTwitterにおける情報拡散の研究をしているので、
基本的なネットワークの特徴量である、中心性の話をしたいと思います。


まずネットワークの中心性がどのようなものなのかを簡単に説明すると、
ネットワーク上の点(ノードと言います)の中でどのノードが中心なのかを表す値です。


例えば、Twitterではインフルエンサーと言われるユーザーであったり、アジアのハブ空港となっているシンガポールであったり、などの中心的なノードを見極める上でとても重要な指標となります。


中心性にもいくつか種類があって、ここでは以下の3種類の中心性を取り扱います。

  • 次数中心性
  • 近接中心性
  • 媒介中心性

次数中心性

他のノードとつながっているリンク(エッジと言います)が多いほど、中心性が高いとする方法。
最も単純でわかりやすい中心性です。

ノードiの次数中心性 = ノードiにつながっているエッジの数

近接中心性

他の点と距離が近いほど中心性が高いとする方法。

ノードiの近接中心性 = (ノードの数 - 1) / (他ノードとノードiの距離の総和)

媒介中心性

その点を通る経路が多いほど、中心性が高いとする計算方法。
最も一般的でよく使われる中心性。

ノードiの媒介中心性 = ノードiを通る経路数の総和 / ノードiを除く点の組合せ数


以上3種類の中心性を簡単に紹介しました。


これ以外にもウェブサイトのランク付けに用いられているPageRankや、それのもとになっている固有ベクトル中心性などの中心性も存在します。
これらの方法は自分のつながっているノードの中心性も考慮して計算を行っています。


興味があれば以下のサイトを参考にしてみてください。

さくらVPS(CentOS)上のApacheでpassengerを使ってRailsを動かす


今回の内容はタイトルの通りです。
内容的にかなり長くなってしまうので、参考にさせていただいたサイトを紹介するという形で進めていきます。

基本とする参考サイト

RailsアプリをさくらVPS上のpassengerを使って本番環境で動かす(1)
RailsアプリをさくらVPS上のpassengerを使って本番環境で動かす(2)


RubyRailsのインストールからpassengerとApacheの設定まで詳しく書かれていて、非常に助かりました。
これを基本にしながら、エラーログ等を見て調べて進めていくといいと思います。

エラーに遭遇したときに参考になったサイト

Rails & Passenger を Production(本番)モードで公開する時
Ruby on Railsをapacheで起動出来るようpassengerの設定


上の記事のおかげで、apacheの設定に、PassengerEnabled onという設定が抜けていたため、うまくpassengerが動かないという問題が解消できました。


下の記事はかなり似たエラーが発生したので、そっくりそのまま参考にさせてもらいました。




Railsはdevelopmentで開発していたアプリケーションをproductionで公開しなければならないので、起きているエラーがサーバー側(apacheやpassenger側)なのかapplication側(Rails側)なのかを見極めることが大切だったと思います。

USBの空き容量がおかしいと思ったら...


最近はUSBを使う機会はあんまりないと思ったのですが、とりあえずシェアしてみます。


USBを使っていると、実際に保存されている容量と空き容量を見て、
あれ、なんか空き容量少なくないか、、、
と思うことが多々あると思います。


少しの違いならいいのですが、僕は32GのUSBを使っていて、実際の空き容量と計算した空き容量の差が10Gもあり、おかしいと思い調べてみました。


調べてみると、USB上で削除したファイルは実際に削除しているわけではなく、.Trashesという隠しファイルに格納されるので、単純に削除しただけでは、空き容量が減らないということがわかりました。


あとはそれを削除すれば解決です!
Finderから隠しファイルを操作するのはめんどうなので、ターミナルから操作することをおすすめします。


USB等の外部ディスクは
/Volumes
ディレクトリに保存されているので、そこだけわかっていれば後は.Trashedというファイルを探して、削除すればOKです。

CakePHPでResponse HeadersのContent-Typeを変更する


こんにちは、結構前に書いたScrapyについての記事が地味にはてブがついたり、
Tweetされていたりして密かに喜んでいる、@ij_spitzです。


今回はCakePHPAjaxを実装したときに半日ほど躓いてしまったポイントについて書きたいと思います。


CakePHPは2.5系を使用しています。


CakePHPからAjaxを使うという記事はたくさんあるので、自分の体験談を書いていきます。


ハマりポイントは主に2つありました。
まず、こちらがjQueryを使って書いたJSのスクリプトです。

$.ajax({
  url: 'http://hoge.com/controller/action',
  type: 'POST',
  dataType: 'json',
  data: {
    id: $('#ajax_id').val()
  },
  success: function(data, status){
    if (data.message == 'success') {
      var ret = parseInt($('p#thanks').text()) + 1;
      $('p#thanks').text(ret);
    }
    console.log(data.message);
  },
  error: function(xhr, status, err) {
    alert('エラーが発生しました.');
  }
});

1. CakePHPでのAjaxパラメータの受け取り方

CakePHPではAjaxで送られてきたパラメーターは単純に、
$this->request->data['id']; というように取ることができます。


ですが、jQueryからjson形式で送られてきているので、パースしないと
なんて思って余計な処理をしていてなかなか値が取れませんでした。


これは簡単に解決したのですが、ここからが問題です。。。

2. CakePHPでResponse HeadersのContent-Typeを変更する

これがまじでしんどかったです。


http://weble.org/2011/11/29/cakephp-2-0-change-thecontent-type
http://nichiyoubi.ch/post/2839

上記の2つの記事を参考に


・ヘッダーの直書き
header("Content-Type: application/json; charset=UTF-8");


・Cakeのheaderメソッド
$this->header('Content-Type: application/json')


・RequestHandlerを使う
$this->RequestHandler->setContent('json');
$this->RequestHandler->respondAs('application/json; charset=UTF-8');


・responseオブジェクトを使う
$this->response->type('json');


・上記の処理をbeforeFilterの中でやってみる


以上のようにいろいろやってみたのですが、全く上手くいきませんでした。
Cakeのバージョンによって変更があったのかもしれません。


まあjsonAjaxしなくてもtextで諦めるか〜と思っていたのですが、解決策が見つかりました。
それがこちらです。

$this->autoRender = false;
return new CakeResponse(array('type' => 'json', 'body' => json_encode(array('message' => $message))));


参考にしたのは下記のURLです、この記事を見つけられてほんとよかったです。笑


http://pyonpyom.net/blog/107

CakePHPで部分テンプレート(エレメント)を使う

こんばんは、久々のブログの更新になります。


最近はCakePHPRuby on Railsで開発をしています。
iOSデベロッパー登録もしてswiftも趣味の範囲ですが、一応やっています。


開発をしていると複数のページで同じ部分レイアウトのコードを書くことがあると思います。
そういったときにスッキリとしたコードを書くための工夫が部分テンプレートとなっています。
ほとんどのフレームワークではこれが実装されており、CakePHPではエレメントという呼び方になっています。


今回はCakePHPでエレメントを使って、コードを簡略化するTipsをご紹介します。

部分テンプレートの作成

<div id="sidebar">
サイドバーです。
</div>


上記のようなviewファイル(ctpファイル)をapp/View/Elements/というディレクトリに作成します。


Ruby on Railsではファイル名をアンダーバーから始めないといけないという制約があったのですが、CakePHPの場合は、そういった制約はないようです。

エレメントの呼び出し

<?php echo $this->element('sidebar'); ?>


このように書くことで、先ほど作成したエレメントファイルはどのViewファイルでも手軽に呼び出せるようになります。

エレメントに変数を受け渡したい

<?php echo $this->element('sidebar', array(
    'name' => 'variable'
)); ?>


変数を利用してページごとに同じレイアウトでも表示する内容を変えたいというときに使える方法です。
ファイル名の後に配列で変数を引き渡すことができます。
これで受け渡した変数はViewで$nameでアクセスできるようになります。



エレメントを利用すると手軽にスッキリとしたコードを実現できます。
ぜひみなさんもエレメントを使ってスッキリとしたコードを実現してみてください。