草薙の研究ログ

英語教育関係。でも最近は統計(特にR)ネタが中心。

最近導入したウェブアプリメモ

Stock

https://www.stock-app.jp/

Snipper.io

https://snipper.io/

  • コードエディタ(ブラウザ上で共同編集できる)

Overleaf

https://www.overleaf.com/

StackEdit

https://stackedit.io/

  • 高性能なMarkdownエディタ
  • 後述のMermaidを使ってUMLのグラフをかける

 Mermaid Live Editor

https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbkFbQ2hyaXN0bWFzXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuQiAtLT4gQ3tMZXQgbWUgdGhpbmt9XG5DIC0tPnxPbmV8IERbTGFwdG9wXVxuQyAtLT58VHdvfCBFW2lQaG9uZV1cbkMgLS0-fFRocmVlfCBGW2ZhOmZhLWNhciBDYXJdXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ

  • Mermaidを使ってUMLのグラフをかける 

 

ウィーナーのサイバネティックスの広い定義

ウィーナーの『サイバネティックス』を読むとやっぱなんか当時の北米の知的雰囲気があってワクワクする。こういう古典って読んでみるとやる気出るね。

特に,岩波文庫版の訳本(池原他訳)で,日本語版へのあとがきのところ…

 

…今日,わたしはそれをこう述べたいと思います。 われわれの状況に関する二つの変量があるものとして,その一方はわれわれには制御できないもの,他の一方は我々に調節できるものであるとしましょう。そのとき制御できない変数の過去から現在にいたるまでの値にもとづいて,調節できる変量の値を適当に定め,われわれに最もつごうのよい状況をもたらせたいと望みがもたれます。それを達成する方法がCyberneticsにほかならないのです。―『サイバネティックス』(岩波文庫版訳本, p. 5)

 

 これすばらしい。なんというかその包括性の大きさにやられる。こんな包括的なことをこんなに明確にいえるのかと。

そして自分がやりたいことは間違いなくこの範疇に入る。

 

マルチレベルのROC曲線

状況

  • 信号検出モデルのおはなし
  • ある信号の有無について多段階評定法(5段階)でデータを取る
  • 横軸にFA(率),縦軸にH(率)を描くとこうなる(ROC曲線)

f:id:kusanagik:20181121155648p:plain

  • このデータを100人について取るとする
  • もちろん,この曲線にも個人差がある

f:id:kusanagik:20181121155958p:plain

  • ところで,FA率,H率をz変換するとおよそ(大雑把にいって)線形回帰で近似できる
  • この線形回帰モデルの傾きが1に等しくなければ,等分散ガウス信号検出モデルの等分散の仮定が怪しい,そういう理屈

f:id:kusanagik:20181121160447p:plain

  • で,これを戻すとまあまあROC曲線に近似するというわけだ

f:id:kusanagik:20181121160728p:plain

  • しかし,これはあくまでもひとりのデータであって,これが100人分ある,と考えよう

ベイズでやろう

  • これは普通に変換したFA率を説明変数,変換したH率を応答変数,個人を変量効果と考えた線形混合効果モデルに帰着する
  • つまり,集団平均の傾きと切片があり,集団内の傾きと切片の分散共分散行列があると考える
  • Rのbrmsパッケージとかでちゃっちゃとやっちゃう

事後分布を見る

  • 基本的に,一番の興味はFAの傾きの母平均
  • ベイズ信用区間からみて,普通に1はなさそうだ(ベイズ因子とかやってもいいけど…)
  • なので,集団平均として見ると,等分散性は怪しそうだ

f:id:kusanagik:20181121161639p:plain

f:id:kusanagik:20181121161836p:plain

  • 0.04から0.20を考えればいいくらいみたいだ

集団平均と個々人の推定値からROC曲線を描いてみる

  • それぞれEAPを使って曲線を描くといいわけだ
  • こんな感じ

f:id:kusanagik:20181121162226p:plain

  • 弁別力が負に入るひともいるし,大体集団平均として等分散はないな,ってことがわかる
  • 次にここから正答率を計算できるわけだけど…って,まあいいや

時代の流れに取り残されていくかんじ

今私がこれを打っているPCは,中古どころかジャンク品として買った2000円のデスクトップPCだ。RAMは1GB,CPUはCore 2 Duo,HDDは欠品だった。今型番を調べたら2004年製だという。前にどこで誰がどのように使っていたかもわからないこのPC。誰も買わないのだろうな,と思うと意味もなくこういうのを買ってしまう。14年前か。自分は大学生だったな,なんておじさんは昔に思いを馳せる。このPCを見るときに,14年前のPC産業というか日本の経済を思い出せる。

