トップ ノート
782   2020-01-15 (水) 10:09:21

One Hot エンコーディング 2020-01-14

One-Hotベクトル

%matplotlib inline
# 特徴量エンジニアリングとしてのOne-Hotベクトルの必要性と、。。。。
# https://qiita.com/koshian2/items/debdaf10a859e5953cfa

import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
import matplotlib.pyplot as plt

np.random.seed(72)
# カテゴリー0は花が大きい、1は極めて小さい、2は普通
L = np.concatenate((np.random.normal(20.0, 2.0, size=50),
                    np.random.normal(1.0, 0.1, size=50),
                    np.random.normal(5.0, 1.0, size=50))).reshape(-1,1)
C = np.concatenate((np.repeat(0, 50), np.repeat(1, 50), np.repeat(2, 50))).reshape(-1,1)
# Lはデータ (20, 2)の正規分布50個と、(1, 0.1)の正規分布50個と、(5,1)を50個
# Cは対応するカテゴリー [0, 1, 2] ミソは1と2がデータの大きさとは逆順(順序尺度でない、名義尺度)
# もしCのカテゴリー付けを[0, 2, 1]とすると(順序尺度)、下のOne-Hotと同じになる。

regressor = LinearRegression()
regressor.fit(C, L)
L_pred = regressor.predict(C)

# R2スコア
r2 = r2_score(L, L_pred)

# 予測値と真の値のプロット
xlabel = np.arange(150)
plt.subplot(2,1,1)
plt.scatter(xlabel, L[:,0])
plt.title("True")
plt.subplot(2,1,2)
plt.scatter(xlabel, L_pred[:,0])
plt.title("Pred")
plt.suptitle("R2 = "+str(r2))
plt.show()

#######

from sklearn.preprocessing import OneHotEncoder

encoder = OneHotEncoder(categories="auto", sparse=False)
C_onehot = encoder.fit_transform(C)
# C_onehotは、カテゴリーを区別するラベルとして[x, y, z]を付ける。
# C=0なら[1,0,0]、C=1なら[0,1,0]、C=2なら[0,0,1]のように。
# これを生成するエンコーダがOneHotEncoderで、元のC=[0..50個..0 1..50個..1 2..50個..2]を
# [[100]..50個..[100] [010]..50個..[010] [001]..50個..[001]]に変換
#print(C_onehot)
print(encoder.categories_)  # 結果は[array([0, 1, 2])]
# その上で、Linear Regressionに食わせる regressor.fit(C_onehot, L)

regressor = LinearRegression()
regressor.fit(C_onehot, L)
L_pred = regressor.predict(C_onehot)

# R2スコア
r2 = r2_score(L, L_pred)

# 予測値と真の値のプロット
xlabel = np.arange(150)
plt.subplot(2,1,1)
plt.scatter(xlabel, L[:,0])
plt.title("True")
plt.subplot(2,1,2)
plt.scatter(xlabel, L_pred[:,0])
plt.title("Pred")
plt.suptitle("R2 = "+str(r2))
plt.show()

2変数の例?

sklearn.preprocessing.OneHotEncoder — scikit-learn 0.22.1 documentation

from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
X = [['Male', 1], ['Female', 3], ['Female', 2]]
enc.fit(X)
#OneHotEncoder(handle_unknown='ignore')
enc.categories_
#[array(['Female', 'Male'], dtype=object), array([1, 2, 3], dtype=object)]
enc.transform([['Female', 1], ['Male', 4]]).toarray()
#array([[1., 0., 1., 0., 0.],
#       [0., 1., 0., 0., 0.]])
enc.inverse_transform([[0, 1, 1, 0, 0], [0, 0, 0, 1, 0]])
#array([['Male', 1],
#       [None, 2]], dtype=object)
enc.get_feature_names(['gender', 'group'])
#array(['gender_Female', 'gender_Male', 'group_1', 'group_2', 'group_3'],
# dtype=object)

enc.categories_の値は [array(['Female', 'Male'], dtype=object), array([1, 2, 3], dtype=object)] なので、この要素を繋いだ ['Female', 'Male']+[1, 2, 3] を列名にしてDataFrameを作る。

###
#  enc.categories_を使って、エンコード後のデータをDataFrameに作る(列名を付ける)
###
print(enc.categories_[0].tolist())
print(enc.categories_[0].tolist() + enc.categories_[1].tolist())
df = pd.DataFrame(enc.transform([['Female', 1], ['Male', 4]]).toarray(), \
                  columns=enc.categories_[0].tolist() + 
enc.categories_[1].tolist())
print(df)
#   Female  Male    1    2    3
#0     1.0   0.0  1.0  0.0  0.0
#1     0.0   1.0  0.0  0.0  0.0

