「Maxima」を活用して数学の学習ロードを駆け抜けよう!
(注) MathJaxを使用しているので、 スマホでは表示に時間がかかることがあります。
モバイル利用(Android)でのメニュー選択は、 SiteMapを利用するか、 「長押し」から「新しいタブを開く」を選択してください。
■ 数式処理ソフト「Maxima」を活用した数学学習 [Map] |
| ||||
| ||||
[御案内] 「Maxima」(マキシマ)は,フリーの数式処理ソフトです. 有料の Mathematica や Maple に劣らないレベルの数式処理が可能であり, Linux,Windows,MacOSのみならず,Android版もあります. ここでは,数学学習での Maxima の活用法について解説します. | ||||
[お知らせ] スマホ(Android)版Maximaの解説本を出版しました. 計算問題やグラフの確認をするときに非常に重宝します. フリーソフトなので一度試してみてください. PC版のコマンドレファランスとしても利用できます。
| ||||
|
■数学学習での活用 |
|
以下では,「TeXmacs」+「Maxima」の画面で基本的な使い方を解説します. |
確率・統計 |
統計に特化したソフトウェアとしては,SPSS,SAS,Rなどが有名ですが, Maximaにも統計向けのパッケージが備わっています. |
|
■データの保存・読込 | ||||||||||||||||||||||||||||||
Maximaを統計解析で利用するには,まず解析すべきデータが必要です.
そのようなデータは「,」で区切って並べて [ ] で囲って表します.
このようなデータをリストといいます.
年度ごとの各種データは,
個々の年度のデータを列ベクトルとする行列で表します.
最初にサンプルデータを用意しましょう.たとえば, 気象庁による2016年の東京都の月ごとの平均気温を例に取り, 月を「month」,平均気温を「templ」とします.
以下は,(%i1)から始まっていません. 途中で入力違いがあったりしたときに最初からやり直すのは面倒なので, 半端な番号から始まっています. 途中で番号が飛んでいる箇所もありますが, 入力を間違えて上書きしたことによるものです. いずれも,気にしないでください. (%i20)では「month:[1,2,3,\(\small \cdots\),12]$」, (%i21)では「templ:[6.1, 7.2, \(\small \cdots\), 8.9]$」と定義し, それぞれ「$」により出力を抑制しています. (%i22)では,このデータを保存するフォルダーを 「dir_name:"c:/users/(中略)/"$」により指定しています. 保存や読み込みを何度か行うことになりそうなときは, あらかじめフォルダー名を適当な変数に割り当てておいた方がよいでしょう. この後にファイル名を結合するので,最後は必ず「/」で終えます. (%i23)では,データを保存するコマンド「write_data」を利用して, 「templ」のデータを保存しています. 書式は,「write_data(データ, 保存場所,'csv)」です. 第2引数では,文字列を結合するコマンド「concat」を利用して, ファイル名をフォルダー名(dir_name)とファイル名(templ.lst)を 「concat(dir_name,"templ.lst")」により結合して表しています. つまり,(%i23)では,templのデータを 「c:/users/(中略)/templ.lst」として保存したことになります. 第3引数「'csv」を付加すると「csv」形式(コンマ区切り)で保存されます. これをつけないと,半角の空白で区切られて保存されます. (%i24)では,月(month)について同様にしています. (%i25)では,正しく保存されたことを確認するため, 保存ファイルを読み込んで「a」に割り当てています. リストデータを読み込むには「read_list」を用いて 「read_list(ファイル名)」とします. ファイル名は, 「concat」を利用してフォルダー名(dir_name)と 「month.lst」を結合したものです. リストデータは,どんなに長いデータでも一つの行に保存されます. 複数の行を持つデータは行列データとして「read_matrix」で読み込む必要があります. 上図では,「month」と「templ」を行に持つ行列を, 同じ内容を持つ「a, b」を利用して「tokyo_kion」と定義し, (%i23)と同様の書式で「kion.data」として保存しています. そのデータは,2つの行をもつデータとして保存されます. (%i29)では,複数の行を持つデータを読み込むために「read_matrix」を用います. (%i29)を「read_list」により読み込むと,2つの行が繋がって1つのリストデータ として読み込まれます. 行列の行や列は,それぞれ「row」「col」により取り出すことができます. (%i30)では行列「c」の1行目を,(%i31)では3列目を,そして(%i32)では (2,4)成分を取りだしています. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
■いろいろな統計量 | ||||||||||||||||||||||||||||||
与えられた統計データから平均や分散等の基本統計量を求めるには,
統計関連の機能をまとめたパッケージ「descriptive」を読み込む必要があります.
このパッケージを利用すると,
下記のような統計量を求めることができます.
詳細は,マニュアルの
50.3節
を参照してください.
次に,行列データで考えてみましょう. 上図では,「dat2」を [u,v,w] とし, 行列「dat3」を(%i57)によりdatとdat2というリストを行に持つ行列とします. この行列に対して平均(mean)を計算すると, 各列ごとの平均が(%o58)のようにリストで返されます. つまり,行列データでは,列データに対して統計量が計算されます. したがって, リストで定義された幾つかのデータを行列にまとめて扱うときは, 個々のリストデータが列データになるようにする必要があります. 行と列を入れ替えるので,それは転置行列をとることで実現できます. (%i59)では,dat3を転置(transpose)した行列をdat4としています. そして,(%i60)でdat4の平均を求めています. 個々の列データの平均がリストで返されていることが分かります. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
■いろいろなデータ処理 | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
統計データに対しては,いろいろな統計量を計算したり,
様々な統計処理を行います.
Maximaの統計パッケージ「descriptive」を読み込むと
次のような処理を行うことができ,
新たにプログラムを組むことなく統計処理を行うことができます.
詳細は,マニュアルの
50.2節を参照してください.
統計パッケージ「descriptive」は,すでに(%i40)で読み込まれています. 最初の例として,円周率の数のリストを読み込み「pidata」とします. [shift][Enter]により改行して入力しています. 下図では,右半分は省略されています. (%o45)により,「pidata」には円周率の数が読み込まれたことが分かります. pidataは,0から9までの1桁の数からなるリストです. 最初に,これらの数が何個含まれているかを見てみましょう. 「continuous_freq(pidata, n)」により, \(\small n\) 個に区分した度数分布を調べることができます. 第2引数のデフォルトは「10」に設定されているので, 10個に区分するのであれば省略できます. 「continuous_freq」を実行すると,上図のような結果が返されます. 右側部分は省略されていますが,(%o47)の後半には [8,8,12,12,10,8,9,8,12,13]というリストが返されています. 前半の分数列のリストは,pidataをどのような階級に分けたかを表す 区分点のリストです.continuous_freqは,0〜9の数の度数を, \(\small [0,\frac9{10}], [\frac9{10},\frac95],[\frac95,\frac{27}{10}],\ldots\) という区間に分けて集計したことを示しています. それぞれの区間には,\(\small 0, 1, 2, \ldots\) という整数しか存在しないので, 結果的に個々の整数が何個あるかを数え上げたことになります. その個数のリストが後半の整数列からなるリストです. (%i48)では,5区分の場合です.\(\small [0,\frac95], [\frac95,\frac{18}{5}],\ldots\) には,それぞれ2つずつの整数があります.後半の整数列は, (%o47)の後半の整数列を2つずつ加えたものと一致しています. 連続データに対しても,同様の書式で度数分布を得ることができます. 「pidata」は離散データです.幾つかの区間に区分するのではなく, 異なるデータが単純に何個ずつあるかを知りたいときは (%i49)のように「discrete_freq」を利用します. この場合は,幾つかの区間に区分することはできません. [0,1,2,...,9]という値が何個あるかが後半のリストで表されます. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
連続データの処理 次に,連続データの場合を考えます. Maximaには,サンプルデータとして 2つのグループに分けられた年齢と血圧の行列データ「biomed.data」があります. (%i53)では,行列を読み取る「read_matrix」を利用して, (%i44)と同様の書式で読み込んで「medata」に割り当てます. (%i54)にあるように,100行からなるデータです. (%i55)では,「medata[1]」により1行目を表示しています. グループ名と年齢の後に4つの数値が並んでいます. 1行目だけ見ると最初の2つは最高血圧と最低血圧のように見えますが, (%i56)で全体を表示させると,必ずしもそうではないように思えます. マニュアルでは「4つの血圧」としか説明されていません. medataは,1列目は計算のできないカテゴリカルデータです. (%i56)で全体を眺めると,4列目と6列目には「NA」が含まれます. 「NA」は「no available」ということで,そこの値は無いことを示します. そこで,「subsample」というコマンドを用いて, カテゴリカルデータやNAを含む行を除いてデータを作り直すことにします. それは,次のような書式になります.
subsample(medata, 条件式の記述が長くなるときは,あらかじめ関数として定義しておくこともできます. 「g(x):=x[4]#NA and x[6]#AN$」 と定義しておいて, 「subsample(medata,g,2,3,4,5,6)」とすることもできます. 下図では,右半分は省略されています. 下図では,この行列を「medata2」に割り当てて,平均を計算したものです. 整数だけのデータの列では分数で表示されますが, 小数が含まれる列では小数で表示されます.右半分は省略されています. 一部の行を除外しないで,単純に1列目を除くだけであれば「transform_sample」 というコマンドを利用することもできます. 6列ある行列を5列にするには,下図の(%i69)のようにするだけです. 第2引数の [a,b,c,d,e,f] は,各列に名前をつけているだけです. そして,第3引数で変換内容を記述しています. この箇所で,列の順序を入れ替えたり,何らかの処理を施すことができます. 例えば,1列目を除くほかに, 2列目と3列目を交換,4列目は平方, そして5列目と6列目を加えたものを6列目とするには, 第3引数を [c,b,d^2,e,e+f] とします.(結果の図は省略します.) | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
血圧の数値は連続データです.その度数分布は
「continuous_freq」を利用すると得られますが,
このコマンドの引数は行列ではなくリストである必要があります.
たとえば,medata2の2列目をリストに変換するには,
「list_matrix_entries」というコマンドを使用します.
1列からなる行列であればリストに変換されます.
複数の列をもつ行列であれば,行が繋がれて一つのリストで返されます.
簡単のため,「dat4」を \[\small {\rm dat4}=\begin{pmatrix}x&u\\ y&v\\ z&w\end{pmatrix}\] として試すと,下記のようになります. なお,入出力の番号はずれています. (%o66)のように,行列に対して適用すると,行が上から順に繋がって一つのリストに なります.そこで,(%i67)では,dat4の2列目を「col(dat4,2)」により取り出して, その列に対して「list_matrix_entries」を適用しています. (%i69)では,medata2の2列目を「md2」に割り当てて, (%i70)で度数分布を得ています. 第2引数を省略すると,デフォルトの10区分の度数分布が作成されます. 上図では右側が省略されていますが,下記の内容が表示されています.
(%o70) [[18.0,81.9,145.8,209.7, デフォルトのまま作成すると,区間の左端と右端は最小値と最大値で設定されて, その範囲(range)が10等分された小区間に分割されます. 実際,個々の区間幅は \(\small 81.9-18.0=63.9\) であり, これは \(\small (657.0-18.0)/10=63.9\) の値と一致します. 両端の値を切れの良い値とすることもできます. たとえば,10〜660 の範囲で考えるには 「continuous_freq(md2,[10,660,10])」として, 第2引数に[左端, 右端, 区分数] を指定します. 次に,データが最初の小区間に集中しているので,その部分を細かく見てみましょう. たとえば,100未満のデータを取り出して,10〜100を9分割してみます. md2というリストから特定の条件を満たすリストを作成するコマンドは 「sublist」です.(%i73)では, (%i58)のsubsampleと同様の書式でラムダ関数を利用して指定しています. (%o74)では,下記の内容が表示されています. 20〜40の箇所に多くの値があります. マニュアルには血圧のデータと書かれていますが, 何か違うデータなのではないでしょうか.
(%o74) [[10,20,30,40,50,60,
(%o76) [[59.4,64.61,69.82,75.03, | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
■統計グラフ 統計パッケージ「descriptive」を読み込むと, 折れ線グラフ以外のいろいろな統計グラフを描画することができます. 詳細は,マニュアルの50.4節を参照してください. | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
折れ線グラフ 離散データの場合は,どの値がどの程度あるのかを把握する必要があります. 結果の集計は「descrete_freq」により得られますが, そのグラフ化に「plot2d」を利用することができます. 「plot2d」は連続関数のグラフばかりではなく, このような離散データのグラフも描画することができます.書式は, \(\small x\) 座標のリストをLx, それに対応する \(\small y\) 座標のリストをLyとするとき, 「plot2d([discrete, Lx, Ly])」により対応する点を線で結んだ グラフが描画されます.Lxは小さい順に並んでいる必要があります. 「pidata」を例にして折れ線グラフを描画してみましょう. 下記では,Lxを「Lx: makelist(i,i,0,9)」により割り当てています. 「makelist(式, 変数, 初期値, 終了値)」により,式で定められた値のリストが 生成されます.直接「Lx: [0,1,2,\(\small \cdots\),9]」とすることもできます. Lyは,(%o72)の2番目のリストとして割り当てています. (%i77)で \(\small y\) の範囲を指定しないと, 最小値と最大値の間のグラフが描画されます. なお,「TeXmacs+Maxima」の場合は,[Enter]で実行,[shift][Enter]で改行します. wxMaximaの場合は[shift][Enter]で実行,[Enter]で改行するので注意してください. グラフはデフォルトでは実線で結ばれますが, 点線で結んだり点を配置するだけにすることもできます. 描画のスタイルは [style, 線種] により指定します. デフォルトでは「lines」が指定されています. 点線とするには「dots」,孤立点とするのは「points」, 実線で結んで点を打つには「linespoints」とします. 下図では「linespoints」を指定しています. 点のタイプは,「point_typle」により指定することができます. 指定できるタイプは下記のものです.
Lxy:[[5,8],[0,8],[6,9],[1,8],[7,8],[2,12],[8,12],[3,12],[9,13],[4,10]]$ その上で,「plot2d([discrete,Lxy],[y,0,15],[style,points],[point_type,box])$」 としても,上記と同じ図が得られます. ただし,「style」に「points」以外を指定すると, Lxyに並んだ順に線で結ばれることになるので注意してください. 下図は,[style,linespoints] と [point_type, circle] を指定した場合です. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
棒グラフ (barplot) 離散データの場合は,どの値がどの程度あるのかを把握する必要があります. 結果の集計は「descrete_freq」により得られますが, それを棒グラフで表すには「barsplot」を利用します. (%i44) で円周率100桁の値のデータ「pidigits.data」を 「pidata」に割り当てているので,それを利用します. 単純に「barsplot(pidata)$」とすると, 下図が表示されます.引数はリストや行列です. どのような数が何個あるかが棒グラフで表示されます. 「gnuplot」を用いて描画されています. 軸のスケールを変えたり,棒の色を変えて塗りつぶすこともできます. 縦軸はデフォルトでは度数で表示されます. 相対度数にするには, 「barsplot(pidata,[frequency=relative]) とします. 度数は「absolute」,百分率は「percent」で指定します. 上図は,下図の(%i92)のコマンドで描画されています. 「fill_density」は,棒を塗りつぶすときの濃さを0〜1の間の数で指定します. グラフ描画を行う別なコマンド「draw」を利用すると, さらに細かい指定を行うこともできます. ただし,コマンド「draw」は機能が豊富すぎて簡単には説明できません. 詳細は,マニュアルの53節にある「53.2.3 Graphic options」を参照してください. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
ヒストグラム (histogram) リストか1次元行列にまとめられたデータから ヒストグラムを作成するには「histogram」を利用します. 円周率のデータ「pidata」を与えて「histogram(pidata)$」とすると, 下図が表示されます. 棒グラフと同じですが,柱は隙間無く隣り合わせになっています. 縦軸は度数になっていますが,下図にある(%i94)のように 「frequency=density」を追加すると確率密度になり 柱の面積が相対度数になります.この場合, 全面積は \(\small 1\) です. 「density」の他に,「absolute」「relative」「percent」が 指定できます.デフォルトは「absolute」になっていて度数になります. 「いろいろなデータ処理」の箇所で述べた 「continuous_freq」や「discrete_freq」を利用すると, 度数分布の区分は等分になりますが,ヒストグラムでは 「nclasses」というオプション変数を利用すると, 区分点を不均等に指定することができます. (%i95)では,nclassesに区分点の左端を指定しています. 「nclasses=5」のようにすると,5等分して表示されます. ただし, (%i95)のような区分点の指定は, 「TeXmacs+Maxima」ではエラーになりました.下図は, Maxima5.42.2が組み込まれているwxMaxima(19.01.2x)によるものです. 区分点の指定機能はMaxima5.38.1以降に追加された機能のようです. 棒グラフの場合と同様に, 「draw」を利用するとさらに細かい指定を することができ,確率密度曲線を重ね合わせることもできます. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
箱ひげ図 (boxplot) 箱ひげ図には中央値,四分位数,最小値,最大値などの情報が図示されるので, データの全体像を把握するときによく利用されます. 「boxplot」により描画することができます.引数は,リストか行列です. 下図は,「boxplot(pidata)$」とした場合の図です. 箱の横幅が広すぎるときは,「box_width」の値で調整することができます. 0〜1 の間の値で指定します. 下図は,(%i97)にあるように「box_width=0.2」としています. 引数が行列のときは,各列の箱ひげ図が図示されます. 下図は,(%i59)で定義した「medata2」の場合です. 2列目には異常値が含まれていることが分かります. おそらくは,小数点のつけ損ないによるものではないでしょうか. だとすると,この箱ひげ図からは, 2列目は最小血圧,3列目は最大血圧のデータのように思えます. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
円グラフ (piechart) 円グラフを描画するには「piechart」を用います. 引数には,リストか,行列の一つの行または列を取ることができます. 下図は,「piechart(pidata)$」の図です. 図が枠内で大きすぎるときは,縦と横の範囲を xrange, yrange を利用して 調整するか,または円の半径を 「pit_radius=a」により指定します. デフォルトの半径は \(\small 1\) です. カラーチャートは描画する度に自動的に変更されます. 自分で指定するには,色のリストを 「sector_colors」に指定します. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
散布図 (scatterplot) 2変量の間の関係を見るには,散布図を描いてみるのが有効です. 散布図は「scatterplot」により描画することができます. 箱ひげ図をみると, データとして血圧のデータ (medata) は相互関係を見るのに適さないので, 風速のデータ (wind.data) を利用することにします. 以下では入出力番号をリセットしたので,パッケージ「descriptive」を 読み込むところから始めることにします. そして,(%i2)により風速のデータを「wind」に割り当てます. 「wind」は(100,5)型の行列です.(%i3)では各列の平均を見ています. (%i4)により箱ひげ図を描画してみて, その状況から4番目と5番目のデータの散布図を見ることにしましょう. 下図は,(%i4)による,5箇所の気象台の風速データの箱ひげ図です. scatterplotに5列からなる行列「wind」の2つの列を引き渡すために, 「submatrix」を利用します. このコマンドの書式は,たとえば 「submatrix(i1,i2,行列データ,j1,j2,j3)」とすると, 行列データから \(\small i_1, i_2\) 行と,\(\small j_1, j_2, j_3\) 列を 除いた行列が返されます. \(\small i_1, i_2\) を省略すると後半の列だけが除かれ, \(\small j_1, j_2, j_3\) を省略すると前半の行だけが除かれます. そこで,上図にある(%i5)により,1〜3列を除いた行列を「wind45」とします. 散布図は,(%i7)により次のように描画されます. 散布する点のタイプは,「point_type」 により変更することができます. (%i8)のように「circle」を指定すると下図が描画されます. なお,Maximaの古いバージョンでは,「point_type」のタイプによっては エラーになる場合があるので注意してください. その場合は,最新版のMaximaを利用すべきです. 2つの列に限定しないで引き渡すと,相互の列どおしの散布図が一気に作成されます. たとえば,(%i9)のように4列と5列を除いた行列を引き渡すと, 下図のように各列の相互関係が行列形式でまとめて表示されます. 画面の拡大図は,こちらを参照してください. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
確率密度曲線 ヒストグラム「histogram」は 他のグラフと重ね合わせることができませんが, 「draw」パッケージを利用すると, ヒストグラムに 確率密度曲線を重ね描きすることができます. 詳しくは「確率分布」の箇所で 解説しますが, Maximaでは20以上の確率分布を扱うことができ,それぞれの分布について 確率密度関数や分布関数が登録されています. また,その確率分布にしたがう乱数も 発生させることができます. ヒストグラム作成の元になるリストデータを alist, 確率密度関数を f(x) とすると, 次の書式で2つのグラフを重ね合わせることができます.
draw2d( ヒストグラムは度数を表示しません. 縦軸を度数にするには「frequency」に「absolute」を指定します. しかし,それがデフォルトの設定なので, 「frequency」を指定しなければ縦軸は自動的に度数で表示されます. それに確率密度曲線を同時に表示させるため, 度数のグラフからヒストグラムを得るときの逆の計算を行い, 確率密度関数にリストの大きさと階級幅を掛けます. (%i11)では,いったん発生させた乱数のリストを「alist」に 割り当てて,その範囲(最大値\(\small -\)最小値)を(%i12)で求めています. (%i13)で20階級に分けたときの階級幅は「haba/20」になります. (%i13)の中で「random_normal」が何度も呼び出されると, その度に新たな乱数が発生して範囲も異なることになるので, ここでは(%i11)で発生させた乱数のリストを固定して考えています. グラフは下図のようになり,縦軸が度数になっています. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
■いろいろな乱数 | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
統計の学習では,「サイコロを100回振る」などを
自分で試してみることも必要ですが,実際にやるのは面倒です.
そのようなときは「乱数」を利用するとよいでしょう.
Maximaはいろいろな確率分布にしたがう乱数を発生させることができます.
詳細は,マニュアルの「52. distrib」を参照してください.
ここでは,疑似乱数,二項乱数,正規乱数についてのみ解説します. この項目を試すには,確率分布に関するパッケージ「distrib」を 読み込む必要があります.
| ||||||||||||||||||||||||||||||
疑似乱数 (random) 引数 x に対して「random(x)」は, x が正の整数のときは 0 から x-1 までの整数を, 正の浮動小数点のときは x よりも小さい非負の浮動小数点を返します. 「random」はデフォルトの機能なので,パッケージを読み込む必要はありあません. 上図では,引数が整数,浮動小数点,負の整数の場合です. 値が1個だけ返されます.この後に同じコマンドを実行すると, 新たな乱数が返されます.結果が同じとは限りません. 「乱数」とはいっても,何らかの数学的性質に基づいて計算された値が返されます. その意味で疑似乱数といいます. 乱数発生のアルゴリズムには,日本の松本眞・西村択士により考案された メルセンヌ・ツイスター という方式(MT19937)が用いられています. これを用いて,たとえばサイコロを15回振ったときの数をシミュレートするには, 「random(6)」を15回実行します. 0〜5の値が返されるので,その値に 1 を加えることで1〜6の値が得られます. 実際には,個別に行うのではなく, (%i6)や(%i7)のように「makelist」を利用して15個の要素を持つリストを作成します. (%i7)は(%i6)に 1 を加えているわけではなく, 新たに発生した乱数に 1 を加えたものです. どの目が出る確率も同じようになっていることを確認するため, 振る回数を増やしてみます. または,たとえば「dice(n)」を 「makelist(random(6)+1,i,1,n)$」により定めて, dice(100)などで参照することもできます. 上図では,それぞれ百回,千回,1万回のリストを生成しています. このようなときは,末尾を「$」として出力を抑制しておきます. 下図では,それぞれの度数分布 (discrete_freq) を求めています. そのコマンドはパッケージ「descriptive」に含まれているので, 最初にそれを読み込んでいます. なお,出力の右側は省略されています. これをグラフ化してみましょう. 「plot2d」を利用した折れ線グラフを作成するため, 最初に \(\small x\) 座標と \(\small y\) 座標のリストを 下図の(%i19)〜(%i22)のように定めます. 離散データのグラフを描画する「plot2d」の書式では [discrete, x座標のリスト, y座標のリスト] を入力することになります. 記述が長いので, それぞれ(%i23)〜(%i25)のようにあらかじめ割り当てておきます. リストの長さ(length)で割って相互比較ができるようにしています. 以上の準備のもとで,それぞれの折れ線グラフは次のように描画されます. それぞれは \(\small 1/6=0.166\cdots\) に近づくはずなので, \(\small y\) 軸の範囲は \(\small [0, 0.3]\) としています. 描画のタイルは「linespoints」を指定して,点を打つようにしました. 色や点の記号は自動的に割り振られます. 回数が増えるほど,一定値に近づいていくことが見て取れます. このように,どの値の出る確率も同じなのが一様分布です.次に,浮動小数点で同様のことを確かめてみましょう. 下図の(%i27)(%i28)では,「random(1.0)」により0〜1の浮動小数点の リストを作成しています.(%i29)(%i30)では, 連続データの場合の度数分布 (continuous_freq) を求めています. 第2引数の [0,1,10] は, 両端に0と1を持つようにして10区分するようにしています. この指定をしないと,出力される区分点は半端な浮動小数点で表示されます. (%o30)の1番目のリストは,11個の値を持ち2番目のリストと個数が合いません. そこで,(%i31)では,0.1刻みで10個の値を持つリストを作成しています. Ly1, Ly2の値が階級の中央にくるようにするため,(%i34)(%i35)では \(\small x\) 座標を 0.05 だけずらしてます. 以上により,下図のグラフが描画されます. 1千回と1万回だけの比較ですが,乱数の発生回数が大きいほど一定値の 0.1 に 近づいていることが分かります. 上記は,2つのグラフの比較をするために折れ線グラフで示しましたが, 一つのリストの分布を見るだけであれば「histogram」が 利用できます.下図は,histogram(float2,frequency=relative) とした場合です. 「float2」が呼び出されるたびに新たな乱数が発生するので, 図を表示させるごとに異なるグラフになります. 上記の折れ線グラフをヒストグラムにしたわけではありません. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
乱数の種(シード) (random_state) いろいろなシミュレーションをするとき, 乱数生成器に同じ乱数を発生させたいときがあるかもしれません. 乱数は,「乱数の種(シード)」と呼ばれる一つの数をもとにして 生成されます. その値を,Maximaでは「ランダム・ステート (random_state)」と呼んでおり, それを操作する関数として「make_random_state」と「set_random_state」があります. 「make_random_state」は次のような機能を持っています. いずれも,「ランダム・ステート」を新たに作成したり,表示したりするだけです. 乱数生成器の状態に変化はありません.
| ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
二項乱数 (random_binomial) 二項分布Binom(n,p)は,ある試行で事象Aの起きる確率を \(\small p\) とするとき, その試行を \(\small n\) 回繰り返して事象Aが何回起きたかを表す分布です. たとえば,「サイコロを100回振って1の目が何回出たか?」という数は二項分布に したがいます.「random_binomial(n,p)」は,この二項分布にしたがう乱数を 1個返します.「random_binomial(n,p,m)」とすると, m個からなるリストを返します.
前の項目の疑似乱数「random」はデフォルトの機能ですが,
二項分布にしたがう乱数を発生させるには確率分布に関するパッケージ「distrb」を
読み込む必要があります.また,発生させた後の度数分布を調べるために,
統計パッケージ「descriptive」も読み込んでおきます.
Ly(n):=discrete_freq(sampbin(n))[2]/length(sampbin(n))$ 度数のリストは,度数分布(discrete_freq)の2番目のリストで返されます. それを取り出して,元データである乱数リスト(sampbin(n))の大きさ(length)で 割って基準化しています. その上で,下図の(%i13)のように定めておきます. 以上のように定めた上で,表示するグラフの \(\small x, y\) の範囲や 描画スタイルを(%i15)のように定めるとグラフが描画されます. ただし,ここでは,Lxを [0,1,2,3,4,5] としているので, sampbin(n)に6回出た場合が含まれると Lx と Ly の成分の個数が合わないので, plot2dでエラーが生じます. そのエラーを回避するには,Lxは0〜6として, Lyに6回出た場合の度数が含まれない場合は Lyの最後に0を追加するように定める必要があります. しかし,それを記述するにはMaximaのプログラミングが必要になります. plot2dを実行するごとにsampbin(n)により新たな乱数リストが作成されるので, 何度かやっていると6回が出ないケースになってグラフが描画されるでしょう. nをもっと大きな数で試したい場合は,Lxは0〜6にしておくのがよいでしょう.二項分布の確率を表す関数と重ね合わせることもできます. その確率を表す関数は「pdf_binomial(x,n,p)」であり,次の式で定義されます. \[\small \binom{n}{x}p^x(1-p)^{n-x}\] この関数は,\(\small x\) は 0〜n の整数のときだけ値を持ち, それ以外の値のときは 0 が返されます.なお, plot2dで描画するたびに新たに発生させた乱数によるグラフが描画されるので, (%i15)によるグラフとは一致しません. 下図では,青のグラフが二項分布です.Grbin(n)の n を増やしていくと, この青いグラフに近づいていきます. なお,書式に誤りがないのにplot2dでエラーが出るときは,何度か試してください. n をもっと大きな値で試すときは,6回出た場合も含まれるように, Lx, Ly, Lybinは作り直す必要があります. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
正規乱数 (random_normal) 正規分布は,いろいろな場面で現れる重要な確率分布です. 平均 \(\small m\),標準偏差 \(\small s\) の正規分布にしたがう乱数は 「random_normal(m,s)」により得られます. \(\small n\) 個の正規乱数を成分を持つリストを得るには 「random_normal(m,s,n)」とします. この乱数を利用するには,パッケージ「distrib」が必要です. なお,正規乱数を発生させるアルゴリズムには ボックス=ミューラー法が用いられています. 上図は,すでに「distrib」と「descriptive」を読込済みとして, (%i32)では \(\small m=0, s=1\) の正規乱数を1個得ています. (%i33)では \(\small m=50, s=10\) の正規乱数を12個得て, 「truncate」により小数部分を切り捨てて整数のリストを得ています.
次に,二項乱数と同様にして,発生させた正規乱数の度数分布を作成して
グラフにしてみましょう.
下図の(%i41)では, \(\small m=0, s=1\) の正規乱数の \(\small n\) 個の
リストをsampnorm(n)としています.
(%i42)では,そのリストデータの
区間 \(\small [-3, 3]\) を12等分した場合の
度数分布を作成してnormdosu(n)としています.
「continuous_freq」を利用すると,
連続データの度数分布を作成することができます.
第2引数の [-3, 3, 12] は,区分点の両端を \(\small -3, 3\) にして,
その区間を12等分するように指定するためのものです.
小区間の幅は 6/12=1/2=0.5 となります.
区間を指定しないと,sampnorm(n)の最小値と最大値の間が12等分されて,
両端や区分点が半端な数値になります.
「Maxima」は世界中のボランティアにより保守されており,
このような不具合が修正されたり新しい機能が追加されたりして
新しいバージョンになっていきます.
「TeXmacs+Maxima」で記述は合っているはずなのに「エラー」が生じるときは,
最新版のMaximaでやり直してみるとよいでしょう.
| ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
逆関数法による乱数の発生 Maximaに登録されている乱数の他に, いろいろな確率分布にしたがう乱数を自分で発生させることができます. 具体的には,次の手順でその確率分布にしたがう乱数が発生します.
上記の値が想定する確率分布にしたがうのは,以下の理由によります.
| ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
確率密度関数の定番問題として,「次の関数が確率密度関数となるように,
定数の値を定めよ.」という問題があります.
たとえば,次の関数を考えてみましょう.
\[\small f(x)=\begin{cases} 1-ax& (0\leq x\leq 2)\\
\quad 0 & (x\lt 0, 2\lt x)\end{cases}\]
この関数が確率密度関数になるのは,
\[\small \int_0^2(1-ax)\,dx=2-2a=1\]
のときなので \(\small a=\frac12\) のときです.
このとき,累積分布関数 \(\small F(x)\) は,\(\small 0\leq x\leq 1\) のときは
\[\small F(x)=\int_{0}^x\left(1-\frac12t\right)\,dt
=x-\frac14{x^2}\]
となるので,\(\small u=x-\frac14x^2\) の逆関数を求めて,
\(\small x=2-2\sqrt{1-u}\) が得られます.したがって,
累積分布関数の逆関数は,\(\small 0\leq u\leq 1\) のとき,
\[\small F^{-1}(u)=2-2\sqrt{1-u}\]
となります.
下図は,以上のことをMaximaを利用して計算したものです. (%i3)では,直前で得られた \(\small a\) の値を, 直接 1/2 として入力してもよいのですが, リスト内の最初の要素(%[1])の右辺(rhs)を取り出することで利用しています. (%i5)では,直前に得られたリストの第1要素の右辺を Finv(u) として定義しています. 次に,この Finv(u) に [0,1] 上の一様分布をあてはめると, 確率密度関数が \(\small 1-\frac12x~(0\leq x\leq 1)\) であるような 分布になることを確かめてみましょう. 最初に,記述統計の計算を行うパッケージ「descriptive」を読み込んでおきます. (%i8)では,Finv(random(1.0)) により, [0,1] 上の一様乱数の累積分布関数の逆関数 \(\small F^{-1}(u)\) の値を求め, その値が \(\small n\) 個からなるリストを作成するコマンドを定義しています. (%i9)では,要素数が10000個の場合のヒストグラムを, 縦軸を確率密度に,柱の本数を20本に指定して描画しています. 下図が描画されます.要素数が少ないと凸凹が生じます. 本数を指定しないと,デフォルトの数である10本で描画されます. このヒストグラムに確率密度関数のグラフを重ねるには, 「draw2d」を利用します.パッケージ「draw」を読み込むと, (%i11)により確率密度関数のグラフと重ね描きされます. その描画コマンドの中でリストを発生させているので, (%i9)のヒストグラムとは異なります. | ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
■推定・検定 | ||||||||||||||||||||||||||||||
推定・検定を行うには,それに関する一連の手続きを納めたパッケージ「stats」を
読み込む必要があります.
パッケージ「stats」を読み込むと,統計計算に必要な
記述統計「descriptive」,確率分布「distrib」,そして
結果を表示させる「inference_result」のパッケージも自動的に読み込まれます.
具体的な使用法は,マニュアルの「83. Stats」を参照してください. 簡単な具体例とともに, 各種のコマンドの使用法や出力される結果の見方について解説されています. ただし,コマンドの使い方が解説されているだけであり,検定の内容が解説されて いるわけではありません.利用しようとする検定がどのようなものであるかは, 統計の教科書で理解した上で使用する必要があります. 以下に,このパッケージに登録されている主なコマンドを列記します.
| ||||||||||||||||||||||||||||||
|