最近は本当になんでも安くなってきていて,メモリーは1,000円台も払えばバルク品でも問題なく増設できるし,SSDだって中国系企業の新製品はびっくりするくらいの値段と品質。なんていうか市場の大きさは正義だ。AmazonよりもAliExpressのほうが物欲をそそるのも事実。

ストレージなんてむしろ16GBで十分だなんて思ってたら,そういうSSDは市場に出回っていない。しかたなく64GB SSDを2,000円台で買った。Wifiドングルは1,000円台。全部で8,000円もあれば,私に必要な環境なんて整ってしまう。4GBのRAM,64GBのストレージ,Core 2 Duo程度のCPU。これは,今ARM系のCPUを積んでeMMCをストレージにしている低価格モバイルノートと同じくらいの性能になる。そういうのがだいたい3-4万だから,とっても格安だ。なによりも部品を集めたり入れ替えたりするのが楽しい。

そういう非力でもう現役を引退している,いわゆるジャンクPCに軽量デスクトップ環境をいれるのが馬鹿みたいに好きだ。もう「押し寄せるパターナリズム」のようなアップデートの通知におじさんはため息をつきたくない。

アップデートといえば,10月のUbuntu系のアップデート。私はLubuntu愛好者なのでLubuntuのアップデートをチェックしたら,なんと噂通りLubuntuはLXDE環境を捨てるのだそう。LXQtに全面的に移行する方針のようだ。

これにはまいった。というか,別にLXQtがLXDEよりも遥かに重いとかそういうことではなくて,LXDEを愛した時代はもう終わっていくんだな,という感傷。デスクトップ環境が変わる,というのはいつでもつらい。自分はそういうのにもう適応していけそうにない。かつてUbuntuのデフォルトデスクトップ環境であったGNOMEがUnityに変わったとき,なら俺はもうUnityを触らない,と決めてLXDEにした。UbuntuのUnityはいつのまにかGNOMEに戻ってたけど,もう俺が知っていたGNOMEではないようだった。

なんていうか,こういう移り変わりの激しいものにその場その場でいいようにうまく適応していくような器量は自分にはない。Lubuntuの18.04はLTSで2021年までサポートだから,俺はそれまで18.04を使おうかと思う。なんならサポート切れてもLXDEでいきたい。

なんでもそうだ。時代が変わっていくのに,自分はそれに適応していけない。いつまでもここで足踏みをするだけなんだな,なんて。それでも,それでも,14年前のPCはこうして動いているのを見る。

狭いベゼルなんてすごく気持ち悪い。曲面ディスプレイはもっと気持ち悪い。目の前にデスクトップPCがあり,ネットに繋がっているのにスマートフォンを触るひとが気持ち悪い。フリップ入力とかいう技術が気持ち悪い。

そうやって,自分のほうが気持ち悪いおっさんになっていくんだな。

…などと思ったLubuntu 18.10だった。

 

 

分散分析結果の可視化例

よく指導法の効果の検証っていうような目的でこんなグラフを見る。

f:id:kusanagik:20181015152256p:plain

これ,カーネルとか使ってこんな感じでいいじゃない?
名前なんていうかわからんけど。
これパッケージにしたら需要あるんだろうか?
流行ったらいいな。

f:id:kusanagik:20181015160334p:plain


または,これでもいいな。

f:id:kusanagik:20181015162253p:plain

library(ks)

group<-c(rep("A",40),rep("B",40))
set.seed(1)
pre<-round(c(rnorm(40,50,8),rnorm(40,50,8)),0)
post<-round(c(rnorm(40,50,8),rnorm(40,80,8)),0)
delayed<-round(c(rnorm(40,40,8),rnorm(40,70,8)),0)
dat<-data.frame(group,pre,post,delayed)


#繰り返しとかめんどくなってしまったからクソ汚い
k.pre.a<-kde(dat[dat[,1]=="A",2])
k.post.a<-kde(dat[dat[,1]=="A",3])
k.delayed.a<-kde(dat[dat[,1]=="A",4])
k.pre.b<-kde(dat[dat[,1]=="B",2])
k.post.b<-kde(dat[dat[,1]=="B",3])
k.delayed.b<-kde(dat[dat[,1]=="B",4])
m.a<-apply(dat[dat[,1]=="A",-1],2,mean)
m.b<-apply(dat[dat[,1]=="B",-1],2,mean)

plot(0,
	xlim=c(0,100),
	ylim=c(0.4,3.4),
	axes=F,
	type="n",
	xlab="Score",
	ylab="Time")
axis(2,1:3,
	c("Delayed","Post","Pre"))
axis(1)
abline(h=1:3,
	lty=2)
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.pre.a)+3,
	col="lightblue")
