(旧) ヒノマルクのデータ分析ブログ

どんな企業、地域、国でも働けるようなスキルを身につけていくブログ

PythonやBIツールを使って分析と可視化をします

アイリスデータであやめの種類を決定木分析で分類してみた

かれこれ10年近く分析業界に関わっていますが、実に様々なデータを扱ってきました。私の場合、新しい手法などを試すときはまずはサンプルデータで試してから実データに適用するといったことをしてきました。会社の実データを自宅からアクセスできる環境がなく、自宅でサンプルデータを利用し分析やモデリングのプログラムを書いていました。

サンプルデータは実データに近い内容を自分で作ったり、ウェブ上で公開されているデータを利用していました。実際はサンプルデータで動いても実データでは予想外に実行時間がかかったりノイズが含まれていたりして上手く動かないことも多々ありましたが、分かりやすいデータでプログラムを動かして結果を確認するということが新しい知識を得るうえで大切だと感じました。

今回からPythonのデータ可視化用ライブラリのseabornを利用してサンプルデータを用いて集計や分析をしていこうと思います。分析仮設を立てて検証するという能力を錆びらせないためにやっていきます。

1. 利用データ説明

何のデータか

今回見ていくデータはフィッシャーのアイリス(アヤメ)データセットです。 分類問題やクラスタリングのサンプルコード紹介でよく利用されるデータです。フィッシャーという方が論文で紹介したのが始めだったんですね。

The Iris flower data set or Fisher's Iris data set is a multivariate data set introduced by the British statistician and biologist Ronald Fisher in his 1936 paper The use of multiple measurements in taxonomic problems as an example of linear discriminant analysis. ("Iris_flower_data_set" Wikipedia: The Free Encyclopedia)

アヤメって?

下記表の一番上にあるのが、アヤメのようです。 色・形はカキツバタハナショウブと似ていますが花びらに模様があるので分かりやすいですね。

抜粋元: https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%A4%E3%83%A1

データ取得先はどこ

seabornにてデータセットが用意されているので、今回はseabornのload_dataset関数を使ってデータを取得します。 seaborn.load_dataset

# irisデータセットの読み込み
# seabornで用意されているので、すぐにデータ確認することができる
import seaborn as sns
df = sns.load_dataset("iris")  #dfはdataframeの略

どのようなデータか

データ数: 150レコード

変数一覧:

英名 日本語訳 備考
sepal_length がく片の縦幅
sepal_width がく片の横幅
petal_length 花びらの縦幅
petal_width 花びらの横幅
species アヤメの種類 setosa、versicolor、virginicaの三種類

データセットに含まれるアヤメの種類

下記三種類のアヤメのがく片と花びらの長さの情報を集めたデータセットのようです。

1.setosa

2.versicolor

3.virginica

2. どのような分析ができそうか

  • がく片と花びらの長さからアヤメの種別を分類する

3. Checking iris dataset using seaborn

テーマは、「アヤメの種別を分類するモデルを作成する」という目的にして分析してみます。

データ読み込み

# irisデータセットの読み込み
# seabornで用意されているので、すぐにデータ確認することができる
import seaborn as sns
df = sns.load_dataset("iris")  #dfはdataframeの略

データ確認

ざっくり全体的にデータの基礎情報を確認しておきます。

# describe関数で各変数の概要を確認
df.describe()
Out[0]
sepal_length sepal_width petal_length petal_width
count 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.057333 3.758000 1.199333
std 0.828066 0.435866 1.765298 0.762238
min 4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
max 7.900000 4.400000 6.900000 2.500000

※ describe関数で表示される各項目の意味

英名 日本語訳
count レコード数
mean 平均
std 標準偏差
min 最小値
25% 25%パーセンタイル
50% 中央値 (50%パーセンタイル)
75% 75%パーセンタイル
max 最大値

ざっくりと全体的にどのようなデータになっているか確認します。 がく片の方が花びらより長いんだななど分析対象の前提知識がない場合はデータを見て想像力を働かせます。

デフォルトだとアウトプット画像のサイズが小さいので設定変更します。

# 出力画像のデザイン変更
from matplotlib import rcParams
rcParams['xtick.labelsize'] = 12       # x軸のラベルのフォントサイズ
rcParams['ytick.labelsize'] = 12       # y軸のラベルのフォントサイズ
rcParams['figure.figsize'] = 18,8      # 画像サイズの変更(inch)

