LoginSignup
3
2

More than 3 years have passed since last update.

SIGNATE Quest③ 宿泊価格推定

Last updated at Posted at 2020-08-27

もくじ:回帰問題の処理手順

①欠損値の処理(①と②を繰り返す)
②基本的手順に沿ってデータの特徴を把握する
  基本統計量
  可視化
③特徴量生成
④重回帰モデルの作成と予測の実行
⑤予測結果の評価(RMSE)
⑥モデルの予測精度改善(⑤に戻る)

欠損値の処理

2020-08-24_23h38_36.png

2020-08-24_23h39_13.png

2020-08-24_23h39_33.png

2020-08-24_23h41_43.png

2020-08-24_23h43_09.png

2020-08-24_23h44_00.png

2020-08-24_23h45_23.png

2020-08-24_23h45_43.png

2020-08-24_23h46_21.png

2020-08-24_23h46_31.png

重要な関数

  DataFrame.isnull().sum()
  DataFrame.dropna()
  DataFrame.fillna()

データ操作

# bedsがNaNになっているデータの抜き出し(SQLで言う select * where )
beds_nan_data = DataFrame[DataFrame['beds'].isnull()]

# bed_typeの種類ごとの件数を表示
print(beds_nan_data['bed_type'].value_counts())

# beds,bedrooms,bathroomsに欠損値を含むデータを削除
data = data.dropna(subset=['beds','bedrooms','bathrooms'])

# 変数mean_valにreview_scores_ratingの平均値を代入してください。
mean_val = data['review_scores_rating'].mean()

# review_scores_ratingの欠損値を平均値で補完してください。
data['review_scores_rating'] = data['review_scores_rating'].fillna(mean_val)

データの可視化

2020-08-25_23h14_27.png

2020-08-25_23h15_02.png

2020-08-26_08h29_14.png

2020-08-26_08h30_24.png

2020-08-26_08h31_06.png

2020-08-26_08h31_54.png

2020-08-26_08h33_12.png

2020-08-26_08h44_51.png

2020-08-26_08h45_12.png

2020-08-26_08h46_10.png

2020-08-26_08h46_26.png

基本統計量

#要素の内容を表示
print(DataFrame['カラム名'].unique())
#要素の数を表示
print(DataFrame['カラム名'].nunique())
#重要:要素ごとの数を降順で表示
print(DataFrame['カラム名'].value_counts())

#2,4,7,7,10,12,13,17,20,22,30の統計量を表示する
#平均値、中央値、最大値などの値と最頻値を表示
s = pd.Series([2,4,7,7,10,12,13,17,20,22,30])
print(s.describe())
print(s.mode())

ヒストグラム、棒グラフ

# 変数dataからy列のみを抜き出し、変数yに代入しましょう
y = data['y']
# ヒストグラムの可視化
y.plot.hist(title='宿泊価格')
# 可視化結果を表示する為に必要な関数
plt.show()

# value_counts()の結果を棒グラフで表示
v = data['カラム名'].value_counts()
v.plot.bar()
plt.show()

外れ値の削除

# yが10以上のデータを抽出したい(10未満を削除したい)ので、条件はdata['y'] >= 10

# 削除前の行数を確認
before_rows = data.shape[0]
print(before_rows)

# 削除
data = data[data['y'] >= 10]

# 削除後の行数を確認
after_rows = data.shape[0]
print(after_rows)

箱ひげ図の描画

# 箱ひげ図の描画
sns.boxplot(data=DataFrame, x='横カラム名', y='縦カラム名')

# 表示範囲を制限
plt.ylim(0,600)

plt.show()

散布図の描画

DataFrame.plot.scatter(x='横カラム名', y='縦カラム名')
plt.show()

複数の条件で抜き出す

# dataからbathroomsが0.0でyが1000ドル以上のデータを抜き出して、表示させてください。
# 複数条件を満たす場合は DataFrame[(条件) & (条件)]
data_tmp = data[(data['bathrooms']==0.0) & (data['y'] >= 1000)]

特徴量の加工

2020-08-26_14h04_06.png

2020-08-26_14h05_22.png

2020-08-26_14h05_44.png

2020-08-26_14h06_38.png

2020-08-26_14h07_14.png

2020-08-26_14h07_37.png

関数

2020-08-26_15h12_14.png

2020-08-26_15h12_51.png

2020-08-26_15h12_58.png

自作関数だと関数を定義した後に関数を呼び出す必要があるが、lambda関数だと関数定義と呼び出しが1行でできる。

2020-08-26_15h13_42.png

2020-08-26_15h13_58.png

# property.csvを読み込んで変数dataに代入しましょう。
mydata = pd.read_csv('property.csv')

# cleaning_feeがt,fになっているので1,0に変換してください。
def change_tf(x):
    if x == 't':
        return 1
    elif x == 'f':
        return 0
mydata['cleaning_fee'] = mydata['cleaning_fee'].apply(change_tf)

評価関数

2020-08-26_17h14_40.png

2020-08-26_17h15_24.png

2020-08-26_17h15_37.png

2020-08-26_17h16_43.png

