ExcelのRandbetween関数の精度

このQ&Aのポイント
  • ExcelのRandBetween関数の精度について検証しています。
  • ExcelのRand関数やRandBetween関数の精度があまりよくないと言われていますが、具体的にどの程度悪いのかを調査しています。
  • 30万個のデータをランダムに生成し、そのバラつき具合を統計的に評価する方法を模索しています。
回答を見る
  • ベストアンサー

ExcelのRandbetween関数の精度

ExcelのRand関数、RandBetween関数はあまり精度がよくないので、メルセンヌツイスターを利用した乱数精製器を使えと、よく言われます。 なんとなく、悪いのだろうな(というよりそれほど重要視していないだろう)という認識はありますが、実際どの程度悪くて、どんなレベルになら利用しても差し支えなくて、どんな状況下では使ってはいけないのか、線引きをするため(と統計学の手法を勉強したいこともあって)自分で検証してみようかと考えています。 なるべくExcelだけですむようにと考えています。 そこで質問です。 (1)まず、データの個数は30万個にしました(うちのPCで操作できる限界がこの辺でしたので) (2)A1~J30000までに「randbetween(1,300000)」という関数を入力し、30万個のセルに1~300000(30万個)のデータを入力しました。 (3)さらにL1にcountif($A$1:$J$30000,(1))と入力し((1)の部分は1~300000)出現数をカウントしました。 ここまでやってみてぱっと見で意外とダブっているなと認識したのですが、これを統計的にどの程度ばらついていないのか、を議論するにはどうすればいいでしょうか? 標準偏差はバラつきを示す指標のひとつですが、完全にばらついた(ユニークである事)を示す指標に使うと意味がわからないです。 とはいえ、これほどのデータだとグラフを書くのも不可能(エクセルのグラフ機能は使用できるデータの個数が限られています)。 どうやって見ればいいのかと、とまってしまっています。 前提条件から覆してこういう見方をするべきだ、という意見も大歓迎です。 ご教授のほど、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんばんは。 本来、RAND 関数で、自然乱数ではなく擬似乱数(pseudo-random numbers)ですが、日本語サイトの情報では、あまり正確な情報が出ていないようです。 そこで、RANDOM について、旧バージョンと比較して、Excel 2003/2007 (2003には、バグが残っています)が、一応、100万回以上を試さない限りは、乱数は保証できると言っています。 Excel 2007 と Excel 2003 の RAND 関数について http://support.microsoft.com/kb/828795/ja いろいろ探してみましたが、以下の論文が一番、話の内容が納得できるようです。 英文資料です。 http://www.daheiser.info/excel/frontpage.html XVIII. Random Number Generation (update, 12/10/08)  pdf 資料(私は、30P の内、半分程度しか読んでいません。) そこに、RANDBETWEEN の説明も書かれていますが、RAND()関数と独立して検査は出来ないけれども、特に問題も見出せなかったとされています。 >とはいえ、これほどのデータだとグラフを書くのも不可能(エクセルのグラフ機能は使用できるデータの個数が限られています)。 それは、大雑把に見るのでしたら、散布図の形を見れば良いのではないでしょうか。それで、X,Y で期待する四角形(30万,30万)で概ね塗りつぶせれば、偏りが少ないだろうし、形やムラが出来れば、偏りがあるのだと判定できるはずです。

forbiddendoll
質問者

お礼

配布リンク先のPDFについては後ほど見るとして、Microsoftの見解は一つの閾値として使えそうです。 うちで使っているのはOffice2000なので、精度の悪い(とされる)Excelのようです。ただ、それでも100万個以上・・・ということですから。 まぁよほどの事がない限り問題にはならないでしょうね。 問題になりえる使い方も、イメージがわきました。検証云々は別途考えるとして、目的の一つである「どういう時には利用すべきでないか」が明確になり、スッキリしました。

その他の回答 (8)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.9

補足: Excel用の説明としては、こちらが分かりやすいかと思います。 MTは、日本人が考えたもので、海外のものよりも優れているのですね。今回は、いろいろ勉強させられました。 良い乱数・悪い乱数 http://www001.upp.so-net.ne.jp/isaku/rand.html ここに、 「このページの目的は、従来の乱数の問題点を指摘し、すばらしい乱数、 「メルセンヌツイスタ」 の普及を促進することである。」 ということが書かれています。 乱数ライブラリ http://www001.upp.so-net.ne.jp/isaku/rand2.html sfmt.zip : ライブラリ一式 (ただし、その前の[zmtrand.zip : ライブラリ本体一式]も入れてください。)こちらは、SFMT があり、Excel用のサンプルも揃っています。 この検査は、1億回調べて、時間を計ります。 仕事では、この中から、ひとつを使えばよいと思います。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.8

