11.6 一些提示与性能考量

准备特征

尽管机器学习演讲中经常着重强调所使用的算法,但切记在实践中,每个算法的好坏只取决于你所使用的特征!
特征准备是大规模机器学习中最重要的一步。

添加信息更丰富的特征(例如与其他数据集连接以引入更多信息)与将现有特征转为合适的向量表示(例如缩放向量)都能极大地帮助改进结果。

配置算法

在正规化选项可用时,MLlib 中的大多数算法都会在正则化打开时表现得更好(在预测准确度方面)。
此外,大多数基于 SGD 的算法需要大约 100 轮迭代来获得较好的结果。

MLlib 尝试提供合适的默认值,但是你应该尝试增加迭代次数,来看看是否能够提高精确度。

缓存RDD以重复使用

MLlib 中的大多数算法都是迭代的,对数据进行反复操作。
因此,在把输入数据集传给MLlib 前使用 cache() 将它缓存起来是很重要的。
即使数据在内存中放不下,你也应该尝试 persist(StorageLevel.DISK_ONLY) 。

在 Python 中,MLlib 会把数据集在从 Python 端传到 Java 端时在 Java 端自动缓存,因此没有必要缓存你的 Python RDD,除非你在自己的程序中还要用到它。
而在 Scala 和 Java 中,则需要由你来决定是否执行缓存操作。

识别稀疏程度

当你的特征向量包含很多零时,用稀疏格式存储这些向量会为大规模数据集节省巨大的时间和空间。

但是如果使用稀疏表示能够让你缓存使用稠密表示时无法缓存的数据,即使数据本身比较稠密,你也应当选择稀疏表示。

并行度

对于大多数算法而言,你的输入 RDD 的分区数至少应该和集群的 CPU 核心数相当,这样才能达到完全的并行。

默认情况下 Spark 会为文件的每个“块”创建一个分区,而块一般为 64 MB。

同时,注意不要使用太多分区,因为这会增加通信开销。