高速データ前処理のためのメモ帳チートシート

データ サイエンスの分野に参入する人々は、多くの場合、自分たちを待っているものについて現実的な期待を持っていません。 多くの人は、今すぐクールなニューラル ネットワークを作成したり、アイアンマンの音声アシスタントを作成したり、金融市場で誰にでも勝つことができると考えています。
でも仕事 且つ 科学者はデータ駆動型であり、最も重要で時間のかかる側面の XNUMX つは、データをニューラル ネットワークに入力したり、特定の方法で分析したりする前にデータを処理することです。

この記事では、私たちのチームが、段階的な手順とコードを使用してデータを迅速かつ簡単に処理する方法について説明します。 私たちは、コードを非常に柔軟にし、さまざまなデータセットに使用できるようにしようとしました。

多くの専門家にとって、この記事には特別なことは何も見つからないかもしれませんが、初心者にとっては何か新しいことを学ぶことができ、高速で構造化されたデータ処理のために別のノートブックを作成することを長い間夢見てきた人は誰でも、コードをコピーして自分でフォーマットすることができます。 完成したノートブックを Github からダウンロードします。

データセットを受け取りました。次はどうする?

つまり、標準: 私たちが扱っているもの、全体像を理解する必要があります。 これを行うには、パンダを使用してさまざまなデータ型を簡単に定義します。

import pandas as pd #импортируем pandas
import numpy as np  #импортируем numpy
df = pd.read_csv("AB_NYC_2019.csv") #читаем датасет и записываем в переменную df

df.head(3) #смотрим на первые 3 строчки, чтобы понять, как выглядят значения

高速データ前処理のためのメモ帳チートシート

df.info() #Демонстрируем информацию о колонках

高速データ前処理のためのメモ帳チートシート

列の値を見てみましょう。

  1. 各列の行数は総行数に対応していますか?
  2. 各列のデータの本質は何でしょうか?
  3. 予測を行うためにどの列をターゲットにしますか?

これらの質問に対する答えによって、データセットを分析し、次のアクションの計画を大まかに描くことができます。

また、各列の値を詳しく調べるには、pandas description() 関数を使用できます。 ただし、この関数の欠点は、文字列値を含む列に関する情報が提供されないことです。 それらについては後で対処します。

df.describe()

高速データ前処理のためのメモ帳チートシート

魔法の視覚化

値がまったくない場合を見てみましょう。

import seaborn as sns
sns.heatmap(df.isnull(),yticklabels=False,cbar=False,cmap='viridis')

高速データ前処理のためのメモ帳チートシート

ここまでは上からの簡単な説明でしたが、ここからはさらに興味深い内容に移ります

すべての行で XNUMX つの値しか持たない列を見つけて、可能であれば削除してみましょう (結果にはまったく影響しません)。

df = df[[c for c
        in list(df)
        if len(df[c].unique()) > 1]] #Перезаписываем датасет, оставляя только те колонки, в которых больше одного уникального значения

ここで、重複行 (既存の行の XNUMX つと同じ情報が同じ順序で含まれる行) から自分自身とプロジェクトの成功を守ります。

df.drop_duplicates(inplace=True) #Делаем это, если считаем нужным.
                                 #В некоторых проектах удалять такие данные с самого начала не стоит.

データセットを XNUMX つに分割します。XNUMX つは定性的な値を含み、もう XNUMX つは定量的な値を含みます。

ここで少し説明する必要があります。定性データと定量データのデータが欠落している行が相互にあまり相関していない場合、データが欠落しているすべての行、またはその一部のみを犠牲にするかを決定する必要があります。または特定の列。 線に相関がある場合、データセットを XNUMX つに分割する権利があります。 それ以外の場合は、まず欠損データに定性的および定量的な相関関係がない行を処理してから、データセットを XNUMX つに分割する必要があります。

df_numerical = df.select_dtypes(include = [np.number])
df_categorical = df.select_dtypes(exclude = [np.number])

これは、これら XNUMX つの異なるタイプのデータの処理を容易にするために行われます。これによって私たちの生活がどれほど楽になるかは、後ほど理解します。

私たちは定量的なデータを扱います

最初に行うべきことは、定量データに「スパイ列」があるかどうかを判断することです。 これらの列は定量的データとして表示されますが、定性的データとしても機能するため、これらの列を と呼びます。

それらをどのように定義すればよいでしょうか? もちろん、すべては分析するデータの性質によって異なりますが、一般に、そのような列には一意のデータがほとんど含まれない可能性があります (一意の値が 3 ~ 10 個の範囲)。

print(df_numerical.nunique())

スパイ列を特定したら、それらを定量的データから定性的データに移動します。

spy_columns = df_numerical[['колонка1', 'колока2', 'колонка3']]#выделяем колонки-шпионы и записываем в отдельную dataframe
df_numerical.drop(labels=['колонка1', 'колока2', 'колонка3'], axis=1, inplace = True)#вырезаем эти колонки из количественных данных
df_categorical.insert(1, 'колонка1', spy_columns['колонка1']) #добавляем первую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка2', spy_columns['колонка2']) #добавляем вторую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка3', spy_columns['колонка3']) #добавляем третью колонку-шпион в качественные данные

最後に、定量的データと定性的データを完全に分離し、適切に作業できるようになりました。 まず最初に、どこに空の値があるかを理解することです (NaN、場合によっては 0 が空の値として受け入れられます)。