こんにちは。 返事をつけるのが遅くなりました。 >どのように評価するのかについては いくつか調べてみましたが、評価は、ヒストグラムでできます。 Excel2000 で試してみました。 エクセルを用いた標準正規分布に従う乱数(正規乱数)の発生とヒストグラム http://homepage1.nifty.com/gfk/Norm-Rand.htm ヒストグラムの取り方は、手作業でも構わないと思いますが、分析ツールがアドインでありますから、そちらを使ってできます。技術関係の方でしたら、お分かりになるかと思います。ヒストグラムの作り方は、上限と下限の区分さえ決めてあげれば、できるはずですから、そこで分布を見ればよいと思います。 それと、Excel2000 ですから、OSは、少なくとも Vista ではありませんから、以下のツールが使えるかと思います。ソースもありますから、コンパイルしてもよいかとは思います。Excel2000では、良い方法が見つけられませんでした。 Mersenne Twister DLL版 http://www.vector.co.jp/soft/win95/prog/se227612.html 解説 http://hp.vector.co.jp/authors/VA020429/mt.html Cでコンパイルされたものですから、C:\Windows など、Path の通った、例えば、\System32の中にでも入れてあげればよいと思います。スピードも多少は遅いのですが、VBAよりは格段に速いです。VBAの中からワークシートに値を出します。 それで、正規分布 NORMDIST で、上記のMTの中の、genrand_real2で、グラフ化を試してみましたが、キレイな正規分布図が取れました。RAND()関数では、そこまでは、正規分布図は取れないように思います。 なお、RANDOM 関数を、RandBetween に直す方法は、 Int((最大値 - 最小値 + 1) * [ランダム関数] + 最小値) とします。

  • NNAQ
  • ベストアンサー率56% (104/184)
回答No.7

擬似乱数の統計的な検定なら、エクセルのサイトではありませんが、 http://www.geocities.jp/m_hiroi/light/pystat04.html エクセルにカイ2乗検定の関数があるので、エクセルで統計的な検定について説明したサイトも探せばあるでしょう。 よく例に挙げられるのがサイコロの出目ですね。 サイコロは6面ですが、1~30万の乱数なら30万面のサイコロ(!)だと考えれば、分かりやすいかもしれません。 30万個のデータだとかなり重そうなので、1~1000の乱数を1万個作ってやってみました。 A1:A10000=RANDBETWEEN(1,1000) B1:B1000=COUNTIF(A:A,ROW()) C1:C1000=10(を入力 理論的には1~1000の数字が10個ずつ出るので) 有意水準 5% で検定を行うとすれば、 =CHITEST(B1:B1000,C1:C1000) の値が、0.05以上ならOKとなります。 (余裕でOKでした) 今度は1~6万の乱数をA1:A60000に作ってみました。 集計結果↓ 出現回数,,個数,,期待値 0,,,,,,,22038,,,22072.58 1,,,,,,,22149,,,22072.95 2,,,,,,,10973,,,11036.48 3,,,,,,,,3684,,,3678.76 4,,,,,,,,966,,,,,919.66 5,,,,,,,,155,,,,,183.92 6,,,,,,,,,31,,,,,,30.65 7,,,,,,,,,,4,,,,,,,4.38 8以上,,,,,,0,,,,,,,0.61 期待値の算出は、よく分からないけど、 =BINOMDIST(出現回数,60000,1/60000,FALSE)*60000 で良いと思う。 出現0回が2万個もあって、最初はおかしいのかなと思ったが、ほぼ期待値通り。 実測個数と期待値でカイ2乗検定したら、これもOKでした。 > 2回出現する数値が数個程度かと思いきや、6回出現する数値が10個近く現れた ↑というようなことは、無いと思うのですが。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.6

#2です。お礼でおっしゃるとおりです。 >メルセンヌツイスターを利用した も判りません。 しかしこの質問コーナーではカテゴリを適当に選んで質問すべきだとは思います。エクセルは色んな分野で(それも主に計算用だけに)使われるので、その背後にはその分野特有の知識があって使う場合があり、2割ぐらいエクセルに関連があっても、数学コーナーで応えられるような人は、エクセルのことも合わせて応えられるはずだと思いました。 その背後にはその分野特有の必要知識があり、それがあると期待される読者のカテに質問されるのがベターと思います。 私は8年ぐらい多数のこのコーナーにお質問を見てきました。 経験則からいっている部分もあります。質問をする方としては、きつい表現と思いましたが。

