KaggleのHouse Pricesで回帰分析(EDA:Exploratory Data Analysis編)

今回は、kaggleの入門者向けチュートリアルコンペ「住宅価格予測」をやってみます。

House Prices: Advanced Regression Techniques

各種指標を用いて住宅の価格を予測する分析問題です。

データ分析のプロセスとして、CRISP-DM(CRoss Industry Standard Process for Data Mining)というものがあります。

モデリングより前のステップである「ビジネスの理解」「データの理解(Exploratory Data Analysis)」「データの準備(Feature Engineering)」のステップが大半を占めます。

まず「データの理解(Exploratory Data Analysis)」についてです。

データ分析の前提知識

教師あり学習には回帰と分類があります。

タイタニック問題は「2クラス分類」のチュートリアルでした。

住宅価格の予測は「回帰」のチュートリアルです。

「回帰」は株価分析など出力が連続値、「分類 (クラスタリング)」は文字認識など離散値という違いがあります。

回帰分析とは何か?

関数をデータに当てはめることによって、ある変数yの変動を別の変数xの変動により説明・予測・影響関係を検討するための手法です。

乱暴にいってしまえば、複数の変数間の関係を一次方程式(Y=aX+b)の形で表現する分析方法です。

次のような用途があります。

  • 因果関係が想像される2つの変数間の関係を調べる(因果関係の証明)
  • 売上高と宣伝費の関係が分かる→目標とする売上高に対して宣伝費を決定する(制御)
  • 人口と商店数の関係が分かる→ある市の人口からその市の商店数を予測する(予測)

予測したい変数のことを目的変数(または被説明変数)といいます。

また、目的変数を説明する変数のことを説明変数(または独立変数)と呼びます。

説明変数が2つ以上の時は重回帰、1つのとき特に単回帰と呼びます。

Python3.8でjupyter-notebookを動作させる

pip でインストールして動かそうとするとエラーが出ます。

ググると対応策がありました。

「C:\Python38\Lib\site-packages\tornado\platform」の「asyncio.py」の最後に下記を書き込みます。

無事に起動を確認できたので、データ前処理を進めていきます。

探索的データ解析(データの理解:EDA)

以前のjupyter-notebook利用例と同じように、データを確認します。

  • データの各特徴名とその意味の確認
  • データの取り込み(.read_csv)
  • 表の一部分表示(pandasの.head())
  • データの大きさの確認(pandasの.shape)
  • ヒストグラムによる分布の可視化(.hist)
  • 特徴量ごとの平均値、最大値、最小値などの統計量確認(pandasの.describe())
  • 欠損値チェック(pandasの.isnull().sum())
  • 型チェック(pandasの.dtypes())
  • ヒートマップによる相関の強い特徴量チェック(heatmap)
  • 外れ値の確認(.regplot)
  • 散布図や箱ひげ図を用いた目的変数と、説明変数の関係の可視化(.boxplot)
  • 時系列データであれば、時系列トレンドの可視化

なお、綺麗なグラフが描写できる「seaborn」も利用しながら可視化しています。

データの各特徴名とその意味の確認

Kaggleの提供しているデータ「data_description.txt」に変数にどんなデータが格納されているのか説明があります。

タイタニックと比べて非常に説明変数が多く、79項目(+価格1項目)あります。

BsmtFullBath:地下フルバスルーム
BsmtHalfBath:地下ハーフバスルーム
FullBath:グレード以上のフルバスルーム
HalfBath:グレード以上のハーフバス
Bedroom:地下室より上の寝室の数
Kitchen:キッチンの数
KitchenQual:キッチンの質

などが、数字や文字列、5段階等で評価されていることが分かります。

なお、今回は「SalePrice」を予測するのがミッションです。

SalePrice – the property’s sale price in dollars. This is the target variable that you’re trying to predict.

データが少なければ一つずつの意味を把握したいですが、今の時点では必要に応じて確認することにします。

データの取り込み(.read_csv)

ファイル形式によって、色々な方法があります。

因みに、カラム名を変えるには次のように記載します。

今回はCSVファイルなので次のように取り込みます。

表の一部分表示(pandasの.head())

まずは、データがどういう構造なのか探っていきます。

欠損値が多く、文字列情報も多く含まれているようです。

データの大きさの確認(pandasの.shape)

変数の数を確認してみます。

81変数あり1460件の住宅情報が含まれている事が分かります。

ヒストグラムによる分布の可視化(.hist)

今度は視覚化するためにヒストグラムで出力してみます。

出力結果です。

「SalePrice」が正規分布となっていないようにみえます。

特徴量ごとの平均値、最大値、最小値などの統計量確認(pandasの.describe())

回帰(Regression)分析の場合、ターゲットの値がどちらかに偏らず正規分布に従っていることが重要です。

「SalePrice」の統計量を確認します。

50%が16万なのに対して、平均(mean)が18万となっています。

また、最小値(min)が3万、最大値(max)が75万なので偏っており、正規分布ではありません。

特徴エンジニアリングの際に、対数変換が必要です。

