使用線性回歸模型進行訓練及預測_(波士頓房價)_透過偏度(skewness)修正來提升預測準確度





沿用上一篇EDA
先抓取到的波士頓房價資料,封裝額外一個python檔案。

getData.py

from sklearn.datasets import load_boston
import pandas as pd
display=pd.options.display
display.max_columns = None
display.max_rows = None
display.width = None
display.max_colwidth = None
def getRawData():
    data=load_boston()
    df = pd.DataFrame(data=data.data,columns=data.feature_names)
    df.insert(0,column='PRICE',value=data.target)
    print(data.DESCR)
    return df

訓練階段.ver1
train_model.py
訓練存出模型二進位檔

import pickle

import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

from getData import  getRawData
import numpy as np
df = getRawData()
data = np.c_[df['LSTAT'] ,df['RM']]
x = pd.DataFrame(data=data,columns=['LSTAT','RM'])#特徵集合
y = df['PRICE']
#進行訓練資料跟測試資料分割
#80% 訓練用 / 20%測試用,訓練好的模型,可以使用剩餘20%的test來進行驗證,並計算分數。
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=5)
model = LinearRegression()#線性回歸模型
model.fit(x_train,y_train)#訓練模型
pickle.dump(model,open('house.model','wb'))#儲存模型(binary format)
#常見模型儲存有兩種,一種是model.save(),是此模型API本身有提供該方法。
#如果模型沒提供save()的API,就要用pickle來進行儲存。
print(data)



預測階段.ver1

predict_model.py
載入剛訓練好的模型做預測,前面段落反黃底的都跟上一個訓練是一致的。

import pickle
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from getData import  getRawData
import numpy as np
df = getRawData()
lstat=df["LSTAT"]
data = np.c_[lstat ,df['RM']]
x = pd.DataFrame(data=data,columns=['LSTAT','RM'])#特徵集合
y = df['PRICE']
#進行訓練資料跟測試資料分割
#80% 訓練用 / 20%測試用,訓練好的模型,可以使用剩餘20%的test來進行驗證,並計算分數。
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=5)

#載入模型
model = pickle.load(open("house.model" , "rb"))
score = model.score(x_test,y_test)#預測分數
print(score)

pre_price=model.predict(x_test)
for i in zip(pre_price,y_test):#將預測價格 跟 實際價格給zip為一組來打印
    print(i)#可順帶觀察預測落差十分大的離群值

可以打印出預測準確計分,目前是0.66的準確率。




偏度(skewness)觀察->正數偏向左,負數偏向右邊。
LSTAT(社區人口中低收入戶人口比)的偏度:0.91
RM(每一棟房子的平均房間數)的偏度:0.4

偏度ver.1 偏度觀察

import seaborn as sns
from getData import  getRawData
import pylab as plt
import numpy as np
df = getRawData()
lstat=df["LSTAT"]#社區人口中低收入戶人口比
sns.histplot(lstat,kde=True)
plt.show()
#Skewness:偏度/ 正數:偏左邊,負數:偏右邊,最理想情況是0,也就是分布趨近中間。
skew=round(lstat.skew(),2)#兩位小數之後四捨五入
print(skew) #0.91 極度偏左

rm=df["RM"]#每一棟房子的平均房間數
sns.histplot(rm,kde=True)
plt.show()
skew=round(rm.skew(),2)#
print(skew) #0.4

可看到大部分屬於中低收入人口
偏度極度往左

平均房間數的偏度則還算是可接受範圍偏度。

偏度ver.2 偏度修正(針對LSTAT =>負相關盡量靠中間偏度縮小接近0)
對中低收入戶人口比開三次根號來修正偏度(太靠左了要把它變小讓他靠中間一些。)

import seaborn as sns
from getData import  getRawData
import pylab as plt
import numpy as np
df = getRawData()
lstat=df["LSTAT"]**(1/3) # 開三次根號來修正偏度(太靠左了要把它變小讓他靠中間一些。)
sns.histplot(lstat,kde=True)
plt.show()
#Skewness:偏度/ 正數:偏左邊,負數:偏右邊,最理想情況是0,也就是分布趨近中間。
skew=round(lstat.skew(),2)#兩位小數之後四捨五入
print(skew) #0.91 極度偏左

rm=df["RM"]#每一棟房子的平均房間數
sns.histplot(rm,kde=True)
plt.show()
skew=round(rm.skew(),2)#
print(skew) #0.4



偏度修正後重新訓練並觀察準確計分
偏度修正後訓練

import pickle

import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