相関係数をざっくり確認しておきます。

# 相関係数確認
sns.heatmap(df.corr(), vmax=1, vmin=-1, center=0,annot=True)
Out[0]

次に各アヤメの種別ごとにがく片や花びらの長さに違いがあるのかを集計します。

df[["sepal_length","species"]].groupby("species").describe()
Out[0]
sepal_length
count mean std min 25% 50% 75% max
species
setosa 50.0 5.006 0.352490 4.3 4.800 5.0 5.2 5.8
versicolor 50.0 5.936 0.516171 4.9 5.600 5.9 6.3 7.0
virginica 50.0 6.588 0.635880 4.9 6.225 6.5 6.9 7.9
df[["sepal_width","species"]].groupby("species").describe()
Out[0]
sepal_width
count mean std min 25% 50% 75% max
species
setosa 50.0 3.428 0.379064 2.3 3.200 3.4 3.675 4.4
versicolor 50.0 2.770 0.313798 2.0 2.525 2.8 3.000 3.4
virginica 50.0 2.974 0.322497 2.2 2.800 3.0 3.175 3.8
df[["petal_length","species"]].groupby("species").describe()
Out[0]
petal_length
count mean std min 25% 50% 75% max
species
setosa 50.0 1.462 0.173664 1.0 1.4 1.50 1.575 1.9
versicolor 50.0 4.260 0.469911 3.0 4.0 4.35 4.600 5.1
virginica 50.0 5.552 0.551895 4.5 5.1 5.55 5.875 6.9
df[["petal_width","species"]].groupby("species").describe()
Out[0]
petal_width
count mean std min 25% 50% 75% max
species
setosa 50.0 0.246 0.105386 0.1 0.2 0.2 0.3 0.6
versicolor 50.0 1.326 0.197753 1.0 1.2 1.3 1.5 1.8
virginica 50.0 2.026 0.274650 1.4 1.8 2.0 2.3 2.5

setosaは他の二種類のアヤメと比べると花びらが短そうですね。これは分類する上で重要なファクターとして採用されそうです。

データクリーニング

Feature Engineering

クラスタリングなど

モデリング

決定木を使ってアヤメの種類を分類します。

今回はsklearnを使います。モデリングをするときはだいたいsklearnを利用することが多いです。決定木以外にも様々な機械学習ができるようにパッケージングされています。

from sklearn import tree
clf = tree.DecisionTreeClassifier(random_state=0, max_depth=4)
X=df[["sepal_length","petal_length","sepal_width","petal_width"]]
Y=df["species"]
tree.plot_tree( clf.fit(X,Y)
               ,feature_names=["sepal_length","petal_length","sepal_width","petal_width"]
               ,class_names=["setosa","versicolor","virginica"]
               ,filled=True, rounded=True
              )
Out[0]

setosaは正答率100%で分類できることがわかる。他の種類よりも花びらの縦幅が小さいのできれいに境界線がわかれると思われる。versicolorとvirtinicaも花びらの縦幅と横幅でほとんど分類可能ということが分かる。(少なくとも今回のサンプルデータ上は)

4. check package versions

分析環境はanaconda macosです。 conda --version の結果はconda 4.7.12です。

今回利用したパッケージのバージョンは下記です。

import seaborn
import matplotlib
import sklearn
import pandas
import numpy
print("seaborn:"+ seaborn.__version__)
print("matplotlib:"+ matplotlib.__version__)
print("sklearn:"+ sklearn.__version__)
print("pandas:"+ pandas.__version__)
print("numpy:"+ numpy.__version__)
Out[0]
 seaborn:0.9.0
 matplotlib:3.1.0
 sklearn:0.21.2
 pandas:0.24.2
 numpy:1.16.4

plot_treeは ver0.21から導入されたので 古いバージョンのsklearnだと使えません。 sklearn.tree.plot_tree

古いバージョンを使っているときはgraphvizのフォーマットに変更して描画していましたが、plot_treeのおかげでかなり楽になりました。

5. 考察

今まで何となく利用していたirisデータですが、改めてデータの内容を確認してみると何を分析しようとしていたのか明確になりました。データの理解が分析をする上で非常に重要なポーションを占めているということが再認識できました。今回初めてjupyter notebookのコード内容をブログに載せましたが、もう少し手作業を含めずに寄稿することができないか要検討です。