データ分析

# この記事の狙い・目的
機械学習を取り入れたAIシステムの構築は、
①データ分析→ ②データセット作成（前処理）→ ③モデルの構築・適用
というプロセスで行っていきます。
その際「データ分析」の段階では、正しく前処理が行えるよう、事前にデータを分析を行い、データの構造、データの傾向を解析し、その後の方針を決定していることが求められます。
このブログでは、「データ分析」の工程について初めから通して解説していきます。

# プログラムの実行環境
Python3
MacBook pro（端末）
PyCharm（IDE）
Jupyter Notebook（Chrome）
Google スライド（Chrome）

# 対象データの確認

```Python
# データ取得
boston_df = pd.read_csv("./boston.csv", sep=',')

# データ確認
boston_df.shape
boston_df.head().astype(str)
boston_df.info()
boston_df.describe().astype(str)

# 地図で確認
from IPython.display import Image
Image("./boston_area.png")
Image("./boston_river.png")
```
![スクリーンショット 2021-10-22 14.56.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/b3fe2668-72d7-3275-4c99-04fa8786e24b.png)
![スクリーンショット 2021-10-22 14.56.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/ac342e47-a41a-bddd-1ce4-d25717a60ec5.png)
![スクリーンショット 2021-10-22 14.57.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/c51fbddd-77d5-749d-744f-992b18512bb6.png)
![スクリーンショット 2021-10-22 14.57.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/e3803502-c842-9bea-e1fd-ceb2b52172eb.png)
![スクリーンショット 2021-10-22 14.57.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/a4860f04-84e2-eb5b-47da-92b6f6f598ca.png)

## 属性

**説明変数**

- CRIM：
町ごとの一人当たりの犯罪率
- ZN：
25,000平方フィートを超える区画にゾーニングされた住宅用地の割合。
- INDUS：
町ごとの非小売ビジネスエーカーの割合
- CHAS：（int）
チャールズリバーダミー変数（路が川に接している場合は1、それ以外の場合は0）
- NOX：
一酸化窒素濃度（1000万あたりのパーツ）[パーツ/10M]
- RM：
住居あたりの平均部屋数
- AGE：
1940年以前に建設された持ち家の割合
- DIS：
ボストンの5つの雇用センターまでの加重距離
- RAD：（int）
放射状高速道路へのアクセスの指標
- TAX：
全額-価値資産、10000ドルあたりの税率($/10k)
- PTRATIO：
町ごとの生徒と教師の比率
- B：
方程式B = 1000（Bk-0.63）^2の結果。ここで、Bkは町ごとの黒人の割合です。
- LSTAT：
人口の％低いステータス

**目的変数**

- MEDV：
持ち家の中央値（1000ドル単位）

## データ型、尺度
- 質的データ
  - 名義尺度：CHAS（2値）
  - 順序尺度：なし

- 量的データ
  - 間隔尺度：RM、DIS、RAD
  - 比例尺度：CRIM、ZN、INDUS、NOX、AGE、TAX、PTRATIO、B、MEDV

# 目的変数の確認

```Python
import warnings
warnings.filterwarnings('ignore')

# 正規分布を重ねて描画する
from scipy.stats import norm
plt.figure(figsize=[8,3])
sns.distplot(boston_df['MEDV'], kde=True, fit=norm, fit_kws={'label': '正規分布'}).grid()
plt.legend()

# QQ Plot
plt.figure(figsize=[8,3])
plt.grid()
stats.probplot(boston_df['MEDV'], dist="norm", plot=plt)

# コルモゴロフ・スミルノフ検定(K-S検定)
from scipy import stats
stats.kstest(boston_df['MEDV'], 'norm')
```
![スクリーンショット 2021-10-22 15.03.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/ead8dbaf-8c09-6a0f-78fd-7157793d793e.png)
![スクリーンショット 2021-10-22 15.04.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/a481de82-96c8-b50d-ab3a-4faa4ca09566.png)
帰無仮説=正規分布と一致している
対立仮説=正規分布と一致していない

p値=0.0(四捨五入した値)のため、帰無仮説が棄却される。（正規分布と一致していない）
線形モデルの場合は、正規分布に変換した方が良さそう。

# 欠損値の確認

