用Python做一个房价预测小工具!转载

原创
小哥 3年前 (2022-10-16) 阅读数 59 #大杂烩

大家好。大家好。

今天,我们向您展示一个机器学习的真实世界示例,它非常适合该领域的新手。

这是一个 房价预测 来自案件的案件来自来自案件的案件 Kaggle 网站,是很多算法初学者的第一竞争话题。

该案例有一个解决机器学习问题的完整流程,包括EDA、特征工程、模型训练、模型融合等。

房价预测流程房价预测流程房价预测流程

请关注下面的我,了解有关此案例的更多信息。跟随我在下面,了解这个案例。跟着我在下面研究这个案例。

没有冗长的文字,没有多余的代码,只有门外汉的解释。

1. EDA

探索性数据分析探索性数据分析探索性数据分析(Exploratory Data Analysis,简称EDA) 其目的是让我们对数据集有一个全面的了解。在这一步中,我们将探讨以下内容。

EDA内容

1.1 输入数据集输入数据集输入数据集

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

训练样本

traintest 分别是训练集和测试集,其中 1460 个样本,80 个特征。

SalePrice 这一栏代表了房价,也是我们想要预测的。

1.2 房价分布

由于我们的使命是预测房价,因此数据集中的核心焦点是房价( SalePrice ) 一列的值的分布。值在一列中的分布。一列中的值的分布。

sns.distplot(train[SalePrice]);

房价估价分布房价估价分布房价估价分布

从图表可以看出, SalePrice 柱峰更陡峭,峰位向左移动。

您也可以直接调用,也可以直接调用 skew()kurt() 函数计算 SalePrice 具体的 偏度峰度 值。

对于 偏度峰度 都是比较大的案例,建议您 SalePrice 列取 log() 执行平滑处理。执行平滑处理。执行平滑处理。执行平滑处理。

1.3 与房价相关的特征与房价相关的特征与房价相关的特征

了解完 SalePrice 在分布之后,我们可以计算在分布之后,我们可以计算 80 个特征与 SalePrice 这些相关性之间的相关性。

注重关系,注重 SalePrice 最相关、最相关、最强相关性 10 个特征。

# 计算列之间的相关性计算列之间的相关性计算列之间的相关性
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高度相关特征高度相关特征高度相关特征

OverallQual (房屋材料和装饰)、(房屋材料和装饰)、(房屋材料和装饰)、 GrLivArea (地上生活区)、(地上生活区)、(地上生活区)、 GarageCars (车库容量)和 TotalBsmtSF (地下室面积)与(地下室面积)相同 SalePrice 两者之间存在着很强的相关性。两者之间存在着很强的相关性。两者之间存在很强的相关性。两者之间有很强的相关性

这些功能在后面的部分中完成这些特征在后面的部分中完成 特征工程 焦点还将放在时机成熟的时候。

1.4 去除异常值样本去除异常值

由于数据集的样本量较小,离群点不利于后续模型的训练。

因此有必要计算每一项,因此需要为每一项计算,因此需要计算每项 数值特性 剔除离群值数量最多的样本。

# 获取数值要素获取数值要素
numeric_features = train.dtypes[train.dtypes != object].index

# 计算每个要素的异常样本计算每个要素的异常样本
for feature in numeric_features:
    outs = detect_outliers(train[feature], train[SalePrice],top=5, plot=False)
    all_outliers.extend(outs)

# 输出离群值数量最多的样本
print(Counter(all_outliers).most_common())

# 去除异常值样本去除异常值
train = train.drop(train.index[outliers])

detect_outliers() 是使用的自定义函数是使用的自定义函数 sklearn 库的 LocalOutlierFactor 计算离群点的算法。该算法计算离群点。计算离群点的算法。

到这里, EDA 这件事已经完成了。最后,将训练集和测试集合并,并进行以下特征工程。

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 训练集和测试集的特征被合并,是我们将在下面处理的数据。

2. 特征工程

特征工程

2.1 校正要素类型校正要素类型校正要素类型

MSSubClass (房屋类型)、(房屋类型)、(房屋类型)、 YrSold (销售年度)和(销售年度)和(销售年度)和 MoSold (销售月数)是类别类型的要素,不同之处在于它们以数字表示,需要转换为文本要素。

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

2.2 填充要素缺失的值填充缺失的要素值

缺失值的填充没有统一的标准,需要根据不同的特征来确定填充的方式。

