NumPy:【one-hotベクトル】への変換と戻し


サマリ

  • bool型をone-hotベクトルに変換
    • .astype(np.int32)を利用
  • 文字列をone-hotベクトルに変換
    • 2回.astype(np.int)を実行
    • 文字列から数値型(floatになる)、floatからint
  • one-hotベクトルからの戻し
    • np.argmax(…, axis=1)を利用

前提

サンプルコード

bool型をone-hotベクトルに変換

bool型(True/False)データを作成

import numpy as np
x = np.random.permutation(np.arange(-1.0, 1.0, 0.1))
y = x > 0
print(y)
[False  True False  True  True  True False  True  True False False  True
  True False False False False False  True False]
  • 20個のbool型配列を作成
    • -1~1を0.1間隔で分割
    • np.arangeで生成した数値をbool型に変換している
    • np.random.permutationでTrue/Falseの出現にばらつきを出す

one-hotベクトルに変換

Y = y.astype(np.int32)
print(Y)
[0 1 0 1 1 1 0 1 1 0 0 1 1 0 0 0 0 0 1 0]
  • np.astype
    • 型変換している
    • 変換後のデータ型は「np.int32」
    • True/Falseが0/1に変換される
  • 参考
    • 以下の記事にもone-hotベクトルに変換している例あり

補足

  • y.astype(np.int)だとワーニングがでた
    • np.int32ではなくてnp.intの指定が良くないらしい
<ipython-input-352-16a9513e4a0f>:1: DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations

文字列をone-hotベクトルに変換

文字列データを作成

import numpy as np
a = np.array([2, 3], dtype='<U11')
print(a)
['2' '3']
  • 文字列のndarray(NumPy配列)を作成した
  • 想定する結果
    • 2を変換 …… [0,0,1,0,0,0,0,0,0,0]
    • 3を変換 …… [0,0,0,1,0,0,0,0,0,0]
  • 方法
    • np.eyeを使う

one-hotベクトルに変換

b = np.eye(10)[a.astype("int")]
c = b.astype(int)
print(b)
print(c)
[[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
[[0 0 1 0 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 0 0 0]]
  • np.astypeが2回登場
    • 1回目:aが文字列なので、数値型に変換
    • 2回目:np.eyeがfloat型なので、int型に変換
  • np.eyeのデータ型を確認すると
    • type(np.eye(3)[0][0])で確認
    • 「numpy.float64」を返す

one-hotベクトル数値への戻し

one-hotベクトル作成

import numpy as np
a = np.eye(10)[[4,2]]
print(a)
print(a.shape)
[[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]]
(2, 10)
  • 2行のone-hotベクトルを作成

戻し実行

b = np.argmax(a, axis=1)
print(b)
print(type(b))
[4 2]
<class 'numpy.ndarray'>
  • axis=1
    • 列方向に探しに行く
  • np.argmax(…)
    • 最も大きい(=1)値を探す
    • その時のインデックス番号を返す
  • つまり、1になっているところのインデックス番号が元の数値

補足

np.eyeの取り出し例

リスト指定

import numpy as np
a = np.eye(10)[[2,3]]
print(a)
print(a.shape)
[[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
(2, 10)
  • 2つのone-hotベクトルが取得できた
  • [2,3]
    • 引数のリスト指定は2,3と言う意味
    • np.eye(10)[2]+np.eye(10)[3]

ndarray(NumPy配列)指定

import numpy as np
b = np.eye(10)[np.array([2,3])]
print(b)
print(b.shape)
[[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
(2, 10)
  • 2つのone-hotベクトルが取得できた
  • ndarrayでもリストと同じ結果になった

同じものがある場合は?

import numpy as np
c = np.eye(10)[[8,3,3,5]]
print(c)
print(c.shape)
[[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]]
(4, 10)
  • リストを見ると3が2つ登場する
  • リストで4つ指定
    • one-hotベクトルも4つ取得


Posted by futa