ペンギンデータセットでデータエンジニアリングの基礎を学ぼう【Python/Pandas/palmerpenguins】

2021-09-04
Main Image

目次

こんにちは。

さて、昨今データサイエンス界隈を賑わせているpalmerpenguinsなるペンギンデータセット。前回の記事で既に生データをダウンロードはされたと思いますが、これをそのまま分析に使うにはちょっと面倒です。

そんなわけで今回は機械学習の初学者の第一歩、ペンギンデータセットでデータエンジニアリングとは何たるかを学びましょう。

という記事です。

よろしく。

ちなみに本記事ではプログラムにPython3を使います。

今回は第2弾として、データの中身の確認とクレンジングをします。

データを分析・機械学習に使うためには事前の準備が大事なので、ぜひ本記事でデータエンジニアリングの基礎を実践してみましょう。

まずはペンギンデータセット(palmerpenguins)をダウンロードしよう

データのダウンロードについては以下の記事にまとめました。

【ペンギンデータセットで機械学習/データサイエンスをはじめよう〜ダウンロード編【Python/palmerpenguins】

palmerpenguins データの列名を見直す

上記の記事でダウンロードして書き出したCSVファイルを読み込んでみます。

import pandas as pd
df = pd.read_csv('penguins_raw.csv')

どんなカラム(列)があるか確認してみると...

df.columns.to_list()

結果

['Unnamed: 0', 'studyName', 'Sample Number', 'Species', 'Region', 'Island', 'Stage', 'Individual ID', 'Clutch Completion', 'Date Egg', 'Culmen Length (mm)', 'Culmen Depth (mm)', 'Flipper Length (mm)', 'Body Mass (g)', 'Sex', 'Delta 15 N (o/oo)', 'Delta 13 C (o/oo)', 'Comments']

カラム名がスペースや大文字が混在していて使いにくそうなので変換しておきます。これは手作業。

col_name = [
  'index',
  'study_name',
  'sample_number',
  'species',
  'region',
  'island',
  'stage',
  'indivisual_id',
  'clutch_completion',
  'date_egg',
  'culmen_length_mm',
  'culmen_depth_mm',
  'flipper_length_mm',
  'body_mass_g',
  'sex',
  'delta_15_n',
  'delta_13_c',
  'comments'
]

df.columns = col_name

データのサイズ・欠損値(NaN)の有無を調べる

まずは基本から。

データのサイズを調べる。

df.shape
(344, 18)

344行 18列。

これくらいのデータならCSVをExcelで開いても中身がなんとなくわかりますが、

一応データサイエンスっぽくPythonでどんな値が入っているのかみてみましょう。

df.head(10)

先頭10行が表示されます。

NULLもありそうなので確認してみる。

df.isnull().sum()
index                  0
study_name             0
sample_number          0
species                0
region                 0
island                 0
stage                  0
indivisual_id          0
clutch_completion      0
date_egg               0
culmen_length_mm       2
culmen_depth_mm        2
flipper_length_mm      2
body_mass_g            2
sex                   10
delta_15_n            14
delta_13_c            13
comments             290

データの型・ユニーク値・ユニークな値の種類を調べる

データを扱う上では、まずどんな値が入っているのかを知る必要があります。変な値が入っていると、思い通りの計算ができなかったり、計算結果が変わってきたりします。

それでは、各列のデータ型、ユニークな値、種類の数を調べてみます。

for c in col_name:
  l = df[c].unique().tolist()
  print('------------------------')
  print(c)
  print(f'dtype : {df[c].dtype}')
  print(f'unique count : {len(l)}')
  print(l)

indexも含んでるので、ぎゃー!って感じの出力量になりますが、1個1個見ていくと、各列の特徴がわかります。

たとえばspecies

------------------------
species
dtype : object
unique count : 3
['Adelie Penguin (Pygoscelis adeliae)', 'Gentoo penguin (Pygoscelis papua)', 'Chinstrap penguin (Pygoscelis antarctica)']
------------------------

3種類。データをダウンロードするところで3種類持ってきたので、まあ想定通り。

sexの列はというと、

------------------------
sex
dtype : object
unique count : 4
['MALE', 'FEMALE', nan, '.']
------------------------

んん?nanはわかるけど.ってなんだ。。

こういうところが怪しげでバグに繋がりますね。性別とかめっちゃ使いそうだし。

データを使うときはちゃんとクレンジングしましょう。

分析に必要な列を抽出する

機械学習で使うときは性別を1,0のフラグ列にしたり目的に合わせて色々データを整形することになると思いますが、

ここではとりあえず分析に使えそうな列を残しておくくらいにしておきます。

機械学習については別記事で。

まず先程見たデータの中身と列の説明から必要な列を選択します。

今回は以下を選別しました。

usecols = [
  'species',
  'island',
  'date_egg',
  'culmen_length_mm',
  'culmen_depth_mm',
  'flipper_length_mm',
  'body_mass_g',
  'sex',
]

df1 = df[usecols].copy()

分析に使うデータの文字列と数値を整形する

ひとつずつ見ていきます。

まずはspecies

やたら文字列が長いのとカッコがついてたりするので短くします。

今回はたまたま半角スペースで区切れているので、str.splitの第一引数に半角スペースを指定すればいけそう。

df1['species_short'] =  df1.species.str.split(' ',expand=True)[0]

確認

df1.species_short.unique()
array(['Adelie', 'Gentoo', 'Chinstrap'], dtype=object)

成功。スッキリ。

もし規則性のない列だったら辞書を作って置換していくのかなーと思います。

不要になった元の列は削除します。

df2 = df1.drop('species', axis=1).rename(columns={'species_short':'species'})

次は、date_eggから生まれたを抽出します。

df2['year'] = pd.to_datetime(df2.date_egg).dt.year
df3 = df2.drop('date_egg', axis=1)

もともとがobjectだったので、最初にpd.to_datetime()datetime型に変換し、dt.yearで年を抽出しました。元の列はいらない子なので削除。

次は、sexの意味不明な.nanに置き換えて、大文字を小文字に揃えます。

import numpy as np
df3['sex'] = df3.sex.replace('.',np.nan)
df3['sex'] = df3.sex.str.lower()

nanを使いたいのでnumpyをインポート。.str.lower()で大文字は小文字に変換されます。

array(['male', 'female', nan], dtype=object)

成功。

あと、実はflipper_length_mmbody_mass_gの数値は小数点以下がないのにNaNがあるせいでfloat64型になってしまっているんですよね。

これはデータの無駄なので、どうにかしたいところ。

とはいえ.astype(int)NaNを含む列には使えないので、事前に.fillna(0)とかしておく必要がある。

0置換は実際のデータと異なってしまうので、あまりよろしくなさそう。

とりあえず今回は無視して、そのままCSVに吐き出します。分析のときにNaNの処理をどうするか考えることにします。

列の順番を整える

最後に列の順番を整えて、CSVに出力します。順番は本家に倣います。

outcols = [
  'species',
  'island',
  'culmen_length_mm',
  'culmen_depth_mm',
  'flipper_length_mm',
  'body_mass_g',
  'sex',
  'year'
]

df4 = df3[outcols].copy()

やってることは単純。並び替えた列名のリストを作って、その列を選択したデータフレームを別のデータフレーム(ここではdf4)に入れただけ。

列の名前を変換する

palmerpenguinsではculmenbillに置換しているので、倣います。

ちなみにculmenは嘴峰長(しほうちょう)の英語で、上嘴(くちばし)の基部から嘴先端までの稜線の長さのこと。billは嘴のことです。勉強になるなあ。

参考 : Wikipedia (https://ja.wikipedia.org/wiki/鳥類用語)

df4 = df4.rename(columns={
  'culmen_length_mm':'bill_length_mm',
  'culmen_depth_mm':'bill_depth_mm'
  })

最後にデータの中身が問題ないか、念押し確認

最後に一応、変な値がないか軽くチェックしておきます。先程と同じ方法。データを確認する癖はつけておいたほうがいい。

for c in df4.columns:
  l = df4[c].unique().tolist()
  print('------------------------')
  print(c)
  print(f'dtype : {df4[c].dtype}')
  print(f'unique count : {len(l)}')
  print(l)

今回は少量のデータなので簡単に目視で確認できますが、ビッグデータになると各列の特性に応じてエラーチェックのやり方を考える必要があります。たとえば数値の場合は散布図にプロットして、外れ値がないか確認するとか。

あ、そういえば今回も数値の列があるので、一番簡単な方法で見ておきましょう。

df4.describe()

.describe()のメソッドでデータフレームの数値の統計量を一括で出してくれます。こいつ超便利。

今回注目するのはmaxminですかね。最初からdf4.max()df4.min()を使ったほうが見やすいかも。

たとえばbill_length_mmは単位がmmのペンギンの嘴の長さですが、最小値が32.1、最大値が59.6ということで、大体3cm~6cmくらい。まあそんなもんかな、という感じです。(3cmって小さい?子どもペンギンならそんなもんかな。)

ここが1000mmとか1mmとかあまりにも常識と異なるような値がでていたら要注意で、外れ値の除外処理とか必要になるかと思います。

データセットをCSVファイルに出力する

というわけで最終チェックも問題なさそうだったので出力します。

df4.to_csv('penguins.csv')

お疲れさまでした。

まとめ

というわけで機械学習データセットの定番、palmerpenguinsのデータを使いやすい状態に整えてみました。

ぶっちゃけ、すでに加工済みのデータはダウンロードできるのですが(でもって、その加工済みのやつがpalmerpenguinsなのだと思うのですが)、こういうのって自分で生データ見て考えながら加工することが、データエンジニアやデータサイエンティストの成長の一歩だと思います。

ぜひこの記事を参考に色々試してみてください〜

みんなでペンギンデータセットを盛り上げていきましょう!

ads【オススメ】未経験からプログラマーへ転職できる【GEEK JOBキャンプ】
▼ Amazonオススメ商品
ディスプレイライト デスクライト BenQ ScreenBar モニター掛け式
スマートLEDフロアライト 間接照明 Alexa/Google Home対応

Author

Penta

都内で働くITエンジニアもどき。好きなものは音楽・健康・貯金・シンプルでミニマルな暮らし。AWSクラウドやデータサイエンスを勉強中。学んだことや体験談をのんびり書いてます。TypeScript / Next.js / React / Python / AWS / インデックス投資 / 高配当株投資 More profile

Location : Tokyo, JPN

Contact : Twitter@penguinchord

Recommended Posts

Copy Right / Penguin Chord, ペンギンコード (penguinchord.com) 2022 / Twitter@penguinchord