日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
用Python做一個(gè)房價(jià)預(yù)測小工具!

哈嘍,大家好。

創(chuàng)新互聯(lián)建站于2013年成立,先為全椒等服務(wù)建站,全椒等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為全椒企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

這是一個(gè)房價(jià)預(yù)測的案例,來源于 Kaggle 網(wǎng)站,是很多算法初學(xué)者的第一道競賽題目。

該案例有著解機(jī)器學(xué)習(xí)問題的完整流程,包含EDA、特征工程、模型訓(xùn)練、模型融合等。

房價(jià)預(yù)測流程

下面跟著我,來學(xué)習(xí)一下該案例。

沒有啰嗦的文字,沒有多余的代碼,只有通俗的講解。

一. EDA

探索性數(shù)據(jù)分析(Exploratory Data Analysis,簡稱EDA) 的目的是讓我們對(duì)數(shù)據(jù)集有充分的了解。在這一步,我們探索的內(nèi)容如下:

EDA內(nèi)容

1.1 輸入數(shù)據(jù)集

train = pd.read_csv('./data/train.csv')
test = pd.read_csv('./data/test.csv')

訓(xùn)練樣本

train和test分別是訓(xùn)練集和測試集,分別有 1460 個(gè)樣本,80 個(gè)特征。

SalePrice列代表房價(jià),是我們要預(yù)測的。

1.2 房價(jià)分布

因?yàn)槲覀內(nèi)蝿?wù)是預(yù)測房價(jià),所以在數(shù)據(jù)集中核心要關(guān)注的就是房價(jià)(SalePrice) 一列的取值分布。

sns.distplot(train['SalePrice']);

房價(jià)取值分布

從圖上可以看出,SalePrice列峰值比較陡,并且峰值向左偏。

也可以直接調(diào)用skew()和kurt()函數(shù)計(jì)算SalePrice具體的偏度和峰度值。

對(duì)于偏度和峰度都比較大的情況,建議對(duì)SalePrice列取log()進(jìn)行平滑。

1.3 與房價(jià)相關(guān)的特征

了解完SalePrice的分布后,我們可以計(jì)算 80 個(gè)特征與SalePrice的相關(guān)關(guān)系。

重點(diǎn)關(guān)注與SalePrice相關(guān)性最強(qiáng)的 10 個(gè)特征。

# 計(jì)算列之間相關(guān)性
corrmat = train.corr()
# 取 top10
k = 10
cols = corrmat.nlargest(k, 'SalePrice')['SalePrice'].index
# 繪圖
cm = np.corrcoef(train[cols].values.T)
sns.set(font_scale=1.25)
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)
plt.show()

與SalePrice高度相關(guān)的特征

OverallQual(房子材料和裝飾)、GrLivArea(地上居住面積)、GarageCars(車庫容量)和 TotalBsmtSF(地下室面積)跟SalePrice有很強(qiáng)的相關(guān)性。

這些特征在后面做特征工程時(shí)也會(huì)重點(diǎn)關(guān)注。

1.4 剔除離群樣本

由于數(shù)據(jù)集樣本量很少,離群點(diǎn)不利于我們后面訓(xùn)練模型。

所以需要計(jì)算每個(gè)數(shù)值特性的離群點(diǎn),剔除掉離群次數(shù)最多的樣本。

# 獲取數(shù)值型特征
numeric_features = train.dtypes[train.dtypes != 'object'].index
# 計(jì)算每個(gè)特征的離群樣本
for feature in numeric_features:
outs = detect_outliers(train[feature], train['SalePrice'],top=5, plot=False)
all_outliers.extend(outs)
# 輸出離群次數(shù)最多的樣本
print(Counter(all_outliers).most_common())
# 剔除離群樣本
train = train.drop(train.index[outliers])

detect_outliers()是自定義函數(shù),用sklearn庫的LocalOutlierFactor算法計(jì)算離群點(diǎn)。

到這里, EDA 就完成了。最后,將訓(xùn)練集和測試集合并,進(jìn)行下面的特征工程。

y = train.SalePrice.reset_index(drop=True)
train_features = train.drop(['SalePrice'], axis=1)
test_features = test
features = pd.concat([train_features, test_features]).reset_index(drop=True)

features合并了訓(xùn)練集和測試集的特征,是我們下面要處理的數(shù)據(jù)。

二. 特征工程

特征工程

2.1 校正特征類型

MSSubClass(房屋類型)、YrSold(銷售年份)和MoSold(銷售月份)是類別型特征,只不過用數(shù)字來表示,需要將它們轉(zhuǎn)成文本特征。

features['MSSubClass'] = features['MSSubClass'].apply(str)
features['YrSold'] = features['YrSold'].astype(str)
features['MoSold'] = features['MoSold'].astype(str)

2.2 填充特征缺失值

