2016年11月6日日曜日

courseraのMachine Learningの復習(week 2)

week 1の復習はこちら

パラメータが複数個の線形回帰


パラメータが$n$個存在するとき、線形回帰の仮説関数は、式(1)の通りとなる。

\begin{equation}
h_\theta(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + ... + \theta_n x_n
\end{equation}

ここで、$\theta$および$x$を下のような行列で表現すると($x_0$は式を単純化できるように便宜的に追加したもので、値は常に1とする)、
\begin{equation}
\theta = \begin{bmatrix}\theta_0 \\ \theta_1 \\ \theta_2 \\ \vdots \\ \theta_n \end{bmatrix}, x = \begin{bmatrix} x_0 \\ x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix}
\end{equation}
仮説関数は式(3)のように表現できる。
\begin{equation}
h_\theta(x) = \theta^T x
\end{equation}

コスト関数は、式(4)の通りになる。表現方法が変わっただけで、内容はweek 1と特に変わらない。
\begin{equation}
J(\theta) = \frac{1}{2m}\sum_{i=1}^m (h_\theta(x^{(i)})-y^{(i)})^2
\end{equation}

再急降下法の式は、次のように一般化される($j=1..n$)。
\[
\theta_j := \theta_j - \alpha\frac{1}{m}\sum_{i=1}^m ((h_\theta(x^{(i)})-y^{(i)})x^{(i)}_j)
\]
$\theta_0$については、$x_0 = 1$であるため、結局最後の$x^{(i)}_j$の部分が消えて、week 1の式と同等になる。


パラメータ値の調整


Feature Scalingと、Mean Normalizationという2つの手法がある。これらを使うことで、gradient descentを早く収束させられる。
Feature Scalingでは、パラメータの値を(そのパラメータの最大値 - そのパラメータの最小値)で割ることによって、パラメータの値を概ね-1から1の間に収めようとする。
Mean Normalizationでは、パラメータの値から、そのパラメータの平均値を引くことによって、そのパラメータの平均値概ね0になるように調整する。

まとめると、それぞれのパラメータの値を、次のように調整する。
\begin{equation}
x^{(i)}_j = \frac{x^{(i)}_j - mean(x_j)}{max(x_j) - min(x_j)}
\end{equation}


learning rateの選定


$\alpha$の値は、0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, ... というように調整していくのがいいらしい。


Normal Equation


最小の$\theta$を求める方法として、再急降下法のほかに、次の式を解く方法があり、これがNormal Equationと呼ばれる。
\begin{equation} \theta = (X^T X)^{-1} X^T y \end{equation}
どうやらgradient descentの式からこれを導出できるようなのだが、詳しいことは今後調べていく。
このあたりの記事が参考になるかもしれない。
Qiita - 線形回帰のNormal Equation(正規方程式)について

パラメータの数が10,000を超えるような場合には、normal equationではなくgradient descentを使ったほうがよいとのこと。

2016年10月10日月曜日

courseraのMachine Learningの復習 (week 1)

courseraが提供しているMachine Learningのコースを再受講しはじめましたので、せっかくなので、あとで復習できるよう、学習の内容をメモで残していきます。
このコースは、機械学習を理論から実践まで総合的に学習でき、英語が苦にならなければ教材としては最高だと思います。

ちなみに、bloggerで数式を使うやり方は、ここを参考にさせてもらいました。


線形回帰(linear regression)のモデル


もっとも単純な線形回帰では、1つの入力変数$x$と出力$y$をトレーニングデータとして与え、未知の$x$に対してなるべく正確に$y$を算出できるよう学習させる。

学習したモデル(このモデルのことを「仮説関数」(hypothesis function)と呼ぶ)は、式(1)のような1次式になり、グラフで表すと傾きと切片を持った直線になる。
\begin{equation}
y=\theta_0+\theta_1x
\end{equation}
線形回帰では、この$\theta_0$(切片)と$\theta_1$(傾き)の調整を行うことになる。

コスト関数(cost function)


