インデックス配列の置き換え

表題だけではよくわからないが、以下のような場合に使う。

たとえばクラス分類のためのターゲットのデータセットが以下のように与えられているとする。

このとき、クラス0~2に対応する以下のような名前で表現したターゲット配列を得ることができるというもの。

順を追って考えてみるのに、まずnames配列から一つの要素を取り出す。

配列の要素をリストとすると、そのリストの要素をインデックスとみなして、インデックスに対応する元の配列の要素を並べた配列を返す。結果はリストではなくndarray。

配列の要素を配列としても同じように動作する。

これより、クラス分類のターゲット配列などが与えられたときに、これを番号ではなくクラス名などの配列に変換することができる。

なお、インデックス配列が2次元の場合は結果の配列も2次元となる。

 

ndarray – ブロードキャスト

1次元の場合

以下の配列を元の配列とする。

数値は1次元配列に拡張されて、要素ごとに演算される。

要素が1つの配列(リスト)は同じサイズの配列に拡張されて、要素ごとに演算される。

2次元の場合

以下の配列を元の配列とする。

数値は2次元配列に拡張されて、要素ごとに計算される。

要素が一つの配列は2次元に拡張されて、要素ごとに計算される。

列数と同じ要素数の1次元配列(リスト)は、同じ列数の2次元配列に拡張されて計算される。

行数と同じ要素数の列ベクトルは、同じ行数の2次元配列に拡張されて計算される。

 

Python/pyplot – 決定境界の描き方

決定境界の描き方として以前ループを使った泥臭い方法を考えたが、meshgridを使って数行で書けることを知ったのでまとめ。

結論としては以下の19~25行目の8行で、以下の手順で決定境界を書いている。

  1. 2つの特徴量の全領域をカバーする値をnumpy.linspace()で生成
  2. numpy.meshgrid()で2次元のグリッドに変換
  3. 各特徴量のメッシュグリッドを1次元に変形し、縦2列の配列化
  4. prediction()メソッドでその配列の各座標に対応する予測値を計算(結果は1次元配列)
  5. 結果の配列をmeshgridと同じ形状の2次元配列に変形
  6. contour/contourf()で決定境界を描画

具体的な変数の変形状況を要素数4の少ない例で示すと以下の通り。

まず、2つの特徴量の範囲の数列を生成する。

それらの数列を、meshgridで2次元配列に変形する。

予測モデルに与える変数は各特徴量を列とする2次元配列とする必要があるので、まず上の2次元配列をそれぞれ1次元に変形。この変形では、2次元配列の各行を連ねていった1行の配列を列ベクトルにした形になる。

次に2つの列ベクトルを横方向に並べて、総計算データ数×特徴量数(2)の2次元配列とする。

この配列の各座標に対する予測値を、predict()メソッドで予測。この結果は、1次元化されたf0やf1と同じく、2次元のmeshgridの各行を横に連ねたものになっている。

この結果を、meshgrid化されたf0(またはf1)と同じ形に変形。これで予測結果がf0×f1平面の各座標に対応した予測値の2次元配列となっている。

この結果を使い、contour()/contourf()で決定境界あるいは決定領域を描画。

ここでlevelsの指定は以下のようにしている。

まずcontour()の場合、ドキュメンテーションには“If an int n, use n data intervals; i.e. draw n+1 contour lines. The level heights are automatically chosen.”と書かれているので、levels=0と指定すると0+1本の線が描かれると考えたが以下のような警告が出て線の位置がずれた。

そこでlevels=[0.5]と2つのクラス値0と1の間をとると適切に表示される。

なおcontourf()のときは、levels=1として2つの領域が描かれる。

 

 

ndarray.min/max – 配列の最小値と最大値

ndarray.min()/max()は、配列の最小値/最大値を返すメソッド。また、ndarray.argmin()/argmax()は、最小/最大の要素のインデックスを配列で返す。

なお、numpy.amin()/amax()numpy.argmin()/argmax()もほぼ同じ動作をする。

以下、次の配列で動作を確認する。

引数に何も指定しない場合、配列の全要素の中の最小値と最大値を返す。このとき、argmin/argmaxでは、配列をreshape(-1)で1次元化したときのインデックスが返される。

引数にaxis=0を指定すると、各列ベクトルの行方向の中での最小値/最大値を返す。以下の例では、各列ごとの最小値/最大値とそれらに対する行インデックスが配列で返されている。

axis=0の0を2次元配列の引数の位置と考えると0番目の引数で、各列における行の位置を表す。これはargmin/argmaxの意味合いと符合する。

