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

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

大家好。大家好。

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

这是一个 房价预测 来自案件的案件来自来自案件的案件 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)

训练样本

train 和 test 分别是训练集和测试集,其中 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有趣案例有趣案例研究案例分析!

版权声明

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