SIGNATEのBeginner限定コンペをやってみた　～アメリカの都市エイムズの住宅価格予測

# 概要
SIGNATEのBeginner限定コンペに挑戦してみました
テーマは、「アメリカの都市エイムズの住宅価格予測」でした。

データ分析は初心者なので、まずは提出するということを目標に取り組んで、この記事を執筆しています。
SIGNATEの練習問題「天秤のバランス分類」をという問題を下記記事を参考に実践したうえで挑戦してみました。

https://qiita.com/Sei123/items/c3985b5d69ccafe958c6

※ありがとうございます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507211/bf8fc393-4f82-ba40-d12c-78f0cb8261d4.png)

# アプローチ
## 手法
天秤のバランス分類では、「天秤の傾き」のみを説明変数とする単回帰モデルを使って目的変数の分類クラスを導き出すといったやり方でした。
今回の課題である住宅価格予測では、与えられている学習用データを参考に確認すると「Full Bath」「Year Built」, 「Garage Cars"」といった住宅価格に影響を与えそうなカラム列が複数見受けたので、「重回帰分析」を用いて回答を作りました。

https://data-viz-lab.com/multiple-regression-analysis

## 使った環境
開発環境：Anaconda

フォルダ構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507211/332c9948-85ef-1d59-bbc6-4d00991b2a07.png)

