ラベル R の投稿を表示しています。 すべての投稿を表示
ラベル R の投稿を表示しています。 すべての投稿を表示

2013年4月2日火曜日

IPython Notebook




IPython Notebookで解析して、それをパブリックに表示するデモンストレーション。

作ったnotebookはIPytnon Notebook viewerを使って、ここで見られる。
http://nbviewer.ipython.org/urls/dl.dropbox.com/u/439394/ipyhon/seaice.ipynb

  1. データとしては、北極海海氷面積データのcsvでダウンロード
  2. pandasでデータを読み、9月の平均データを作る。
  3. IPythonのRmagicを使い、線形回帰を行いトレンドラインを引く



参考文献

2010年10月7日木曜日

富士山の初冠雪日(2) 続・トレンド



前回の続きとして、私自身あまりよく理解しているとは言えないが、ココを参考にして、ロバスト推定でも線形回帰をとってみた。

参考:
ロバスト推定(統計数理研究所)
http://www.ism.ac.jp/~fujisawa/research/robust.html
ロバスト推定(朱鷺の社)
http://ibisforest.org/index.php?%E3%83%AD%E3%83%90%E3%82%B9%E3%83%88%E6%8E%A8%E5%AE%9A

Rのパッケージrobustbaseを使うために
install.packages("robustbase")
を行っておく。
以下がプログラム。
import numpy as np
import scikits.timeseries as ts
#module
from read_FirstSnowFuji import *

#for R
import rpy2.robjects as robjects

ayear,amonth,aday= read_FirstSnowFuji()
days=np.array([],dtype="i4")
for  n in range(ayear.size):
    td=ts.Date("D",year=ayear[n],month=amonth[n],day=aday[n])
    days=np.append(days,td.day_of_year)


#for R
ryear=robjects.FloatVector(ayear)
rdays=robjects.FloatVector(days)
robjects.globalEnv["ryear"] = ryear
robjects.globalEnv["rdays"] = rdays

r=robjects.r

scripts="""
library("robustbase")   #import robustbase
png('FujiSnow_trend_robust.png')
plot(ryear,rdays,xlab="Year",ylab="Day of year") #scatter plot 
fm<-lmrob(rdays ~ ryear)  # robust linear model
abline(fm)  #plot regression line
abline(lm(rdays ~ ryear),lty=2) # usual linear model
dev.off()
"""
r(scripts)

# summary
summary=r('sm<-summary(fm)')
print summary


以下が図。点線が前回の回帰直線、実線がrobustbaseで得られた直線である。


出力(print summary)は


Call:
lmrob(formula = rdays ~ ryear)

Weighted Residuals:
    Min      1Q  Median      3Q     Max
-57.989  -7.872  -0.125   5.986  25.291

Coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) 76.10515   51.85081   1.468 0.144896   
ryear        0.10154    0.02673   3.798 0.000234 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Robust residual standard error: 10.03
Convergence in 12 IRWLS iterations

Robustness weights:
 2 observations c(21,115) are outliers with |weight| <= 0.00057 ( < 0.00085);
 13 weights are ~= 1. The remaining 102 ones are summarized as
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
0.00365 0.88600 0.94480 0.88410 0.98680 0.99880
Algorithmic parameters:
tuning.chi         bb tuning.psi refine.tol    rel.tol
 1.5476400  0.5000000  4.6850610  0.0000001  0.0000001
 nResample     max.it     groups    n.group   best.r.s   k.fast.s      k.max
       500         50          5        400          2          1        200
 trace.lev compute.rd
         0          0
seed : int(0) 

これによると回帰係数は0.10154(100年で約10日冠雪日が遅くなる)で、しかもp値が非常に小さく統計的に有意である。
ただし、c(21,115)が外れ値、すなわち1914年(ayear[21-1]=1914)と2008年(ayear[115-1]=2008)が外れ値になるのは良いとして、weightが1に近い点は13だけで、あとの外れ値を除く102点はweightが1以下に落とされている。

これを見るために、回帰直線の係数、weightなどの数値をpythonに戻し、プロットしてみる(同じことをRでもできるはずだが、pythonのmatplotlibのほうがなれているので)。
以下プログラム。
robust推定で得られた回帰直線を緑線で、
weightが1に近い点を青○で、
weightが0.5から0.9988の間にある点を黒点、
weightが0.00085から0.5の間にある点を赤点、
外れ値を赤xでプロットした。
#weights
weights=r('weights<-sm$weights')
weight=np.array(weights)