polygon(seq(0,100,.1),
	-7*dkde(seq(0,100,.1),
	k.pre.b)+3,
	col="orange")
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.post.a)+2,
	col="lightblue")
polygon(seq(0,100,.1),
	-7*dkde(seq(0,100,.1),
	k.post.b)+2,
	col="orange")
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.delayed.a)+1,
	col="lightblue")
polygon(seq(0,100,.1),
	-7*dkde(seq(0,100,.1),
	k.delayed.b)+1,
	col="orange")
legend("bottomleft",
	legend=c("Control","Treatment"),
	pch=20,
	col=c("lightblue","orange"),
	box.lty=0)
lines(m.a,c(3.05,2.05,1.05),
	type="b",
	lty=2,
	pch=20)
lines(m.b,c(3-.05,2-.05,1-.05),
	type="b",
	lty=2,
	pch=20)

plot(0,
	xlim=c(0,100),
	ylim=c(0.4,3.4),
	axes=F,
	type="n",
	xlab="Score",
	ylab="Time")
axis(2,1:3,
	c("Delayed","Post","Pre"))
axis(1)
abline(h=1:3,
	lty=2)
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.pre.a)+3,
	col=rgb(0,0,1,alpha=.2))
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.pre.b)+3,
	col=rgb(1,1,0,alpha=.2))
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.post.a)+2,
	col=rgb(0,0,1,alpha=.2))
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.post.b)+2,
	col=rgb(1,1,0,alpha=.2))
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.delayed.a)+1,
	col=rgb(0,0,1,alpha=.2))
polygon(seq(0,100,.1),
	7*dkde(seq(0,100,.1),
	k.delayed.b)+1,
	col=rgb(1,1,0,alpha=.2))
legend("bottomleft",
	legend=c("Control","Treatment"),
	pch=20,
	col=c(rgb(0,0,1,alpha=.2),rgb(1,1,0,alpha=.2)),
	box.lty=0,
	bg="gray98")
lines(m.a,
	c(3,2,1),
	type="b",
	lty=2,
	pch=20)
lines(m.b,
	c(3,2,1),
	type="b",
	lty=2,
	pch=20)

数式の中でイタリックにするものしないもの

いつもながら自分は大変に不勉強なもので,だいぶ恥をかき続けてしまっていた。
要は,数式の中でこういう表記をするのはあまりよくないって話。


logit(p_i) = ln(\frac{p_i}{1-p_i})


これだと流石に自分程度でもかなり格好悪いのがわかる。
…こうじゃなくてはならない。


{\rm logit}(p_i) = {\rm ln}(\frac{p_i}{1-p_i})


そうだな,expとかlnとかlogitは数式の中で直立体でないとダメだなあと理解できる。
変数lと変数nが仮にあったとしたら,lnこれらの変数の積のように読めてしまう
しかし,これだとどうだろう?自分はなんか全然悪くない気がしてしまう。
それに実際自分でこう書いてしまっている論文なども多い。


c=-\frac{1}{2} \{z(HR)+ z(FAR)\}


調べたら,信号検出理論の教科書などでは,こうイタリックで書いているものもある。
見慣れてしまっているから,なんか許せてしまうけど,確かに,HRHRの積かもしれない。
慣習はおいておいて,直立体にすべきだと思った。


c=-\frac{1}{2} \{z(\rm HR)+ z(\rm FAR)\}


最近多いのは,ベイズの事前分布とかで,


\beta_j \sim Normal(0, 1000)


みたいな。だいぶ自分もやってしまっている。
これも,やっぱりこうするべき。


\beta_j \sim {\rm Normal}(0, 1000)


国内外問わず,結構イタになっている例もあるし,最悪著者が論文内で一貫していないのもあるんだけど,気をつけたいものだ。
でもこれ,こう書いたらイタなんだよな。


\beta_j \sim N(0, 1000)


添字も同じことがあるよね。


CV_{RT}=\frac{\sigma_{RT}}{\mu_{RT}}


は,


CV_{\rm RT}=\frac{\sigma_{\rm RT}}{\mu_{\rm RT}}


って書いて,あれ,CVはイタでいいのか,みたいな話になる。微妙だ。
微妙っていえば,微分で出てくるdも本来は直立体なんだけど,慣習的にイタリックになっているそう。


\frac{dN}{dt}=-\lambda N


みたいに。でもちょっと調べたら直立体もあった。


\frac{{\rm d}N}{{\rm d}t}=-\lambda N



うむ。よくよく気をつけたいものだ。慣習っていうのもあるのだろうし,ま,それよりも数式の中身が重要だ,っていうひともいるだろうけど。
なんといっても,TeXで打つときに,\rmをめんどくさがったらダメってはなしだな。