# Functional:文档提供了典型值:文档提供了典型值:文档提供了典型值 Typ
features[Functional] = features[Functional].fillna(Typ) #Typ 是典型值

# 分组填充要求按相似的特征分组,采用复数或中位数
# MSZoning根据(房屋面积)根据(房屋面积) MSSubClass类型分组填充复数(住房)类型分组填充复数
features[MSZoning] = features.groupby(MSSubClass)[MSZoning].transform(lambda x: x.fillna(x.mode()[0]))

#LotFrontage根据(接受范例)根据(接受范例)按(接受范例)出版社Neighborhood分组填充中值组填充中值组逐组填充中值
features[LotFrontage] = features.groupby(Neighborhood)[LotFrontage].transform(lambda x: x.fillna(x.median()))

# 车库相关数值型功能,为空表示无,使用0填充空值。填充空值。填充空值。填充空值。
for col in (GarageYrBlt, GarageArea, GarageCars):
    features[col] = features[col].fillna(0)

2.3 偏度校正

跟探索 SalePrice 列类似,对偏度高的特征执行平滑处理。执行平滑处理。执行平滑处理。执行平滑处理。

# skew()方法,计算特征的偏斜度(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

# 处理高偏度特征以将其转换为正态分布也可以使用简单的log变换
for i in skew_index:
    features[i] = boxcox1p(features[i], boxcox_normmax(features[i] + 1))

2.4 要素删除和添加要素移除和添加

对于几乎总是丢失的值,或具有较高百分比的单次获取的值(99.94%)可以直接删除特征。)可以直接删除功能。)可以简单地删除功能。)可以直接删除功能。

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

同时,多个特征可以被融合以生成新的特征。

有时模型很难学习到特征之间的关系,而人工融合特征可以降低模型学习的难度,提高效果。

# 原施工日期与改造日期合一
features[YrBltAndRemod]=features[YearBuilt]+features[YearRemodAdd]

# 地下室区域,地下室区域将是1楼、2建筑面积融合建筑面积融合
features[TotalSF]=features[TotalBsmtSF] + features[1stFlrSF] + features[2ndFlrSF]

可以发现,我们融合的特征都与 SalePrice 强关联特征。强关联特征。

最后,对于单调分布的特征,简化了特征。100在全部数据的数据中有99的值的值的值0.9,另1个是0.1),进行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 生成最终训练数据生成最终训练数据生成最终训练数据

这里完成了功能项目。在这里,功能项目完成了。在这里,特写工作已经完成。在这里,特性化项目已经完成。 我们需要从我们需要从我们需要看的开始 features 训练和测试集被彼此重新分离,以构建最终的训练数据。

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())

3. 模型训练

因为 SalePrice 是数值的和连续的,所以有必要训练一个 回归模型

3.1 单一模型

首先以 岭回归(Ridge) 例如,构造一个例子,构造一个作为例子,构造一个作为例子,构造一个k折叠交叉验证模型。折叠交叉验证模型。折叠交叉验证模型。折叠交叉验证模型。

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))

岭回归 模型有一个超参数,模型有一个超参数 alpha ,而 RidgeCV 的参数名称的参数名称的参数名称 alphas ,表示超参数的输入 alpha 数组。当拟合模型时,它取自 alpha 在数组中选择性能更好的值。

因为现在只有一种型号,所以不可能确定 岭回归 不是最好的模特。这样我们就可以找到一些高颜值的模特来尝试更多。

# 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(展开到一阶导数)(展开到一阶导数)(展开到一阶导数)
gbr = GradientBoostingRegressor(...)

#lightgbm
lightgbm = LGBMRegressor(...)

#xgboost(展开至二阶导数)(展开至二阶导数)(展开至二阶导数)
xgboost = XGBRegressor(...)

对于多个模型,我们可以定义一个评分函数来对这些模型进行评分。

#模型评分函数模型评分函数
def cv_rmse(model, X=X):
    rmse = np.sqrt(-cross_val_score(model, X, y, scoring="neg_mean_squared_error", cv=kfolds))
    return (rmse)

岭回归 作为例子,计算了模型得分。作为例子,计算了模型分数。

score = cv_rmse(ridge) 

