某房地产公司雇佣数据科学家,需要完成工作步骤

  1. 观察大局(全局/市场)
  2. 获取数据
  3. 从数据探索和可视化中获得洞见
  4. 机器学习算法的数据准备
  5. 选择并训练模型
  6. 微调模型
  7. 展示解决方案
  8. 启动、监控、维护系统

1. 观测大局

1.1 询问老板需求

  • 明确业务目标,公司如何从模型中获益
    • 模型输出(预测区域房价中位数)将跟其他许多信号被传给另一个机器学习系统,下游系统被用来决定该区域是否值得投资
    • 机器学习流水线:每一步机器学习系统生成的数据存入一个数据仓库,下一个机器学习系统从数据仓库中获取数据,增强整体系统的鲁棒性
  • 了解当前解决方案:例如专家团队手动估算区域房价

    1.2 设计系统:

    • 框架:有监督/无监督/强化学习
    • 任务:分类/回归/其他
    • 批量学习/在线学习(增量学习)

      1.3 选择性能指标(L范数)

      回归问题经典性能指标是均方根误差(RMSE, root mean square error)
      [C2] End-to-end ML Project - 图1
  • X表示矩阵,x表示特征向量,普通小写字符表示标量

  • 平方和的根对应欧几里得范数,l2范数

当数据中存在很多异常区域时,可使用平均绝对误差(MAE, mean absolute error)
[C2] End-to-end ML Project - 图2

  • 绝对值的和,对应L1范数,曼哈顿范数,只沿着街区横向或纵向行走

上述两种方法都是测量两个向量之间距离的方法。

一般而言,包含n个元素的向量v的Lk范数定义为:
[C2] End-to-end ML Project - 图3

  • 其中L0给出向量中非零元素的数量
  • L∞给出向量最大绝对值
  • 范数指标越高,它越关注大值,而忽略小值。因此RMSE比MAE异常值更加敏感

**

1.4 检查假设是否合理

  • 以免很大努力之后发现下游任务需要某个价格区间(分类任务即可完成)

2. 获取数据

  • jupyter notebook

2.1 下载数据

  1. # 下载->解压->保存到指定路径->csv
  2. def fetch_housing_data(url, housing_path):
  3. pass
  4. # 加载数据到内存
  5. def load_housing_data(housing_path):
  6. pass

2.2 查看数据

  • DataFrame格式数据 ```python

    查看前n行

    housing.head()

获取数据信息

housing.info()

查看不同分类的数量

housing[‘ocean_proximity’].value_counts()

显示数值属性:count/mean/min/…

housing.descrbie()

绘制每个属性直方图:特征值与实例数量关系图

%matplotlib inline # 设置Matplotlib使用jupyter自己的后端 import matplotlib.pyplot as plt housing.hist(bins=50, figsize=(20, 15)) plt.show() # (可选)因为Jupyter执行每个cell时会自动显示图形

  1. - 直方图数据可看出,有些数据被限制区间
  2. - 某些特征出现长尾而非钟型图像,即右侧延伸比左侧远的多(不好,需修正)
  3. <a name="pJMAg"></a>
  4. ### 2.3 创建测试集
  5. <a name="3L4Qe"></a>
  6. #### 随机抽样
  7. - 随机选择20%的实例,分割出放到一边即可
  8. ```python
  9. import numpy as np
  10. # 设置随机种子,使每次随机操作得到相同的值
  11. np.random.seed(42)
  12. # 随机排列数,返回 ndarray
  13. shuffled_indices = np.random.permutation(len(data))
  14. test_indices = shuffled_indices[:test_set_size]
  15. test = data.iloc[test_indices]
  16. # 结果同上
  17. from sklearn.model_selection import train_test_split
  18. train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)

为了保持每次运行后测试集的一致性:

  • 运行一次后,保存测试集和训练集,之后使用直接加载
  • 设置固定的随机种子,使生成的permutation索引相同
  • (上述方法无法处理增量数据)对每个实例使用一个标识符决定是否进入测试集
    • 例如,计算每个标识符的哈希值,将小于等于最大哈希值的20%数据作为测试数据

zlib.crc32()

  • 将字符数据转换为特殊数串
  • Cyclic Redundancy Check 循环冗余校验
  • Return the unsigned 32-bit checksum integer ```python import hashlib def test_set_check(identifier, test_ratio, hash=hashlib.md5): return bytearray(hash(np.int64(identifier)).digest())[-1] < 256 * test_ratio

只有在pandas中,数据列全部类型为bool时,~表示bool取反,否则表示按位取反

def splittrain_test_by_id(data, test_ratio, id_column): ids = data[id_column] in_test_set = ids.apply(lambda id: testset_check(id, test_ratio)) return data.loc[~in_test_set], data.loc[in_test_set]

  1. <a name="VfB7v"></a>
  2. #### 均匀抽样,代表性
  3. - 例如,男女比例均匀
  4. - 不同地区数量的均匀
  5. 分层抽样
  6. - pd.cut()
  7. - sklearn.model_selection.StratifiedShuffleSplit()
  8. ```python
  9. pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise', ordered=True)
  10. # 将中位收入数据分为5类
  11. housing['income_cat'] = pd.cut(housing['median_income'], bins=[0. , 1.5, 3, 4.5, 6., np.inf], labels=[1,2,3,4,5])
  12. # 分层抽样,比例分布与原始数据类别分布几乎相同
  13. from sklearn.model_selection import StratifiedShuffleSplit
  14. split = StratiifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
  15. for train_index, test_index in split.split(housing, housing['income_cat']):
  16. strat_train_set = housing.loc[train_index]
  17. strat_test_set = housing.loc[test_index]
  18. # 删除分类
  19. for set_ in (strat_train_set, strat_test_set):
  20. set_.drop("income_cat", axis=1, inplace=True)