コスト関数は、仮説関数に$x$を与えたときに得られる$y$がどれだけ実際の$y$と乖離しているかを求めるための関数である。コスト関数の計算結果を$J$とすると、線形回帰の目的は、この$J$を最小化することである。

コスト関数は式(2)のようになる。$h_\theta(x)$は仮説関数、$m$はトレーニングデータの数を表す。\begin{equation}
J(\theta_0, \theta_1) = \frac{1}{2m}\sum_{i=1}^m (h_\theta(x_i)-y_i)^2
\end{equation}
要するに、やってることは、全トレーニングデータの誤差の2乗の平均を求め、それを2で割っている。なぜ2で割るのかについては、ここを参考にする限り、後でこの式を微分するときにこの2が消えるので計算がやりやすくなる、ということらしい。

1変数のコスト関数は、$\theta_0$, $\theta_1$, $J$の3つを軸にとったグラフで表現すると、ボウルのような形になる。

最急降下法(gradient descent)


最急降下法(gradient descent)によって、コスト関数の値が小さくなるよう少しずつ$\theta_0$と$\theta_1$を調整していく。計算式は次のとおり。これを収束するまで続ける。
\[
\theta_0 := \theta_0 - \alpha\frac{1}{m}\sum_{i=1}^m (h_\theta(x_i)-y_i) \\
\theta_1 := \theta_1 - \alpha\frac{1}{m}\sum_{i=1}^m ((h_\theta(x_i)-y_i)x_i)
\]
$\alpha$はlearning rateと呼ばれ、この値が調整幅を決める。$\alpha$が大きくなるほど、スピードは上がるが、収束とは逆の方向に進んでしまう可能性がある。$\alpha$を小さくすれば、確実に収束する方向に向かえるが、スピードが落ちる。

上の式でやっていることは、コスト関数に対し、現在地点における$\theta_0$軸と$\theta_1$軸のそれぞれの傾きを求め、傾きが落ちている方向に$\theta_0$と$\theta_1$を移動させている。
コスト関数の偏微分がなぜ上の式になるのかについては、これを読むとわかるかもしれない。

2016年6月9日木曜日

ArcGIS Runtime for .NETを使ってS57 ENCを表示させる

前にツイートしましたが、
ということで、サンプルコードを公開します。 (ArcGIS Runtime for .NETのインストールなどは、チュートリアルを参照してください) 実行してズームインしてみると、こんな感じで表示されてます。

2016年2月16日火曜日

交通ジオメディアサミットの資料だけ拝見

先日、交通ジオメディアサミット ~IT×公共交通 2020年とその先の未来を考える~というイベントが開催されました。GISを本職としている者として、ものすごく興味があったのですが、この時期はどうしても仕事が多忙になるもので参加できず、せめて資料だけでも拝見したいと思っていたところ、ありがたいことに、資料を公開していただけておりました。

「交通ジオメディアサミット ~ IT×公共交通 2020年とその先の未来を考える~」発表資料と反応



資料を拝見する限り、今回は公共交通の中でもバスが話題の中心で、話の方向性として、「バスに関するデータがなかなか出てこない。また、出てきたとしてもフォーマットがバラバラで使いづらい。」という課題があるのが見えました。バスデータのオープンデータ化・標準化が必要というアプローチなのかな。OpenTrans.itなど、これらの問題の解決に向けた具体的な取り組みも興味深く読ませていただきました。

個人的に、オープンデータが地域のバスに関する課題を解消できるのか、まだいまいちピンときていないのが正直なところで、
  • 地域のバスなんて地元住民しかほとんど乗らないんだから、時刻表データをオープンにしなくても、また、経路探索でバスが出てこなくても、そんなに困らないのではないか。
  • データをオープンにしたところで、利用者が増えるわけではないので、利用状況の分析とかやったところで、不採算問題の解消にはつながりにくいのではないか。
  • データのオープン化によって何か地域の課題が浮かびあがる、というイメージが見えてこない。
