Data Every Day: 不動産データセット

# tldr

Kggleの[Real Estate DataSet](https://www.kaggle.com/arslanali4343/real-estate-dataset)を[Predicting Real Estate Value With Random Forests - Data Every Day #086](https://www.youtube.com/watch?v=HdOhQ1Qa_tk&list=PLs_CQl4mUvI7Z9HnwoeOS5EUu9gyvekjK&index=86)に沿ってやっていきます。

実行環境はGoogle Colaboratorです。

# インポート


```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

import sklearn.preprocessing as sp
from sklearn.model_selection import train_test_split
import sklearn.linear_model as slm
from sklearn.ensemble import RandomForestRegressor
```

# データのダウンロード

Google Driveをマウントします。


```python
from google.colab import drive
drive.mount('/content/drive')
```

    Mounted at /content/drive


KaggleのAPIクライアントを初期化し、認証します。
認証情報はGoogle Drive内（`/content/drive/My Drive/Colab Notebooks/Kaggle`）に`kaggle.json`として置いてあります。


```python
import os
kaggle_path = "/content/drive/My Drive/Colab Notebooks/Kaggle"
os.environ['KAGGLE_CONFIG_DIR'] = kaggle_path

from kaggle.api.kaggle_api_extended import KaggleApi
api = KaggleApi()
api.authenticate() 
```

Kaggle APIを使ってデータをダウンロードします。


```python
dataset_id = 'arslanali4343/real-estate-dataset'
dataset = api.dataset_list_files(dataset_id)
file_name = dataset.files[0].name
file_path = os.path.join(api.get_default_download_dir(), file_name)
file_path
```

    Warning: Looks like you're using an outdated API Version, please consider updating (server 1.5.10 / client 1.5.9)





    '/content/data.csv'




```python
api.dataset_download_file(dataset_id, file_name, force=True, quiet=False)
```

    100%|██████████| 34.6k/34.6k [00:00<00:00, 5.74MB/s]

    Downloading data.csv to /content
    


    





    True



# データの読み込み

Padasを使ってダウンロードしてきたCSVファイルを読み込みます。


```python
data = pd.read_csv(file_path)
```


```python
data
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>CRIM</th>
      <th>ZN</th>
      <th>INDUS</th>
      <th>CHAS</th>
      <th>NOX</th>
      <th>RM</th>
      <th>AGE</th>
      <th>DIS</th>
      <th>RAD</th>
      <th>TAX</th>
      <th>PTRATIO</th>
      <th>B</th>
      <th>LSTAT</th>
      <th>MEDV</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0.00632</td>
      <td>18.0</td>
      <td>2.31</td>
      <td>0</td>
      <td>0.538</td>
      <td>6.575</td>
      <td>65.2</td>
      <td>4.0900</td>
      <td>1</td>
      <td>296</td>
      <td>15.3</td>
      <td>396.90</td>
      <td>4.98</td>
      <td>24.0</td>
    </tr>
    <tr>
      <th>1</th>
      <td>0.02731</td>
      <td>0.0</td>
      <td>7.07</td>
      <td>0</td>
      <td>0.469</td>
      <td>6.421</td>
      <td>78.9</td>
      <td>4.9671</td>
      <td>2</td>
      <td>242</td>
      <td>17.8</td>
      <td>396.90</td>
      <td>9.14</td>
      <td>21.6</td>
    </tr>
    <tr>
      <th>2</th>
      <td>0.02729</td>
      <td>0.0</td>
      <td>7.07</td>
      <td>0</td>
      <td>0.469</td>
      <td>7.185</td>
      <td>61.1</td>
      <td>4.9671</td>
      <td>2</td>
      <td>242</td>
      <td>17.8</td>
      <td>392.83</td>
      <td>4.03</td>
      <td>34.7</td>
    </tr>
    <tr>
      <th>3</th>
      <td>0.03237</td>
      <td>0.0</td>
      <td>2.18</td>
      <td>0</td>
      <td>0.458</td>
      <td>6.998</td>
      <td>45.8</td>
      <td>6.0622</td>
      <td>3</td>
      <td>222</td>
      <td>18.7</td>
      <td>394.63</td>
      <td>2.94</td>
      <td>33.4</td>
    </tr>
    <tr>
      <th>4</th>
      <td>0.06905</td>
      <td>0.0</td>
      <td>2.18</td>
      <td>0</td>
      <td>0.458</td>
      <td>7.147</td>
      <td>54.2</td>
      <td>6.0622</td>
      <td>3</td>
      <td>222</td>
      <td>18.7</td>
      <td>396.90</td>
      <td>5.33</td>
      <td>36.2</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>506</th>
      <td>0.98765</td>
      <td>0.0</td>
      <td>12.50</td>
      <td>0</td>
      <td>0.561</td>
      <td>6.980</td>
      <td>89.0</td>
      <td>2.0980</td>
      <td>3</td>
      <td>320</td>
      <td>23.0</td>
      <td>396.00</td>
      <td>12.00</td>
      <td>12.0</td>
    </tr>
    <tr>
      <th>507</th>
      <td>0.23456</td>
      <td>0.0</td>
      <td>12.50</td>
      <td>0</td>
      <td>0.561</td>
      <td>6.980</td>
      <td>76.0</td>
      <td>2.6540</td>
      <td>3</td>
      <td>320</td>
      <td>23.0</td>
      <td>343.00</td>
      <td>25.00</td>
      <td>32.0</td>
    </tr>
    <tr>
      <th>508</th>
      <td>0.44433</td>
      <td>0.0</td>
      <td>12.50</td>
      <td>0</td>
      <td>0.561</td>
      <td>6.123</td>
      <td>98.0</td>
      <td>2.9870</td>
      <td>3</td>
      <td>320</td>
      <td>23.0</td>
      <td>343.00</td>
      <td>21.00</td>
      <td>54.0</td>
    </tr>
    <tr>
      <th>509</th>
      <td>0.77763</td>
      <td>0.0</td>
      <td>12.70</td>
      <td>0</td>
      <td>0.561</td>
      <td>6.222</td>
      <td>34.0</td>
      <td>2.5430</td>
      <td>3</td>
      <td>329</td>
      <td>23.0</td>
      <td>343.00</td>
      <td>76.00</td>
      <td>67.0</td>
    </tr>
    <tr>
      <th>510</th>
      <td>0.65432</td>
      <td>0.0</td>
      <td>12.80</td>
      <td>0</td>
      <td>0.561</td>
      <td>6.760</td>
      <td>67.0</td>
      <td>2.9870</td>
      <td>3</td>
      <td>345</td>
      <td>23.0</td>
      <td>321.00</td>
      <td>45.00</td>
      <td>24.0</td>
    </tr>
  </tbody>
</table>
<p>511 rows × 14 columns</p>
</div>



# 下準備


```python
data.info()
```

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 511 entries, 0 to 510
    Data columns (total 14 columns):
     #   Column   Non-Null Count  Dtype  
    ---  ------   --------------  -----  
     0   CRIM     511 non-null    float64
     1   ZN       511 non-null    float64
     2   INDUS    511 non-null    float64
     3   CHAS     511 non-null    int64  
     4   NOX      511 non-null    float64
     5   RM       506 non-null    float64
     6   AGE      511 non-null    float64
     7   DIS      511 non-null    float64
     8   RAD      511 non-null    int64  
     9   TAX      511 non-null    int64  
     10  PTRATIO  511 non-null    float64
     11  B        511 non-null    float64
     12  LSTAT    511 non-null    float64
     13  MEDV     511 non-null    float64
    dtypes: float64(11), int64(3)
    memory usage: 56.0 KB


## 欠損値の処理


```python
data['RM'] = data['RM'].fillna(data['RM'].mean())
```


```python
data.isna().sum().sum()
```




    0



# X, Yデータの分割


```python
y = data['MEDV']
X = data.drop('MEDV', axis=1)
```

# スケーリング


```python
scaler = sp.StandardScaler()
X = scaler.fit_transform(X)
```

# トレーニング、テストデータの分割


```python
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7)
```

# トレーニング


```python
no_bootstrap_model = RandomForestRegressor(n_estimators=100, criterion='mse', bootstrap=False)
no_bootstrap_model.fit(X_train, y_train)
```




    RandomForestRegressor(bootstrap=False, ccp_alpha=0.0, criterion='mse',
                          max_depth=None, max_features='auto', max_leaf_nodes=None,
                          max_samples=None, min_impurity_decrease=0.0,
                          min_impurity_split=None, min_samples_leaf=1,
                          min_samples_split=2, min_weight_fraction_leaf=0.0,
                          n_estimators=100, n_jobs=None, oob_score=False,
                          random_state=None, verbose=0, warm_start=False)




```python
bootstrap_model = RandomForestRegressor(n_estimators=100, criterion='mse', bootstrap=True)
bootstrap_model.fit(X_train, y_train)
```




    RandomForestRegressor(bootstrap=True, ccp_alpha=0.0, criterion='mse',
                          max_depth=None, max_features='auto', max_leaf_nodes=None,
                          max_samples=None, min_impurity_decrease=0.0,
                          min_impurity_split=None, min_samples_leaf=1,
                          min_samples_split=2, min_weight_fraction_leaf=0.0,
                          n_estimators=100, n_jobs=None, oob_score=False,
                          random_state=None, verbose=0, warm_start=False)



# 結果


```python
print('R^2 without bootstrapping:', no_bootstrap_model.score(X_test, y_test))
print('   R^2 with bootstrapping:', bootstrap_model.score(X_test, y_test))
```

    R^2 without bootstrapping: 0.46518356517728865
       R^2 with bootstrapping: 0.759932629153558


ブートストラップサンプリングを使ったモデルがかなり高い精度をだしました。