```Python
boston_df.isnull().sum()
```
![スクリーンショット 2021-10-22 15.04.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/bcd0b959-4b34-435d-e84a-e04cf6e07845.png)
欠損値は含まれない。

# 外れ値の確認

```Python
# 箱ひげ図
def hige_graph(cols):
    fig, ax = plt.subplots()
    data_ = []
    for col in cols:
        data_.append(boston_df[col])
    ax.set_title('箱ひげ図')
    ax.boxplot(data_, labels=cols)
    plt.grid()
    plt.show()


# 全項目
all_col = boston_df.columns
hige_graph(cols=all_col)
```
![スクリーンショット 2021-10-22 15.05.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/48d2d385-d90a-fc7f-2b77-6b4353e7a821.png)

```Python
plt.grid()
sns.countplot(boston_df["ZN"])

plt.figure(figsize=[10,3])
sns.boxplot(data=boston_df, x='CRIM').grid()

plt.figure(figsize=[10,3])
sns.boxplot(data=boston_df, x='B').grid()

sns.lmplot(x='B',y='CRIM',data=boston_df,aspect=5,height=5)

sns.lmplot(x='CRIM',y='B',data=boston_df,aspect=5,height=5)
```

![スクリーンショット 2021-10-22 15.05.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/c132aa7f-3ebc-9ec1-2055-857be4ba0331.png)
![スクリーンショット 2021-10-22 15.05.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/68264bfe-efd6-cd79-301d-1397a36e36b5.png)
![スクリーンショット 2021-10-22 15.05.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/00ce2a9e-4e9c-8142-b825-9c7d28eac7e8.png)
![スクリーンショット 2021-10-22 15.05.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/6a65c03e-a1cf-00b5-10bf-f20bd63d3282.png)
![スクリーンショット 2021-10-22 15.06.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/18d581d8-e096-9b05-72db-6eb292ca9546.png)

- CRIM
  - 外れ値（80）を含む。犯罪率80%は疑わしい値。線形モデルを使用する場合はこの外れ値を除去する。
- B
  - 何%で切るか難しいところだが、0.1〜10%台は全体の1.5%。除外しても良いかもしれない。

# 単・多変量データ解析
## 単変量データ解析

```Python
boston_df.hist(bins=10, figsize=(20,15))
```
![スクリーンショット 2021-10-22 15.08.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/5b9e60e0-b40f-09f7-4325-752939362362.png)

```Python
plt.figure(figsize=[20,5])
sns.distplot(boston_df['CRIM']).grid()

plt.figure(figsize=[20,5])
sns.distplot(boston_df['B'], bins=100).grid()

plt.figure(figsize=[8,3])
sns.distplot(boston_df[boston_df['B']<200], bins=10).grid()
```
![スクリーンショット 2021-10-22 15.10.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/e00d8563-9a35-f66c-2b00-771863ae4269.png)
![スクリーンショット 2021-10-22 15.10.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/abfd38fb-a19b-ba7a-fc29-7caf1c8ddfe2.png)
![スクリーンショット 2021-10-22 15.10.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/82311469-6760-35c8-c7a6-950c83729a5a.png)