main.py：処理を書いてます
test.csv:テストデータ（運営からダウンロード）
train.csv:学習用データ（運営からダウンロード）
data_description.txt：(未確認　運営からダウンロード　多分カラム列の説明？が載ってる？）
sample_submit.csv：提出用のデータのサンプル　これに推論結果を加えて回答を作る（運営からダウンロード）
submit.csv:main.pyに実行によって生成されたデータ

## 処理の手順
①train.csvの読み込み
②train.csvの中から説明変数として有効そうなカラム列をチョイスする
 -数値データのもの
 ‐SalesPriceに対して相関があること
  ※今回の取り組みではちょっとここのアプローチが誤ってる、もしくは弱い
③学習用データを使って、重回帰分析の公式に基づき、②で選択した各カラムごとの係数と切片を算出する
④③で求めた式を使ってテストデータからSalesPriceを算出する
⑤提出用データに転記して提出

## コード全文
```
from sklearn.linear_model import LinearRegression

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt


#データの読み込み
train = pd.read_csv("train.csv") 


# 数値データのみを選択
numerical_columns = train.select_dtypes(include=['float64', 'int64']).columns
correlation_matrix = train[numerical_columns].corr()

# 'SalePrice'との相関が高い順に表示
correlation_with_saleprice = correlation_matrix['SalePrice'].sort_values(ascending=False)
print(correlation_with_saleprice)

# 'SalePrice'との相関が正である変数のみを選択
positive_correlation_with_saleprice = correlation_matrix['SalePrice'][correlation_matrix['SalePrice'] > 0]

top_correlated_variables = positive_correlation_with_saleprice.sort_values(ascending=False).head()
print(top_correlated_variables)

selected_columns = ["Full Bath", "Year Built", "Garage Cars", "Gr Liv Area", "Garage Area", 
                    "Overall Qual", "Total Bsmt SF", "Half Bath", "Year Remod/Add", "Fireplaces",
                    "Bsmt Full Bath", "1st Flr SF", "Bsmt Unf SF", "BsmtFin SF 1", "Lot Area",
                    "Open Porch SF", "2nd Flr SF", "Wood Deck SF"]

# 説明変数と目的変数を選択
X = train[selected_columns]
Y = train['SalePrice']

#各変数の傾きを計算
linear_regression = LinearRegression()
linear_regression.fit(X,Y)
A = linear_regression.coef_

#切片の取得
B = linear_regression.intercept_

#テスト　サンプル　データ読み込み
testFrame = pd.read_csv("test.csv")    # ファイル名は適切なものに変更してください
sample = pd.read_csv("sample_submit.csv", header=None)


testFrame['SalePrice'] = (
    testFrame['Full Bath'] * A[0] +
    testFrame['Year Built'] * A[1] +
    testFrame['Garage Cars'] * A[2] +
    testFrame['Gr Liv Area'] * A[3] +
    testFrame['Garage Area'] * A[4] +
    testFrame['Overall Qual'] * A[5] +
    testFrame['Total Bsmt SF'] * A[6] +
    testFrame['Half Bath'] * A[7] +
    testFrame['Year Remod/Add'] * A[8] +
    testFrame['Fireplaces'] * A[9] +
    testFrame['Bsmt Full Bath'] * A[10] +
    testFrame['1st Flr SF'] * A[11] +
    testFrame['Bsmt Unf SF'] * A[12] +
    testFrame['BsmtFin SF 1'] * A[13] +
    testFrame['Lot Area'] * A[14] +
    testFrame['Open Porch SF'] * A[15] +
    testFrame['2nd Flr SF'] * A[16] +
    testFrame['Wood Deck SF'] * A[17] +
    B
)

sample[1] = testFrame['SalePrice']
print(sample.head())
sample.to_csv("submit.csv",index=None,header=None)
```
## ①
```
#ライブラリの読み込み
from sklearn.linear_model import LinearRegression

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt


#データの読み込み
train = pd.read_csv("train.csv") 

#テスト　サンプル　データ読み込み
testFrame = pd.read_csv("test.csv")    # ファイル名は適切なものに変更してください
sample = pd.read_csv("sample_submit.csv", header=None)

```
from sklearn.linear_model import LinearRegression
で線形回帰モデルをインポートしている

## ②
```
# 数値データのみを選択
numerical_columns = train.select_dtypes(include=['float64', 'int64']).columns
correlation_matrix = train[numerical_columns].corr()

# 'SalePrice'との相関が高い順に表示
correlation_with_saleprice = correlation_matrix['SalePrice'].sort_values(ascending=False)
print(correlation_with_saleprice)

# 'SalePrice'との相関が正である変数のみを選択
positive_correlation_with_saleprice = correlation_matrix['SalePrice'][correlation_matrix['SalePrice'] > 0]

top_correlated_variables = positive_correlation_with_saleprice.sort_values(ascending=False).head()
print(top_correlated_variables)

selected_columns = ["Full Bath", "Year Built", "Garage Cars", "Gr Liv Area", "Garage Area", 
                    "Overall Qual", "Total Bsmt SF", "Half Bath", "Year Remod/Add", "Fireplaces",
                    "Bsmt Full Bath", "1st Flr SF", "Bsmt Unf SF", "BsmtFin SF 1", "Lot Area",
                    "Open Porch SF", "2nd Flr SF", "Wood Deck SF"]
```
SalePrice         1.000000
Full Bath         0.293996
Year Built        0.221131
Garage Cars       0.210248
Gr Liv Area       0.201057
Garage Area       0.190580
Overall Qual      0.149422
Total Bsmt SF     0.134633
Half Bath         0.130738
Year Remod/Add    0.130724
Fireplaces        0.120770
Bsmt Full Bath    0.107504
1st Flr SF        0.102831
Bsmt Unf SF       0.097631
BsmtFin SF 1      0.086038
Lot Area          0.075765
Open Porch SF     0.064211
2nd Flr SF        0.034164
Order             0.033780
Wood Deck SF      0.031295
TotRms AbvGrd     0.027719
MS SubClass       0.024983
Mo Sold           0.005314
index            -0.000678
Kitchen AbvGr    -0.017277
Yr Sold          -0.030169
Bedroom AbvGr    -0.051785
Overall Cond     -0.053452

正の相関になっているものだけを選択しているだけのため、
負の相関になっているものも含めて影響度を勘案して選択するべきな気がする

数値データ以外は切り捨てているがワンホット化もできそう

※データ選択・加工については次のステップとします。

## ③
```
# 説明変数と目的変数を選択
X = train[selected_columns]
Y = train['SalePrice']

#各変数の傾きを計算
linear_regression = LinearRegression()
linear_regression.fit(X,Y)
A = linear_regression.coef_

#切片の取得
B = linear_regression.intercept_
```
線形回帰モデルを使って各項目の係数と切片を求めてくれる便利なライブラリがpythonにはある

## ④
```
testFrame['SalePrice'] = (
    testFrame['Full Bath'] * A[0] +
    testFrame['Year Built'] * A[1] +
    testFrame['Garage Cars'] * A[2] +
    testFrame['Gr Liv Area'] * A[3] +
    testFrame['Garage Area'] * A[4] +
    testFrame['Overall Qual'] * A[5] +
    testFrame['Total Bsmt SF'] * A[6] +
    testFrame['Half Bath'] * A[7] +
    testFrame['Year Remod/Add'] * A[8] +
    testFrame['Fireplaces'] * A[9] +
    testFrame['Bsmt Full Bath'] * A[10] +
    testFrame['1st Flr SF'] * A[11] +
    testFrame['Bsmt Unf SF'] * A[12] +
    testFrame['BsmtFin SF 1'] * A[13] +
    testFrame['Lot Area'] * A[14] +
    testFrame['Open Porch SF'] * A[15] +
    testFrame['2nd Flr SF'] * A[16] +
    testFrame['Wood Deck SF'] * A[17] +
    B
)
```
重回帰モデルの公式に当てはめる
Y = b0 + b1*X1 + b2*X2 + ... + bn*Xn
※説明変数の項目数・順番の変更も勘案すると本来は動的に式を生成するのが適切
　（だけどchatGPTがあるので）

 ## ⑤
 ```
 sample[1] = testFrame['SalePrice']
print(sample.head())
sample.to_csv("submit.csv",index=None,header=None)
```
生成されたsubmit.csvを提出して終了です

# 結果
80人中66位でした

# これから
・ドメイン（背景）の精査
・天秤のように、提供されたデータから新しい特徴量の発掘（特徴量エンジニアリング）
・データクレンジング

データ分析の基礎を勉強しながら高順位を目指したいと思います。