填充缺失值沒有統(tǒng)一的標(biāo)準(zhǔn),需要根據(jù)不同的特征來決定按照什么樣的方式來填充。

# Functional:文檔提供了典型值 Typ
features['Functional'] = features['Functional'].fillna('Typ') #Typ 是典型值
# 分組填充需要按照相似的特征分組,取眾數(shù)或中位數(shù)
# MSZoning(房屋區(qū)域)按照 MSSubClass(房屋)類型分組填充眾數(shù)
features['MSZoning'] = features.groupby('MSSubClass')['MSZoning'].transform(lambda x: x.fillna(x.mode()[0]))
#LotFrontage(到接到舉例)按Neighborhood分組填充中位數(shù)
features['LotFrontage'] = features.groupby('Neighborhood')['LotFrontage'].transform(lambda x: x.fillna(x.median()))
# 車庫相關(guān)的數(shù)值型特征,空代表無,使用0填充空值。
for col in ('GarageYrBlt', 'GarageArea', 'GarageCars'):
features[col] = features[col].fillna(0)

2.3 偏度校正

跟探索SalePrice列類似,對(duì)偏度高的特征進(jìn)行平滑。

# skew()方法,計(jì)算特征的偏度(skewness)。
skew_features = features[numeric_features].apply(lambda x: skew(x)).sort_values(ascending=False)
# 取偏度大于 0.15 的特征
high_skew = skew_features[skew_features > 0.15]
skew_index = high_skew.index
# 處理高偏度特征,將其轉(zhuǎn)化為正態(tài)分布,也可以使用簡單的log變換
for i in skew_index:
features[i] = boxcox1p(features[i], boxcox_normmax(features[i] + 1))

2.4 特征刪除和新增

對(duì)于幾乎都是缺失值,或單一取值占比高(99.94%)的特征可以直接刪除。

features = features.drop(['Utilities', 'Street', 'PoolQC',], axis=1)

同時(shí),可以融合多個(gè)特征,生成新特征。

有時(shí)候模型很難學(xué)習(xí)到特征之間的關(guān)系,手動(dòng)融合特征可以降低模型學(xué)習(xí)難度,提升效果。

# 將原施工日期和改造日期融合
features['YrBltAndRemod']=features['YearBuilt']+features['YearRemodAdd']
# 將地下室面積、1樓、2樓面積融合
features['TotalSF']=features['TotalBsmtSF'] + features['1stFlrSF'] + features['2ndFlrSF']

可以發(fā)現(xiàn),我們?nèi)诤系奶卣鞫际桥cSalePrice強(qiáng)相關(guān)的特征。

最后簡化特征,對(duì)分布單調(diào)的特征(如:100個(gè)數(shù)據(jù)中有99個(gè)的數(shù)值是0.9,另1個(gè)是0.1),進(jìn)行01處理。

features['haspool'] = features['PoolArea'].apply(lambda x: 1 if x > 0 else 0)
features['has2ndfloor'] = features['2ndFlrSF'].apply(lambda x: 1 if x > 0 else 0)

2.6 生成最終訓(xùn)練數(shù)據(jù)

到這里特征工程就做完了, 我們需要從features中將訓(xùn)練集和測試集重新分離出來,構(gòu)造最終的訓(xùn)練數(shù)據(jù)。

X = features.iloc[:len(y), :]  
X_sub = features.iloc[len(y):, :]
X = np.array(X.copy())
y = np.array(y)
X_sub = np.array(X_sub.copy())

三. 模型訓(xùn)練

因?yàn)镾alePrice是數(shù)值型且是連續(xù)的,所以需要訓(xùn)練一個(gè)回歸模型。

3.1 單一模型

首先以嶺回歸(Ridge) 為例,構(gòu)造一個(gè)k折交叉驗(yàn)證模型。

from sklearn.linear_model import RidgeCV
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import KFold
kfolds = KFold(n_splits=10, shuffle=True, random_state=42)
alphas_alt = [14.5, 14.6, 14.7, 14.8, 14.9, 15, 15.1, 15.2, 15.3, 15.4, 15.5]
ridge = make_pipeline(RobustScaler(), RidgeCV(alphas=alphas_alt, cv=kfolds))

嶺回歸模型有一個(gè)超參數(shù)alpha,而RidgeCV的參數(shù)名是alphas,代表輸入一個(gè)超參數(shù)alpha數(shù)組。在擬合模型時(shí),會(huì)從alpha數(shù)組中選擇表現(xiàn)較好某個(gè)取值。

由于現(xiàn)在只有一個(gè)模型,無法確定嶺回歸是不是最佳模型。所以我們可以找一些出場率高的模型多試試。

