epiDisplayの使い方

多変量ロジスティック回帰分析結果を出力できるepiDisplayの使い方。
 
インストールはいつもの感じでパッケージをインストールする。
install.packages("epiDisplay")
 
ライブラリを呼び出す
library(epiDisplay)
 
オッズ比と、調整済みオッズ比と95%信頼区間を出力
logistic.display(res_forward)
 
調整済みオッズ比の結果だけ出力
logistic.display(res_forward, simplified=TRUE)
 

stargazerの使い方

Rの解析結果値をhtml等で出力できるstargazerの使い方。
 
インストールはいつもの感じでパッケージをインストールする。
install.packages("stargazer")
 
ライブラリを呼び出す
library(stargazer)
 
解析結果modelをつかったhtml出力サンプル
stargazer(model, style = "ajps",dep.var.labels = "モデル",title = "テストモデル", type ="html")

ggplot使い方

Rのグラフィクスパッケージggplotの使い方。
 
インストールはいつもの感じでパッケージをインストールする。
install.packages("ggplot2", dependencies=TRUE)
 
ライブラリを呼び出す
library(ggplot2)
 
サンプルデータirisをつかったサンプルグラフサンプル
ggplot(iris, aes(x=Sepal.Width, y=Sepal.Length, colour=Species))+geom_point()

R Commanderのインストール

Rには、コマンド入力ではなくメニュー等からの選択で実行する「R Commander」とゆうGUIがある。

インストール方法は

install.packages("Rcmdr")

でパッケージをインストールする。

 

f:id:norimakibros:20171219075446p:plain

 

ミラーサイトを選択して実行。

実行後

library(Rcmdr)

で実行すると、不足しているパッケージが表示され、インストールするかどうかを聞かれるのでインストールする。

 

f:id:norimakibros:20171219075720p:plain

インストールが終了すると、Rcmdrパネルが表示されます。

f:id:norimakibros:20171219080005p:plain

ちなみに一度Rcmdrパネルを閉じると、もう一度library(Rcmdr)を入力しても表示されず、Rを再起動したら表示される。library()だから2回目以降は効いていないのか?たぶんなにか方法があるんだろうと思うので、判ったら追記しよう。

 

 

 

 

RとQGISとPostgreSQLと

FOSS4G Advent Calendar 2017 18日目の記事です。

 

毎年皆さま新しい技術記事のなか、今さらながらRを始めたのでQGISプラグインから使ってみた記事です。

 

R:オープンソースの統計解析向けプログラミング言語。初心者です。

QGISオープンソースGISソフト。お世話になってます。

PostgreSQLオープンソースのデータベースソフト。お世話になってます。

Python:いろいろ使えるスクリプト言語。チューニング次第で早くなったり遅くなったり。

 

で、この方々の関係がどうなっているかとゆうと

 

R - QGIS

プロセッシングでRスクリプトを利用できる。

https://docs.qgis.org/2.18/ja/docs/training_manual/processing/r_intro.html

 

R- PostgreSQL

RPostgreSQLパッケージで利用できる。

 

R- Python

今はRを使わないでPythonで統計をやるのが流行りらしい。

Python からRを利用できるライブラリのPypeRとゆうものがあるらしい。

 

QGIS - PostgreSQL

レイヤとしてテーブル内容を読み込めるし、プラグインからSQLを実行できる。

 

QGIS - Python

PythonQGISプラグインを作成できる。

 

Python - PostgreSQL

ドライバモジュール使用で接続できる。

 

らしい。

とゆうことでQGISプラグインPythonで作成して、PyperでRを実行。R内でRPostgreSQLを使ってデータベースを更新してQGISに更新結果を反映してみる試み。

 

QGISとRとPostgreSQLはインストール済み。

 

データは国土数値情報の市区町村データと統計局estatの統計データから出生数・人口総数・婚姻数等をPostgreSQLに突っ込む。

 

f:id:norimakibros:20171208142330p:plain

 

DB 名:rsample

市区町村名テーブル:shikuchouson。これのbornに出生数、born2に推定出生数、born_diffに差異を入れる。

 

統計データテーブル:tbl2017_a。

a1101 :総人口、a4101:出生数、a9101:婚姻件数

 

これをRで出生数を目的変数、人口総数、婚姻数を説明変数とし、重回帰分析して出生数の実数、推計数、推計差分をQGISプラグインから実行してテーブルを更新して表示してみる。

 

まずQGISプラグインを作成する。作り方は矢崎さんの記事などを参考。

QGISプラグインの作り方(パッケージ生成編) - Qiita

私の環境(QGIS2.18)だとresources_rc.pyをresources.pyにリネームしないとプラグインが壊れていますとか言われた。GUIはこんな感じ。この推計出生数ボタンを押された時にRスクリプトを実行してDBを更新させる。

f:id:norimakibros:20171214154424p:plain

 

 

 次にQGIS環境変数を確認・設定。

PYTHONHOME: QGISで使用するpythonのインストール先

PYTHONPATH:pythonのsite-packagesのインストール先

R_HOME : Rのインストール先

PATH:R_HOMEを追加

 

そしてPYTHONHOMEのpythonにRのライブラリPypeRをpipでインストールする。対応するpythonのsite-packagesにインストールされるはず。

pip install pyper

インストールが正常にいき、パスがちゃんと通っていればQGISプラグイン>pythonコンソール上でimportできるはず。エラーがでたら失敗です。pythonのバージョンいろいろ入れている人はパス関係を確認してください。私はここで、はまりました。

 