というのが今の私がぼんやりと抱いている考えだったりするのですが、これはおそらく私自身がこの分野の素人だからそう思うのであって、もっと勉強が必要なのでしょう。
地域の課題を抜きにして考えれば、たとえば京都のバスなんかはオープンデータが発達するとすごく便利になりそうな気がします。電車とバスの乗り継ぎを一度に検索できて、しかも渋滞や遅延なども加味されると、観光効率は各段に上がるのではないかと。

次回はぜひ出席したいです。年度末だけ避けていただければ…。
あと、ナビタイムさんすごく面白いことやってるな。

2016年1月13日水曜日

CartoDBを試す

昨年のFOSS4Gか何かでCartoDBの紹介があってちょっと気になっていたところに、FOSS4G Advent Calendar (二個目)にCartoDBのチュートリアル記事がありましたので、いい機会なので試してみました。

アカウントを作る


CartoDBのサイトにアクセスして、"SIGN UP"をクリックし、アカウントとメールアドレスとパスワードを登録すれば(あと職種と業種をきかれた)、簡単にアカウントを作れます。特に迷うことはないかと。
サインアップし終わったところ


データを作る


チュートリアル記事の通りやりました。データもそちらからお借りしました。詳しくはチュートリアル記事をご参照ください。手抜きですみません。


shpファイル(が入ったzip)をデータセットに追加
shpを追加したところ
ベースマップを変えてみる(赤丸のボタンで、自分の好きなものに変更できます)
地理院タイルの白地図をベースマップにしてみた
属性値をラベルとして表示
データのマージ
SQLクエリー実行
コロプレス表示

QGISで表示する


CartoDB Plugin for QGISを使うとQGIS上でも表示できます(編集もできるっぽいですが試してません)。

まず、CartoDBのプラグインをインストールします。


そうすると、Webツールバーにこんなのが出てきます。
Webツールバー上のCartoDB
まずはCartoDBに接続します。"Add Connection"をクリックし、Connection Managerで"New"をクリックします。

ここでユーザー名とAPIキーを入力します。APIキーはCartoDBのサイトで確認することができます。
ここでユーザー名とAPIキーを入力
保存してConnection Managerに戻り、"Connect"を押すと接続されます。
接続されました
"Add CartoDB Layer"のボタン(ユーザー名のすぐ右のボタン)をクリックし、テーブルを選んでOKをクリックします。
データセットを選択

これでレイヤーがQGISに追加されたはず。
CartoDBのデータセットがQGISにロードされたところ

おわりに

とにかく操作が簡単で、今回くらいの地図であれば、GISにそれほど詳しくなくてもできてしまいそうですね。
今回はごく基本的なところしか試していませんが、ギャラリーには、タイムラインを出して時系列にマップを表示したり、正方形タイル状に表示したり、いろんな表示例を見ることができ、見てて楽しいです。結構奥が深いのかも。

2015年12月31日木曜日

GeoGigでGISデータのバージョン管理をする (4)QGIS GeoGig Pluginを試す

GeoGigをQGISで使えるプラグインが出たそうなので、今回はそれを試してみることにします。

GeoGigの基本的な機能については、以前書いた記事で紹介しています。

環境

次の環境で試しました。
  • Windows 10
  • QGIS 2.12.0(最新版よりはちょっと古いです)
※ 現在のところ、Windows版とMacOSX版にしか対応していない("At the moment, the plugin works only in OSX and Windows")のだそうです。

インストール

qgis-geogit-pluginのgithubサイトから、zipファイルをダウンロードします。zipを展開すると、"versio"というフォルダーがでてきますので、それをフォルダーごとQGISのプラグインのフォルダー([ユーザーフォルダー]\.qgis2\python\plugin)に配置します。

QGISプラグインフォルダーにversioを配置したところ

QGISを起動し、プラグインの管理画面を開きます。


インストール済のプラグイン一覧に「GeoGigClient」があるのを確認し、GeoGigClientにチェックを入れて有効にします。
プラグインの表示

そうすると、レイヤ管理ツールバーにアイコンが1個増えます。これでインストールは完了のようです。
GeoGigのアイコンが追加されたところ

操作


プラグインの説明はこちらに詳しく書かれています。これをもとにして、基本的な操作を試してみます。

