モンテカルロ法で円周率を計算する。(python)



スポンサードリンク

モンテカルロ法の勉強の一貫として、円周率を導出するプログラムを書いたので載せます。

今回はこちらの本を用いて勉強しました。数値計算の基本的な手法について網羅されております。

 

 

モンテカルロ法とは?

乱数を用いてサンプル分布の情報を得る手法の総称です。乱数を用いていれば、その乱数の分布がなんであろうが、全てモンテカルロ法になるわけです。

かなり広義な意味です。さらにその乱数の確率分布に正規分布とかベルヌーイ分布、コーシー分布、指数分布とかがあるわけです。

円周率の計算

使用したコードです。

 

擬似乱数を用いていますので、プログラムを動かすたびに違う結果になります。

ちなみに500回円周率を計算した時の平均値は3.141804799999997になりました。グラフから見てもあってそうです。

さすがにデータ点10000点×500回なので、ほぼ真の値に収束しています。

計算回数を増やせば増やすほど、値が収束する現象は「大数の法則」として知られています。

 


 

各回数での円周率の計算値がどれくらい真の値からずれているのか、ずれに頻度はどれくらいかを視覚化するためヒストグラムを作成しました。

横軸が(円周率-計算で求めた円周率)、縦軸が各範囲における頻度です。今回はビン数を40(x軸の範囲内で何等分するか)にしました。

 



スポンサードリンク

乱数プロットの画像描画

モンテカルロ法のwiki風な画像を作成しました。試しにデータ点が10000と1000の時で計算しました。左側がデータ点10000、右側がデータ点1000の時です。半径1の円内にあるものが赤、それ以外が青です。

 

  

 

 

 

 

 

 

上の図を作成するために使用したコードを載せます。

 

本当はwikiみたいにデータ点数を変えた時のプロット描画を見たかったので、for文を回して各データ点数ごとにグラフを作成し、それを動画にするプログラムも書きたかったのですが、疲れたので今回はここまでにします。

wiki風動画作成は別途記事にしようと思います。

記事が役に立ったらシェア!

ニュートン法の復習<実はすごい簡単>



スポンサードリンク

ニュートン法

微分方程式を解く際に使う数値計算の近似解法です。ここでは簡単のため一変数関数について述べます。変数が増えても根本原理は変わらず、プログラミングする際も機械的に変数の数を増やすだけなので、特に難しくはないです。

\( y =f(x)\)とします。これを式①とします。

  1. まず微分します。