forbiddendoll
質問者

お礼

おっしゃるとおり、ここでは最もほしかった答え、どの程度のレベルにならRand関数を使っても問題なさそうかが解決しましたが、 そこから先の、どのように評価するのかについては別に調べた方がいいということは分かりました。 あなたの言い方に正直なところカチンときてしまいましたが、適切な場所に、という点は納得しています。 あおるような返事をしてしまったことをお詫びします。 回等ありがとうございました。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

こんにちは。 >うちで使っているのはOffice2000なので そうしたら、メルセンヌツイスタ法の解決は最終手段にしてください。理由は、遅いからです。乱数生成は、セキュリティに直接関わってくる問題ですから、別に、誰かに聞かれたからというよりも、きちんと認識しておく必要はあるように思います。 上記のメ法の前に解決手段がいくつか英文の中で読んだのですが、まさか、Excel 2000だと思わなかったので、2003以降の英文しか読んでいません。もう一度英語論文等で、Excel 2000 の部分を読んでみます。締めないで、少し、時間をください。単純なVBAでも解決したような気がします。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

修正 Excel 2003/2007 [(2003には、バグが残っています)] 2003 の修正はPack1 にして、直っているそうです。 メルセンヌツイスタ法を使う必要があるかは、統計を取ってみないとはっきりしないかもしれませんが、使う用途によって決まってくるのではないでしょうか。なお、統計を取るには、Frequency 関数を使うのが一般的ですが、同関数は、配列を使いますから、数が多いと負担が大きいので、その代わりに、VBAで、同様の関数を作ったほうが良いかもしれません。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

#3の修正 #[形や]ムラが出来れば、偏りがあるのだと判定できるはずです。 形が四角形にならなかったり、・・・・

noname#99913
noname#99913
回答No.1

回答にはなりませんが…… エクセルの乱数は、単一使用を前提に作られています。ほかのセルの結果にかかわらず、各セル単独で乱数が作られます。ですので、同一値が出ることは当然あります。 それでも15桁(セル内では9桁表示)の乱数ですから、何千、何万という範囲なら、重複の可能性はかなり低いので、日常使用には支障はないと思います。どうしても重複が許せないのなら、マクロを使うのがいいでしょう。

forbiddendoll
質問者

お礼

>エクセルの乱数は、単一使用を前提に作られています。ほかのセルの結果にかかわらず、各セル単独で乱数が作られます。ですので、同一値が出ることは当然あります。 はい、承知の上です。 ですが、それでもぱっと見て(Rank関数で出現数を取り出したところ)思った以上に重複があったもので(2回出現する数値が数個程度かと思いきや、6回出現する数値が10個近く現れたものですから)、何か視覚化できないかと思いました。 まぁ本来はVBAを使用しなければいけないのでしょうが、それを利用に至る閾値が、自分自身の中でほしいので検証できないものかと思っています。