```Python
def sns_distplot(col_name, bins):
    import warnings
    warnings.filterwarnings('ignore')
    plt.figure(figsize=[8,3])
    sns.distplot(boston_df[col_name], bins=bins).grid()

sns_distplot(col_name='INDUS', bins=10)

sns_distplot(col_name='CHAS', bins=10)

sns_distplot(col_name='NOX', bins=10)

sns_distplot(col_name='RM', bins=10)

sns_distplot(col_name='AGE', bins=10)

sns_distplot(col_name='DIS', bins=10)

sns_distplot(col_name='RAD', bins=10)

sns.countplot(boston_df["RAD"]).grid()

sns_distplot(col_name='TAX', bins=10)

sns_distplot(col_name='PTRATIO', bins=10)

sns_distplot(col_name='LSTAT', bins=10)
```
![スクリーンショット 2021-10-22 15.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/4a5c0660-8277-dbad-8222-5a0d7d94daf2.png)
![スクリーンショット 2021-10-22 15.11.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/ba5e43b7-e919-5f43-1e05-1f84abae3c5b.png)
![スクリーンショット 2021-10-22 15.11.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/e5b50e16-bbb3-ed0c-9601-923fcb65cd1d.png)
![スクリーンショット 2021-10-22 15.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/3299ef04-d004-0008-4544-935e0fbc46f5.png)
![スクリーンショット 2021-10-22 15.11.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/f3d6311c-962e-031a-cab0-a4fb3c2ba9ef.png)
![スクリーンショット 2021-10-22 15.11.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/d4827a32-e018-788f-a856-b66cf66770e4.png)
![スクリーンショット 2021-10-22 15.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/5026477d-2bd6-a4fa-d354-86db90203c6d.png)
![スクリーンショット 2021-10-22 15.12.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/00d25f33-a33c-77ea-5901-cf634ba0b4ee.png)
![スクリーンショット 2021-10-22 15.12.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/c2553f95-f5d5-9769-9a37-af799dbd1dd4.png)
![スクリーンショット 2021-10-22 15.12.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/1dd67d97-6249-d99f-afc8-cf2b57ff683d.png)
![スクリーンショット 2021-10-22 15.12.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/74966442-365a-4f4c-c334-ca4b5afcacb2.png)

NOX, RM, DIS, PTRATIO, LSTAT, MEDV
モデリングに線形モデルを用いる場合、正規分布に変換（近づける）する処理を施す。

## 多変量データ解析
### 相関分析
```Python
# 散布図行列
pd.plotting.scatter_matrix(boston_df, c='blue', figsize=(20, 20))
```
![スクリーンショット 2021-10-22 15.14.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/b1c58e97-4d83-75cd-b1cb-8e12c5b4b937.png)

```Python
# ヒートマップ1
plt.figure(figsize=(7, 7))
sns.heatmap(pd.DataFrame(boston_df).corr(method='pearson'), annot=False, vmin=-1, vmax=1, cmap='bwr', cbar=True)

# ヒートマップ2
plt.figure(figsize=(7, 7))
sns.heatmap(pd.DataFrame(boston_df).corr(method='spearman'), annot=False, vmin=-1, vmax=1, cmap='bwr', cbar=True)
```
![スクリーンショット 2021-10-22 15.14.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/6b381b69-e4cd-0bb0-ea0b-64a939c41469.png)
![スクリーンショット 2021-10-22 15.14.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/481178a1-7bca-762b-5bf6-51bd50037e8c.png)

- 非線形で相関のありそうな変数
  - CRIM: INDUS, NOX, RM, RAD, TAX
  - INDUS: NOX, DIS
  - NOX: AGE, DIS
  - AGE: DIS
  - RAD: TAX
  - MEDV: LSTAT
- 相関の弱い変数
  - CHAS: 単体では不要そう

```Python
# 目的変数との関係性を確認
def target_relation(tgt, data):
    y_train = data[tgt]

    # ヒートマップの表示数
    k = len(data.columns)
    fig = plt.figure(figsize=(20,20))

    # 各変数間の相関係数
    corrmat = data.corr()

    # リストの最大値から順にk個の要素を取得
    cols = corrmat.nlargest(k, tgt)[tgt].index

    # 全て可視化
    for i in np.arange(1, k):
        X_train = data[cols[i]]
        ax = fig.add_subplot(4,4, i)
        sns.regplot(x=X_train, y=y_train)
    
    plt.tight_layout()
    plt.show()
```
![スクリーンショット 2021-10-22 15.15.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/2b0a8d73-1788-4f58-d928-e5e9ca377bf6.png)

```Python
sns.jointplot(x='MEDV', y='RM', data=boston_df)

sns.jointplot(x='MEDV', y='LSTAT', data=boston_df)
```
![スクリーンショット 2021-10-22 15.15.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/9192d5cd-0a86-92db-673d-d4448681acdb.png)
![スクリーンショット 2021-10-22 15.15.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/3d558898-8fc5-2057-0df6-c2a071976456.png)
RM, LSTATは目的変数と線形性が関係がある。

```Python
fig = px.box(boston_df, x="CHAS", y="MEDV", color="CHAS", width=600, height=400)
fig.show()
```
![スクリーンショット 2021-10-22 15.17.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/9e692629-fd11-14c9-5716-63b146356ce9.png)
川に面している住宅（CAHS＝1）価格の方が、少し高い。
CAHS＝０で高級住宅は、外れ値となっている。

