技術関連

[高収入判別/Census Income]データの前処理方法を紹介2

投稿日:

概要

作成したもの

  • 高収入者分類データセットを前処理

使用した技術・ライブラリ

  • Pandas
  • Scikit-learn
  • seaborn

動機

Deep Learning関連の案件でデータの前処理をする機会が多かったので、一度整理してみました。

なぜデータの前処理が必要なのか

まず、何らかの手段で欲しいデータが手に入ったとして、そのデータが完璧である可能性はほぼありません。
大抵データ内には欠損、ノイズ、エラー値などがあります。これらは無視してもよい場合もありますが、データの欠けに対しては適切な値で埋めたり、好ましくないデータ値は除いたりする必要があります。

高収入者分類データ

データの概要

学歴や出身などの経歴データをもとに年収が50Kドル以上かどうかが分類されたデータセット(adult Dataset)です。
アメリカの国税局のデータベースをもとに作成されたデータセットになります。Adult Datasetと表記されていますが怪しくはないです。

ターゲットとなる情報は、

age: continuous.
workclass: Private, Self-emp-not-inc, Self-emp-inc, Federal-gov, Local-gov, State-gov, Without-pay, Never-worked.
fnlwgt: continuous.
education: Bachelors, Some-college, 11th, HS-grad, Prof-school, Assoc-acdm, Assoc-voc, 9th, 7th-8th, 12th, Masters, 1st-4th, 10th, Doctorate, 5th-6th, Preschool.
education-num: continuous.
marital-status: Married-civ-spouse, Divorced, Never-married, Separated, Widowed, Married-spouse-absent, Married-AF-spouse.
occupation: Tech-support, Craft-repair, Other-service, Sales, Exec-managerial, Prof-specialty, Handlers-cleaners, Machine-op-inspct, Adm-clerical, Farming-fishing, Transport-moving, Priv-house-serv, Protective-serv, Armed-Forces.
relationship: Wife, Own-child, Husband, Not-in-family, Other-relative, Unmarried.
race: White, Asian-Pac-Islander, Amer-Indian-Eskimo, Other, Black.
sex: Female, Male.
capital-gain: continuous.
capital-loss: continuous.
hours-per-week: continuous.
native-country: United-States, Cambodia, England, Puerto-Rico, Canada, Germany, Outlying-US(Guam-USVI-etc), India, Japan, Greece, South, China, Cuba, Iran, Honduras, Philippines, Italy, Poland, Jamaica, Vietnam, Mexico, Portugal, Ireland, France, Dominican-Republic, Laos, Ecuador, Taiwan, Haiti, Columbia, Hungary, Guatemala, Nicaragua, Scotland, Thailand, Yugoslavia, El-Salvador, Trinadad&Tobago, Peru, Hong, Holand-Netherlands.

で、

クラスは、

>50K, <=50K. に分類されます。

ダウンロード

UCI(様々なデータセットが登録なしで無料で公開されているサイト)

https://archive.ics.uci.edu/ml/datasets/Adult

から高収入判別データ(adult.data)をダウンロードします。

インストール

前処理をするうえで必要なライブラリをインストールしていきます。Python3.xxでの環境になります。

pip seaborn
pip install pandas
pip install scikit-learn

データ整形

jupyter-notebook上で実行結果を確認しながら、データを整形していきます。

データの読み込み

ダウンロードしたデータセットを読み込みます。
必要なライブラリをインポートしてから、
データフレームでヘッダーを指定しCSV形式で読み込み、読み込んだ結果を確認します。

csv_path = './adult.csv'
header =  ["x__0:age",
           "x__1:workplace",
           "x__2:fnlwgt",
           "x__3:education",
           "x__4:education_num",
           "x__5:marital-status",
           "x__6:occupation",
           "x__7:relationship",
           "x__8:race",
           "x__9:sex",
           "x__10:capital-gain",
           "x__11:capital-loss",
           "x__12:hours-per-week",
           "x__13:native-country",
           "y:class"]
df=pd.read_csv(csv_path, sep=',',names = header)
print(len(df))
df.head()

ヘッダー付きでCSVデータが読み込めていることが確認できます。

	x__0:age	x__1:workplace	x__2:fnlwgt	x__3:education	x__4:education_num	x__5:marital-status	x__6:occupation	x__7:relationship	x__8:race	x__9:sex	x__10:capital-gain	x__11:capital-loss	x__12:hours-per-week	x__13:native-country	y:class
