Collatzの問題

ドイツのLothar Collatzという数学者が1937年に提示したとのことで、まだ証明がされていないらしい。予想は以下のようにシンプル。

任意の自然数の初期値nに対して、以下の操作を繰り返すことにより、有限回の操作で必ず1に達する。

  • nが偶数の場合、2で割る
  • nが奇数の場合、3倍して1を足す

CoffeeScriptによるコードの例

いくつかの初期値に対するnの変化

 

R – ヒストグラム

基本形

ヒストグラムは、ベクトルでデータと階級を与えて表示させる。

r-hist-ex-smp

オプション

階級値の指定と度数/頻度の選択

  • breaks属性に指定したベクトルで階級値を指定
  • ylim属性に指定したベクトルで縦軸の範囲を指定
  • prob=TRUEを指定することで縦軸を度数から頻度に変更

r-hist-ex-smp-axis

ラベルや色の指定

  • main属性とxlab属性に文字列を指定して、表題と横軸のラベルを設定
  • col属性でヒストグラムの色指定が可能

r-hist-ex-smp-lblcol

複数グラフ

横に並べる

r-hist-ex-col2

縦に並べる

 

r-hist-ex-row2

関数曲線との重ね合わせ

ヒストグラムの定義域の数値をそのまま使い、関数を渡して描画させることができる。

要点は以下の通り

  • hist()関数でfreq=FALSEを指定
  • curve()関数の第一引数で描画したい関数を指定(独立変数をxとする)
  • curve()関数でadd=TRUEを指定

r-hist-ex-superimpose

これを利用して、ヒストグラムに確率密度関数を重ねて描画することができる。

 

R – plot()

概要

Rの高水準作図関数で、タイプ指定で散布図、折れ線グラフなど様々なグラフを描くことができる。

基本形

数字の対を与えて散布図を描く。

r-plot-basic

タイプ指定

plot()のタイプ

引数 機能
type="p" 点プロット(デフォルト)
type="l" 折れ線グラフ
type="b" 点と線のプロット
type="c" “b”で点を描かないプロット
type="o" 点プロットと線プロットの重ね描き
type="h" 各点からx軸まで垂線を描く
type="s" 左側の値から右にステップ表示
type="S" 右側の値から左にステップ表示
type="n" 軸だけ描く(その後低水準関数でプロット)

折れ線グラフ

例えばtype指定によって折れ線グラフを描ける。

r-plot-type-l

関数を直接与える場合

関数と定義域を与えて、直接その形を描ける。

r-plot-function-sin

定義した関数を渡すこともできる。

r-plot-function-user

  • asp=1は縦軸と横軸のスケール比を1:1に設定する引数
  • pos=0はゼロで軸が交わるようにする引数

 

 

 

 

R – 整数化関数

実数を整数化する関数には以下の通り。

floor(x) x以上でない最大の整数(正の数なら切り捨て)
ceiling(x) x未満でない最小の整数(正の数なら切り上げ)
trunc(x) 0に近い方へ整数化(切り捨て)
round(x, digits = 0) IEEE式で丸める
signif(x, digits = 6) digitsで指定された有効桁数に丸める

 

R – ベクトルのソート

sort()関数

sort()関数で引数にベクトルを指定して、その要素をソートできる。デフォルトで昇順、decreasing属性で降順にもできる。

partial属性は、指定した位置の要素より小さい要素をその要素より前に、大きい要素を後ろに移動させる(完全なソートはしない)。

以下の例では、3番目の要素(5)より小さな要素を前へ、大きな要素を後ろへ移動させている。5の前の要素の列、後ろの列は、それぞれ必ずしもソートされない。

partial属性をベクトルで与えた場合、複数の位置の要素の前後に各要素が集められる。以下の例では、5番目の要素(5)と10番目の要素(11)が基準となり、5より小さい要素群、5と11の間の要素群、11より大きい要素群に分けられるが、それぞれは必ずしもソートされない。

ちなみにこの指定の仕方で、基準となる要素の大小関係が逆転していると、よくわからない結果になる。

rank()関数

ベクトルの要素を昇順でソートしたときの順序を要素とするベクトルを返す。

 

 

R – ベクトルの演算

