Skip to content

Commit

Permalink
fix some typos (#49)
Browse files Browse the repository at this point in the history
fix some typos
  • Loading branch information
luweizheng authored May 13, 2024
1 parent bd70b57 commit 4268228
Show file tree
Hide file tree
Showing 28 changed files with 1,156 additions and 881 deletions.
2 changes: 1 addition & 1 deletion _toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ subtrees:
- file: ch-ray-cluster/index
entries:
- file: ch-ray-cluster/ray-cluster
- file: ch-ray-cluster/ray-job
- file: ch-ray-cluster/ray-resource
- file: ch-ray-cluster/ray-job
- file: ch-ray-data/index
entries:
- file: ch-ray-data/ray-data-intro
Expand Down
4 changes: 2 additions & 2 deletions ch-dask-dataframe/map-partitions.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Dask DataFrame 的某些 API 的计算模式是 Embarrassingly Parallel,它的底层很可能就是使用 `map_partitions()` 实现的。\n",
"Dask DataFrame 的某些 API Embarrassingly Parallel 的,它的底层就是使用 `map_partitions()` 实现的。\n",
"\n",
"{numref}`sec-dask-dataframe-indexing` 提到过,Dask DataFrame 会在某个列上进行切分,但如果对这些切分的列做了改动,需要 `clear_divisions()` 或者重新 `set_index()`。"
"{numref}`sec-dask-dataframe-indexing` 提到过,Dask DataFrame 会在某个列(索引列)上进行切分,但如果 `map_partitions()` 对这些索引列做了改动,需要 `clear_divisions()` 或者重新 `set_index()`。"
]
},
{
Expand Down
4 changes: 3 additions & 1 deletion ch-dask-dataframe/read-write.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1750,7 +1750,9 @@
"* 内嵌表模式\n",
"* 数据压缩\n",
"\n",
"具体而言,列式存储按照列进行存储,而不是 CSV 那样按行存储。数据分析时,我们可能只关心特定的列,而不是所有的列,因此在读取数据时,Parquet 允许很方便地过滤掉不需要的列,而不必读取整个行。因为减少了读取的数据量,Parquet 可以显著提高性能,也被广泛应用在 Apache Spark、Apache Hive 和 Apache Flink 等大数据生态。Parquet 自带了表模式,每个 Parquet 文件里嵌入了每个列的列名、数据类型等元数据,也就避免了 Dask DataFrame 进行表模式推测时推测不准确的问题。Parquet 中的数据是经过压缩的,相比 CSV,Parquet 更节省持久化存储的空间。\n",
"具体而言,列式存储按照列进行存储,而不是 CSV 那样按行存储。数据分析时,我们可能只关心特定的列,而不是所有的列,因此在读取数据时,Parquet 允许很方便地过滤掉不需要的列,而不必读取整个行,即列裁剪(Column Pruning)。除了列裁剪,行裁剪(Row Pruning)是另一种减少数据读取的技术。Parquet 自带了表模式,每个 Parquet 文件里嵌入了每个列的列名、数据类型等元数据,也就避免了 Dask DataFrame 进行表模式推测时推测不准确的问题。Parquet 中的数据是经过压缩的,相比 CSV,Parquet 更节省持久化存储的空间。\n",
"\n",
"Parquet 被广泛应用在 Apache Spark、Apache Hive 和 Apache Flink 等大数据生态。\n",
"\n",
"```{figure} ../img/ch-dask-dataframe/parquet.svg\n",
"---\n",
Expand Down
16 changes: 8 additions & 8 deletions ch-dask-dataframe/shuffle.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"\n",
"为解决 Task Graph 过大的问题,Dask 设计了一种点对点(Peer-to-peer)的 Shuffle 机制。如 {numref}`fig-shuffle-tasks-p2p` 右侧所示,`p2p` 在 Task Graph 中引入了一个虚拟的障碍(Barrier)节点。Barrier 并不是一个真正的 Task,引入 Barrier 节点可以使 Task Graph 复杂度显著下降。\n",
"\n",
"```{figure} ../img/ch-dask-dataframe/shuffle-tasks-p2p.png\n",
"```{figure} ../img/ch-dask-dataframe/shuffle-tasks-p2p.svg\n",
"---\n",
"width: 800px\n",
"name: fig-shuffle-tasks-p2p\n",
Expand Down Expand Up @@ -105,19 +105,19 @@
"source": [
"## 数据重分布\n",
"\n",
"Dask 提供了三种数据重分布方法:`set_index`,`repartition` 和 `shuffle`,这三种都可能在全局层面对数据进行重分布。\n",
"Dask DataFrame 提供了三种数据重分布方法:`set_index()`,`repartition()` 和 `shuffle()`,这三种都可能在全局层面对数据进行重分布。\n",
"\n",
"```{table} Dask 三种数据重分布方法\n",
":name: tab-dask-repartition\n",
"\n",
"| 方法名 | 用途 | 是否修改索引 | 是否可以修改 Partition 数量 |\n",
"|---\t|---\t|---\t|---\t|\n",
"| [`DataFrame.set_index`](https://docs.dask.org/en/latest/generated/dask_expr._collection.DataFrame.set_index.html) | 修改索引列,加速后续基于索引列的计算\t| 是 | 是\t|\n",
"| [`DataFrame.repartition`](https://docs.dask.org/en/latest/generated/dask_expr._collection.DataFrame.repartition.html) | 修改 Partition 数量,多用于数据倾斜场景 | 否\t| 是 |\n",
"| [`DataFrame.shuffle`](https://docs.dask.org/en/latest/generated/dask_expr._collection.DataFrame.shuffle.html) | 将相同的值归结到同一个 Partition | 否 | 是 |\n",
"| [`DataFrame.set_index()`](https://docs.dask.org/en/latest/generated/dask_expr._collection.DataFrame.set_index.html) | 修改索引列,加速后续基于索引列的计算\t| 是 | 是\t|\n",
"| [`DataFrame.repartition()`](https://docs.dask.org/en/latest/generated/dask_expr._collection.DataFrame.repartition.html) | 修改 Partition 数量,多用于数据倾斜场景 | 否\t| 是 |\n",
"| [`DataFrame.shuffle()`](https://docs.dask.org/en/latest/generated/dask_expr._collection.DataFrame.shuffle.html) | 将相同的值归结到同一个 Partition | 否 | 是 |\n",
"```\n",
"\n",
"在 {numref}`sec-dask-dataframe-indexing` 我们提过,`set_index` 将某字段设置为索引列,后续一系列计算非常依赖这个字段,`set_index` 能显著加速后续计算。`repartition` 主要解决数据倾斜的问题,即某些 Partiton 上的数据过大,过大的 Partition 有可能导致内存不足。"
"在 {numref}`sec-dask-dataframe-indexing` 我们提过,`set_index()` 将某字段设置为索引列,后续一系列计算非常依赖这个字段,`set_index()` 能显著加速后续计算。`repartition()` 主要解决数据倾斜的问题,即某些 Partiton 上的数据过大,过大的 Partition 有可能导致内存不足。"
]
},
{
Expand All @@ -140,11 +140,11 @@
"\n",
"* 分组:按照 `by` 指定的分组字段进行分组,相同的分组字段被分到一起,这里涉及到大量 Shuffle 操作。\n",
"* 组内聚合:组内聚合的 Shuffle 操作相对比较少。\n",
"* 组间聚合:组间聚合的 Shuffle 操作相对比较小\n",
"* 组间聚合:组间聚合的 Shuffle 操作相对比较少\n",
"\n",
"根据 Shuffle 操作的数量,不难得出结论:\n",
"\n",
"* `groupby(by=indexed_columns).agg()` 和 `groupby(by=indexed_columns).apply(user_def_fn)` 性能最好。`indexed_columns` 指的是分组字段 `by` 在索引列({numref}`sec-dask-dataframe-indexing` 中 `set_index` 的列);`agg` 指的是 Dask DataFrame 提供的官方的 `sum`,`mean` 等聚合方法。因为 `indexed_columns` 是排过序的了,可以很快地对 `indexed_columns` 进行分组和数据分发。\n",
"* `groupby(by=indexed_columns).agg()` 和 `groupby(by=indexed_columns).apply(user_def_fn)` 性能最好。`indexed_columns` 指的是分组字段 `by` 是索引列({numref}`sec-dask-dataframe-indexing` 中 `set_index` 的列);`agg` 指的是 Dask DataFrame 提供的官方的 `sum`,`mean` 等聚合方法。因为 `indexed_columns` 是排过序的了,可以很快地对 `indexed_columns` 进行分组和数据分发。\n",
"* `groupby(by=non_indexed_columns).agg()` 的数据交换量要更大一些,Dask 官方提供的 `agg` 方法做过一些优化。\n",
"* `groupby(by=non_indexed_columns).apply(user_def_fn)` 的成本最高。它既要对所有数据进行交换,又要执行用户自定义的函数,用户自定义函数的效率比 Dask 官方的低。"
]
Expand Down
6 changes: 3 additions & 3 deletions ch-dask-ml/distributed-training.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"调用 `fit` 方法(与 scikit-learn 类似):"
"调用 `fit()` 方法(与 scikit-learn 类似):"
]
},
{
Expand Down Expand Up @@ -2118,9 +2118,9 @@
"\n",
"XGBoost 和 LightGBM 是两种决策树模型的实现,他们本身就对分布式训练友好,且集成了 Dask 的分布式能力。下面以 XGBoost 为例,介绍 XGBoost 如何基于 Dask 实现分布式训练,LightGBM 与之类似。\n",
"\n",
"在 XGBoost 中,训练一个模型既可以使用 `train` 方法,也可以使用 scikit-learn 式的 `fit()` 方法。这两种方式都支持 Dask 分布式训练。\n",
"在 XGBoost 中,训练一个模型既可以使用 `train()` 方法,也可以使用 scikit-learn 式的 `fit()` 方法。这两种方式都支持 Dask 分布式训练。\n",
"\n",
"下面的代码对单机的 XGBoost 和 Dask 分布式训练两种方式进行了性能对比。如果使用 Dask,需要将 [`xgboost.DMatrix`](https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.DMatrix) 修改为 [`xgboost.dask.DaskDMatrix`](https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.dask.DaskDMatrix),`xgboost.dask.DaskDMatrix` 可以将分布式的 Dask Array 或 Dask DataFrame 转化为 XGBoost 所需要的数据格式;再将 [`xgboost.train`](https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.train) 修改为 [`xgboost.dask.train`](https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.dask.train);并传入 Dask 集群客户端 `client`。"
"下面的代码对单机的 XGBoost 和 Dask 分布式训练两种方式进行了性能对比。如果使用 Dask,用户需要将 [`xgboost.DMatrix`](https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.DMatrix) 修改为 [`xgboost.dask.DaskDMatrix`](https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.dask.DaskDMatrix),`xgboost.dask.DaskDMatrix` 可以将分布式的 Dask Array 或 Dask DataFrame 转化为 XGBoost 所需要的数据格式;用户还需要将 [`xgboost.train()`](https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.train) 修改为 [`xgboost.dask.train()`](https://xgboost.readthedocs.io/en/stable/python/python_api.html#xgboost.dask.train);并传入 Dask 集群客户端 `client`。"
]
},
{
Expand Down
6 changes: 4 additions & 2 deletions ch-dask-ml/hyperparameter.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"* 基于 scikit-learn 的 joblib 后端,将多个超参数调优任务分布到 Dask 集群\n",
"* 使用 Dask-ML 提供的超参数调优 API\n",
"\n",
"这两种方式都是针对训练数据量可放到单机内存中的场景。\n",
"\n",
"## scikit-learn joblib\n",
"\n",
"单机的 scikit-learn 已经提供了丰富易用的模型训练和超参数调优接口,它默认使用 joblib 在单机多核之间并行。像随机搜索和网格搜索等超参数调优任务容易并行,任务之间没有依赖关系,很容易并行起来。\n",
Expand Down Expand Up @@ -185,7 +187,7 @@
"\n",
"Dask-ML 的超参数调优算法要求输入为 Dask DataFrame 或 Dask Array 等可被切分的数据,而非 pandas DataFrame,因此数据预处理部分需要改为 Dask。\n",
"\n",
"值得注意的是,Dask-ML 提供的 `SuccessiveHalvingSearchCV` 和 `HyperbandSearchCV` 等算法要求模型必须支持 `partial_fit()` 和 `score()`。`partial_fit()` 是 scikit-learn 中迭代式算法(比如梯度下降法)的一次迭代过程。连续减半算法和 Hyperband 算法先分配一些算力额度,不是完成试验的所有迭代,而只做一定次数的迭代(对 `partial_fit()` 进行一定次数的调用),评估性能(在验证集上调用 `score()` 方法),淘汰性能较差的试验。"
"值得注意的是,Dask-ML 提供的 `SuccessiveHalvingSearchCV` 和 `HyperbandSearchCV` 等算法要求模型必须支持 `partial_fit()` 和 `score()`。`partial_fit()` 是 scikit-learn 中迭代式算法(比如梯度下降法)的一次迭代过程。连续减半算法和 Hyperband 算法先分配一些算力额度,不是完成试验的所有迭代,而只做一定次数的迭代(对 `partial_fit()` 调用有限次数),评估性能(在验证集上调用 `score()` 方法),淘汰性能较差的试验。"
]
},
{
Expand Down Expand Up @@ -775,7 +777,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"本书还会介绍 Ray 的超参数调优,相比 Dask,Ray 的兼容性和功能完善程度更好,读者可以根据自身需求选择适合自己的框架。"
"本书还会介绍 Ray 的超参数调优,相比 Dask,Ray 在超参数调优上的兼容性和功能完善程度更好,读者可以根据自身需求选择适合自己的框架。"
]
}
],
Expand Down
2 changes: 1 addition & 1 deletion ch-dask/dask-distributed.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@
"\n",
"## Dask Nanny\n",
"\n",
"Dask 在启动集群时,除了启动 Dask Scheduler 和 Dask Worker 外,还启动了一个叫做 Dask Nanny 的监控服务。Nanny 英文意为保姆,Dask Nanny 就是在执行保姆的作用,它监控着 Dask Worker 的 CPU 和内存使用情况,避免 Dask Worker 超出资源上限;Dask Worker 宕机时重启 Dask Worker。如果某个 Dask Worker 被 Dask Nanny 重启了,该 Dask Worker 上的计算任务被重新执行,其他 Dask Worker 一直等待该 Dask Worker 恢复到刚刚宕机的时间点;但这会给其他 Dask Worker 增加很多负担。"
"Dask 在启动集群时,除了启动 Dask Scheduler 和 Dask Worker 外,还启动了一个叫做 Dask Nanny 的监控服务。Nanny 英文意为保姆,Dask Nanny 就是在执行保姆的作用,它监控着 Dask Worker 的 CPU 和内存使用情况,避免 Dask Worker 超出资源上限;Dask Worker 宕机时,Dask Nanny 负责重启 Dask Worker。如果某个 Dask Worker 被 Dask Nanny 重启了,该 Dask Worker 上的计算任务被重新执行,其他 Dask Worker 保留当时状态和数据,并一直等待该 Dask Worker 恢复到刚刚宕机的时间点;这会给其他 Dask Worker 增加很多负担。如果 Dask Worker 频繁重启,可能需要考虑用 `rechunk()` 或 `repartition()` 调整 Partition 的数据大小"
]
},
{
Expand Down
8 changes: 4 additions & 4 deletions ch-dask/task-graph-partitioning.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"\n",
"## 数据切分\n",
"\n",
"Dask 将大数据切分成可被很多个小数据,Dask Array 将切分的小数据称为块(Chunk);Dask DataFrame 将切分的小数据称为分区(Partition)。虽然 Chunk 和 Partition 名词不同,但本质上都是数据的切分。\n",
"Dask 将大数据切分成很多个小数据,Dask Array 将切分的小数据称为块(Chunk);Dask DataFrame 将切分的小数据称为分区(Partition)。虽然 Chunk 和 Partition 名词不同,但本质上都是数据的切分。\n",
"\n",
"下面的例子模拟了这样的计算:一个 $10 \\times 10$ 矩阵切分为 4 个 $5 \\times 5$ 矩阵。"
]
Expand Down Expand Up @@ -522,13 +522,13 @@
"\n",
"数据块过大,则 Dask Worker 很容易内存耗尽(Out of Memory,OOM),因为所切分的数据块无法被单个 Dask Worker 所处理。Dask 遇到 OOM 时,会将部分数据卸载到(Spill)硬盘,如果 Spill 之后仍无法完成计算,Dask Worker 进程可能被重启,甚至反复重启。\n",
"\n",
"### 迭代式算法\n",
"## 迭代式算法\n",
"\n",
"迭代式算法通常会使用循环,循环的当前迭代依赖之前迭代的数据。Dask 的 Task Graph 对于这类迭代式算法处理得并不好,每个数据依赖都会在 Task Graph 中增加有向边,进而会使得 Task Graph 非常庞大,导致执行效率很低。比如,很多机器学习算法、SQL JOIN 都是基于循环的迭代式算法,用户需要对这些操作有心理准备。\n",
"\n",
"## 设置正确的数据块大小\n",
"\n",
"总之,在做数据块切分时,不应过大,也不应过小。Dask 没有一个简单通用的设置原则,需要开发者根据自身数据的情况和 Dask 的仪表盘或日志来不断调整。Dask Array 中使用 `rechunk(chunks=...)` 设置数据块大小,`chunks` 参数可以是 `int` 表示一个切分成多少个数据块,也可以是 `(5, 10, 20)` 这样的 `tuple`,表示单个数据块的维度大小。Dask DataFrame 中使用 `repartition(npartitions=...)` 设置数据块大小。 \n",
"总之,在做数据块切分时,不应过大,也不应过小。Dask 没有一个简单通用的设置原则,需要开发者根据自身数据的情况和 Dask 的仪表盘或日志来不断调整。\n",
"\n",
"### 仪表盘\n",
"\n",
Expand Down Expand Up @@ -603,7 +603,7 @@
"\n",
"Dask Array 和 Dask DataFrame 都提供了设置数据块的方式。\n",
"\n",
"可以在初始化时就设定每个数据块的大小,比如 `x = da.ones((10, 10), chunks=(5, 5))`,`chunks` 参数用来设置每个数据块大小。也可以在程序运行过程中调整,比如 Dask Array 的 [`rechunk()`](https://docs.dask.org/en/latest/generated/dask.array.rechunk.html) 和 Dask DataFrame 的 [`repartition()`](https://docs.dask.org/en/stable/generated/dask.dataframe.DataFrame.repartition.html)。\n"
"可以在初始化时就设定每个数据块的大小,比如 `x = da.ones((10, 10), chunks=(5, 5))`,`chunks` 参数用来设置每个数据块大小。也可以在程序运行过程中调整,比如 Dask Array 的 [`rechunk()`](https://docs.dask.org/en/latest/generated/dask.array.rechunk.html) 和 Dask DataFrame 的 [`repartition()`](https://docs.dask.org/en/stable/generated/dask.dataframe.DataFrame.repartition.html)。Dask Array 的 `rechunk(chunks=...)` 在程序运行过程中调整数据块大小,`chunks` 参数可以是 `int` 表示切分成多少个数据块,也可以是 `(5, 10, 20)` 这样的 `tuple`,表示单个矩阵的维度大小;Dask DataFrame 的 `repartition(npartitions=...)` 将数据切分成多少个 Partition。 \n"
]
},
{
Expand Down
Loading

0 comments on commit 4268228

Please sign in to comment.