for i in df_numerical.columns:
    print(i, df[i][df[i]==0].count())

この時点で、どの列のゼロが欠損値を示している可能性があるかを理解することが重要です。これはデータの収集方法によるものでしょうか? それともデータ値に関係しているのでしょうか? これらの質問には、ケースバイケースで答える必要があります。

したがって、それでもゼロがあるデータが欠落している可能性があると判断した場合は、後でこの失われたデータを扱いやすくするために、ゼロを NaN に置き換える必要があります。

df_numerical[["колонка 1", "колонка 2"]] = df_numerical[["колонка 1", "колонка 2"]].replace(0, nan)

次に、データが欠落している場所を見てみましょう。

sns.heatmap(df_numerical.isnull(),yticklabels=False,cbar=False,cmap='viridis') # Можно также воспользоваться df_numerical.info()

高速データ前処理のためのメモ帳チートシート

ここで、列内の欠落している値は黄色でマークされている必要があります。 ここからが楽しみの始まりです - これらの値にどう対処するか? これらの値または列を含む行を削除する必要がありますか? それとも、これらの空の値を他の値で埋めますか?

以下は、原則として空の値で何ができるかを決定するのに役立つ近似図です。

高速データ前処理のためのメモ帳チートシート

0. 不要な列を削除する

df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)

1. この列の空の値の数は 50% を超えていますか?

print(df_numerical.isnull().sum() / df_numerical.shape[0] * 100)

df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)#Удаляем, если какая-то колонка имеет больше 50 пустых значений

2. 空の値を含む行を削除する

df_numerical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, если потом останется достаточно данных для обучения

3.1. ランダムな値を挿入する

import random #импортируем random
df_numerical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True) #вставляем рандомные значения в пустые клетки таблицы

3.2. 定数値の挿入

from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>") #вставляем определенное значение с помощью SimpleImputer
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями

3.3. 平均値または最頻値を挿入します

from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='mean', missing_values = np.nan) #вместо mean можно также использовать most_frequent
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями

3.4. 別のモデルで計算された値を挿入します

sklearn ライブラリまたは他の同様のライブラリのモデルを使用した回帰モデルを使用して値を計算できる場合があります。 私たちのチームは、これをどのように実現できるかについて、近い将来別の記事を書く予定です。

したがって、現時点では、定量的データに関する説明は中断します。さまざまなタスクでデータの準備と前処理をより適切に実行する方法については、他にも多くのニュアンスがあり、定量的データの基本的な事項はこの記事で考慮されているためです。今こそ、定量的なデータから数歩下がった定性的なデータに戻る時です。 このノートブックを自由に変更して、さまざまなタスクに適応させることができるため、データの前処理が非常に迅速に行われます。

定性的データ

基本的に、定性データの場合は、文字列 (またはオブジェクト) から数値にフォーマットするために、ワンホット エンコーディング方法が使用されます。 この点に進む前に、上記の図とコードを使用して空の値を処理してみましょう。

df_categorical.nunique()

sns.heatmap(df_categorical.isnull(),yticklabels=False,cbar=False,cmap='viridis')

高速データ前処理のためのメモ帳チートシート

0. 不要な列を削除する

df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)

1. この列の空の値の数は 50% を超えていますか?

print(df_categorical.isnull().sum() / df_numerical.shape[0] * 100)

df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True) #Удаляем, если какая-то колонка 
                                                                          #имеет больше 50% пустых значений

2. 空の値を含む行を削除する

df_categorical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, 
                                   #если потом останется достаточно данных для обучения

3.1. ランダムな値を挿入する

import random
df_categorical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True)

3.2. 定数値の挿入

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>")
df_categorical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_categorical[['колонка1', 'колонка2', 'колонка3']])
df_categorical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True)

これで、ついに定性データの null を扱うことができました。 次に、データベース内の値に対してワンホット エンコーディングを実行します。 この方法は、アルゴリズムが高品質のデータから確実に学習できるようにするためによく使用されます。

def encode_and_bind(original_dataframe, feature_to_encode):
    dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
    res = pd.concat([original_dataframe, dummies], axis=1)
    res = res.drop([feature_to_encode], axis=1)
    return(res)

features_to_encode = ["колонка1","колонка2","колонка3"]
for feature in features_to_encode:
    df_categorical = encode_and_bind(df_categorical, feature))

それで、ついに別々の定性的データと定量的データの処理が完了しました - それらを結合して戻す時間です

new_df = pd.concat([df_numerical,df_categorical], axis=1)

データセットを 0 つに結合したら、最終的に sklearn ライブラリの MinMaxScaler を使用してデータ変換を使用できるようになります。 これにより、値が 1 と XNUMX の間になり、将来モデルをトレーニングするときに役立ちます。

from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler()
new_df = min_max_scaler.fit_transform(new_df)

このデータは、ニューラル ネットワーク、標準 ML アルゴリズムなど、あらゆるものに使用できるようになりました。

この記事では、時系列データの操作については考慮していません。そのようなデータの場合は、タスクに応じて若干異なる処理手法を使用する必要があるためです。 将来的には、私たちのチームがこのトピックについて別の記事を書く予定であり、この記事のように、何か興味深く、新しく、役立つものをあなたの生活にもたらすことができれば幸いです。

出所: habr.com

コメントを追加します