共通数量化とOne Hot Encoding
カテゴリ変量の共通数量化とOne Hot Encodingとの比較報告(岡本安晴、2020)を行ったが、そのときに用意したプログラムを公開用に編集して用意した。One Hot Encodingは機械学習(Machine Learning)においてカテゴリ変量に数値を与える方法として用いられており、各項目にダミー変数を割り当てて、項目が選ばれた場合は1、そうでない場合は0の値で表される。共通数量化では、変量単位で数値の割り当てを考え、数値を割り当てたときの変量の分散が最大になるようにカテゴリ値に数値が与えられる。詳しくは、Okamoto (2015)、岡本安晴(2019)第8章を参照されたい。
共通数量化およびOne Hot Encodingのスクリプト例を圧縮ファイルfiles_q_one.zipにまとめた。ダウンロード展開すれば自由に利用できる。
Pythonのインストールの説明のウェブサイトも用意した。
プログラムの入力データはExcelファイルとして用意する(図1)。
図1 データファイル例(DataPsy.xlsx)
第1行目に変数名を書く。第2行目に変数の処理法を指定する数値を書く。0であれば、何もせず、そのままである。1であれば、標準得点化する。2以上の整数値のときは、共通数量化のプログラムでは共通数量化、One Hot EncodingのプログラムではOne Hot Encodingが行われる。整数値はカテゴリ変量のカテゴリ値の数であり、カテゴリ値の数がKのときはカテゴリ値は1からKまでの整数値である。カテゴリ値の数は変数間で異なってもよい。データ値は第3行目から書く。
図1のデータは、岡本安晴(2019)の表8.2.1に掲載されているものである。DataIDは、回答者を区別するものである。Q1からQ5までがカテゴリ変量である。回答カテゴリ数は3個あるいは4個であったが、回答者のないカテゴリ値を除くと、すべて3カテゴリのデータとなった。問Q6とQ7は数値による評定である。各問いの内容は、岡本安晴(2019)の第8.2節を参照されたい。
図1のデータに対してOne Hot Encodingおよび共通数量化でデータの前処理(preprocessing)を行うが、まず共通数量化について、次にOne Hot Encodingについて処理例を示す。
共通数量化は変数ごとに分散を最大にするという基準でカテゴリ値に数値を割り当てるものであり、プログラムでは次の関数comqによって行われる。
#
# X: The categorical
variable to bu quantified
# NCat: The number of categories in the
variable
#
NCase: The number of cases
#
def comq( X, NCat, NCase ):
G =
[0]*NCase
# A list for the indicator
matrix
for
i in range(0, NCase):
if (X[i] < 1) or (X[i] > NCat):
print("Category is out of the range...X[%d] = %d"%(i,X[i]))
raise
"CatRange"
G[i] = []
for j in range(0, NCat):
if (X[i] == j + 1):
G[i].append(1)
else:
G[i].append(0)
G =
np.array(G)
onesRow
= np.full((1, NCase), 1)
onesCol
= np.full((NCase, 1), 1)
f =
onesRow @ G
H =
G - (onesCol @ f) / NCase
HpH
= H.transpose() @ H
w, v
= eigen(HpH)
# Eigen decomposition of HpH
= H'H
n_quant = 0;
# n_quant: the number of
non-zero eigen values
while (w[n_quant] > 1.0e-7):
n_quant = n_quant + 1
eigen_val = w[0: n_quant]
eigen_vec =
v[0: n_quant]
matOmega
= eigen_vec.transpose()
#
#
Calculation of the standardized scores of quantification
#
z =
H @ matOmega
invLmbdN = np.full((n_quant, n_quant), 0.0)
for
i in range(n_quant):
invLmbdN[i, i] = 1.0 / ((eigen_val[i] / NCase) ** 0.5)
z =
z @ invLmbdN
return n_quant, eigen_val, matOmega, z
#
n_quant: The
number of quantification variables
#
eigen_val:
The vector of eigen values of quantification
#
matOmega: The matrix
of the eigen vectpors (the weights)
#
of
quantification
プログラムのスクリプトファイルとサンプルデータファイルは圧縮ファイルfiles_q_one.zipにまとめられている。共通数量化のメインプログラムMainCommonQ.pyを実行すると、入力データファイル名の設定が求められる(図2)。
図2
図2では、図1のファイル名が設定されている。入力データファイル名を設定してEnterキーを押すと、データの読み込みが始まり、読み込まれたデータが表示される(図3)。
図3
読み込まれたデータの出力後、計算結果(ウェイトなど)の出力先テキストファイル名の設定が求められる。適当なテキストファイル名を設定する。図3では「Results.txt」と設定されている。
プログラムMainCommonQ.pyでは、共通数量化の前処理を行った結果はExcelファイルとして出力される。計算結果の出力先テキストファイル名を設定すると、次に共通数量化の前処理を行った結果の出力先Excelファイル名の設定が求められる。図3では「q_data.xlsx」と設定されている。ファイル拡張子が「.xlsx」となっていることに注意。
出力用Excelファイル名の設定が終わると、計算が始まり、終了すると出力Excelファイルと計算結果出力テキストファイルが保存されたことが表示されてプログラムの実行終了となる。
プログラムの実行終了後、出力Excelファイルを開くと図4のようになっている。適切に処理が行われていることが分かる。
図4
計算結果出力ファイルは以下のようになっている。共通数量化の計算に必要な固有値と固有ベクトルが出力されており、共通数量化の解釈に必要な情報である。
Input data file = DataPsy.xlsx
Categorical variable: Q1
quantified.Number of quantification variables = 2
Eigen value = 13.84615
Eigen vector =
0.40825
-0.81650
0.40825
Eigen value = 12.00000
Eigen vector =
-0.70711
-0.00000
0.70711
Categorical variable: Q2
quantified.Number of quantification variables = 2
Eigen value = 14.78034
Eigen vector =
-0.61920
0.77052
-0.15132
Eigen value = 6.24530
Eigen vector =
0.53222
0.27013
-0.80235
・
・
・
図4に示されている共通数量化による前処理を行ったデータの主成分分析を行うと図5の結果を得る。
図5
Q6とQ4-0、およびQ1-1とQ2-0の間に原点に関して反対側に存在するという意味で強い関係が認められる。これらの解釈は、岡本安晴(2020)あるいは岡本安晴(2019)を参照されたい。
One Hot Encodingの処理プログラムも作成してみた。
One Hot Encodingは関数OneHotEncodingによって行っている。
#
# X: The categorical
variable to bu quantified
# NCat: The number of categories in the
variable
#
NCase: The number of cases
#
def OneHotEncoding( X, NCat, NCase ):
G =
[0]*NCase
# A list for the indicator
matrix
for
i in range(0, NCase):
if (X[i] < 1)
or (X[i] > NCat):
print("Category is out of the range...X[%d] = %d"%(i,X[i]))
raise "CatRange"
G[i] = []
for j in range(0, NCat):
if
(X[i] == j + 1):
G[i].append(1)
else:
G[i].append(0)
G =
np.array(G)
return G
スクリプトファイルとサンプルデータファイルは圧縮ファイルfiles_q_one.zipにまとめているので、ダウンロード展開すれば自由に利用できる。
メインスクリプトファイルはMainOneHotEncoding.pyである。MainOneHotEncoding.pyを実行すると、入力データファイル名の設定が求められる(図6)。
図6
入力Excelデータファイル名を設定する。図6では、図1のファイル名DataPsy.xlsxが設定されている。
入力データファイル名を設定してEnterキーを押すと、ファイルの読み込みが始まり、読み込まれたデータが表示される。
読み込みデータの出力後、出力用テキストファイル名の設定が求められる(図7)。
図7
適当なテキストファイル名を設定する。図7ではResultsOHE.txtと設定されている。
出力用テキストファイル名を設定すると、次にOnr Hot Encodingの処理結果を出力するExcelファイル名の設定が求められる。
図7ではohe_data.xlsxと設定されている。ファイル拡張子が「.xlsx」となっていることに注意。
出力用Excelファイル名を設定すると処理が始まる。処理が終了すると、Excel出力ファイルと出力用テキストファイルが保存されたことが表示され、プログラムの実行終了となる。
プログラムの実行終了後、出力Excelファイルを開くと図8のようになっている。
図8
処理が適切に行われていることが分かる。
図8のOne Hot Encodingによる前処理後のデータの主成分分析を行うと図9の結果を得る。
図9
個別の項目単位の関係が表されているが、解釈は岡本安晴(2020)を参照されたい。
岡本安晴(2019).いまさら聞けないPythonでデータ分析」丸善出版.
岡本安晴(2020)One Hot Encodingと共通数量化、日本行動計量学会第48回大会抄録集、212−215.