情報工学Ⅱ (第9回) 月曜4限 担当:北川 晃
データの統計処理に関する諸問題 データの分布の様子 データの期待値(平均値) データの分散,標準偏差(ばらつきの度合い) 回帰直線へのフィッティング(最小二乗法) 一様乱数の発生 正規乱数への変換 モンテカルロシミュレーション
例題:度数分布 n個のデータx1, x2, …, xnが与えられている. ‘normal_data.txt’よりデータを逐次読み込んで, 次の区分に従って度数分布を調べよ. x<-2.25 -2.25≦x<-1.75 -1.75≦x<-1.25 -1.25≦x<-0.75 -0.75≦x<-0.25 -0.25≦x< 0.25 0.25≦x< 0.75 0.75≦x< 1.25 1.25≦x< 1.75 1.75≦x< 2.25 2.25≦x
度数分布:考え方 それぞれ領域を以下のように定める. x<-2.25:領域0 -2.25≦x<-1.75:領域1 データを読み込んで,領域iに当てはまるとき, c(i)の値を1増やす. p(i)=c(i)/nの値を計算し,書き出す. x<-2.25:領域0 -2.25≦x<-1.75:領域1 -1.75≦x<-1.25:領域2 … :… 1.75≦x< 2.25:領域9 2.25≦x :領域10
出力例:度数分布
度数分布:プログラム例 読み込んだ値がどの領域に属するか判定 Dim n, c(100) As Integer, x, p(100) As Single Dim ReadText As New IO.StreamReader( _ "D:\…\normal_data.txt", System.Text.Encoding.Default) For i As Integer = 0 To 10 c(i) = 0 Next n = ReadText.ReadLine() For i As Integer = 1 To n x = ReadText.ReadLine() If x < -2.25 Then c(0) = c(0) + 1 ElseIf -2.25 <= x And x < -1.75 Then c(1) = c(1) + 1 ElseIf -1.75 <= x And x < -1.25 Then c(2) = c(2) + 1 読み込んだ値がどの領域に属するか判定
度数分布:プログラム例(続き) 読み込んだ値がどの領域に属するか判定 ElseIf -1.25 <= x And x < -0.75 Then c(3) = c(3) + 1 ElseIf -0.75 <= x And x < -0.25 Then c(4) = c(4) + 1 ElseIf -0.25 <= x And x < 0.25 Then c(5) = c(5) + 1 ElseIf 0.25 <= x And x < 0.75 Then c(6) = c(6) + 1 ElseIf 0.75 <= x And x < 1.25 Then c(7) = c(7) + 1 ElseIf 1.25 <= x And x < 1.75 Then c(8) = c(8) + 1 ElseIf 1.75 <= x And x < 2.25 Then c(9) = c(9) + 1 Else c(10) = c(10) + 1 End If Next 読み込んだ値がどの領域に属するか判定
度数分布:プログラム例(続き) 各領域の規格化度数を計算 For i As Integer = 0 To 10 p(i) = c(i) / n Console.WriteLine("p({0})={1}", i, p(i)) Next
出力例:度数分布(エクセルによる表示) 釣り鐘型(正規分布)
平均値と標準偏差 平均値: 標準偏差: n個のデータx1, x2, …, xnが与えられている. データを逐次読み込んで,その平均値と 標準偏差を求めよ. 平均値: 標準偏差:
平均値と標準偏差:具体例 (i) N≧2のとき :平均値 :標準偏差
プログラミング演習 外部データ’normal_data.txt’よりデータ点数および各データを読み込んで,それらの平均値を計算するプログラムを作れ. ‘normal_data.txt’を読み込みファイルとして接続する. データ点数を読み込み,nに代入する. すべてのデータを配列a(i)に代入する. すべてのデータの和sを計算する. 平均値aveを計算し,表示する.
出力例:平均値の計算
プログラム例:平均値の計算 データ点数の読み込み データを配列へ読み込む データの和の計算 平均値の計算 Dim a(10000), ave As Single, s As Single = 0, n As Integer Dim ReadText As New IO.StreamReader( _ "D:\…\normal_data.txt", System.Text.Encoding.Default) n = ReadText.ReadLine() For i As Integer = 1 To n a(i) = ReadText.ReadLine() Next s = s + a(i) ave = s / n Console.WriteLine("平均はE={0,8}", ave) ReadText.Close() データ点数の読み込み データを配列へ読み込む データの和の計算 平均値の計算
プログラミング演習 外部データ’normal_data.txt’よりデータ点数および各データを読み込んで,それらの平均値を計算するプログラムを作れ. 上記のプログラムをFunctionプロシージャに書き直し,平均値を計算するプログラムを作れ.
例題:平均値を求める関数副プログラム データ点数nとa(i) (i=1,…,n)を引数として,それらの 平均値を返す関数副プログラムを作れ. 関数プロシージャの引数には,配列を取ることも可能. 配列 Sub Main() Dim a(10), ave As Single, n As Integer … ave = ave_func(n,a) End Sub Function ave_func(n,a) Return ave End Function 配列 配列
平均値を求める関数副プログラム:プログラム例 Sub Main() Dim a(10000), ave As Single, n As Integer Dim ReadText As New IO.StreamReader( _ "D:\…\normal_data.txt", System.Text.Encoding.Default) n = ReadText.ReadLine() For i As Integer = 1 To n a(i) = ReadText.ReadLine() Next ReadText.Close() ave = ave_func(n, a) Console.WriteLine("平均はE={0,8}", ave) End Sub
平均値を求める関数副プログラム:プログラム例 Function ave_func(n, a) Dim s As Single = 0, ave As Single For i As Integer = 1 To n s = s + a(i) Next ave = s / n Return ave End Function 関数副プロシージャで, 以下のものは宣言不要 共通に宣言した変数 関数の仮引数
プログラミング演習 外部データ’normal_data.txt’よりデータ点数および各データを読み込んで,それらの平均値を計算するプログラムを作れ. 上記のプログラムをFunctionプロシージャに書き直し,平均値を計算するプログラムを作れ. さらに標準偏差を計算するプログラムを,Functionプロシージャを用いて作れ.
平均値を求める関数副プログラム:プログラム例 Sub Main() Dim a(10000), ave, sd As Single, n As Integer Dim ReadText As New IO.StreamReader( _ "D:\…\normal_data.txt", System.Text.Encoding.Default) n = ReadText.ReadLine() For i As Integer = 1 To n a(i) = ReadText.ReadLine() Next ReadText.Close() ave = ave_func(n, a) sd = sd_func(n, a, ave) Console.WriteLine("平均はE={0,8}", ave) Console.WriteLine(“標準偏差はσ={0,8}", sd) End Sub
平均値を求める関数副プログラム:プログラム例 Function ave_func(n, a) … Return ave End Function Function sd_func(a, ave, n) Dim s2 As Single = 0.0 Dim var, sd As Single For i As Integer = 1 To n s2 = s2 + a(i) ^ 2 Next var = s2 / n - ave ^ 2 sd = Math.Sqrt(var) Return sd
プログラミング演習 外部データ’normal_data.txt’よりデータ点数および各データを読み込んで,それらの平均値および標準偏差を計算するサブルーチン・プログラムを作れ.
Subプロシージャとは 主プログラムの一部を外部の副プログラムに移す 繰り返し同じ記述をする場合などに有効 Functionプロシージャとは異なり, 主プログラムに値は返さない 主プログラムと変数のやりとりをすることもできる プログラムで 共有する変数は,Mainよりも外で 宣言する Mainプログラムも, Subプロシージャの一つ Sub Main() … プロシージャ名(変数) End Sub Sub プロシージャ名(変数) 文ブロック 値は返さないので, “Return *”はいらない
平均値を求めるサブルーチン:プログラム例 Sub Main() Dim a(10000), ave, sd As Single Dim n As Integer Dim ReadText As New IO.StreamReader("d:\normal_data.txt", _ System.Text.Encoding.Default) n = ReadText.ReadLine() For i As Integer = 1 To n a(i) = ReadText.ReadLine() Next ReadText.Close() ave_sub(n,a) sd_sub(n,a,ave) End Sub サブルーチンは値を返さないので, サブルーチン内で結果を表示する (主プログラムの変数を書き換える ことはできる(’ByRef’))
平均値を求めるサブルーチン:プログラム例 Sub ave_sub(n,a) Dim s As Single = 0.0 For i As Integer = 1 To n s = s + a(i) Next ave = s / n Console.WriteLine("平均はE={0,8}", ave) End Sub Sub sd_sub(n,a,ave) Dim s2 As Single = 0.0, var As Single s2 = s2 + a(i) ^ 2 var = s2 / n - ave ^ 2 sd = Math.Sqrt(var) Console.WriteLine("標準偏差はσ={0,8}", sd) サブルーチンは,プログラムの 一部を外部に分割. 値を返さない.
平均値を求めるサブルーチン:プログラム例 Dim a(10000), ave, sd As Single Sub Main() Dim n As Integer Dim ReadText As New IO.StreamReader("d:\normal_data.txt", _ System.Text.Encoding.Default) n = ReadText.ReadLine() For i As Integer = 1 To n a(i) = ReadText.ReadLine() Next ReadText.Close() ave_sub(n) sd_sub(n) Console.WriteLine("平均はE={0,8}", ave) Console.WriteLine("標準偏差はσ={0,8}", sd) End Sub 主プログラムの外で変数を宣言する 主プログラムの変数を 書き換えているわけではない (サブルーチンで計算した 値が使える)
平均値を求めるサブルーチン:プログラム例 Sub ave_sub(n) Dim s As Single = 0.0 For i As Integer = 1 To n s = s + a(i) Next ave = s / n End Sub Sub sd_sub(n) Dim s2 As Single = 0.0, var As Single s2 = s2 + a(i) ^ 2 var = s2 / n - ave ^ 2 sd = Math.Sqrt(var)