又は、列名をenc.get_feature_names(['sex', 'origin', 'browser'])とすれば

dfenc = pd.DataFrame(enc.transform([['female', 'from US', 'uses Safari']]).toarray(), \
                    columns=enc.get_feature_names(['sex', 'origin', 'browser']))
print("Result of [['female', 'from US', 'uses Safari']]\n", dfenc)
#Result of [['female', 'from US', 'uses Safari']]
#    sex_female  sex_male  origin_from Europe  origin_from US  \
#  0         1.0       0.0                 0.0             1.0   
#
#   browser_uses Firefox  browser_uses Safari  
#  0                   0.0                  1.0   

2変数の例 その2

# リスト 3-19   パッケージ mca を使ったコレスポンデンス分析の例
#%matplotlib inline   # Jupyter Notebookで実行する場合コメントマーク#を外す
# コレスポンデンス分析のライブラリ 髪の色・目の色の例
# hair/eye distribution https://www.utdallas.edu/~herve/Abdi-MCA2007-pretty.pdf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import OneHotEncoder
import mca
np.set_printoptions(formatter={'float':'{: 0.4f}'.format})
pd.set_option('display.precision', 5)
pd.set_option('display.max_columns', 25)

t = np.array([
  [326, 38, 241, 110, 3],
  [688, 116, 584, 188, 4],
  [343, 84, 909, 412, 26],
  [98, 48, 403, 681, 85]])
# データを1人ずつに展開して、OneHot形式に変換する
z = [[[i, j]] * (int(t[i, j])) for i in range(4) for j in range(5)]
tdata = []
for v in z:
    tdata.extend(v)
oh = OneHotEncoder()
oh_fit = oh.fit(tdata)
oh_ary = oh_fit.transform(tdata).toarray()
hair = ['Fair hair', 'Red hair','Medium hair', 'Dark hair', 'Black hair']
eyes = ['Blue eyes', 'Light eyes', 'Medium eyes', 'Dark eyes']
colindex = hair + eyes
X = pd.DataFrame(oh_ary, columns=colindex).astype(int)

# mcaでコレスポンデンス分析
ncols = 2     # hair, eye
mca_ben = mca.MCA(X, ncols=ncols)

# 固有値と貢献度
data = np.array([mca_ben.L[:2],
                 mca_ben.expl_var(greenacre=True, N=2) * 100]).T
df3 = pd.DataFrame(data=data, columns=['cλ','%c'], index=range(1, 3))
print('df3\n', df3)
# 各データ点の因子負荷量と貢献度
fs, cont ='Factor score', 'Contributions x 1000'
table3 = pd.DataFrame(columns=X.index, index=pd.MultiIndex\
                      .from_product([[fs, cont], range(1, 3)]))
table3.loc[fs, :] = mca_ben.fs_r(N=2).T
table3.loc[cont, :] = mca_ben.cont_r(N=2).T * 1000
print('table3\n', np.round(table3.astype(float), 2))

# 各データを主成分軸上に散布図でプロット
colors = {0: 'red', 1: 'orange', 2: 'green', 3: 'blue', 4: 'yellow'}
markers = {0: 'o', 1: '>', 2: '^', 3: 's'}
tdf = pd.DataFrame(tdata, columns=['eyes', 'hair'])
tdf['fs0'] = mca_ben.fs_r(N=2)[:, 0]
tdf['fs1'] = mca_ben.fs_r(N=2)[:, 1]
for u in [0, 1, 2, 3, 4]:
    for v in [0, 1, 2, 3]:
        if (u == 0) and (v == 0):
            ax = tdf[(tdf['hair'] == u) & (tdf['eyes'] == v)].plot.scatter( \
               x='fs0', y='fs1', s=50, c=colors[u], marker=markers[v])
        else:
            tdf[(tdf['hair'] == u) & (tdf['eyes'] == v)].plot.scatter( \
               x='fs0', y='fs1', s=50, c=colors[u], marker=markers[v], ax=ax)
plt.title('コレスポンデンス分析・髪と眼の色')
plt.margins(0.1)
plt.axhline(0, color='gray')
plt.axvline(0, color='gray')
plt.savefig('correspondence-haireyes-tutorialstyle.png')
plt.show()

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2020-01-15 (水) 10:09:21 (1169d)