f:id:norimakibros:20171214151610p:plain

 

最後にRにPostgreSQLに接続するためのRPostgreSQLパッケージをインストール。

Rを起動して

install.packages("DBI")

install.packages("RPostgreSQL")

f:id:norimakibros:20171214162755p:plain

 これで使用準備は終わり。後はRのスクリプトを作成する。今回のスクリプトは以下のようなものを born.Rとして保存。

 

#RPostgreSQLライブラリ呼び出し
require("DBI")
require("RPostgreSQL")

# DB連結
con <- dbConnect(PostgreSQL(), host="localhost", port=5434, dbname="rsample", user="postgres", password="postgres")

# データセット作成
dataset <- dbGetQuery(con,"SELECT * FROM tbl2017_a")

# lmで重回帰分析
ans <- lm(a4101~a1101+a9101, dataset)

# パラメータ取得
intercept <- as.character(ans$coefficients["(Intercept)"])
a1101 <- as.character(ans$coefficients["a1101"])
a9101 <- as.character(ans$coefficients["a9101"])

# 推計式作成
formura = paste(intercept,"+",a1101,"*a1101 +",a9101,"*a9101")

# 推計値を入力するSQL
sql = paste("UPDATE shikuchouson SET born2=a.born2 FROM",
"(SELECT scode,round(", formura, ",0) AS born2 FROM tbl2017_a) a",
"WHERE a.scode=TO_NUMBER(n03_007, '99999');")

# 実際値と推計値の差異を入力するSQL
sql2 = "UPDATE shikuchouson SET born_diff=abs(born-born2);"

# SQL実行
dbGetQuery(con,sql)
dbGetQuery(con,sql2)

 

そしてプラグイン側でこのスクリプトを読み込み実行

#---------------------------------------------------------------------------------------
# R推計値セット
#---------------------------------------------------------------------------------------

import pyper as py

def setR(self):
    success = True
    try:
        r = py.R()
        r("source(file='C:/tmp/R/QGIS/born.R')")
        QtGui.QMessageBox.information(self.dlg, u'確認', u'R推測値セットしました',         QtGui.QMessageBox.Close)
    except:
        QtGui.QMessageBox.critical(self.dlg, u'エラー', u'R推測値セットに失敗しました',         QtGui.QMessageBox.Close)
        success = False

 

import pyper as py でpyperをインポート。pyを別名にする。

r = py.R() でRのインスタンスを作成

r("source(file={ファイル名})") でRのスクリプトを実行する。

 

これはR側で全部処理した場合ですが、python側で処理したものをRとやりとりする場合は

r.assign('data', test) # rにtestをdataとして渡す

res = r.get("result") # rのresultをresとして受け取る

のような形で受け渡しできます。

 

f:id:norimakibros:20171214154714p:plain

推計値で色分け。

f:id:norimakibros:20171214154739p:plain

推計値差異で色分け。濃いとこが差異多い。

 

ちなみに北海道では札幌市を各区別としたら、旭川市が一番出生数が多いらしい。

Rは地図用のパッケージいろいろあるみたいですね。来年勉強します。

 

 

ロジスティック回帰分析(その1)

ロジスティック回帰分析とは発生確率を予測する手法。

基本的な考え方は線形回帰分析と同じだが、予測結果が0~1の値を取る。

0%(0.00)~100%(1.00)のような確率で予測を行う場合に有意な手法。

 

Rではglm()で以下のように実行できる

ans = glm(Y~X1+X2+・・・Xn, data=DATA, family=binomial(link="logit"))

summary(ans)

 

線形解析分析と同様に解析結果は β0+β1*X1+β2*X2・・・βn*Xnの形になりますが、推測値として0~1の範囲内に収まる確率値を得るために対数をとり、以下の式になります。

log(Y/(1-Y)) = β0+β1*X1+β2*X2・・・βn*Xn

ここでYは目的変数が発生する確率であり1-Yは発生しない確率を意味します。

分解すると

t=β0+β1*X1+β2*X2・・・βn*Xn

log(Y/(1-Y)) = t

Y/(Y-1) = exp(t)

et = exp(t)

Y = et /(1+et)

となります。

 

 

 

 

 

重回帰分析(その2)

さて、桐生6日目最終日。本当は5日目までのデータをとりたかったが、竹井選手が優勝戦に乗れず、やる気がなくなったので4日目までのデータで重回帰分析してみた。

目的変数 result (着順)

説明変数1 shinnyu (進入コース)

説明変数2 motor_2win (モータ2連帯率)

説明変数3 bort_2win (ボート2連帯率)

 

ans = lm(result~shinnyu+motor_2win+bort_2win, dataset)

ans

 

f:id:norimakibros:20171211233325p:plain

推定着順 = 4.234239 + 0.380960 * shinnyu -0.056836 * motor_2win -0.001379 * bort_2win

 

これを元に最終日優勝戦の推定着順を求めてみると

f:id:norimakibros:20171211234854p:plain

resultが小さいほど1着に近いと考える。

まず1号艇頭は固い&6号艇は要らない。2,3,4,5は団子とゆう、まぁあまり面白くない推定になった。まぁ2連帯率だけだからね。

 

ちなみに展示走行で5号艇がスタート気張りそう&モータ勝率で2着固定にして取れました。

1->5->2 ¥2420。大瀧選手おめでと~!

f:id:norimakibros:20171212000540p:plain