#plot
import matplotlib.pyplot as plt
plt.plot(ayear,ayear*a+b,'g-')
range=(weight>0.9988)
plt.plot(ayear[range],days[range],"bo")
range=np.logical_and(weight<=0.9988,weight>=0.5)
plt.plot(ayear[range],days[range],"k.")
range=np.logical_and(weight<0.5,weight>=0.00085)
plt.plot(ayear[range],days[range],"r.")
range=(weight<0.00085)
plt.plot(ayear[range],days[range],"rx")
plt.xlim(ayear[0],ayear[-1]) 
plt.xlabel("year")
plt.ylabel("day of year")
plt.savefig("FujiSnow_trend_robust_2.png")
plt.show()
ちなみに今年2010年の重みはweight[-1]=0.86999219949571671
このように多数の点の重みを落とすのは統計的に良くても、物理的な理由は自明ではない。
今回、この方法を用いたのは適当ではなかったかもしれない。

前回と今回の解析で、初冠雪日にトレンドがあるかは統計的にははっきりしなかったが、初冠雪日が遅くなっていっているかもしれないという作業仮説自体は興味深いものがある。これから、将来、どのような傾向があらわれてくるだろうか?

参考
異常気象を追う 初冠雪
http://www.bioweather.net/column/essay2/aw15.htm

縮小する富士山の永久凍土
http://www.fujisan-net.jp/data/article/1583.html

2010年10月6日水曜日

富士山の初冠雪日(2) トレンド



前回作ったモジュール(read_FirstSnowFuji)で初冠雪日を読み、年初からの日にち(1月1日を1とする)に変換したうえで、線形回帰を当てはめてみる。
以前やったように、rpy2を用いて、Rにデータを渡してやる。

import numpy as np
import matplotlib.pyplot as plt
import scikits.timeseries as ts
#module
from read_FirstSnowFuji import *

#for R
import rpy2.robjects as robjects

ayear,amonth,aday= read_FirstSnowFuji()
days=np.array([],dtype="i4")
for  n in range(ayear.size):
    td=ts.Date("D",year=ayear[n],month=amonth[n],day=aday[n])
    days=np.append(days,td.day_of_year)


#for R
ryear=robjects.FloatVector(ayear)
rdays=robjects.FloatVector(days)
robjects.globalEnv["ryear"] = ryear
robjects.globalEnv["rdays"] = rdays
r=robjects.r

scripts="""
png('FujiSnow_trend.png')
plot(ryear,rdays,xlab="Year",ylab="Day of year") # scatter plot
fm<-lm(rdays ~ ryear) # linear model
abline(fm) # plot regression line                 
dev.off()             
"""
r(scripts)
summary=r('sm<-summary(fm)')
print summary
出力(print summary)は
Call:
lm(formula = rdays ~ ryear)

Residuals:
     Min       1Q   Median       3Q      Max
-54.2679  -5.8555   0.9491   8.1001  27.3063

Coefficients:
             Estimate Std. Error t value Pr(>|t|) 
(Intercept) 138.25153   71.89542   1.923   0.0570 .
ryear         0.06873    0.03683   1.866   0.0645 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 13.45 on 115 degrees of freedom
Multiple R-squared: 0.0294,    Adjusted R-squared: 0.02096
F-statistic: 3.484 on 1 and 115 DF,  p-value: 0.06453

係数が0.06873/yearだから、100年に一週間ほどのトレンド(初冠雪日が遅くなる)となる。ただし、p値が約0.0645であるから危険率5%でトレンドがない可能性を否定できない。データのばらつきが大きいことから、さもありなんといったところである。

2010年5月26日水曜日

Rでwavelet



前回までのようにRにNINO3のデータを渡し、今回は連続wavelet解析を行ってみる。

Wavelet解析にはwmtsaパッケージを用いる。

以下がプログラムである。
プロットする時、series=TRUEでもとの時系列もプロットする。

from read_NINO import read_NINO

#for R
import rpy2.robjects as robjects

data=read_NINO()
x=data["NINO3 ANOM"]

year=str(x.year[0])
month=str(x.month[0])

#data to R
nino3=robjects.FloatVector(x)
robjects.globalEnv["nino3"] = nino3