2020-08-26_17h18_23.png

2020-08-26_17h18_33.png

2020-08-26_17h19_06.png

RMSEの計算方法

# ライブラリのインポート
import numpy as np
from sklearn.metrics import mean_squared_error as MSE

# 変数の準備
actual = [3,4,6,2,4,6,1]
pred = [4,2,6,5,3,2,3]

# MSEの算出
mse = MSE(actual,pred)
print(mse)

# RMSEの算出
rmse = np.sqrt(mse)
print(rmse)

RMSEはscikit-learnに実装されていません。RMSEの平方根を取る前の値であるMSE(Mean Squared Error)は実装されています。MSEの平方根をとる部分を実装することでRMSEを算出しています。

線形回帰モデル

2020-08-26_17h32_04.png

2020-08-26_17h33_14.png

2020-08-26_17h33_31.png

# LinearRegressionをインポートしましょう。
from sklearn.linear_model import LinearRegression

# モデルの準備
lr = LinearRegression()

# モデルを学習
lr.fit(X_train, y_train)

# 偏回帰係数の表示
print(pd.DataFrame(lr.coef_, index=X_train.columns))

# 切片の表示
print(lr.coef_)

# X_trainに対して予測するように空欄を埋めてください。
y_pred_train = lr.predict(X_train)

# 予測結果の確認
print(y_pred_train)

# 結果を丸めて表示
chk = int(round(y_pred_train[1]))

まとめ:説明変数、データ分割、モデル作成、モデル評価(RMSE)

# 予測に使用する説明変数、データ分割、モデル作成、モデル評価(RMSE)
select_columns = ['room_type','accommodates','bed_type','bathrooms','cleaning_fee']
dummy_data = pd.get_dummies(data[select_columns],drop_first=True)

X_train,X_test,y_train,y_test = train_test_split(dummy_data, data['y'], random_state = 1234)

lr = LinearRegression()
lr.fit(X_train, y_train)

y_pred_train = lr.predict(X_train)

# X_trainのRMSEを算出
rmse_train = np.sqrt(MSE(y_train, y_pred_train))

# 評価用に残しておいたX_testを使って予測
y_pred_test = lr.predict(X_test)

# X_testの予測に対するRMSEの算出
rmse_test = np.sqrt(MSE(y_test,y_pred_test))

# 学習および評価データに対するRMSEを表示
print(rmse_train)
print(rmse_test)

testデータに対するRMSEが約131であることから、このモデルは評価用データに対しては、実際の宿泊価格に対して、平均して131ドル程度の誤差がある予測をしていることが分かります。

3つのモデルを作成し、統合した結果の線形回帰分析結果を表示する


select_columns = ['room_type','accommodates','bed_type','bathrooms','cleaning_fee']

data_entire = data[data['room_type'] == 'Entire home/apt']
data_private = data[data['room_type'] == 'Private room']
data_share = data[data['room_type'] == 'Shared room']
dummy_data_entire = pd.get_dummies(data_entire[select_columns], drop_first=True)
dummy_data_private = pd.get_dummies(data_private[select_columns],drop_first=True)
dummy_data_share = pd.get_dummies(data_share[select_columns], drop_first=True)

X_train_e,X_test_e,y_train_e,y_test_e = train_test_split(dummy_data_entire, data_entire['y'], random_state = 1234)
X_train_p,X_test_p,y_train_p,y_test_p = train_test_split(dummy_data_private, data_private['y'], random_state = 1234)
X_train_s,X_test_s,y_train_s,y_test_s = train_test_split(dummy_data_share, data_share['y'], random_state = 1234)

model_e = LinearRegression()
model_e.fit(X_train_e, y_train_e)
pred_e_train = model_e.predict(X_train_e)
pred_e_test = model_e.predict(X_test_e)

model_p = LinearRegression()
model_p.fit(X_train_p, y_train_p)
pred_p_train = model_p.predict(X_train_p)
pred_p_test = model_p.predict(X_test_p)

model_s = LinearRegression()
model_s.fit(X_train_s, y_train_s)
pred_s_train = model_s.predict(X_train_s)
pred_s_test = model_s.predict(X_test_s)

# pred_e_train, pred_p_train, pred_s_trainを1つの配列にして、pred_trainに代入してください。
pred_train = np.concatenate([pred_e_train, pred_p_train, pred_s_train])
# 実際の値であるy_train_e,y_train_p,y_train_sを1つの配列にして、answer_trainに代入してください。
answer_train = np.concatenate([y_train_e,y_train_p,y_train_s])
# pred_train,answer_trainから全訓練データの予測値のRMSEを求め、rmse_trainに代入してください。
rmse_train = np.sqrt(MSE(pred_train, answer_train))

# 同様に全テストデータの予測値のRMSEを求め、rmse_testに代入してください。
pred_test = np.concatenate([pred_e_test, pred_p_test, pred_s_test])
answer_test = np.concatenate([y_test_e,y_test_p,y_test_s])
rmse_test = np.sqrt(MSE(pred_test, answer_test))

print(rmse_train)
print(rmse_test)

以上

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2