\(\frac{dy}{dx} =f'(x)\)

これを式②とします。

2. 微分の定義に従って ①を計算します

\begin{eqnarray}
\frac{dy}{dx} = \lim_{x \to \infty} \frac{f(x + \Delta x) – f(x)}{(x +\Delta x)- \Delta x} \\
\end{eqnarray}

近似計算なので、極限は一回無視します。詳細は数値計算法についての専門書をみた方が早いです。

両辺に\((x +\Delta x)- \Delta x \)をかけます

\begin{eqnarray}
\frac{\Delta y}{\Delta x}((x +\Delta x)- \Delta x) = f(x + \Delta x) – f(x) \\
\end{eqnarray}

移項して整理します。

\begin{eqnarray}
f(x + \Delta x) &=&\frac{\Delta y}{\Delta x}((x +\Delta x) – \Delta x ) + f(x)\\
&=& \frac{\Delta y}{\Delta x} x + f(x) \\
\end{eqnarray}

\( f(x),\Delta x , \Delta y\)はx(t)における情報です(tは任意の時刻)。

よって\(x(t)\)のみの情報で\(f(x + \Delta x) \)が決まったことになります。


こうして任意のxについてy = f(x)を求めるのがニュートン法です。

そしてこのニュートン法は、数値計算の近似解法の中で一番雑な方法です。まず研究では使いません。しかし数値計算をやる上で大事なエッセンスが詰まっていますので、教科書の最初に書かれています。

適当に微分方程式を解くプログラムでも書いて解を比較して見れば面白いと思います。

ついでに以前自分は「オイラー法」と「ルンゲクッタ法」の解の比較についての記事を書いたので、気になる方は目を通してみてください。



スポンサードリンク

記事が役に立ったらシェア!

pythonで線形最適化問題を解いてみた



スポンサードリンク

pythonで線形最適化問題を解いたので記録しておきます。

参考にしたサイトはこちら。

ラグランジュの未定乗数法

関数の最適化問題を解くのに知っておかないといけないのは「ラグランジュの未定乗数法」です。

自然言語処理等の機械学習の分野ではこれを知るのと知らないのでは、論文の理解度も全く変わってくるそうです。

こちらの文献にも書いております。

 

条件

  • 目的関数(最適化したい関数)をf(x,y)とする
  • 制約条件(境界条件)をg(x,y)=0とする
  • \(\frac{\partial f}{\partial x}\neq 0\)
  • \(\frac{\partial f}{\partial y}\neq 0\)

の時、未定数\(\lambda\)を考えると以下が成り立つ。
\begin{eqnarray}
\left\{ \begin{array}{ll}
\frac{\partial f}{\partial x}+\lambda\frac{\partial g}{\partial x} = 0 \\
\frac{\partial f}{\partial y}+\lambda\frac{\partial g}{\partial y} = 0 \\
g(x,y) = 0
\end{array} \right.
\end{eqnarray}

以上の三式を満たす(x,y,\(\lambda\))を求める方法が「ラグランジュの未定乗数法」です。

そしてこれが制約条件の元での「最適解」ということです。

別途記事にして書こうと思いますが、この式はナイーブベイズやサポートヴェクターマシン等の最適問題を解く際に必須になる式です。

 

 



スポンサードリンク

pythonを用いて線形最適問題を解く。

pythonで線形計画問題を解く場合、pulpというライブラリを用います。非線形の場合は「open opt」というライブラリを用いるみたいです。今回はpulpの紹介のみで終わりにします。

まずはpulpをpipでインストール

今回の線形最適化問題を示します。

  • 目的関数 \(2x +3 y + 10\)
  • 制約条件 \( x + y = 0.5\)

以上の条件でpulpを用いて計算します。

problem で目的関数と制約条件を定義しています。problem.solve()で解きます。

実行結果

と結果が出ました。x = 0.5 ,y = 0 がどうやら最適解のようです。軽くラグランジュの未定乗数法の復習と、pulpの勉強ができました。
次は非線形問題の最適化についてpythonで勉強していきます。



スポンサードリンク

 

 

 

記事が役に立ったらシェア!

レビィ分布をグラフ描画して見た(python&gnuplot)



スポンサードリンク

今読んでいる本「ウォール街の物理学者 (ハヤカワ・ノンフィクション文庫)」という本にレヴィ分布という確率分布が出てきました。

初めて聞いたのでpython やらgnuplot使って描画して見るかと思いやったので書いときます。誰得なのか不明ですが笑

レヴィ分布とは?

wikipediaに『レヴィ分布は、安定な分布のなかでも解析表現可能な確率密度関数を有する数少ない分布のひとつである。』と紹介されています。

初めて聞いたけど、正規分布とかコーシー分布と並んで紹介されているということは結構使えそうな確率分布です。

以下の式で表現されます。
\begin{eqnarray}
f(x;\mu,c)=\sqrt{\frac{c}{2\pi}} \frac{e^\frac{-c}{2(x-\mu)}}{(x-\mu)^{3/2}}
\end{eqnarray}

ここでは[/latex]\mu = 0,  c = 0.5,1,2,4,6,8\(\)と変化させてグラフ描画しました。

pythonの場合

描画に用いたコード

グラフは以下になります。



スポンサードリンク

gnuplotの場合

描画に用いたコードは以下です。

gnuplotの場合はファイル名.gpで上記を保存し、gnuplot “ファイル名.gp”で実行すれば描けます。

ぱっとみ同じに見えますが、c=1とc=0.5のときの形が大分違います。gnuplotの関数指定のところを見ても特に違っている様子はないんですけどねー笑

 

比較してわかったこと

gnuplotで書くよりもpython で書いた方が綺麗に書けそうです。それにnp.arrayでxの刻み幅も指定できるので、粗いグラフから滑らかなグラフまで速攻で書けそうですし。

gnuplotはどうやって関数描いてるのか不明です。xの刻み幅の指定方法もよくわかりません。もしかしたら刻み幅を指定する方法があって、細かく指定してやればpythonのように滑らかで綺麗なグラフが書けるのかもしれません。

 


簡単な関数のグラフ書くならpythonの方が良さそうです。ライブラリも豊富ですしね。今回使ってませんが、listとか使って各グラフ(各c)の設定とかを保持しておいてそのlistの全要素に対して関数を描画するようにしたらもっとコードも短くできますね。

 

記事が役に立ったらシェア!

ダイクストラ法についてまとめる



スポンサードリンク

アルゴリズムクイックリファレンスで2点間の最短ルートを求める「ダイクストラ法」について勉強したのでまとめます。

参考ドキュメントはこちらです。ウルトラ参考になりました。

 

応用的には飛行機の最短経路、電車の最短ルートの検索、カーナビとかの経路探索にも使われているアルゴリズムだろう。日常的におせわになっているアルゴリズムと言っても過言ではない。

ダイクストラ法(単一始点の最短経路アルゴリズム)

今回解く問題は以下の問題です。参考サイトに一つノードを加えました。

開始点(スタート)は1、終了点(ゴール)は6。上の図のような重み(距離)が与えられているときの1→6の最短経路を解きます。

ダイクストラ法の解説

ここでは一般的な説明ではなく、上記の解法の説明をします。いきなり一般論を述べるより具体的な問題から入った方が後のアルゴリズムも理解しやすいかと思います。

  1. スタート地点を1番とする(当然)
  2. 地点1から地点(2と3)に移動できるので、地点2と3の重みを更新します。(まだ地点2と地点3への最短経路は決定していません)
  3. 番号の小さい方(ここでは2)に移動します。(これが初めての移動なので、地点2への最短経路は1→2で決定です)
  4. 地点2から移動できる地点(3,4,6)があるので、重みを更新します。
  5. 3,4,6のうち最小番号の3に移動します。
  6. すでに3には1→3の重み80が存在しますが、今辿ってきた経路1→2→3が70なのでこちらの方が近いということになります。なので3の重みを70で更新します。とりあえずここまでの状態を図に示します。決定項目(最短経路)が青で未決定(現状では決定できない)事項が黄緑です。
  7. 最初の図に戻ります。地点3から移動できるのは4と5なので、重みを更新します。そうすると今回の経路(1→2→3→4)での重みは70+10=80ですが、すでにある経路(1→2→4)の方が重みが小さいのでこちらが最短経路ということになります。なので今回は重みは更新しません。
  8. そして3から移動できる最小番号(地点4)に行きます。
  9. 地点4から移動できるのは5と6です。今回の経路(1→2→3→4)の重みで更新すると、地点5での重みは4→5が30なので95、地点6での重みは4→6が10なので75となります。現時点での仮の経路は以下です。
  10. この時点で最小経路は(1→2→4 →6)となるのが自明なのですが、練習のため最後までやりましょう。地点4からいける最小番号は5なので、地点5に移動。
  11. 地点5はこれが初めての重みなので95で更新する。地点5から移動できる地点は地点6のみ。今回の経路(1→2→4→5)で重みを更新すると5→6が15なので95+15で110となる。すでにある経路(1→2→4→6)の重みが75なので今回は更新されずに最短経路が1→2→4→6で決定する。

このような解き方がダイクストラ法です。別名「貪欲法」と言います。残っている値(この場合は接点の数)が最小のものを選ぶという意味で貪欲です。なおダイクストラ法は重みが非負数の場合のみ使えます。非負数の場合はベルマン-フォード法を用います。これについては別途説明します。

コードを書いてみる

全体をいくつかの部分に分けて説明します。


隣接行列を定義します。隣接行列についてはこちらを参考にしてください。ここでは2重リストを用いて隣接行列の成分を表しています。

接点数をlen()関数で定義しています。未探索の接点をlist(range(node_num))で定義。これで未探索接点の初期条件(0,1,2,3,4,5)を設定します。

[math.inf]は正の無限大を表すので全ての接点の初期距離を∞(到着可能か不明)とする。

移動前の接点を[-1]*node_numで定義します。

接点0までの距離は開始点なので0とする。


次に最小のインデックス番号を取得する部分の関数です。

接点番号の初期値は0なのでstart = 0

indexに未探索ノード(ある地点から移動できる点)がある場合、index (接点)はそのまま。移動できる点がなくなった場合(接点1の場合2も3も計算した場合)、もうないのでelseとなり次の接点番号2へ移る。


ここはダイクストラ法の根本部分です。

while文は未探索接点がなくなるまで繰り返します(len(unserched_nodes) !=0)

最初の接点間の重みは無限大(math.inf)と定義する。ここから、上記で説明した1番にたどり着く(プログラミングは前提条件与えるのにやっとですね笑)

for文は未探索ノードにおけるループです。posible_min_distance=distance[node_index]の部分で最短距離が小さければ更新します。

そして先ほど説明したget_target_min_index関数で接点から次の接点へ移動する際の最小番号を更新する。(移動できる場合は更新せずにそのまま)

そして、この点は探索終了なので未探索接点(unserched_node)から削除する(remove(target_min_index))

経路の重み計算にはその時の接点番号を用いる(ターゲットから伸びる接点)のでtarget_edgeとして定義する。

そしてif文内で過去に更新した重み(距離)よりも小さければ(重みが少なければ)それをdistance[index]として更新する。

最後に一つ前の接点に到達する接点のリストを更新する。


正直ここが全然わかりません。

previous_nodeとprevious_nodesの違いがいまいち。二行目のnode_num-1もなんの意味が。

node_numは接点数のはず。接点数は一定で6-1で5のはず。そしたらelse文とか意味ないじゃんて思ってしまう。

難しい。

実行結果

上で手計算で解いた時と同じ結果になります。しかし自分で0から書いたコードではないので、どこで何が起きているのか不明です。まさにブラックボックスの状態ですね。

以上、一応ダイクストラ法のアルゴリズムについて勉強してみましたがやはりコードに落としこむことができないm(_ _)m

今回はオライリーの「アルゴリズムクイックリファレンス」とgoogle先生を頼りに勉強しました。

正直この本は初心者には嫌われてますが、これを理解するための入門書チラ見しながらとかgoogle先生に聞きながらなら、かろうじて読めるかなと行ったところ。論文読んでるような感じです。時間はかかるけど、しっかり理解しながら読めば気付いた時にはそこらへんの入門書程度なら余裕だなって感じの知識はつきます。

たまには難しめの本から入りたいという変わり者にはおすすめです。



スポンサードリンク

 

 

 

 

記事が役に立ったらシェア!

Rで学ぶグラフ理論(第3回)



スポンサードリンク

前回の続きをしていこうと思います。グラフ理論というより厳密にはネットワーク分析ですね笑。まあそういう細かいことはほっておいて笑。

用いるデータは前回と変わりません。

ネットワーク構造の諸批評

前回説明した密度以外にどんなものがあるか述べていきます。

推移性

わかりやすくいうと無向グラフの場合、グラフ全体のうち閉ループになっている割合です。

私が参考にしている本では「自分の友達の友達は自分の友達である割合」と言っています。人的ネットワークでいうと三角関係の割合というところでしょうか。

下のような隣接行列で表されるグラフであれば、3-2-1とか、1-4-5-の関係の割合です。

具体的な計算方法

  1. 隣接行列Aを2乗する。→理由は不明だが、算出された各成分は長さ2の経路の数に等しくなる。
  2. 1で求めた行列A2の成分の和を求める。→長さ2の経路の数
  3. 2で求めたもののうち、両端の頂点に直接関係のあるものは、A2とAの成分積の成分の総和となる

よって推移性は以下の式で定義される。
\begin{eqnarray}
R = \frac{\sum A_{ij}}{\sum A2_{ij}}
\end{eqnarray}

Rでの計算方法

12から14行目はグラフ表示する部分ですので、推移性を求める場合はいらないです。

計算すると

となります。


スポンサードリンク

密度との比較

ここで前回のデータ(高校生の友人関係のネットワークデータ)を用いて、推移性を求めてみようと思います。

gtrans()は推移性を求める関数です。

1957年秋に比べ、1958年春の方が推移性は下がっています。友人関係の密度(繋がり)は増加しても、三角関係というか(共通の知り合い)は増えないみたいです。

友達の紹介を通じて得られる友人よりも、個人個人で新たに繋がりを増やす人の方が多いということでしょうか。

ネットワーク分析で事象の背景が見えてくるのは本当に面白いですね。



スポンサードリンク

 

 

 

記事が役に立ったらシェア!

ゲーム理論とトルエル

 



スポンサードリンク

今回は「トルエル」という例を用いて「ゲーム理論」について述べていきます。

「ゲーム理論」とは?

もともとボードゲームを戦略的に戦うところから生まれたものです。この言葉の生みの親は、マンハッタン計画にも参画していた物理学者「ジョン・フォン・ノイマン」です。

ゲーム理論の研究者は、冷戦時代に戦略に関する助言を求められたこともあるそうです。ノイマンは実際に、戦略開発としてアメリカに雇われています

現在では、株式市場の研究に大きな意味を持っています。また最善の戦略を慎重に実行することは問題解決によく似ていることから、ゲーム理論は人工知能の研究者にとってもかなり興味深いテーマであると言えるでしょう。

トルエルへの応用

「トルエル」とは「3人で行う決闘のようなもの」です。

トルエルの手順を説明していきます。

1、A,B,Cの3人がいます、Aが拳銃を打ち、人に当たる確率は\(\frac{1}{3}\),Bが拳銃をうち、人に当たる確率は\(\frac{2}{3}\),Cが拳銃をうち人に当たる確率は100%=\(\frac{3}{3}\)です。

2、3人は三角形になるように立っていて、拳銃を打つ順番は、拳銃の下手な順です。すなわち、A→B→Cの順番です。

3、一発当たったら人は死ぬとします。このとき、最初に打つAは誰に向かって発砲すれば良いか?

文章だけではわかりづらいと思うので図を示します。

直感的には、Aは命中率100%のCの向かって打つのが良いと思われるかもしれませんが、答えは「どちらにも打たない(空に向かって打つ)」が正解です。

これがAが生き残る最善の策です。

空に向かって発砲したとしましょう。次に発砲するのはBです。Bは誰に向かって打つかというと間違いなくCです。なぜならCからすると脅威なのはAとBのうち、Bだからです(命中率の高い方)。

なので、Bは「次にCが銃口を向けてくるのは俺だ」となりますので、Bは一刻も早くCを消しにいきます笑

BがCに発砲し、外れる場合と当たる場合があります。順番に見ていきましょう。


スポンサードリンク

 

  • 外れる場合

次に打つのはCですので、CはBに向かって発砲し、Bは死にます。

そしてAは一番最初に死ぬのは免れるわけです。そして次はAです。Aは残ったCに向かって打つしかありません。

  • 当たる場合

Cは死にます。そしてこの場合もAは一番最初に死ぬことは免れるわけです。

そして次に打つのはAですので、AはBに向かって発砲すれば良いわけです。

 

どちらの場合も一番最初に死ぬのはAではなく、BかCです。そして実はAにとっては「3人でやる決闘の一番最初に打つ」のではなく、「2人でやる決闘の一番最初に打つ」という状態に持っていけるわけです。

一見、一番拳銃の下手なAが不利なように見えますが、戦略的に戦うと実はそうではないということがわかります。こういう風な考え方が「ゲーム理論」です。

「ゲーム理論」を応用した問題は他にもたくさんありますので、調べて見てください。もちろん、後々ここでも記事にしていきます。



スポンサードリンク

記事が役に立ったらシェア!

三平方の定理と余弦定理の関係



スポンサードリンク

先日、僕が教えてもらったことを書こうかなと。

今回は「余弦定理と三平方の定理」の関係です。三平方の定理は実はいらない?ということに気づかされました。

 

余弦定理とは?

軽く復習します。

以下のような三角形があったとします。

この時に
\begin{equation}
a^{2}=b^{2}+c^{2}-2bc\cos\theta
\end{equation}
が成り立ちます。要は三角形の6つの情報(辺三つ、角度三つ)のうち三つがわかれば他は全部計算で求まるということです。

これが余弦定理です。


スポンサードリンク

ピタゴラスの定理(三平方の定理)

次にピタゴラスの定理です。これについては以前に記事に書いたので詳細はそちらを参考にしてください。

>>>ピタゴラスの定理

ここでは以下の三角形の時の公式を書いておきます。

\begin{equation}
a^{2}=b^{2}+c^{2}
\end{equation}

 

余弦定理と三平方の定理の関係

本題に入ります。

二つの式を並べて確認して見ましょう。

\begin{eqnarray}
a^{2}&=&b^{2}+c^{2}-2bc\cos\theta\\
a^{2}&=&b^{2}+c^{2}
\end{eqnarray}

\(-2bc\cos\theta\)があるかどうかということが、みてわかると思います。

では、この\(-2bc\cos\theta\)が0になるときはどんな時でしょうか?

bとcは0になり得ないので、\(\cos\theta = 0\)の時であることがわかります。

要するに\(\theta = 90°\)の時です。

\(\theta = 90°\)はどんな三角形かというと、直角三角形ですね。

すなわち「三平方の定理」は「余弦定理」の一部、「三平方の定理」を全ての\(\theta\)に対して拡張したものが「余弦定理」であることがわかりますね。

授業で習うときは全く別々の公式のように習うかもしれませんが、実は余弦定理を知っていれば、ピタゴラスの定理を覚える必要はないのです。

式の向こうに見える関係に注目すると数学は楽しくなるので、こういう思考を大切にしていきましょう。


スポンサードリンク

記事が役に立ったらシェア!

パーセプトロンのアルゴリズム(pythonその2)



スポンサードリンク

前回までで、パーセプトロンの理論的な背景と、そのデータセットの用意のところまではすでに説明し終えたので、その続きから説明していきます。

>>>全体のソースコードがみたい方は前回の記事をみてください。

>>>パーセプトロンの理論的な背景についての記事

パーセプトロンのアルゴリズム(確率的勾配降下法)

w0,w1,w2の初期値は全て0で始めていますね。

biasの部分は少し説明する必要があります。


スポンサードリンク

バイアス項とは何か?

バイアス項とはベクトル\(\phi_n\)の第一成分です。

ベクトル\(\phi_n\)の説明については以下の記事を読んでください

>>>パーセプロトンのアルゴリズム(線形分離)

求める直線の方程式を
\begin{eqnarray}
f(x,y) = w_{0}+w_{1}x+w_{2}y
\end{eqnarray}
とおきましたが、
\begin{eqnarray}
f(x,y) = cw_{0}+w_{1}x+w_{2}y
\end{eqnarray}
と仮定することもできます。この場合、ベクトル\(\phi_{n}\)のバイアス項は「c(任意定数)」になります。

ベクトルwの更新には\(t_{n}\phi_{n}\)が用いられますので、w0は±cだけ更新されることになります。

なので、このcを適切に選択すれば、アルゴリズムの収束速度を改善できるということになります。

上のコードではこのcの値(biasの部分)をデータに含まれる全てのxn,ynの平均値を使っています。

なぜ平均値をとるのか

データの値(xn,yn)がとてつもなく大きい数(1000とか10000)で、平均的に10000とかの場合、勾配降下法のアルゴリズムより、w1,w2も10000程度の大きさで一気に増減します。

もしバイアス項が”1″ならw0の値は更新されても±1でしか変化しないことになります。

w0の変化がw1,w2の変化に比べて小さすぎるので、正しいwが得られるのに時間がかかります。

そこでバイアス項もデータの平均的な値にすることで、w0の変化率もw1,w2と同等にしてやろうという意味です。

Iteration

Iterationはベクトルwの更新回数です。今回は30回です。

ここはそんなに説明する必要はないと思います。

前々回の記事で説明した理論的な計算をおこなっている部分です。要は「更新」作業の一番の根幹の部分です。

判定誤差の計算

分散が大きい場合と小さい場合での比較として、エラー率を計算しています。

前にも述べましたが、分散が小さい場合は綺麗に直線で二つのデータ群を分割できますが、分散が大きいと二つのデータ群に重なる領域が生まれますので、直線で分割することができなくなります。

30回更新し直しても、直線で分割したエリアとは違うエリアにデータが含まれている場合、それをエラー率として表示するようにしています。

結果の表示、2種類の分散での実行

ここはグラフを作るだけですので、特に問題ないと思います。

最後のfor文以降で、”2種類の分散”でこれまでの全ての計算を実行するようにしています。

忘れたかもしれませんがVariance(分散)は最初に配列で設定していますね。


スポンサードリンク

計算結果

上が計算結果です。

分散が小さい方(左上)は綺麗に直線で分割できます。その証拠にw0,w1,w2の更新も7回目くらいで収束しているのがわかります(左上)。

分散が大きい方(右上)は更新を30回やっても直線で綺麗に分割することはできず、エラー率6パーセントになっています。

実際、●のある領域に×のデータが入り混んでいます。エラーが出ているということは、30回更新してもw0,w1,w2は収束していないことが右下のグラフからわかります。

以上、パーセプトロンのアルゴリズムについて理論と実際にコードを用いてどのように計算されているのか述べてきました。

データセットの用意は乱数を用いているので、計算するたびに結果が異なります。更新回数や、データ数等変えて遊んでみてください。

 

 

記事が役に立ったらシェア!

パーセプトロンのアルゴリズム(python編)



スポンサードリンク

ここではパーセプトロンについて実際のプログラムを、pythonの数理統計関数の説明していきながら述べていきます。

計算に用いたプログラム

 

最初のパラメータのところは問題ないと思います。

Variancesdで2種類の分散を用意しているのは、分散が大きい時と小さい時で、分類結果を比較するためです。

分散が大きい時は、二つのデータ群が多かれ少なかれ、重なる領域が生じ、綺麗に二つのデータ群を直線で分割できなくなります。

前ページで言えば、総誤差ΣEは小さくすることはできるが、0にならないということになります。

分散が小さい時は二つのデータ群はそれぞれの中心座標からあまり離れることなく、データが分布するので、領域が明確になり、直線で二つのデータ群を分割できます。

前ページで言えば誤差関数=0の状態です。

データセットの用意に関して

  • varianceは標本から分散を推定する場合に用いるコマンドです。

「分散」とはデータの中心からのバラツキの度合いです。

ここでは、関数の変数として使われていますので、注意してください。

上記は二重にネストした配列を作成しています。


スポンサードリンク

  • multivariate_normal

このコマンドは

のように用いると多次元正規分布の乱数を生成してくれるみたいです。

よくわからないので、途中でreturnの前にprint df1を挟んで確認してみます。

Dateframeコマンドで、マトリクスを作成するみたいです。

columnsでインデックスの指定、さらにマトリクスに行とインデックスを追加する場合には別で

と書いていますね。

  • pd.concat

よくわからないのでprint

linuxのcatコマンドからきているのでしょう。df1とdf2を縦に連結しています。

もう一つ下のdfも不明なので、これまたprint.

df.reindex(np.random.permutationでランダムに並び替えています。

その次のreset_index(drop=True)で左端のインデックスのみ数字順に並び替えています。

以降ではパーセプトロンのアルゴリズムの部分と計算結果について述べていきます。

>>>続きはこちら。



スポンサードリンク

記事が役に立ったらシェア!