数値演算

ベクトル同士の数値演算

同じ長さのベクトル同士の演算は、要素ごとにその演算が実行される。

ベクトルの長さが違う場合は、短い方の要素が循環して利用される。ただし長い方の要素数が短い方の要素数の整数倍になっていないと警告メッセージが出る。

ベクトルの各要素への同じ演算の適用

要素数1のベクトルを用いると、ベクトルの全要素に同じ演算を施すことができる。

比較演算

数値演算と同じく、要素ごとの比較演算も可能。要素数が違う場合も同じように循環適用される。

結果は論理型ベクトルとして返される。

数学関数

数学関数の引数にベクトルを使うと、各要素にその関数が適用される。

集合演算

ベクトルを集合とみなして、集合演算を行うことができる。

 

R – ベクトルの操作

要素の取得・部分ベクトルの抽出

単一要素の取得

ベクトルの要素は[]で添字を指定して参照

  • 先頭要素は(0番目ではなく)1番目
  • 要素数より大きい数を指定した場合はNAが返される
  • 0を指定した場合はnumeric(0)~0を0個並べたベクトルが返される

複数要素からなるベクトルを抽出

複数の要素をベクトル化して指定した場合は、それらの位置の要素からなるベクトルが返される。返り値のベクトルの要素の順番は引数のベクトルで指定した順番になる。

要素を除外したベクトルを取得

負の数を指定した場合は、その絶対値の位置の要素を除いたベクトルが返される。

  • 複数の要素を除外したい場合は、除外したい位置の添字をベクトル化して指定
  • 除外要素の指定は順不同
  • 返り値のベクトルの要素の順番は元のベクトルに準ずる
  • 負数を使う場合は正数は混在できない
  • 0は使えるが意味を持たない

条件を指定した要素・ベクトルの抽出

要素の代わりに条件式を指定すると、その条件に合った要素からなるベクトルが返される。

条件式を変数として書くこともできて、

  • 条件を満たす要素位置がTRUE、満たさない要素位置がFALSEという要素からなるベクトルが返される
  • そのベクトルを元のベクトルの引数として指定すると、TRUEの位置の要素からなるベクトルが返される

要素の追加・ベクトルの結合

既存のベクトルの長さ以上の要素を指定して値を代入すると、ベクトルが拡張されて値が代入される。

間が空いていればNAが代入される。

c()関数の中でベクトルと要素を列記して結合できる。複数の要素とベクトルを混在させることが可能。

append(v1, v2, after=n)関数は、v1のn番目の要素の後ろにv2を挿入。

また、以下のように現在の要素数 + 1の要素に値をセットすると要素が追加される。

要素・ベクトルの置換

replace()関数で指定位置の要素を指定した要素で置き換える。

  • 複数要素を置き換える場合は、指定位置と置き換え要素をベクトルで指定
    • 指定位置の数と置き換え要素の数が等しいこと
  • 指定位置の要素をベクトルで置き換えることはできない模様

条件を指定して、その条件を満足する要素のみ置換することも可能。

 

 

R – ベクトルの生成

値を直接指定して生成する

c(...)の関数の中に要素を列挙する。

同じ値が繰り返されるベクトル

要素が値の場合。

ベクトルを与えると、そのベクトルの要素が繰り返される。

ベクトルの要素を要素ごとに繰り返す。

要素ごとに繰り返しながら全体を繰り返す。timeseachの指定順は関係しない。

一定値で増減するベクトル

1ずつ増減

[開始値]:[終了値]で指定する。

seq()関数を使っても同じ。

seq()関数の本来の表現。

1以外のステップ値で増減するベクトル

seq()関数の”by=”引数でステップ値を指定。

単に引数を3つ指定した場合は、3つ目の値が”by=”の値とみなされる。

終了値がジャストでない場合は手前まで。

ただし要素の変化方向と増減値の符号が逆の場合はエラー。

ベクトルの長さ(要素数)を指定

length.out属性で指定。

length.outの代わりにlengthlenとしてもよい。

seq_len()関数は、非負の整数で長さを与えて数列を生成。

sequence()関数

seq()関数とは違う。

