Edited at

# データの観察

### ライブラリのインポート

import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
%matplotlib inline
from scipy.stats import skew
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

### データ数の確認

print(train.shape)

train　(1460, 81)

# 欠損値処理

### 欠損値の確認

train.isnull().sum()[train.isnull().sum()>0].sort_values(ascending=False)

• PoolQC 1453

• MiscFeature 1406

• Alley 1369

• Fence 1179

• FireplaceQu 690

• LotFrontage 259

• GarageYrBlt 81

• GarageType 81

• GarageFinish 81

• GarageQual 81

• GarageCond 81

• BsmtFinType2 38

• BsmtExposure 38

• BsmtFinType1 37

• BsmtCond 37

• BsmtQual 37

• MasVnrArea 8

• MasVnrType 8

• Electrical 1

train = train.drop(columns=["PoolQC","MiscFeature","Alley","Fence" ,"FireplaceQu" ,"LotFrontage"])

##### 残りの欠損値処理

train = pd.get_dummies(train)

train = train.fillna(train.mean())

# 新たな変数の設計

train["TotalSF"] = train["TotalBsmtSF"] + train["1stFlrSF"] + train["2ndFlrSF"] + train['GarageArea']

train['YearBuilt'] = 2011 - train['YearBuilt']

###### 新たな変数を作るときに使った変数は取り除く。

train.drop(['1stFlrSF','GarageArea',"TotalBsmtSF","2ndFlrSF"], axis=1, inplace=True)

# 可視化

#### 相関係数の大きい順に並べる。

['SalePrice', 'TotalSF', 'OverallQual', 'GrLivArea', 'GarageCars', 'ExterQual_TA', 'FullBath', 'BsmtQual_Ex', 'YearBuilt','KitchenQual_TA']

## Heatmap

###### 相関係数の大きいもの10個を選んでお互いの相関係数を表示する。

plt.figure(figsize=(12, 9))

sns.heatmap(train.loc[:,['SalePrice', 'OverallQual', 'TotalSF', 'GrLivArea', 'GarageCars',
'ExterQual_TA', 'FullBath', 'BsmtQual_Ex', 'YearBuilt',
'KitchenQual_TA']].corr(), annot=True, square=True, fmt='.2f')
plt.show()

## Pairplot

sns.pairplot(train.loc[:,[ "TotalSF", "OverallQual", "GrLivArea", 'YearBuilt',"SalePrice"]])

## 外れ値の処理

sns.jointplot('GrLivArea',"SalePrice",data= train)

###### しっかり取り除けたか確認しよう。

train = train[~((train['GrLivArea'] > 4000) & (train['SalePrice'] < 300000))]

## "OverallQual"と"SalePrice"

sns.jointplot("OverallQual","SalePrice",data= train)

このグラフを見る限り、2次関数のような振る舞いをするようにも思える。そこで、"OverallQual"については２次まで検討する。

train["OverallQual_2"]=train["OverallQual"]**2

## "SalePrice"

SalePriceについて観察する。

sns.distplot(train["SalePrice"])

plt.show()

グラフが左へ歪んでいるのが分かるだろう。そこで、対数変換を用いる。

# 対数変換

##### 全体として対数変換を行う。

train = np.log1p(train)

## 対数変換後の観察

plt.figure(figsize=(12, 9))

sns.heatmap(train.loc[:,['SalePrice', 'OverallQual',OverallQual_2' 'TotalSF', 'GrLivArea', 'GarageCars',
'ExterQual_TA', 'FullBath', 'BsmtQual_Ex', 'YearBuilt',
'KitchenQual_TA']].corr(), annot=True, square=True, fmt='.2f')
plt.show()

グラフを見るとSalePriceが11あたりより小さい部分が気になる。住宅価格が低いときのデータが少ないことや幽霊物件の可能性も考えて、今回は取り除こうと思う。

train = train[~(train['SalePrice'] < 11.1)]

plt.figure(figsize=(12, 9))

sns.heatmap(train.loc[:,['SalePrice', 'OverallQual',OverallQual_2' 'TotalSF', 'GrLivArea', 'GarageCars',
'ExterQual_TA', 'FullBath', 'BsmtQual_Ex', 'YearBuilt',
'KitchenQual_TA']].corr(), annot=True, square=True, fmt='.2f')
plt.show()

# 学習

X = train.loc[:,train.columns != "SalePrice"]

y = train.loc[:, ['SalePrice']].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 0)
las = Lasso(alpha=0.0005)
las.fit(X_train, y_train)
print("ラッソ回帰でのRMSE：",np.sqrt(mean_squared_error(las.predict(X_test), y_test)))

# 結果

ラッソ回帰でのRMSE: 0.10114175427614815

# Kaggleでの評価

public score : 0.11833

順位：　228/4649（上位4.9パーセント）

# 反省

まだまだ、改善すべきことがたくさんあると思う。とくに欠損値の処理や変数の設計をもっと厳密にする必要があると思う。ただ、データサイエンスとはどういうものなのかを知れたのはとても良かったと思う。