未知のデータを科学するノンパラメトリック回帰。

データ分析
各種SNSで記事を共有

🔄 最終更新日 2020年4月12日 by takara_semi

パラメトリック回帰とノンパラメトリック回帰

身近にあるデータを解析する際、プロットしたときに明示的な統計的性質が分からない場合が多くあります。そうすると、解析のために、利用する統計モデルを検討する必要があります。例えばパラメトリック回帰ではある程度の目途をつけてモデルを仮定し、与えられたデータと最も上手くフィットするモデルパラメータを最尤法などを用いて推定することで、データを上手く表現するモデル(数式)を得ることができます。しかし実際には、先述の通り、事前の予想ではモデルを上手く仮定できない場合が多くあります。そこで、仮定するモデルの形自体を与えられたデータから推定する回帰手法があり、そのような手法はノンパラメトリック回帰と呼ばれます。

ハエの寿命の回帰

本記事では、Rのパッケージに含まれるサンプル・データセットの中から「ハエの寿命に関するデータ(medflies.csv)」を用いて、ノンパラメトリック回帰の方法を適用して解析します。解析するデータセットの散布図をFig1およびFig2に示します。

タカラゼミ_non_ノンパラメトリック回帰_002

Fig1 その日までのハエの死亡率
タカラゼミ_non_ノンパラメトリック回帰_001

Fig2 その日の始まりに生きているチチュウカイミバエの数

Fig1のデータセットに対する回帰結果をFig3に示します。Fig3はパラメータDF(等価自由度)によって、回帰結果がどのように変化するかを検証した結果です。この結果からDFが大きいほど回帰する関数がひとつひとつのデータ点を忠実になぞるような形に変化する様子が見て取れます。つまり、DFを変化させることで、モデル自体の複雑さを調整することができることが分かります。今回のデータセットに対してはDF=5の場合がおおよそ良好な回帰を実現しています。

タカラゼミ_non_ノンパラメトリック回帰_004

Fig3 Fig1のデータに対する等価自由度DFによるノンパラメトリック回帰結果の変化

またFig2のデータセットに対する回帰結果をFig4に示します。Fig4はFig3と同様、パラメータDF(等価自由度)によって、回帰結果がどのように変化するかを検証した結果です。この結果からもDFが大きいほど回帰する関数がひとつひとつのデータ点を忠実になぞるような形に変化する様子が見て取れます。今回のデータセットに対してはDF=20の場合において実データとの誤差がほとんど見られない程、精度の良い回帰結果が得られました。これはFig1のデータに比べFig2のデータは外れ値が少なく整ったデータセットで、回帰が容易であったためだと考えられます。

タカラゼミ_non_ノンパラメトリック回帰_005

Fig4 Fig2のデータに対する等価自由度DFによるノンパラメトリック回帰結果の変化

回帰の他の例としてFig1のデータに対してガウスカーネルを用いた回帰を実行した結果をFig5に示します。このモデルにおいてもsmooth.splineを用いたノンパラメトリック回帰におけるDFと同様の働きをするハイパーパラメータ$\sigma$を調整することで、データに沿った良好な回帰を実現することができます(Fig5はある程度良好な回帰結果が得られた時の回帰例を示したものです)。

ノンパラメトリック回帰の利点と欠点

ノンパラメトリック回帰の手法の利点は、パラメトリック回帰と比較して、ハイパーパラメータの調整によってオーバーフィッティングを避ける事ができることや、モデルの複雑さ自体を推定することができること(複雑さを明に扱う必要がない)などが挙げられます。モデルの複雑度は、モデルの表現力を測るための尺度になります。ガウシアンカーネルを用いた場合は、パラメータ$\sigma$の値によって、回帰モデルの複雑さを調整することができます。これらの特徴はノンパラメトリック回帰特有のものであり、パラメトリック回帰と比較し優位な点です。ノンパラメトリック回帰の欠点としては、扱うデータ数の増加に伴う計算コストや要するメモリの増加などが挙げられます。結局のところ、それぞれの回帰手法の特徴を理解した上で、与えられたデータによって、適当な手法を判断する必要があるといえます。

タカラゼミ_non_ノンパラメトリック回帰_006

Fig5 ガウスカーネルを用いたノンパラメトリック回帰

以下のコードをR Studioなどで実行すれば、本記事中の結果をすべて再現することができます。