欠損値チェック(pandasの.isnull().sum())

データ分析において、欠損値の処理は1つの重要なポイントです。

Kaggleでもスピード重視でこのパートを雑に行うとパフォーマンスが上がりません。

0より大きい数で降順にソートをかけ欠損値を確認します。

凄い数の欠損があります・・・・。

可視化は次のように記載します。

【matplotlibの場合】

【seabornの場合】

最も欠損が多いのはPoolQC(プールのクオリティ)です。

型チェック(pandasの.dtypes())

欠損値を含む列のデータタイプを確認します。

PoolQC(プールのクオリティ)は欠損が大量にあり、更に文字列のデータした。

このカラムは削除したくなります。

ですが、Kaggleの提供しているデータ「data_description.txt」に「PoolQC(プールのクオリティ)」を再確認すると次のように記載されています。

PoolQC: Pool quality

Ex Excellent
Gd Good
TA Average/Typical
Fa Fair
NA No Pool

つまり、NaN(欠損)は「No Pool」の事であり、データの欠損そのものが情報となっています。

他の変数を確認しても欠損の意味は同じようです。

変数 意味
PoolQC: Pool quality 備え付けられているプールの質を表す。プールがない場合にはNA
MiscFeature: Miscellaneous feature not covered in other categories その他の備え付けられている設備を表す。エレベータやテニスコートなど。特にない場合はNA
Alley: Type of alley access to property 物件にアクセスするための道の種類(砂利なのか舗装されているのか)を表す。該当しない場合はNA
Fence: Fence quality フェンスの質を表す。フェンスがない場合はNA
FireplaceQu: Fireplace quality 暖炉の品質を表す。暖炉がない場合はNA
LotFrontage: Linear feet of street connected to property 物件に隣接した道路の長さ

このため、欠損データの補完方法を考える必要があります。

ヒートマップによる相関の強い特徴量チェック(heatmap)

分析方針を立てるために、何の変数が「SalePrice(施設の売却価格)」と強い相関があるが一気に確認しておきましょう。

この結果から以下の点が読み取れます。

SalePrice(施設の売却価格)と強い相関がある

  • OverallQual:全体的な素材と仕上げの品質
  • GrLivArea:上階(地面)のリビングエリア平方フィート
  • GarageCars:車庫のサイズ
  • TotalBsmtSF:地下室の総平方フィート

強い相関がある(多重共線性の点から一つに絞る必要がある)

  • GarageCars:車庫のサイズ
  • GarageArea:車庫サイズ
  • TotalBsmtSF:地下室の総平方フィート
  • 1stFlrSF:1階平方フィート
  • GrLivArea:上階(地面)のリビングエリア平方フィート
  • TotRmsAbvGrd:グレード以上の総客室数
  • 2ndFlrSF:2階平方フィート
  • FullBath:グレード以上のフルバスルーム
  • YearBuilt:元の建設日
  • Foundation:基礎、基盤の種類

「GarageCars」「GarageArea」などは項目の意味からも相関の強さは明らかで、これらは多重共線性を引き起こします。

※ 最も一般的な解消法は、「相関関係が高いと考えられる説明変数を外すこと」です

このような状況を検出するのにヒートマップは便利です。

外れ値の確認

TotalBsmtSF(地下室の総平方フィート)はSalePrice(施設の売却価格)と強い相関がありました。

変数を見るとTotalBsmtSF以外にも物件の大きさを表しているものがあります。

  • 1stFlrSF: 1階の広さ
  • 2ndFlrSF: 2階の広さ
  • TotalBsmtSF:地下の広さ
  • GrLivArea:上階(地面)のリビングエリア平方フィート

こちらの合計の変数の外れ値を確認します。

TotalSFが10000より小さく、SalePriceが300000より小さい場合は除去できそうです。

より詳細に確認したい場合は次のように記載できます。

散布図や箱ひげ図を用いた目的変数と、説明変数の関係の可視化

OverallQual(全体的な素材と仕上げの品質)はSalePrice(施設の売却価格)と相関が高かったので、外れ値の確認をしてみます。

「箱ひげ図」を出力して確認してみます。

OverallQualが10より小さく、SalePriceが500000より大きい場合は除去できそうです。

また、OverallQualが5より小さく、SalePriceが200000より大きい場合は除去できそうです。

最後に、散布図に出力して俯瞰します。

全部出力するのは多すぎるので、相関の高い上位20変数を出力しています。

外れ値がまだ多くあるようです。

マニュアルで地道に削除することになります。

テストデータのみに存在する変数確認

学習データには存在せず、テストデータのみに存在するカテゴリ変数が存在するか確認します。

なぜなら、学習モデルがそのカテゴリを学習できず、予測値がおかしくなる可能性があるためです。

今回は、学習データの中に数が0となっているカテゴリ変数はありません。

まとめ

タイタニックのチュートリアルで行った確認方法と同じですが、細かい確認が多いです。

この辺りは、他のデータを使っても同じかと思うのでライブラリ化しておきたいです。

タイトルとURLをコピーしました