from getData import  getRawData
import numpy as np
df = getRawData()
lstat=df["LSTAT"]**(1/3)
data = np.c_[lstat ,df['RM']]
x = pd.DataFrame(data=data,columns=['LSTAT','RM'])#特徵集合
y = df['PRICE']
#進行訓練資料跟測試資料分割
#80% 訓練用 / 20%測試用,訓練好的模型,可以使用剩餘20%的test來進行驗證,並計算分數。
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=5)
model = LinearRegression()#線性回歸模型
model.fit(x_train,y_train)#訓練模型
pickle.dump(model,open('house_adjust.model','wb'))
#常見模型儲存有兩種,一種是model.save(),是此模型API本身有提供該方法。
#如果模型沒提供save()的API,就要用pickle來進行儲存。
print(data)




偏度修正後預測

import pickle
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from getData import  getRawData
import numpy as np
df = getRawData()
lstat=df["LSTAT"]**(1/3)
data = np.c_[lstat ,df['RM']]
x = pd.DataFrame(data=data,columns=['LSTAT','RM'])#特徵集合
y = df['PRICE']
#進行訓練資料跟測試資料分割
#80% 訓練用 / 20%測試用,訓練好的模型,可以使用剩餘20%的test來進行驗證,並計算分數。
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=5)
#載入模型
#model = pickle.load(open("house.model" , "rb"))
model = pickle.load(open("house_adjust.model" , "rb"))
score = model.score(x_test,y_test)#預測分數
print(score)


可以打印出預測準確計分,目前是0.71的準確率,有明顯提升計分。


偏度ver.3 偏度修正(針對RM =>正相關則將偏度加大)
把RM偏度加大,凸顯房間數愈多價格愈大的特徵,將RM靠左側一點。

import seaborn as sns
from getData import  getRawData
import pylab as plt
import numpy as np
df = getRawData()
lstat=df["LSTAT"]**(1/3) # 開三次根號來修正偏度(太靠左了要把它變小讓他靠中間一些。)
sns.histplot(lstat,kde=True)
plt.show()
#Skewness:偏度/ 正數:偏左邊,負數:偏右邊,最理想情況是0,也就是分布趨近中間。
skew=round(lstat.skew(),2)#兩位小數之後四捨五入
print(skew) #0.91 極度偏左

rm=df["RM"]**2 #每一棟房子的平均房間數
sns.histplot(rm,kde=True)
plt.show()
skew=round(rm.skew(),2)#
print(skew) #0.4

RM就從偏度:0.4上升到0.99

RM偏度修正後重新訓練並觀察準確計分
RM偏度修正後訓練

import pickle

import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

from getData import  getRawData
import numpy as np
df = getRawData()
lstat=df["LSTAT"]**(1/3) # 開三次根號來修正偏度 ->負相關篇度縮小接近0
rm = df['RM']**2 #正相關需要將偏度加大(去凸顯此特興出來)
data = np.c_[lstat ,rm]
x = pd.DataFrame(data=data,columns=['LSTAT','RM'])#特徵集合
y = df['PRICE']
#進行訓練資料跟測試資料分割
#80% 訓練用 / 20%測試用,訓練好的模型,可以使用剩餘20%的test來進行驗證,並計算分數。
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=5)
model = LinearRegression()#線性回歸模型
model.fit(x_train,y_train)#訓練模型
pickle.dump(model,open('house_adjust.model','wb'))#儲存模型(binary format)
#常見模型儲存有兩種,一種是model.save(),是此模型API本身有提供該方法。
#如果模型沒提供save()的API,就要用pickle來進行儲存。
print(data)


RM偏度修正後預測

import pickle
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from getData import  getRawData
import numpy as np
df = getRawData()
lstat=df["LSTAT"]**(1/3) # 開三次根號來修正偏度 ->負相關篇度縮小接近0
rm = df['RM']**2 #正相關需要將偏度加大(去凸顯此特興出來)
data = np.c_[lstat ,rm]
x = pd.DataFrame(data=data,columns=['LSTAT','RM'])#特徵集合
y = df['PRICE']
#進行訓練資料跟測試資料分割
#80% 訓練用 / 20%測試用,訓練好的模型,可以使用剩餘20%的test來進行驗證,並計算分數。
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=5)

#載入模型
#model = pickle.load(open("house.model" , "rb"))
model = pickle.load(open("house_adjust.model" , "rb"))

score = model.score(x_test,y_test)#預測分數
print(score)

#pre_price=model.predict(x_test)
#for i in zip(pre_price,y_test):#將預測價格 跟 實際價格給zip為一組來打印
#    print(i)#可順帶觀察預測落差十分大的離群值



可以打印出預測準確計分,目前是0.74的準確率,有明顯提升計分。






留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

(2021年度)駕訓學科筆試準備題庫歸納分析_法規是非題

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header