机器学习入门项目分享 - 波士顿房价预测
该分享源于 Udacity 机器学习进阶中的一个 mini 作业项目, 用于入门非常合适, 刨除了繁琐的部分, 保留了最关键, 基本的步骤, 能够对机器学习基本流程有一个最清晰的认识;
项目描述
利用马萨诸塞州波士顿郊区的房屋信息数据训练和测试一个模型, 并对模型的性能和预测能力进行测试;
项目分析
数据集字段解释:
RM: 住宅平均房间数量;
LSTAT: 区域中被认为是低收入阶层的比率;
PTRATIO: 镇上学生与教师数量比例;
MEDV: 房屋的中值价格(目标特征, 即我们要预测的值);
其实现在回过头来看, 前三个特征应该都是挖掘后的组合特征, 比如 RM, 通常在原始数据中会分为多个特征: 一楼房间, 二楼房间, 厨房, 卧室个数, 地下室房间等等, 这里应该是为了教学简单化了;
MEDV 为我们要预测的值, 属于回归问题, 另外数据集不大(不到 500 个数据点), 小数据集上的回归问题, 现在的我初步考虑会用 SVM, 稍后让我们看看当时的选择;
Show Time
Step 1 导入数据
注意点:
如果数据在多个 CSV 中(比如很多销售项目中, 销售数据和店铺数据是分开两个 CSV 的, 类似数据库的两张表), 这里一般要连接起来;
训练数据和测试数据连接起来, 这是为了后续的数据处理的一致, 否则训练模型时会有问题(比如用训练数据训练的模型, 预测测试数据时报错维度不一致);
观察下数据量, 数据量对于后续选择算法, 可视化方法等有比较大的影响, 所以一般会看一下;
pandas 内存优化, 这一点项目中目前没有, 但是我最近的项目有用到, 简单说一下, 通过对特征字段的数据类型向下转换 (比如 int64 转为 int8) 降低对内存的使用, 这里很重要, 数据量大时很容易撑爆个人电脑的内存存储;
上代码:
- # 载入波士顿房屋的数据集
- data = pd.read_csv('housing.csv')
- prices = data['MEDV']
- features = data.drop('MEDV', axis = 1)
- # 完成
- print "Boston housing dataset has {} data points with {} variables each.".format(*data.shape)
Step 2 分析数据
加载数据后, 不要直接就急匆匆的上各种处理手段, 加各种模型, 先慢一点, 对数据进行一个初步的了解, 了解其各个特征的统计值, 分布情况, 与目标特征的关系, 最好进行可视化, 这样会看到很多意料之外的东西;
基础统计运算
统计运算用于了解某个特征的整体取值情况, 它的最大最小值, 平均值中位数, 百分位数等等, 这些都是最简单的对一个字段进行了解的手段;
上代码:
- # 目标: 计算价值的最小值
- minimum_price = np.min(prices)# prices.min()
- #目标: 计算价值的最大值
- maximum_price = np.max(prices)# prices.max()
- #目标: 计算价值的平均值
- mean_price = np.mean(prices)# prices.mean()
- #目标: 计算价值的中值
- median_price = np.median(prices)# prices.median()
- #目标: 计算价值的标准差
- std_price = np.std(prices)# prices.std()
特征观察
这里主要考虑各个特征与目标之间的关系, 比如是正相关还是负相关, 通常都是通过对业务的了解而来的, 这里就延伸出一个点, 机器学习项目通常来说, 对业务越了解, 越容易得到好的效果, 因为所谓的特征工程其实就是理解业务, 深挖业务的过程;
比如这个问题中的三个特征:
RM: 房间个数明显应该是与房价正相关的;
LSTAT: 低收入比例一定程度上表示着这个社区的级别, 因此应该是负相关;
PTRATIO: 学生 / 教师比例越高, 说明教育资源越紧缺, 也应该是负相关;
上述这三个点, 同样可以通过可视化的方式来验证, 事实上也应该去验证而不是只靠主观猜想, 有些情况下, 主观感觉与客观事实是完全相反的, 这里要注意;
Step 3 数据划分
为了验证模型的好坏, 通常的做法是进行 cv, 即交叉验证, 基本思路是将数据平均划分 N 块, 取其中 N-1 块训练, 并对另外 1 块做预测, 并比对预测结果与实际结果, 这个过程反复 N 次直到每一块都作为验证数据使用过;
上代码:
- # 提示: 导入 train_test_split
- from sklearn.model_selection import train_test_split
- X_train, X_test, y_train, y_test = train_test_split(features, prices, test_size=0.2, random_state=RANDOM_STATE)
- print X_train.shape
- print X_test.shape
- print y_train.shape
- print y_test.shape
Step 4 定义评价函数
这里主要是根据问题来定义, 比如分类问题用的最多的是准确率 (精确率, 召回率也有使用, 具体看业务场景中更重视什么), 回归问题用 RMSE(均方误差) 等等, 实际项目中根据业务特点经常会有需要去自定义评价函数的时候, 这里就比较灵活;
Step 5 模型调优
通过 GridSearch 对模型参数进行网格组合搜索最优, 注意这里要考虑数据量以及组合后的可能个数, 避免运行时间过长哈;
上代码:
- from sklearn.model_selection import KFold,GridSearchCV
- from sklearn.tree import DecisionTreeRegressor
- from sklearn.metrics import make_scorer
- def fit_model(X, y):
- """基于输入数据 [X,y], 利于网格搜索找到最优的决策树模型"""
- cross_validator = KFold()
- regressor = DecisionTreeRegressor()
- params = {'max_depth':[1,2,3,4,5,6,7,8,9,10]}
- scoring_fnc = make_scorer(performance_metric)
- grid = GridSearchCV(estimator=regressor, param_grid=params, scoring=scoring_fnc, cv=cross_validator)
- # 基于输入数据 [X,y], 进行网格搜索
- grid = grid.fit(X, y)
- # 返回网格搜索后的最优模型
- return grid.best_estimator_
可以看到当时项目中选择的是决策树模型, 现在看, 树模型在这种小数据集上其实是比较容易过拟合的, 因此可以考虑用 SVM 代替, 你也可以试试哈, 我估计是 SVM 效果最好;
学习曲线
通过绘制分析学习曲线, 可以对模型当前状态有一个基本了解, 如下图:
可以看到, 超参数 max_depth 为 1 和 3 时, 明显训练分数过低, 这说明此时模型有欠拟合的情况, 而当 max_depth 为 6 和 10 时, 明显训练分数和验证分析差距过大, 说明出现了过拟合, 因此我们初步可以猜测, 最佳参数在 3 和 6 之间, 即 4,5 中的一个, 其他参数一样可以通过学习曲线来进行可视化分析, 判断是欠拟合还是过拟合, 再分别进行针对处理;
小结
通过以上的几步, 可以非常简单, 清晰的看到一个机器学习项目的全流程, 其实再复杂的流程也是这些简单步骤的一些扩展, 而更难的往往是对业务的理解, 没有足够的理解很难得到好的结果, 体现出来就是特征工程部分做的好坏, 这里就需要各位小伙伴们奋发图强了, 路漫漫啊;
项目链接
通篇浏览可以通过来看;
项目源文件, 数据集文件可以通过 GitHub 波士顿项目 https://github.com/NemoHoHaloAi/boston_housing 获取, 欢迎 Follow,Fork,Star;
最后
大家可以到我的 GitHub 上看看有没有其他需要的东西, 目前主要是自己做的机器学习项目, Python 各种脚本工具, 数据分析挖掘项目以及 Follow 的大佬, Fork 的项目等: https://github.com/NemoHoHaloAi
来源: https://www.cnblogs.com/helongBlog/p/11612128.html