```Python
fig = px.box(boston_df, x="RAD", y="MEDV", color="RAD")
fig.show()
```
![スクリーンショット 2021-10-22 15.18.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/24da4b23-b5fe-64a4-26de-d5164fe8399b.png)
低価格帯は、RAD=24しかカバーできていない。

```Python
fig = px.scatter (boston_df, x = "MEDV", y = "RM", color = "CHAS",  trendline="ols")
fig.show()

fig = px.scatter(boston_df, x = "MEDV", y = "RM", color = "RAD",  trendline="ols")
fig.show()
```
![スクリーンショット 2021-10-22 15.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/74843df5-43d0-c882-5bc7-7f25aca78a97.png)
![スクリーンショット 2021-10-22 15.19.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/2bb60be3-ac05-3553-25a6-859129631633.png)
CHAS=0はノイズを含んでいる。

```Python
fig = px.scatter (boston_df, x = "MEDV", y = "LSTAT", color = "CHAS",  trendline="ols")
fig.show()

fig = px.scatter (boston_df, x = "MEDV", y = "LSTAT", color = "RAD",  trendline="ols")
fig.show()

fig = px.scatter (boston_df, x = "MEDV", y = "LSTAT", color = "AGE",  trendline="ols")
fig.show()
```
![スクリーンショット 2021-10-22 15.19.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/4fe8e041-6cb5-abed-0632-9b1466fbbcbe.png)
![スクリーンショット 2021-10-22 15.19.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/6acc1aed-7ab8-c60d-7d40-5479757e0489.png)
![スクリーンショット 2021-10-22 15.19.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/8c9c5a92-039b-fe5d-e78e-6f61ebfc9279.png)
RAD=24は外れる傾向がある。
AGE=80代以上は外れる傾向がある。

### 割合の確認
```Python
# 積み立て棒グラフ
def stack_graph(columns):
    tgt_df = pd.DataFrame()
    for i in range(24):
        tgt_df['RAD' + str(i+1)] = boston_df[boston_df['RAD'] == i+1][columns].mean()

    plt.figure(figsize=[20,5])
    my_plot = tgt_df.T.plot(kind='bar', stacked=True, title="各クラスタの平均")
    my_plot.set_xticklabels(my_plot.xaxis.get_majorticklabels(), rotation=0)
    plt.grid()

columns = ['RAD', 'MEDV', 'CRIM', 'DIS']
stack_graph(columns)

columns = ['RAD', 'MEDV', 'AGE']
stack_graph(columns)
```
![スクリーンショット 2021-10-22 15.20.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/146e0115-df07-25bd-8bff-4a042444ed86.png)
![スクリーンショット 2021-10-22 15.20.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569276/3cc5f69a-6f02-3ae9-ea95-22fe94b51690.png)
RAD1~8は傾向が似ているが、各要素の割合は若干異なる。
RAD24は要素の割合が大きく異なる。

# まとめ
今回はボストンの住宅価格データを用いてデータの解析を行なってきました。
項目数はあまり多くはありませんが、その中で目的変数と関係性の高そうな項目、他の項目と組み合わせて影響のありそうな項目、関係性の低い効かなそうな項目が見えてきました。
この考察を元に、次回前処理を行なっていきます。

# 最後に
他の記事はこちらでまとめています。是非ご参照ください。
##
https://qiita.com/tk-tatsuro/items/b72e418724ceb78e4af9
##

# 解析結果
[実装結果：GitHub/boston_regression_analytics.ipynb](https://github.com/tk-tatsuro/data_science/blob/master/20211018_boston_regression/boston_regression_analytics.ipynb)
[データセット：Boston House Prices-Advanced Regression Techniques](https://www.kaggle.com/fedesoriano/the-boston-houseprice-data)

# 参考資料
##
https://www.amazon.co.jp/%E3%83%87%E3%83%BC%E3%82%BF%E8%A7%A3%E6%9E%90%E3%81%AE%E5%AE%9F%E5%8B%99%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E5%85%A5%E9%96%80-%E3%81%82%E3%82%93%E3%81%A1%E3%81%B9/dp/4627817711
##