0	39	State-gov	77516	Bachelors	13	Never-married	Adm-clerical	Not-in-family	White	Male	2174	0	40	United-States	<=50K
1	50	Self-emp-not-inc	83311	Bachelors	13	Married-civ-spouse	Exec-managerial	Husband	White	Male	0	0	13	United-States	<=50K
2	38	Private	215646	HS-grad	9	Divorced	Handlers-cleaners	Not-in-family	White	Male	0	0	40	United-States	<=50K
3	53	Private	234721	11th	7	Married-civ-spouse	Handlers-cleaners	Husband	Black	Male	0	0	40	United-States	<=50K
4	28	Private	338409	Bachelors	13	Married-civ-spouse	Prof-specialty	Wife	Black	Female	0	0	40	Cuba	<=50K

欠損値の処理

今回のデータセットには欠損値[?]が含まれています。
欠損値が1つでも含まれている行はすべて削除するように前処理をします。
欠損値をNaNに置き換え、pandasの関数を使って欠損値が含まれる行を削除します。

# 欠損が含まれる行を全て削除
df.replace(' ?', np.nan, inplace=True)
df.dropna(how="any", inplace=True)
print(len(df))

ラベルの置き換え

DeepLearningに突っ込むためにデータをすべて数値に変換します。
置き換え作業をするカラムを指定し、ラベルにユニークな数値を振っています。
また、capital-gainとcapital-lossの値を0,1(有り無し)に変換します。

for column in df.columns:
    if column in ["x__1:workplace","x__3:education","x__5:marital-status","x__6:occupation","x__7:relationship","x__8:race","x__9:sex","x__13:native-country","y:class"]:
        labels, uniques = pd.factorize(df[column])
        df[column] = labels
        
# x__10:capital-gainとx__11:capital-lossを0,1に変換
df.loc[df["x__10:capital-gain"] > 0, "x__10:capital-gain"] = 1
df.loc[df["x__11:capital-loss"] > 0, "x__11:capital-loss"] = 1
df["x__2:fnlwgt"] = 0

df.head()

ラベルがすべて数値化されていることが確認できます。

x__0:age	x__1:workplace	x__2:fnlwgt	x__3:education	x__4:education_num	x__5:marital-status	x__6:occupation	x__7:relationship	x__8:race	x__9:sex	x__10:capital-gain	x__11:capital-loss	x__12:hours-per-week	x__13:native-country	y:class
0	39	0	0	0	13	0	0	0	0	0	1	0	40	0	0
1	50	1	0	0	13	1	1	1	0	0	0	0	13	0	0
2	38	2	0	1	9	2	2	0	0	0	0	0	40	0	0
3	53	2	0	2	7	1	2	1	1	0	0	0	40	0	0
4	28	2	0	0	13	1	3	2	1	1	0	0	40	1	0

クラス分布の確認

各クラスごとの数をseabornの棒グラフで表示します。

sns.countplot(data=df, x='y:class')
plt.title('0:>50K 1:<=50K')

分布に偏りがあることが確認できます。

クラス数の調整

クラス数が一様になるように調整します。
データをシャッフルし、一番少ないクラスの数に合わせます。

# ダウンサンプリング
df_shuffle = df.sample(frac=1) # シャッフル
mim_count = df_shuffle['y:class'].value_counts().iat[-1] # 一番少ないクラス数
gdf = df.groupby('y:class')
gdf = gdf.head(mim_count)
sns.countplot(data=gdf, x='y:class')

データ数が減ってしまいましたが、クラス数を一様にすることができました。

学習データの分割

データセットを学習データと検証データに分割します。
scikit-learnを使って、8:2にデータセットを分割し、それぞれCSVファイルに出力しています。

from sklearn.model_selection import train_test_split

x=np.array(gdf.iloc[:,:-1])
y=np.array(gdf.iloc[:,-1])

# データセットの分割
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8, random_state=0, stratify=y)# csvに保存
# 学習データ
train_data = np.concatenate([x_train, y_train[:, np.newaxis]], 1)
train_df = pd.DataFrame(data=train_data, columns=df.columns.values)
train_df['y:class'].astype(np.int64)
# 検証データ
test_data = np.concatenate([x_test, y_test[:, np.newaxis]], 1)
test_df = pd.DataFrame(data=test_data, columns=df.columns.values)
test_df['y:class'].astype(np.int64)

# CSV出力
train_df.to_csv('adult_train.csv', index=False)
test_df.to_csv('adult_test.csv', index=False)

結論・感想

講習収入者データの整形をしました。データの整形は機械学習をする上で面倒ですが、避けられない作業です。
この作業によってモデルの結果の良し悪しに大きく左右されます。
今回欠損は削除する処理をしましたが、次回は補完をやっていきたいと思います。

-技術関連

Copyright© AIなんて気合いダッ! , 2019 All Rights Reserved Powered by AFFINGER5.