からあげ博士の日常と研究と

博士課程を満期退学した人が好きなことを好きなままに書くところ。

scikit-learnのデータセット、irisデータセットの使い方


 こんにちは。からあげ博士(@phd_karaage)です。pythonでなにかのデータ解析の練習をしようと思った時に、手元にデータがなければなにもできません。さらに初心者にとって何か使えそうなデータを生み出すのはなかなか難しいところです。さらに言えば、実用的なデータや、誰かが実験に使っているようなデータ、解析対象のデータというのはなかなか公開されているものではありません。こういった記事を書こうと思った時に、自分も自分が使っているデータを用いて解説することができません。

 そういう人のために、という訳ではないでしょうがpythonのライブラリ、scikit-learnにはデータセットがいくらか用意されています。今回紹介するirisデータセットもそのうちの1つです。このデータセットをどのように使うか、なにができるのか紹介していきたいと思います。

 その上で今後統計的な解析やその手法について紹介していくときに、このirisデータセットを使っていこうと思います。

目次

irisデータセットとは?

 irisデータセットとは植物のアヤメの表現型、品種に関するデータが入ったデータセットです。表現型とは、長さや高さ、大きさなど植物体の観察値のことを言います*1。これらデータは数値によって入っています。このデータセットでは、これら表現型の値に、どの品種の個体から得られたデータか、という情報が含まれています。

 実際にどのようなデータが含まれているのか、それはscikit-learnのドキュメントを読みながら見てみましょう。

scikit-learn.org

  • data

The data matrix.

 まさにdataの中には表現型データの行列が入っている、と書かれています。具体的な中身については、データをインポートしてから確認してみましょう。

  • target

The classification target.

 ここはとりあえずデータに触ってみたい、という人には分かりにくいかもしれませんが、どの品種から取られたデータかを示す値が格納されているデータです。表現型ではなく、どの品種のアヤメのデータか、という情報が含まれています。

  • feature_names

The names of the dataset columns.

 dataの中に含まれるのは表現型データの行列、つまり値しか入っていないものでしたが、その行列の列がどのようなデータか、その列名が書かれたリストが格納されています。

  • target_names

The names of target classes.

 targetの中にはどの品種から取られたかを示す値が格納されていると書きましたが、ここにはその値がどの品種に対応するかという品種名のリストが格納されています。

  • DESCR

The full description of the dataset.

 このデータがどんなデータかということが文字列で記述されているものです。後で中身を見てみましょう。

  • filename

The path to the location of the data.

 このデータセットがコンピュータ上のどの位置に存在しているか、というのを示したものになります。これもまた文字列で記述されています。なおこれはscikit-learnのバージョン0.20から実装されたとのこと。

 これらデータセットは架空のデータセットなどではなく、実際にフィッシャーが使用し論文化したデータであることがUser Guideに記載されています。フィッシャーとは有名な統計学者の人ですね。

実際に読み込んでみる

from sklearn.datasets import load_iris

iris_dataset = load_iris()

 これだけで読み込むことがてきます。非常に簡単ですね。ただこれだけでは、iris_datasetはBunch Objectと呼ばれる形で与えられているので実際に解析を試す際にはここからデータを取り出してあげる必要があります。Spyderでは変数エクスプローラーを使って中身を見ることができるのでちょっと中身を見てみましょう。

 先ほど説明した通りのデータが入っていることが分かります。DESCRにはirisデータセットの説明、dataには(150,4)の形の行列、feature_namesには各列に格納されたデータのラベル、filenameにはirisデータセットの在処、targetには品種の値、target_namesには品種名ということで、文字列で構成された行列が格納されているということが分かります。

データを取り出す

data_array = iris_dataset["data"]
line_num = iris_dataset["target"]
line = iris_dataset["target_names"]
feature = iris_dataset["feature_names"]