引数にaxis=1を指定すると、各行ベクトルの列方向の中での最小値/最大値を返す。以下の例では、各行ごとの最小値/最大値とそれらに対する列インデックスが配列で返されている。

axis=1の1を2次元配列の引数の位置と考えると1番目の引数で、各行における列の位置を表す。これはargmin/argmaxの意味合いと符合する。

 

pyplot – グラフ要素のフォントサイズ

グラフ全体のフォントサイズ

pyplot.rcParams()で基準のフォントサイズを変更。デフォルトはfont.size=12。以下は全体のフォントサイズを大きくした例。

個別要素のフォントサイズ

タイトル、軸ラベル、軸目盛、凡例について個別にフォントサイズを指定した例。

 

Python – 多重ループの一重化

概要

以下のような二重ループを、一重ループで実現する方法。

内包表記による方法

内包表記の中で二重ループを回し、1つのリストを生成する。

itertools.productによる方法

itertoolsライブラリーにあるproduct()は、引数のリストの各要素の直積を要素とするリストを返す。

 

numpy – r_とc_

概要

numpy.r_ / numpy.c_は配列を結合するオブジェクト。r_は縦方向に配列を結合し、c_は横方向に配列を結合する。vstack() / hstack()linspace()と似たような使い方ができるが、少し癖がある。

  • 配列と数値を混在させて結合できる
  • スライスでステップ数やか分割数を指定して数列をつくれる
  • vstack()hstack()の代わりに使える

vstack()hstack()と同じように使う。

r_について

numpy.r_で2次元配列に1行だけ追加するとき、1次元配列のままだ”次元が異なる”とエラー。素直にvstack()を使った方がよい。

r_のデフォルトで1次元配列同士を結合すると、単に横方向に結合される。配列と要素が混在していてもok。文字列の配列も結合できるが、文字列要素が混在するとエラーになる。

スライスを使って数列を生成。

3つ目の引数に'j'をつけてnumpy.linspace()と同様の動作。このときは終了値が含まれる。

c_について

numpy.c_で2次元配列にその行数と同じ要素数の1次元配列を結合すると、列ベクトルとみなされて1列追加される。hstack()が1次元配列を列ベクトル化する必要があるのに比べると手軽。

さらに要素数が同じ1次元配列同士を結合すると、それらが列ベクトルとみなされて結合される。

空の配列に対して順次列ベクトルを追加する場合には、empty(n, 0, dtype=type)を準備する。

 

numpy.percentile()~パーセンタイル

numpy.percentile()は、与えた配列から指定したパーセンタイル値を計算する。

percentile(a, q)
a:パーセンタイルを計算する元の配列。
q:パーセンタイル値、または配列。パーセンタイル値は0~100で、百分率表示であることに注意。1次元配列を指定すると、各要素のパーセンタイル値に相当する値が同じサイズの配列で返される。

以下は実行例。パーセンタイル値が要素の間になる場合は内挿される。

元の配列はソートされていなくてもよい。

 

パーセンタイル値を配列で指定した場合。

95%両側信頼区間の場合、以下のように計算できる。

 

ndarray – 整数の乱数配列を作る

重複しない乱数配列

0~n−1の整数を重複なくランダムに並べた配列。arange()で数列を作り、それをnumpy.randomモジュールのshuffle()permutation()でシャッフルする。shuffle()は元の配列を書き換え、permutation()は元の配列を書き換えずにシャッフル後の新たな配列を返す。permutation(n)で整数を指定すると、0 ~n-1がランダムに並んだ配列を返す。

“permutation”は置換の意味で、配列中の2要素を何回かランダムに置換していくイメージ(同じ単語が順列の意味でも使われる)。

m~n−1の乱数配列は、arange(m, n)をシャッフル。

重複を許す乱数配列

0~m−1の範囲で重複を許してn個の要素を持つ配列を生成する方法。

簡単なのはnumpy.randomchoice()でサイズを指定する方法。

m~n−1の範囲の乱数配列は、arange(m, n)choice()を使う。

 

numpy.varやnumpy.stdの自由度

numpy.varnumpy.stdは、それぞれ配列で与えたデータの分散、標準偏差を返す。

numpy.var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=<no value>)

numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False)

この関数の引数にddofというのがあり、numpyのドキュメントには以下のように書かれている。

ddof : int, optional
Means Delta Degrees of Freedom. The divisor used in calculations is N – ddof, where N represents the number of elements. By default ddof is zero.

つまり、分散の計算の際にN−ddofで割っていて、デフォルトではddof=0なので、母分散及び母集団の標準偏差として計算される。

ddof=1とすると不偏分散およびその平方根として計算される。

 

ただし正確には、不偏分散の平方根は母集団の標準偏差の不偏推定量ではないらしい。