第1章 256级灰度 1
1.1 什么是机器学习 2
1.2 经典的机器学习问题:图像分类 3
1.2.1 挑战:构建一个数字识别程序 3
1.2.2 机器学习中的距离函数 5
1.2.3 从简单的方法入手 5
1.3 我们的第一个模型(C#版本) 6
1.3.1 数据集组织 6
1.3.2 读取数据 7
1.3.3 计算图像之间的距离 9
1.3.4 编写分类器 11
1.4 那么,如何知道程序有效? 12
1.4.1 交叉验证 12
1.4.2 评估模型质量 13
1.4.3 改进模型 14
1.5 介绍用于机器学习的F# 15
1.5.1 使用F#交互执行进行实时脚本编写和数据研究 15
1.5.2 创建第一个F#脚本 18
1.5.3 剖析第一个F#脚本 19
1.5.4 创建函数管道 22
1.5.5 用元组和模式匹配操纵数据 23
1.5.6 训练和评估分类器函数 24
1.6 改进我们的模型 26
1.6.1 试验距离的另一种定义 26
1.6.2 重构距离函数 27
1.7 我们学到了什么 30
1.7.1 在好的距离函数中能找到什么 30
1.7.2 模型不一定要很复杂 31
1.7.3 为什么使用F#? 31
1.8 更进一步 32
第2章 垃圾邮件还是非垃圾邮件? 33
2.1 挑战:构建一个垃圾邮件检测引擎 34
2.1.1 了解我们的数据集 34
2.1.2 使用可区分联合建立标签模型 35
2.1.3 读取数据集 36
2.2 根据一个单词决定 38
2.2.1 以单词作为线索 38
2.2.2 用一个数字表示我们的确定程度 39
2.2.3 贝叶斯定理 40
2.2.4 处理罕见的单词 42
2.3 组合多个单词 42
2.3.1 将文本分解为标记 42
2.3.2 简单组合得分 43
2.3.3 简化的文档得分 44
2.4 实现分类器 45
2.4.1 将代码提取到模块中 46
2.4.2 文档评分与分类 47
2.4.3 集合和序列简介 49
2.4.4 从文档语料库中学习 51
2.5 训练第一个分类器 53
2.5.1 实现第一个标记化程序 54
2.5.2 交互式验证设计 54
2.5.3 用交叉验证确立基准 55
2.6 改进分类器 56
2.6.1 使用每个单词 56
2.6.2 大小写是否重要? 57
2.6.3 简单就是美 58
2.6.4 仔细选择单词 59
2.6.5 创建新特征 61
2.6.6 处理数字值 63
2.7 理解分类错误 64
2.8 我们学到了什么? 66
第3章 类型提供程序的快乐 67
3.1 探索StackOverflow数据 68
3.1.1 StackExchange API 68
3.1.2 使用JSON类型提供程序 70
3.1.3 构建查询问题的最小化DSL 73
3.2 世界上的所有数据 76
3.2.1 世界银行类型提供程序 76
3.2.2 R类型提供程序 77
3.2.3 分析数据与R数据框架 81
3.2.4.NET数据框架Deedle 83
3.2.5 全世界的数据统一起来! 84
3.3 我们学到了什么? 88
第4章 自行车与人 91
4.1 了解数据 92
4.1.1 数据集有哪些内容? 92
4.1.2 用FSharp.Charting检查数据 93
4.1.3 用移动平均数发现趋势 94
4.2 为数据适配模型 96
4.2.1 定义简单直线模型 96
4.2.2 寻找最低代价模型 97
4.2.3 用梯度下降找出函数的最小值 98
4.2.4 使用梯度下降进行曲线拟合 99
4.2.5 更通用的模型公式 100
4.3 实施梯度下降的方法 101
4.3.1 随机梯度下降 101
4.3.2 分析模型改进 103
4.3.3 批量梯度下降 105
4.4 拯救者——线性代数 107
4.4.1 宝贝,我缩短了公式! 108
4.4.2 用Math.NET进行线性代数运算 109
4.4.3 标准形式 110
4.4.4 利用MKL开足马力 111
4.5 快速演化和验证模型 112
4.5.1 交叉验证和过度拟合 112
4.5.2 简化模型的创建 113
4.5.3 在模型中添加连续特征 115
4.6 用更多特征改进预测 117
4.6.1 处理分类特征 117
4.6.2 非线性特征 119
4.6.3 正规化 122
4.7 我们学到了什么? 123
4.7.1 用梯度下降最大限度地减小代价 123
4.7.2 用回归方法预测数字 124
第5章 你不是独一无二的雪花 125
5.1 发现数据中的模式 126
5.2 我们所面临的挑战:理解StackOverflow上的主题 128
5.3 用K-均值聚类方法找出聚类 132
5.3.1 改进聚类和质心 133
5.3.2 实施K-均值聚类方法 135
5.4 StackOverflow标签的归类 138
5.4.1 运行聚类分析 138
5.4.2 结果分析 139
5.5 好的聚类和坏的聚类 141
5.6 重新标度数据集以改进聚类 144
5.7 确定需要搜索的聚类数量 147
5.7.1 什么是“好”的聚类? 147
5.7.2 确定StackOverflow数据集的k值 148
5.7.3 最终的聚类 150
5.8 发现特征的相关性 151
5.8.1 协方差和相关系数 151
5.8.2 StackOverflow标签之间的相关性 153
5.9 用主成分分析确定更好的特征 154
5.9.1 用代数方法重新组合特征 155
5.9.2 PCA工作方式预览 156
5.9.3 实现PCA 158
5.9.4 对StackOverflow数据集应用PCA 159
5.9.5 分析提取的特征 160
5.10 提出建议 165
5.10.1 简单标签推荐系统 165
5.10.2 实现推荐系统 166
5.10.3 验证做出的推荐 168
5.11 我们学到了什么? 170
第6章 树与森林 171
6.1 我们所面临的挑战:“泰坦尼克”上的生死存亡 171
6.1.1 了解数据集 172
6.1.2 观察各个特征 173
6.1.3 构造决策桩 174
6.1.4 训练决策桩 176
6.2 不适合的特征 177
6.2.1 数值该如何处理? 177
6.2.2 缺失数据怎么办? 178
6.3 计量数据中的信息 180
6.3.1 用熵计量不确定性 180
6.3.2 信息增益 182
6.3.3 实现最佳特征识别 184
6.3.4 使用熵离散化数值型特征 186
6.4 从数据中培育一棵决策树 187
6.4.1 建立树的模型 187
6.4.2 构建决策树 189
6.4.3 更漂亮的树 191
6.5 改进决策树 192
6.5.1 为什么会过度拟合? 193
6.5.2 用过滤器限制过度的自信 194
6.6 从树到森林 195
6.6.1 用k-折方法进行更深入的交叉验证 196
6.6.2 将脆弱的树组合成健壮的森林 198
6.6.3 实现缺失的部分 199
6.6.4 发展一个森林 200
6.6.5 尝试森林 201
6.7 我们学到了什么? 202
第7章 一个奇怪的游戏 205
7.1 构建一个简单的游戏 206
7.1.1 游戏元素建模 206
7.1.2 游戏逻辑建模 207
7.1.3 以控制台应用的形式运行游戏 209
7.1.4 游戏显示 211
7.2 构建一个粗糙的“大脑” 213
7.2.1 决策过程建模 214
7.2.2 从经验中学习制胜策略 215
7.2.3 实现“大脑” 216
7.2.4 测试“大脑” 218
7.3 我们能更高效地学习吗? 221
7.3.1 探索与利用的对比 221
7.3.2 红色的门和蓝色的门是否不同? 222
7.3.3 贪婪与规划的对比 223
7.4 无限的瓷砖组成的世界 224
7.5 实现“大脑”2.0 227
7.5.1 简化游戏世界 227
7.5.2 预先规划 228
7.5.3 ε-学习 229
7.6 我们学到了什么? 231
7.6.1 符合直觉的简单模型 231
7.6.2 自适应机制 232
第8章 重回数字 233
8.1 调整代码 233
8.1.1 寻求的目标 234
8.1.2 调整距离函数 235
8.1.3 使用Array.Parallel 239
8.2 使用Accord.NET实现不同的分类器 240
8.2.1 逻辑回归 241
8.2.2 用Accord实现简单逻辑回归 242
8.2.3 一对一、一对多分类 244
8.2.4 支持向量机 246
8.2.5 神经网络 248
8.2.6 用Accord创建和训练一个神经网络 250
8.3 用m-brace.net实现伸缩性 253
8.3.1 用Brisk启动Azure上的MBrace 253
8.3.2 用MBrace处理大数据集 256
8.4 我们学到了什么? 259
第9章 结语 261
9.1 描绘我们的旅程 261
9.2 科学! 262
9.3 F#:函数式风格更有效率 263
9.4 下一步是什么? 264