AI・機械学習 技術関連

[中古車査定/CarEvaluationDataset]データの前処理方法を紹介1

投稿日:

概要

作成したもの

  • 中古車査定データセットを前処理

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

  • Pandas
  • Scikit-learn
  • seaborn

動機

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

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

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

中古車査定データ

データの概要

中古車情報データをもとに査定結果が分類されたデータセット(Car Evaluation Dataset)です。
構造化データの研究者がフランスの中古車の査定データベースをもとに作成されました。

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

buying:販売価格 (vhigh, high, med, low)
maint:整備費用 (vhigh, high, med, low)
doors:ドアの数 (2, 3, 4, 5more)
persons:積載人数 (2, 4, more)
lug_boot:荷台の大きさ (small, med, big)
safety:安全性 (low, med, high)

で、

クラスは、

・unacc:受け入れ不可
・acc:受け入れ可
・good:良い
・vgood:とても良い

に分類されます。

ダウンロード

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

https://archive.ics.uci.edu/ml/datasets/Car+Evaluation

から中古車の査定データ(car.data)をダウンロードします。

インストール

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

pip seaborn
pip install pandas
pip install scikit-learn

データ整形

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

データの読み込み

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

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
csv_path = './car.data'
df=pd.read_csv(csv_path, sep=',',names = ["buying", "maint", "doors", "persons","lug-boot","safety","class"])
df.head()

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

	buying	maint	doors	persons	lug-boot	safety	class
0	vhigh	vhigh	2	2	small	low	unacc
1	vhigh	vhigh	2	2	small	med	unacc
2	vhigh	vhigh	2	2	small	high	unacc
3	vhigh	vhigh	2	2	med	low	unacc
4	vhigh	vhigh	2	2	med	med	unacc

ラベルの置き換え

DeepLearningに突っ込むためにデータをすべて数値に変換します。
各カラムごとにラベルに対してユニークな数値を振っています。

for column in df.columns:
    labels, uniques = pd.factorize(df[column])
    df[column] = labels
df.head()

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

	buying	maint	doors	persons	lug-boot     safety	class
0	0	0	0	0	0	0	0
1	0	0	0	0	0	1	0
2	0	0	0	0	0	2	0
3	0	0	0	0	1	0	0
4	0	0	0	0	1	1	0

クラス分布の確認

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

sns.countplot(data=df, x=class')
plt.title('0:unacceptbale 1:acc 2:good 3:very-good')

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

クラス数の調整

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

# ダウンサンプリング
df_shuffle = df.sample(frac=1) # シャッフル
mim_count = df_shuffle['class'].value_counts().iat[-1] # 一番少ないクラス数
gdf = df.groupby('class')
gdf = gdf.head(mim_count)
sns.countplot(data=gdf, x='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('car_train.csv', index=False)
test_df.to_csv('car_test.csv', index=False)

各カラムの相関性(おまけ)

seabornを使って、各カラムの相関を見ます。
今回はしていませんが、データの次元を削減する際にどのカラムが結果との相関が少ないかどうか見ています。

sns.heatmap(df.corr(),annot=True,cmap='cool')
figure,axes=plt.subplots(2,2,figsize=(10,10))
sns.countplot(data=df,x='buying',hue='y:class',ax=axes[0,0])
sns.countplot(data=df,x='maint',hue='y:class',ax=axes[0,1])
sns.countplot(data=df,x='lug-boot',hue='y:class',ax=axes[1,0])
sns.countplot(data=df,x='safety',hue='y:class',ax=axes[1,1])

安全性がクラスとの強い相関があり、販売価格とクラスの相関が弱いことが図から分かります。

結論・感想

中古車査定データの整形をしました。データの整形は機械学習をする上で面倒ですが、避けられない作業です。
この作業によってモデルの結果の良し悪しに大きく左右されます。
今回は、欠損がないデータセットでしたので、次回は欠損データの整形をやっていきたいと思います。

-AI・機械学習, 技術関連

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