リポジトリの作成


新しくできたアイコンをクリックする(またはアイコンの横の▼をクリックして"GeoGig Navigator"を選択する)と、GeoGig Navigatorという画面が開きます。この画面の左上にある"New Repository"ボタンから、新しいリポジトリを作ることができます。

レイヤ管理ツールバー上のGeoGig Navigatorアイコン


GeoGig Navigator(リポジトリを1個作ったところ)



リポジトリにレイヤーを追加する

レイヤーを先ほど作ったリポジトリに登録するには、レイヤパネルから、表示中のレイヤーを右クリックして、"GeoGig"⇒"Add layer to Repository"を選択します。

レイヤーの追加

対象のリポジトリと、最初のチェックインコメントを入力して、"Add layer"をクリックします。

追加先のリポジトリとチェックインコメントを入力

ユーザーの設定ができていない場合には、下のようなユーザー設定が出てきます。

ユーザー情報を入力

これでレイヤーが登録されます。


レイヤパネルから、再び表示中のレイヤーを右クリックして、今度は"GeoGig"⇒"Browse layer history..."をAdd layer to Repository"を選択すると、チェックインの履歴が表示されます。

履歴表示

リポジトリ内のレイヤーのロード


リポジトリに登録したレイヤーをQGISに読み込むには、GeoGig Navigatorの画面上でレイヤーを選択し、右下の"Open Repository in QGIS"ボタンをクリックします。
GeoGig Navigatorからレイヤーをロード

レイヤーをロードしたところ


地物の追加

次は、レイヤーを編集して、下図のように地物を追加してみます。
右下の三角形を追加

編集を保存すると、自動的にチェックインコメントの入力ダイアログが出てきます。

チェックインコメント入力
履歴にはこんな感じで出てきます(日本語は文字化けしてしまう模様)。

変更履歴(一番上の文字化けしてるのが今追加したもの)


差分の表示

このプラグインには、リポジトリの差分を表示する機能があるようです。

まずは、レイヤーを編集して下図のようにして、チェックインします。
左上の地物を変形、左下の地物を移動
履歴を開き、今追加したバージョンを選んで、"Show changes introduced to this version..."を選択します。

履歴から差分を表示

そうすると、前のバージョンとの差分が下図のように表示されます。地物の変更前後の状態を図で出してくれます。

差分を表示したところ



おわりに

上記で試したことのほか、タグやブランチを作ったり、以前のバージョンに戻したりもできるようなので、バージョン管理に必要な一通りの機能は備わっているという印象です。
あとは、リモートのGeoGigリポジトリにアクセスできるといいかなと(すでにそういう機能もあるのかもしれません)。

2015年12月22日火曜日

FOSS4Gで電子海図の世界をのぞく

これは、「FOSS4G 二個目だよ Advent Calendar 2015」の22日目の記事です。

QGISでは様々は形式のベクタファイルを読み込むことができますが、その中でも最もなじみが薄いファイルの一つだと思われる「S-57 Base File」について、少しお話します。
今回の主役はこれ

これはなに?

これは、「航海用電子海図」(ENC: Electric Navigable Chart)という呼ばれるものです。「S-57」というのは、ENCのデータフォーマットを定めている仕様の名称です(→S-57の仕様書はこちら)。
ENCは、大型の客船や貨物船に搭載されている「ECDIS(電子海図表示システム)」と呼ばれる専用の機器の上で海図を表示するのに使われます。

ENCデータの入手方法

日本近海のENCは、日本水路協会およびENC販売代理店から購入することで入手できます(→詳しい購入方法はこちら)。ただし、ENCのデータは、ECDISなどの専用の装置または表示用ソフトウェアでないと表示できないように、特殊な暗号化処理がかけられています。したがって、ENCのデータだけを入手して、QGISなどのGISソフトで表示させることはできません

例外として、アメリカ海洋大気庁(NOAA)が作成しているアメリカのENCは、前述の暗号化をかけていない状態でインターネット上に公開されており、誰でも無償でダウンロードして利用することができます。この記事では、アメリカのENCを見てみることにします。

