Pythonで0からディシジョンツリーを作って理解する
1.概要編 - 2. Pythonプログラム基礎編 - 3. データ分析ライブラリPandas編 - 4.データ構造編 - 5.情報エントロピー編 - 6.ツリー生成編 - (番外編) 離散化
ディシジョンツリーを作るためのPandasライブラリの使い方について説明いたします。
3.1 ライブラリのインポート
# pamdasをインポートし、プログラム内では、pdという名前で使用すると宣言する。
import pandas as pd
3.2 DataFrame, Series
pandasでは、データフレーム(DataFrame)とシリーズ(Series)を使用します。次の図のようにExcelのテーブルのようにデータを行は1つのデータ、列はデータの項目(属性)としたとき、DataFrameはテーブル全体を表し、Seriesは1行分を表すことになります。
3.3 DataFrameの生成
Excelファイルを読み込む。read_excel ExcelWriter
# Excelファイルは、このipynbファイルと同じ場所にアップロードしておく。
df0 = pd.read_excel("data_golf.xlsx")
# DataFrameをHTMLのtableとして表示する。
from IPython.display import HTML
html = "<div style='font-family:\"メイリオ\";'>"+df0.to_html()+"</div>"
HTML(html)
# Excelファイルへの保存 (withは、f.closeの処理を自動的に実行してくれるもの)
with pd.ExcelWriter("data_golf2.xlsx") as f:
df0.to_excel(f)
辞書型(連想配列)から生成する方法:辞書型(連想配列)は、列でデータをまとめます。DataFrame
# 辞書型から生成:列でデータをまとめる。
d = {
"天気":["晴","晴","曇","雨","雨","雨","曇","晴","晴","雨","晴","曇","曇","雨"],
"温度":["暑","暑","暑","暖","涼","涼","涼","暖","涼","暖","暖","暖","暑","暖"],
"湿度":["高","高","高","高","普通","普通","普通","高","普通","普通","普通","高","普通","高"],
"風":["無","有","無","無","無","有","有","無","無","無","有","有","無","有"],
"ゴルフ":["×","×","○","○","○","×","○","×","○","○","○","○","○","×"],
}
df0 = pd.DataFrame(d)
配列から生成する方法:行でデータをまとめます。DataFrame
# 配列から生成:行でデータをまとめる。
d = [["晴","暑","高","無","×"],
["晴","暑","高","有","×"],
["曇","暑","高","無","○"],
["雨","暖","高","無","○"],
["雨","涼","普通","無","○"],
["雨","涼","普通","有","×"],
["曇","涼","普通","有","○"],
["晴","暖","高","無","×"],
["晴","涼","普通","無","○"],
["雨","暖","普通","無","○"],
["晴","暖","普通","有","○"],
["曇","暖","高","有","○"],
["曇","暑","普通","無","○"],
["雨","暖","高","有","×"],
]
# 列名、行名をcolumns, index で指定できる。省略した場合には、通し番号が付く。
df0 = pd.DataFrame(d,columns=["天気","温度","湿度","風","ゴルフ"],index=range(len(d)))
3.4 テーブルの情報(行、列の名前、数)を取得
# テーブルの情報(行、列の名前、数)を取得
# 行、列の数
print(df0.shape) # 出力 (14, 5)
# 行数の取得
print(df0.shape[0]) #出力 14
# 列名の取得
print(df0.columns) # 出力 Index(['天気', '温度', '湿度', '風', 'ゴルフ'], dtype='object')
# 行名の取得(df0の行名は、自動で割り振られたインデックスになっている)
print(df0.index) # 出力 RangeIndex(start=0, stop=14, step=1)
3.5 値の取得 loc iloc values
# 値の取得
# 行と列を指定して値を取得する。
# 行番号1 (2個目のデータ), の湿度を取得する。
print(df0.loc[1,"湿度"]) # 出力 高
# 行と列を配列で複数指定して、値を取得する。
# 行番号1,2,4 の 天気とゴルフの値をまとめて取得、取得したデータもDataFrame型となる。
df = df0.loc[[1,2,4],["天気","ゴルフ"]]
print(df)
# 出力
# 天気 ゴルフ
# 1 晴 ×
# 2 曇 ○
# 4 雨 ○
print(type(df)) # 出力 <class 'pandas.core.frame.DataFrame'>
# 行と列の配列での指定には、スライス(配列を抜き出す処理)を利用することもできる。
# 1~4の行の、すべての列のデータを取得する。locは名前を指定するので、1:4とすると4を含みます。
df = df0.loc[1:4,:]
print(df)
# 出力
# 天気 温度 湿度 風 ゴルフ
# 1 晴 暑 高 有 ×
# 2 曇 暑 高 無 ○
# 3 雨 暖 高 無 ○
# 4 雨 涼 普通 無 ○
# iloc を使用すると、行、列をインデックスで指定できる。インデックスは、0から順に数える。
# 1~3の行の、最後の列(ゴルフ)以外のデータを取得する。ilocはインデックスを指定するので、1:4とすると4を含みません。
df = df0.iloc[1:4,:-1]
print(df)
# 出力
# 天気 温度 湿度 風
# 1 晴 暑 高 有
# 2 曇 暑 高 無
# 3 雨 暖 高 無
# 1行分 (Series) からの値の取得
# 最初の行のデータを取得する。sは、Series型
s = df0.iloc[0,:]
# 辞書型と同じように、s["列名"]で値を取得できる。
print(s["天気"]) # 出力 晴
# すべての値を配列(numpy.ndarray)の形式で取得する。
print(df0.values)
3.6 データのループ、順次データを見ていく iterrows iteritems
# データのループ、順次データを見ていく。
# 行でループする。1行ごとデータを見ていく。
for i,row in df0.iterrows():
# i は行名称(行のインデックス)、rowはSeries
print(i,row)
pass
# 列でループする。1列ごと、縦にデータを見ていく。
for i,col in df0.iteritems():
# iは列の名称、colはSeries
print(i,col)
pass
3.7 度数 value_counts
度数とは、例えば「晴、雨、雨、曇、晴」のデータにおける晴2、曇1、雨2といった各項目のデータがいくつあるかを示すものです。
# 度数(データの出現個数)
# 天気の列の全データを取得する。sは、Series
s = df0.loc[:,"天気"]
# なんのデータが何個あるか、を取得する。
print(s.value_counts())
# 出力
# 晴 5
# 雨 5
# 曇 4
# Name: 天気, dtype: int64
# 例えば、晴の個数を取得する。
print(s.value_counts()["晴"]) # 出力 5
3.8 特定のデータの抽出 query
pythonの条件文のような文字列を与えてデータを抽出することもできます。
# 特定データの抽出
# 天気が晴のデータの取得
print(df0.query("天気=='晴'"))
# 出力
# 天気 温度 湿度 風 ゴルフ
# 0 晴 暑 高 無 ×
# 1 晴 暑 高 有 ×
# 7 晴 暖 高 無 ×
# 8 晴 涼 普通 無 ○
# 10 晴 暖 普通 有 ○
# 天気が晴でゴルフに行くデータの取得
print(df0.query("天気=='晴' and ゴルフ=='○'"))
# 出力
# 天気 温度 湿度 風 ゴルフ
# 8 晴 涼 普通 無 ○
# 10 晴 暖 普通 有 ○
# 天気が晴、または、ゴルフに行くデータの取得
print(df0.query("天気=='晴' or ゴルフ=='○'"))
# 出力
# 天気 温度 湿度 風 ゴルフ
# 0 晴 暑 高 無 ×
# 1 晴 暑 高 有 ×
# 2 曇 暑 高 無 ○
# 3 雨 暖 高 無 ○
# 4 雨 涼 普通 無 ○
# 6 曇 涼 普通 有 ○
# 7 晴 暖 高 無 ×
# 8 晴 涼 普通 無 ○
# 9 雨 暖 普通 無 ○
# 10 晴 暖 普通 有 ○
# 11 曇 暖 高 有 ○
# 12 曇 暑 普通 無 ○
# lenによる抽出したデータの個数の取得
print(len(df0.query("天気=='晴' or ゴルフ=='○'")))
# 出力 12