#r script
r=robjects.r
rscripts="""
nino3ts=ts(nino3,start=c(%(year)s,%(month)s),frequency=12)
png('NINO3_R_wavelet.png')

#import library wmtsa
library("wmtsa")
## calculate the CWT of the sunspots series using
## a Mexican hat wavelet (gaussian2)
a<-wavCWT(nino3ts)    
## print the result
print(a)
## plot an image of the modulus of the CWT and the
## time series
plot(a,series=TRUE) 

dev.off()
"""
r(rscripts %locals())

結果
Continuous Wavelet Transform of nino3ts
---------------------------------------
Wavelet           : Mexican Hat (Gaussian, second derivative)
Wavelet variance  : 1
Length of series  : 724
Sampling interval : 0.08333333
Number of scales  : 73
Range of scales   : 0.0833333333333333 to 60.3333333333333
x軸は年。Y軸は0が1年(2^0)、2が4年(2^2)に対応する。

参考
A Practical Guide to Wavelet Analysis
http://paos.colorado.edu/research/wavelets/


書籍
Wavelet Methods for Time Series Analysis (Cambridge Series in Statistical and Probabilistic Mathematics)


2010年5月15日土曜日

Rで自己相関



前回に続いてRにNINO3のデータを渡し、今回は自己相関を求めてみる。

Rで自己相関を求める関数はacf である。
自己相関を求めるlagは72点(72ヶ月)までとした(lag.max=72)
自己相関の他に
自己共分散 type="covariance"
偏自己相関 type="partial"
も求めることができる。
以下、プログラム

#coding: utf-8
from read_NINO import read_NINO

#for R
import rpy2.robjects as robjects

data=read_NINO()
x=data["NINO3 ANOM"]

year=str(x.year[0])
month=str(x.month[0])

#data to R
nino3=robjects.FloatVector(x)
robjects.globalEnv["nino3"] = nino3

#r script
r=robjects.r
rscripts="""
nino3ts=ts(nino3,start=c(%(year)s,%(month)s),frequency=12)
png('NINO3_R_acf.png')

op<- par(mfrow=c(1,3)) #  描画設定:1行3列画面表示
acf(nino3ts,lag.max=72,xlab="lag (year)")              # 自己相関プロット
acf(nino3ts,type="covariance",lag.max=72,xlab="lag (year)") #自己共分散プロット
acf(nino3ts,type="partial",lag.max=72,xlab="lag (year)")    #偏相関プロット
par(op)                  #作業前の描画設定に戻す

dev.off()
"""
r(rscripts %locals())

図の横の点線は95%の信頼区間をしめす(これより絶対値の小さい相関は95%の信頼区間で無相関ではないとは言えない)。 これを90%などにしたいときはci=0.9などとする。

参考
R の基本パッケージ base, stats 中の時系列オブジェクトの簡易解説
(RjpWiki)

 R言語による時系列分析
(hamadakoichi blog)

R による時系列分析入門
(書籍)

過去のRに関する記事

2010年5月14日金曜日

Rで時系列



以前につくったpythonで取り込むNINO監視領域のデータを、統計ソフトRに持って行き、時系列データとする。Rに取り込むとRを使って統計解析ができるから便利だ。

Pythonの世界からRの世界に持っていくにはrpy2を用いる。
NINO3データを渡して、Rではtsを使って時系列オブジェクトを作り、
plot.tsでプロットする。

以下、プログラム。

from read_NINO import read_NINO


#for R
import rpy2.robjects as robjects


data=read_NINO()
x=data["NINO3 ANOM"]

year=str(x.year[0])
month=str(x.month[0])

#data to R
nino3=robjects.FloatVector(x)
robjects.globalEnv["nino3"] = nino3

#r script
r=robjects.r
rscripts="""
png('NINO3_R.png')
nino3ts=ts(nino3,start=c(%(year)s,%(month)s),frequency=12)
plot.ts(nino3ts)
dev.off()
"""
r(rscripts %locals())



参考
R の基本パッケージ base, stats 中の時系列オブジェクトの簡易解説
(RjpWiki)

 R言語による時系列分析
(hamadakoichi blog)

Rによる時系列分析入門
(書籍)

過去のRに関する記事


2010年2月14日日曜日

串本・浦神の潮位差と黒潮流路緯度 Rで線形モデル (続き2)



前回のさらに続き。推定値・予測値の信頼区間も描くことができる。

前々回もとめた係数をα、切片をβとすると、
(1) -7から35を1刻みで分割した串本・浦神の各点x0
(2) αx0+βの推定値、およびその99%信頼区間
(3)  αx0+βの推定値、および値αx0+β+ε0(ε0はx0で混入する誤差)の予測値の99%信頼区間
(4)  αx0+βの推定値および予測値の信頼区間を黒、推定値の信頼区間を青でプロット (計6本の線。直線ではない)。
(5) グラフを重ねがきする。
(6) データ点をプロットする。

rscript="""
new<-data.frame(rlevel=seq(-7,35,1))  # (1)
png(\'kuroshio_reg_R3.png\')
dc<-predict(fm,new,interval="confidence",level=0.99) #(2)   
dp<-predict(fm,new,interval="prediction",level=0.99) #(3)
matplot(new$rlevel,cbind(dp,dc),lty=1,col=c("black","black","black","black","blue","blue"),type="l",xlab="",ylab="",xlim=c(-7, 35),ylim=c(30,33.5))  #(4)
par(new=T) #(5)
plot(rlevel,rlat,xlab=\"Kushimoto-Uragami\",ylab=\"Kuroshio Latitude\",xlim=c(-7, 35),ylim=c(30,33.5))  #(6)
dev.off()     
"""
r(rscript)

 

参考: やさしい医学統計手法 6.二標本の関連性を見る。
http://www3.ocn.ne.jp/~stat/medical/med_023.htm

2010年2月13日土曜日

串本・浦神の潮位差と黒潮流路緯度 Rで線形モデル (続き)



前回の続き。
以下のようにして残差(residuals)に関するプロットを作ることができる。
(1) 図を四分割し、上下左右の間隔を指定。現在の作図パラメータはoparに退避。
(2)4種類の診断図を一度に描く。
(3) 作図パラメータをもとにもどす。

r('png(\'kuroshio_reg_R2.png\')')
r('opar<-par(mfrow=c(2,2),oma=c(0,0,1.1,0))')  #(1)
r('plot(fm)')                                       #(2)
r('par(opar)')                                      #(3)  
r('dev.off()')


 
左上: 予測値対残差。残差が1.96σを超える(正規分布で95%内に入っていない)データにはデータ番号が示されている。
右上: 標準化された残差に対する累積比率に対する正規Q-Qプロット。残差が正規分布しているか。
左下: 残差の標準化の絶対値の平方根を予測値に対してプロットしている。
右下: leverage(梃子比: 回帰直線への影響度)と標準化された残差。

例えば、右上は黒潮の緯度が高い(日本に近い)場合には、回帰直線は過大評価になっている。これは陸地があるので、それ以上は高い位置にいけないからであろう。緯度が低い(沿岸から離れる)場合に値がばらついているのは、黒潮が十分に岸から離れている場合には串本・浦神の潮位差は0に近く、黒潮の離岸距離との関係がうすまっていると考えられる。

2010年2月11日木曜日

串本・浦神の潮位差と黒潮流路緯度 Rで線形モデル



前回の続き。今回はrpy2を通してRを使い、串本・浦神の潮位差と黒潮流路緯度を線形モデルとして評価してみる。
(1) データをRに渡し、scatter plotを描く。
(2) 潮位差(rlevel)と黒潮緯度(rlat)の線形モデルを考える。
(3) 線形モデルをもとに、regression line の直線を引く。
(4) 線形モデルの結果を打ち出す。
missing valueもmasked arrayから自動的に選別して除いてくれているようだ。
#read module
#for data
from read_kuroshio_lat import read_kuroshio_lat
from read_kushimoto_uragami import read_kushimoto_uragami

#for R
import rpy2.robjects as robjects

#read data
kuroshio_lat=read_kuroshio_lat()
kushimoto_uragami=read_kushimoto_uragami()   


#for R
rlat=robjects.FloatVector(kuroshio_lat)
rlevel=robjects.FloatVector(kushimoto_uragami)
robjects.globalEnv["rlat"] = rlat
robjects.globalEnv["rlevel"] = rlevel
r=robjects.r
r('png(\'kuroshio_reg_R.png\')')    
r('plot(rlevel,rlat,xlab=\"Kushimoto-Uragami\",ylab=\"Kuroshio Latitude\")') #scatter plot 
r('fm<-lm(rlat ~ rlevel)')  # linear model
r('abline(fm)')             # plot regression line
r('dev.off()')            
summary=r('sm<-summary(fm)')
print summary

 
summaryの出力
Call:
lm(formula = rlat ~ rlevel)

Residuals:
     Min       1Q   Median       3Q      Max
-3.17592 -0.32259  0.08407  0.40907  1.30406

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 31.955937   0.038044  839.98   <2e-16 ***
rlevel       0.066666   0.003672   18.15   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.6225 on 532 degrees of freedom
  (42 observations deleted due to missingness)
Multiple R-squared: 0.3825,    Adjusted R-squared: 0.3813
F-statistic: 329.5 on 1 and 532 DF,  p-value: < 2.2e-16

線形モデルの係数は0.066666、切片は31.955937
ともにp値は小さく(2e-16)、0であるという帰無仮説は棄却できる。
線形モデルのR^2値は約38%で、前回求めた相関係数0.62の2乗になっている。

係数などは以下のようにとりだせる。
print summary.names
 [1] "call"          "terms"         "residuals"     "coefficients"
 [5] "aliased"       "sigma"         "df"            "r.squared"  
 [9] "adj.r.squared" "fstatistic"    "cov.unscaled"  "na.action"  

cf=r('cf<-sm$coefficients')
print cf.names
[[1]]
[1] "(Intercept)" "rlevel"   

[[2]]
[1] "Estimate"   "Std. Error" "t value"    "Pr(>|t|)"

for i in range(8):
    print cf[i]
31.9559366577
0.066665747972
0.0380437732903
0.00367237036394
839.978106637
18.1533291486
0.0
1.13483941203e-57

参考:単回帰http://www.geocities.jp/kashiwabara_fact/statistics-tankaiki.htm

関連ポスト
北極振動 Rで統計
北極振動 Rで統計グラフ編


2010年1月23日土曜日

北極振動 Rで統計 グラフ編

* *

前回の続き

#boxplot
scripts="""
png(’boxplot.png’)
boxplot(rdatain)
dev.off()
"""
r(scripts)
去年の12月の値は「外れ値」にはなっていない

#hist
scripts="""
png('hist.png')
hist(rdatain,seq(-4, 4, 0.4),prob=TRUE)
x<-seq(-4, 4, 0.2)
lines(x, dnorm(x, mean=mean(rdatain), sd=sqrt(var(rdatain))), lty=3)
dev.off()
"""
a=r(scripts)
#cdf plot
scripts="""
png('cdf.png')
plot(ecdf(rdatain), do.points=FALSE, verticals=TRUE)
x<-seq(-4, 4, 0.01)
lines(x, pnorm(x, mean=mean(rdatain), sd=sqrt(var(rdatain))), lty=3)
dev.off()
"""
r(scripts)
#qqplot
scripts="""
png('qqplot.png')
qqnorm(rdatain)
qqline(rdatain)
dev.off()
"""
r(scripts)
正規分布より分布がせまい。

2010年1月21日木曜日

北極振動 Rで統計





北極振動 12月だけを抜き出しの続き

12月のデータだけ抜き出して、Rで統計処理する。 Rpy2を使う。
まずは以下のように準備。readAOpickup_monthは以前作ったもの。


AO_rpy2.py 
from readAO import readAO # read AO data
from pick_month import pick_month # pick month
#
import scikits.timeseries as ts
#
import rpy2.robjects as robjects


# read AO data
AOindex_series=readAO()


# pickup December
AOindex_dec=pick_month(AOindex_series,month=12)


#remove missig value
data=AOindex_dec[AOindex_dec.mask==False].data


# for R
rdata=robjects.FloatVector(data)
robjects.globalEnv["rdatain"] = rdata
r=robjects.r


それで、
a=r('summary(rdatain)')
または
a=r.summary(rdata)
または
summary=r['summary']
a=summary(rdata)
いずれも同じ結果


print a
Min. 1st Qu. Median Mean 3rd Qu. Max.
-3.41300 -1.24200 -0.08762 -0.19740 0.82490 2.28200

print a[0]
-3.413

print a.names
[1] "Min." "1st Qu." "Median" "Mean" "3rd Qu." "Max."

b=a.r["Mean"]
print b
Mean
-0.1974

b[0]
-0.19739999999999999

print a.subset(1)
Min.
-3.413

参考
Rで統計: データ集合中の最大、最小、平均、中央値 - summary()関数http://www.yukun.info/blog/2008/09/r-summary-mean-median.html