某房地产公司雇佣数据科学家,需要完成工作步骤
- 观察大局(全局/市场)
- 获取数据
- 从数据探索和可视化中获得洞见
- 机器学习算法的数据准备
- 选择并训练模型
- 微调模型
- 展示解决方案
- 启动、监控、维护系统
1. 观测大局
1.1 询问老板需求
- 明确业务目标,公司如何从模型中获益
- 模型输出(预测区域房价中位数)将跟其他许多信号被传给另一个机器学习系统,下游系统被用来决定该区域是否值得投资
- 机器学习流水线:每一步机器学习系统生成的数据存入一个数据仓库,下一个机器学习系统从数据仓库中获取数据,增强整体系统的鲁棒性
-
1.2 设计系统:
X表示矩阵,x表示特征向量,普通小写字符表示标量
- 平方和的根对应欧几里得范数,l2范数
当数据中存在很多异常区域时,可使用平均绝对误差(MAE, mean absolute error)
- 绝对值的和,对应L1范数,曼哈顿范数,只沿着街区横向或纵向行走
上述两种方法都是测量两个向量之间距离的方法。
一般而言,包含n个元素的向量v的Lk范数定义为:
- 其中L0给出向量中非零元素的数量
- L∞给出向量最大绝对值
- 范数指标越高,它越关注大值,而忽略小值。因此RMSE比MAE异常值更加敏感
1.4 检查假设是否合理
- 以免很大努力之后发现下游任务需要某个价格区间(分类任务即可完成)
2. 获取数据
- jupyter notebook
2.1 下载数据
# 下载->解压->保存到指定路径->csv
def fetch_housing_data(url, housing_path):
pass
# 加载数据到内存
def load_housing_data(housing_path):
pass
2.2 查看数据
获取数据信息
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时会自动显示图形
- 直方图数据可看出,有些数据被限制区间
- 某些特征出现长尾而非钟型图像,即右侧延伸比左侧远的多(不好,需修正)
<a name="pJMAg"></a>
### 2.3 创建测试集
<a name="3L4Qe"></a>
#### 随机抽样
- 随机选择20%的实例,分割出放到一边即可
```python
import numpy as np
# 设置随机种子,使每次随机操作得到相同的值
np.random.seed(42)
# 随机排列数,返回 ndarray
shuffled_indices = np.random.permutation(len(data))
test_indices = shuffled_indices[:test_set_size]
test = data.iloc[test_indices]
# 结果同上
from sklearn.model_selection import train_test_split
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]
<a name="VfB7v"></a>
#### 均匀抽样,代表性
- 例如,男女比例均匀
- 不同地区数量的均匀
分层抽样
- pd.cut()
- sklearn.model_selection.StratifiedShuffleSplit()
```python
pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise', ordered=True)
# 将中位收入数据分为5类
housing['income_cat'] = pd.cut(housing['median_income'], bins=[0. , 1.5, 3, 4.5, 6., np.inf], labels=[1,2,3,4,5])
# 分层抽样,比例分布与原始数据类别分布几乎相同
from sklearn.model_selection import StratifiedShuffleSplit
split = StratiifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_index, test_index in split.split(housing, housing['income_cat']):
strat_train_set = housing.loc[train_index]
strat_test_set = housing.loc[test_index]
# 删除分类
for set_ in (strat_train_set, strat_test_set):
set_.drop("income_cat", axis=1, inplace=True)