print("Ridge score: {:.4f} ({:.4f})

".format(score.mean(), score.std()), datetime.now(), ) #0.1024

运行其他模型显示,这些分数是相似的。

在这一点上,我们可以选择任何模型、对其进行拟合、预测并提交培训结果。仍与 岭回归 为例

# 训练模型
ridge.fit(X, y)

# 模型预测
submission.iloc[:,1] = np.floor(np.expm1(ridge.predict(X_sub)))

# 输出测试结果输出测试结果
submission = pd.read_csv("./data/sample_submission.csv")
submission.to_csv("submission_single.csv", index=False)

submission_single.csv 是岭回归预测的房价,我们可以将这个结果上传到 Kaggle 网站查看结果的得分和排名。

3.2 模型融合-stacking

有时,为了利用多个模型,我们以一种也称为 集成学习

stacking 这是一个共同的,是一个共同的,是一个共同的 集成学习 方法。简单地说,它定义了一个元模型,将其他模型的输出作为元模型的输入特征,并将元模型的输出作为最终的预测结果。

stacking

这里,我们用了 mlextend 库中的 StackingCVRegressor 做模型的模块,做模型的模块,做模型的stacking。

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

训练和预测的过程与上面相同,这里不再重复。

3.3 模型融合-线性融合

多模型线性融合的思想很简单,给每个模型分配一个权重(权重的总和)。=1),则将最终的预测结果作为每个模型的加权平均。

# 培训单个模型培训单个模型培训单个模型
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
]

# 分配模型权重分配模型权重分配模型权重
public_coefs = [0.1, 0.1, 0.1, 0.1, 0.15, 0.1, 0.1, 0.25]

# 线性融合,取加权平均线性融合,取加权平均
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

到这里, 房价预测 我们已经完成了案例研究,您可以自己运行它来查看培训模型的不同方法的效果。

回顾整个案例会发现,我们在数据预处理和特征工程上花费了大量的精力,虽然机器学习问题模型的原理很难学习,但实际过程往往是花费在特征工程上的最多心思。

推荐阅读:
入门: 最完整的零基学习最全面的零基学习最完整的零基学习Python的问题  | 从零开始学习从零基础学习从零基础学习8个月的Python  | 实战项目 |学Python这是捷径,这是捷径,这是捷径
干货:爬行豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析最佳球员分析 |   从万众期待到口碑惨败!唐探3令人失望  | 笑新伊田图龙记笑新伊田图龙记笑新伊田图龙记 | 谜语之王回答灯谜之王灯谜之王谜语之王 |用Python人山人海素描图人山人海素描图人山人海 Dishonor太火了,我用机器学习做了一个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python日常酷跑游戏日常酷跑游戏日常酷跑游戏!
AI: 会写诗的机器人会写诗的机器人会写诗的机器人 | 给图片上色给图片上色给图片上色 | 预测收入 | 《耻辱》太火了,我用机器学习做了一部迷你推荐系统电影
小工具: Pdf转Word易于修复表单和水印!易于处理的表单和水印!易于修复表单和水印!简单的表格和水印! | 一键把html将页面另存为网页另存为网页另存为pdf!|  再见PDF提款费!提款费!提款费!提款费用! | 用90构建最强大的代码行构建最强大的代码行构建最强大的代码行PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一个固定的低成本机票提醒!制作一张别针的低价机票提醒! |60代码行做了一个语音墙纸切换,天天见女士!

年度弹出文案年度弹出文案年度爆炸性文案

  • 1). 卧槽!Pdf转Word用Python轻松搞定 !

  • 2).学Python闻起来好香!我用100一行代码做了一个网站,帮助人们做了一行代码,做了一个网站,帮助了人们做了一行代码,帮助了人们PS旅行图片赚鸡腿吃旅行图片赚鸡腿

  • 3).第一次播放量过亿,火爆全网,我分析了《顺风车妹妹》,发现了这些秘密

  • 4). 80一行行代码!使用Python让救济金做正确的事做做的人做好事的人A梦分身

  • 5).你必须掌握的东西你必须掌握20个python代码,简短而紧凑,永无止境的有用代码,简短而甜蜜,永无止境的有用的代码,简短而紧凑,永无止境的使用代码,简短而甜蜜,永无止境的用途

  • 6). 30个Python古怪技能集古怪小贴士收藏古怪技能集

  • 7). 我总结的80《菜鸟学习专页》《菜鸟学习专页》《菜鸟学习》Python精选干货.pdf》,都是干货

  • 8). 再见Python!我要学Go了!2500词深度分析词深度分析词深度分析 !

  • 9).发现了一只舔狗的福利!这Python爬虫神器太酷了,不能自动下载女孩的照片

点击原文阅读原文200有趣案例有趣案例研究案例分析!

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门