今天给大家介绍一个非常适合新手入门的机器学习实战案例。

这是一个房价预测的案例,来源于 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 KFoldkfolds = 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})\n".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技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、Python必备开发工具

三、精品Python学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

四、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

五、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

六、Python练习题

检查学习结果。

七、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

这份完整版的Python全套学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

Python资料、技术、课程、解答、咨询也可以直接点击下面名片,添加官方客服斯琪

广州的房价是我遥不可及的梦,今天就用Python来做一个房价预测小工具相关推荐

  1. 广州的房价是我遥不可及的梦,今天就用Python来做一个房价预测小工具。

    哈喽,大家好. 今天给大家介绍一个非常适合新手入门的机器学习实战案例. 这是一个房价预测的案例,来源于 Kaggle 网站,是很多算法初学者的第一道竞赛题目. 该案例有着解机器学习问题的完整流程,包含 ...

  2. 用Python做一个房价预测小工具!

    哈喽,大家好. 今天给大家介绍一个非常适合新手入门的机器学习实战案例. 这是一个房价预测的案例,来源于 Kaggle 网站,是很多算法初学者的第一道竞赛题目. 该案例有着解机器学习问题的完整流程,包含 ...

  3. 用Python做一个房价预测小工具

    哈喽,大家好. 今天给大家介绍一个非常适合新手入门的机器学习实战案例. 这是一个房价预测的案例,来源于 Kaggle 网站,是很多算法初学者的第一道竞赛题目. 该案例有着解机器学习问题的完整流程,包含 ...

  4. python画哆啦a梦图片_80行代码!用Python做一个哆来A梦分身

    原标题:80行代码!用Python做一个哆来A梦分身 对于分身术,大家想必都或多或少的从<火影忍者>的动漫上看到过,炫酷的影分身场面,每每看到都觉得非常过瘾. 今天, 小编其实是蓝胖子的铁 ...

  5. 用Python分析波士顿的房价,酸爽!!!

    这个是Kaggle专栏的第二篇,赛题名是:House Prices - Advanced Regression Techniques.在本文中你将会学习到: 单.多变量分析 相关性分析 缺失值和异常值 ...

  6. 用python画路飞代码_80行代码!用Python做一个哆来A梦分身

    对于分身术,大家想必都或多或少的从<火影忍者>的动漫上看到过,炫酷的影分身场面,每每看到都觉得非常过瘾. 今天,小编其实是蓝胖子的铁粉,满满的童年回忆啊!今天Python来实现一个简单的哆 ...

  7. 无锡1座楼盘房价从1.6万跌至6900元引政府不满-楼市调控-房价-限售

    无锡1座楼盘房价从1.6万跌至6900元引政府不满|楼市调控|房价|限售 无锡1座楼盘房价从1.6万跌至6900元引政府不满|楼市调控|房价|限售 相关的主题文章: 中国湿地公园发起者-大米鱼虾蟹均系 ...

  8. python模型预测_【超级干货!】教你用Python做回归模型预测房价

    原标题:[超级干货!]教你用Python做回归模型预测房价 欢迎关注天善智能 hellobi.com,我们是专注于商业智能BI,大数据,数据分析领域的垂直社区,学习.问答.求职,一站式搞定! 对商业智 ...

  9. dedemonkey下载_织梦cms标签生成工具–monkey建站工具箱—织梦标签小工具

    在织梦仿站时,经常要做的就是使用织梦的标签,我们获得标签的方法通常是查看织梦的默认模板,但每次都打开默认模板的确有点麻烦,如果有个专门提供织梦标签的工具就方便多了,不用我们费事的找标签了,这次提供给大 ...

最新文章

  1. 连续举办了十七年的韩国大学生智能车竞赛谢幕了
  2. 为何 short s1 = 1; 是对的,而 float f=3.4; 是错的?
  3. Cesium中Clock控件及时间序列瓦片动态加载
  4. Python 技术篇-用PIL库实现等比例压缩、缩小图片实例演示
  5. 【百战GAN】自动增强图像对比度和颜色美感,GAN如何做?
  6. 视频上传、转码、切面、存储的思路
  7. 渲染服务器位置,如何用服务器做渲染
  8. excel判断两列中同一行的数据是否一致
  9. 基于SpringBoot在线电影订票系统
  10. 一款漂亮的Bootstrap模板INSPINIA_adminV2.5 ---- 20161102
  11. 微型计算机原理与接口技术知识点
  12. 目标检测-ImageAI从安装到使用详解
  13. 计算机相关专业零基础论文画图详细教程(避免掉坑教程)
  14. 上级对下级用通知合适吗_“通知”是上级给下级的还是下级给上级的?
  15. 灵机一栋团队小黄衫展示
  16. 测试行业3年经验,从大厂裸辞后,面试阿里、字节全都一面挂,被面试官说我的水平还不如应届生
  17. win10:如何设置电脑睡眠只息屏
  18. 人物-商界-杨惠妍:杨惠妍
  19. XML Publisher介绍
  20. Debian与Ubuntu到底有什么不同,应该如何选择?

热门文章

  1. Autoware介绍
  2. 内网和外网之间的通信
  3. 区块链DAPP开发 以太坊智能合约框架有哪些
  4. Qt添加.qrc文件和设置exe图标和控件图标
  5. python递归算法 - 汉诺塔问题
  6. 基于Python的统计建模
  7. 代价函数、目标函数、损失函数
  8. linux动态链接库全局变量共享问题DLL共享数据段
  9. About TexturePacker
  10. 手机编程python可以实现吗?有哪些软件值得推荐?