=f'(x)\)これを式2とします。\\\end{eqnarray}近似計算なので、極限は一回無視します。詳細は数値計算法についての専門書をみた方が早いです。\\\end{eqnarray}移項して整理します。y\)はx(t)における情報です(tは任意の時刻)。\)が決まったことになります。f(x)を求めるのがニュートン法です。このニュートン法は、数値計算の近似解法の中で一番雑な方法です。数値計算をやる上で大事なエッセンスが詰まっていますので、教科書の最初に書かれています。適当に微分方程式を解くプログラムでも書いて解を比較して見れば面白いと思います。ついでに以前自分は「オイラー法」と「ルンゲクッタ法」の解の比較についての記事を書いたので、気になる方は目を通してみてください。コメントを残すpythonで線形最適化問題を解いてみたスポンサードリンクpythonで線形最適化問題を解いたので記録しておきます。参考にしたサイトはこちら。関数の最適化問題を解くのに知っておかないといけないのは「ラグランジュの未定乗数法」です。自然言語処理等の機械学習の分野ではこれを知るのと知らないのでは、論文の理解度も全く変わってくるそうです。こちらの文献にも書いております。0\)の時、未定数\(\lambda\)を考えると以下が成り立つ。\right.\end{eqnarray}以上の三式を満たす(x,y,\(\lambda\))を求める方法が「ラグランジュの未定乗数法」です。これが制約条件の元での「最適解」ということです。別途記事にして書こうと思いますが、この式はナイーブベイズやサポートヴェクターマシン等の最適問題を解く際に必須になる式です。スポンサードリンクpythonを用いて線形最適問題を解く。pythonで線形計画問題を解く場合、pulpというライブラリを用います。opt」というライブラリを用いるみたいです。今回はpulpの紹介のみで終わりにします。pulp今回の線形最適化問題を示します。0.5\)以上の条件でpulpを用いて計算します。目的関数と制約条件を定義しています。problem.solve()で解きます。0.0と結果が出ました。軽くラグランジュの未定乗数法の復習と、pulpの勉強ができました。次は非線形問題の最適化についてpythonで勉強していきます。いう本にレヴィ分布という確率分布が出てきました。gnuplot使って描画して見るかと思いやったので書いときます。誰得なのか不明ですが笑レヴィ分布とは?wikipediaに『レヴィ分布は、安定な分布のなかでも解析表現可能な確率密度関数を有する数少ない分布のひとつである。』と紹介されています。聞いたけど、正規分布とかコーシー分布と並んで紹介されているということは結構使えそうな確率分布です。以下の式で表現されます。0.5,1,2,4,6,8\(\)と変化させてグラフ描画しました。凡例を表示plt.savefig("graph.png")plt.show()グラフは以下になります。描画に用いたコードは以下です。“ファイル名.gp”で実行すれば描けます。み同じに見えますが、c=1とc=0.5のときの形が大分違います。書いた方が綺麗に書けそうです。それにnp.arrayでxの刻み幅も指定できるので、粗いグラフから滑らかなグラフまで速攻で書けそうですし。gnuplotはどうやって関数描いてるのか不明です。xの刻み幅の指定方法もよくわかりません。したら刻み幅を指定する方法があって、細かく指定してやればpythonのように滑らかで綺麗なグラフが書けるのかもしれません。簡単な関数のグラフ書くならpythonの方が良さそうです。ライブラリも豊富ですしね。今回使ってませんが、listとか使って各グラフ(各c)の設定とかを保持しておいてそのlistの全要素に対して関数を描画するようにしたらもっとコードも短くできますね。コメントを残すダイクストラ法についてまとめるスポンサードリンクアルゴリズムクイックリファレンスで2点間の最短ルートを求める「ダイクストラ法」について勉強したのでまとめます。参考ドキュメントはこちらです。ウルトラ参考になりました。応用的には飛行機の最短経路、電車の最短ルートの検索、カーナビとかの経路探索にも使われているアルゴリズムだろう。日常的におせわになっているアルゴリズムと言っても過言ではない。ダイクストラ法(単一始点の最短経路アルゴリズム)今回解く問題は以下の問題です。参考サイトに一つノードを加えました。開始点(スタート)は1、終了点(ゴール)は6。上の図のような重み(距離)が与えられているときの1→6の最短経路を解きます。ダイクストラ法の解説ここでは一般的な説明ではなく、上記の解法の説明をします。一般論を述べるより具体的な問題から入った方が後のアルゴリズムも理解しやすいかと思います。スタート地点を1番とする(当然)地点1から地点(2と3)に移動できるので、地点2と3の重みを更新します。(まだ地点2と地点3への最短経路は決定していません)番号の小さい方(ここでは2)に移動します。(これが初めての移動なので、地点2への最短経路は1→2で決定です)地点2から移動できる地点(3,4,6)があるので、重みを更新します。3,4,6のうち最小番号の3に移動します。3には1→3の重み80が存在しますが、今辿ってきた経路1→2→3が70なのでこちらの方が近いということになります。3の重みを70で更新します。ここまでの状態を図に示します。決定項目(最短経路)が青で未決定(現状では決定できない)事項が黄緑です。地点3から移動できるのは4と5なので、重みを更新します。すると今回の経路(1→2→3→4)での重みは70+10=80ですが、すでにある経路(1→2→4)の方が重みが小さいのでこちらが最短経路ということになります。今回は重みは更新しません。3から移動できる最小番号(地点4)に行きます。地点4から移動できるのは5と6です。今回の経路(1→2→3→4)の重みで更新すると、地点5での重みは4→5が30なので95、地点6での重みは4→6が10なので75となります。現時点での仮の経路は以下です。→6)となるのが自明なのですが、練習のため最後までやりましょう。地点4からいける最小番号は5なので、地点5に移動。地点5はこれが初めての重みなので95で更新する。地点5から移動できる地点は地点6のみ。今回の経路(1→2→4→5)で重みを更新すると5→6が15なので95+15で110となる。ある経路(1→2→4→6)の重みが75なので今回は更新されずに最短経路が1→2→4→6で決定する。このような解き方がダイクストラ法です。別名「貪欲法」と言います。残っている値(この場合は接点の数)が最小のものを選ぶという意味で貪欲です。ダイクストラ法は重みが非負数の場合のみ使えます。非負数の場合はベルマン-フォード法を用います。これについては別途説明します。コードを書いてみる全体をいくつかの部分に分けて説明します。0隣接行列を定義します。隣接行列についてはこちらを参考にしてください。ここでは2重リストを用いて隣接行列の成分を表しています。接点数をlen()関数で定義しています。未探索の接点をlist(range(node_num))で定義。これで未探索接点の初期条件(0,1,2,3,4,5)を設定します。[math.inf]は正の無限大を表すので全ての接点の初期距離を∞(到着可能か不明)とする。移動前の接点を[-1]*node_numで定義します。接点0までの距離は開始点なので0とする。+1次に最小のインデックス番号を取得する部分の関数です。移動できる点がなくなった場合(接点1の場合2も3も計算した場合)、もうないのでelseとなり次の接点番号2へ移る。target_min_indexここはダイクストラ法の根本部分です。!=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]として更新する。最後に一つ前の接点に到達する接点のリストを更新する。!=0:print(str(previous_node+1)+"<-",end='')else:print(str(previous_node+1))previous_node=previous_nodes[previous_node]print("-----距離-----")print(distance[node_num-1])正直ここが全然わかりません。previous_nodeとprevious_nodesの違いがいまいち。二行目のnode_num-1もなんの意味が。node_numは接点数のはず。接点数は一定で6-1で5のはず。したらelse文とか意味ないじゃんて思ってしまう。751234------経路------6<-4<-2<-1-----距離-----75上で手計算で解いた時と同じ結果になります。自分で0から書いたコードではないので、どこで何が起きているのか不明です。ブラックボックスの状態ですね。_)m今回はオライリーの「アルゴリズムクイックリファレンス」とgoogle先生を頼りに勉強しました。この本は初心者には嫌われてますが、これを理解するための入門書チラ見しながらとかgoogle先生に聞きながらなら、かろうじて読めるかなと行ったところ。論文読んでるような感じです。時間はかかるけど、しっかり理解しながら読めば気付いた時にはそこらへんの入門書程度なら余裕だなって感じの知識はつきます。難しめの本から入りたいという変わり者にはおすすめです。Neubigの自然言語処理チュートリアル(第一回)スポンサードリンク自然言語処理100本ノックがだんだんと難しくなり、やる気が失せてきたので復習がてらグラムニュービッグさんのチュートリアルに手を出してみることにしました。全部で14問あるみたいで、今日はその第一問目です。解法ファイルを一行ずつ読み込み、split()で単語にわけるCounter()関数でカウントcounter.most_common()で辞書型にプリントって感じでしょうか。11なぜかthisが別々にカウントされている。2本当は上のようになるはず。スポンサードリンク原因これだと、同じ単語が来てもそれを同じと判断することができずに別々にカウントしてしまう。同じ行内ならば同じ単語は追加のものとして加算してくれるみたいだが、行が違うと同じ単語でもダメみたいです。2行目に読み込んだpenは2回にカウントされている。1counter.most_common()はご丁寧に回数の多い順に出力してくれるみたいです。Counter()関数はかなり使いどころが多いのと、extendの使い方についても知ることができました。appendにして何回も詰まりました笑。そんなに難しくない問題なのにこの程度で詰まるなんて、まだまだですね。Neubigさんのチュートリアル第一回目を終わりにします。コメントを残すRで学ぶグラフ理論(第3回)スポンサードリンク前回の続きをしていこうと思います。グラフ理論というより厳密にはネットワーク分析ですね笑。いう細かいことはほっておいて笑。用いるデータは前回と変わりません。前回説明した密度以外にどんなものがあるか述べていきます。推移性わかりやすくいうと無向グラフの場合、グラフ全体のうち閉ループになっている割合です。私が参考にしている本では「自分の友達の友達は自分の友達である割合」と言っています。人的ネットワークでいうと三角関係の割合というところでしょうか。下のような隣接行列で表されるグラフであれば、3-2-1とか、1-4-5-の関係の割合です。隣接行列Aを2乗する。→理由は不明だが、算出された各成分は長さ2の経路の数に等しくなる。1で求めた行列A2の成分の和を求める。→長さ2の経路の数2で求めたもののうち、両端の頂点に直接関係のあるものは、A2とAの成分積の成分の総和となるよって推移性は以下の式で定義される。0sum(A2*A)/sum(A2)12から14行目はグラフ表示する部分ですので、推移性を求める場合はいらないです。計算すると0.428571410.4285714となります。スポンサードリンク密度との比較ここで前回のデータ(高校生の友人関係のネットワークデータ)を用いて、推移性を求めてみようと思います。0.3802817gtrans()は推移性を求める関数です。1957年秋に比べ、1958年春の方が推移性は下がっています。友人関係の密度(繋がり)は増加しても、三角関係というか(共通の知り合い)は増えないみたいです。友達の紹介を通じて得られる友人よりも、個人個人で新たに繋がりを増やす人の方が多いということでしょうか。ネットワーク分析で事象の背景が見えてくるのは本当に面白いですね。コメントを残すRで学ぶグラフ理論(第2回)スポンサードリンク今回は、ネットワーク構造の指標の一つである密度について述べていきます。対象データ今回用いた対象データは、Colemanによる73人の男子高校生の友人ネットワークです。付き合いのある相手をあげてもらい、その方向のデータです。ここでは1957年のと1958年の春の2回分のネットワークデータについてグラフ化します。前回(Rを用いてグラフ理論を学んでみる。)では、コンソールに直接コードを入力しましたが、非効率なので今回はスクリプトを作成し、それを実行するようにしました。右上側にあるRunボタンだと、スクリプトが一行ずつ読み込まれるようです。そのため最後まで読み込むには連打しなければいけません。それよりも右側にあるSourceボタンを押してください。するとスクリプトファイルの内容を一発で実行できます。作成したスクリプトは、以下です。1958")gplot()でプロットするグラフを定義します。最初のgplotは同じ生徒が同じ位置に来るように配置を定義するためのものです。試しに以下のコードを実行します。1)生成されるグラフは以下のようになります。(m,n))は画面をm行n列に分割して画像を生成するという意味。最後にgplotで先ほど定義した「友人関係の配置を定義したもの」を用いて、ネットワーク関係(相互関係)のみ更新して終わりです。作成されるグラフは以下になります。以上の例でみたネットワークの密度を求める前に、密度の定義について述べて行きます。密度の定義グラフにおいてはることができる全ての辺の数に対する、実際の辺の比率です。単純グラフの場合、頂点数nの無向グラフにおいて可能な辺の数は最大で、\(\frac{n(n-1)}{2}\)であるから、グラフに含まれる辺の数をmとすると、密度は次のように定義されます。4}&=&0.6\end{eqnarray}となります。\frac{m}{n(n-1)}\end{eqnarray}となります。Rを用いて密度を計算しよう!といってもsnaパッケージにあるgden()コマンドを用いるだけです。0.05003805密度が1958年の春の方が大きい、すなわちグラフが密になっているので、高校生のネットワークが増えているということでしょう。時間が経てば、同コミュニティ内のネットワークが深まるのは経験則と照らし合わせても、異論はないと思います。ネットワーク分析における指標は他にもあるので、次回以降それらについても述べていこうと思います。コメントを残すRを用いてグラフ理論を学んでみる。スポンサードリンクグラフ理論をRを使って勉強してみよう思います。今回は簡単なグラフを可視化するところから。その前に環境構築(mac)Rは簡単にインストールできます。いうxcode,androidアプリでいうandroid-studio)のインストール方法について述べて行きます。homebrewはあらじかじめインストールしておいてください。rかなり時間かかります。辛抱強く待ちましょう。caskroom/cask次にインストールコマンド。rstudioインストールが終了するとターミナルに以下が表示されると思います。installed!以下のコマンドを実行するかlaunchpad等から直接起動しましょう。/Applications/RStudio.app以上で準備は終わりです。グラフ理論の細かいことはほっといて...とりあえずR-studioで遊びましょう。起動すると以下のような画面になると思います。左側がコンソールでここにコマンド打ち込んで行きます。スクリプトを作成し、それを読み込ませることもできるみたいですが、それはまた今度で。R-studioでグラフ理論を学ぼう!(超基本)グラフを作成するために以下のコマンドを実行しライブラリを読み込みます。>library(igraph)ahuグラフ1>library(igraph)ahuグラフグラフ理論ではグラフをGで定義し、ここでは以下のように定義します。g<-erdos.renyi.game(10,9/10,directed=T)erdos.renyi.game()の意味は現時点では不明だが、呪文だと思って使うことにします。()内の数字は、10がグラフ理論における隣接行列の行の数(正方行列)。9/10が一列または一行における成分が「1」の数となる最大値。これはランダム生成なので、必ずしも列、行内に1が9個出現する訳ではありません。最後は有向グラフという意味。無向グラフの場合はいりません。xそうすると以下のような隣接行列が作成されます。.次にエッジリストです。隣接行列に比べ、コンパクトになるので、大規模かつ疎なグラフに対して用いられます以下のコマンドを実行。y実行するとわかりますが、グラフが密であるため、成分が多くなり、かなり行数が多くなります。今回はスペース省略のため割愛させていただきます。可視化!>plot(g,layout=layout.circle)1>plot(g,layout=layout.circle)layout.()関数はグラフを描画するためのコマンドで、色々な種類のグラフを作成するために多くの関数が用意されています。今回は円で表示したいのでcircleにする。R-studioの右下の欄に以下が表示されれば、おっけーです。ついでにlayout.circleをlayout.sphereにしてみる。以上で、R-studioでのグラフ理論の遊びを終わりにします。隣接行列やエッジリストの説明など今回は省きましたが、R-studioを使って遊びながら書いて行きます。グラフ理論Rを用いてグラフ理論を学んでみる。コメントを残すゲーム理論とトルエルスポンサードリンク今回は「トルエル」という例を用いて「ゲーム理論」について述べていきます。「ゲーム理論」とは?もともとボードゲームを戦略的に戦うところから生まれたものです。この言葉の生みの親は、マンハッタン計画にも参画していた物理学者「ジョン・フォン・ノイマン」です。ゲーム理論の研究者は、冷戦時代に戦略に関する助言を求められたこともあるそうです。ノイマンは実際に、戦略開発としてアメリカに雇われています。現在では、株式市場の研究に大きな意味を持っています。最善の戦略を慎重に実行することは問題解決によく似ていることから、ゲーム理論は人工知能の研究者にとってもかなり興味深いテーマであると言えるでしょう。「トルエル」とは「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は残った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{eqnarray}a^{2}&=&b^{2}+c^{2}-2bc\cos\theta\\a^{2}&=&b^{2}+c^{2}\end{eqnarray}\(-2bc\cos\theta\)があるかどうかということが、みてわかると思います。0\)の時であることがわかります。90°\)はどんな三角形かというと、直角三角形ですね。「三平方の定理」は「余弦定理」の一部、「三平方の定理」を全ての\(\theta\)に対して拡張したものが「余弦定理」であることがわかりますね。授業で習うときは全く別々の公式のように習うかもしれませんが、実は余弦定理を知っていれば、ピタゴラスの定理を覚える必要はないのです。式の向こうに見える関係に注目すると数学は楽しくなるので、こういう思考を大切にしていきましょう。