計測工学基礎
2019.05.08

Back



  1. 本日の作業内容

  2. 前回の宿題について

    提出者が少し少なかったのが残念でした.作業がわからない場合などは早めに質問してください.また,メンター学習室も有効に活用してください.

    後は,学生番号と名前が未記入の人がいましたので,今後は注意してください.それと,式やグラフの説明がいい加減な人もいましたので,それなりにきちんと記述してください.その点で若干減点されることもあるので,しっかりと書きましょう.

  3. 前回の復習

    確率分布に関する作業と,グラフ作成や数式作成についての作業を前回は行いました.グラフでは標準偏差を求めることで,エラーバーのついたグラフの作成ができるようになりました.また,平均値の平均値を取ることで,標準偏差が小さくなる(理論上は1/√N)となることも確認しました.Calcの機能は使わないと忘れてしまうので,学生実験のレポートや各授業の復習の際に使用して自然と作業できるようになってください.

  4. 自習資料

    リンク先の資料を参考にしてください.

    また,標準正規分布表も参照できるようになっています.

  5. 演習

    • 正規分布を扱う関数

      まず,自分で正規分布関数のグラフを作成しましょう.平均値0で,標準偏差が1の標準正規分布を描きます.使用する関数は norm.dist() です.Normal distributionから関数名が来ています.

      Calcの関数ウイザードを使用すると,指示が出てきますので,それに従ってグラフを作成してください.

      また,正規分布は確率密度関数ですので,その全範囲にわたって積分すると1になります.それを求めることも norm.dist() 関数を使用してできます.図1のように,正規分布の形と累積度数のグラフを作ります.


      図1 標準正規分布の形と累積度数

      横軸の変数 u は,-5から5までの範囲を0.1刻みで作って見ました.

      実は,標準積分布関数については,平均値などを入力しなくても良い norm.s.dist() というものが用意されています.
      これ以降の作業内容がわかるのはこの後すぐ!

    • 前回のデータの分布

      前回の作業で,0から99までの乱数を10回発生させて平均値を取る作業を10回行って,平均値の平均値を取る作業をしました.その時に得られた5個の平均値と標準偏差を用いて,乱数の平均値の分布図を作成しましょう.


      図2 前回の乱数の平均の平均の分布

      norm.dist() 関数には平均値と標準偏差を引数として与えます.
    • 積算度数の意味

      元々の乱数は0から99のどの整数も等しい確率で出てくる「離散一様分布」というものでしたが,平均値の分布は正規分布とみなしても良いものになります.(中心極限定理)図2を見ると,平均値の平均値が,例えば30くらいになることはかなり低い確率となりそうです.では,どの程度の確率でそうなるのか,やはり norm.dist() 関数を用いて確認してみましょう.

      関数の引数の4番目を1にすると,積算を計算してくれます.試しに図2の結果で試してみると,0.022という値となりました.これは,30以下の平均値になる確率が2.2%であることを意味しています.また,70以上になることもほとんどなさそうですが,実際に確率を計算で求めてみましょう.

    • 中心極限定理の確認

      これまで見てきたように rand() 関数によって発生させた乱数は離散一様分布になります.これが,その平均値が実際に中心極限定理により正規分布になるのかを確認しましょう.

      大量のデータが必要になりますので,今回もC言語のプログラムを利用して,作業を行います.次に示すプログラムは0から9までの整数を乱数により10回発生させ,その平均値を求める作業を100回行うものです.まず,データをこれにより作成しましょう.データの保存方法は以前に行ったように,実行結果をリダイレクトして行います.

      #include <stdio.h>
      #include <stdlib.h>
      #include <time.h>
      
      int main(void)
      {
      	srand((unsigned) time(NULL));
      	
      	int i, j, sum;
      	
      	for(i=1; i<=100; i++)
      	{
      		sum = 0;
      		
      		for(j=1; j<=10; j++)
      		{
      			sum += rand() % 10;
      		}
      		
      		printf("%d, %f\n", i, (double) sum / 10);
      	}
      	
      	return 0;
      }
      

      $ ./a.out > data.csv


      図3 中心極限定理の確認その1

      上のグラフ作成のためのデータ処理は以下のように行っています.

      • 横軸用のデータ

        度数分布を取るので,横軸はある範囲で区切って用意することになります.ここでは,0.5刻みです.すなわち,0,0.5,…,8.5,9というように18個のセルを作成しました.

      • 度数を求める

        以前 countif() 関数を用いて度数を求める作業を行いました.そのときは,隣のセルと数値が一致するかどうかだったので引数も単純でしたが,今回は不等号を使用するのでちょっと複雑です.

        =COUNTIF(B$1:B$100,"<="&D4)-COUNTIF(B$1:B$100,"<="&D3)

        まず,元々の平均値のデータがB1からB100のセルに入っているとします.それらのセルのうちで,左隣のセルに入っている値(例えば1.5)以下の平均値の個数をひとつ目の countif() で数え,次にその値から一つ上のセルの値以下の平均値の個数を2つ目の countif() で数えて引いています.

        countif()の中で不等号で比較するときには,不等号を二重引用符 " " で囲い,さらにデータセルの前に記号の & をつける必要があります.
      • グラフ

        グラフは散布図で作成しています.

    • より大量のデータによる確認

      最後の作業が明らかになるのはこの後すぐ!

      一様分布から正規分布に形が変わっている様子は先ほどの作業で確認できました.ただ,まだ凸凹しています.そこで,より多くのデータを用いて作業を行ってみましょう.

      以下のプログラムは0から99までの乱数を10回発生させて平均値を取ることを100万回行って,平均値の分布をグラフ化するためのデータ作成を行うプログラムです.実行すると,グラフにすぐ読み込める形式で度数を計算していますので,確認してみましょう.

      #include <stdio.h>
      #include <stdlib.h>
      #include <time.h>
      #include <math.h>
      
      int main(void)
      {
      	srand((unsigned) time(NULL));
      	
      	int i, j, sum, count[100];
      	double ave[1000000], sum_x = 0, sum_x2 = 0, mean, stdev;
      	
      	for(i=0; i<=99; i++)
      	{
      		count[i] = 0;
      	}
      	
      	for(i=0; i<=999999; i++)
      	{
      		sum = 0;
      		
      		for(j=1; j<=10; j++)
      		{
      			sum += rand() % 100;
      		}
      		
      		ave[i] = (double) sum / 10;
      	}
      	
      	for(i=0; i<=99; i++)
      	{
      		for(j=0; j<=999999; j++)
      		{
      			if(ave[j]>i && ave[j]<=i+1)
      			{
      				count[i]++;
      			}
      		}
      	}
      	
      	printf("mean,frequency\n");
      	
      	for(i=0; i<=99; i++)
      	{
      		printf("%d, %d\n", i+1, count[i]);
      	}
      	
      	for(i=0; i<=999999; i++)
      	{
      		sum_x += ave[i];
      		sum_x2 += ave[i]*ave[i];
      	}
      	
      	mean = sum_x / 1000000;
      	stdev = sqrt((sum_x2 - mean * mean * 1000000) / 999999);
      	
      	printf("\n\n\nmean,%f\n", mean);
      	printf("stdev,%f\n", stdev);
      	
      	return 0;
      }
      


      図4 確率分布と正規分布の比較

      図4ではプログラムの実行結果の度数の部分を確率に直し,プログラムの最後に計算してある平均値と標準偏差を用いて正規分布のグラフも作成して比較してあります.
  6. 次回の予習範囲

    次回も「正規分布」について学習します.引き続き予習用の資料を参考に予習してください.

  7. 宿題

    いつものレポート提出システムを利用して行います.

    宿題の公開は原則として授業の後13:00からとなります.また,提出の締め切りは授業前日火曜日の13:00までです.よろしくお願いします.


Back