|
2 weeks ago | |
---|---|---|
.. | ||
README.md | 2 weeks ago | |
assignment.ipynb | 3 weeks ago | |
assignment.md | 4 weeks ago | |
notebook.ipynb | 3 weeks ago |
README.md
データの取り扱い: データ準備
![]() |
---|
データ準備 - スケッチノート by @nitya |
講義前クイズ
データの出所によっては、生データに一貫性のない部分が含まれていることがあり、これが分析やモデリングの際に課題を引き起こす可能性があります。言い換えれば、このようなデータは「汚れている」と分類され、クリーンアップが必要です。このレッスンでは、欠損、不正確、または不完全なデータに対処するためのデータのクリーニングと変換の技術に焦点を当てます。このレッスンで取り上げるトピックは、PythonとPandasライブラリを使用し、このディレクトリ内のノートブックで実演されます。
データをクリーンにする重要性
-
使いやすさと再利用性: データが適切に整理され正規化されていると、検索、利用、他者との共有が容易になります。
-
一貫性: データサイエンスでは、複数のデータセットを扱うことがよくあります。異なるソースからのデータセットを結合する必要がある場合、それぞれのデータセットが共通の標準化を持っていることが重要です。これにより、すべてのデータセットを1つに統合した際にも有用性が保たれます。
-
モデルの精度: クリーンなデータは、それに依存するモデルの精度を向上させます。
一般的なクリーニングの目標と戦略
-
データセットの探索: データ探索(後のレッスンで取り上げます)は、クリーンアップが必要なデータを発見するのに役立ちます。データセット内の値を視覚的に観察することで、他の部分がどのように見えるかの期待値を設定したり、解決可能な問題のアイデアを得ることができます。探索には、基本的なクエリ、可視化、サンプリングが含まれます。
-
フォーマットの統一: データの出所によっては、データの提示方法に一貫性がない場合があります。これにより、検索や値の表現に問題が生じる可能性があります。一般的なフォーマットの問題には、空白、日付、データ型の解決が含まれます。フォーマットの問題を解決する方法は、データを使用する人々に委ねられることが多いです。例えば、日付や数字の表現方法に関する標準は国によって異なる場合があります。
-
重複: データが複数回出現すると、不正確な結果を生む可能性があり、通常は削除する必要があります。これは、2つ以上のデータセットを結合する際によく見られる現象です。ただし、結合されたデータセット内の重複が追加情報を提供する場合があり、その場合は保持する必要があることもあります。
-
欠損データ: 欠損データは、不正確さや弱い、または偏った結果を引き起こす可能性があります。これらは、データの「再読み込み」や、Pythonのようなコードを使用して欠損値を補完することで解決できる場合があります。または、単に値と対応するデータを削除することもあります。データが欠損する理由はさまざまであり、それを解決するためのアクションは、欠損の原因や理由に依存することがあります。
DataFrame情報の探索
学習目標: このセクションの終わりまでに、pandas DataFrameに格納されたデータの一般的な情報を見つけることに慣れることができます。
データをpandasにロードすると、それはほとんどの場合DataFrameに格納されます(詳細は前のレッスンを参照してください)。しかし、DataFrame内のデータセットが60,000行と400列ある場合、どのようにして扱うデータの概要を把握すればよいのでしょうか?幸いなことに、pandasは、DataFrameの全体的な情報をすばやく確認するための便利なツールを提供しています。
この機能を探索するために、Pythonのscikit-learnライブラリをインポートし、象徴的なデータセットであるIrisデータセットを使用します。
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris_df = pd.DataFrame(data=iris['data'], columns=iris['feature_names'])
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | |
---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 |
1 | 4.9 | 3.0 | 1.4 | 0.2 |
2 | 4.7 | 3.2 | 1.3 | 0.2 |
3 | 4.6 | 3.1 | 1.5 | 0.2 |
4 | 5.0 | 3.6 | 1.4 | 0.2 |
- DataFrame.info: 最初に、
info()
メソッドを使用して、DataFrame
内の内容の概要を表示します。このデータセットを見てみましょう。
iris_df.info()
RangeIndex: 150 entries, 0 to 149
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 sepal length (cm) 150 non-null float64
1 sepal width (cm) 150 non-null float64
2 petal length (cm) 150 non-null float64
3 petal width (cm) 150 non-null float64
dtypes: float64(4)
memory usage: 4.8 KB
これにより、Irisデータセットには4列に150エントリがあり、欠損値がないことがわかります。すべてのデータは64ビット浮動小数点数として格納されています。
- DataFrame.head(): 次に、
DataFrame
の実際の内容を確認するために、head()
メソッドを使用します。iris_df
の最初の数行を見てみましょう。
iris_df.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
- DataFrame.tail(): 逆に、
DataFrame
の最後の数行を確認するには、tail()
メソッドを使用します。
iris_df.tail()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
145 6.7 3.0 5.2 2.3
146 6.3 2.5 5.0 1.9
147 6.5 3.0 5.2 2.0
148 6.2 3.4 5.4 2.3
149 5.9 3.0 5.1 1.8
ポイント: DataFrameの情報や最初と最後の数値を確認するだけでも、扱うデータのサイズ、形状、内容について即座に把握することができます。
欠損データの処理
学習目標: このセクションの終わりまでに、DataFrameから欠損値を置き換えたり削除したりする方法を理解できるようになります。
使用したい(または使用せざるを得ない)データセットには、ほとんどの場合欠損値が含まれています。欠損データの処理方法には、最終的な分析や現実世界の結果に影響を与える微妙なトレードオフが伴います。
Pandasでは、欠損値を処理する方法が2つあります。1つ目は、以前のセクションで見たNaN
(Not a Number)です。これは、IEEE浮動小数点仕様の一部であり、欠損浮動小数点値を示すためにのみ使用されます。
浮動小数点以外の欠損値については、pandasはPythonのNone
オブジェクトを使用します。None
とNaN
の2種類の欠損値が存在するのは混乱を招くように思えるかもしれませんが、この設計選択には合理的なプログラム上の理由があり、実際にはほとんどのケースで良い妥協点を提供します。それにもかかわらず、None
とNaN
の両方には、それらの使用方法に関する制約があることを覚えておく必要があります。
NaN
とNone
についての詳細は、ノートブックを参照してください!
- 欠損値の検出:
pandas
では、isnull()
とnotnull()
メソッドが欠損データを検出するための主な方法です。どちらもデータに対してブールマスクを返します。numpy
を使用してNaN
値を扱います。
import numpy as np
example1 = pd.Series([0, np.nan, '', None])
example1.isnull()
0 False
1 True
2 False
3 True
dtype: bool
出力をよく見てください。何か驚くことはありますか?0
は算術的にはnullですが、それでも完全に有効な整数であり、pandasはそのように扱います。''
はもう少し微妙です。セクション1では空の文字列値を表すために使用しましたが、それでも文字列オブジェクトであり、pandasにとってはnullの表現ではありません。
次に、これらのメソッドを実際に使用する方法に近い形で使用してみましょう。ブールマスクを直接Series
やDataFrame
のインデックスとして使用することができ、欠損値(または存在する値)を扱う際に便利です。
ポイント:
isnull()
とnotnull()
メソッドは、DataFrame
で使用すると似たような結果を生成します。結果とそのインデックスを表示するため、データを扱う際に非常に役立ちます。
- 欠損値の削除: 欠損値を特定するだけでなく、pandasは
Series
やDataFrame
から欠損値を削除する便利な方法を提供します(特に大規模なデータセットでは、欠損値を他の方法で処理するよりも、分析から削除する方が望ましい場合が多いです)。これを実際に見てみましょう。
example1 = example1.dropna()
example1
0 0
2
dtype: object
これは、example3[example3.notnull()]
の出力と同じように見えるはずです。違いは、マスクされた値をインデックスする代わりに、dropna
がSeries
example1
から欠損値を削除した点です。
DataFrame
は2次元であるため、データを削除するためのオプションが増えます。
example2 = pd.DataFrame([[1, np.nan, 7],
[2, 5, 8],
[np.nan, 6, 9]])
example2
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | NaN | 7 |
1 | 2.0 | 5.0 | 8 |
2 | NaN | 6.0 | 9 |
(pandasがNaN
に対応するために2つの列を浮動小数点型にアップキャストしたことに気づきましたか?)
DataFrame
から単一の値を削除することはできないため、行または列全体を削除する必要があります。状況に応じて、どちらかを選択することになります。データサイエンスでは、列が変数を、行が観測値を表すことが多いため、データの行を削除する方が一般的です。dropna()
のデフォルト設定は、null値を含むすべての行を削除することです。
example2.dropna()
0 1 2
1 2.0 5.0 8
必要に応じて、列からNA値を削除することもできます。これを行うには、axis=1
を指定します。
example2.dropna(axis='columns')
2
0 7
1 8
2 9
これにより、小さなデータセットでは保持したいデータが多く削除される可能性があります。すべてのnull値を含む行や列だけを削除したい場合はどうすればよいでしょうか?dropna
のhow
およびthresh
パラメータを使用してこれを指定できます。
デフォルトでは、how='any'
です(確認したい場合や、メソッドに他のパラメータがあるかを確認したい場合は、コードセルでexample4.dropna?
を実行してください)。代わりに、how='all'
を指定して、すべてのnull値を含む行や列のみを削除することもできます。例を拡張してみましょう。
example2[3] = np.nan
example2
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | NaN | 7 | NaN |
1 | 2.0 | 5.0 | 8 | NaN |
2 | NaN | 6.0 | 9 | NaN |
thresh
パラメータを使用すると、より細かい制御が可能になります。保持するために必要な非null値の数を設定します。
example2.dropna(axis='rows', thresh=3)
0 1 2 3
1 2.0 5.0 8 NaN
ここでは、最初と最後の行が削除されています。これは、それらが非null値を2つしか含んでいないためです。
- 欠損値の補完: データセットによっては、欠損値を削除するよりも有効な値で補完する方が理にかなっている場合があります。これをインプレースで行うために
isnull
を使用することもできますが、多くの値を補完する必要がある場合は手間がかかります。このため、pandasはfillna
を提供しており、これを使用すると、欠損値を指定した値で置き換えたSeries
やDataFrame
のコピーを返します。別の例を作成して、これがどのように機能するかを見てみましょう。
example3 = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))
example3
a 1.0
b NaN
c 2.0
d NaN
e 3.0
dtype: float64
すべての欠損エントリを単一の値(例えば0
)で補完することができます。
example3.fillna(0)
a 1.0
b 0.0
c 2.0
d 0.0
e 3.0
dtype: float64
欠損値を前方補完することもできます。これは、最後の有効な値を使用して欠損値を補完する方法です。
example3.fillna(method='ffill')
a 1.0
b 1.0
c 2.0
d 2.0
e 3.0
dtype: float64
また、後方補完を使用して、次の有効な値を後方に伝播させて欠損値を補完することもできます。
example3.fillna(method='bfill')
a 1.0
b 2.0
c 2.0
d 3.0
e 3.0
dtype: float64
予想される通り、これはDataFrame
でも同様に機能しますが、null値を補完する軸を指定することもできます。以前使用したexample2
を再度使用してみましょう。
example2.fillna(method='ffill', axis=1)
0 1 2 3
0 1.0 1.0 7.0 7.0
1 2.0 5.0 8.0 8.0
2 NaN 6.0 9.0 9.0
前方補完のための以前の値が利用できない場合、null値はそのまま残ることに注意してください。
ポイント: データセット内の欠損値に対処する方法は複数あります。使用する具体的な戦略(削除する、置き換える、またはどのように置き換えるか)は、そのデータの特性によって決定されるべきです。データセットを扱い、操作する経験を積むことで、欠損値への対処方法に対する感覚がより磨かれていきます。
重複データの削除
学習目標: このセクションの終わりまでに、DataFrameから重複する値を特定し削除する方法に慣れることを目指します。
欠損データに加えて、現実世界のデータセットでは重複データに遭遇することもよくあります。幸いなことに、pandas
を使えば、重複エントリを簡単に検出して削除することができます。
- 重複の特定:
duplicated
: pandasのduplicated
メソッドを使うと、簡単に重複値を見つけることができます。このメソッドは、DataFrame
内のエントリが以前のエントリと重複しているかどうかを示すブール値のマスクを返します。これを実際に試すために、別の例のDataFrame
を作成してみましょう。
example4 = pd.DataFrame({'letters': ['A','B'] * 2 + ['B'],
'numbers': [1, 2, 1, 3, 3]})
example4
letters | numbers | |
---|---|---|
0 | A | 1 |
1 | B | 2 |
2 | A | 1 |
3 | B | 3 |
4 | B | 3 |
example4.duplicated()
0 False
1 False
2 True
3 False
4 True
dtype: bool
- 重複の削除:
drop_duplicates
:duplicated
の値がすべてFalse
であるデータのコピーを返します。
example4.drop_duplicates()
letters numbers
0 A 1
1 B 2
3 B 3
duplicated
とdrop_duplicates
はデフォルトで全ての列を考慮しますが、DataFrame
内の特定の列のみに限定して処理を行うよう指定することも可能です。
example4.drop_duplicates(['letters'])
letters numbers
0 A 1
1 B 2
まとめ: 重複データの削除は、ほぼすべてのデータサイエンスプロジェクトにおいて重要なステップです。重複データは分析結果を変えてしまい、不正確な結果をもたらす可能性があります!
🚀 チャレンジ
ここで学んだ内容はすべてJupyter Notebookとして提供されています。また、各セクションの後には演習問題が用意されているので、ぜひ挑戦してみてください!
講義後のクイズ
復習と自己学習
データを分析やモデリングのために準備する方法は多岐にわたり、データのクリーニングは「実践的」な経験が重要なステップです。このレッスンでカバーされていないテクニックを探求するために、Kaggleの以下のチャレンジに挑戦してみてください。
課題
免責事項:
この文書は、AI翻訳サービス Co-op Translator を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な表現が含まれる可能性があります。原文(元の言語で記載された文書)が公式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当社は一切の責任を負いません。