![]() |
ノート/OneHotエンコードhttps://pepper.is.sci.toho-u.ac.jp:443/pepper/index.php?%A5%CE%A1%BC%A5%C8%2FOneHot%A5%A8%A5%F3%A5%B3%A1%BC%A5%C9 |
![]() |
トップ ノート
782 2020-01-15 (水) 10:09:21
%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()
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
# リスト 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()