アメリカのENCを入手するには、NOAAの海図ダウンロードサイトに行き、次の操作をします。
  1. 「Electronic Charts(ENC)」タブを選択
  2. 入手したいENCのある地域を地図上でクリック(囲いのあるところが、ENCデータの存在する領域になります)。
  3. 画面右側の"My Selection Information"から、入手したいENCデータを選んで、"Available Products"欄にある"ENC"リンクをクリックすると、ENCファイルをzip形式でダウンロードできます。
下図の例では、US4HA51Mという名前のハワイのオアフ島周辺の海図を選択しています。
NOAAの海図ダウンロードサイト


ダウンロードしたzipを展開すると、ENC_ROOTという名前のフォルダーの中に、US4HA51Mというサブフォルダーがあり(この名前は選択したENCによって異なります)、その中に拡張子が「.000」のファイルが存在します。これがENCデータファイルです(拡張子が「.001」とか「.002」などのファイルが同梱されていることがありますが、これは「電子水路通報」と呼ばれるファイルで、今回は無視します)。

ENC_ROOTフォルダーの中身

サブフォルダーの中身

ENCデータを見る


QGISで見る

QGISで見るには、「ベクタレイヤの追加」で、フォーマットから「S-57 Base file」を選択し、上記でダウンロード・展開した.000ファイルを選択します。
そうすると、 「追加するベクタレイヤの選択」というダイアログで、どのレイヤをQGISに読ませるかをきかれます(ENCにおける地物の種類ごとにレイヤが作られることになります)。まずは何も考えずに「全てを選択」しておけばよいでしょう。
レイヤの選択


ファイルの読み込みが完了すると、レイヤが作られてENCの内容が表示されます。
ただ、こんな感じで、何がなんだかさっぱりわかりません。
ファイルをロードしたところ


表示するレイヤを絞って、色の調整をすると、多少マシになります。下図の茶色の部分がオアフ島の陸地の部分になります。陸地の周辺に多数点在する緑の点は、その地点の水深を表す地物です。

少しは見やすくなったかも


専用ソフトで見る

QGISのほか、OpenCPNという、ENC表示専用のオープンソースソフトウェアがあります。当たりまえですが、こちらのほうが実際の表示に近いものです。
OpenCPNでENCを表示(上記と同じENCデータの一部を拡大表示)


また、ArcGIS for Desktopでも、Esri S-57 Viewerというエクステンションをインストールすることによって、ENCを表示することができます。

GDALでENCデータを扱う

GDALでもENCのデータを扱うことができます。

ogrinfoでデータの中身を見ると、こんな感じでレイヤー(地物)の一覧を見ることができます。
c:\ENC_ROOT\US4HA51M>ogrinfo US4HA51M.000
ERROR 4: S57 Driver doesn't support update.
Had to open data source read-only.
INFO: Open of `US4HA51M.000'
      using driver `S57' successful.
1: DSID (None)
2: ADMARE (Polygon)
3: AIRARE
4: ACHARE
5: BCNLAT (Point)
6: BCNSPP (Point)
7: BRIDGE
8: BUISGL
9: BUAARE
(以下省略)

また、ogr2ogrを使って、ENCデータを別のフォーマットに変換することも可能です。
c:\ENC_ROOT\US4HA51M>ogr2ogr.exe -f "ESRI shapefile" LNDARE.shp US4HA51M.000 LNDARE
ERROR 6: Can't create fields of type StringList on shapefile layers.
ERROR 6: Can't create fields of type IntegerList on shapefile layers.

変換されたshapefileをQGISで見ると、属性も含めて、きちんと表示されます。
陸地データだけ拾ったshapefileをQGISで表示したところ

おわりに


上述したように、電子海図データは、(一部地域を除いて)専用の表示装置でないと見られないので、非常に扱いづらいものになっていますが、オープンデータ化しようという動きもどうやらありそうで、そうなればもっとポピュラーなデータとして認知されるのではないかと思います。早く公開されることを願うばかりです。