関連するQ&A

  • エクセル 関数について

    エクセルの型番と、個数が入力されているデータから、 入力されている型番の一覧リストと、各型番の個数を求めるような 関数が知りたいです。 お願いいたします。

  • ExcelのRAND関数

    ExcelのRAND関数で、0から1の間の乱数を発生させることができます。 たとえば、10万行のデータの各行に一度にRAND関数で乱数を発生させた場合(1件目に=RAND()を入力してから下方向コピーする。)、同じ値が発生することはありうるのでしょうか。 データ量が多くなるほど小数点以下の桁数が増えていくので、そのようなことは起きないようになっているのではないかと思いますが、実際はどうなのでしょうか? 

  • エクセルで1次関数

    わかるかた、教えて下さい。 エクセルで1次関数(例えば、y=2x+3)のような関数のグラフを作りたいのですが、どうゆうふうに入力すればいいのですか?

  • エクセルに関する質問

    エクセルに関する質問なんですが 統計数字データをグラフに変換して、統計データによるグラフを作成する際に 統計データの始点と終点を同じにして、重ねて比べられるようなグラフにしたいのですが 統計データの量が、比較したいAとBでは異なるため、 始点終点を同じにして、重ねて比べることができません。 何か関数とかその他の方法で、 違うデータ量のものを重ねて比較する方法はないでしょうか?

  • エクセル2003のグラフ作成について

    一度質問しましたが、私の質問が曖昧だったのでもう一度記入します。 エクセルで毎日記入しているデーターがあります。 日付を記入し個数を書いています。 日付  A  B 4/1  6  7 4/1  9  4 5月、6月・・・と続き どんどん追加されるデーターです。 このデーターをベースに、グラフを作りたいのです。 目的は、日付毎の合計を出し、月々でグラフ化したいらしいです。 縦の棒グラフがいいと思っています。 左に月で、下が個数。 このデーターを蓄積して、どの曜日が多いか、どの月が多いかを グラフをみて、統計を出したいそうです。 ピボットテーブルは却下されてしまいました。 これからも毎日入力するデーターですが、 入力すると、自動的にグラフが出来るようにしたいらしいのです。 そんなことってできるのでしょうか? ピボットは切り貼りするのが面倒らしく、 手間をかけずにデーターを入力すれば、 別シートにグラフができている……という感じです。 初心者ですが、アドバイスお願いします。

  • エクセルでグラフから出た関数Xにたいして計算したい

     エクセルでデータを入力してグラフをつくり、そこからでた関数から グラフにxのパラメーターを入力することでyの値を自動計算したいのですがどうやればよろしいのでしょうか。 よろしくおねがいします。 関数式例)  y=13.524(-0.0038X)  ()は指数

  • メルセンヌツイスターによる乱数の使い方

    メルセンヌツイスターによる乱数を生成したいのですが、下記コードにすると、mt_rand関数を呼ぶたびにシードが初期化され他乱数が生成されます。 やりたいことは、main関数で一度シード101で初期化した後は、mt_rand関数内では、初期化することなく継続した乱数を生成したいのです。 そのためa_mt_rand関数のようにすると、mtが定義されていないとなるエラーとなります。 namespaceの問題と思うのですが、色々試してみましたが、できませんでした。 どのようにすればできるでしょうか。 vc++11、windows11 使用 参考サイト C++ 乱数ライブラリ std::random の使い方 リンクはうまく貼れませんでした。 #pragma hdrstop #include <iostream> #include <stdio.h> #include <random> using namespace std; void mt_rand(void); int main(int argc, char *argv[]) { int ptr; std::mt19937 mt(101); // メルセンヌツイスターの32ビット版、引数は初期シード std::uniform_int_distribution <> rand100(0, 100); // [0, 99] 範囲の一様乱数 ptr = rand100(mt); printf("ptr=%d\n",ptr); mt_rand(); } void mt_rand(void) { int ptr=0; std::mt19937 mt(101); // メルセンヌツイスターの32ビット版、引数は初期シード std::uniform_int_distribution <> rand100(0, 100); // [0, 99] 範囲の一様乱数 ptr = rand100(mt); printf("%d\n",ptr); } void a_mt_rand(void) { int ptr=0; ptr = rand100(mt); printf("%d\n",ptr); }

  • Excelの関数について

    仕事でExcelを使った資料を作成しています。 例 1.りんご 20個 2.ばなな 50個 3.すいか 5個 このように、品目に個数を入力していく資料を作成しているのですが、たとえば入力した個数が20個以上なら入力した数値の2倍を返し、20個以下なら入力した数値の半分を返す、といった関数は作成できるものでしょうか? どうぞ知恵をお貸し下さい。

  • エクセルで関数を使い注文品別の一覧表を作るには?

    まず、元になるデータとして、縦軸1~80に発注者氏名、横軸A~Jに注文品を記した表があり、発注した個数を入力してあります。縦軸最後にはSUM関数で注文品別の合計発注数が出ています。 この表を基に、注文品別の発注者がわかる一覧表を作成したいのですが、ご教授お願いします。 VLOOKUP関数等考えてみましたが、うまくいきません。(個数を入力したセルから氏名をひっぱってくる方法が不明です)エクセル上級者の皆様、宜しくお願い致します。(アクセスがないのでエクセルでお願いします)

  • エクセルで関数を使い注文品別の一覧表を作るには?

    まず、元になるデータとして、縦軸1~80に発注者氏名、横軸A~Jに注文品を記した表があり、発注した個数を入力してあります。縦軸最後にはSUM関数で注文品別の合計発注数が出ています。 この表を基に、注文品別の発注者がわかる一覧表を作成したいのですが、ご教授お願いします。 VLOOKUP関数等考えてみましたが、うまくいきません。(個数を入力したセルから氏名をひっぱってくる方法が不明です)エクセル上級者の皆様、宜しくお願い致します。(アクセスがないのでエクセルでお願いします)

専門家に質問してみよう