# lasso
lasso = make_pipeline(
RobustScaler(),
LassoCV(max_iter=1e7, alphas=alphas2, random_state=42, cv=kfolds))
#elastic net
elasticnet = make_pipeline(
RobustScaler(),
ElasticNetCV(max_iter=1e7, alphas=e_alphas, cv=kfolds, l1_ratio=e_l1ratio))
#svm
svr = make_pipeline(RobustScaler(), SVR(
C=20,
epsilon=0.008,
gamma=0.0003,
))
#GradientBoosting(展開到一階導(dǎo)數(shù))
gbr = GradientBoostingRegressor(...)
#lightgbm
lightgbm = LGBMRegressor(...)
#xgboost(展開到二階導(dǎo)數(shù))
xgboost = XGBRegressor(...)

有了多個(gè)模型,我們可以再定義一個(gè)得分函數(shù),對(duì)模型評(píng)分。

#模型評(píng)分函數(shù)
def cv_rmse(model, X=X):
rmse = np.sqrt(-cross_val_score(model, X, y, scoring="neg_mean_squared_error", cv=kfolds))
return (rmse)

以嶺回歸為例,計(jì)算模型得分。

score = cv_rmse(ridge)  
print("Ridge score: {:.4f} ({:.4f})\n".format(score.mean(), score.std()), datetime.now(), ) #0.1024

運(yùn)行其他模型發(fā)現(xiàn)得分都差不多。

這時(shí)候我們可以任選一個(gè)模型,擬合,預(yù)測,提交訓(xùn)練結(jié)果。還是以嶺回歸為例

# 訓(xùn)練模型
ridge.fit(X, y)
# 模型預(yù)測
submission.iloc[:,1] = np.floor(np.expm1(ridge.predict(X_sub)))
# 輸出測試結(jié)果
submission = pd.read_csv("./data/sample_submission.csv")
submission.to_csv("submission_single.csv", index=False)

submission_single.csv是嶺回歸預(yù)測的房價(jià),我們可以把這個(gè)結(jié)果上傳到 Kaggle 網(wǎng)站查看結(jié)果的得分和排名。

3.2 模型融合-stacking

有時(shí)候?yàn)榱税l(fā)揮多個(gè)模型的作用,我們會(huì)將多個(gè)模型融合,這種方式又被稱為集成學(xué)習(xí)。

stacking 是一種常見的集成學(xué)習(xí)方法。簡單來說,它會(huì)定義個(gè)元模型,其他模型的輸出作為元模型的輸入特征,元模型的輸出將作為最終的預(yù)測結(jié)果。

stacking

這里,我們用mlextend庫中的StackingCVRegressor模塊,對(duì)模型做stacking。

stack_gen =  
StackingCVRegressor(
regressors=(ridge, lasso, elasticnet, gbr, xgboost, lightgbm),
meta_regressor=xgboost,
use_features_in_secondary=True)

訓(xùn)練、預(yù)測的過程與上面一樣,這里不再贅述。

3.3 模型融合-線性融合

多模型線性融合的思想很簡單,給每個(gè)模型分配一個(gè)權(quán)重(權(quán)重加和=1),最終的預(yù)測結(jié)果取各模型的加權(quán)平均值。

# 訓(xùn)練單個(gè)模型
ridge_model_full_data = ridge.fit(X, y)
lasso_model_full_data = lasso.fit(X, y)
elastic_model_full_data = elasticnet.fit(X, y)
gbr_model_full_data = gbr.fit(X, y)
xgb_model_full_data = xgboost.fit(X, y)
lgb_model_full_data = lightgbm.fit(X, y)
svr_model_full_data = svr.fit(X, y)
models = [
ridge_model_full_data, lasso_model_full_data, elastic_model_full_data,
gbr_model_full_data, xgb_model_full_data, lgb_model_full_data,
svr_model_full_data, stack_gen_model
]
# 分配模型權(quán)重
public_coefs = [0.1, 0.1, 0.1, 0.1, 0.15, 0.1, 0.1, 0.25]
# 線性融合,取加權(quán)平均
def linear_blend_models_predict(data_x,models,coefs, bias):
tmp=[model.predict(data_x) for model in models]
tmp = [c*d for c,d in zip(coefs,tmp)]
pres=np.array(tmp).swapaxes(0,1)
pres=np.sum(pres,axis=1)
return pres

到這里,房價(jià)預(yù)測的案例我們就講解完了,大家可以自己運(yùn)行一下,看看不同方式訓(xùn)練出來的模型效果。

回顧整個(gè)案例會(huì)發(fā)現(xiàn),我們?cè)跀?shù)據(jù)預(yù)處理和特征工程上花費(fèi)了很大心思,雖然機(jī)器學(xué)習(xí)問題模型原理比較難學(xué),但實(shí)際過程中往往特征工程花費(fèi)的心思最多。


網(wǎng)站題目:用Python做一個(gè)房價(jià)預(yù)測小工具!
鏈接分享:http://www.5511xx.com/article/cocgssp.html