クロス表の作成と並べ替え
クロス表の作成を、pandasのcrosstabを用いた例とsklearnのconfusion_matrixを用いた例を作成してみた。
なお、クロス表の分析法の例も用意している。
Pandasのcrosstabを用いたクロス表作例を以下のように作成した。
リスト1 クロス表の作成:例1
import numpy
import pandas
data = numpy.array([
[3,
1], [3, 2], [3, 2], [2, 1], [2, 2],
[1,
2], [3, 1], [2, 2], [3, 1], [1, 2],
[2,
2], [2, 2], [2, 3], [3, 1], [3, 2],
[2,
2], [3, 1], [3, 3], [1, 1], [2, 2],
[2,
1], [1, 2], [2, 2], [1, 2], [1, 3],
[3,
1], [1, 2], [2, 2], [1, 2], [1, 2],
[1,
2], [2, 2], [2, 1], [2, 3], [2, 2],
[1,
2], [3, 2], [3, 3], [1, 2]
])
print(data[:5], '\n')
xtable = pandas.crosstab(data.T[0],
data.T[1])
print(xtable)
クロス表作成のデータを対ごとにリストとし、それらをリストとしてまとめ、numpyのndarray型とした。
関数crosstabは、第1引数に行変数の値、第2変数に列変数の値を指定して呼び出すと第1変数と第2変数の値によるクロス表が返される。
xtable = pandas.crosstab(data.T[0],
data.T[1])
上のスクリプト例を実行すると以下の出力を得る。
[[3 1]
[3 2]
[3 2]
[2 1]
[2 2]]
col_0 1 2 3
row_0
1 1 10
1
2 3 10
2
3 6 4 2
第1変数はrow_0として、第2変数はcol_0として表示されている。
クロス表の行を並べ替えるときは、クロス表の部分をnumpyのndarray型に変換して何行目を何番目の行に置くかを指定すればよい。
例えば。2行目を1番目に、3行目を2番目に、1行目を3番目に移動するときは、上のサンプルスクリプトに続けて、以下のスクリプトを実行する。
行の順番は0から始まることに注意。
xtable_np = numpy.array(xtable)
xtable_r = xtable_np[[1,2,0]]
print(xtable_r)
上のスクリプトを先のスクリプトに続けて実行すると、以下の出力を得る。
[[ 3 10 2]
[ 6
4 2]
[ 1 10 1]]
さらに、2列目を1番目に、1列目を2番目に、3列目を3番目に置くときは、以下のコードを続けて実行すればよい。列の場合も、位置は0番目から数えることに注意。
xtable_rc = xtable_r[:,[1,0,2]]
print(xtable_rc)
実行すると、以下の出力を得る。
[[10 3
2]
[ 4
6 2]
[10
1 1]]
変数名として自動的に割り付けられるrow_0やcol_0を避けて、変数名を指定するときは以下のようにすればよい。
リスト2 クロス表の作成:例2
import pandas
raw_data = [
[3,
1], [3, 2], [3, 2], [2, 1], [2, 2],
[1,
2], [3, 1], [2, 2], [3, 1], [1, 2],
[2,
2], [2, 2], [2, 3], [3, 1], [3, 2],
[2,
2], [3, 1], [3, 3], [1, 1], [2, 2],
[2, 1], [1, 2], [2, 2], [1, 2], [1, 3],
[3,
1], [1, 2], [2, 2], [1, 2], [1, 2],
[1,
2], [2, 2], [2, 1], [2, 3], [2, 2],
[1,
2], [3, 2], [3, 3], [1, 2]
]
dframe = pandas.DataFrame(data =
raw_data,columns = ['A', 'B'])
print(dframe[:5], '\n')
xtableAB =
pandas.crosstab(dframe['A'], dframe['B'])
print(xtableAB, '\n')
val_table = xtableAB.values
print(val_table, '\n')
print(type(val_table), '\n')
print(val_table.sum(axis=0))
上の例では、まずリストとして与えられたデータからPnadasのDataFrame型のオブジェクトdframeを次のコードで作成している。
dframe = pandas.DataFrame(data =
raw_data,columns = ['A', 'B'])
第1引数dataにDataFrame型に変換するリストデータを指定し、第2引数columnsに変数名を指定している。
Excelファイルから読み込みDataFrame型を作成する例は、岡本(2022)におけるリスト12を参照されたい。CSV型からの読み込みはリスト3を参照されたい。
このデータフレームに対して、次のコードでクロス表を作成している。
xtableAB =
pandas.crosstab(dframe['A'], dframe['B'])
第1引数に行変数の値、第2変数に列変数の値を指定して呼び出している。
関数の返り値はDataFrame型であるが、クロス表の数値の部分はアトリビュートvaluesにより取り出すことができる。次のコード
val_table = xtableAB.values
により、数値の部分がndarray型の配列val_tableとして得ることができるので、次の分析ステップで用いることができる。
リスト2のスクリプトを実行すると以下の出力を得る。
A B
0
3 1
1
3 2
2
3 2
3
2 1
4
2 2
B
1 2 3
A
1
1 10 1
2
3 10 2
3
6 4 2
[[ 1 10 1]
[ 3 10 2]
[ 6
4 2]]
<class 'numpy.ndarray'>
[10 24 5]
クロス表の統計分析、ベイズ分析、行項目・列項目の視覚化などのウェブサイトも用意している。
Sklearnのconfusion_mtrixを用いたクロス表の作成
クロス表(Contingency Table)をPythonのライブラリsklearnのsklearn.metrics.confusion_matrix関数を用いて作成した例を示す。
例えば、次のデータについて説明する。
data = [
[3,
1], [3, 2], [3, 2], [2, 1], [2, 2],
[1,
2], [3, 1], [2, 2], [3, 1], [1, 2],
[2,
2], [2, 2], [2, 3], [3, 1], [3, 2],
[2,
2], [3, 1], [3, 3], [1, 1], [2, 2],
[2,
1], [1, 2], [2, 2], [1, 2], [1, 3],
[3,
1], [1, 2], [2, 2], [1, 2], [1, 2],
[1,
2], [2, 2], [2, 1], [2, 3], [2, 2],
[1,
2], [3, 2], [3, 3], [1, 2]
]
2つのカテゴリ変数AとBのデータが[A,B]の形式で39個与えられている。
これを各カテゴリ変量ごとにリストAとBにまとめるため、次のスクリプトを実行する。
data = numpy.array(data)
A = data.T[0]
B = data.T[1]
この後、クロス表を作成して出力する。スクリプトは以下のようである。
tbl = confusion_matrix(A,B)
print(tbl)
混同行列(confusion matrix)は、カテゴリ学習の成績を表すものであるが、これを用いてクロス表を作成している。カテゴリ変数AとBのデータからクロス表作成のカテゴリ値を読み取り、クロス表が作成される。混同行列の作成のための関数なので、行(第1引数、いまの場合A)と列(第2引数、いまの場合B)はカテゴリ値の変域は同じであると見なされてクロス表の作成におけるカテゴリ値が決められる(このカテゴリ値は、第3引数で指定することもできる)。カテゴリ値は、ともに数値、あるいは文字列である。
上のスクリプトの実行により、次のクロス表が出力される。
[[ 1 10 1]
[ 3 10 2]
[ 6 4 2]]
2列目と3列名を入れ換えると、度数が右上がりの関係になるので、列の入れ換えを行う。関数confusion_matrixでは、クロス表におけるカテゴリの並びは列と行で共通で、指定しなかった場合は昇順である。次の例では、他の場合の参考として、行と列の両方のカテゴリ値の変換を行うための辞書を用意して変換を行い、クロス表を作成している。
dicA = {1:0, 2:1, 3:2}
dicB = {1:0, 2:2, 3:1}
print('dicA = ', dicA)
print('dicB = ', dicB)
Atf = [dicA[v] for v in A]
Btf = [dicB[v] for v in B]
tbl1 = confusion_matrix(Atf, Btf)
print(tbl1)
実行結果は以下のようである。
dicA = {1: 0, 2: 1, 3: 2}
dicB = {1: 0, 2: 2, 3: 1}
[[ 1 1 10]
[ 3
2 10]
[ 6
2 4]]
上の例では、データがスクリプト内で与えられているが、データをファイルから読み込む場合は、以下のようにすればよい。
いま、図1のようにデータが用意されているとする。これは、上の例の場合のデータであり、拙著<岡本安晴「いまさら聞けないPythonでデータ分析」丸善出版>の図8.2.7と同じものである。
図1
図1のデータをCSV形式のファイルとして保存する。これは、ファイル拡張子として「.csv」を選べばCSV形式のファイルとして保存される。ファイル名「Data.csv」として保存したときのクロス表作成のスクリプト例を以下に示す。
import numpy as np
from sklearn.metrics import
confusion_matrix
import csv
with open('Data.csv', 'r') as f:
d = [v for v in
csv.reader(f)]
data = []
for i in range(1, len(d)):
data.append([int(d[i][0]),
int(d[i][1])])
data = np.array(data)
A = data.T[0]
B = data.T[1]
tbl = confusion_matrix(A,B)
print(tbl)
dicA = {1:0, 2:1, 3:2}
dicB = {1:0, 2:2, 3:1}
print('dicA = ', dicA)
print('dicB = ', dicB)
Atf = [dicA[v] for v in A]
Btf = [dicB[v] for v in B]
tbl1 = confusion_matrix(Atf, Btf)
print(tbl1)
実行結果は、上のスクリプトの場合と同じである。
スクリプトファイルなどは圧縮ファイルxtablefiles.zipとしてまとめた。Jupyter Notebook用の圧縮ファイルxtables_jn.zipも用意した。それぞれダウンロード・解凍して自由に利用されたい。
クロス表のポアッソン回帰モデルによる分析例を、拙著<岡本安晴「いまさら聞けないPythonでデータ分析」丸善出版>の第12章および第15章で説明している。