print(data_array.shape)
print(line_num.shape)
print(line.shape)
print(len(feature))

 実際のデータはBunch Objectで格納されていますが、辞書形式と同じ形で取り出すことができます。先ほどは変数エクスプローラーを使って中身を見ましたが、ここでは取り出した後.shapeを加えてprintすることでその行列の形を確認しています。ただし、feature_namesだけは行列ではなくlist形式で格納されていて、取り出すとlistになるため、.shapeではなくlen()で確認しています。うまく取り出せるとこのような形で返り値があるはずです。

データを成形する

 もちろんデータを取り出して、これで解析に回すこともできるのですが、pandasのデータフレームの形にしてあげると便利に解析ができることでしょう。ということでpandasのデータフレームにしてあげます。ちなみにscikit-learnのversion 0.23以降では一撃でデータフレームを抽出することもできるようです。ただ試したかったんですけど、conda updateで落ちてきたscikit-learnのversionが0.22までだったのでとりあえず保留。

df_data = pd.DataFrame(data_array, columns = feature)
df_line = pd.DataFrame(line_num)
df = pd.concat([df_data, df_line], axis = 1)
df = df.rename(columns = {0: "Target"})

print(df)

 ここではpandasのデータフレームに成形しています。それぞれの行列をpd.DataFrameによってデータフレームに格納していきます。このとき、data_arrayの列名をfeatureに格納されているものに変えています。そしてそれぞれのデータフレームをpd.concatによって結合し、最後に系統の番号の列名をTargetに変更しているという次第です。

 こうすることにより、1つのデータフレームに解析に使われるようなデータがまとめられました。データフレームにまとめられたことで、各データには以下のようにアクセスが可能です。

print(df["sepal length (cm)"])
print(df["sepal width (cm)"])
print(df["petal length (cm)"])
print(df["petal width (cm)"])
print(df.Target)

 データフレームの中身にアクセスする場合、2通りのやり方があり、1つはDataFrame["列名"]で行うことができ、もう1つはDataFrame."列名"です。ただし後者で行う場合、列名に空白やカッコが含まれるとアクセスできなかったりするので、今回の場合はfeature_namesに入っていた列名をそのまま使いましたが、あまりオススメはしません。

 ここでfeature_namesの中身に触れたので、データについて深堀していきましょう。

  • sepal length (cm)

 正直どのデータも英語を直訳すればわかるのですが、これは花のがく片の長さに関するデータが含まれています。

  • sepal width (cm)

 これはがく片の幅ですね。

  • petal length (cm)

 これは花びらの長さ

  • petal width (cm)

 これは花びらの幅

 ということで、これらデータセットには、アヤメの花に関するデータが含まれているということになります。

Toy dataで遊ぼう

 ユーザーガイドには、これらデータはToy datasetsと書かれています。つまりおもちゃのデータセット。これを使って解析手法を身につけようね。というデータセットになります。irisデータセットもその一つ。解析を身につけるだけではなく、データの成形なんかもここではトライしましたね。今後はこのirisデータセットを使ってデータ解析の方法だったり、そのコードなんかを紹介できたらなと考えています。

 試しに簡単な散布図を書いてどんなデータなのか見てみましょう。

import matplotlib.pyplot as plt

plt.scatter(df["sepal length (cm)"], df["sepal width (cm)"], c = df.Target)

 すごく単純にmatplotlibで散布図を書いてみました。色は品種ごとに分けられています。このデータからどんなことを考えることができるのか、その考察を深めるのに、どのような解析が必要だろうか。あるいはこれら品種をデータからうまく判別するにはどうしたらよいだろうか?そんなことを今後紹介できたらと思っています(OpenCVの紹介ももうちょい頑張ります……)。

www.phd-karaage.com

www.phd-karaage.com

*1:実際の定義はもう少し難しいもの。遺伝的に支配された、生物の観察可能な特徴、とでもいうべきでしょうか。人間の身長や体重もまた表現型であり、形質の1つとも言えます。難しいですね。なおこれらは量的形質の1つ。