引数に整数値を持つベクトルc(n1, n2, …)を指定して、各要素を終了値としたベクトル1:n1、1:n2、…を結合したベクトルを返す。

乱数列の生成

Rでは、様々な確率分布に従う乱数列を生成することができる。

基本形はr<name>(n, <parameters>)の形を取り、<name>で確率分布を、<parameters>で確率分布に対応したパラメータを指定する。

一様分布

runif(n, min=a, max=b)

(a, b)の一様分布に従う乱数をn個生成する。

二項分布

rbinom(n, size=s, prob=p)

確率pの二項分布に従う乱数を生成する。たとえば不良品率pの部品からs個のサンプルを取り出し、不良品の数を数えるという試行をn回繰り返す、などの例に相当する。

指数分布

rexp(n, rate=l)

l=\lambda指数分布に従う乱数を生成する。

ポアソン分布

rpois(n, lambda=l)

l=\lambdaポアソン分布に従う乱数を生成する。

正規分布

rnorm(n, mean=m, sd=s)

平均m、標準偏差sの正規分布に従う乱数を生成する。

 

R – 演算子

算術演算子

四則演算は他の言語と同じ。正数除算(%/%)と剰余(%%)は独特。

演算の優先順位は、

  1. ()
  2. ^
  3. %/%, %%
  4. *, /
  5. +, –

比較演算子

他の言語と同じだが、数値の同一性は一定の誤差より小さい場合に「等しい」と判定される。

論理演算子

数値に対しては他の言語と同じ

 

 

ポアソン過程について

概要

次のような条件で、客の到着、トランザクションやトラブルの発生といったランダム事象の発生を考える。

  • 各事象は、その前の事象の発生から影響を受けたり、その次の事象に影響を与えたりしない(無記憶性)
  • 各事象が単位時間あたりに発生する数には偏りがない(均質性)

この場合、事象の発生は時間軸上で一様分布と考えられ、定常ポアソン過程/ポアソン到着と呼ばれる。

ポアソン過程の到着数

単位時間当たりの到着数が\lambdaで与えられたとき、観測時間tの間にk回の到着が観測される確率は、以下のPoisson分布で与えられる。

(1)    \begin{equation*} P_n (X = k; t; \lambda) = \frac{(\lambda t)^k}{k!} e^{- \lambda t} \end{equation*}

この導出は”ポアソン過程の到着数~ポアソン分布“に示すが、その概略は、観測時間tを有限・等間隔の微小時間間隔\Delta tに分け、到着数がk回となる組み合わせの数を考慮しながら確率を計算し、\Delta t \to \inftyの極限をとるという操作。

このとき、到着回数の平均と分散は以下のようになるが、その導出はPoisson分布の説明を参照。

(2)    \begin{equation*} E(k) = \lambda = {\rm const} \end{equation*}

(3)    \begin{equation*} V(k) = \lambda = {\rm const} \end{equation*}

ポアソン過程の到着時間間隔

単位時間当たりの到着数が\lambdaで与えられたとき、ある到着から次の到着までの時間間隔tは指数分布に従い、その確率密度f(t)と確率分布F(t \le T)は以下のように与えられる。

(4)    \begin{equation*} f(t) = \lambda e^{- \lambda t} \end{equation*}

(5)    \begin{equation*} F(t \le T) = 1 - e^{- \lambda T} \end{equation*}

この導出は”ポアソン過程の到着間隔~指数分布“に示すが、その概略は上のPoisson分布と同じく、観測時間tを微小時間間隔に分けて、その極限をとるという操作。

このとき、到着時間間隔の平均と分散は以下のようになるが、その導出は指数分布の説明を参照。

(6)    \begin{equation*} E(k) = \frac{1}{\lambda} \end{equation*}

(7)    \begin{equation*} V(k) = \frac{1}{\lambda ^2} \end{equation*}

このほか、それぞれの確率分布の形状や考察についても、Poisson分布の説明指数分布の説明にまとめた。

ポアソン過程のシミュレーションと確認

一様分布による到着のシミュレーション

ポアソン過程~一様分布によるシミュレーション“で、一様分布に従う乱数を発生させて、その到着時間間隔/到着回数が指数分布/Poisson分布に従っているか確認した。