<br />
library(SemiPar)<br />
medflies&lt;-read.table(&quot;medflies.csv&quot;,header=T, sep=&quot;,&quot;)#チチュウカイミバエの死亡率のデータ<br />
plot(medflies$day,medflies$living,pch=20)#その日の初めに生きているチチュウカイミバエの数<br />
plot(medflies$day,medflies$mortrate,pch=20)#その日までのハエの死亡率<br />
dim(medflies)</p>
<p>#スプライン回帰(smooth.spline)<br />
##その日までのハエの死亡率のノンパラメトリック回帰<br />
par(mfrow=c(2,2))<br />
medflies.ss &lt;- smooth.spline(medflies[1:170,1], medflies[1:170,3], df=3);medflies.ss<br />
plot(medflies[1:170,-2], pch=20, main=&quot;smooth.spline (DF=3)&quot;)<br />
lines(spline(medflies.ss$x,medflies.ss$y), col = &quot;blue&quot;, lwd=2)<br />
medflies.ss &lt;- smooth.spline(medflies[1:170,1], medflies[1:170,3], df=5);medflies.ss<br />
plot(medflies[1:170,-2], pch=20, main=&quot;smooth.spline (DF=5)&quot;)<br />
lines(spline(medflies.ss$x,medflies.ss$y), col = &quot;blue&quot;, lwd=2)<br />
medflies.ss &lt;- smooth.spline(medflies[1:170,1], medflies[1:170,3], df=10);medflies.ss<br />
plot(medflies[1:170,-2], pch=20, main=&quot;smooth.spline (DF=10)&quot;)<br />
lines(spline(medflies.ss$x,medflies.ss$y), col = &quot;blue&quot;, lwd=2)<br />
medflies.ss &lt;- smooth.spline(medflies[1:170,1], medflies[1:170,3], df=20);medflies.ss<br />
plot(medflies[1:170,-2], pch=20, main=&quot;smooth.spline (DF=20)&quot;)<br />
lines(spline(medflies.ss$x,medflies.ss$y), col = &quot;blue&quot;, lwd=2)<br />
par(mfrow=c(1,1))</p>
<p>#その日の初めに生きているチチュウカイミバエの数のノンパラメトリック回帰<br />
par(mfrow=c(2,2))<br />
medflies.ss &lt;- smooth.spline(medflies[1:170,1], medflies[1:170,2], df=3);medflies.ss<br />
plot(medflies[1:170,-3], pch=20, main=&quot;smooth.spline (DF=3)&quot;)<br />
lines(spline(medflies.ss$x,medflies.ss$y), col = &quot;blue&quot;, lwd=2)<br />
medflies.ss &lt;- smooth.spline(medflies[1:170,1], medflies[1:170,2], df=5);medflies.ss<br />
plot(medflies[1:170,-3], pch=20, main=&quot;smooth.spline (DF=5)&quot;)<br />
lines(spline(medflies.ss$x,medflies.ss$y), col = &quot;blue&quot;, lwd=2)<br />
medflies.ss &lt;- smooth.spline(medflies[1:170,1], medflies[1:170,2], df=10);medflies.ss<br />
plot(medflies[1:170,-3], pch=20, main=&quot;smooth.spline (DF=10)&quot;)<br />
lines(spline(medflies.ss$x,medflies.ss$y), col = &quot;blue&quot;, lwd=2)<br />
medflies.ss &lt;- smooth.spline(medflies[1:170,1], medflies[1:170,2], df=20);medflies.ss<br />
plot(medflies[1:170,-3], pch=20, main=&quot;smooth.spline (DF=20)&quot;)<br />
lines(spline(medflies.ss$x,medflies.ss$y), col = &quot;blue&quot;, lwd=2)<br />
par(mfrow=c(1,1))</p>
<p>#正則化付きカーネル回帰(ノンパラメトリック回帰)<br />
#その日までのハエの死亡率のノンパラメトリック回帰<br />
library(kernlab);library(MASS)<br />
sigma &lt;- 0.01; lambda &lt;- 0.1; #モデルパラメータ設定<br />
n &lt;- 170<br />
medflies&lt;-as.matrix(medflies)<br />
x &lt;- medflies[1:170,1]<br />
y &lt;- medflies[1:170,3]<br />
K &lt;- kernelMatrix(rbfdot(sigma=sigma),x)#ガウシアン・カーネル(rbfdot)のグラム行列<br />
rowK &lt;- rowSums(K)#推定量の計算(一般逆行列を使って線形方程式を解く)<br />
A &lt;- rbind(cbind(K%*%K+lambda*K,rowK),c(rowK,n))<br />
b &lt;- c(K%*%y, sum(y))<br />
estpar &lt;- as.vector(ginv(A)%*%b)<br />
beta &lt;- estpar[1:n]<br />
b &lt;- estpar[n+1]<br />
px &lt;- seq(0,170,l=170)<br />
pK &lt;- kernelMatrix(rbfdot(sigma=sigma),px,x)<br />
py &lt;- pK%*%beta+b #予測値<br />
plot(x,y,pch=20)<br />
lines(px,py,lwd=4,col=2)<br />

<参考文献>
[1] 金 明哲, “Rによるデータサイエンス”, 森北出版(2007).
[2] 金森 敬文, “Rで学ぶデータサイエンス5 パターン認識”, 共立出版(2009).
各種SNSで記事を共有
takara_semi
著者紹介 旧帝大学生。自然科学/社会学/教育学/健康増進医学/工学/数学など、および学際的な研究領域に興味があります。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

error: