2020-07-22に更新

「Python実践データ分析100本ノック」学習記録(第1部:データ加工 )

はじめに

初心者ながら「Python実践データ分析100本ノック」を進めています。

「第1部:データ加工」編ということで、第1章〜第2章(ノック1〜20)について、学んだことを言語化する目的でまとめを作ってみました。
データ分析を実践で活用する流れや、重要そうなポイントを整理しておきます。

学習しながら整理しているので、間違えや補足があれば指摘いただけると嬉しいです!

第1部の概要と感想

この第1部では「揃っているデータを加工して機械学習に使えるデータにするところまで」の練習でした。
この段階ではまだ機械学習を活用する前段階の、データの整理とデータの全体像を把握、そして機械学習に適したデータ形式に加工する「クレンジング」という作業のやり方を学びます。

第1章ではデータの結合など基本的な前処理をしたのち、統計量や欠損値などを調べてデータ全体像を把握し、さらにデータを集計・可視化(折れ線グラフで図示)する、という一連の流れ。まずは導入として綺麗で揃っている扱いやすいデータを扱います。

第2章では上記の「基本的な前処理」の部分を深掘りします。現場にありがちな汚いデータを扱って、「データの揺れ」や欠損のあるデータの加工のプロセスを学びます。
実際の現場ではデータが最初からまとまって整理されている訳ではなく、手入力や複数人での入力により表記違いや入力ミスがあるのが一般的です。それらを含んだ綺麗でないデータを「どう扱って機械学習に適したデータに加工していくのか」という、泥臭い作業ながらも重要な作業です。

個人的な感想

  • 1周目は細かいロジックよりも「データ加工の流れを把握すること」を最優先にすると、進めやすく整理しやすかった(細かいロジックは2周目で理解する)
  • 現場で入力ミスや表記揺れが発生してしまうのはよくありがち。データを取る際はそれが発生しないような仕組みも重要だと思った
  • データ分析をする目的も重要。「データをどのような形に加工すればゴールなのか」は書籍だけだと難しいので実践の必要あり
  • 「自分なりにデータと対話しながら分析を進めていく」という表現があって、その「データと対話する」という感覚が良いなあと思った

データ加工する際の流れ

基本的にはデータ解析用のライブラリPandasを活用し、グラフ描画にMatplotlibというライブラリを使用。
目的に応じて、3の集計や4の可視化を行って必要なデータを作っていきます(カッコの中はそれぞれの工程で本書に出てきたPandasの関数です)

  1. データの読み込み(read_csv, read_excel
  2. データの加工
    • 複数のデータを結合、列の追加をして必要なデータフレームを作成する。ユニオンとジョイン(concat, merge
    • 欠損値(isnull)・データの揺れのチェックと修正
  3. 集計(groupby, pivot_table
  4. グラフによる可視化
  5. データの保存。ダンプ(to_csv

「データ加工」のいくつかのポイント

  • データの検算:データを結合した際には件数を確認したり検算して、操作が正しいかどうかを把握する
  • 欠損値のチェック:欠損値があると正しく修正できないので、チェックして必要に応じて補完or除去する
  • データの揺れの修正:表記揺れをなくしたり、日付に関しては扱いやすいようにデータ型を統一する
  • 各種統計量の把握をする:平均値や最大・最小など、また全体の数字のスケール感を把握する (describe, sum, meanなど)

重要そうなポイント

(1)Pandasの基礎的操作

本来は基礎的な操作を抑えてからこの書籍をやるべきなのですが、自分はいきなり書籍に取り組んでしまったので、ある程度進めるうちに付いていけなくなり整理することにしました。
多くは書籍を進めていく中で覚えていけるのですが、データ列の参照方法、データを行インデックスで参照する方法(loc関数)などは常時使いされるので、使い方をちゃんと抑えておきたいです。

#列を取得(抽出)
df[列名]
df[[列名1, 列名2, 列名3, …]]  #列名のリストを指定すると、複数の列を取得することもできる
#行、列を指定して値を取得
#loc:行ラベルと列ラベルで指定、iloc:行番号と列番号で指定。ラベルや番号にはスライスが使われることも多い
df.loc[行名, 列名] 
df.iloc[行番号, 列番号]

(2)データの結合について

データ加工をする過程で、データを結合する作業が何度も登場します。
巻末にある「Appendix①」に目を通しておくと理解が深まります。

結合のやり方には「縦方向の結合(ユニオン)」と「横方向の結合(ジョイン)」があります。

  • 縦方向の結合(ユニオン) concat
    同じ情報(列名)を持ったデータを下にくっつけて行を増やしていくイメージ

  • 横方向の結合(ジョイン) merge
    例えば「売上データ」と「顧客データ」など別の情報(列名)を持ったデータを、ある情報(例えば顧客名)などをキーとしてくっつけることで列を増やすというイメージです。

特にデータを横方向に結合するmergeは引数に指定できるオプションが初見では複雑に感じます。
結合したい表を2つ左右に並べたイメージで、「左側の表」と「右側の表」をonに指定した列名でくっつける。そしてその時にどちらの表をベースにするかという結合方法をhowで指定する…というイメージで捉えると、僕はひとまず理解が進みました(慣れるためのざっくりしたイメージ付けなので、正確でないのはご了承ください)。

#concat:縦に結合
pd.concat([df1, df2])
#merge:横に結合。左に置く表(df1)と右に置く表(df2)を指定してあげるイメージ。以下のどちらのやり方でも可能
pd.merge(df1, df2)
df1.merge(df2)

#on:結合するキーを指定するオプション。共通の列名を指定する。
#列名がデータによって異なる場合、right_onやleft_onを使うこともできる。
pd.merge(df1, df2, on=キーにしたい列名)
pd.merge(df1, df2, left_on=df1のキーの列名, right_on=df2のキーの列名)

#how:結合方法を指定するオプション。inner, outer, left, rightを指定できる。
pd.merge(df1, df2, on=キーにしたい列名, how=left)

(3)欠損値の補完のやり方

ノック15の「欠損値をチェックして補完する」ところのアルゴリズムが急に複雑になりました。
流れとしては「特定の列を見ていって欠損値のある行を特定し、その欠損値を別のデータから参照してきて置き換える」という流れになるのでしょうか。
欠損値のある行をTrueとしたフラグ(flg_is_null)をインデックスとしてTrueの行のみに操作を施す…というやり方が登場します。
ここで(1)で挙げたlocの理解が重要になってきます。

→(詳細を追記予定)

(4)日付の表記揺れの補正とデータ型

ノック8では、登録日などの日付データから、目的に応じて年月の列を作成して集計する、という流れが出てきました。このように月別にカテゴリ分けができるのは、活用できる機会が多そうです。
またノック17では、日付の揺れを補正するために、数値型や文字列型で入ってしまっている日付データの書式を統一する、という処理が登場します。
データ型を確認するdtypesや変換するastype()の使い方、また日付型に関係する関数扱い方(to_datetime, to_timedelta)を整理しておきたいところです。

→(詳細を追記予定)

(5)集計について

グループ化(group_by)とピボットテーブル(pivot_table)による集計が出てきますが、これらの活用の仕方が1周ではまだピンと来ませんでした。これらの関数をどういう目的の時にどう使ったら良いかうまく言語化できなかったので、課題とします。

ピボットテーブルを使うと、行と列を指定してそれが表になって出力されます。見やすい表に整形して出力してくれる、という機能でしょうか。
(Excelの「ピボットテーブル機能」と同様のようで馴染みのある方は多いのでしょうか?)

#groupby:まとめたい(グループかしたい)列を引数に指定して、集計方法を示す関数を呼び出すと、グループごとの統計値が算出できる
#引数に1つの列を指定する基本の使い方
df.groupby('month').sum() #monthごとの合計値
df.groupby('month').mean() #monthごとの平均値

#引数に複数列をリストで指定する使い方。表形式で統計値が出力される
df.groupby(['month', 'name']).sum() #monthとnameの組み合わせごとに合計値を表示
df.groupby(['month', 'name']).count() #monthとnameの組み合わせごとにデータ数を表示

→(詳細を追記予定)

(備考)データフレームとは?

学習していると「データフレーム(df)」という単語が頻繁に出てきます。
データフレームはPandasの型の一つで、ざっくり「行名と列名も一緒に入ったエクセルの表のようなデータ」というようなイメージでしょうか。
df.valuesで値を参照、df.indexdf.columnsで行名と列名を取り出したりすることができます)

書籍の中では特に解説はありませんが、Pandasには主にDataFrameSeriesというデータ型があるようで、それぞれ

  • Seriesは1列だけのデータ。行名(index)のみ割り振られている
  • DataFrameはテーブル形式の2次元のデータ。行名(index)と列名(column)が割り振られている

どちらもPython標準のリストとはまた異なるデータ型です。
他にも3次元データもあるようですね。また今後、必要に応じて理解していこうと思います。

おわりに

他にもこのまとめに入れられなかった要素(Matplotlibによる可視化など)もあるので、必要に応じて整理したいです。

この書籍、著者の方の意図としては、まえがきに「Pythonの入門書ではありません」と明記されているように、本来は初歩を学んだ人がデータ分析を学ぶための実践書のような位置付けとなっています。
Pandasの操作もデータ分析の基礎も理解していない僕がやるのは本来の活用の仕方から外れているのかもしれませんが、それでも「実際にデータ分析をするにはどのようなことを学ぶべきか」というイメージ作りができるのがとても良いな、という印象を持っています。
なんとか最後まで完走して、画像処理・言語処理まで体験してみたいというモチベーションで続けています。

実践形式で手を動かすのにとても適した書籍なので、興味はあるけどまだ取り組むことが見えていない人でも、基礎練習として取り組むのにも有効に思うので、オススメの書籍です!

ツイッターでシェア
みんなに共有、忘れないようにメモ

Massa

北海道でアプリ制作に取り組んでるノンプログラマな農夫。仕事や日常生活で感じる小さな不便を解消すべく趣味と実益を兼ねて遊んでます ■Python・GAS + LINE bot

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント