├── .nojekyll ├── 特征工程 ├── 时序分析 │ └── README.md ├── 数据集 │ ├── README.md │ ├── 文本 │ │ ├── README.md │ │ └── 常用数据集介绍.md │ ├── 数据集特点.md │ └── 图片 │ │ └── 猫狗.ipynb ├── 特征编码 │ ├── TF-IDF.md │ ├── README.old.md │ ├── 归一化.md │ └── README.md ├── 应用案例 │ └── README.md ├── README.md ├── 特征降维 │ ├── PCA.md │ └── README.md ├── 特征选择 │ └── README.md └── 数据清理 │ └── README.md ├── INTRODUCTION.md ├── 聚类算法 ├── BIRCH.md └── DBSCAN │ └── DBSCAN_Scratch.ipynb ├── 回归 └── 线性回归.md ├── 00~导论 ├── 机器学习三要素.md ├── README.md ├── 机器学习简史.md ├── 机器学习算法.md └── MachineLearning-Is-Fun-For-Anyone-Curious-About-ML.md ├── 数据挖掘 └── README.md ├── 用户画像 └── README.md ├── 模型评估 ├── 欠拟合与过拟合.md ├── 正则化项 │ └── 正则化.md ├── 误差与验证.md └── 范式.md ├── 99~参考资料 └── Machine Learning From Scratch │ └── README.md ├── 分类 └── 贝叶斯分类器.md ├── .gitignore ├── _sidebar.md ├── README.md ├── index.html ├── header.svg └── LICENSE /.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /特征工程/时序分析/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /INTRODUCTION.md: -------------------------------------------------------------------------------- 1 | # 本篇导读 2 | -------------------------------------------------------------------------------- /聚类算法/BIRCH.md: -------------------------------------------------------------------------------- 1 | # BIRCH 2 | -------------------------------------------------------------------------------- /特征工程/数据集/README.md: -------------------------------------------------------------------------------- 1 | # 常用数据集介绍 2 | -------------------------------------------------------------------------------- /特征工程/特征编码/TF-IDF.md: -------------------------------------------------------------------------------- 1 | # TF-IDF 2 | -------------------------------------------------------------------------------- /回归/线性回归.md: -------------------------------------------------------------------------------- 1 | # 线性回归 2 | 3 | ![线性回归](https://s1.ax1x.com/2020/10/07/0auHmQ.png) 4 | -------------------------------------------------------------------------------- /00~导论/机器学习三要素.md: -------------------------------------------------------------------------------- 1 | # 机器学习三要素 2 | 3 | # 特征与样本 4 | 5 | # 模型 6 | 7 | # 策略 8 | 9 | # 算法 10 | -------------------------------------------------------------------------------- /数据挖掘/README.md: -------------------------------------------------------------------------------- 1 | # 数据挖掘 2 | 3 | ![数据科学与机器学习](https://pic.imgdb.cn/item/61a2eb472ab3f51d917c1b68.png) 4 | -------------------------------------------------------------------------------- /特征工程/数据集/文本/README.md: -------------------------------------------------------------------------------- 1 | # 概述 2 | 3 | 数据和算法在 NLP 中都非常重要,使用公开的数据集可以帮助我们快速学习 NLP 相关知识并实践,下面我们将介绍常用的几个数据集。 4 | -------------------------------------------------------------------------------- /用户画像/README.md: -------------------------------------------------------------------------------- 1 | # 用户画像 2 | 3 | ![用户画像](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230416205246.png) 4 | -------------------------------------------------------------------------------- /模型评估/欠拟合与过拟合.md: -------------------------------------------------------------------------------- 1 | # 欠拟合与过拟合 2 | 3 | # Links 4 | 5 | - http://zh.gluon.ai/chapter_deep-learning-basics/underfit-overfit.html 6 | -------------------------------------------------------------------------------- /99~参考资料/Machine Learning From Scratch/README.md: -------------------------------------------------------------------------------- 1 | > [原文地址](https://github.com/Yimeng-Zhang/Machine-Learning-From-Scratch) 2 | 3 | # Machine Learning From Scratch 4 | -------------------------------------------------------------------------------- /特征工程/应用案例/README.md: -------------------------------------------------------------------------------- 1 | # 特征工程案例 2 | 3 | # Links 4 | 5 | - https://towardsdatascience.com/feature-engineering-for-machine-learning-3a5e293a5114 6 | - https://blog.csdn.net/zdy0_2004/article/details/79692400 7 | - https://medium.com/@michaelabehsera/feature-engineering-cookbook-for-machine-learning-7bf21f0bcbae 8 | -------------------------------------------------------------------------------- /特征工程/README.md: -------------------------------------------------------------------------------- 1 | # 数据处理与特征工程 2 | 3 | 熟悉数据挖掘和机器学习的小伙伴们都知道,数据处理相关的工作时间占据了整个项目的 70%以上。数据的质量,直接决定了模型的预测和泛化能力的好坏。它涉及很多因素,包括:准确性、完整性、一致性、时效性、可信性和解释性。而在真实数据中,我们拿到的数据可能包含了大量的缺失值,可能包含大量的噪音,也可能因为人工录入错误导致有异常点存在,非常不利于算法模型的训练。数据清洗的结果是对各种脏数据进行对应方式的处理,得到标准的、干净的、连续的数据,提供给数据统计、数据挖掘等使用。 4 | 5 | 数据处理与特征工程的主要步骤分为:数据清理、特征编码、特征选择、特征降维、特征评估等。 6 | 7 | # Links 8 | 9 | - https://towardsdatascience.com/feature-engineering-for-machine-learning-3a5e293a5114 10 | - https://mp.weixin.qq.com/s/btjxZ4toD0nGQBLbU77cwg 11 | -------------------------------------------------------------------------------- /特征工程/特征降维/PCA.md: -------------------------------------------------------------------------------- 1 | # PCA 2 | 3 | PCA(Principal Component Analysis)不仅仅是对高维数据进行降维,更重要的是经过降维去除了噪声,发现了数据中的模式。PCA 把原先的 n 个特征用数目更少的 m 个特征取代,新特征是旧特征的线性组合,这些线性组合最大化样本方差,尽量使新的 m 个特征互不相关。从旧特征到新特征的映射捕获数据中的固有变异性。 4 | 5 | 根据上面对 PCA 的数学原理的解释,我们可以了解到一些 PCA 的能力和限制。PCA 本质上是将方差最大的方向作为主要特征,并且在各个正交方向上将数据“离相关”,也就是让它们在不同正交方向上没有相关性。因此,PCA 也存在一些限制,例如它可以很好的解除线性相关,但是对于高阶相关性就没有办法了,对于存在高阶相关性的数据,可以 考虑 Kernel PCA,通过 Kernel 函数将非线性相关转为线性相关,关于这点就不展开讨论了。另外,PCA 假设数据各主特征是分布在正交方向上,如果在非正交方向上 存在几个方差较大的方向,PCA 的效果就大打折扣了。 6 | 7 | 最后需要说明的是,PCA 是一种无参数技术,也就是说面对同样的数据,如果不考虑清洗,谁来做结果都一样,没有主观参数的介入,所以 PCA 便于通用实现,但是本身无法个性化的优化。 8 | -------------------------------------------------------------------------------- /特征工程/特征编码/README.old.md: -------------------------------------------------------------------------------- 1 | # 数据变换 2 | 3 | 数据变换包括对数据进行规范化,离散化,稀疏化处理,达到适用于挖掘的目的。 4 | 5 | # 规范化处理 6 | 7 | ![](https://tva1.sinaimg.cn/large/007DFXDhgy1g5urbccl78j30tz0v5q70.jpg) 8 | 9 | # 离散化处理 10 | 11 | 数据离散化是指将连续的数据进行分段,使其变为一段段离散化的区间。分段的原则有基于等距离、等频率或优化的方法。数据离散化的原因主要有以下几点: 12 | 13 | - 模型需要:比如决策树、朴素贝叶斯等算法,都是基于离散型的数据展开的。如果要使用该类算法,必须将离散型的数据进行。有效的离散化能减小算法的时间和空间开销,提高系统对样本的分类聚类能力和抗噪声能力。 14 | 15 | - 离散化的特征相对于连续型特征更易理解。 16 | 17 | - 可以有效的克服数据中隐藏的缺陷,使模型结果更加稳定。 18 | 19 | 等频法:使得每个箱中的样本数量相等,例如总样本 n=100,分成 k=5 个箱,则分箱原则是保证落入每个箱的样本量=20。 20 | 21 | 等宽法:使得属性的箱宽度相等,例如年龄变量(0-100 之间),可分成 [0,20],[20,40],[40,60],[60,80],[80,100]五个等宽的箱。 22 | 23 | 聚类法:根据聚类出来的簇,每个簇中的数据为一个箱,簇的数量模型给定。 24 | 25 | # 稀疏化处理 26 | 27 | 针对离散型且标称变量,无法进行有序的 LabelEncoder 时,通常考虑将变量做 0,1 哑变量的稀疏化处理,例如动物类型变量中含有猫,狗,猪,羊四个不同值,将该变量转换成 is*猪,is*猫,is*狗,is*羊四个哑变量。若是变量的不同值较多,则根据频数,将出现次数较少的值统一归为一类'rare'。稀疏化处理既有利于模型快速收敛,又能提升模型的抗噪能力。 28 | -------------------------------------------------------------------------------- /分类/贝叶斯分类器.md: -------------------------------------------------------------------------------- 1 | # 贝叶斯分类器 2 | 3 | ```py 4 | # 导入基础库 5 | from sklearn.datasets import make_classification 6 | from sklearn.metrics import roc_auc_score 7 | from sklearn.model_selection import train_test_split 8 | 9 | # 导入朴素贝叶斯分类器 10 | from naive_bayes_classifier import NaiveBayesClassifier 11 | 12 | # 构造二元分类问题 13 | X, y = make_classification(n_samples=1000, n_features=10, n_informative=10, 14 | random_state=1111, n_classes=2, class_sep=2.5, 15 | n_redundant=0) 16 | 17 | # 划分训练数据集与测试数据集 18 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, 19 | random_state=1111) 20 | 21 | model = NaiveBayesClassifier() 22 | 23 | # 进行模型拟合训练 24 | model.fit(X_train, y_train) 25 | 26 | # 进行模型预测 27 | predictions = model.predict(X_test)[:, 1] 28 | 29 | # 输出最终的测试结果 30 | print('classification accuracy', roc_auc_score(y_test, predictions)) 31 | ``` 32 | -------------------------------------------------------------------------------- /00~导论/README.md: -------------------------------------------------------------------------------- 1 | # 机器学习 2 | 3 | ![机器学习版图](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230416205319.png) 4 | 5 | # 程序与学习 6 | 7 | 大部分程序并不需要深度学习或者是更广义上的人工智能技术。例如,如果我们要为一台微波炉编写一个用户界面,只需要一点儿工夫我们便能设计出十几个按钮以及一系列能精确描述微波炉在各种情况下的表现的规则。再比如,假设我们要编写一个电子邮件客户端。这样的程序比微波炉要复杂一些,但我们还是可以沉下心来一步一步思考:客户端的用户界面将需要几个输入框来接受收件人、主题、邮件正文等,程序将监听键盘输入并写入一个缓冲区,然后将它们显示在相应的输入框中。当用户点击“发送”按钮时,我们需要检查收件人邮箱地址的格式是否正确,并检查邮件主题是否为空,或在主题为空时警告用户,而后用相应的协议传送邮件。 8 | 9 | 值得注意的是,在以上两个例子中,我们都不需要收集真实世界中的数据,也不需要系统地提取这些数据的特征。只要有充足的时间,我们的常识与编程技巧已经足够让我们完成任务。与此同时,我们很容易就能找到一些连世界上最好的程序员也无法仅用编程技巧解决的简单问题。例如,假设我们想要编写一个判定一张图像中有没有猫的程序。这件事听起来好像很简单,对不对?程序只需要对每张输入图像输出“真”(表示有猫)或者“假”(表示无猫)即可。但令人惊讶的是,即使是世界上最优秀的计算机科学家和程序员也不懂如何编写这样的程序。 10 | 11 | 一种解决以上问题的思路是逆向思考。与其设计一个解决问题的程序,不如从最终的需求入手来寻找一个解决方案。事实上,这也是目前的机器学习和深度学习应用共同的核心思想:我们可以称其为“用数据编程”。与其枯坐在房间里思考怎么设计一个识别猫的程序,不如利用人类肉眼在图像中识别猫的能力。我们可以收集一些已知包含猫与不包含猫的真实图像,然后我们的目标就转化成如何从这些图像入手得到一个可以推断出图像中是否有猫的函数。这个函数的形式通常通过我们的知识来针对特定问题选定。例如,我们使用一个二次函数来判断图像中是否有猫,但是像二次函数系数值这样的函数参数的具体值则是通过数据来确定。 12 | 13 | 通俗来说,机器学习是一门讨论各式各样的适用于不同问题的函数形式,以及如何使用数据来有效地获取函数参数具体值的学科。深度学习是指机器学习中的一类函数,它们的形式通常为多层神经网络。近年来,仰仗着大数据集和强大的硬件,深度学习已逐渐成为处理图像、文本语料和声音信号等复杂高维度数据的主要方法。 14 | -------------------------------------------------------------------------------- /特征工程/特征选择/README.md: -------------------------------------------------------------------------------- 1 | # 数据规约 2 | 3 | 数据归约技术可以用来得到数据集的归约表示,它小得多,但仍接近地保持原数据的完整性。这样,在归约后的数据集上挖掘将更有效,并产生相同(或几乎相同)的分析结果。用于数据分析的数据可能包含数以百计的属性,其中大部分属性与挖掘任务不相关,是冗余的。维度归约通过删除不相关的属性,来减少数据量,并保证信息的损失最小。 4 | 5 | # 属性子集选择 6 | 7 | 目标是找出最小属性集,使得数据类的概率分布尽可能地接近使用所有属性的原分布。在压缩 的属性集上挖掘还有其它的优点。它减少了出现在发现模式上的属性的数目,使得模式更易于理解。 8 | 9 | - 逐步向前选择:该过程由空属性集开始,选择原属性集中最好的属性,并将它添加到该集合中。在其后的每一次迭代,将原属性集剩下的属性中的最好的属性添加到该集合中。 10 | 11 | - 逐步向后删除:该过程由整个属性集开始。在每一步,删除掉尚在属性集中的最坏属性。 12 | 13 | - 向前选择和向后删除的结合:向前选择和向后删除方法可以结合在一起,每一步选择一个最 好的属性,并在剩余属性中删除一个最坏的属性。 14 | 15 | Python scikit-learn 中的递归特征消除算法 Recursive feature elimination (RFE),就是利用这样的思想进行特征子集筛选的,一般考虑建立 SVM 或回归模型。 16 | 17 | # 单变量重要性 18 | 19 | 分析单变量和目标变量的相关性,删除预测能力较低的变量。这种方法不同于属性子集选择,通常从统计学和信息的角度去分析。 20 | 21 | - pearson 相关系数和卡方检验,分析目标变量和单变量的相关性。 22 | 23 | - 回归系数:训练线性回归或逻辑回归,提取每个变量的表决系数,进行重要性排序。 24 | 25 | - 树模型的 Gini 指数:训练决策树模型,提取每个变量的重要度,即 Gini 指数进行排序。 26 | 27 | - Lasso 正则化:训练回归模型时,加入 L1 正则化参数,将特征向量稀疏化。 28 | 29 | - IV 指标:风控模型中,通常求解每个变量的 IV 值,来定义变量的重要度,一般将阀值设定在 0.02 以上。 30 | 31 | 通常的做法是根据业务需求来定,如果基于业务的用户或商品特征,需要较多的解释性,考虑采用统计上的一些方法,如变量的分布曲线,直方图等,再计算相关性指标,最后去考虑一些模型方法。如果建模需要,则通常采用模型方法去筛选特征,如果用一些更为复杂的 GBDT,DNN 等模型,建议不做特征选择,而做特征交叉。 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all 2 | * 3 | 4 | # Unignore all with extensions 5 | !*.* 6 | 7 | # Unignore all dirs 8 | !*/ 9 | 10 | .DS_Store 11 | 12 | # Logs 13 | logs 14 | *.log 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (https://nodejs.org/api/addons.html) 44 | build/Release 45 | 46 | # Dependency directories 47 | node_modules/ 48 | jspm_packages/ 49 | 50 | # TypeScript v1 declaration files 51 | typings/ 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env 70 | 71 | # next.js build output 72 | .next 73 | -------------------------------------------------------------------------------- /特征工程/特征编码/归一化.md: -------------------------------------------------------------------------------- 1 | # Normalization 2 | 3 | 数据标准化(归一化)处理是数据挖掘的一项基础工作,不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。原始数据经过数据标准化处理后,各指标处于同一数量级,适合进行综合对比评价。以下是两种常用的归一化方法: 4 | 5 | # min-max 标准化(Min-Max Normalization) 6 | 7 | 也称为离差标准化,是对原始数据的线性变换,使结果值映射到[0 - 1]之间。转换函数如下: 8 | 9 | [![clip_image002](http://images.cnitblog.com/blog/407700/201307/31105200-fa4ecf7c8f7f4960a1cc47c349979c45.gif)](http://images.cnitblog.com/blog/407700/201307/31105200-6bd5002661114e40ba1ee5d7d3377015.gif) 10 | 11 | 其中 max 为样本数据的最大值,min 为样本数据的最小值。这种方法有个缺陷就是当有新数据加入时,可能导致 max 和 min 的变化,需要重新定义。 12 | 13 | # Z-score 标准化方法 14 | 15 | 这种方法给予原始数据的均值(mean)和标准差(standard deviation)进行数据的标准化。经过处理的数据符合标准正态分布,即均值为 0,标准差为 1,转化函数为: 16 | 17 | [![clip_image004](http://images.cnitblog.com/blog/407700/201307/31105201-fa88e179a3ed46e99372f1804a914c4f.gif)](http://images.cnitblog.com/blog/407700/201307/31105201-a6fe07c7a6764af0ac554988a3468917.gif) 18 | 19 | 其中[![clip_image006](http://images.cnitblog.com/blog/407700/201307/31105201-d56ab5212c974bc7816b147c6051f54f.gif)](http://images.cnitblog.com/blog/407700/201307/31105201-9d0fa14ece1946f38e3888c5549eb5d9.gif)为所有样本数据的均值,[![clip_image008](http://images.cnitblog.com/blog/407700/201307/31105202-56805481fe2f4c10804c5c5d83be27b1.gif)](http://images.cnitblog.com/blog/407700/201307/31105202-75fa8d217dcb462d81166b034ba7b400.gif)为所有样本数据的标准差。 20 | -------------------------------------------------------------------------------- /模型评估/正则化项/正则化.md: -------------------------------------------------------------------------------- 1 | # Regularization:正则化 2 | 3 | 我们都知道,在进行数据挖掘或者机器学习模 型建立的时候,因为在统计学习中,假设数据满足独立同分布(i.i.d,independently and identically distributed),即当前已产生的数据可以对未来的数据进行推测与模拟,因此都是使用历史数据建立模型,即使用已经产生的数据去训练,然后使用该 模型去拟合未来的数据。但是一般独立同分布的假设往往不成立,即数据的分布可能会发生变化(distribution drift),并且可能当前的数据量过少,不足以对整个数据集进行分布估计,因此往往需要防止模型过拟合,提高模型泛化能力。而为了达到该目的的最常见方 法便是:正则化, 4 | 正则化(Regularization)是机器学习中一个很重要的防止过拟合的手段,它会为模型的目标函数(objective function)或代价函数(cost function)加上正则项来避免模型参数过度拟合于测试数据。而 L1 正则与 L2 正则的区别在于 L1 是权重的直接和,而 L2 是权重的平方和。 5 | 规则化符合奥卡姆剃刀(Occam's razor)原理,在所有可能选择的模型中,我们应该选择能够很好地解释已知数据并且十分简单的模型。从贝叶 斯估计的角度来看,规则化项对应于模型的先验概率。民间还有个说法就是,正则化是结构风险最小化策略的实现,是在经验风险上加一个正则化项 (regularizer)或惩罚项(penalty term)。加上正则化项之后的监督函数的目标函数为: 6 | 7 | $$ 8 | w^* = arg min_{w} \sum_i L(y_i,f(x_i;w)) + \lambda \Omega(w) 9 | $$ 10 | 11 | 在上述表达式中,第一项$L(y_i,f(x_i;w))$即是衡量模型对第$i$个样本的预测值$f(x_i;w)$与真实的标签值$y_i$之间的误差。第二项$\lambda \Omega(w)$即是正则化项用于约束我们的模型能够尽量的简单。而 L1 正则化与 L2 正则化的差异在于: 12 | | L2 Regularization | L1 Regularization | 13 | | ---------------------------------------- | ---------------------------------------- | 14 | | Computational efficient due to having analytical solutions | Computational inefficient on non-sparse cases | 15 | | Non-sparse outputs | Sparse outputs | 16 | | No feature selection | Built-in feature selection | 17 | 18 | 这里简要解释下上面三个比较项的含义,具体的求值与应用在下文中进行阐述: 19 | 20 | - Computational Efficiency:计算性能 21 | - Sparsity:稀疏度 22 | - Built-in Feature Selection:内建的特征选择 23 | 24 | # L1 Regularization 25 | 26 | # L2 Regularization 27 | -------------------------------------------------------------------------------- /_sidebar.md: -------------------------------------------------------------------------------- 1 | - [1 00~导论 [4]](/00~导论/README.md) 2 | - [1.1 MachineLearning Is Fun For Anyone Curious About ML](/00~导论/MachineLearning-Is-Fun-For-Anyone-Curious-About-ML.md) 3 | - [1.2 机器学习三要素](/00~导论/机器学习三要素.md) 4 | - [1.3 机器学习简史](/00~导论/机器学习简史.md) 5 | - [1.4 机器学习算法](/00~导论/机器学习算法.md) 6 | - 2 99~参考资料 [1] 7 | - [2.1 Machine Learning From Scratch](/99~参考资料/Machine%20Learning%20From%20Scratch/README.md) 8 | 9 | - [3 INTRODUCTION](/INTRODUCTION.md) 10 | - 4 分类 [1] 11 | - [4.1 贝叶斯分类器](/分类/贝叶斯分类器.md) 12 | - 5 回归 [1] 13 | - [5.1 线性回归](/回归/线性回归.md) 14 | - [6 数据挖掘](/数据挖掘/README.md) 15 | 16 | - 7 模型评估 [4] 17 | - [7.1 欠拟合与过拟合](/模型评估/欠拟合与过拟合.md) 18 | - 7.2 正则化项 [1] 19 | - [7.2.1 正则化](/模型评估/正则化项/正则化.md) 20 | - [7.3 范式](/模型评估/范式.md) 21 | - [7.4 误差与验证](/模型评估/误差与验证.md) 22 | - [8 特征工程 [7]](/特征工程/README.md) 23 | - [8.1 应用案例](/特征工程/应用案例/README.md) 24 | 25 | - [8.2 数据清理](/特征工程/数据清理/README.md) 26 | 27 | - [8.3 数据集 [2]](/特征工程/数据集/README.md) 28 | - [8.3.1 数据集特点](/特征工程/数据集/数据集特点.md) 29 | - [8.3.2 文本 [1]](/特征工程/数据集/文本/README.md) 30 | - [8.3.2.1 常用数据集介绍](/特征工程/数据集/文本/常用数据集介绍.md) 31 | - [8.4 时序分析](/特征工程/时序分析/README.md) 32 | 33 | - [8.5 特征编码 [2]](/特征工程/特征编码/README.md) 34 | - [8.5.1 README.old](/特征工程/特征编码/README.old.md) 35 | - [8.5.2 TF IDF](/特征工程/特征编码/TF-IDF.md) 36 | - [8.5.3 归一化](/特征工程/特征编码/归一化.md) 37 | - [8.6 特征选择](/特征工程/特征选择/README.md) 38 | 39 | - [8.7 特征降维 [1]](/特征工程/特征降维/README.md) 40 | - [8.7.1 PCA](/特征工程/特征降维/PCA.md) 41 | - [9 用户画像](/用户画像/README.md) 42 | 43 | - 10 聚类算法 [1] 44 | - [10.1 BIRCH](/聚类算法/BIRCH.md) -------------------------------------------------------------------------------- /特征工程/数据清理/README.md: -------------------------------------------------------------------------------- 1 | # 数据清理 2 | 3 | 数据清理(data cleaning) 的主要思想是通过填补缺失值、光滑噪声数据,平滑或删除离群点,并解决数据的不一致性来“清理“数据。如果用户认为数据时脏乱的,他们不太会相信基于这些数据的挖掘结果,即输出的结果是不可靠的。 4 | 5 | # 缺失值的处理 6 | 7 | 由于现实世界中,获取信息和数据的过程中,会存在各类的原因导致数据丢失和空缺。针对这些缺失值的处理方法,主要是基于变量的分布特性和变量的重要性(信息量和预测能力)采用不同的方法。主要分为以下几种: 8 | 9 | - 删除变量:若变量的缺失率较高(大于 80%),覆盖率较低,且重要性较低,可以直接将变量删除。 10 | 11 | - 定值填充:工程中常见用-9999 进行替代 12 | 13 | - 统计量填充:若缺失率较低(小于 95%)且重要性较低,则根据数据分布的情况进行填充。对于数据符合均匀分布,用该变量的均值填补缺失,对于数据存在倾斜分布的情况,采用中位数进行填补。 14 | 15 | - 插值法填充:包括随机插值,多重差补法,热平台插补,拉格朗日插值,牛顿插值等 16 | 17 | - 模型填充:使用回归、贝叶斯、随机森林、决策树等模型对缺失数据进行预测。 18 | 19 | - 哑变量填充:若变量是离散型,且不同值较少,可转换成哑变量,例如性别 SEX 变量,存在 male,fameal,NA 三个不同的值,可将该列转换成 IS_SEX_MALE, IS_SEX_FEMALE, IS_SEX_NA。若某个变量存在十几个不同的值,可根据每个值的频数,将频数较小的值归为一类'other',降低维度。此做法可最大化保留变量的信息。 20 | 21 | 先用 pandas.isnull.sum()检测出变量的缺失比例,考虑删除或者填充,若需要填充的变量是连续型,一般采用均值法和随机差值进行填充,若变量是离散型,通常采用中位数或哑变量进行填充。注意:若对变量进行分箱离散化,一般会将缺失值单独作为一个箱子(离散变量的一个值) 22 | 23 | # 离群点处理 24 | 25 | 异常值是数据分布的常态,处于特定分布区域或范围之外的数据通常被定义为异常或噪声。异常分为两种:“伪异常”,由于特定的业务运营动作产生,是正常反应业务的状态,而不是数据本身的异常;“真异常”,不是由于特定的业务运营动作产生,而是数据本身分布异常,即离群点。主要有以下检测离群点的方法: 26 | 27 | - 简单统计分析:根据箱线图、各分位点判断是否存在异常,例如 pandas 的 describe 函数可以快速发现异常值。 28 | 29 | - 3$\sigma$ 原则:若数据存在正态分布,偏离均值的 3$\sigma$ 之外. 通常定义 $P(|x-\mu|>3\sigma)<=0.03$ 范围内的点为离群点。 30 | 31 | - 基于绝对离差中位数(MAD):这是一种稳健对抗离群数据的距离值方法,采用计算各观测值与平均值的距离总和的方法。放大了离群值的影响。 32 | 33 | - 基于距离:通过定义对象之间的临近性度量,根据距离判断异常对象是否远离其他对象,缺点是计算复杂度较高,不适用于大数据集和存在不同密度区域的数据集 34 | 35 | - 基于密度:离群点的局部密度显著低于大部分近邻点,适用于非均匀的数据集 36 | 37 | - 基于聚类:利用聚类算法,丢弃远离其他簇的小簇。 38 | 39 | 总结来看,在数据处理阶段将离群点作为影响数据质量的异常点考虑,而不是作为通常所说的异常检测目标点,因而楼主一般采用较为简单直观的方法,结合箱线图和 MAD 的统计方法判断变量的离群点。 40 | 41 | 具体的处理手段: 42 | 43 | - 根据异常点的数量和影响,考虑是否将该条记录删除,信息损失多 44 | 45 | - 若对数据做了 log-scale 对数变换后消除了异常值,则此方法生效,且不损失信息 46 | 47 | - 平均值或中位数替代异常点,简单高效,信息的损失较少 48 | 49 | - 在训练树模型时,树模型对离群点的鲁棒性较高,无信息损失,不影响模型训练效果 50 | 51 | # 噪声点处理 52 | 53 | 噪声是变量的随机误差和方差,是观测点和真实点之间的误差。通常的处理办法:对数据进行分箱操作,等频或等宽分箱,然后用每个箱的平均数,中位数或者边界值(不同数据分布,处理方法不同)代替箱中所有的数,起到平滑数据的作用。另外一种做法是,建立该变量和预测变量的回归模型,根据回归系数和预测变量,反解出自变量的近似值。 54 | -------------------------------------------------------------------------------- /特征工程/数据集/数据集特点.md: -------------------------------------------------------------------------------- 1 | # Instant Message:即时聊天信息 2 | 3 | ## Usage:用处 4 | 5 | Instant message clustering is very useful for analyzing its content characteristic or establishing other mining application. 6 | 7 | ## Features:文本特点 8 | 9 | ### 短文本,特征稀疏:sparse key words when clustering on instant messages 10 | 11 | The most common text processing approach is to represent the documents with vectors. This is so—called vector space model. in which a vector corresponds to one document and the dimensions correspond to words in this document. Once the high-dimensional vectors are derived. the major challenge left for document clustering is how to deal with these high dimensional data. However. instant message is extremely shorter than the common document. There are usually only several key words in one instant message. and key words about the message topic are even latent sometimes.The sparsity of key words makes word—frequency based methods inappropriate to measure the similarity among Instant messages. 12 | 13 | ## Process:处理方法 14 | 15 | methos to enhance the description of instant messages to response the problem of sparse key words when clustering on instant message.Firstly, we notice that instant message is a kind of semi-structured data. which has source and destination addresses with time stamp. Instant messages sent back and forth among specific persons during some specific time intervals form a conversation, which groups these instant messages into a specific topic. So we combine these messages as one conversation. it is obvious that conversation has more key works and more integral context information than simply single message. Then clustering is performed toward conversations instead of messages. Secondly. we enhance the content description of a conversation with words. which are not in the conversation but are closely related with existing words in this conversation. Fox example. words ‘ball’ and ‘football‘ are added to lM-2. which are not appear in lM-2 but have obvious correlation with the word. ‘basketball'. in lM-2. in this paper. we propose an instant message clustering method called WR-KMcans. which can automatically scan instant message corpora, construct conversations and enhance traditional TF-lDF model by adding relevant words in conversations. 16 | -------------------------------------------------------------------------------- /特征工程/特征编码/README.md: -------------------------------------------------------------------------------- 1 | # Feature Encoding 2 | 3 | # Feature Extraction(特征抽取) 4 | 5 | ## TF-IDF 6 | 7 | TF/IDF(term frequency/inverse document frequency) 的概念被公认为信息检索中最重要的发明。TF-IDF 比较典型的应用是在搜索引擎与文档分类中,用于描绘某个词所在特征维度的权重。譬如当我们搜索"原子能的应用",这个包含了"原子能"与"应用"两个关键词的句式时(已经忽略了停止词:的),要寻找与其最接近的网页,即是寻找这个查询语句或者待分类文档与已分类文档之间的相关性。概括地讲,如果一个查询包含关键词$w_1,w_2,...,w_N$, 它们在一篇特定网页中的词频分别是: $TF_1, TF_2, ..., TF_N$。(TF: term frequency)。那么,这个查询和该网页的相关性就是:$$TF_1 + TF_2 + ... + TF_N$$。 8 | 在汉语中,“应用”是个很通用的词,而“原子能”是个很专业的词,后者在相关性排名中比前者重要。因此我们需要给汉语中的每一个词给一个权重,这个权重的设定必须满足下面两个条件: 9 | 10 | 1. 一个词预测主题能力越强,权重就越大,反之,权重就越小。我们在网页中看到“原子能”这个词,或多或少地能了解网页的主题。我们看到“应用”一次,对主题基本上还是一无所知。因此,“原子能“的权重就应该比应用大。 11 | 2. 应删除词的权重应该是零。 12 | 如果一个关键词只在很少的网页中出现,我们通过它就容易锁定搜索目标,它的权重也就应该大。反之如果一个词在大量网页中出现,我们看到它仍 然不很清楚要找什么内容,因此它应该小。概括地讲,假定一个关键词 w 在 Dw 个网页中出现过,那么 Dw 越大,w 的权重越小,反之亦然。在信息检索中,使用最多的权重是“逆文本频率指数” (Inverse document frequency 缩写为IDF),它的公式为log(D/Dw)其中D是全部网页数。比如,我们假定中文网页数是D=10亿,应删除词“的”在所有的网页中都出现,即 Dw=10亿,那么它的IDF= log(10 亿/10 亿)= log (1) = 0。假如专用词“原子能”在两百万个网页中出现,即Dw=200万,则它的权重IDF= log(500) =6.2。又假定通用词“应用”,出现在五亿个网页中,它的权重IDF = log(2) 13 | 则只有 0.7。也就只说,在网页中找到一个“原子能”的比配相当于找到九个“应用”的匹配。利用 IDF,上述相关性计算个公式就由词频的简单求和变成了加权求和,即 TF1*IDF1 +  TF2*IDF2 +... + TFN\*IDFN。在上面的例子中,该网页和“原子能的应用”的相关性为 0.0161,其中“原子能”贡献了 0.0126,而“应用”只贡献了 0.0035。这个比例和我们的直觉比较一致了。 14 | 其实 IDF 的概念就是一个特定条件下、关键词的概率分布的交叉熵(Kullback-Leibler Divergence) 15 | 16 | ### 数学原理 17 | 18 | 一个查询(Query)中每一个关键词(Key Word)$w$的权重应该反映这个词对查询来讲提供了多少的信息。最简单的办法就是用每个词的信息量作为它的权重: 19 | 20 | $$ 21 | I(w) = -P(w)logP(w) = -\frac{TF(w)}{N}log\frac{TF(w)}{N} = \frac{TF(w)}{N}log\frac{N}{TF(w)} 22 | $$ 23 | 24 | 其中$N$是整个语料库的大小,是个可以省略的常数。而$TF(w)$是整个文档中某个词的词频,换言之,在上述公式中并没有将不同词汇在不同文档中的出现频次的差异考虑进去。公式可以简化为: 25 | $$I(w)=TF(w)log\frac{N}{TF(w)}$$ 26 | 显而易见,如果两个词的 TF 频率一致,但是一个是某几篇特定文章中的常见词,而另一个是均匀分散在多篇文章中的,那么前者的权重应该更大一点。在推导出新公式之前,首先进行一些假设: 27 | 28 | - 每个文献大小基本相同,均为 M 个词,即$$M=\frac{N}{D}=\frac{\sum_w{TF(w)}}{D}$$ 29 | - 每个关键词一旦出现,则次数均等,即某个关键词在所有包含它的文档中出现的次数相等。则每个关键词出现$$c(w) = \frac{TF(w)}{D(w)}$$次。 30 | 31 | 那么可以得到: 32 | 33 | $$ 34 | \frac{TF(w)}{N} log \frac{N}{TF(w)} = \frac{TF(w)}{N}log\frac{MD}{c(w)D(w)}= 35 | \frac{TF(w)}{N}log( \frac{D}{D(w)} \frac{M}{c(w)}) 36 | $$ 37 | 38 | 根据该公式,可以推导出 TF-IDF 公式的另一个表述: 39 | 40 | $$ 41 | TF-IDF(w)=I(w)-TF(w)log(\frac{M}{c(w)}) 42 | $$ 43 | 44 | 可以看出一个词的信息量$I(w)$越多,TF-IDF 值越大;同时$w$命中的文献中$w$平均出现的次数越多,第二项越小,TF-IDF 也越大。这些结论和信息论完全等同。 45 | 46 | ## StandardScaler 47 | 48 | # Feature Selection(特征选择) 49 | 50 | # PCA 51 | 52 | # Transform 53 | 54 | ## [Normalizer](http://spark.apache.org/docs/latest/mllib-feature-extraction.html#normalizer) 55 | 56 | # Association Rule Learning Algorithms 57 | 58 | ![Assoication Rule Learning Algorithms](http://3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com/wp-content/uploads/2013/11/Assoication-Rule-Learning-Algorithms.png) 59 | 60 | Association rule learning are methods that extract rules that best explain observed relationships between variables in data. 61 | 62 | These rules can discover important and commercially useful associations in large multidimensional datasets that can be exploited by an organisation. 63 | 64 | The most popular association rule learning algorithms are: 65 | 66 | - Apriori algorithm 67 | - Eclat algorithm 68 | -------------------------------------------------------------------------------- /00~导论/机器学习简史.md: -------------------------------------------------------------------------------- 1 | # 机器学习简史 2 | 3 | 机器学习是人工智能研究发展到一定阶段的必然产物,本章仅从笔者的视角对机器学习这五十年来的发展进行一个略述,疏漏错误之处烦请指正。下面这幅漫画中就展示了一个无奈的问题,三岁幼童可以轻松解决的问题却需要最顶尖的科学家花费数十年的光阴,或许机器学习离我们在电影里看到的那样还有很长一段路要走。 4 | 5 | 知识来源于哪里?知识来源于进化、经验、文化和计算机。对于知识和计算机的关系,可以引用 Facebook 人工智能实验室负责人 Yann LeCun 的一段话:将来,世界上的大部分知识将由机器提取出来,并且将长驻与机器中。而帮助计算机获取新知识,可以通过以下五种方法来实现: 6 | 7 | - 填充现存知识的空白 8 | 9 | - 对大脑进行仿真 10 | 11 | - 对进化进行模拟 12 | 13 | - 系统性的减少不确定性 14 | 15 | - 注意新旧知识之间的相似点 16 | 17 | 对应以上这几种知识获取的途径,我们可以认为常见的人工智能的方向有: 18 | 19 | | 派别 | 起源 | 擅长算法 | 20 | 21 | | -------------------- | ------ | ----------------------------- | 22 | 23 | | 符号主义(Symbolists) | 逻辑学、哲学 | 逆演绎算法(Inverse deduction) | 24 | 25 | | 联结主义(Connectionists) | 神经科学 | 反向传播算法(Backpropagation) | 26 | 27 | | 进化主义(Evolutionaries) | 进化生物学 | 基因编程(Genetic programming) | 28 | 29 | | 贝叶斯派(Bayesians) | 统计学 | 概率推理(Probabilistic inference) | 30 | 31 | | Analogizer | 心理学 | 核机器(Kernel machines) | 32 | 33 | # 二十世纪五十年代:推理期 34 | 35 | 二十世纪五十年代到七十年代初,人工智能研究处于”推理期“,彼时人们以为只要能赋予机器逻辑推理的能力,机器就能具有智能。这一阶段的代表性作品有 A. Newell 和 H. Simon 的“逻辑理论家”程序,该程序于 1952 年证明了罗素和怀特海的名著《数学原理》中的 38 条定理,在 1963 年证明了全部的 52 条定理。不过随着时间的发展,人们渐渐发现仅具有逻辑推理能力是远远实现不了人工智能的。 36 | 37 | # 二十世纪七十年代中期:知识期 38 | 39 | 从二十世纪七十年代中期开始,人工智能研究进入了“知识期”,在这一时期,大量的专家系统问世,在很多应用领域取得了大量成果。在本阶段诞生的技术的一个鲜明的代表就是模式识别,它强调的是如何让一个计算机程序去做一些看起来很“智能”的事情,例如识别“3”这个数字。而且在融入了很多的智慧和直觉后,人们也的确构建了这样的一个程序。从这个时代诞生的模式识别领域最著名的书之一是由 Duda & Hart 执笔的“模式识别(Pattern Classification)”。对基础的研究者来说,仍然是一本不错的入门教材。不过对于里面的一些词汇就不要太纠结了,因为这本书已经有一定的年代了,词汇会有点过时。自定义规则、自定义决策,以及自定义“智能”程序在这个任务上,曾经都风靡一时。有趣的是笔者在下文中也会介绍如何用深度学习网络去识别手写的数字,有兴趣的朋友可以去探究下使用模式识别与深度学习相比,同样是识别手写数字上的差异。 40 | 41 | 不过,专家系统面临“知识工程瓶颈”,即由人来把知识总结出来再教给计算机是相当困难的,于是人们开始考虑如果机器能够自己学习知识,该是一件多么美妙的事。 42 | 43 | # 二十世纪八十年代:从样例中学习 44 | 45 | R.S.Michalski 等人将机器学习分为了“从样例中学习”、“在问题求解和规划中学习”、“通过观察和发现学习”、“从指令中学习”等类别;E.A.Feigenbaum 等人在著作《人工智能手册》中,则把机器学习划分为了“机械学习”、“示教学习”、“类比学习”和“归纳学习”。机械学习又被称为死记硬背式学习,即把外界输入的信息全部记录下来,在需要时原封不动地取出来使用,这实际上没有进行真正的学习,仅仅是在进行信息存储和检索;示教学习和类比学习类似于 R.S.Michalski 等人所说的从指令中学习和通过观察和发现学习。归纳学习则相当于从样例中学习,即从训练样本中归纳出学习结果。二十世纪八十年代以来,被研究最多、应用最广的是“从样例中学习”,也就是广泛的归纳学习,它涵盖了监督学习、无监督学习等。 46 | 47 | ## 符号主义学习 48 | 49 | 在二十世纪八十年代,从样例中学习的一大主流就是符号主义学习,其代表包括决策树和基于逻辑的学习。符号学习一个直观的流程可以参考下图: 50 | 51 | 典型的决策树学习以信息论为基础,以信息熵的最小化为目标,直接模拟了人类对概念进行判定的树形流程。基于逻辑的学习的著名代表是归纳逻辑程序设计 Inductive Logic Programming,简称 ILP,可以看做机器学习与逻辑程序设计的交叉。它使用一阶逻辑,即谓词逻辑来进行知识表示,通过修改和扩充逻辑表达式来完成对于数据的归纳。符号主义学习占据主流地位与前几十年人工智能经历的推理期和知识期密切相关,最后,可以来认识几位符号主义的代表人物: 52 | 53 | ## 连接主义学习 54 | 55 | 二十世纪九十年代中期之前,从样例中学习的另一主流技术是基于神经网络的连接主义学习。下图就是典型的神经元、神经网络与著名的 BP 算法的示例。 56 | 57 | 与符号主义学习能产生明确的概念表示不同,连接主义学习产生的是黑箱模型,因此从知识获取的角度来看,连接主义学习技术有明显弱点。然而,BP 一直是被应用的最广泛的机器学习算法之一,在很多现实问题上发挥作用。连接主义学习的最大局限是其试错性。简单来说,其学习过程设计大量的参数,而参数的设置缺乏理论指导,主要靠手工调参;夸张一点来说,参数调节上失之毫厘,学习结果可能谬以千里。 58 | 59 | # 二十世纪九十年代中期:统计学习 60 | 61 | 二十世纪九十年代中期,统计学习闪亮登场并且迅速占据主流舞台,代表性技术是支持向量机(Support Vector Machine)以及更一般的核方法(Kernel Methods)。正是由于连接主义学习技术的局限性凸显,人们才把目光转向以统计学习理论为直接支撑的统计学习技术。 62 | 63 | # 二十一世纪:深度学习 64 | 65 | 深度学习掀起的热潮也许大过它本身真正的贡献,在理论和技术上并没有太多的创新,只不过是由于硬件技术的革命,计算机的速度大大提高了,使得人们有可能采用原来复杂度很高的算法,从而得到比过去更精细的结果。 66 | 67 | 二十一世纪初,连接主义学习又卷土重来,掀起了以深度学习为名的热潮。所谓深度学习,狭义的说就是“很多层”的神经网络。在若干测试和竞赛上,尤其是涉及语音、图像等复杂对象的应用中,深度学习技术取得了优越性能。之前的机器学习技术在应用中要取得好的性能,对于使用者的要求较高。而深度学习技术涉及的模型复杂度非常高,以至于只要下功夫“调参”,把参数调节好,性能往往就好。深度学习虽然缺乏严格的理论基础,但是显著降低了机器学习应用者的门槛,为机器学习走向工程实践带来了便利。深度学习火热的原因有: 68 | 69 | - 数据大了,计算能力抢了,深度学习模型拥有大量参数,若数据样本少,则很容易过拟合。 70 | 71 | - 由于人类进入了大数据时代,数据储量与计算设备都有了大发展,才使得连接主义学习技术焕发了又一春。 72 | -------------------------------------------------------------------------------- /00~导论/机器学习算法.md: -------------------------------------------------------------------------------- 1 | # 机器学习算法 2 | 3 | 算法基本上从功能或者形式上来分类。比如,基于树的算法,神经网络算法。这是一个很有用的分类方式,但并不完美。因为有许多算法可以轻易地被分到两类中去,比如说 Learning Vector Quantization 就同时是神经网络类的算法和基于实例的方法。正如机器学习算法本身没有完美的模型一样,算法的分类方法也没有完美的。 4 | 5 | # 变量关系 6 | 7 | # 学习风格 8 | 9 | # 算法相似度 10 | 11 | # 常用算法 12 | 13 | 本小节我们对机器学习中常见的算法及其特征与使用场景进行简单梳理。 14 | 15 | ## 贝叶斯算法 16 | 17 | 贝叶斯算法是给予贝叶斯定理与特征条件独立假设的监督型分类方法,典型的算法有朴素贝叶斯、高斯朴素贝叶斯、多种名义朴素贝叶斯、平均单依赖估计、BBN、BN 等。该算法要求各特征间相互独立,对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。其典型的运用场景包括了: 18 | 19 | - 文本分类 20 | - 疾病预测 21 | - 检测 SNS 社区中不真实账号 22 | - 垃圾邮件过滤 23 | 24 | ## 线性回归与逻辑回归 25 | 26 | 线性回归的目的在于找出某一变量与其他多个变量之间的定量关系,并且是线性关系;逻辑回归则是将数据拟合到一个 logit 函数(或者叫做 logistic 函数)中,从而能够完成对事件发生的概率进行预测。线性回归模型太简单,如果数据呈线性关系可采用;逻辑回归相对来说模型更简单,好理解,实现起来,特别是大规模线性分类时比较方便。同样的线性分类情况下,如果异常点较多的话,无法剔除,首先 LR,LR 中每个样本都是有贡献的,最大似然后会自动压制异常的贡献。 27 | 28 | ## 决策树 29 | 30 | 决策树是利用训练数据集来构造决策树,用构造好的决策树对将来的新数据进行分类的监督型算法,典型的算法有 ID3、ID4、ID5、C4.0、C4.5、C5.0、CART 等,其常用于二元或者多元分类。该算法要求变量只能数值型、名称型,其核心概念中涉及信息熵、信息增益,在构造决策树时,实际上是选择信息增益 Max 的属性作为决策节点;算法 C4.5 引入来信息增益率的概念。决策树常用于以下场景: 31 | 32 | - 金融行业用决策树做贷款风险评估 33 | - 保险行业用决策树做推广预测 34 | - 医疗行业用决策树生成辅助诊断处置模型 35 | - 用户分级评估 36 | - 分析对某种响应可能性影响最大的因素,比如判断具有什么特征的客户流失概率更高 37 | - 为其他模型筛选变量。决策数找到的变量是对目标变量影响很大的变量。所以可以作为筛选变量的手段。 38 | 39 | # SVM 支持向量机 40 | 41 | SVM 同样是监督型分类算法,基本想法就是求解能正确划分训练样本并且其几何间隔最大化的超平面。线性支持向量机既可以解决线性可分问题,又可以解决线性不可分问题。其构建过程如下:获取训练输入,将其映射至多维空间,使用回归算法找到可最佳分离两类输入数据的超平面(超平面是一个在 n 维空间中将空间划分为两个半空间的一个平面)。一旦支持向量机完成了受训,它就可以评估有关划分超平面的新输入数据,并将划分为其中一类,在 SVM 分类决策中起决定作用的是支持向量。 42 | 43 | SVM 常用于模式识别领域中的文本识别,中文分类,人脸识别等;工程技术和信息过滤。 44 | 45 | ## KNN(K 近邻算法) 46 | 47 | KNN 是监督型分类算法,通过测量不同特征值之间的距离进行分类。它的的思路是:如果一个样本在特征空间中的 K 个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。K 通常是不大于 20 的整数。KNN 算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 48 | 49 | KNN 要求事先要有正确样本,算法比较简单,完全依赖于数据,没有数学模型,所以应用在很简单的模型。其易于理解,易于实现,无需估计参数,无需训练;适合对稀有事件进行分类,特别适合于多分类问题(multi-modal,对象具有多个类别标签),KNN 比 SVM 的表现要好。不过当样本不平衡时,抗造能力差,并且计算量大。 50 | 51 | KNN 的典型应用场景譬如约会网站的数据分类,或者手写数字识别。 52 | 53 | ## 聚类算法 54 | 55 | 聚类将数据集中的样本划分为若干个不相交的子集,每个子集可能对应一个潜在的类别,这些类别对聚类算法是未知的。其典型算法有 K-means,LVQ,高斯混合聚类,密度聚类,层次聚类等。聚类算法不需要训练集。 56 | 57 | ## 随机森林 58 | 59 | 随机森林是监督型分类算法,顾名思义,是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,看看这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为那一类。 60 | 61 | 随机森林主要包含了采样(有放回的采样)与完全分裂(叶子节点要么无法再分裂,要么要么里面的所有样本的都是指向的同一个分类)等步骤。随机森林对多元公线性不敏感,结果对缺失数据和非平衡的数据比较稳健,可以很好地预测多达几千个解释变量的作用;在数据集上表现良好,两个随机性的引入,使得随机森林不容易陷入过拟合。 62 | 63 | 在当前的很多数据集上,相对其他算法有着很大的优势,两个随机性的引入,使得随机森林具有很好的抗噪声能力。它能够处理很高维度(feature 很多)的数据,并且不用做特征选择,对数据集的适应能力强:既能处理离散型数据,也能处理连续型数据,数据集无需规范化。可生成一个 Proximities=(pij)矩阵,用于度量样本之间的相似性:pij=aij/N, aij 表示样本 i 和 j 出现在随机森林中同一个叶子结点的次数,N 随机森林中树的颗数。 64 | 65 | 在创建随机森林的时候,对 generlization error 使用的是无偏估计,训练速度快,可以得到变量重要性排序(两种:基于 OOB 误分率的增加量和基于分裂时的 GINI 下降量,在训练过程中,能够检测到 feature 间的互相影响,容易做成并行化方法,实现比较简单。 66 | 67 | ## Adaboost 68 | 69 | Adaboost 是监督型聚合式分类算法,和随机森林有点像,区别在于随机森林是并行,Adaboost 是串行,上一个分类器的结果放入下一个分类器。Adaboost 最后的分类器 YM 是由数个弱分类器(weak classifier)组合而成的,相当于最后 m 个弱分类器来投票决定分类,而且每个弱分类器的话语权 α 不一样。 70 | 71 | Adaboost 常用于二分类或多分类的应用场景,用于做分类任务的 baseline 无脑化,简单,不会 overfitting,不用调分类器。还可以用于特征选择(feature selection)。并且 Boosting 框架用于对 badcase 的修正,只需要增加新的分类器,不需要变动原有分类器。 72 | 73 | ## 神经网络 74 | 75 | 人工神经网络算法模拟生物神经网络,是一类模式匹配算法。一般分为输入层、隐藏层、输出层,隐藏层的层数根据算法需要来定,层数越多,模型越复杂,计算能力要求越高。对于输入层和隐藏层,每一个神经元代表输入,经过一系列计算得到输出,将输出作为下一层神经元的输入,以此类推,直到传递到输出层。 76 | 77 | 神经网络可以充分逼近任意复杂的非线性关系;所有定量或定性的信息都等势分布贮存于网络内的各神经元,故有很强的鲁棒性和容错性;采用并行分布处理方法,使得快速进行大量运算成为可能;可学习和自适应不知道或不确定的系统。 78 | -------------------------------------------------------------------------------- /模型评估/误差与验证.md: -------------------------------------------------------------------------------- 1 | # 误差与验证 2 | 3 | # 模型误差 4 | 5 | # Cross-Validation: 交叉验证 6 | 7 | ![](https://pic1.zhimg.com/v2-577bb114a1073273452cc1c73045e274_b.png) 8 | 9 | 右边是十种不同的训练集和测试集划分方法得到的 test MSE,可以看到,在不同的划分方法下,test MSE 的变动是很大的,而且对应的最优 degree 也不一样。所以如果我们的训练集和测试集的划分方法不够好,很有可能无法选择到最好的模型与参数。 10 | 11 | ## LOOCV 12 | 13 | LOOCV(Leave-one-out cross-validation) 像 Test set approach 一样,LOOCV 方法也包含将数据集分为训练集和测试集这一步骤。但是不同的是,我们现在只用一个数据作为测试集,其他的数据都作为训练集,并将此步骤重复 N 次(N 为数据集的数据数量)。 14 | 15 | ![img](https://pic1.zhimg.com/v2-27f8c5989dd7790ccf6b626e6854e06c_b.png)如上图所示,假设我们现在有 n 个数据组成的数据集,那么 LOOCV 的方法就是每次取出一个数据作为测试集的唯一元素,而其他 n-1 个数据都作为训练集用于训练模型和调参。结果就是我们最终训练了 n 个模型,每次都能得到一个 MSE。而计算最终 test MSE 则就是将这 n 个 MSE 取平均。 16 | 17 | ![img](https://pic1.zhimg.com/v2-c6a79e230f946da8aefd793ed57c0454_b.png)![y_i](https://zhihu.com/equation?tex=y_i)比起 test set approach,LOOCV 有很多优点。首先它不受测试集合训练集划分方法的影响,因为每一个数据都单独的做过测试集。同时,其用了 n-1 个数据训练模型,也几乎用到了所有的数据,保证了模型的 bias 更小。不过 LOOCV 的缺点也很明显,那就是计算量过于大,是 test set approach 耗时的 n-1 倍。 18 | 19 | 为了解决计算成本太大的弊端,又有人提供了下面的式子,使得 LOOCV 计算成本和只训练一个模型一样快。 20 | 21 | ![img](https://pic2.zhimg.com/v2-ec72b82d605902ddfa060c2fb5777a05_b.png)其中![\hat{y_i}](https://zhihu.com/equation?tex=%5Chat%7By_i%7D)表示第 i 个拟合值,而![h_i](https://zhihu.com/equation?tex=h_i)则表示 leverage。关于![h_i](https://zhihu.com/equation?tex=h_i)的计算方法详见线性回归的部分(以后会涉及)。 22 | 23 | ## K-fold Cross Validation 24 | 25 | 另外一种折中的办法叫做 K 折交叉验证,和 LOOCV 的不同在于,我们每次的测试集将不再只包含一个数据,而是多个,具体数目将根据 K 的选取决定。比如,如果 K=5,那么我们利用五折交叉验证的步骤就是: 26 | 27 | 1. 将所有数据集分成 5 份 28 | 29 | 2. 不重复地每次取其中一份做测试集,用其他四份做训练集训练模型,之后计算该模型在测试集上的![MSE_i](https://zhihu.com/equation?tex=MSE_i) 30 | 31 | 3. 将 5 次的![MSE_i](https://zhihu.com/equation?tex=MSE_i)取平均得到最后的 MSE 32 | 33 | ![img](https://pic4.zhimg.com/v2-fcb843dd06c15a515d03a543864bbb77_b.png)不难理解,其实 LOOCV 是一种特殊的 K-fold Cross Validation(K=N )。再来看一组图: 34 | 35 | ![img](https://pic2.zhimg.com/v2-daf077823e7faa57c6f4014389fe12b9_b.png)每一幅图种蓝色表示的真实的 test MSE,而黑色虚线和橙线则分贝表示的是 LOOCV 方法和 10-fold CV 方法得到的 test MSE。我们可以看到事实上 LOOCV 和 10-fold CV 对 test MSE 的估计是很相似的,但是相比 LOOCV,10-fold CV 的计算成本却小了很多,耗时更少。 36 | 37 | 最后,我们要说说 K 的选取。事实上,和开头给出的文章里的部分内容一样,K 的选取是一个 Bias 和 Variance 的 trade-off。 38 | 39 | K 越大,每次投入的训练集的数据越多,模型的 Bias 越小。但是 K 越大,又意味着每一次选取的训练集之前的相关性越大(考虑最极端的例子,当 k=N,也就是在 LOOCV 里,每次都训练数据几乎是一样的)。而这种大相关性会导致最终的 test error 具有更大的 Variance。 40 | 41 | 一般来说,根据经验我们一般选择 k=5 或 10。 42 | 43 | # 混淆矩阵 44 | 45 | [机器学习笔记 - 模型评估与模型选择](http://blog.rainy.im/2016/03/28/ml-model-selection/) 46 | 47 | 监督学习的主要任务就是用模型实现精准的预测。我们希望自己的机器学习模型在新数据(未被标注过的)上取得尽可能高的准确率。换句话说,也就是我们希望用 训练数据训练得到的模型能适用于待测试的新数据。正是这样,当实际开发中训练得到一个新模型时,我们才有把握用它预测出高质量的结果。现在,假设我们要使用一个简单的非参数回归模型来构建耕地农药使用率和谷物亩产量的模型。最简单的机器学习回归模型之一就是内核平滑技术。内核平滑即计算 局部平均:对于每一个新的数据来说,用与其特征值接近的训练数据点求平均值来对其目标变量建模。唯一一个参数:宽参数,是用来控制局部平均的窗口大小。内核平滑窗宽参数取值不同所产生的效果。窗宽值较大时,几乎是用所有训练数据的平均值来预测测试集里每个数据点的目标值。这导致模型很平坦,对训练数据分布的明显趋势欠拟合(under-fit )了。同样,窗宽值过小时,每次预测只用到了待测数据点周围一两个训练数据。因此,模型把训练数据点的起伏波动完完全全地反映出来。这种疑似拟合噪音数据而非真实信号的现象被称为过拟合(over-fitting )。我们的理想情况是处于一个平衡状态:既不欠拟合,也不过拟合。![](http://mmbiz.qpic.cn/mmbiz/Pn4Sm0RsAughQO34EKthdtP0lj5eE2E7OykekrBrkAW1MoIGF0rJvmM6ibMH2nPMtW7v1hmJ4b4ODO7qIHhjCzA/640?wx_fmt=png&wxfrom=5&wx_lazy=1) 由此可见,我们机器学习模型评估的目标就是希望能够判断分析机器学习模型对预测新数据时候的泛化能力,上述场景中就是指判断分析机器学习模型对预测其它农场的谷物产量的泛化能力。对于回归问题,标准的评估方法是均方误差(MSE ),即目标变量的真实值与模型预测值的误差平方的平均值。 48 | 49 | ## 交叉验证 50 | 51 | 模型评估中一个难解之处在于模型在训练集数据上的误差不能反映其在新数据集上的误差情况。为了更好地估计模型在新数据集上的错误率,我们必须使用更复杂的方法,称作**交叉验证(cross validation )**,它严格地使用训练集数据来评价模型在新数据集上的准确率。 52 | 53 | ### Holdout 方法 54 | 55 | 同一份训练数据既用于数据拟合又用于准确率评估,会导致过度乐观。最容易的规避方法是分别准备训练和测试的两个子数据集,训练子集仅用于拟合模型,测试子集仅用于评估模型的准确率。这个方法被称作是 holdout 方法,因为随机地选择一部分训练数据仅用于训练过程。通常保留 30% 的数据作为测试数据。![](http://mmbiz.qpic.cn/mmbiz/Pn4Sm0RsAughQO34EKthdtP0lj5eE2E7tevaallxmsz753137Tzj1TQBd7FXCSMU2iaoWzyIiaxteSFEGwOw9FLg/640?wx_fmt=png&wxfrom=5&wx_lazy=1) 伪代码如下所示: ![](http://mmbiz.qpic.cn/mmbiz/Pn4Sm0RsAughQO34EKthdtP0lj5eE2E72r5bVUaRKvuVuK7k7tjVMcEfh1ljKy3qSL1ASZfHoDUXMVZOcSZ5Jg/640?wx_fmt=png&wxfrom=5&wx_lazy=1) 56 | 57 | ### K-Fold 交叉验证 58 | 59 | ![](http://mmbiz.qpic.cn/mmbiz/Pn4Sm0RsAughQO34EKthdtP0lj5eE2E7SSicUVS7NN6E7R394TxW3AhstdbVQZmTz3G4Z7icRLs1ichccVPoFqrfg/640?wx_fmt=png&wxfrom=5&wx_lazy=1) 如同 Holdout 方法,K-fold 交叉验证也依赖于训练数据的若干个相互独立子集。主要的区别在于 K-fold 交叉验证一开始就随机把数据分割成 K 个 不相连的子集,成为 folds(一般称作 K 折交叉验证,K 的取值有 5、10 或者 20)。每次留一份数据作为测试集,其余数据用于训练模型。![](http://mmbiz.qpic.cn/mmbiz/Pn4Sm0RsAughQO34EKthdtP0lj5eE2E7YRZpXTQ8FxIYtB4Ydxyx6ib57ODia2hNdn3rjP2ATSRxSSQfbTvkgAwg/640?wx_fmt=png&wxfrom=5&wx_lazy=1) 60 | 61 | ## Evaluation Metric( 评价指标 ) 62 | -------------------------------------------------------------------------------- /特征工程/数据集/图片/猫狗.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "cats_and_dogs.ipynb", 7 | "version": "0.3.2", 8 | "provenance": [], 9 | "collapsed_sections": [], 10 | "include_colab_link": true 11 | }, 12 | "kernelspec": { 13 | "name": "python3", 14 | "display_name": "Python 3" 15 | } 16 | }, 17 | "cells": [ 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "id": "view-in-github", 22 | "colab_type": "text" 23 | }, 24 | "source": [ 25 | "\"Open" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "metadata": { 31 | "id": "FRRkXMLYgc_1", 32 | "colab_type": "code", 33 | "outputId": "8b5930f5-8d40-4249-c5ca-4d904f6d173b", 34 | "colab": { 35 | "base_uri": "https://localhost:8080/", 36 | "height": 88 37 | } 38 | }, 39 | "source": [ 40 | "from google.colab import drive\n", 41 | "drive.mount(\"/content/drive\")\n", 42 | "\n", 43 | "print('Files in Drive:')\n", 44 | "!ls /content/drive/'My Drive'" 45 | ], 46 | "execution_count": 0, 47 | "outputs": [ 48 | { 49 | "output_type": "stream", 50 | "text": [ 51 | "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n", 52 | "Files in Drive:\n", 53 | "'Colab Notebooks' Data Web\n" 54 | ], 55 | "name": "stdout" 56 | } 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "metadata": { 62 | "id": "t_fh0McPgEPU", 63 | "colab_type": "code", 64 | "outputId": "2112f26a-dcd3-43f1-c625-01467326b843", 65 | "colab": { 66 | "base_uri": "https://localhost:8080/", 67 | "height": 303 68 | } 69 | }, 70 | "source": [ 71 | "# we will download the cats and dogs dataset and unzip them\n", 72 | "# after this run, set your data_dir variable: data_dir = 'Cat_Dog_data'\n", 73 | "# so all the data is available. so path to your training data becomes `Cat_Dog_data/train`\n", 74 | "# path to test is `Cat_Dog_data/test`\n", 75 | "\n", 76 | "%env DIR=/content/drive/My Drive/Data/animals\n", 77 | "\n", 78 | "!rm -rf \"$DIR\"\n", 79 | "!mkdir -pv \"$DIR\"\n", 80 | "!wget -O \"$DIR\"/cats_and_dogs.zip https://s3.amazonaws.com/content.udacity-data.com/nd089/Cat_Dog_data.zip\n", 81 | "\n", 82 | "# remove existing directories\n", 83 | "!(cd \"$DIR\" && unzip -qqj cats_and_dogs.zip -d .)\n" 84 | ], 85 | "execution_count": 0, 86 | "outputs": [ 87 | { 88 | "output_type": "stream", 89 | "text": [ 90 | "env: DIR=/content/drive/My Drive/Data/animals\n", 91 | "^C\n", 92 | "--2019-06-15 14:55:45-- https://s3.amazonaws.com/content.udacity-data.com/nd089/Cat_Dog_data.zip\n", 93 | "Resolving s3.amazonaws.com (s3.amazonaws.com)... 52.216.101.61\n", 94 | "Connecting to s3.amazonaws.com (s3.amazonaws.com)|52.216.101.61|:443... connected.\n", 95 | "HTTP request sent, awaiting response... 200 OK\n", 96 | "Length: 580495262 (554M) [application/zip]\n", 97 | "Saving to: ‘/content/drive/My Drive/Data/animals/cats_and_dogs.zip’\n", 98 | "\n", 99 | "/content/drive/My D 100%[===================>] 553.60M 41.2MB/s in 15s \n", 100 | "\n", 101 | "2019-06-15 14:56:01 (35.9 MB/s) - ‘/content/drive/My Drive/Data/animals/cats_and_dogs.zip’ saved [580495262/580495262]\n", 102 | "\n", 103 | "replace ./.DS_Store? [y]es, [n]o, [A]ll, [N]one, [r]ename: N\n", 104 | "n\n", 105 | "n\n", 106 | "n\n" 107 | ], 108 | "name": "stdout" 109 | } 110 | ] 111 | } 112 | ] 113 | } -------------------------------------------------------------------------------- /模型评估/范式.md: -------------------------------------------------------------------------------- 1 | # 范式与正则化 2 | 3 | 正则化是为了防止过拟合 4 | 5 | 交叉验证是为了选择 hyperparameter 6 | 7 | # Model Evaluation 8 | 9 | # Overfitting 10 | 11 | ![](https://pic2.zhimg.com/c3fca0a39141f16ae0700b10f44e4909_b.jpg) 12 | 13 | (1)对于机器来说,在使用学习算法学习数据的特征的时候,样本数据的特征可以分为局部特征和全局特征,全局特征就是任何你想学习的那个概念所对应的数据都具备的特征,而局部特征则是你用来训练机器的样本里头的数据专有的特征. 14 | (2)在学习算法的作用下,机器在学习过程中是无法区别局部特征和全局特征的,于是机器在完成学习后,除了学习到了数据的全局特征,也可能习得一部分局部特征,而习得的局部特征比重越多,那么新样本中不具有这些局部特征但具有所有全局特征的样本也越多,于是机器无法正确识别符合概念定义的“正确”样本的几率也会上升,也就是所谓的“泛化性”变差,这是过拟合会造成的最大问题. 15 | (3)所谓过拟合,就是指把学习进行的太彻底,把样本数据的所有特征几乎都习得了,于是机器学到了过多的局部特征,过多的由于噪声带来的假特征,造成模型的“泛化性”和识别正确率几乎达到谷点,于是你用你的机器识别新的样本的时候会发现就没几个是正确识别的. 16 | (4)解决过拟合的方法,其基本原理就是限制机器的学习,使机器学习特征时学得不那么彻底,因此这样就可以降低机器学到局部特征和错误特征的几率,使得识别正确率得到优化. 17 | (5)从上面的分析可以看出,要防止过拟合,训练数据的选取也是很关键的,良好的训练数据本身的局部特征应尽可能少,噪声也尽可能小. 18 | 19 | (1)打个形象的比方,给一群天鹅让机器来学习天鹅的特征,经过训练后,知道了天鹅是有翅膀的,天鹅的嘴巴是长长的弯曲的,天鹅的脖子是长长的有点曲度,天鹅的整个体型像一个“2”且略大于鸭子.这时候你的机器已经基本能区别天鹅和其他动物了。 20 | (2)然后,很不巧你的天鹅全是白色的,于是机器经过学习后,会认为天鹅的羽毛都是白的,以后看到羽毛是黑的天鹅就会认为那不是天鹅. 21 | (3)好,来分析一下上面这个例子:(1)中的规律都是对的,所有的天鹅都有的特征,是全局特征;然而,(2)中的规律:天鹅的羽毛是白的.这实际上并不是所有天鹅都有的特征,只是局部样本的特征。机器在学习全局特征的同时,又学习了局部特征,这才导致了不能识别黑天鹅的情况. 22 | ![](https://pic2.zhimg.com/afa034d52962681db09b4dc1060f8075_b.png) 23 | 24 | ## Early stopping 25 | 26 | 对模型进行训练的过程即是对模型的参数进行学习更新的过程,这个参数学习的过程往往会用到一些迭代方法,如梯度下降(Gradient descent)学习算法。Early stopping 便是一种迭代次数截断的方法来防止过拟合的方法,即在模型对训练数据集迭代收敛之前停止迭代来防止过拟合。 27 |   Early stopping 方法的具体做法是,在每一个 Epoch 结束时(一个 Epoch 集为对所有的训练数据的一轮遍历)计算 validation data 的 accuracy,当 accuracy 不再提高时,就停止训练。这种做法很符合直观感受,因为 accurary 都不再提高了,在继续训练也是无 益的,只会提高训练的时间。那么该做法的一个重点便是怎样才认为 validation accurary 不再提高了呢?并不是说 validation accuracy 一降下来便认为不再提高了,因为可能经过这个 Epoch 后,accuracy 降低了,但是随后的 Epoch 又让 accuracy 又上去 了,所以不能根据一两次的连续降低就判断不再提高。一般的做法是,在训练的过程中,记录到目前为止最好的 validation accuracy,当连续 10 次 Epoch(或者更多次)没达到最佳 accuracy 时,则可以认为 accuracy 不再提高了。此时便可以停止迭代了 (Early Stopping)。这种策略也称为“No-improvement-in-n”,n 即 Epoch 的次数,可以根据实际情况取,如 10、20、30…… 28 | 29 | ## 数据集扩增 30 | 31 | 在数据挖掘领域流行着这样的一句话,“有时候往往拥有更多的数据胜过一个好的模型”。因为我们在使用训练数据训练模型,通过这个模型对将来的数据进 行拟合,而在这之间又一个假设便是,训练数据与将来的数据是独立同分布的。即使用当前的训练数据来对将来的数据进行估计与模拟,而更多的数据往往估计与模 拟地更准确。因此,更多的数据有时候更优秀。但是往往条件有限,如人力物力财力的不足,而不能收集到更多的数据,如在进行分类的任务中,需要对数据进行打 标,并且很多情况下都是人工得进行打标,因此一旦需要打标的数据量过多,就会导致效率低下以及可能出错的情况。所以,往往在这时候,需要采取一些计算的方 式与策略在已有的数据集上进行手脚,以得到更多的数据。 32 |    通俗得讲,数据机扩增即需要得到更多的符合要求的数据,即和已有的数据是独立同分布的,或者近似独立同分布的。一般有以下方法: 33 | 34 | - 从数据源头采集更多数据 35 | - 复制原有数据并加上随机噪声 36 | - 重采样 37 | - 根据当前数据集估计数据分布参数,使用该分布产生更多数据等 38 | 39 | ## Cross Validation:交叉验证 40 | 41 | # Norm:范式 42 | 43 | - [l0-norm-l1-norm-l2-norm-l-infinity-norm](https://rorasa.wordpress.com/2012/05/13/l0-norm-l1-norm-l2-norm-l-infinity-norm/) 44 | - [differences-between-the-l1-norm-and-the-l2-norm-least-absolute-deviations-and-least-squares](http://www.chioka.in/differences-between-the-l1-norm-and-the-l2-norm-least-absolute-deviations-and-least-squares/) 45 | 46 | 一般在机器学习的实践中,我们常用的范式就是 L1 范式 47 | 48 | ## Types:范式类型 49 | 50 | ### L0 Norm 51 | 52 | ### L1 Norm 53 | 54 | ### L2 Norm 55 | 56 | ### L-Infinity Norm 57 | 58 | ## Loss/Error Function:损失函数 59 | 60 | L1 范式与 L2 范式常用的场景就是作为损失函数或者代价函数,而使用 L1 范式的损失函数一般称为 LAD(Least Absolute Deviations),即最小绝对值偏差或者 LAE(Least Absolute Errors),即最小绝对值错误。LAD 的目标即是使得目标值$Y_i$与测量值$f(x_i)$之间的绝对值差和最小。 61 | 62 | $$ 63 | S = \sum_{i=1}^{n}|y_i - f(x_i)| 64 | $$ 65 | 66 | 使用 L2 范式的损失函数一般又被称为 LSE(Least Squares Error),即最小平方误差: 67 | 68 | $$ 69 | S = \sum^n_{i=1}(y_i - f(x_i))^2 70 | $$ 71 | 72 | 而 LAE 与 LSE 的区别可以总结为: 73 | | L2 loss function | L1 loss function | 74 | | ------------------- | --------------------------- | 75 | | Not very robust | Robust | 76 | | Stable solution | Unstable solution | 77 | | Always one solution | Possibly multiple solutions | 78 | 79 | - Solution uniqueness:是否唯一解 80 | ![](http://7xiegq.com1.z0.glb.clouddn.com/L1-norm-and-L2-norm-distance.png) 81 | 上图中的绿色的线,即 L2 范式即是唯一的最短路径的解,而红色的、蓝色的以及黄色的线,即 L1 范式则是相同长度的解。将这个情况扩展到 N 维,即可以认为 L2 范式是有唯一解而 L1 范式则可以有多解。 82 | - Robustness:鲁棒性,即异常值的影响能力 83 | 直观来说,因为 LSE 使用了 L2 范式,即将误差值平方求和,这就导致了模型会比 LAE 存在更大的误差,因此模型与 LAE 相比会更加地敏感于单个数据点。如果该数据点是个异常值,那么模型会为了更好地拟合这个异常值的情形而导致对于其他值的偏差增大。一般来说,正常的数据点造成的误差值都比较小,而异常数据点造成的误差值会比较大,在 LSE 中异常数据点对于拟合结果的影响会大于 LAE。 84 | 85 | - Stable:稳定性,即异常值发生变化时候的影响 86 | 在 LAD 中,如果某个数据点发生了一点水平位移,都可能导致最后的拟合线发生较大的变化。而 LSE 与之相比则有较大的稳定性,对于数据点任何较小地变化,拟合线也只会变化一点点,即拟合地参数可以看做关于数据的一个持续函数的值。 87 | 88 | 下图就是一个使用真实的数据与真实的拟合模型构造的结果图: 89 | ![](http://7xiegq.com1.z0.glb.clouddn.com/programmatic-L1-vs-L2-visualization.png) 90 | 91 | 关于上图需要注意两点: 92 | (1)在同一张图中,计入异常点与不计入异常点相比,LAE 的两条拟合线差异较大,而 LSE 则差异较小。 93 | (2)在将异常点从左到右进行移动地过程中,LAE 与 LSE 相比会发生更多的变化。 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Contributors][contributors-shield]][contributors-url] 2 | [![Forks][forks-shield]][forks-url] 3 | [![Stargazers][stars-shield]][stars-url] 4 | [![Issues][issues-shield]][issues-url] 5 | [![license: CC BY-NC-SA 4.0](https://img.shields.io/badge/license-CC%20BY--NC--SA%204.0-lightgrey.svg)][license-url] 6 | 7 | 8 |
9 |

10 | 11 | Logo 12 | 13 | 14 |

15 | 在线阅读 >> 16 |
17 |
18 | 代码案例 19 | · 20 | 参考资料 21 | 22 |

23 |

24 | 25 | 26 | 27 | # Machine Learning Series 28 | 29 | 互联网的迅猛发展催生了数据的爆炸式增长。面对海量数据,如何挖掘数据的架子,成为一个越来越重要的问题。首先,对于数据挖掘的概念,目前比较广泛认可的一种解释如下:数据挖掘是一种通过分析海量数据,从数据中提取潜在的但是非常有用的模式的技术。 30 | 31 | 数据挖掘的任务可以分为预测性任务和描述性任务,预测性任务主要是预测可能出现的情况;描述性任务则是发现一些人类可以解释的模式或者规律。数据挖掘中比较常见的任务包括分类、聚类、关联规则挖掘、时间序列挖掘、回归等,其中分类、回归属于预测性任务,聚类、关联规则挖掘、时间序列分析等则都是解释性任务。 32 | 33 | 机器学习即是指能够帮你从数据中寻找到感兴趣的部分而不需要编写特定的问题解决方案的通用算法的集合。通用的算法可以根据你不同的输入数据来自动地构建面向数据集合最优的处理逻辑。举例而言,算法中一个大的分类即分类算法,它可以将数据分类到不同的组合中。而可以用来识别手写数字的算法自然也能用来识别垃圾邮件,只不过对于数据特征的提取方法不同。相同的算法输入不同的数据就能够用来处理不同的分类逻辑。 34 | 35 | 换一个形象点的阐述方式,对于某给定的任务 T,在合理的性能度量方案 P 的前提下,某计算机程序可以自主学习任务 T 的经验 E;随着提供合适、优质、大量的经验 E,该程序对于任务 T 的性能逐步提高。即随着任务的不断执行,经验的累积会带来计算机性能的提升。 36 | 37 | ![mindmap](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230416205150.png) 38 | 39 | ## 什么是机器学习? 40 | 41 | ![机器学习的行业应用](https://s2.ax1x.com/2019/10/26/KBZu3d.png) 42 | 43 | Andrew Ng 对机器学习的定义是:Machine Learning is the science of getting computers to act without being explicitly programmed. 微软的定义是:Machine learning is a technique of data science that helps computers learn from existing data in order to 44 | forecast future behaviors, outcomes, and trends. 45 | 46 | ![机器学习与传统应用的区别](https://s2.ax1x.com/2019/10/26/KBuEMd.png) 47 | 48 | ![机器学习的工作流程](https://s2.ax1x.com/2019/10/26/KBnCcj.png) 49 | 50 | ![常用的机器学习分类与回归算法](https://s2.ax1x.com/2019/10/26/KBMFud.png) 51 | 52 | # Nav | 关联导航 53 | 54 | # About | 关于 55 | 56 | 57 | 58 | ## Contributing 59 | 60 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. 61 | 62 | 1. Fork the Project 63 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 64 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 65 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 66 | 5. Open a Pull Request 67 | 68 | 69 | 70 | ## Acknowledgements 71 | 72 | - [Awesome-Lists](https://github.com/wx-chevalier/Awesome-Lists): 📚 Guide to Galaxy, curated, worthy and up-to-date links/reading list for ITCS-Coding/Algorithm/SoftwareArchitecture/AI. 💫 ITCS-编程/算法/软件架构/人工智能等领域的文章/书籍/资料/项目链接精选。 73 | 74 | - [Awesome-CS-Books](https://github.com/wx-chevalier/Awesome-CS-Books): :books: Awesome CS Books/Series(.pdf by git lfs) Warehouse for Geeks, ProgrammingLanguage, SoftwareEngineering, Web, AI, ServerSideApplication, Infrastructure, FE etc. :dizzy: 优秀计算机科学与技术领域相关的书籍归档。 75 | 76 | ## Copyright & More | 延伸阅读 77 | 78 | 笔者所有文章遵循[知识共享 署名 - 非商业性使用 - 禁止演绎 4.0 国际许可协议](https://creativecommons.org/licenses/by-nc-nd/4.0/deed.zh),欢迎转载,尊重版权。您还可以前往 [NGTE Books](https://ng-tech.icu/books-gallery/) 主页浏览包含知识体系、编程语言、软件工程、模式与架构、Web 与大前端、服务端开发实践与工程架构、分布式基础架构、人工智能与深度学习、产品运营与创业等多类目的书籍列表: 79 | 80 | [![NGTE Books](https://s2.ax1x.com/2020/01/18/19uXtI.png)](https://ng-tech.icu/books-gallery/) 81 | 82 | 83 | 84 | 85 | [contributors-shield]: https://img.shields.io/github/contributors/wx-chevalier/MachineLearning-Notes.svg?style=flat-square 86 | [contributors-url]: https://github.com/wx-chevalier/MachineLearning-Notes/graphs/contributors 87 | [forks-shield]: https://img.shields.io/github/forks/wx-chevalier/MachineLearning-Notes.svg?style=flat-square 88 | [forks-url]: https://github.com/wx-chevalier/MachineLearning-Notes/network/members 89 | [stars-shield]: https://img.shields.io/github/stars/wx-chevalier/MachineLearning-Notes.svg?style=flat-square 90 | [stars-url]: https://github.com/wx-chevalier/MachineLearning-Notes/stargazers 91 | [issues-shield]: https://img.shields.io/github/issues/wx-chevalier/MachineLearning-Notes.svg?style=flat-square 92 | [issues-url]: https://github.com/wx-chevalier/MachineLearning-Notes/issues 93 | [license-shield]: https://img.shields.io/github/license/wx-chevalier/MachineLearning-Notes.svg?style=flat-square 94 | [license-url]: https://github.com/wx-chevalier/MachineLearning-Notes/blob/master/LICENSE.txt 95 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | AIDL Series 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 34 | 38 | 40 | 45 | 46 |
47 | 64 | 97 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 142 | 143 | 144 | 145 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /header.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 101 | 366 |
367 |

368 | AI Series by 王下邀月熊 369 |

370 |

371 | 人工智能与深度学习实战 372 |

373 |
374 | 375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 | 391 | 392 |
393 |
394 |
-------------------------------------------------------------------------------- /特征工程/特征降维/README.md: -------------------------------------------------------------------------------- 1 | # 特征降纬 2 | 3 | 维度变换是将现有数据降低到更小的维度,尽量保证数据信息的完整性。楼主将介绍常用的几种有损失的维度变换方法,将大大地提高实践中建模的效率: 4 | 5 | - 主成分分析(PCA)和因子分析(FA):PCA 通过空间映射的方式,将当前维度映射到更低的维度,使得每个变量在新空间的方差最大。FA 则是找到当前特征向量的公因子(维度更小),用公因子的线性组合来描述当前的特征向量。 6 | 7 | - 奇异值分解(SVD):SVD 的降维可解释性较低,且计算量比 PCA 大,一般用在稀疏矩阵上降维,例如图片压缩,推荐系统。 8 | 9 | - 聚类:将某一类具有相似性的特征聚到单个变量,从而大大降低维度。 10 | 11 | - 线性组合:将多个变量做线性回归,根据每个变量的表决系数,赋予变量权重,可将该类变量根据权重组合成一个变量。 12 | 13 | - 流行学习:流行学习中一些复杂的非线性方法,可参考 skearn:LLE Example 14 | 15 | - [维度打击,机器学习中的降维算法:ISOMAP & MDS ](http://blog.csdn.net/dark_scope/article/details/53229427) 16 | 17 | # Dimensionality Reduction(降维) 18 | 19 | ![](http://3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com/wp-content/uploads/2013/11/Dimensional-Reduction-Algorithms.png) 20 | 21 | Like clustering methods, dimensionality reduction seek and exploit the inherent structure in the data, but in this case in an unsupervised manner or order to summarise or describe data using less information. 22 | 23 | This can be useful to visualize dimensional data or to simplify data which can then be used in a supervized learning method. Many of these methods can be adapted for use in classification and regression. 24 | 25 | - Principal Component Analysis (PCA) 26 | - Principal Component Regression (PCR) 27 | - Partial Least Squares Regression (PLSR) 28 | - Sammon Mapping 29 | - Multidimensional Scaling (MDS) 30 | - Projection Pursuit 31 | - Linear Discriminant Analysis (LDA) 32 | - Mixture Discriminant Analysis (MDA) 33 | - Quadratic Discriminant Analysis (QDA) 34 | - Flexible Discriminant Analysis (FDA) 35 | 36 | 降维的必要性: 37 | 38 | 1.多重共线性--预测变量之间相互关联。多重共线性会导致解空间的不稳定,从而可能导致结果的不连贯。2.高维空间本身具有稀疏性。一维正态分布有 68%的值落于正负标准差之间,而在十维空间上只有 0.02%。3.过多的变量会妨碍查找规律的建立。4.仅在变量层面上分析可能会忽略变量之间的潜在联系。例如几个预测变量可能落入仅反映数据某一方面特征的一个组内。 39 | 降维的目的:1.减少预测变量的个数 2.确保这些变量是相互独立的 3.提供一个框架来解释结果 40 | 降维的方法有:主成分分析、因子分析、用户自定义复合等。 41 | 42 | # 数据的向量表示 43 | 44 | 一般情况下,在数据挖掘和机器学习中,数据被表示为向量。例如某个淘宝店 2012 年全年的流量及交易情况可以看成一组记录的集合,其中每一天的数据是一条记录,格式如下: 45 | (日期, 浏览量, 访客数, 下单数, 成交数, 成交金额) 46 | 其中“日期”是一个记录标志而非度量值,而数据挖掘关心的大多是度量值,因此如果我们忽略日期这个字段后,我们得到一组记录,每条记录可以被表示为一个五维向量,其中一条看起来大约是这个样子: 47 | $ 48 | (500,240,25,13,2312.15)^T 49 | $ 50 | 注意这里我用了转置,因为习惯上使用列向量表示一条记录(后面会看到原因),本文后面也会遵循这个准则。不过为了方便有时我会省略转置符号,但我们说到向量默认都是指列向量。 51 | 我们当然可以对这一组五维向量进行分析和挖掘,不过我们知道,很多机器学习算法的复杂度和数据的维数有着密切关系,甚至与维数呈 指数级关联。当然,这里区区五维的数据,也许还无所谓,但是实际机器学习中处理成千上万甚至几十万维的情况也并不罕见,在这种情况下,机器学习的资源消耗 是不可接受的,因此我们必须对数据进行降维。 52 | 降维当然意味着信息的丢失,不过鉴于实际数据本身常常存在的相关性,我们可以想办法在降维的同时将信息的损失尽量降低。 53 | 举个例子,假如某学籍数据有两列 M 和 F,其中 M 列的取值是如何此学生为男性取值 1,为女性取值 0;而 F 列是学生为女性取值 1,男 性取值 0。此时如果我们统计全部学籍数据,会发现对于任何一条记录来说,当 M 为 1 时 F 必定为 0,反之当 M 为 0 时 F 必定为 1。在这种情况下,我们将 M 或 F 去 掉实际上没有任何信息的损失,因为只要保留一列就可以完全还原另一列。 54 | 当然上面是一个极端的情况,在现实中也许不会出现,不过类似的情况还是很常见的。例如上面淘宝店铺的数据,从经验我们可以知道,“浏览量”和“访客数”往往具有较强的相关关系,而“下单数”和“成交数”也具有较强的相关关系。这里我们非正式的使用“相关关系”这个词,可以直观理解 为“当某一天这个店铺的浏览量较高(或较低)时,我们应该很大程度上认为这天的访客数也较高(或较低)”。后面的章节中我们会给出相关性的严格数学定义。 55 | 这种情况表明,如果我们删除浏览量或访客数其中一个指标,我们应该期待并不会丢失太多信息。因此我们可以删除一个,以降低机器学习算法的复杂度。 56 | 上面给出的是降维的朴素思想描述,可以有助于直观理解降维的动机和可行性,但并不具有操作指导意义。例如,我们到底删除哪一列损 失的信息才最小?亦或根本不是单纯删除几列,而是通过某些变换将原始数据变为更少的列但又使得丢失的信息最小?到底如何度量丢失信息的多少?如何根据原始 数据决定具体的降维操作步骤? 57 | 要回答上面的问题,就要对降维问题进行数学化和形式化的讨论。而 PCA 是一种具有严格数学基础并且已被广泛采用的降维方法。下面我不会直接描述 PCA,而是通过逐步分析问题,让我们一起重新“发明”一遍 PCA。 58 | 59 | ## 向量的表示及基变换 60 | 61 | ## 内积与投影 62 | 63 | 两个维数相同的向量的内积被定义为: 64 | 65 | $$ 66 | (a_1,a_2,\cdots,a_n)^{T}\cdot (b_1,b_2,\cdots,b_n)^{T}=a_1b_1+a_2b_2+\cdots+a_nb_n 67 | $$ 68 | 69 | 内积运算将两个向量映射为一个实数。其计算方式非常容易理解,但是其意义并不明显。下面我们分析内积的几何意义。假设 A 和 B 是两个 n 维向量,我们知道 n 维向量可以等价表示为 n 维空间中的一条从原点发射的有向线段,为了简单起见我们假设 A 和 B 均为二维向量,则 A=(x_1,y_1),B=(x_2,y_2)。则在二维平面上 A 和 B 可以用两条发自原点的有向线段表示,见下图: 70 | ![](http://blog.codinglabs.org/uploads/pictures/pca-tutorial/01.png) 71 | 好,现在我们从 A 点向 B 所在直线引一条垂线。我们知道垂线与 B 的交点叫做 A 在 B 上的投影,再设 A 与 B 的夹角是 a,则投影的矢量长度为$|A|cos(a)$,其中$|A|=\sqrt{x_1^2+y_1^2}$是向量 A 的模,也就是 A 线段的标量长度。 72 | 注意这里我们专门区分了矢量长度和标量长度,标量长度总是大于等于 0,值就是线段的长度;而矢量长度可能为负,其绝对值是线段长度,而符号取决于其方向与标准方向相同或相反。 73 | 到这里还是看不出内积和这东西有什么关系,不过如果我们将内积表示为另一种我们熟悉的形式: 74 | $A\cdot B=|A||B|cos(a)$ 75 | x(1,0)T+y(0,1)T 76 | 77 | 现在事情似乎是有点眉目了:A 与 B 的内积等于 A 到 B 的投影长度乘以 B 的模。再进一步,如果我们假设 B 的模为 1,即让|B|=1,那么就变成了: 78 | $A\cdot B=|A|cos(a)$ 79 | 也就是说,设向量 B 的模为 1,则 A 与 B 的内积值等于 A 向 B 所在直线投影的矢量长度!这就是内积的一种几何解释,也是我们得到的第一个重要结论。在后面的推导中,将反复使用这个结论。 80 | 81 | ## 基 82 | 83 | 一个二维向量可以对应二维笛卡尔直角坐标系中从原点出发的一个有向线段。例如下面这个向量: 84 | ![](http://blog.codinglabs.org/uploads/pictures/pca-tutorial/02.png) 85 | 在代数表示方面,我们经常用线段终点的点坐标表示向量,例如上面的向量可以表示为(3,2),这是我们再熟悉不过的向量表示。 86 | 不过我们常常忽略,只有一个(3,2)本身是不能够精确表示一个向量的。我们仔细看一下,这里的 3 实际表示的是向量在 x 轴上的投影值是 3,在 y 轴上的投影值是 2。也就是说我们其实隐式引入了一个定义:以 x 轴和 y 轴上正方向长度 为 1 的向量为标准。那么一个向量(3,2)实际是说在 x 轴投影为 3 而 y 轴的投影为 2。注意投影是一个矢量,所以可以为负。 87 | 更正式的说,向量(x,y)实际上表示线性组合: 88 | $x(1,0)^{T}+y(0,1)^{T}$ 89 | (52,−12) 90 | 91 | 不难证明所有二维向量都可以表示为这样的线性组合。此处(1,0)和(0,1)叫做二维空间中的一组基。 92 | ![](http://blog.codinglabs.org/uploads/pictures/pca-tutorial/03.png) 93 | 所以,要准确描述向量,首先要确定一组基,然后给出在基所在的各个直线上的投影值,就可以了。只不过我们经常省略第一步,而默认以(1,0)和(0,1)为基。 94 | 我们之所以默认选择(1,0)和(0,1)为基,当然是比较方便,因为它们分别是 x 和 y 轴正方向上的单位向量,因此就使得二维平 面上点坐标和向量一一对应,非常方便。但实际上任何两个线性无关的二维向量都可以成为一组基,所谓线性无关在二维平面内可以直观认为是两个不在一条直线上 的向量。 95 | 例如,(1,1)和(-1,1)也可以成为一组基。一般来说,我们希望基的模是 1,因为从内积的意义可以看到,如果基的模是 1,那么就可以方便的用向量点乘基而直接获得其在新基上的坐标了!实际上,对应任何一个向量我们总可以找到其同方向上模为 1 的向量,只要让两个分量分别除以模 就好了。例如,上面的基可以变为$(\frac{1}{\sqrt{2}},\frac{1}{\sqrt{2}}) 96 | $和$(-\frac{1}{\sqrt{2}},\frac{1}{\sqrt{2}}) 97 | $。 98 | 现在,我们想获得(3,2)在新基上的坐标,即在两个方向上的投影矢量值,那么根据内积的几何意义,我们只要分别计算(3,2)和两个基的内积,不难得到新的坐标为$(\frac{5}{\sqrt{2}},-\frac{1}{\sqrt{2}}) 99 | $。下图给出了新的基以及(3,2)在新基上坐标值的示意图: 100 | ![](http://blog.codinglabs.org/uploads/pictures/pca-tutorial/05.png) 101 | 另外这里要注意的是,我们列举的例子中基是正交的(即内积为 0,或直观说相互垂直),但可以成为一组基的唯一要求就是线性无关,非正交的基也是可以的。不过因为正交基有较好的性质,所以一般使用的基都是正交的。 102 | 103 | ## 基变换的矩阵表示 104 | 105 | 下面我们找一种简便的方式来表示基变换。还是拿上面的例子,想一下,将(3,2)变换为新基上的坐标,就是用(3,2)与第一个基做内积运算,作为第一个 新的坐标分量,然后用(3,2)与第二个基做内积运算,作为第二个新坐标的分量。实际上,我们可以用矩阵相乘的形式简洁的表示这个变换: 106 | 107 | $$ 108 | \begin{pmatrix} 1/\sqrt{2} & 1/\sqrt{2} \\ -1/\sqrt{2} & 1/\sqrt{2} \end{pmatrix} \begin{pmatrix} 3 \\ 2 \end{pmatrix} = \begin{pmatrix} 5/\sqrt{2} \\ -1/\sqrt{2} \end{pmatrix} 109 | $$ 110 | 111 | 太漂亮了!其中矩阵的两行分别为两个基,乘以原向量,其结果刚好为新基的坐标。可以稍微推广一下,如果我们有 m 个二维向量,只要 将二维向量按列排成一个两行 m 列矩阵,然后用“基矩阵”乘以这个矩阵,就得到了所有这些向量在新基下的值。例如(1,1),(2,2),(3,3),想变 换到刚才那组基上,则可以这样表示: 112 | 113 | $$ 114 | \begin{pmatrix} 1/\sqrt{2} & 1/\sqrt{2} \\ -1/\sqrt{2} & 1/\sqrt{2} \end{pmatrix} \begin{pmatrix} 1 & 2 & 3 \\ 1 & 2 & 3 \end{pmatrix} = \begin{pmatrix} 2/\sqrt{2} & 4/\sqrt{2} & 6/\sqrt{2} \\ 0 & 0 & 0 \end{pmatrix} 115 | $$ 116 | 117 | aj 118 | 于是一组向量的基变换被干净的表示为矩阵的相乘。 119 | 一般的,如果我们有 M 个 N 维向量,想将其变换为由 R 个 N 维向量表示的新空间中,那么首先将 R 个基按行组成矩阵 A,然后将向量按列组成矩阵 B,那么两矩阵的乘积 AB 就是变换结果,其中 AB 的第 m 列为 A 中第 m 列变换后的结果。 120 | 数学表示为: 121 | 122 | $$ 123 | \begin{pmatrix} p_1 \\ p_2 \\ \vdots \\ p_R \end{pmatrix} \begin{pmatrix} a_1 & a_2 & \cdots & a_M \end{pmatrix} = \begin{pmatrix} p_1a_1 & p_1a_2 & \cdots & p_1a_M \\ p_2a_1 & p_2a_2 & \cdots & p_2a_M \\ \vdots & \vdots & \ddots & \vdots \\ p_Ra_1 & p_Ra_2 & \cdots & p_Ra_M \end{pmatrix} 124 | $$ 125 | 126 | (1124213344) 127 | 其中$p_i 128 | $是一个行向量,表示第 i 个基,$a_j$是一个列向量,表示第 j 个原始数据记录。 129 | 特别要注意的是,这里 R 可以小于 N,而 R 决定了变换后数据的维数。也就是说,我们可以将一 N 维数据变换到更低维度的空间中去,变换后的维度取决于基的数量。因此这种矩阵相乘的表示也可以表示降维变换。 130 | 最后,上述分析同时给矩阵相乘找到了一种物理解释:两个矩阵相乘的意义是将右边矩阵中的每一列列向量变换到左边矩阵中每一行行向量为基所表示的空间中去。更抽象的说,一个矩阵可以表示一种线性变换。很多同学在学线性代数时对矩阵相乘的方法感到奇怪,但是如果明白了矩阵相乘的物理意义,其合理性就一目了然了。 131 | 132 | ## 协方差矩阵及优化目标 133 | 134 | 上面我们讨论了选择不同的基可以对同样一组数据给出不同的表示,而且如果基的数量少于向量本身的维数,则可以达到降维的效果。但 是我们还没有回答一个最最关键的问题:如何选择基才是最优的。或者说,如果我们有一组 N 维向量,现在要将其降到 K 维(K 小于 N),那么我们应该如何选择 K 个基才能最大程度保留原有的信息? 135 | 要完全数学化这个问题非常繁杂,这里我们用一种非形式化的直观方法来看这个问题。 136 | 为了避免过于抽象的讨论,我们仍以一个具体的例子展开。假设我们的数据由五条记录组成,将它们表示成矩阵形式: 137 | 138 | $$ 139 | \begin{pmatrix} 1 & 1 & 2 & 4 & 2 \\ 1 & 3 & 3 & 4 & 4 \end{pmatrix} 140 | $$ 141 | 142 | 其中每一列为一条数据记录,而一行为一个字段。为了后续处理方便,我们首先将每个字段内所有值都减去字段均值,其结果是将每个字段都变为均值为 0(这样做的道理和好处后面会看到)。 143 | 我们看上面的数据,第一个字段均值为 2,第二个字段均值为 3,所以变换后: 144 | 145 | $$ 146 | \begin{pmatrix} -1 & -1 & 0 & 2 & 0 \\ -2 & 0 & 0 & 1 & 1 \end{pmatrix} 147 | $$ 148 | 149 | ![](http://blog.codinglabs.org/uploads/pictures/pca-tutorial/06.png) 150 | 现在问题来了:如果我们必须使用一维来表示这些数据,又希望尽量保留原始的信息,你要如何选择? 151 | 通过上一节对基变换的讨论我们知道,这个问题实际上是要在二维平面中选择一个方向,将所有数据都投影到这个方向所在直线上,用投影值表示原始记录。这是一个实际的二维降到一维的问题。 152 | 那么如何选择这个方向(或者说基)才能尽量保留最多的原始信息呢?一种直观的看法是:希望投影后的投影值尽可能分散。 153 | 以上图为例,可以看出如果向 x 轴投影,那么最左边的两个点会重叠在一起,中间的两个点也会重叠在一起,于是本身四个各不相同的二 维点投影后只剩下两个不同的值了,这是一种严重的信息丢失,同理,如果向 y 轴投影最上面的两个点和分布在 x 轴上的两个点也会重叠。所以看来 x 和 y 轴都不是 最好的投影选择。我们直观目测,如果向通过第一象限和第三象限的斜线投影,则五个点在投影后还是可以区分的。 154 | 下面,我们用数学方法表述这个问题。 155 | 156 | ### 方差 157 | 158 | 上文说到,我们希望投影后投影值尽可能分散,而这种分散程度,可以用数学上的方差来表述。此处,一个字段的方差可以看做是每个元素与字段均值的差的平方和的均值,即: 159 | $Var(a)=\frac{1}{m}\sum_{i=1}^m{(a_i-\mu)^2}$ 160 | X=(a1a2⋯amb1b2⋯bm) 161 | 由于上面我们已经将每个字段的均值都化为 0 了,因此方差可以直接用每个元素的平方和除以元素个数表示: 162 | $Var(a)=\frac{1}{m}\sum_{i=1}^m{a_i^2}$ 163 | 1mXXT=(1m∑i=1mai21m∑i=1maibi1m∑i=1maibi1m∑i=1mbi2) 164 | 于是上面的问题被形式化表述为:寻找一个一维基,使得所有数据变换为这个基上的坐标表示后,方差值最大。 165 | 166 | ### 协方差 167 | 168 | 对于上面二维降成一维的问题来说,找到那个使得方差最大的方向就可以了。不过对于更高维,还有一个问题需要解决。考虑三维降到二维问题。与之前相同,首先我们希望找到一个方向使得投影后方差最大,这样就完成了第一个方向的选择,继而我们选择第二个投影方向。 169 | 如果我们还是单纯只选择方差最大的方向,很明显,这个方向与第一个方向应该是“几乎重合在一起”,显然这样的维度是没有用的,因 此,应该有其他约束条件。从直观上说,让两个字段尽可能表示更多的原始信息,我们是不希望它们之间存在(线性)相关性的,因为相关性意味着两个字段不是完 全独立,必然存在重复表示的信息。 170 | 数学上可以用两个字段的协方差表示其相关性,由于已经让每个字段均值为 0,则: 171 | $Cov(a,b)=\frac{1}{m}\sum_{i=1}^m{a_ib_i}$ 172 | D=1mYYT=1m(PX)(PX)T=1mPXXTPT=P(1mXXT)PT=PCPT 173 | 可以看到,在字段均值为 0 的情况下,两个字段的协方差简洁的表示为其内积除以元素数 m。 174 | 当协方差为 0 时,表示两个字段完全独立。为了让协方差为 0,我们选择第二个基时只能在与第一个基正交的方向上选择。因此最终选择的两个方向一定是正交的。 175 | 至此,我们得到了降维问题的优化目标:将一组 N 维向量降为 K 维(K 大于 0,小于 N),其目标是选择 K 个单位(模为 1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为 0,而字段的方差则尽可能大(在正交的约束下,取最大的 K 个方差)。 176 | 177 | ### 协方差矩阵 178 | 179 | 上面我们导出了优化目标,但是这个目标似乎不能直接作为操作指南(或者说算法),因为它只说要什么,但根本没有说怎么做。所以我们要继续在数学上研究计算方案。 180 | 我们看到,最终要达到的目的与字段内方差及字段间协方差有密切关系。因此我们希望能将两者统一表示,仔细观察发现,两者均可以表示为内积的形式,而内积又与矩阵相乘密切相关。于是我们来了灵感: 181 | 假设我们只有 a 和 b 两个字段,那么我们将它们按行组成矩阵 X: 182 | $X=\begin{pmatrix} a_1 & a_2 & \cdots & a_m \\ b_1 & b_2 & \cdots & b_m \end{pmatrix}$ 183 | (e1e2⋯en) 184 | 然后我们用 X 乘以 X 的转置,并乘上系数 1/m: 185 | $\frac{1}{m}XX^\mathsf{T}=\begin{pmatrix} \frac{1}{m}\sum_{i=1}^m{a_i^2} & \frac{1}{m}\sum_{i=1}^m{a_ib_i} \\ \frac{1}{m}\sum_{i=1}^m{a_ib_i} & \frac{1}{m}\sum_{i=1}^m{b_i^2} \end{pmatrix}$ 186 | (λ1λ2⋱λn) 187 | 奇迹出现了!这个矩阵对角线上的两个元素分别是两个字段的方差,而其它元素是 a 和 b 的协方差。两者被统一到了一个矩阵的。 188 | 根据矩阵相乘的运算法则,这个结论很容易被推广到一般情况: 189 | 设我们有 m 个 n 维数据记录,将其按列排成 n 乘 m 的矩阵 X,设 C=\frac{1}{m}XX^\mathsf{T},则 C 是一个对称矩阵,其对角线分别个各个字段的方差,而第 i 行 j 列和 j 行 i 列元素相同,表示 i 和 j 两个字段的协方差。 190 | 191 | ## 协方差矩阵对角化 192 | 193 | 根据上述推导,我们发现要达到优化目前,等价于将协方差矩阵对角化:即除对角线外的其它元素化为 0,并且在对角线上将元素按大小从上到下排列,这样我们就达到了优化目的。这样说可能还不是很明晰,我们进一步看下原矩阵与基变换后矩阵协方差矩阵的关系: 194 | 设原始数据矩阵 X 对应的协方差矩阵为 C,而 P 是一组基按行组成的矩阵,设 Y=PX,则 Y 为 X 对 P 做基变换后的数据。设 Y 的协方差矩阵为 D,我们推导一下 D 与 C 的关系: 195 | \begin{array}{l l l} D & = & \frac{1}{m}YY^\mathsf{T} \\ & = & \frac{1}{m}(PX)(PX)^\mathsf{T} \\ & = & \frac{1}{m}PXX^\mathsf{T}P^\mathsf{T} \\ & = & P(\frac{1}{m}XX^\mathsf{T})P^\mathsf{T} \\ & = & PCP^\mathsf{T} \end{array} 196 | 现在事情很明白了!我们要找的 P 不是别的,而是能让原始协方差矩阵对角化的 P。换句话说,优化目标变成了寻找一个矩阵 P,满足 PCP^\mathsf{T}是一个对角矩阵,并且对角元素按从大到小依次排列,那么 P 的前 K 行就是要寻找的基,用 P 的前 K 行组成的矩阵乘以 X 就使得 X 从 N 维降到了 K 维并满足上述优化条件。 197 | 至此,我们离“发明”PCA 还有仅一步之遥! 198 | 现在所有焦点都聚焦在了协方差矩阵对角化问题上,有时,我们真应该感谢数学家的先行,因为矩阵对角化在线性代数领域已经属于被玩烂了的东西,所以这在数学上根本不是问题。 199 | 由上文知道,协方差矩阵 C 是一个是对称矩阵,在线性代数上,实对称矩阵有一系列非常好的性质:1)实对称矩阵不同特征值对应的特征向量必然正交。2)设特征向量\lambda 重数为 r,则必然存在 r 个线性无关的特征向量对应于\lambda,因此可以将这 r 个特征向量单位正交化。 200 | 由上面两条可知,一个 n 行 n 列的实对称矩阵一定可以找到 n 个单位正交特征向量,设这 n 个特征向量为 e_1,e_2,\cdots,e_n,我们将其按列组成矩阵: 201 | E=\begin{pmatrix} e_1 & e_2 & \cdots & e_n \end{pmatrix} 202 | 则对协方差矩阵 C 有如下结论: 203 | E^\mathsf{T}CE=\Lambda=\begin{pmatrix} \lambda_1 & & & \\ & \lambda_2 & & \\ & & \ddots & \\ & & & \lambda_n \end{pmatrix} 204 | 其中\Lambda 为对角矩阵,其对角元素为各特征向量对应的特征值(可能有重复)。 205 | 以上结论不再给出严格的数学证明,对证明感兴趣的朋友可以参考线性代数书籍关于“实对称矩阵对角化”的内容。 206 | 到这里,我们发现我们已经找到了需要的矩阵 P: 207 | P=E^\mathsf{T} 208 | P 是协方差矩阵的特征向量单位化后按行排列出的矩阵,其中每一行都是 C 的一个特征向量。如果设 P 按照\Lambda 中特征值的从大到小,将特征向量从上到下排列,则用 P 的前 K 行组成的矩阵乘以原始数据矩阵 X,就得到了我们需要的降维后的数据矩阵 Y。 209 | 至此我们完成了整个 PCA 的数学原理讨论。在下面的一节,我们将给出 PCA 的一个实例。 210 | -------------------------------------------------------------------------------- /特征工程/数据集/文本/常用数据集介绍.md: -------------------------------------------------------------------------------- 1 | # 搜狗实验室数据 2 | 3 | ![常用数据集简介-图1](picture/常用数据集简介-图1.png "搜狗实验室数据") 4 | 5 | 搜狗实验室(Sogo Labs)是搜狗搜索核心研发团队对外交流的窗口,包含数据资源、数据挖掘云、研究合作等几个栏目。数据资源包括评测集合、语料数据、新闻数据、图片数据和自然语言处理相关数据,网址为[这里](http://www.sogou.com/labs/resource/list_pingce.php) 6 | 7 | ## 互联网语料库(SogouT) 8 | 9 | SogouT 来自互联网各种类型的 1.3 亿个原始网页, 压缩前的大小超过了 5TB,格式如下: 10 | 11 | ```xml 12 | 13 | 页面 ID 14 | 页面 URL 15 | 页面原始内容 16 | 17 | ``` 18 | 19 | 为了满足不同需求,SogouT 分为了不同的版本,差别体现在数据量上: 20 | 21 | - 迷你版(样例数据, 61KB):tar.gz 格式,zip 格式 22 | - 完整版(1TB):(硬盘拷贝) 23 | - 历史版本(130GB):V2.0(硬盘拷贝) 24 | 25 | ## 全网新闻数据(SogouCA) 26 | 27 | SogouCA 来自若干新闻站点 2012 年 6 月—7 月期间国内,国际,体育,社会,娱乐等 18 个频道的新闻数据,提供 URL 和正文信息,格式如下: 28 | 29 | ```html 30 | 31 | 页面URL 32 | 33 | 页面ID 34 | 35 | 页面标题 36 | 37 | 页面内容 38 | 39 | ``` 40 | 41 | 为了满足不同需求,SogouCA 分为了不同的版本,差别体现在数据量上: 42 | 43 | - 迷你版(样例数据, 101KB):tar.gz 格式,zip 格式 44 | - 完整版(711MB):tar.gz 格式,zip 格式 45 | - 历史版本:- 完整版(同时提供硬盘拷贝,1.02GB):tar.gz 格式 - 迷你版(样例数据, 3KB):tar.gz 格式 - 精简版(一个月数据, 437MB):tar.gz 格式 46 | 47 | ## 搜狐新闻数据(SogouCS) 48 | 49 | SogouCS 来自搜狐新闻 2012 年 6 月—7 月期间国内,国际,体育,社会,娱乐等 18 个频道的新闻数据,提供 URL 和正文信息,格式如下: 50 | 51 | ```html 52 | 53 | 页面URL 54 | 55 | 页面ID 56 | 57 | 页面标题 58 | 59 | 页面内容 60 | 61 | ``` 62 | 63 | 为了满足不同需求,SogouCS 分为了不同的版本,差别体现在数据量上: 64 | 65 | - 迷你版(样例数据, 110KB):tar.gz 格式,zip 格式 66 | - 完整版(648MB):tar.gz 格式,zip 格式 67 | - 历史版本:- 完整版(同时提供硬盘拷贝,65GB):tar.gz 格式 - 迷你版(样例数据, 1KB):tar.gz 格式 - 精简版(一个月数据, 347MB):tar.gz 格式 - 特别版(王灿辉 WWW08 论文数据, 647KB):tar.gz 格式 68 | 69 | ## 文本分类评价(SogouTCE) 70 | 71 | SogouTCE 用以评估文本分类结果的正确性,语料来自搜狐等多个新闻网站近 20 个频道,格式如下: 72 | 73 | ```sh 74 | URL前缀\t对应类别标记 75 | ``` 76 | 77 | SogouTCE 只包含 URL 前缀和对应类别标记的数据,原始的文本数据可以使用 SogouCA 和 SogouCS。 78 | 79 | ## 互联网词库(SogouW) 80 | 81 | SogouW 来自于对 SOGOU 搜索引擎所索引到的中文互联网语料的统计分析,统计所进行的时间是 2006 年 10 月,涉及到的互联网语料规模在 1 亿页面以上。统计出的词条数约为 15 万条高频词,除标出这部分词条的词频信息之外,还标出了常用的词性信息,格式如下: 82 | 83 | ``` 84 | 词A 词频 词性1 词性2 … 词性N 85 | 86 | 词B 词频 词性1 词性2 … 词性N 87 | 88 | 词C 词频 词性1 词性2 … 词性N 89 | ``` 90 | 91 | # IMDB Reviews 92 | 93 | 互联网电影资料库(Internet Movie Database,简称 IMDB)是一个关于电影演员、电影、电视节目、电视明星和电影制作的在线数据库。IMDB Reviews 是记录了观众对 IMDB 中作品的评价。除了训练和测试评估示例之外,还有更多未标记的数据可供使用,包括文本和预处理的词袋格式。IMDB Reviews 包含 25,000 个高度差异化的电影评论用于训练,25,000 个测试,通常用于英文的情感理解。 94 | 95 | # Sentiment140 96 | 97 | Sentiment140 是一个可用于情感分析的数据集,包含 160,000 条推文。一个流行的数据集,非常适合开始你的 NLP 旅程。情绪已经从数据中预先移除。最终的数据集具有以下 6 个特征: 98 | 99 | - 推文的极性 100 | - 推文的 ID 101 | - 推文的日期 102 | - 问题 103 | - 推文的用户名 104 | - 推文的文本 105 | 106 | # Yelp Reviews 107 | 108 | Yelp Reviews 是 Yelp 为了学习目的而发布的一个开源数据集。它包含了由数百万用户评论,商业属性和来自多个大都市地区的超过 20 万张照片。这是一个常用的全球 NLP 挑战数据集,包含 5,200,000 条评论,174,000 条商业属性。 109 | 数据集下载地址为: 110 | 111 | > https://www.yelp.com/dataset/download 112 | 113 | ![常用数据集简介-图5](picture/常用数据集简介-图5.png) 114 | 115 | 数据集格式分为 JSON 和 SQL 两种,以 JSON 格式为例,其中最重要的 review.json,包含评论数据,格式如下: 116 | 117 | ```json 118 | { 119 | // string, 22 character unique review id 120 | "review_id": "zdSx_SD6obEhz9VrW9uAWA", 121 | 122 | // string, 22 character unique user id, maps to the user in user.json 123 | "user_id": "Ha3iJu77CxlrFm-vQRs_8g", 124 | 125 | // string, 22 character business id, maps to business in business.json 126 | "business_id": "tnhfDv5Il8EaGSXZGiuQGg", 127 | 128 | // integer, star rating 129 | "stars": 4, 130 | 131 | // string, date formatted YYYY-MM-DD 132 | "date": "2016-03-09", 133 | 134 | // string, the review itself 135 | "text": "Great place to hang out after work: the prices are decent, and the ambience is fun. It's a bit loud, but very lively. The staff is friendly, and the food is good. They have a good selection of drinks.", 136 | 137 | // integer, number of useful votes received 138 | "useful": 0, 139 | 140 | // integer, number of funny votes received 141 | "funny": 0, 142 | 143 | // integer, number of cool votes received 144 | "cool": 0 145 | } 146 | ``` 147 | 148 | 另外 tip.json 文件记录了短评数据,格式如下: 149 | 150 | ```json 151 | { 152 | // string, text of the tip 153 | "text": "Secret menu - fried chicken sando is da bombbbbbb Their zapatos are good too.", 154 | 155 | // string, when the tip was written, formatted like YYYY-MM-DD 156 | "date": "2013-09-20", 157 | 158 | // integer, how many likes it has 159 | "likes": 172, 160 | 161 | // string, 22 character business id, maps to business in business.json 162 | "business_id": "tnhfDv5Il8EaGSXZGiuQGg", 163 | 164 | // string, 22 character unique user id, maps to the user in user.json 165 | "user_id": "49JhAJh8vSQ-vM4Aourl0g" 166 | } 167 | ``` 168 | 169 | 专门有个开源项目用于解析该 JSON 文件: 170 | 171 | > https://github.com/Yelp/dataset-examples 172 | 173 | # Enron-Spam 174 | 175 | Enron-Spam 数据集是目前在电子邮件相关研究中使用最多的公开数据集,其邮件数据是安然公司(Enron Corporation, 原是世界上最大的综合性天然气和电力公司之一,在北美地区是头号天然气和电力批发销售商)150 位高级管理人员的往来邮件。这些邮件在安然公司接受美国联邦能源监管委员会调查时被其公布到网上。机器学习领域使用 Enron-Spam 数据集来研究文档分类、词性标注、垃圾邮件识别等,由于 Enron-Spam 数据集都是真实环境下的真实邮件,非常具有实际意义。 176 | Enron-Spam 数据集合如下图所示,使用不同文件夹区分正常邮件和垃圾邮件。 177 | 178 | ![常用数据集简介-图3.png](picture/常用数据集简介-图3.png "Enron-Spam数据集文件夹结构") 179 | 180 | 正常邮件内容举例如下: 181 | 182 | > Subject: christmas baskets 183 | > the christmas baskets have been ordered . 184 | > we have ordered several baskets . 185 | > individual earth - sat freeze - notis 186 | > smith barney group baskets 187 | > rodney keys matt rodgers charlie 188 | > notis jon davis move 189 | > team 190 | > phillip randle chris hyde 191 | > harvey 192 | > freese 193 | > faclities 194 | 195 | 垃圾邮件内容举例如下: 196 | 197 | > Subject: fw : this is the solution i mentioned lscoo 198 | > thank you , 199 | > your email address was obtained from a purchased list ,reference # 2020 mid = 3300 . if you wish to unsubscribe 200 | > from this list, please click here and enter 201 | > your name into the remove box . if you have previously unsubscribed 202 | > and are still receiving this message, you may email our abuse 203 | > control center, or call 1 - 888 - 763 - 2497, or write us at : nospam , 204 | > 6484 coral way, miami, fl, 33155 " . 2002 205 | > web credit inc . all rights reserved . 206 | 207 | Enron-Spam 数据集对应的网址为: 208 | 209 | > http://www2.aueb.gr/users/ion/data/enron-spam/ 210 | 211 | # babi 阅读理解数据集 212 | 213 | babi 是来自 FAIR(Facebook AI Research)的合成式阅读理解与问答数据集,是个入门级的阅读理解数据集,其训练集以对话集合[2] + 问题[1] + 回答[1]的形式组成: 214 | 215 | 1 Mary moved to the bathroom. 216 | 2 John went to the hallway. 217 | 3 Where is Mary? bathroom 1 218 | 4 Daniel went back to the hallway. 219 | 5 Sandra moved to the garden. 220 | 6 Where is Daniel? hallway 4 221 | 7 John moved to the office. 222 | 8 Sandra journeyed to the bathroom. 223 | 9 Where is Daniel? hallway 4 224 | 10 Mary moved to the hallway. 225 | 11 Daniel travelled to the office. 226 | 12 Where is Daniel? office 11 227 | 13 John went back to the garden. 228 | 14 John moved to the bedroom. 229 | 15 Where is Sandra? bathroom 8 230 | 1 Sandra travelled to the office. 231 | 2 Sandra went to the bathroom. 232 | 3 Where is Sandra? bathroom 2 233 | 4 Mary went to the bedroom. 234 | 5 Daniel moved to the hallway. 235 | 6 Where is Sandra? bathroom 2 236 | 7 John went to the garden. 237 | 8 John travelled to the office. 238 | 9 Where is Sandra? bathroom 2 239 | 10 Daniel journeyed to the bedroom. 240 | 11 Daniel travelled to the hallway. 241 | 12 Where is John? office 8 242 | 243 | 抽象表示格式为: 244 | 245 | ID text 246 | ID text 247 | ID text 248 | ID question[tab]answer[tab]supporting fact IDS. 249 | 250 | 项目主页地址为: 251 | 252 | > https://research.fb.com/downloads/babi/ 253 | 254 | 数据下载地址为: 255 | 256 | > http://www.thespermwhale.com/jaseweston/babi/tasks_1-20_v1.tar.gz 257 | 258 | 下载压缩包,解压后,全部文件保存在 en 文件下,文件夹下包含以下文件: 259 | 260 | qa10_indefinite-knowledge_test.txt 261 | qa1_single-supporting-fact_test.txt 262 | qa10_indefinite-knowledge_train.txt 263 | qa1_single-supporting-fact_train.txt 264 | qa11_basic-coreference_test.txt 265 | qa20_agents-motivations_test.txt 266 | qa11_basic-coreference_train.txt 267 | qa20_agents-motivations_train.txt 268 | qa12_conjunction_test.txt 269 | qa2_two-supporting-facts_test.txt 270 | qa12_conjunction_train.txt 271 | qa2_two-supporting-facts_train.txt 272 | qa13_compound-coreference_test.txt 273 | qa3_three-supporting-facts_test.txt 274 | qa13_compound-coreference_train.txt 275 | qa3_three-supporting-facts_train.txt 276 | qa14_time-reasoning_test.txt 277 | qa4_two-arg-relations_test.txt 278 | qa14_time-reasoning_train.txt 279 | qa4_two-arg-relations_train.txt 280 | qa15_basic-deduction_test.txt 281 | qa5_three-arg-relations_test.txt 282 | qa15_basic-deduction_train.txt 283 | qa5_three-arg-relations_train.txt 284 | qa16_basic-induction_test.txt 285 | qa6_yes-no-questions_test.txt 286 | qa16_basic-induction_train.txt 287 | qa6_yes-no-questions_train.txt 288 | qa17_positional-reasoning_test.txt 289 | qa7_counting_test.txt 290 | qa17_positional-reasoning_train.txt 291 | qa7_counting_train.txt 292 | qa18_size-reasoning_test.txt 293 | qa8_lists-sets_test.txt 294 | qa18_size-reasoning_train.txt 295 | qa8_lists-sets_train.txt 296 | qa19_path-finding_test.txt 297 | qa9_simple-negation_test.txt 298 | qa19_path-finding_train.txt 299 | qa9_simple-negation_train.txt 300 | 301 | # SMS Spam Collection 302 | 303 | SMS Spam Collection 是用于骚扰短信识别的经典数据集,完全来自真实短信内容,包括 4831 条正常短信和 747 条骚扰短信。从官网下载数据集压缩包,解压,正常短信和骚扰短信保存在一个文本文件中。 304 | 每行完整记录一条短信内容,每行开头通过 ham 和 spam 标识正常短信和骚扰短信,数据集文件内容举例如下: 305 | 306 | > ham What you doing?how are you? 307 | > ham Ok lar... Joking wif u oni... 308 | > ham dun say so early hor... U c already then say... 309 | > ham MY NO. IN LUTON 0125698789 RING ME IF UR AROUND! H\* 310 | > ham Siva is in hostel aha:-. 311 | > ham Cos i was out shopping wif darren jus now n i called him 2 ask wat present he wan lor. Then he started guessing who i was wif n he finally guessed darren lor. 312 | > spam FreeMsg: Txt: CALL to No: 86888 & claim your reward of 3 hours talk time to use from your phone now! ubscribe6GBP/ mnth inc 3hrs 16 stop?txtStop 313 | > spam Sunshine Quiz! Win a super Sony DVD recorder if you canname the capital of Australia? Text MQUIZ to 82277. B 314 | > spam URGENT! Your Mobile No 07808726822 was awarded a L2,000 Bonus Caller Prize on 02/09/03! This is our 2nd attempt to contact YOU! Call 0871-872-9758 BOX95QU 315 | 316 | SMS Spam Collection 数据集主页地址为: 317 | 318 | > http://archive.ics.uci.edu/ml/datasets/SMS+Spam+Collection 319 | 320 | ![常用数据集](picture/常用数据集-图4.png) 321 | 322 | # UBUNTU DIALOG CORPUS 323 | 324 | UBUNTU DIALOG CORPUS(UDC)是可用的最大的公共对话数据集之一,下载地址为: 325 | 326 | > cs.mcgill.ca/~jpineau/datasets/ubuntu-corpus-1.0/ubuntu_dialogs.tgz 327 | 328 | 它基于公共 IRC 网络上的 Ubuntu 频道的聊天记录。训练数据包括 100 万个样例,50%的正样例(标签 1)和 50%的负样例(标签 0)。每个样例都包含一个上下文,即直到这一点的谈话记录,以及一个话语,即对上下文的回应。一个正标签意味着话语是对当前语境上下文的实际响应,一个负标签意味着这个话语不是真实的响应 ,它是从语料库的某个地方随机挑选出来的。这是一些示例数据: 329 | 330 | ![常用数据集简介-图8](picture/常用数据集简介-图8.png) 331 | 332 | UDC 相关的经典论文地址为: 333 | 334 | > https://arxiv.org/abs/1506.08909 335 | 336 | UDC 相关的 Github 地址为: 337 | 338 | > https://github.com/rkadlec/ubuntu-ranking-dataset-creator 339 | 340 | # Hate speech identification 341 | 342 | Hate speech identification 由 ICWSM 2017 论文“自动仇恨语音检测和无礼语言问题”的作者提供。包含 3 类短文本: 343 | 344 | - 包含仇恨言论; 345 | - 是冒犯性的,但没有仇恨言论; 346 | - 根本没有冒犯性。 347 | 348 | 由 15,000 行文本构成,每个字符串都经过 3 人判断。 349 | 350 | 下载链接为: 351 | 352 | > https://github.com/t-davidson/hate-speech-and-offensive-language 353 | 354 | # Twitter Progressive issues sentiment analysis 355 | 356 | Twitter Progressive issues sentiment analysis 是关于诸如堕胎合法化、女权主义、希拉里·克林顿等各种左倾问题的推文,分为赞成、反对或保持中立的三种类别。 357 | 358 | 下载链接为: 359 | 360 | > https://www.figure-eight.com/data-for-everyone/ 361 | 362 | # 今日头条新闻文本分类数据集 363 | 364 | 今日头条新闻文本分类数据集共 382688 条,分布于 15 个分类中,分类 code 与名称: 365 | 366 | - 100 民生 故事 news_story 367 | - 101 文化 文化 news_culture 368 | - 102 娱乐 娱乐 news_entertainment 369 | - 103 体育 体育 news_sports 370 | - 104 财经 财经 news_finance 371 | - 106 房产 房产 news_house 372 | - 107 汽车 汽车 news_car 373 | - 108 教育 教育 news_edu 374 | - 109 科技 科技 news_tech 375 | - 110 军事 军事 news_military 376 | - 112 旅游 旅游 news_travel 377 | - 113 国际 国际 news_world 378 | - 114 证券 股票 stock 379 | - 115 农业 三农 news_agriculture 380 | - 116 电竞 游戏 news_game 381 | 382 | 数据格式为: 383 | 384 | ```sh 385 | 6552431613437805063_!_102_!_news_entertainment_!_谢娜为李浩菲澄清网络谣言, 386 | 之后她的两个行为给自己加分_!_佟丽娅,网络谣言,快乐大本营,李浩菲,谢娜,观众们 387 | ``` 388 | 389 | 每行为一条数据,以 `_!_` 分割的个字段,从前往后分别是 新闻 ID,分类 code,分类名称,新闻字符串(仅含标题),新闻关键词. 390 | 391 | 项目主页在 github 上,运行 get_data.py 即可获取实时获取对应的数据:https://github.com/fateleak/toutiao-text-classfication-dataset 392 | 393 | 也可以直接使用 github 上的历史数据进行分析:https://github.com/fateleak/toutiao-text-classfication-dataset/raw/master/toutiao_cat_data.txt.zip 394 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 2 | Public License 3 | 4 | By exercising the Licensed Rights (defined below), You accept and agree 5 | to be bound by the terms and conditions of this Creative Commons 6 | Attribution-NonCommercial-ShareAlike 4.0 International Public License 7 | ("Public License"). To the extent this Public License may be 8 | interpreted as a contract, You are granted the Licensed Rights in 9 | consideration of Your acceptance of these terms and conditions, and the 10 | Licensor grants You such rights in consideration of benefits the 11 | Licensor receives from making the Licensed Material available under 12 | these terms and conditions. 13 | 14 | 15 | Section 1 -- Definitions. 16 | 17 | a. Adapted Material means material subject to Copyright and Similar 18 | Rights that is derived from or based upon the Licensed Material 19 | and in which the Licensed Material is translated, altered, 20 | arranged, transformed, or otherwise modified in a manner requiring 21 | permission under the Copyright and Similar Rights held by the 22 | Licensor. For purposes of this Public License, where the Licensed 23 | Material is a musical work, performance, or sound recording, 24 | Adapted Material is always produced where the Licensed Material is 25 | synched in timed relation with a moving image. 26 | 27 | b. Adapter's License means the license You apply to Your Copyright 28 | and Similar Rights in Your contributions to Adapted Material in 29 | accordance with the terms and conditions of this Public License. 30 | 31 | c. BY-NC-SA Compatible License means a license listed at 32 | creativecommons.org/compatiblelicenses, approved by Creative 33 | Commons as essentially the equivalent of this Public License. 34 | 35 | d. Copyright and Similar Rights means copyright and/or similar rights 36 | closely related to copyright including, without limitation, 37 | performance, broadcast, sound recording, and Sui Generis Database 38 | Rights, without regard to how the rights are labeled or 39 | categorized. For purposes of this Public License, the rights 40 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 41 | Rights. 42 | 43 | e. Effective Technological Measures means those measures that, in the 44 | absence of proper authority, may not be circumvented under laws 45 | fulfilling obligations under Article 11 of the WIPO Copyright 46 | Treaty adopted on December 20, 1996, and/or similar international 47 | agreements. 48 | 49 | f. Exceptions and Limitations means fair use, fair dealing, and/or 50 | any other exception or limitation to Copyright and Similar Rights 51 | that applies to Your use of the Licensed Material. 52 | 53 | g. License Elements means the license attributes listed in the name 54 | of a Creative Commons Public License. The License Elements of this 55 | Public License are Attribution, NonCommercial, and ShareAlike. 56 | 57 | h. Licensed Material means the artistic or literary work, database, 58 | or other material to which the Licensor applied this Public 59 | License. 60 | 61 | i. Licensed Rights means the rights granted to You subject to the 62 | terms and conditions of this Public License, which are limited to 63 | all Copyright and Similar Rights that apply to Your use of the 64 | Licensed Material and that the Licensor has authority to license. 65 | 66 | j. Licensor means the individual(s) or entity(ies) granting rights 67 | under this Public License. 68 | 69 | k. NonCommercial means not primarily intended for or directed towards 70 | commercial advantage or monetary compensation. For purposes of 71 | this Public License, the exchange of the Licensed Material for 72 | other material subject to Copyright and Similar Rights by digital 73 | file-sharing or similar means is NonCommercial provided there is 74 | no payment of monetary compensation in connection with the 75 | exchange. 76 | 77 | l. Share means to provide material to the public by any means or 78 | process that requires permission under the Licensed Rights, such 79 | as reproduction, public display, public performance, distribution, 80 | dissemination, communication, or importation, and to make material 81 | available to the public including in ways that members of the 82 | public may access the material from a place and at a time 83 | individually chosen by them. 84 | 85 | m. Sui Generis Database Rights means rights other than copyright 86 | resulting from Directive 96/9/EC of the European Parliament and of 87 | the Council of 11 March 1996 on the legal protection of databases, 88 | as amended and/or succeeded, as well as other essentially 89 | equivalent rights anywhere in the world. 90 | 91 | n. You means the individual or entity exercising the Licensed Rights 92 | under this Public License. Your has a corresponding meaning. 93 | 94 | 95 | Section 2 -- Scope. 96 | 97 | a. License grant. 98 | 99 | 1. Subject to the terms and conditions of this Public License, 100 | the Licensor hereby grants You a worldwide, royalty-free, 101 | non-sublicensable, non-exclusive, irrevocable license to 102 | exercise the Licensed Rights in the Licensed Material to: 103 | 104 | a. reproduce and Share the Licensed Material, in whole or 105 | in part, for NonCommercial purposes only; and 106 | 107 | b. produce, reproduce, and Share Adapted Material for 108 | NonCommercial purposes only. 109 | 110 | 2. Exceptions and Limitations. For the avoidance of doubt, where 111 | Exceptions and Limitations apply to Your use, this Public 112 | License does not apply, and You do not need to comply with 113 | its terms and conditions. 114 | 115 | 3. Term. The term of this Public License is specified in Section 116 | 6(a). 117 | 118 | 4. Media and formats; technical modifications allowed. The 119 | Licensor authorizes You to exercise the Licensed Rights in 120 | all media and formats whether now known or hereafter created, 121 | and to make technical modifications necessary to do so. The 122 | Licensor waives and/or agrees not to assert any right or 123 | authority to forbid You from making technical modifications 124 | necessary to exercise the Licensed Rights, including 125 | technical modifications necessary to circumvent Effective 126 | Technological Measures. For purposes of this Public License, 127 | simply making modifications authorized by this Section 2(a) 128 | (4) never produces Adapted Material. 129 | 130 | 5. Downstream recipients. 131 | 132 | a. Offer from the Licensor -- Licensed Material. Every 133 | recipient of the Licensed Material automatically 134 | receives an offer from the Licensor to exercise the 135 | Licensed Rights under the terms and conditions of this 136 | Public License. 137 | 138 | b. Additional offer from the Licensor -- Adapted Material. 139 | Every recipient of Adapted Material from You 140 | automatically receives an offer from the Licensor to 141 | exercise the Licensed Rights in the Adapted Material 142 | under the conditions of the Adapter's License You apply. 143 | 144 | c. No downstream restrictions. You may not offer or impose 145 | any additional or different terms or conditions on, or 146 | apply any Effective Technological Measures to, the 147 | Licensed Material if doing so restricts exercise of the 148 | Licensed Rights by any recipient of the Licensed 149 | Material. 150 | 151 | 6. No endorsement. Nothing in this Public License constitutes or 152 | may be construed as permission to assert or imply that You 153 | are, or that Your use of the Licensed Material is, connected 154 | with, or sponsored, endorsed, or granted official status by, 155 | the Licensor or others designated to receive attribution as 156 | provided in Section 3(a)(1)(A)(i). 157 | 158 | b. Other rights. 159 | 160 | 1. Moral rights, such as the right of integrity, are not 161 | licensed under this Public License, nor are publicity, 162 | privacy, and/or other similar personality rights; however, to 163 | the extent possible, the Licensor waives and/or agrees not to 164 | assert any such rights held by the Licensor to the limited 165 | extent necessary to allow You to exercise the Licensed 166 | Rights, but not otherwise. 167 | 168 | 2. Patent and trademark rights are not licensed under this 169 | Public License. 170 | 171 | 3. To the extent possible, the Licensor waives any right to 172 | collect royalties from You for the exercise of the Licensed 173 | Rights, whether directly or through a collecting society 174 | under any voluntary or waivable statutory or compulsory 175 | licensing scheme. In all other cases the Licensor expressly 176 | reserves any right to collect such royalties, including when 177 | the Licensed Material is used other than for NonCommercial 178 | purposes. 179 | 180 | 181 | Section 3 -- License Conditions. 182 | 183 | Your exercise of the Licensed Rights is expressly made subject to the 184 | following conditions. 185 | 186 | a. Attribution. 187 | 188 | 1. If You Share the Licensed Material (including in modified 189 | form), You must: 190 | 191 | a. retain the following if it is supplied by the Licensor 192 | with the Licensed Material: 193 | 194 | i. identification of the creator(s) of the Licensed 195 | Material and any others designated to receive 196 | attribution, in any reasonable manner requested by 197 | the Licensor (including by pseudonym if 198 | designated); 199 | 200 | ii. a copyright notice; 201 | 202 | iii. a notice that refers to this Public License; 203 | 204 | iv. a notice that refers to the disclaimer of 205 | warranties; 206 | 207 | v. a URI or hyperlink to the Licensed Material to the 208 | extent reasonably practicable; 209 | 210 | b. indicate if You modified the Licensed Material and 211 | retain an indication of any previous modifications; and 212 | 213 | c. indicate the Licensed Material is licensed under this 214 | Public License, and include the text of, or the URI or 215 | hyperlink to, this Public License. 216 | 217 | 2. You may satisfy the conditions in Section 3(a)(1) in any 218 | reasonable manner based on the medium, means, and context in 219 | which You Share the Licensed Material. For example, it may be 220 | reasonable to satisfy the conditions by providing a URI or 221 | hyperlink to a resource that includes the required 222 | information. 223 | 3. If requested by the Licensor, You must remove any of the 224 | information required by Section 3(a)(1)(A) to the extent 225 | reasonably practicable. 226 | 227 | b. ShareAlike. 228 | 229 | In addition to the conditions in Section 3(a), if You Share 230 | Adapted Material You produce, the following conditions also apply. 231 | 232 | 1. The Adapter's License You apply must be a Creative Commons 233 | license with the same License Elements, this version or 234 | later, or a BY-NC-SA Compatible License. 235 | 236 | 2. You must include the text of, or the URI or hyperlink to, the 237 | Adapter's License You apply. You may satisfy this condition 238 | in any reasonable manner based on the medium, means, and 239 | context in which You Share Adapted Material. 240 | 241 | 3. You may not offer or impose any additional or different terms 242 | or conditions on, or apply any Effective Technological 243 | Measures to, Adapted Material that restrict exercise of the 244 | rights granted under the Adapter's License You apply. 245 | 246 | 247 | Section 4 -- Sui Generis Database Rights. 248 | 249 | Where the Licensed Rights include Sui Generis Database Rights that 250 | apply to Your use of the Licensed Material: 251 | 252 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 253 | to extract, reuse, reproduce, and Share all or a substantial 254 | portion of the contents of the database for NonCommercial purposes 255 | only; 256 | 257 | b. if You include all or a substantial portion of the database 258 | contents in a database in which You have Sui Generis Database 259 | Rights, then the database in which You have Sui Generis Database 260 | Rights (but not its individual contents) is Adapted Material, 261 | including for purposes of Section 3(b); and 262 | 263 | c. You must comply with the conditions in Section 3(a) if You Share 264 | all or a substantial portion of the contents of the database. 265 | 266 | For the avoidance of doubt, this Section 4 supplements and does not 267 | replace Your obligations under this Public License where the Licensed 268 | Rights include other Copyright and Similar Rights. 269 | 270 | 271 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 272 | 273 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 274 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 275 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 276 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 277 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 278 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 279 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 280 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 281 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 282 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 283 | 284 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 285 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 286 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 287 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 288 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 289 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 290 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 291 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 292 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 293 | 294 | c. The disclaimer of warranties and limitation of liability provided 295 | above shall be interpreted in a manner that, to the extent 296 | possible, most closely approximates an absolute disclaimer and 297 | waiver of all liability. 298 | 299 | 300 | Section 6 -- Term and Termination. 301 | 302 | a. This Public License applies for the term of the Copyright and 303 | Similar Rights licensed here. However, if You fail to comply with 304 | this Public License, then Your rights under this Public License 305 | terminate automatically. 306 | 307 | b. Where Your right to use the Licensed Material has terminated under 308 | Section 6(a), it reinstates: 309 | 310 | 1. automatically as of the date the violation is cured, provided 311 | it is cured within 30 days of Your discovery of the 312 | violation; or 313 | 314 | 2. upon express reinstatement by the Licensor. 315 | 316 | For the avoidance of doubt, this Section 6(b) does not affect any 317 | right the Licensor may have to seek remedies for Your violations 318 | of this Public License. 319 | 320 | c. For the avoidance of doubt, the Licensor may also offer the 321 | Licensed Material under separate terms or conditions or stop 322 | distributing the Licensed Material at any time; however, doing so 323 | will not terminate this Public License. 324 | 325 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 326 | License. 327 | 328 | 329 | Section 7 -- Other Terms and Conditions. 330 | 331 | a. The Licensor shall not be bound by any additional or different 332 | terms or conditions communicated by You unless expressly agreed. 333 | 334 | b. Any arrangements, understandings, or agreements regarding the 335 | Licensed Material not stated herein are separate from and 336 | independent of the terms and conditions of this Public License. 337 | 338 | 339 | Section 8 -- Interpretation. 340 | 341 | a. For the avoidance of doubt, this Public License does not, and 342 | shall not be interpreted to, reduce, limit, restrict, or impose 343 | conditions on any use of the Licensed Material that could lawfully 344 | be made without permission under this Public License. 345 | 346 | b. To the extent possible, if any provision of this Public License is 347 | deemed unenforceable, it shall be automatically reformed to the 348 | minimum extent necessary to make it enforceable. If the provision 349 | cannot be reformed, it shall be severed from this Public License 350 | without affecting the enforceability of the remaining terms and 351 | conditions. 352 | 353 | c. No term or condition of this Public License will be waived and no 354 | failure to comply consented to unless expressly agreed to by the 355 | Licensor. 356 | 357 | d. Nothing in this Public License constitutes or may be interpreted 358 | as a limitation upon, or waiver of, any privileges and immunities 359 | that apply to the Licensor or You, including from the legal 360 | processes of any jurisdiction or authority. 361 | -------------------------------------------------------------------------------- /00~导论/MachineLearning-Is-Fun-For-Anyone-Curious-About-ML.md: -------------------------------------------------------------------------------- 1 | > 系列翻译自 [machine-learning-is-fun-part-1](https://medium.com/@ageitgey/machine-learning-is-fun-80ea3ec3c471#.dniejuowp),原文共分三个部分,笔者在这里合并到一篇文章中,并且对内容进行了重新排版以方便阅读,归档到了 [人工智能与深度学习实战--机器学习篇中](https://github.com/wx-chevalier/AIDL-Notes) 中。 2 | 3 | # What is Machine Learning:Machine Learning 的概念与算法介绍 4 | 5 | 估计你已经厌烦了听身边人高谈阔论什么机器学习、深度学习但是自己摸不着头脑,这篇文章就由浅入深高屋建瓴地给你介绍一下机器学习的方方面面。本文的主旨即是让每个对机器学习的人都有所得,因此你也不能指望在这篇文章中学到太多高深的东西。言归正传,我们先来看看到底什么是机器学习: 6 | 7 | > Machine learning is the idea that there are generic algorithms that can tell you something interesting about a set of data without you having to write any custom code specific to the problem. Instead of writing code, you feed data to the generic algorithm and it builds its own logic based on the data. 8 | 9 | 笔者在这里放了原作者的英文描述,以帮助更好地理解。Machine Learning 即是指能够帮你从数据中寻找到感兴趣的部分而不需要编写特定的问题解决方案的通用算法的集合。通用的算法可以根据你不同的输入数据来自动地构建面向数据集合最优的处理逻辑。举例而言,算法中一个大的分类即分类算法,它可以将数据分类到不同的组合中。而可以用来识别手写数字的算法自然也能用来识别垃圾邮件,只不过对于数据特征的提取方法不同。相同的算法输入不同的数据就能够用来处理不同的分类逻辑。 10 | 11 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-YXiclXZdJQVJZ0tQHCv5zw.png) 12 | 13 | > “Machine learning” is an umbrella term covering lots of these kinds of generic algorithms. 14 | 15 | ## Two kinds of Machine Learning Algorithms: 两类机器学习算法 16 | 17 | 粗浅的划分,可以认为机器学习攘括的算法主要分为有监督学习与无监督学习,概念不难,但是很重要。 18 | 19 | ### Supervised Learning: 有监督学习 20 | 21 | 假设你是一位成功的房地产中介,你的事业正在蒸蒸日上,现在打算雇佣更多的中介来帮你一起工作。不过问题来了,你可以一眼看出某个房子到底估值集合,而你的实习生们可没你这个本事。为了帮你的实习生尽快适应这份工作,你打算写个小的 APP 来帮他们根据房子的尺寸、邻居以及之前卖的类似的屋子的价格来评估这个屋子值多少钱。因此你翻阅了之前的资料,总结成了下表: 22 | 23 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-ZWYX9nwsDFaNOW4jOrHDkQ.png) 24 | 25 | 利用这些数据,我们希望最后的程序能够帮我们自动预测一个新的屋子大概能卖到多少钱: 26 | 27 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-V0OXzLOPtpU13MVVrlZJjA.png) 28 | 29 | 解决这个问题的算法呢就是叫做监督学习,你已知一些历史数据,可以在这些历史数据的基础上构造出大概的处理逻辑。在将这些训练数据用于算法训练之后,通用的算法可以根据这个具体的场景得出最优的参数,有点像下面这张图里描述的一个简单的智力题: 30 | 31 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-SihYXaJQS3T6tOwqJ6fzPw.png) 32 | 33 | 这个例子里,你能够知道根据左边的数字的不同推导出不同的右边的数字,那么你脑子里就自然而然生成了一个处理该问题的具体的逻辑。在监督学习里,你则是让机器帮你推导出这种关系,一旦知道了处理特定系列问题的数学方法,其他类似的问题也就都能迎刃而解。 34 | 35 | ### Unsupervised Learning: 无监督学习 36 | 37 | 我们再回到最初的那个问题,如果你现在不知道每个房间的售价,而只知道房间大小、尺寸以及临近的地方,那咋办呢?这个时候,就是无监督学习派上用场的时候了。 38 | 39 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-mUJw2yL4-OBI25xUKS7_Bg.png) 40 | 41 | 这种问题有点类似于某人给了你一长串的数字然后跟你说,我不知道每个数字到底啥意思,不过你看看能不能通过某种模式或者分类或者啥玩意找出它们之间是不是有啥关系。那么对于你的实习生来说,这种类型的数据有啥意义呢?你虽然不能知道每个屋子的价格,但是你可以把这些屋子划分到不同的市场区间里,然后你大概能发现购买靠近大学城旁边的屋子的人们更喜欢更多的小卧室户型,而靠近城郊的更喜欢三个左右的卧室。知道不同地方的购买者的喜好可以帮助你进行更精确的市场定位。另外你也可以利用无监督学习发现些特殊的房产,譬如一栋大厦,和其他你售卖的屋子差别很大,销售策略也不同,不过呢却能让你收获更多的佣金。本文下面会更多的关注于有监督学习,不过千万不能觉得无监督学习就无关紧要了。实际上,在大数据时代,无监督学习反而越来越重要,因为它不需要标注很多的测试数据。 42 | 43 | > 这里的算法分类还是很粗浅的,如果要了解更多的细致的分类可以参考: 44 | 45 | - [维基百科](https://en.wikipedia.org/wiki/Machine_learning#Algorithm_types) 46 | > 47 | - [笔者的数据科学与机器学习算法分类](https://github.com/wx-chevalier/datascience-practice-handbook/blob/master/datascience-machinelearning-algorithms.md) 48 | 49 | # House Price Estimation With Supervised Learning: 利用监督学习进行房屋价格估计 50 | 51 | 作为高等智慧生物,人类可以自动地从环境与经历中进行学习,所谓熟读唐诗三百首,不会做诗也会吟,你房子卖多了那自然而然看到了某个屋子也就能知道价格以及该卖给啥样的人了。这个 [Strong_AI](https://en.wikipedia.org/wiki/Strong_AI) 项目也就是希望能够将人类的这种能力复制到计算机上。不过目前的机器学习算法还没这么智能,它们只能面向一些特定的有一定限制的问题。因此,`Learning`这个概念,在这里更应该描述为 : 基于某些测试数据找出解决某个问题的等式,笔者也喜欢描述为对于数据的非线性拟合。希望五十年后看到这篇文章的人,能够推翻这个论述。 52 | 53 | ## Let's Write the Program 54 | 55 | 基本的思想很好理解,下面就开始简单的实战咯。这里假设你还没写过任何机器学习的算法,那么直观的来说,我们可以编写一些简单的条件判断语句来进行房屋价格预测,譬如: 56 | 57 | ```py 58 | def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood): 59 | price = 0 60 | # 俺们这嘎达,房子基本上每平方200 61 | price_per_sqft = 200 62 | if neighborhood == "hipsterton": 63 | # 市中心会贵一点 64 | price_per_sqft = 400 65 | elif neighborhood == "skid row": 66 | # 郊区便宜点 67 | price_per_sqft = 100 68 | # 可以根据单价*房子大小得出一个基本价格 69 | price = price_per_sqft * sqft 70 | # 基于房间数做点调整 71 | if num_of_bedrooms == 0: 72 | # 没房间的便宜点 73 | price = price — 20000 74 | else: 75 | # 房间越多一般越值钱 76 | price = price + (num_of_bedrooms * 1000) 77 | return price 78 | ``` 79 | 80 | 这就是典型的简答的基于经验的条件式判断,你也能通过这种方法得出一个较好地模型。不过如果数据多了或者价格发生较大波动的时候,你就有心无力了。而应用机器学习算法则是让计算机去帮你总结出这个规律,大概如下所示: 81 | 82 | ```py 83 | def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood): 84 | price = 85 | return price 86 | ``` 87 | 88 | 通俗的理解,价格好比一锅炖汤,而卧室的数量、客厅面积以及邻近的街区就是食材,计算机帮你自动地根据不同的食材炖出不同的汤来。如果你是喜欢数学的,那就好比有三个自变量的方程,代码表述的话大概是下面这个样子: 89 | 90 | ```py 91 | def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood): 92 | price = 0 93 | # a little pinch of this 94 | price += num_of_bedrooms * .841231951398213 95 | # and a big pinch of that 96 | price += sqft * 1231.1231231 97 | # maybe a handful of this 98 | price += neighborhood * 2.3242341421 99 | # and finally, just a little extra salt for good measure 100 | price += 201.23432095 101 | return price 102 | ``` 103 | 104 | 注意,上面那些譬如 `.841...` 这样奇怪的数据,它们就是被称为 `权重`,只要我们能根据数据寻找出最合适的权重,那我们的函数就能较好地预测出房屋的价格。 105 | 106 | ## Weights 107 | 108 | 首先,我们用一个比较机械式的方法来寻找最佳的权重。 109 | 110 | ### Step 1 111 | 112 | 首先将所有的权重设置为 1: 113 | 114 | ```py 115 | def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood): 116 | price = 0 117 | # a little pinch of this 118 | price += num_of_bedrooms * 1.0 119 | # and a big pinch of that 120 | price += sqft * 1.0 121 | # maybe a handful of this 122 | price += neighborhood * 1.0 123 | # and finally, just a little extra salt for good measure 124 | price += 1.0 125 | return price 126 | ``` 127 | 128 | ### Step 2 129 | 130 | 拿已知的数据来跑一波,看看预测出来的值和真实值之间有多少差距,大概效果如下所示: 131 | 132 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-Dih1jJrDpqF0NJsWkA1qgw.png) 133 | 134 | 咳咳,可以看出这个差距还是很大的啊,不过不要担心,获取正确的权重参数的过程漫漫,我们慢慢来。我们将每一行的真实价格与预测价格的差价相加再除以总的屋子的数量得到一个差价的平均值,即将这个平均值称为 `cost`,即所谓的代价函数。最理想的状态就是将这个代价值归零,不过基本上不太可能。因此,我们的目标就是通过不断的迭代使得代价值不断地逼近零。 135 | 136 | ### Step 3 137 | 138 | 不断测试不同的权重的组合,从而找出其中最靠近零的一组。## Mind Blowage Time 很简单,不是吗?让我们再回顾下你刚才做了啥,拿了一些数据,通过三个泛化的简单的步骤获取一个预测值,不过在进一步优化之前,我们先来讨论一些小小的思考: 139 | 140 | - 过去 40 年来,包括语言学、翻译等等在内的很多领域都证明了通用的学习算法也能表现出色,尽管这些算法本身看上去毫无意义。 141 | - 刚才咱写的那个函数也是所谓的无声的,即函数中,并不知道卧室数目 bedrooms、客厅大小 square_feet 这些变量到底是啥意思,它只知道输入某些数字然后得出一个值。这一点就很明显地和那些面向特定的业务逻辑的处理程序有很大区别。 142 | - 估计你是猜不到哪些权重才是最合适的,或许你连自己为啥要这么写函数都不能理解,虽然你能证明这么写就是有用的。 143 | - 如果我们把参数`sqft`改成了图片中的像素的敏感度,那么原来输出的值是所谓的价格,而现在的值就是所谓的图片的类型,输入的不同,输出值的意义也就可以不一样。 144 | 145 | ## Try every number? 146 | 147 | 言归正传,我们还是回到寻找最优的权重组合上来。你可以选择去带入所有的可能的权重组合,很明显是无穷大的一个组合,这条路肯定是行不通的。是时候展示一波数学的魅力了,这里我们介绍一个数学中常见的优化求值的方法:首先,我们将 Step 2 中提出的代价方程公式化为如下形式: 148 | 149 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-4j82aAIUGQKKUmKcHLMWJQ.png) 150 | 151 | 然后,我们将这个代价方程变得更加通用一点: ![](http://7u2q25.com1.z0.glb.clouddn.com/1-ZyboMOVQ5zOv0ZTC4a3usA.png) 这个方程就代表了我们目前的权重组合离真实的权重组合的差距,如果我们测试多组数据,那么大概可以得出如下的数据图: 152 | 153 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-uorFgyflbSMtvfSo9hlI1A.png) 154 | 155 | 图中的蓝色低点即意味着代价最小,也就是权重组合最接近完美值的时候。 156 | 157 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-prsH6EfJmFqdmFElj1Ht8g.png) 158 | 159 | 有了图之后是不是感觉形象多了?我们寻找最优权重的过程就是一步一步走到谷底的过程,如果我们每次小小地修改权重而使得其不断向谷底靠近,我们也就在向结果靠近。如果你还记得微积分的一些知识,应该知道函数的导数代表着函数的切线方向,换言之,在图中的任何一点我们通过计算函数的导数就知道变化的方向,即梯度下降的方向。我们可以计算出代价函数中每个变量的偏导数然后将每个当前变量值减去该偏导数,即按照梯度相反的方向前进,那就可以逐步解决谷底咯。如果你感兴趣的话,可以深入看看[批量梯度下降](https://hbfs.wordpress.com/2012/04/24/introduction-to-gradient-descent/)相关的知识。如果你是打算找个机器学习的工具库来辅助工具,那么到这里你的知识储备已经差不多咯,下面我们再扯扯其他的东西。 160 | 161 | ## Something Skip Over: 刚才没提到的一些东西 162 | 163 | 上文提到的所谓三步的算法,用专业的名词表述应该是多元线性回归。即通过输入含有多个自变量的训练数据获得一个有效的计算表达式用于预测未来的部分房屋的价格。但是上面所讲的还是一个非常简单的例子,可能并不能在真实的环境中完美地工作,这时候就会需要下文即将介绍的包括神经网络、SVM 等等更复杂一点的算法了。另外,我还没提到一个概念:overfitting(过拟合)。在很多情况下,只要有充足的时间我们都能得到一组在训练数据集上工作完美的权重组合,但是一旦它们用于预测,就会跌破眼镜,这就是所谓的过拟合问题。同样的,关于这方面也有很多的方法可以解决,譬如[正则化](http://en.wikipedia.org/wiki/Regularization_%28mathematics%29#Regularization_in_statistics_and_machine_learning) 或者使用 [交叉验证](http://en.wikipedia.org/wiki/Cross-validation_%28statistics%29)。一言以蔽之,尽管基础的概念非常简单,仍然会需要一些技巧或者经验来让整个模型更好地工作,就好像一个才学完 Java 基础的菜鸟和一个十年的老司机一样。 164 | 165 | ## Further Reading | 深入阅读 166 | 167 | 可能看完了这些,觉着 ML 好简单啊,那这么简单的东西又是如何应用到图片识别等等复杂的领域的呢?你可能会觉得可以用机器学习来解决任何问题,只要你有足够多的数据。不过还是要泼点冷水,千万记住,机器学习的算法只在你有足够的解决某个特定的问题的数据的时候才能真正起作用。譬如,如果你想依靠某个屋子内盆栽的数目来预测某个屋子的价格,呵呵。这是因为房屋的价格和里面的盆栽数目没啥必然联系,不管你怎么尝试,输入怎么多的数据,可能都不能如你所愿。 168 | 169 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-N6pxRoVoEoedFELL2HdxbA.png) 170 | 171 | 所以,总结而言,如果是能够手动解决的问题,那计算机可能解决的更快,但是它也无法解决压根解决不了的问题。在原作者看来,目前机器学习存在的一个很大的问题就是依然如阳春白雪般,只是部分科研人员或者商业分析人员的关注对象,其他人并不能简单地理解或者使用,在本节的最后也推荐一些公开的课程给对机器学习有兴趣的朋友: 172 | 173 | - [Machine Learning class on Coursera](https://www.coursera.org/course/ml) 174 | 175 | - [scikit-learn](http://scikit-learn.org/stable/) 176 | 177 | # Neural Network: 神经网络 178 | 179 | 上文中,我们通过一个简单的房价预测的例子了解了机器学习的基本含义,在本节,我们将会继续用一些泛化的算法搭配上一些特定的数据做些有趣的事情。本节的例子大概如下图所示,一个很多人的童年必备的游戏:马里奥,让我们用神经网络帮你设计一些新奇的关卡吧。 180 | 181 | 在正文之前,还是要强调下,本文是面向所有对机器学习有兴趣的朋友,所以大牛们看到了勿笑。 182 | 183 | ## Introduction To Neural Networks: 神经网络模型初探 184 | 185 | 上文中我们是使用了多元线性回归来进行房屋价格预测,数据格式大概这个样子: 186 | 187 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-tzN3MZMnGMjAX59GGnsPMQ.png) 188 | 189 | 最后得到的函数是: 190 | 191 | ```py 192 | def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood): 193 | price = 0 194 | # a little pinch of this 195 | price += num_of_bedrooms * 0.123 196 | # and a big pinch of that 197 | price += sqft * 0.41 198 | # maybe a handful of this 199 | price += neighborhood * 0.57 200 | return price 201 | ``` 202 | 203 | 如果用图来表示的话,大概是这个样子 204 | 205 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-LlTIwE6h0l1Aoln2GlAGcw.png) 206 | 207 | 不过正如上文中提到的,这个算法只能处理一些较为简单的问题,即结果与输入的变量之间存在着某些线性关系。Too young,Too Simple, 真实的房价和这些可不仅仅只有简单的线性关系,譬如邻近的街区这个因子可能对面积较大和面积特别小的房子有影响,但是对于那些中等大小的毫无关系,换言之,price 与 neighborhood 之间并不是线性关联,而是类似于二次函数或者抛物线函数图之间的非线性关联。这种情况下,我们可能得到不同的权重值(形象来理解,可能部分权重值是收敛到某个局部最优): 208 | 209 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-hOemQF_v42KHlMyiqcQNyQ.png) 210 | 211 | 现在等于每次预测我们有了四个独立的预测值,下一步就是需要将四个值合并为一个最终的输出值: 212 | 213 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-VeS0ziSjogCQThPYZh0TIQ.png) 214 | 215 | ### What is Neural Network?: 神经网络初识 216 | 217 | 我们将上文提到的两个步骤合并起来,大概如下图所示: 218 | 219 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-Lt8RZaeQ6f6B_eA1oD32JQ.png) 220 | 221 | 咳咳,没错,这就是一个典型的神经网络,每个节点接收一系列的输入,为每个输入分配权重,然后计算输出值。通过连接这一系列的节点,我们就能够为复杂的函数建模。同样为了简单起见,我在这里也跳过了很多概念,譬如 [feature scaling](https://en.wikipedia.org/wiki/Feature_scaling) 以及 [activation function](https://en.wikipedia.org/wiki/Activation_function),不过核心的概念是: 222 | 223 | - 每个能够接收一系列的输入并且能够按权重求和的估值函数被称为 Neuron( 神经元 ) 224 | - 多个简单的神经元的连接可以用来构造处理复杂问题的模型 225 | 226 | 有点像乐高方块,单个的乐高方块非常简单,而大量的乐高方块却可以构建出任何形状的物体: 227 | 228 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-AcWzHbgnmiMYyv1_IXcY0w.png) 229 | 230 | ### Giving Our Neural Network a Memory: 给神经网络加点上下文 231 | 232 | 目前,整个神经网络是无状态的,即对于任何相同的输入都返回相同的输出。这个特性在很多情况下,譬如房屋价格估计中是不错的,不过这种模式并不能处理时间序列的数据。举个栗子,我们常用的输入法中有个智能联想的功能,可以根据用户输入的前几个字符预测下一个可能的输入字符。最简单的,可以根据常见的语法来推测下一个出现的字符,而我们也可以根据用户历史输入的记录来推测下一个出现的字符。基于这些考虑,我们的神经网络模型即如下所示: 233 | 234 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-e2YPupJVOiZj4B_nGZi5pQ.png) 235 | 236 | 譬如用户已经输入了如下的语句: 237 | 238 | ``` 239 | Robert Cohn was once middleweight boxi 240 | ``` 241 | 242 | 你可能会猜想是`n`,这样整个词汇就是`boxing`,这是基于你看过了前面的语句以及基本的英文语法得出的推论,另外,`middleweight`这个单词也给了我们额外的提示,跟在它后面的是`boxing`。换言之,在文本预测中,如果你能将句子的上下文也考虑进来,再加上基本的语法知识就能较为准确地预测出下一个可能的字符。因此,我们需要给上面描述的神经网络模型添加一些状态信息,也就是所谓的上下文的信息: 243 | 244 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-dcdVATcm0yJQxr4jGG5bFA.png) 245 | 246 | 在神经网络模型中也保持了对于上下文的追踪,从而使得该模型不仅仅能预测第一个词是啥,也能预测最有可能出现的下一个词汇。该模型就是所谓的 Recurrent Neural Network: 循环神经网络的基本概念。每次使用神经网络的同时也在更新其参数,也就保证了能够根据最新的输入内容预测下一个可能的字符,只要有足够的内存情况下,它可以将完整的时序上下文全部考虑进去。 247 | 248 | ### Generating a story: 生成一个完整的故事 249 | 250 | 正如上文所说,文本预测在实际应用中一个典型的例子就是输入法,譬如 iPhone 里面会根据你之前输入的字符自动帮你补全: 251 | 252 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-pmDVDfrT9au3YwNiiO0FwQ.png) 253 | 254 | 不过我们做的更疯狂一点,既然模型可以根据上一个字符自动预测下一个字符,那我们何不让模型来自动构建一个完整的故事?我们在这里使用[Andrej Karpathy](http://karpathy.github.io/about/)创建的[Recurrent Neural Network implementation](https://github.com/karpathy/char-rnn)框架来进行实验,他也发表了一系列[关于如何使用 RNN 进行文档生成的博客](http://karpathy.github.io/2015/05/21/rnn-effectiveness/)。我们还是使用 `The Sun Also Rises` 这篇文章,该文章包括大小写、标点符号等在内一共有 84 个不同的字符以及 362239 个词汇。这个数据集合的大小和真实环境中的应用文本相比还是很小的,为了尽可能模仿原作者的风格,最好的是能有数倍的文本进行训练,不过作为例子这边还是足够的。经过大概 100 次迭代之后,得到的结果是: 255 | 256 | ``` 257 | hjCTCnhoofeoxelif edElobe negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe. 258 | Ddelnss.eelaishaner” cot AAfhB ht ltny 259 | ehbih a”on bhnte ectrsnae abeahngy 260 | amo k ns aeo?cdse nh a taei.rairrhelardr er deffijha 261 | ``` 262 | 263 | 惨不忍睹啊,继续进行训练,大概 1000 次迭代之后,内容看起来好一点了: 264 | 265 | ``` 266 | hing soor ither. And the caraos, and the crowebel for figttier and ale the room of me? Streat was not to him Bill-stook of the momansbed mig out ust on the bull, out here. I been soms 267 | inick stalling that aid. 268 | “Hon’t me and acrained on .Hw’s don’t you for the roed,” In’s pair.” 269 | “Alough marith him.” 270 | ``` 271 | 272 | 已经能够识别基本的句型结构与语法规则咯,甚至能够较好地为上下文添加标点符号了,不过还是存在着大量的无意义词汇,我们继续增加训练的次数: 273 | 274 | ``` 275 | He went over to the gate of the café. It was like a country bed. 276 | “Do you know it’s been me.” 277 | “Damned us,” Bill said. 278 | “I was dangerous,” I said. “You were she did it and think I would a fine cape you,” I said. 279 | “I can’t look strange in the cab.” 280 | “You know I was this is though,” Brett said. 281 | “It’s a fights no matter?” 282 | “It makes to do it.” 283 | “You make it?” 284 | “Sit down,” I said. “I wish I wasn’t do a little with the man.” 285 | “You found it.” 286 | “I don’t know.” 287 | “You see, I’m sorry of chatches,” Bill said. “You think it’s a friend off back and make you really drunk.” 288 | ``` 289 | 290 | 现在差不多能看了,有些句式还是很模仿 Hemingway’s 的风格的,而原作者的内容是: 291 | 292 | ``` 293 | There were a few people inside at the bar, and outside, alone, sat Harvey Stone. He had a pile of saucers in front of him, and he needed a shave. 294 | “Sit down,” said Harvey, “I’ve been looking for you.” 295 | “What’s the matter?” 296 | “Nothing. Just looking for you.” 297 | “Been out to the races?” 298 | “No. Not since Sunday.” 299 | “What do you hear from the States?” 300 | “Nothing. Absolutely nothing.” 301 | “What’s the matter?” 302 | ``` 303 | 304 | ## Super Mario: 利用神经网络进行 Mario 过关训练 305 | 306 | In 2015, Nintendo 宣布了 [Super Mario Maker™](http://supermariomaker.nintendo.com/) 用于 Wii U 游戏系统上。 307 | 308 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-F5j2M7usF53vF4stTO0Tsw.png) 309 | 310 | 这个制作器能够让你去手动制作马里奥的一些关卡,很不错的和朋友之间进行互动的小工具。你可以添加常见的障碍物或者敌人到你自己设计的关卡中,有点像可视化的乐高工作台。我们可以使用刚才创建的用于预测 Hemingway 文本的模型来自动地创建一个超级马里奥的关卡。首先呢,我们还是需要去找一些训练数据,最早的 1985 年推出的经典的超级马里奥的游戏不错: 311 | 312 | 这个游戏有大概 32 个关卡,其中 70% 的场景都有相似的外观,很适合用来做训练数据啊。我找来了每一关的设计方案,网上有很多类似的教程教你怎么从内存中读取游戏的设计方案,有兴趣的话你也可以试试。下面呢就是一个经典的全景视图: 313 | 314 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-cZddr0SxPVnr3RU9Kx2fQQ.gif) 315 | 316 | 用放大镜观察的话,可以看出每一关都是由一系列的网格状对象组成的: 317 | 318 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-c8wiw6UsCLuJ2KJE2rTxLQ.png) 319 | 320 | 这样的话,我们可以将每个网格中的对象用一个字符代替,而整个关卡的字符化表述就是: 321 | 322 | ``` 323 | -------------------------- 324 | -------------------------- 325 | -------------------------- 326 | #??#---------------------- 327 | -------------------------- 328 | -------------------------- 329 | -------------------------- 330 | -##------=--=----------==- 331 | --------==--==--------===- 332 | -------===--===------====- 333 | ------====--====----=====- 334 | =========================- 335 | ``` 336 | 337 | 其中: 338 | 339 | - `-` 代表空白 340 | - `=` 代表坚固的方块 341 | - `#` 代表那些可以被撞破的块 342 | - `?` 代表钱币块 343 | 344 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-D9hjauyOBy9xGPFOiKCZuA.png) 345 | 346 | 仔细瞅瞅这个文件,你会发现如果按照一行一行从左到右读的话,好像是毫无头绪: 347 | 348 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-3Anjg6hI_iGkK1GAR8tQug.png) 349 | 350 | 不过如果按照列的次序从上往下读的话,你会发现还是有点套路的: 351 | 352 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-Y-Awqi55np9Ynxz-da73DQ.png) 353 | 354 | 为了更好地训练数据,我们打算按列来分割数据,这里我们会使用[特征选择](https://en.wikipedia.org/wiki/Feature_selection)的技术来将数据转化为最合适的表示。首先,我们将整个文本旋转 90 度: 355 | 356 | ```-----------= 357 | -------#---= 358 | -------#---= 359 | -------?---= 360 | -------#---= 361 | -----------= 362 | -----------= 363 | ----------@= 364 | ----------@= 365 | -----------= 366 | -----------= 367 | -----------= 368 | ---------PP= 369 | ---------PP= 370 | ----------== 371 | ---------=== 372 | --------==== 373 | -------===== 374 | ------====== 375 | -----======= 376 | ---========= 377 | ---========= 378 | ``` 379 | 380 | 然后就可以使用上面创建好的模型进行训练咯,经过几轮训练之后大概可以得出这个样子: 381 | 382 | ```-------------------------- 383 | LL+<&=------P------------- 384 | -------- 385 | ---------------------T--#-- 386 | ----- 387 | -=--=-=------------=-&--T-------------- 388 | -------------------- 389 | --=------$-=#-=-_ 390 | --------------=----=<---- 391 | -------b 392 | - 393 | ``` 394 | 395 | 最初的训练里模型认知到应该大量的出现`-`与`=`字符,不过还是很粗糙,再经过几千次的训练,得出的内容是: 396 | 397 | ```-- 398 | -----------= 399 | ----------= 400 | --------PP= 401 | --------PP= 402 | -----------= 403 | -----------= 404 | -----------= 405 | -------?---= 406 | -----------= 407 | -----------= 408 | ``` 409 | 410 | 此时模型已经能够认知到需要将每行保证相同的长度,甚至开始寻找出 Mario 内在的规律:管道呢一般都是两个块这么宽,所以它将所有的`P`都放到了 2\*2 的矩阵中,聪明了一点啊。继续学习: 411 | 412 | ``` 413 | --------PP= 414 | --------PP= 415 | ----------= 416 | ----------= 417 | ----------= 418 | ---PPP=---= 419 | ---PPP=---= 420 | ----------= 421 | ``` 422 | 423 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-MSFyG2WgN_TdFPuQRIeOFA.png) 424 | 425 | 看上去像模像样了,其中有几个需要特别注意的地方: 426 | 427 | - Lakitu,就是那个小怪兽被放到了半空中,跟 Mario 关卡一样一样的。 428 | - 它认知到了应该把管道插入大地 429 | - 并没有让玩家无路可走 430 | - 看起来风格非常像最传统的马里奥的版本 431 | 432 | 最后生成出来的游戏截图大概是这样的: 433 | 434 | ![](http://7u2q25.com1.z0.glb.clouddn.com/1-jrm6nO8BbKNUjOFWsITcxg.jpeg) 435 | 436 | 你可以在[这里](https://youtu.be/_-Gc6diodcY)观看完整的游戏视频。 437 | 438 | ## Toys VS Real World Applications 439 | 440 | 这里用于训练模型的循环神经网络算法与真实环境下大公司用于解决语音识别以及文本翻译等常见问题的算法一本同源,而让我们的模型看上去好像个玩具一样的原因在于我们的训练数据。仅仅取自最早期的超级马里奥的一些关卡数据远远不足以让我们的模型出类拔萃。如果我们能够获取由其他玩家创建的成百上千的关卡信息,我们可以让模型变得更加完善。不过可惜的是我们压根获取不到这些数据。随着机器学习在不同的产业中变得日渐重要,好的程序与坏的程序之间的差异越发体现在输入数据的多少。这也就是为啥像 Google 或者 Facebook 这样的大公司千方百计地想获取你的数据。譬如 Google 最近开源的[TensorFlow](https://www.tensorflow.org/),一个用于大规模可扩展的机器学习的集群搭建应用,它本身就是 Google 内部集群的重要组成部分。不过没有 Google 的海量数据作为辅助,你压根创建不了媲美于 Google 翻译那样的牛逼程序。下次你再打开 [Google Maps Location History](https://maps.google.com/locationhistory/b/0) 或者 [Facebook Location History](https://www.facebook.com/help/1026190460827516),想想它们是不是记录下你日常的东西。 441 | 442 | ## Further Reading 443 | 444 | 条条大道通罗马,在机器学习中解决问题的办法也永远不止一个。你可以有很多的选项来决定如何进行数据预处理以及应该用啥算法。[增强学习](https://en.wikipedia.org/wiki/Ensemble_learning)正是可以帮你将多个单一的方法组合起来的好途径。如果你想更深入的了解,你可以参考下面几篇较为专业的论文: 445 | 446 | - [Amy K. Hoover](http://amykhoover.com/)’s team used an approach that [represents each type of level object (pipes, ground, platforms, etc) as if it were single voice in an overall symphony](http://julian.togelius.com/Hoover2015Composing.pdf). Using a process called functional scaffolding, the system can augment levels with blocks of any given object type. For example, you could sketch out the basic shape of a level and it could add in pipes and question blocks to complete your design. 447 | 448 | - [Steve Dahlskog](http://forskning.mah.se/en/id/tsstda)’s team showed that modeling each column of level data as a series of n-gram “words” [makes it possible to generate levels with a much simpler algorithm](http://julian.togelius.com/Dahlskog2014Linear.pdf) than a large RNN. 449 | 450 | # Object Recognition In Images With Deep Learning: 利用深度学习对于图片中对象进行识别 451 | 452 | 近年来关于深度学习的讨论非常火爆,特别是之前阿尔法狗大战李世乭之后,更是引发了人们广泛地兴趣。南大的周志华教授在《机器学习》这本书的引言里,提到了他对于深度学习的看法:深度学习掀起的热潮也许大过它本身真正的贡献,在理论和技术上并没有太大的创新,只不过是由于硬件技术的革命,从而得到比过去更精细的结果。相信读者看完了第三部分也会有所感。仁者见仁智者见智,这一章节就让我们一起揭开深度学习的神秘面纱。在本章中,我们还是基于一个实际的例子来介绍下深度学习的大概原理,这里我们会使用简单的卷积神经网络来进行图片中的对象识别。换言之,就类似于 Google Photos 的以图搜图的简单实现,大概最终的产品功能是这个样子的: 453 | 454 | ![](http://7xi5sw.com1.z0.glb.clouddn.com/1-F-6upZSC6GMMTP9yHeuwDg.gif) 455 | 456 | 就像前两章一样,本节的内容尽量做到即不云山雾罩,不知所云,也不阳春白雪,曲高和寡,希望每个队机器学习感兴趣的人都能有所收获。这里我们不会提到太多的数学原理与实现细节,所以也不能眼高手低,觉得深度学习不过尔尔呦。 457 | 458 | ## Recognizing Objects: 对象识别 459 | 460 | 先来看一个有趣的漫画: 461 | 462 | ![](http://7xi5sw.com1.z0.glb.clouddn.com/1-wUZiI2Mg2cncuMWWXIiBgQ.png) 463 | 464 | 这个漫画可能有点夸张了,不过它的灵感还是来自于一个现实的问题:一个三岁的小孩能够轻易的辨别出照片中的鸟儿,而最优秀的计算机科学家需要用 50 年的时间来教会机器去识别鸟儿。在过去的数年中,我们发现了一个对象识别的好办法,即是利用深度卷积神经网络。有点像 William Gibson 的科幻小说哈,不过只要跟着本文一步一步来,你就会发现这事一点也不神秘。Talk is cheap, Show you the word~ 465 | 466 | ## Starting Simple: 先来点简单的 467 | 468 | 在尝试怎么识别照片中的鸟儿之前,我们先从一些简单的识别开始:怎么识别手写的数字 8。在上一章节,我们了解了神经网络是如何通过链式连接组合大量的简单的 neurons(神经元) 来解决一些复杂的问题。我们创建了一个简单的神经网络来基于床铺数目、房间大小以及邻居的类型来预测某个屋子的可能的价格。 469 | 470 | ![](http://7xi5sw.com1.z0.glb.clouddn.com/1-Lt8RZaeQ6f6B_eA1oD32JQ.png) 471 | 472 | 再重述下机器学习的理念,即是一些通用的,可以根据不同的数据来处理不同的问题的算法。因此我们可以简单地修改一些神经网络就可以识别手写文字,在这里简单起见,我们只考虑一个字符:手写的数字 8。大量的数据是机器学习不可代替的前提条件与基石,首先我们需要去寻找很多的训练数据。索性对于这个问题的研究已持续了很久,也有很多的开源数据集合,譬如[MNIST 关于手写数字的数据集](http://yann.lecun.com/exdb/mnist/)。MNIST 提供了 60000 张不同的关于手写数字的图片,每个都是 `18*18` 的大小,其中部分关于 8 的大概是这个样子: 473 | 474 | ![](http://7xi5sw.com1.z0.glb.clouddn.com/1-jYKYXkfI4iaE6qg-dEUEcQ.jpeg) 475 | 476 | 上章节中构造的神经网络有三个输入,在这里我们希望用神经网络来处理图片,第二步就是需要将一张图片转化为数字的组合,即是计算机可以处理的样子。表担心,这一步还是很简单的。对于电脑而言,一张图片就是一个多维的整型数组,每个元素代表了每个像素的模糊度,大概是这样子: ![](http://7xi5sw.com1.z0.glb.clouddn.com/1-zY1qFB9aFfZz66YxxoI2aw.gif) 为了能够将图片应用到我们的神经网络模型中,我们需要将 `18*18` 像素的图片转化为 324 个数字: 477 | 478 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-UDgDe_-GMs4QQbT8UopoGA.png) 479 | 480 | 这次的共有 324 个输入,我们需要将神经网络扩大化转化为 324 个输入的模型: 481 | 482 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-b31hqXiBUjIXo2HSn_grFw.png) 483 | 484 | 注意,我们的神经网络模型中有两个输出,第一个输出预测该图片是 8 的概率,第二个输出是预测图片不是 8 的概率。对于要辨别的图片,我们可以使用神经网络将对象划分到不同的群组中。虽然这次我们的神经网络比上次大那么多,但是现代的电脑仍然可以在眨眼间处理上百个节点,甚至于能够在你的手机上工作。( PS: TensorFlow 最近支持 iOS 了)在训练的时候,当我们输入一张确定是 8 的图片的时候,会告诉它概率是 100%,不是 8 的时候输入的概率就是 0%。我们部分的训练数据如下所示: 485 | 486 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-vEVQDKp9MgZkVPK4M70EhA.jpeg) 487 | 488 | ### Tunnel Vision 489 | 490 | 虽然我们上面一直说这个任务不难,不过也没那么简单。首先,我们的识别器能够对于标准的图片,就是那些数字端端正正坐在中间,不歪不扭的图片,可以非常高效准确地识别,譬如: 491 | 492 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-5ciREAL7xdyXcD-cSRP7Jw.png) 493 | 494 | 不过实际情况总不会如我们所愿,当那些熊孩子一般的 8 也混进来的时候,我们的识别器就懵逼了。 495 | 496 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-b5jMTAiyVhOIB9hheXhMmA.png) 497 | 498 | #### Searching with a Sliding Window: 基于滑动窗口的搜索 499 | 500 | 虽然道路很曲折,但是问题还是要解决的,我们先来试试暴力搜索法。我们已经创建了一个可以识别端端正正的 8 的识别器,我们的第一个思路就是把图片分为一块块地小区域,然后对每个区域进行识别,判断是否属于 8,大概思路如下所示: 501 | 502 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-bGBijVuJnTRj8025et0mcQ.gif) 503 | 504 | 这方法叫滑动窗口法,典型的暴力搜索解决方法。在部分特定的情况下能起到较好地作用,不过效率非常低下。譬如对于同一类型但是大小不同的图片,你可能就需要一遍遍地搜索。 505 | 506 | #### More data and a Deep Neural Net 507 | 508 | 刚才那个识别器训练的时候,我们只是把部分规规矩矩的图片作为输入的训练数据。不过如果我们选择更多的训练数据时,自然也包含那些七歪八斜的 8 的图片,会不会起到什么神奇的效果呢?我们甚至不需要去搜集更多的测试数据,只要写个脚本然后把 8 放到图片不同的位置上即可: 509 | 510 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-biD9eS5eB6zXzieonNk-VQ.png) 511 | 512 | 用这种方法,我们可以方便地创建无限的训练数据。数据有了,我们也需要来扩展下我们的神经网络,从而使它能够学习些更复杂的模式。具体而言,我们需要添加更多的中间层: 513 | 514 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-wfmpsoFqWKC7VadjTJxwnQ.png) 515 | 516 | 这个呢,就是我们所谓的`深度神经网络`,因为它比传统的神经网络有更多的中间层。这个概念从十九世纪六十年代以来就有了,不过训练大型的神经网络一直很缓慢而无法达到真实的应用预期。不过近年来随着我们认识到使用 3D 图卡来代替传统的 CPU 处理器来进行神经网络的训练,使用大型的神经网络突然之间就变得不再那么遥不可及。 517 | 518 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-DSbLJ2Ll7Ex0qW-lT5zY8A.png) 519 | 520 | 不过尽管我们可以依靠 3D 图卡解决计算问题,仍然需要寻找合适的解决方案。我们需要寻找合适的将图片处理能够输入神经网络的方法。好好考虑下,我们训练一个网络用来专门识别图片顶部的 8 与训练一个网络专门用来识别图片底部的 8,把这两个网络分割开来,好像压根没啥意义。因此,我们最终要得到的神经网络是要能智能识别无论在图片中哪个位置的 8。 521 | 522 | ## The Solution is Convolution: 卷积神经网络 523 | 524 | 人们在看图片的时候一般都会自带层次分割的眼光,譬如下面这张图: 525 | 526 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-v_06o9d5u4k2lp9cTHQUtg.jpeg) 527 | 528 | 你可以一眼看出图片中的不同的层次: 529 | 530 | - 地上覆盖着草皮与水泥 531 | - 有个宝宝 532 | - 宝宝坐在个木马上 533 | - 木马在草地上 534 | 535 | 更重要的是,不管宝宝坐在啥上面,我们都能一眼看到那嘎达有个宝宝。即使宝宝坐在汽车、飞机上,我们不经过重新的学习也可以一眼分辨出来。可惜现在我们的神经网络还做不到这一点,它会把不同图片里面的 8 当成不同的东西对待,并不能理解如果在图片中移动 8,对于 8 而言是没有任何改变的。也就意味着对于不同位置的图片仍然需要进行重新学习。我们需要赋予我们的神经网络能够理解平移不变性:不管 8 出现在图片的哪个地方,它还是那个 8。我们打算用所谓的卷积的方法来进行处理,这个概念部分来自于计算机科学,部分来自生物学,譬如神经学家教会猫如何去辨别图片。 536 | 537 | ### How Convolution Works 538 | 539 | 上面我们提到一个暴力破解的办法是将图片分割到一个又一个的小网格中,我们需要稍微改进下这个办法。 540 | 541 | #### 将图片分割为重叠的砖块 542 | 543 | 譬如上面提到的滑动窗口搜索,我们将原图片分割为独立的小块,大概如下图所示: 544 | 545 | 通过这一步操作,我们将原始图片分割为了 77 张大小相同的小图片。 546 | 547 | #### 将每个图片瓷砖输入到小的神经网络中 548 | 549 | 之前我们就训练一个小的神经网络可以来判断单个图片是否属于 8,不过在这里我们的输出并不是直接判断是不是 8,而是处理输出一个特征数组: 550 | 551 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-84-TdHvtAHkfnzwa1ZsTVg.png) 552 | 553 | 对于不同的图片的瓷砖块,我们都会使用`具有相同权重的神经网络`来进行处理。换言之,我们将不同的图片小块都同等对待,如果在图片里发现了啥好玩的东西,我们会将该图片标识为待进一步观察的。 554 | 555 | #### 将每个小块的处理结果存入一个新的数组 556 | 557 | 对于每个小块输出的数组,我们希望依然保持图片块之间的相对位置关联,因此我们将每个输出的数组仍然按照之前的图片块的次序排布: 558 | 559 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-tpMqyjAFgsYWpvlNkZgFfw.png) 560 | 561 | 到这里,我们输入一个大图片,输出一个相对而言紧密一点的数组,包含了我们可能刚兴趣的块的记录。#### 缩减像素采样上一步的结果是输出一个数组,会映射出原始图片中的哪些部分是我们感兴趣的。不过整个数组还是太大了: 562 | 563 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-1WWTbW9yyEJ69TF1rsPv4g.png) 564 | 565 | 为了缩减该特征数组的大小,我们打算使用所谓的[max pooling](https://en.wikipedia.org/wiki/Convolutional_neural_network#Pooling_layer)算法来缩减像素采样数组的大小,这算法听起来高大上,不过还是挺简单的: 566 | 567 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-xOAroFiw9X0WSkCwgcIO6Q.png) 568 | 569 | Max pooling 处理过程上呢就是将原特征矩阵按照 2\*2 分割为不同的块,然后从每个方块中找出最有兴趣的位保留,然后丢弃其他三个数组。 570 | 571 | #### 进行预测 572 | 573 | 截至目前,一个大图片已经转化为了一个相对较小地数组。该数组中只是一系列的数字,因此我们可以将该小数组作为输入传入另一个神经网络,该神经网络会判断该图片是否符合我们的预期判断。为了区别于上面的卷积步骤,我们将此称为`fully connected`网络,整个步骤呢,如下所示: ![](http://7xiegq.com1.z0.glb.clouddn.com/1-tJ1Rkl5xw_5izEZXmNfh5Q.png) 574 | 575 | #### 添加更多的步骤 576 | 577 | 上面的图片处理过程可以总结为以下步骤: 578 | 579 | - Convolution: 卷积 580 | - Max-pooling: 特征各维最大汇总 581 | - Full-connected: 全连接网络 582 | 583 | 在真实的应用中,这几个步骤可以组合排列使用多次,你可以选择使用两个、三个甚至十个卷积层,也可以在任何时候使用 Max-pooling 来减少数据的大小。基本的思想就是将一个大图片不断地浓缩直到输出一个单一值。使用更多地卷积步骤,你的网络就可以处理学习更多地特征。举例而言,第一个卷积层可以用于识别锐边,第二个卷积层能够识别尖锐物体中的鸟嘴,而第三个卷积层可以基于其对于鸟嘴的知识识别整个鸟。下图就展示一个更现实点地深度卷积网络: 584 | 585 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-JSnKtzEgiHd4p6UlNv_C7w.png) 586 | 587 | 在这个例子中,最早地是输入一个 224\*224 像素的图片,然后分别使用两次卷积与 Max-pooling,然后再依次使用卷积与 Max-pooling,最后使用两个全连接层。最后的结果就是图片被分到哪一类。 588 | 589 | ## Building our Bird Classifier: 构建一个真实的鸟儿分类器 590 | 591 | 概念了解了,下面我们就动手写一个真正的鸟类分类器。同样地,我们需要先收集一些数据。免费的 [CIFAR10 data set](https://www.cs.toronto.edu/~kriz/cifar.html)包含了关于鸟儿的 6000 多张图片以及 52000 张不是鸟类的图片。如果不够,[Caltech-UCSD Birds-200–2011 data set](http://www.vision.caltech.edu/visipedia/CUB-200-2011.html) 中还有 12000 张鸟类的图片。其中关于鸟类的图片大概如下所示: 592 | 593 | 非鸟类的图片大概这样: 594 | 595 | 这边我们会使用[TFLearn](http://tflearn.org/)来构建我们的程序,TFLearn 是对于 Google 的 [TensorFlow](https://www.tensorflow.org/) 深度学习库的一个包裹,提供了更易用的 API,可以让编写卷积神经网络就好像编译我们其他的网络层一样简单: 596 | 597 | ```py 598 | # -*- coding: utf-8 -*- 599 | 600 | """ 601 | Based on the tflearn example located here: 602 | https://github.com/tflearn/tflearn/blob/master/examples/images/convnet_cifar10.py 603 | """ 604 | from __future__ import division, print_function, absolute_import 605 | 606 | 607 | # Import tflearn and some helpers 608 | import tflearn 609 | from tflearn.data_utils import shuffle 610 | from tflearn.layers.core import input_data, dropout, fully_connected 611 | from tflearn.layers.conv import conv_2d, max_pool_2d 612 | from tflearn.layers.estimator import regression 613 | from tflearn.data_preprocessing import ImagePreprocessing 614 | from tflearn.data_augmentation import ImageAugmentation 615 | import pickle 616 | 617 | 618 | # Load the data set 619 | X, Y, X_test, Y_test = pickle.load(open("full_dataset.pkl", "rb")) 620 | 621 | 622 | # Shuffle the data 623 | X, Y = shuffle(X, Y) 624 | 625 | 626 | # Make sure the data is normalized 627 | img_prep = ImagePreprocessing() 628 | img_prep.add_featurewise_zero_center() 629 | img_prep.add_featurewise_stdnorm() 630 | 631 | 632 | # Create extra synthetic training data by flipping, rotating and blurring the 633 | # images on our data set. 634 | img_aug = ImageAugmentation() 635 | img_aug.add_random_flip_leftright() 636 | img_aug.add_random_rotation(max_angle=25.) 637 | img_aug.add_random_blur(sigma_max=3.) 638 | 639 | 640 | # Define our network architecture: 641 | 642 | 643 | # Input is a 32x32 image with 3 color channels (red, green and blue) 644 | network = input_data(shape=[None, 32, 32, 3], 645 | data_preprocessing=img_prep, 646 | data_augmentation=img_aug) 647 | 648 | 649 | # Step 1: Convolution 650 | network = conv_2d(network, 32, 3, activation='relu') 651 | 652 | 653 | # Step 2: Max pooling 654 | network = max_pool_2d(network, 2) 655 | 656 | 657 | # Step 3: Convolution again 658 | network = conv_2d(network, 64, 3, activation='relu') 659 | 660 | 661 | # Step 4: Convolution yet again 662 | network = conv_2d(network, 64, 3, activation='relu') 663 | 664 | 665 | # Step 5: Max pooling again 666 | network = max_pool_2d(network, 2) 667 | 668 | 669 | # Step 6: Fully-connected 512 node neural network 670 | network = fully_connected(network, 512, activation='relu') 671 | 672 | 673 | # Step 7: Dropout - throw away some data randomly during training to prevent over-fitting 674 | network = dropout(network, 0.5) 675 | 676 | 677 | # Step 8: Fully-connected neural network with two outputs (0=isn't a bird, 1=is a bird) to make the final prediction 678 | network = fully_connected(network, 2, activation='softmax') 679 | 680 | 681 | # Tell tflearn how we want to train the network 682 | network = regression(network, optimizer='adam', 683 | loss='categorical_crossentropy', 684 | learning_rate=0.001) 685 | 686 | 687 | # Wrap the network in a model object 688 | model = tflearn.DNN(network, tensorboard_verbose=0, checkpoint_path='bird-classifier.tfl.ckpt') 689 | 690 | 691 | # Train it! We'll do 100 training passes and monitor it as it goes. 692 | model.fit(X, Y, n_epoch=100, shuffle=True, validation_set=(X_test, Y_test), 693 | show_metric=True, batch_size=96, 694 | snapshot_epoch=True, 695 | run_id='bird-classifier') 696 | 697 | 698 | # Save model when training is complete to a file 699 | model.save("bird-classifier.tfl") 700 | print("Network trained and saved as bird-classifier.tfl!") 701 | ``` 702 | 703 | 如果你有足够的 RAM,譬如 Nvidia GeForce GTX 980 Ti 或者更好地硬件设备,大概能在 1 小时内训练结束,如果是普通的电脑,时间要耗费地更久一点。随着一轮一轮地训练,准确度也在不断提高,第一轮中准确率只有 75.4%,十轮之后准确率到 91.7%,在 50 轮之后,可以达到 95.5% 的准确率。 704 | 705 | ### Testing out Network 706 | 707 | 我们可以使用如下脚本进行图片的分类预测: 708 | 709 | ```py 710 | # -*- coding: utf-8 -*- 711 | from __future__ import division, print_function, absolute_import 712 | 713 | import tflearn 714 | from tflearn.layers.core import input_data, dropout, fully_connected 715 | from tflearn.layers.conv import conv_2d, max_pool_2d 716 | from tflearn.layers.estimator import regression 717 | from tflearn.data_preprocessing import ImagePreprocessing 718 | from tflearn.data_augmentation import ImageAugmentation 719 | import scipy 720 | import numpy as np 721 | import argparse 722 | 723 | 724 | parser = argparse.ArgumentParser(description='Decide if an image is a picture of a bird') 725 | parser.add_argument('image', type=str, help='The image image file to check') 726 | args = parser.parse_args() 727 | 728 | # Same network definition as before 729 | img_prep = ImagePreprocessing() 730 | img_prep.add_featurewise_zero_center() 731 | img_prep.add_featurewise_stdnorm() 732 | img_aug = ImageAugmentation() 733 | img_aug.add_random_flip_leftright() 734 | img_aug.add_random_rotation(max_angle=25.) 735 | img_aug.add_random_blur(sigma_max=3.) 736 | 737 | 738 | network = input_data(shape=[None, 32, 32, 3], 739 | data_preprocessing=img_prep, 740 | data_augmentation=img_aug) 741 | network = conv_2d(network, 32, 3, activation='relu') 742 | network = max_pool_2d(network, 2) 743 | network = conv_2d(network, 64, 3, activation='relu') 744 | network = conv_2d(network, 64, 3, activation='relu') 745 | network = max_pool_2d(network, 2) 746 | network = fully_connected(network, 512, activation='relu') 747 | network = dropout(network, 0.5) 748 | network = fully_connected(network, 2, activation='softmax') 749 | network = regression(network, optimizer='adam', 750 | loss='categorical_crossentropy', 751 | learning_rate=0.001) 752 | 753 | 754 | model = tflearn.DNN(network, tensorboard_verbose=0, checkpoint_path='bird-classifier.tfl.ckpt') 755 | model.load("bird-classifier.tfl.ckpt-50912") 756 | 757 | 758 | # Load the image file 759 | img = scipy.ndimage.imread(args.image, mode="RGB") 760 | 761 | 762 | # Scale it to 32x32 763 | img = scipy.misc.imresize(img, (32, 32), interp="bicubic").astype(np.float32, casting='unsafe') 764 | 765 | 766 | # Predict 767 | prediction = model.predict([img]) 768 | 769 | 770 | # Check the result. 771 | is_bird = np.argmax(prediction[0]) == 1 772 | 773 | 774 | if is_bird: 775 | print("That's a bird!") 776 | else: 777 | print("That's not a bird!") 778 | ``` 779 | 780 | ## How accurate is 95% accurate?: 怎么理解这 95% 的准确率 781 | 782 | 刚才有提到,我们的程序有 95% 的准确度,不过这并不意味着你拿张图片来,就肯定有 95% 的概率进行准确分类。举个栗子,如果我们的训练数据中有 5% 的图片是鸟类而其他 95% 的都不是鸟类,那么就意味着每次预测其实不是鸟类的准确度达到 95%。因此,我们不仅要关注整体的分类的准确度,还需要关注分类正确的数目,以及哪些图片分类失败,为啥失败的。这里我们假设预测结果并不是简单的正确或者错误,而是分到不同的类别中: 783 | 784 | - 首先,我们将正确被标识为鸟类的鸟类图片称为:True Positives 785 | 786 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-iuk7uONvXNfEDwAyED0HIQ.png) 787 | 788 | - 其次,对于标识为鸟类的非鸟类图片称为:True Negatives 789 | 790 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-QZWiJpImtlmohA-6TQPsEg.png) 791 | 792 | - 对于划分为鸟类的非鸟类图片称为:False Positives 793 | 794 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-UcKIK1Mxe29WB9Df1gembQ.png) 795 | 796 | - 对于划分为非鸟类的鸟类图片称为:False Negatives 797 | 798 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-Ac9OnpayukliEJchRKiKFQ.png) 799 | 800 | 最后的值可以用如下矩阵表示: 801 | 802 | ![](http://7xiegq.com1.z0.glb.clouddn.com/1-lgSDQ4-Js3elXBpavIp6FA.png) 803 | 804 | 这种分法的一个现实的意义譬如我们编写一个程序在 MRI 图片中检测癌症,false positives 的结果很明显好于 false negatives。False negatives 意味着那些你告诉他没得癌症但是人家就是癌症的人。这种错误的比例应该着重降低。除此之外,我们还计算[Precision_and_recall](https://en.wikipedia.org/wiki/Precision_and_recall)来衡量整体的准确度: ![](http://7xiegq.com1.z0.glb.clouddn.com/1-T8SURWDvTTEY37yjUvu_pQ.png) 805 | 806 | ## Further Reading 807 | 808 | - [https://segmentfault.com/a/1190000003984727](https://segmentfault.com/a/1190000003984727) 809 | 810 | - [TensorFlow 实战之 K-Means 聚类算法实践](https://segmentfault.com/a/1190000004006924) 811 | 812 | - [TensorFlow 实战之 Scikit Flow 系列指导:Part 2 ](https://segmentfault.com/a/1190000004045926) 813 | 814 | - [TFLearn 的示例](https://github.com/tflearn/tflearn/tree/master/examples#tflearn-examples) 815 | 816 | - [how to use algorithms to train computers how to play Atari games](http://karpathy.github.io/2016/05/31/rl/) next? 817 | -------------------------------------------------------------------------------- /聚类算法/DBSCAN/DBSCAN_Scratch.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "DBSCAN Scratch.ipynb", 7 | "provenance": [] 8 | }, 9 | "kernelspec": { 10 | "name": "python3", 11 | "display_name": "Python 3" 12 | } 13 | }, 14 | "cells": [ 15 | { 16 | "cell_type": "code", 17 | "metadata": { 18 | "id": "cG7P-KKZCxsM" 19 | }, 20 | "source": [ 21 | "!git clone https://github.com/eriklindernoren/ML-From-Scratch\n", 22 | "!mv ./ML-From-Scratch/* ./\n", 23 | "!(python setup.py install)" 24 | ], 25 | "execution_count": null, 26 | "outputs": [] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "metadata": { 31 | "id": "ZYPtymW2Dvlp" 32 | }, 33 | "source": [ 34 | "from __future__ import print_function, division\n", 35 | "import numpy as np\n", 36 | "from mlfromscratch.utils import Plot, euclidean_distance, normalize\n", 37 | "\n", 38 | "class DBSCAN():\n", 39 | " \"\"\"A density based clustering method that expands clusters from \n", 40 | " samples that have more neighbors within a radius specified by eps\n", 41 | " than the value min_samples.\n", 42 | "\n", 43 | " Parameters:\n", 44 | " -----------\n", 45 | " eps: float\n", 46 | " The radius within which samples are considered neighbors\n", 47 | " min_samples: int\n", 48 | " The number of neighbors required for the sample to be a core point. \n", 49 | " \"\"\"\n", 50 | " def __init__(self, eps=1, min_samples=5):\n", 51 | " self.eps = eps\n", 52 | " self.min_samples = min_samples\n", 53 | "\n", 54 | " def _get_neighbors(self, sample_i):\n", 55 | " \"\"\" Return a list of indexes of neighboring samples\n", 56 | " A sample_2 is considered a neighbor of sample_1 if the distance between\n", 57 | " them is smaller than epsilon \"\"\"\n", 58 | " neighbors = []\n", 59 | " idxs = np.arange(len(self.X))\n", 60 | " for i, _sample in enumerate(self.X[idxs != sample_i]):\n", 61 | " distance = euclidean_distance(self.X[sample_i], _sample)\n", 62 | " if distance < self.eps:\n", 63 | " neighbors.append(i)\n", 64 | " return np.array(neighbors)\n", 65 | "\n", 66 | " def _expand_cluster(self, sample_i, neighbors):\n", 67 | " \"\"\" Recursive method which expands the cluster until we have reached the border\n", 68 | " of the dense area (density determined by eps and min_samples) \"\"\"\n", 69 | " cluster = [sample_i]\n", 70 | " # Iterate through neighbors\n", 71 | " for neighbor_i in neighbors:\n", 72 | " if not neighbor_i in self.visited_samples:\n", 73 | " self.visited_samples.append(neighbor_i)\n", 74 | " # Fetch the sample's distant neighbors (neighbors of neighbor)\n", 75 | " self.neighbors[neighbor_i] = self._get_neighbors(neighbor_i)\n", 76 | " # Make sure the neighbor's neighbors are more than min_samples\n", 77 | " # (If this is true the neighbor is a core point)\n", 78 | " if len(self.neighbors[neighbor_i]) >= self.min_samples:\n", 79 | " # Expand the cluster from the neighbor\n", 80 | " expanded_cluster = self._expand_cluster(\n", 81 | " neighbor_i, self.neighbors[neighbor_i])\n", 82 | " # Add expanded cluster to this cluster\n", 83 | " cluster = cluster + expanded_cluster\n", 84 | " else:\n", 85 | " # If the neighbor is not a core point we only add the neighbor point\n", 86 | " cluster.append(neighbor_i)\n", 87 | " return cluster\n", 88 | "\n", 89 | " def _get_cluster_labels(self):\n", 90 | " \"\"\" Return the samples labels as the index of the cluster in which they are\n", 91 | " contained \"\"\"\n", 92 | " # Set default value to number of clusters\n", 93 | " # Will make sure all outliers have same cluster label\n", 94 | " labels = np.full(shape=self.X.shape[0], fill_value=len(self.clusters))\n", 95 | " for cluster_i, cluster in enumerate(self.clusters):\n", 96 | " for sample_i in cluster:\n", 97 | " labels[sample_i] = cluster_i\n", 98 | " return labels\n", 99 | "\n", 100 | " # DBSCAN\n", 101 | " def predict(self, X):\n", 102 | " self.X = X\n", 103 | " self.clusters = []\n", 104 | " self.visited_samples = []\n", 105 | " self.neighbors = {}\n", 106 | " n_samples = np.shape(self.X)[0]\n", 107 | " # Iterate through samples and expand clusters from them\n", 108 | " # if they have more neighbors than self.min_samples\n", 109 | " for sample_i in range(n_samples):\n", 110 | " if sample_i in self.visited_samples:\n", 111 | " continue\n", 112 | " self.neighbors[sample_i] = self._get_neighbors(sample_i)\n", 113 | " if len(self.neighbors[sample_i]) >= self.min_samples:\n", 114 | " # If core point => mark as visited\n", 115 | " self.visited_samples.append(sample_i)\n", 116 | " # Sample has more neighbors than self.min_samples => expand\n", 117 | " # cluster from sample\n", 118 | " new_cluster = self._expand_cluster(\n", 119 | " sample_i, self.neighbors[sample_i])\n", 120 | " # Add cluster to list of clusters\n", 121 | " self.clusters.append(new_cluster)\n", 122 | "\n", 123 | " # Get the resulting cluster labels\n", 124 | " cluster_labels = self._get_cluster_labels()\n", 125 | " return cluster_labels\n" 126 | ], 127 | "execution_count": 44, 128 | "outputs": [] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "metadata": { 133 | "id": "WUt0ts7PGuBl", 134 | "outputId": "a02e20c9-d308-485a-88eb-0a6361d2b278", 135 | "colab": { 136 | "base_uri": "https://localhost:8080/", 137 | "height": 573 138 | } 139 | }, 140 | "source": [ 141 | "import sys\n", 142 | "import os\n", 143 | "import math\n", 144 | "import random\n", 145 | "from sklearn import datasets\n", 146 | "import numpy as np\n", 147 | "\n", 148 | "from mlfromscratch.utils import Plot\n", 149 | "\n", 150 | "# Load the dataset\n", 151 | "X, y = datasets.make_moons(n_samples=300, noise=0.08, shuffle=False)\n", 152 | "\n", 153 | "# Cluster the data using DBSCAN\n", 154 | "clf = DBSCAN(eps=0.17, min_samples=5)\n", 155 | "y_pred = clf.predict(X)\n", 156 | "\n", 157 | "# Project the data onto the 2 primary principal components\n", 158 | "p = Plot()\n", 159 | "p.plot_in_2d(X, y_pred, title=\"DBSCAN\")\n", 160 | "p.plot_in_2d(X, y, title=\"Actual Clustering\")\n" 161 | ], 162 | "execution_count": 45, 163 | "outputs": [ 164 | { 165 | "output_type": "display_data", 166 | "data": { 167 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAEWCAYAAABIVsEJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO2de5xVZbn4v8/MwAzIVcDEC6LmQbSLCWlHJSUUbynndFHDCiF/pFmYlnY9WtbxmGYmeYtjmscks44FHjVQREPNC3hHIpXICygIgoPAMMw8vz/W2sOaPeu+174/389nPjP7Xbdn71n7fdb7XEVVMQzDMIykNJRbAMMwDKM6MQViGIZhpMIUiGEYhpEKUyCGYRhGKkyBGIZhGKkwBWIYhmGkwhSIYRiGkQpTIIYRAxFZKSJbRKRVRDaIyKMicpaINLjbfy0i20Rkk7vPEhE50nP8HiLyvyLytohsFJEXROQMz/beIvIDEXlJRN5zr3eTiIzMk+PXIrJdRIbnjf9ARFRETvGMNblj3c5hGFlhCsQw4nOSqvYH9gIuA74F/Mqz/XJV7QcMAK4H7hSRRnfbrcBr7rFDgC8Ab3mO/QNwMjAZGAh8GFgCTMjtICI7AZ8GNgKf95FvPfBDzzUNo6iYAjGMhKjqRlWdC5wKTBGRD+RtV2A2sDPwPnf4o8CvVfU9Vd2uqk+r6r0AInI0cAwwSVWfdLdvVNVrVdWroD4NbAAuAab4iPZnYBv+ysUwMscUiGGkRFWfAF4HxnnH3RXAF4F/sGOV8RhwrYicJiIj8k51NPCEqr4WcckpwG+B24H9RWRMvkjAfwAXi0ivpO/HMJJiCsQwCmMVzkoD4JsisgHYBPwc+A9V7XC3fRZYhDPB/0NEnhGRj7rbhgCrwy7iKp3xwGxVfQtYgKOkuuGujNYCZxb0rgwjBqZADKMwdsfxPQD8VFUHAX2BscAVInI8gKq+o6rfVtUDccxazwB/EhEB1gHDe566G18AlqnqM+7r24DJASuN7wPfA1oKeF+GEYkpEMNIibuC2B142DuuDi8AjwAn5h+nqm8DPwV2w1m93A8cIiJ7hFzui8A+IvKmiLwJ/AwYCpzgc/77gJeBr6R5X4YRF1MghpEQERkgIp/E8UX8RlWf99lnf+AIYKn7+ici8gE3tLY/cDbwsqquU9X7gfuAP4rImNw+bpjwNBH5V2Bf4BDgIPfnAziO+h5mLJfvARdm+sYNIw9TIIYRn7tEpBUnHPd7OKuAqZ7tF7p5IO8B84GbgV+62/oCf8SJolqBE857sufYzwD3AL/DCdN9AccMdj+O83yOqj6vqm/mfoCrgU+KyM7koaqPAE9k87YNwx+xhlKGYRhGGmwFYhiGYaTCFIhhGIaRClMghmEYRipMgRiGYRipaCq3AKVk6NChOnLkyHKLYRiGUVUsWbLkbVUdlj9eVwpk5MiRLF68uNxiGIZhVBUi8k+/cTNhGYZhGKkoqwJxG+asEZEXArafLiLPicjzbgOfD3u2rXTHnxERW1YYhmGUmHKvQH4NHBey/R/Akar6QeBHwKy87eNV9SBVHVsk+QzDMIwAyuoDUdW/hLXbVNVHPS8fA8KKzRmGYRglpNwrkCR8CbjX81qB+W7v6elBB4nIdBFZLCKL165dW3QhDcMw6oWqUCAiMh5HgXzLM3yEqh4MHA+cIyIf9ztWVWep6lhVHTtsWI8oNKPCWTB7EaePPJuJjadw+sizWTB7UblFMgzDpeIViIh8CLgRp1/0uty4qr7h/l6DU+X0kPJIaBSLBbMXcdX0G1jz6tuoKmtefZurpt9gSsQwKoSKViBuG887gS+o6t894zu5PRUQkZ2AiTjlr40a4qbvzqZt87ZuY22bt3HTd2eXSSLDMLyU1YkuIr8FjgKGisjrwMVALwBVvQG4CKdf9HVO50+2uxFX78NpvgPOe5itqn8u+Rswisra19YlGjcMo7SUOwrrcxHbzwTO9BlfAXy45xFGLTFszyGsefVt33HDMMpPRZuwjPpm2qWTae7bu9tYc9/eTLt0cpkkMgzDiykQo2KZMHkc5806i11GDEVEGDCkP71bevOTL/zCIrIMowIwBWJUNBMmj+O2ldfzrVu/RtuWNlrXb0ockWWhwEatMWf5Mo64eRb7zrySI26exZzly8oihykQoypIG5FlocBGrTFn+TK+u2A+q1pbUWBVayvfXTC/LErEFIhRFaSNyMoqFNhWMUalcMWji9iyfXu3sS3bt3PFo6W/J02BGFVBUORVVERWFqHAtooxKonVra2JxouJKRCjKkgbkZVW8XixhEajkhjev3+i8WJiCsSoCvIjsnYZMZTzZp3FhMnjQo/LIhTYEhqNSuKCw8bRp6l7Cl+fpiYuOCz8u1AM6qqlrVHdTJg8rofCWDB7ETd9dzZrX1vHsD2HMO3Syd32yf0dtk8UxU5ojHoPRu3zaus9LF1/DVu2v0mfpl05cOevMqL/Cb77Tho1GnB8IatbWxnevz8XHDaua7yUiKqW/KLlYuzYsWo90WuHnG/Ca15q7ts71sqkUq5TqvdgVC6vtt7D02t/RIdu7RprlBY+Muw/ApVIqRGRJX6N+8yEZVQtpfJNpDWfxcH8K8bS9dd0Ux4AHbqVpeuvKZNE8TEFYpSdtCGypfRN5BIa53fcwbRLJ3PTd2dnEtJr/hVjy/Y3E41XEqZAjLJSSIhskA9CGqRo+RpZh/RmESVmVDd9mnZNNF5JmAIxykohJhy/CCuAzo7OouVrZG1ysoKRxoE7fxU07z7W3s54hWMKxCgrhZhw8n0TDY09b+es/QlZm5yK6V8xqoOnV+3N7587lPWbd0IV1m/eid8/dyhPr9q73KJFYmG8RlkpNETWG9o7sfEU332y9CcUI6TXLzzZqB+ueHQRq1r34vHX9+o2/trGRWUJzU2CrUCMsuJrhhI49MQxgccEOd1L4U8wk5ORJXOWL2NVgaVJylmZ1xSIUVYmTB7HxCnjQTyDCvNvWejruwhzYvtN7k29m9iyaWtmTvUsTE5WmNGAHVV1gxjY3Bz7HOWqzGuJhEYiipE1ffrIs33NQruMGMptK69PtK9Xvv479+O9dzfT0d7RtV+5k/QscdDIccTNswJXHwC9Ghq4/JjjQs1YQefYrX9/Hp46PRM5wRIJjQwoVlXaJI7pqH29+RotOzV3Ux7gONWvO/fmrtelXg1Y4qCRI8pE1d7ZGVmivdyVecuqQETkJhFZIyIvBGwXEZkpIi+LyHMicrBn2xQRecn9mVI6qeuXNJNfnAk6ie8iyb5Byubdda0smL2oLGXag2TyW1UZtU2c6rlRiqDclXnLvQL5NXBcyPbjgf3cn+nA9QAisjNwMXAocAhwsYgMLqqkRuIQ1rgTdBLHdJBz3W+83+CdfPcFRxmWYzUQ6NAXzBdSZ/hV1c0nShGUuzJvWRWIqv4FWB+yyyTgf9ThMWCQiAwHjgXuU9X1qvoOcB/hisjIgKRRTtede3OsCdrrmAZoaGzo2i9/Un387iW+1/IbFxGfPR3WvrYudDVwbK9TmXnOjb7bo1ZVYdunXTq5e8BADsXMWHXGpFGjuXTCRHZzlUT+bRFHEXjPITi+j0snTCxZ+G+l54HsDrzmef26OxY0bhSRaZdO9nUA+60UFsxexLvr/JfffhN3zoHsPX9uxeLdnmQV1Lp+U+B7ySm9INNRZ0cnd10/D4AZ157ZNZ7vBM+XMWj70keW8/jdSxw5A+JWrP5V/TFp1OiuyX7O8mWpSrR7z1FqKl2BFIyITMcxfzFixIgyS1PdJOmtEfY0HbRiCTMp5a6RJJEvaF+ELqWXrxDzuXvWfd0USJCMl0+5hp984RdIg9DZ0dlj+103zAtUHGHvAaxfSL1QTkWQlkpXIG8Ae3pe7+GOvQEclTf+oN8JVHUWMAucMN5iCFlPxM2aDnuaDkq6i7O6SLIK8tsXgZPOOrbbe7jpu7NDVyJxZMztpx0Bt1jEnRe2kotalRlGuSi3Ez2KucAX3WisjwEbVXU1MA+YKCKDXef5RHfMKAGFRFb137lf4MQXx8eSJJHPb99v3zqj24piwuRxoVnk+fW1sq6SG/UeLOy3vilnlnkcyroCEZHf4qwkhorI6ziRVb0AVPUG4B7gBOBlYDMw1d22XkR+BDzpnuoSVQ1zxhsZEfeJOGilcM7MaYHnPvTEMV1+h/xxL0lqR4Xtu2D2Iq6dcVOor+TE6cd0e+27qolC8F2B+CVK5mP9QuqXXJb5lu3bgR1Z5otXvcHClSvK3s4WLBPdiCDf/r5l01bfCddvMvQe22/wTogIres3Bdrxk2SkZ/G+ohTBSWcf22214j02977Cvj8iwrA9h3DoiWOYf8vCVNnnQZ/JgCH9admp2fwiNUxUpnqOPk1NRY+8CspENwViBBJnks0hIszvuCP2efwm0ImNp/hOyGHnTkvQxJz0msc0fDZw232dv+/6O60j3O+za+rdhKpWVIkWI3v2nXlllOusi6xLl+RjpUyMxPjZ34MI8w3EteMXWk03SVmSKBNQ3GvmclfyaWhs6HZ9b4mV21Zen8gEl+/H6dOvxbdEi/fztIKN1U+SbPJVra1l8ZWYAjECiWtnjypnHteOX0ip9KRlScIURHPf3hx64piuCfhTQ6fy6WHTAhMDg7oiZlEWxW/lsumd93z3zX2e5SjRYmRPkmxygbJU5DUFYgQSNMkOGNI/UTnzuCuLQkqlJ41WCpr4Bwzpz8Qp45l/y8KuCbh1/SbeXdfqOxnnZM66G+KC2Yv49LBpXPb5mT0UQVCJltznaZFblUuSqKpJo0YzKEZJd78YjS3bt0cWYswCUyBGIEErgq9cPTWROSZsZZFvagFSmXqSRiv5hvj+Zgb/u/YmHr97SajpLn8ynjB5HNrpb61OEy2VW0H4ZfK3bd6GiISu1CxyqzJJ07vj4qMm9Kh11cCOsieNIoF+klJU5K30REKjTORMJ22bt9HQ2EBnRye7jBiaKtonKIMdokuXxCVNq9mgEN84E23+Plm2uo3yPbWu38S3bv1aoFO+GG13jcK54tFFXSG5OXIrhaAIqtx4rsTJwOZm3mtvp73TSVztUA2KEi9JRV5TIHVA0gig/Mifzo7OrifctFE+fpP16SPPjixdEvf9JMlQj6L/zv0C63jlyJ+Ms7x+HAd/WH5LlrIY2ZG2d4e3xMkRN89iQ1tbt+1KTzNWqSrymgmrCkkSYZPGoVqIDT2LSKiwCTTo/QAFt5rNERXaHjQZN/fZYa/uv3O/1NePcvBHKYIs2u4a2ZNF744gZaNQloq8tgKpMpLWRopToDCftDb0pLKlMbWEvZ8kPpMwgqKcAF8znl+uxratCTLV8wjKdu+/cz/OmTmtpIrACjlmxwWHjeuWWQ7dVwpxqvEO79+/JC1s42IrkCojzurAuwoISpYLUwZp8zGyiITKKiS4EILeZy4jPn8CzTrqacLkcUycMr4rsquhsYGTzj6WO9++OXLyDoveShrGa+HA2RLWuyOug73cDaTyMQVSZURNoPlf+iDClEHafIwsIqGyCgkuhKTvP2ultmD2IubfsrCrwm9nRyfzb1kYOXFHRW8lVWgWDpw9k0aN5uGp03llxjd4eOr0bk7yIAd7/vHlbCCVj5mwqowos0+c7PEoZZCk70cS2YKulcQkUgoHcdL3n3XUUxqzY9BxXpIqNAsHLh1JHOyV1DfEFEiVETWBhn25c8X94iiDpBN7HNmyIK1yS3OduOfM+n2nnbizKs/i3d/CgUtDkG+jFKG4hWAKpMqImkCDvvRZVLSNcqhW4uSeFWHvPev3nXbiDuzASDqFZuHApSPKwZ6UtO1xkxJYjVdEPgj8N06v8XuBb6nqO+62J1T1kMylKTL1UI03buXbSjlvNVDq9572ekHVkwuJ3spXnIeeOKart7tFZWVLVpN+fh8RKLzke+Jy7iLyMPBj4DHgTJxmTier6isi8rSqfiSVJGWkHhQIFCf0Mqj8ef+d+3Hn2zcXdO5Kp5R9SnIUUv7dL+M/7Fxxr1XPDxHVRFAfkUJCfdMokGdV9cOe1+Nxeot/AbhOVQ9OJUkZqRcFUgyCenUAfPs3M2p6AillnxIvWTwIRE36SZRCORSp0ZOolUpYH5Grjj0h1SokVT8QERmY+1tVFwKfBm4F9kosgVHVRCX31TKlCB3OJ6scjKCIrsunXMPExlO4fMo1sUN1LSqr/MTJFwlzvGdd5j1MgfwE6KaqVPU5YAJwZ2YSGIkpR7OgNMl9tdLUqJA+JWnJKgcj6H/T2dGJqnblmsQ5rhyK1OhOnHwRv2TDoH0LJVCBqOpsVX3MZ/xVVf1/mUlgJKJc2cETJo9jwBD/Jxu/CaSWspjLUVsqq6f9tJO733HlUKRGd+Lki+SSDZOeIw2WiV5llDM7+CtXT409gdRaFnPalrRpyeppP6hxVhhB/1Mr0lg84jaailuQcdKo0eyWQfHGKMqqQETkOBFZLiIvi8i3fbZfJSLPuD9/F5ENnm0dnm1zSyt5+SiGHTquqSnJBGL28sLI6mk//3/m1zkRnHpbcZRCqRVpPZCk0VSSWlilqJsVmUgoIoer6iNRY0kRkUbgWuAY4HXgSRGZq6ov5vZR1fM8+38N8IYOb1HVgwqRoRrJOjs4aQXduEl8lsVcGFkmJ3r/ZxaKW3kkaTSV32AqLF8kyb5piZOJ/gsgP2TXbywphwAvq+oKABG5HZgEvBiw/+eAiwu8ZtXjW+pb4NATx6Q6X9q6S2nkNHt5MoqRcV+qagFGfKL8Gn5hu3HzOYpdNytQgYjIvwKHAcNE5HzPpgFAYwbX3h14zfP6deDQAFn2AvYGHvAMt4jIYmA7cJmq/ing2OnAdIARI0ZkIHZ5mTB5HEsfWc5dN8zb0YJMYf4tCznw8FGJJ4JimZpsoqpciqGYrG9IesLqYOVnlefMW0BFFFQM84H0BvrhKJn+np93gc8UX7RunAb8QVU7PGN7uYktk4Gfi8i+fgeq6ixVHauqY4cNG1YKWYvO43cv6dEEuW3zNq47N3lGeDFDM81eXh/UUsRdOQjzVcQt814uwsJ4H1LVHwIfU9Ufen5+pqovZXDtN4A9Pa/3cMf8OA34bZ58b7i/VwAP0t0/UtMErQ7eXdea+Eub1FlbK7kdRnbUWsRdqQnr8ZG2j3qpiOMDaRaRWcBI7/6q+okCr/0ksJ+I7I2jOE7DWU10Q0T2BwYDf/WMDQY2q2qbiAwFDgcuL1CeqiGs6mq+7yLLCrpJHe5G9RPHNGURd4UT5Kuo9DLvccJ4fw88DXwfuMDzUxCquh34KjAPWAbcoapLReQSETnZs+tpwO3avRjRaGCxiDwLLMTxgQQ532uOuFnhUaaF3GriJ1/4BQDfuvVroaYme9KsL+KapixDvXiMH7kPkjcm7nglEFhMsWsHp4hWuhCfCqOWiil+auhUWtdv6jHuLWwXVvwuKEoqLJyzXEUFjWQ8cPcz/Hrmfax9cyPDdh3IGTOO4RMnxot49644pEF8S53kF0+00ODCCCqO6FeWPUeh5dmTElRMMY4J6y4R+QrwR6AtN6iq6zOUz0jIOTOnRYbJhpkW0oTvWm5HZbNg9iKuu+gPbGrZCWlwjAtrVm/k6h/OAYhUIjPPubFbdJ92+D9c5t9XFnGXnrAoq+tf+CMf+OA/ae69nbZtTax8dRfWrhsEBOeJlJo4CmSK+9trtlKgMtZQdUqcL22/wTv5rlL6Dd4pld3acjsql9wqoH2PPbqUR462re38euZ9oQpkwexF3UPDQ/B7YChHl8haICjK6voX/sjQ3VbQ2Oj8Q1qat7PfPqsBupRIJTjSIxWIqu5dCkGM5ER9aUXyrac7xtOsJuxJs3LJrSgbevl/pde+uTHy+DjKA9InrRo9CVICA3f5Z5fyyNHYqIwcsaZLgVSCIz3SiS4ifUXk+24kFiKyn4h8sviiGYXit/rIjaettWS5HZVJ18qxvae9HGDYrgN9x3scH4PH714Se18jnCAl0Nzb//+YG8+6plVa4piwbgaW4GSlgxNy+3vg/4ollBEfr9Oz3+CdEBFa129i2J5DAk1Yw/YcYquJGmLB7EVIg6Adir61FnbftZsZq7mlF2fMOCb0HGGh4flYeG52XHDYON/+5X0bBrBF3+2xf9s2Z8pubsyiGEjhxFEg+6rqqSLyOQBV3SxBthGjJOSUxppX33Zi+tyVrldZrHn1bZp6N9HYq5GO9h0J/N5Vhtmtq5+c7yMXLaUbXZPI+4YhvZoYMLAPZ33nk5EOdN8aawEM23NI6IOLPYjEZ9Ko0Sxe9Qa3v/AcHao0ivCp0Qdy/N6HcN1Lv+pmxuroEFa+ugsAG9raKqKkSZw8kG0i0gd3mnJLhrSFH2IUC29sPhBqt96+bTs7DegbWX7dssurF79oOt3YCq+s5ILvHMcdD38/VgivX6n+k84+1tfMeeiJY7rlh7Su38S761qtjEkK5ixfxp3LltLhhsd3qHLnsqWsXTeIt1ftw9a2JlRha1sTL60Y3uX/gMooaRInD+QYnCTCA4D5OFnfZ6jqg0WXLmNqIQ8kKLcjiKgcDYvhr26KnZvjl4netfoNoaGxAe1UW5FEcMTNs3wzzXdz80GC8kByCPDKjG8UUUL3OmnzQFT1PhF5CvgYjrznqmr8GczIlKT2536DdwrdXqxy7kZpSBJNl6Zirp+ZM1e5IIycSc3K3YQTVuvK28/DT8lA+SOx4nYkbAHewanEe4CIfLx4IhlhJE3a27Jpa6g5weoYVTdxo+myrJib9B60cjfBRLWonTRqNA9Pnc5Vx55Q9O6CaYgTxvsT4BHge+yog/XNIstlBODb49oNaZCGnrEN27dtD/3yWh2j6iZum+Es65il6bNuDyT+xG07G1axt5zEicL6N2CUqprjvAIIC7+d2HiK7zGWXV7bxImmy3KlmX8PeqOwgupn2QOJP3HazubXyvrZsSeUXXHkiKNAVgC9sMiriiFowrDsciOIrOuY5e7BfL/KoSeOYf4tC+2BJAFhbWcrvSNhHAWyGXhGRBbQvZjijKJJZSRmwexFbH2vp46Pm11uCqO2KcZK068/zPxbFjJxyngev3uJPZDEIKgSb46wjoTVokDmuj9GCUgTKeMXigvQf+d+nDNzmn15jUxXmt0SWfNo27yNx+9e0q3cu+FPnNVF1XckVNVbRKQ38C/u0HJVbS+uWPVJ2o5/fg5SgD79Wkx5GF1ksdIMeljxYg7zeMRZXVR9R0IROQp4CbgWuA74u4XxFoe0kTIWimuUiqCHFS/mMI9HnNVF3CitchHHhHUlMFFVlwOIyL8AvwWspnPGpFUE1ujJKBVxHkrMYR6POKuLsCitKP9JKYijQHrllAeAqv5dRHoVUaa6Ja0isFBco1REVe0dMKS/mU1jElSJ1y8HJF8xVEp0VpxM9MUicqOIHOX+/DdQ3QWlKpRCenTESSYzjEIJSyJs7tubr1w9tcQSVS+FJAeG+U9KSZxiis3AOcAR7tAi4LpqTCyshmKKaaKwSnk+w/BGYTU0NtDZ0ckuI4bavVVC9p15pW8h7mIVVwwqphipQNyDewOjgU6cKKzopgHxhDoOuBpoBG5U1cvytp8BXIHTxArgGlW90d02BadKMMCPVfWWqOtVgwLJEqu0axiVTVo/RlgV34enTs9cziAFEicK60TgFZyJ/hrgZRE5PgOBGnEiu47HKRX/ORE5wGfX36nqQe5PTnnsDFwMHAocAlwsIoMLlakaCevlkWX9I8MwsiXnx1jV2oqyw48xZ/myyGMrJTorjg/kSmC8qh6lqkcC44GrMrj2IcDLqrrCXdHcDkyKeeyxwH2qul5V3wHuA47LQKaqIqrCqoX3GkblUogfo1KKK8aJwmpV1Zc9r1cAWaRB7g685nn9Os6KIp9Pu3knfwfOU9XXAo7d3e8iIjIdmA4wYsSIDMSuHKJ6edR6eG8lhDHWO+ZjS0+hWeZhNbRKRRwFslhE7gHuwGmg+lngSRH5FICq3llE+e4CfquqbSLyZeAW4BNJTqCqs4BZ4PhAshexfEStMGo5vDcsjBF6xs37jZX7y1ftpK2cYDgE5YE0iLDvzCur4j6No0BagLeAI93Xa4E+wEk4CiWtAnkD2NPzeg92OMsBUFXvDHkjcLnn2KPyjn0wpRxVS9QKo5Yr7QYt/3/44ALaOjq6KZYL598LIrR3dnaNVVJF02olaAV87YybavKey5qglrW5/ujVcJ/GqYVVrMDuJ4H9RGRvHIVwGtDt0VhEhqvqavflyUDOuzQPuNTjOJ8IfKdIclYscVYYtVppN2iZv6GtZ3R5uyrkRRtWUkXTaiVoBdy6fhOt6zcBtioJIz/LvEGkS3nk8PpEglbQXlPuoJYWVJWNbW0lWcFEKhB3gv8aMNK7v6qeXMiFVXW7iHwVRxk0Ajep6lIRuQRYrKpzgRkicjKwHVgPnOEeu15EfoSjhAAuUdX1hchTjdTyCiOMOcuX+X7ZklIpFU2rlais9Bxev5zRHa8fY9+ZV/ruk1uJBJlrvdve2bq1x3G56xSDOImEzwK/Ap7HyQMBQFUfKopERaRW80DqyZGZ7/vw0qepiZampm5fojCKFTNfL8SpzJtDRJjfcUcJpKpegnI7GgMelhpFGNDcHHm/Z3Gfp84DAbaq6kxVXaiqD+V+CpLGiCQsvyN/v7BQ3lrDz/cBzpfp0gkTuejIT/SIj+8lQq+G7rd6JVU0rVa8JXQAGhqDp5NaifwrJkG5HUEr7Q7VWA9LxVxpx3GiXy0iFwPz6d6R8KmiSVXnJIluiQrlrUbCwnODvgydqj06uVkUVvHJ3WNhK5FaifwrNkGVd694dJHvyiQuxewdEkeBfBD4Ak74bM6EpSQMpzXik0Qp1FqyYFSV0bglsL3lrs+fd48pjYzwM5eG9QixrpjJCMrtuHD+vU4wSEKKvdKOY8L6LLCPqh6pquPdH1MeRSSJUggyDVSrySAqOzduCYdCykQY/gSZS8Mc6du2ZlI2r+aYs3wZR9w8i31nXskRN88KvS8njRpNv+bmwO2Dmpu7MtIHt7QwqLm5ZNnpcVYgLwCDgDVFk8LoRlB0S/+d+/UYqyJEhSEAACAASURBVLVkwajs3LAGO17itAs1khG0Mg6j2s2pxSBNL48NIb6Oi4+aULZ7Oo4CGQT8TUSepLsPpKAwXiOYaZdO5qfTrmP7tu4T4HvvbmbB7EXdvoy1FsqbxEQVRqFlIoyepDWLVqs5tVikebgJ+l4Mbmkp6wNRHAVycdGlMLoxYfI4rp1xU1cyVo6O9g4un3JN1z7e/atVYeQTt0ubFz+nexxFZCQjaGWc6wkSdpyxgzQPN0Hfi4uOLK83IdIH4obs/g3o7/4sszDe4rPpnfd8xzs7Orlq+g1ceMwlHNvrVI5p+CzH9jqVmefcWGIJi0PSKqNBvo7xI/epiHLXtcShJ47xHf/wUQeGdilMa06NG8pebQQ9xIQ93FRK9d184iQSnoLT1OlBnIZX44ALVPUPRZcuY6opkfD0kWfHyvL1ctLZxzLj2jOLJFFlEtZYJxcCaaG72RB0T+a6EWbZpbCWm6H5JcP2aWqqCIUQROqOhG4m+jGqusZ9PQy4X1U/XBRJi0ilKhC/0EiAK6ZeS0d7R+zzNDQ2MK/9d8USsyIpdWvPemZi4yn4zRfFyDIPU1a3rbw+02uVg2prRRCkQOL4QBpyysNlHfHCf40YBCUNHvCvoxIpDyDUDl2rmK+jdJSyv0yt5TflUwm9PLIgjiL4s4jME5Ez3B7ldwP3Fles+iEoNPLpBc8nPldYKYlaZfzIfXzHRw4cFDvO3ojHtEsn9/B1eH0cWfosai2/KS5J8kMqgThO9AuAXwIfcn9mqeqFxRasXkjzRPWRCR/0HT9x+jGFilN1LFy5wnf8r6+/ZkmEGeOtfSUi7DJiaJdPIuuabFHKqhapxuTXQAUiIu8XkcPB6Tqoquer6vnAWhHZt2QSVjFRT2QLZi9CGiTZSQWOnTqek84+tmvF0dDYUJcOdAgOfcy31MftNW2EM2HyOG5beT3zO+7gtpXXd8tDCiq/k/Y6QcqqVimkR3q5CPOB/Bz/Jk0b3W0nFUWiGiGqIGJuu6/fQug5A+ZQ58t628rr61Jh5DOwudm3iZQflkRYPIrhs6jG/KZCnOPVmPwaZsJ6n6r2MMS7YyOLJlGNEPVEFlSArqGxgZPOOjYwrh5qx5GYBSLxV3DmWC8e9eqz8JLWBJXzewQ9M1byfRumQAaFbOuTtSC1RtQTWdB27VRmXHsm5806K9ApXk9fyijCagR5sSTC4jLt0sk09e5u0Gjq3VTTPot80pigvErHj0q/b8MUyGIR+X/5gyJyJrCkeCLVBlFPZFHbJ0wex4W3fLXuHIlJifN0NrilpaKTtGqF/ByRqByzWiONCSqoQRpUTrZ5GGEK5OvAVBF5UESudH8eAr4EnFsa8aqXqCiSOFEm9ehITIpfefd8+vTqVdFfwlrgpu/O7pG31NHekdqJXo2kKVESpFwEeHjq9K6+NpUa2hv4zVPVt4DDRGQ88AF3+G5VfaAkklU5UVVy41bRrUZHYinJKYbz5t0TuE8lOyFrhVpP/ItDmkKgUYmwaUq/l5LIUia1RKWWMjEKJ6gmFjimgIenTi+xRPVFrZceiUvSKKyoulhhtd5KeU8HlTIpa+qyiBwnIstF5GUR+bbP9vNF5EUReU5EFojIXp5tHSLyjPszt7SSZ0etVhwtNRccNo5eDT1v514iFe2ErBWCTLKHnjimru7vSaNG8/DU6bwy4xtdJqio/cOq7FZ6aG+cWlhFQUQagWuBY4DXgSdFZK6qvujZ7WlgrKpuFpGzgcuBU91tW1T1oJIKHRO/4oh+ZqioXJFiXbcWyX3hLnnoAd5xI7MGNTeXtVtbPeFnkj30xDHMv2VhZvd3rRJWF6vSa72VzYQlIv8K/EBVj3VffwdAVf8rYP+PANeo6uHu602q2rPHawilMGElKUMdZ9kfpBTyx/O/rGHXNYxSYGatwqmU0u+Jy7mLSCv++dACqKoOKFCgzwDHqeqZ7usvAIeq6lcD9r8GeFNVf+y+3g48A2wHLlPVPwUcNx2YDjBixIgx//znPwsRO5IkX5qo8thBymjilPE9lEVQ9rp9WYOptpLa1UYpy79XCkH3lN84EOv+q4T7NHE5d1WtjDUSICKfB8YCR3qG91LVN0RkH+ABEXleVV/JP1ZVZwGzwFmBFFvWJNEoUeWxg7LZ77phXk9lEfDO6ikKJgmVHt1SC5Sy/HslEHRPLV71BncuW9pt/ML594II7Z2d3faFnvdfJZd+j+1EF5FdRGRE7ieDa78B7Ol5vYc7ln/do4HvASeralfRI1V9w/29Aqdb4kcykKlgkpR0iMoFCZz8E6jBWv2yFko1Fq6rNuqtom7QPXX7C8/1GG9X7VIe3n2r7f6LVCAicrKIvAT8A3gIWEk2/UCeBPYTkb1FpDdwGtAtmsr1e/wSR3ms8YwPFpFm9++hwOGA1/leNpJ8aaISBRNP/nlloWr5y1oolR7dUgvUYiJsWFJf0L3TkcDP7D1HJScQ5ogThfUj4GM4bWw/4iYWfr7QC6vqdhH5KjAPaARuUtWlInIJsFhV5+L0Yu8H/N4tmveqqp4MjAZ+KSKdOErwsrzorbIRN0HQu3/QtmmXTuayz8+Mdd2cb+Txu5fUZRRWUio9uqVWqOZEWK/vYVBLC1vb29nSsSPbPt/sFHRPJaFaEghzxOmJvlhVx7q90T+iqp0i8qz1RC8Nnx42jXfX9bwpBwzpT8tOzaYsAohyPFZKdItRmfjdH0HkkvqSHNNLpJsPBCozgTBHIT3RN4hIP2ARcJuIrAHey1pAw5+vXD3VNxLrK1dPNYURQJynt9zvcke3GJVJWJHDfHJmpzhldQRiRWFVi4k1jgKZBGzFKa54OjAQuKSYQhk7SGoSqyXShi+GOci9x0dFt1RC+KRRHpJM1F6z56RRo7ni0UWxVw/VmkCYI1KBqOp7IrIrcAiwHpinqhYbWkKq2Y6clkJswFk8vVWLDdooDnH9GX7FEtMUVcwni3OUgjhRWGcCTwCfAj4DPCYi04otmFHfFBJmm6asdn7EyyUPPWBhvnVMnDYBfn1mcqvWLdu30+h2y0zT1yOqRlalEMeEdQGO83wdgIgMAR4FbiqmYEZ9U8gqIunTm99qI4hVra3sO/NKM2nVOPk+skEtLagqG9vaevzvc0pjVWtrt4IQHapd912a+6SSEwhzxFEg6wDvN6rVHTNSUM8FD5NQiA04qYM8icMU6Nbv2ns9o7aIM4HnP3zkx7T6+d5qiTgK5GXgcRGZg/P5TAKeE5HzAVT1Z0WUr6aIqr5rymUHhdqAkzy9pY1sqfXJod6JE0QR5+FjdWtrzQZkxFEgr7g/Oea4vysrHKAKCKptlWv7mWVp92qnmGG2+V/mlsbGbgliOQY1N9O3d29Wt7YGVo+ptLBKIxviBlHE+f8PbG6u2YAM60hYQsKqkwYVnrNqutkSN9mrlwiXTzy+6wteaYldRrbkP1Rs3raNDW1tPfYb1NzMU1/eUTA8rBMmOKvmlqamrh41Xqrp3kmcSCgiP1fVr4vIXfiU73NLihgJCKtOaj2lS0Ncf0e/5uZuT4fVElZpJCdJEMWGtjbmLF/G4lVvcPsLz/nWuco50ndzV83nByQW1sLqNcyEdav7+6elEKQemHbpZN+s8mmXTuam786uq9LXpcT7dBl3vb0h74nRr+Nhc2NjlmIaZSJpEMX3Fsxnc8D+u/mYWoMSCystKTANYf1Alrh/LsZpH9sJXa1om0sgW02Rc5C3bd5GQ2MDnR2d7DJiaDdHeZByMZLhVRgDm5t5r729R+nsKBpE2Hfmld3CNwe1tLDJY9bY0NZWM7bseibpSiBIeTSK+Jqkann1GqcfyAKgr+d1H+D+4ohTm+Sir3IrjM6Ozi7l4HWQ927ZUQZ+wJD+VV/6uhzkzBGr3NXGhra2xMoDnBh+Bd7ZupUNbW1df7fnmSwsubD6CVoJxG6W5BJUtr1akgLTECcKq0VVN+VeqOomEekbdoDRnbDoq1z4bv7qo21LTweeEU0Sc0SusN34kfuwcOUKVre20iCSqH8D1IYtu54JWiF8avSB3ToJ5sa3bt/uawrNZZ77UQ1JgWmIo0DeE5GDVfUpABEZA2wprli1RZSDPErBeLFckXDiTuZBETD7zrwy8TVrwZZdz4SFjI/dbfce2ehBDyinfeBDpRS7IoijQL6O09BpFc5D267AqUWVqsaI6g0dNwIrKhHRiFcEL8z+nLQpUK3YsuudoBVCbjwq/LsBGLvb7kWWsvKINPOp6pPA/sDZwFnAaI+D3YhBVJvbuH3UoxIRDf8ieL1EGNzSEsv+HFcZpLVlV0ObUqMnUabRTnefeiPOCgTgo8BId/+DRQRV/Z+iSVVjRPX0CAvv9WK5ItEUmsE+adRofvjgAt8kMi+vzPhGYtmsRHz1Esc0Wo++sEgFIiK3AvsCzwC5eg8KmAJJQFhPj7hNo6JMYYZDoQ7Li4+aEGquCHOWhhG30VUYtVpTqdKJY9qsR19YnBXIWOAAraeaJ2UgTtOouCsVo3Bampoyd5YW2ujKVjDlwy9Sy0u9+sLiKJAXcBznq4ssixGBtbct/pP3nOXLuHD+vT3yPcBZeZz2gQ/xo/FHpzp3oW1Ks1jBGOnIN40ObG5GRNiwdWtdrwTjKJChwIsi8gTQZRjOohaWiBwHXA00Ajeq6mV525txTGVjcHqQnKqqK91t3wG+hGNWm6Gq8wqVJ0vShttGHWftbYv75P3DBxf4Ko/8InppKDQjOYtWvdVCJZrqajWXoxDiKJAfFOPCbkmUa4FjgNeBJ0Vkrqq+6NntS8A7qvp+ETkN+AlwqogcAJwGHAjsBtwvIv+iqj1rcpeBtOG2FqbrTymfvIOc52FO9biTXaEO/kJXMNWCmeqqh0gFoqoPFenahwAvq+oKABG5HadZlVeBTGKHAvsDcI2IiDt+u6q2Af8QkZfd8/21SLImIkliYBbH1TqV/OSddLIr5Cm2lmsqeSnmA0OQsq/EFU81EFbO/WFVPUJEWulezl0AVdUBBV57d+A1z+vXgUOD9lHV7SKyERjijj+Wd6xvFo+ITAemA4wYMaJAkeMRFFa75tW3WTB7UaAysDBdf0r55D24pcW3d8Pglhbf/Uu5Oipmk61y4TdxF+uBIUjZL171RreSJbbiiU9gIqGqHuH+7q+qAzw//TNQHiVDVWep6lhVHTts2LCSXDMsrPaq6TewYLZ/wlHQcarKMQ2f5fSRZwceW8v4JQcW68n7oiM/Qa+G7l+LXg0NXHTkJ3z3L/XqaNKo0Tw8dTqvzPgGD0+dXtUTXH7hy9zEPShAWRf6wBCk7G9/4bnAhwAjnNBMdBFpFJG/FenabwB7el7v4Y757iMiTcBAHGd6nGPLhl/meY6wzPFpl06mqXewVTHnE6k3JVLKaqaTRo3m8mOO63aty485LvBaQZNa0Lhlou8gaEJX1aI8MAQp9aDimZVgIq10Qn0gqtohIstFZISqvprxtZ8E9hORvXEm/9OA/ISGucAUHN/GZ4AHVFVFZC4wW0R+huNE3w94ImP5UpMzUV32+Zm+28NMUlHpNvXqEyllBEySayXxS5hzuDtBE/TGtjZ+duwJmZvqgkyhjQEVmGstOKEYxInCGgwsdcN438sNFhrG6/o0vgrMwwnjvUlVl4rIJcBiVZ0L/Aq41XWSr8dRMrj73YHjcN8OnFMpEVg5JkweF9llcP5fXuSXtz3MmnXvssuQAWx/4iU62qPfRr37RCqJJH4Jy+PoTphvqxgPDONH7sNtzz/bY/zQ3ffg6TdX13xwQjGIo0D+o1gXV9V7gHvyxi7y/L0V+GzAsf8J/GexZMuCsMzx+X95kZ/cMJ+2Nuemfevtd2HEUHqta6Xp9XAFYaVLKou4k10Wmei15EAvdVTZwpUrfMdXbtzApRMm1tRnWyrCorBacKrvvh94HviVqsZvHFznRLWw/fSXZ3Upjy6aGtl+4J6hCsRKl1QecSf2QqLJatH8VeqosjAF7vcQUGsKuxiErUBuAdqBRcDxwAHAuaUQqtrJTwj0a2G7Zt27vsdqn57Od2kQtFN79FA3yk+Sib2QJ+5aNX+V0reVRIHXosIuBmEK5ABV/SCAiPyKCnJSVzpxEgJ3GTLAMVvlMbBvM4NGDK27WlfVSpKJvZAn7kpOpiwFWawGkijwWlXYWROmQNpzf7gO7xKIUxvESQj88ulH8F/X/Jn2js6usV6NDZw7/Wgm/mZG0WU0siHpxJ72iXtgc7NvOZWBzc2JzwXVZZ7JajWQRIHXu8KOS5gC+bCI5B6RBejjvs4qE71midO3o/H1dTQ9tYLt+w1H+/RGtmyj6aXVNEY40I3KIt8s0tC3naaB25BGZcKff87XD5zASXt+MPF58yf4bZ2dvvulebCrNvNMlquBuAq8XuqOFUpYJnpjXvZ5UzVmopeDqBa24Ji5WPEWLfOeoc+fnqBl3jOw4i1rT1tleLPkG/q20zS4DWlSEFi1ZSMXPX0Xd732fKJz+mVob25v9913g0/ZlSjCJuSsyDJhshyrgVJWP6hmInui1zsLZi/i9JFnM7HxlNilRCZMHsd5s85ilxFDERF2GTGU82ad1c2XkbbuVRp5jOLhzZJvGrgNyftGbe1o5+dLFyQ6Z1T/bS/5T8RxJu5iT8hBJUrSKpGk2f5ZUMrqB9VM3J7odUkh5dWj+nakaU9r5d4rk5xZ5IA//hC/OgKrt2xMdL4kE/n4kfsAzqSd38s9yDRVbPNM1g7o8SP3Yfbzz3b7bEuxGrD+H9GYAgmhmOXV07SntXLvlc3wPgNZ5aMshvcZmOw8Mfpv51i4ckUPn4YXr2kq51MZ1NJCL5FujbOiJuQkTvckK5yo8uqrWlsdp6vnGAE+NfrA0Mm9moIEqhlTICEUs7x6mva0Vu69svn6gRO46Om72Nqxw1/R0tiLrx84IdF5ovpve1nd2hpp8lrV2sqF9/2ZdtcR/87WrTSKMKi5mY1tbZETbFKne9wVTtzy6vmrOqV7Vnm+shg/ch8rz14iTIGEkMbMlISk7WmLLY9RGLloq58vXcDqLRsZ3mdgqigsv3DTzdu2+YbxDu/fP9LkJdClPHJ0qLKts5NXZnwjUp4gk9R58+7hikcX9VA+cfMtwsqrB1XIzZF7z35KKN/clTuv5XBkjymQENKYmepJHqMnJ+35wVRhu/nk29/9zFS5STln6vGjT1NT4Opkc3s7c5Yvi5xUwxSU39N93HyLpOXVveRWM35KKOjoVa2tHPzLaxARNmzdaqatDDAFEkIaM1M9yWOUjqhJ+cL593bzaYDTRfGiIz/BefPu6XG+HHGeyqN8Mn5P93Ec0EHnbQD8s14cvKuZpJFjcYIMjPiYAokgqZmp2FSaPEbpCJ2URcCjQHJdFCeNGt0jOsuL1xQUpJzi+GTShAAHmbpQZUuHf1uD3fJkC1JC+Y73IMy0VRiWB2IYCajEjoJXPLqoh4+jvbOzK/rq4qOCnfjD+/ePzNvI5USEMbC5OfHnEpRrsTVAecCOoIHc+YMS/iZ/8MPsFjMs2cqTpMdWIIYRk0otARIVNjtp1GgWr3ojMJciTt7GpFGjQ30t77W3d61yknwufquqsOt4FZz3/EGrpyNunhUZEm3lSdJjKxDDiEkpSoCkIU6m9o/GH83Pjj3BN7M6bt6G39O+AH179eqxAor7ufit6Pyuk4/3/JNGjebhqdN5ZcY3eHjq9B4RYWHVwqw8SWGYAjGMmMSdaEtt5opbtylooo1bKsTP5PSzY09gS0CdLq9/xe/zCDKdAd2uE0Qc09OkUaNDfSFWnqQwzIRlGDGJkyBXDjNXoZ39/JzZwo4yKfnXimty8vpX/D6PsBWdV8EFmaHimp52C/i/7eb2XjfSYysQw4hJnCf9cpm5wsw4USuiSaNG86nRB3Z72lfgzmVLI1dPc5Yv812BRPlXvjn/3kDfRBzTWRLTk1XWLR5lUSAisrOI3CciL7m/B/vsc5CI/FVElorIcyJyqmfbr0XkHyLyjPtzUGnfgVGPxKnQWmmNiOJWxl24ckVg9nbUud/JKyk/qLk50r8SliwYx3SWxPQUdnwlRtVVE+UyYX0bWKCql4nIt93X38rbZzPwRVV9SUR2A5aIyDxV3eBuv0BV/1BCmRNx95JlXH3vI7z5Tiu7Du7PuccfzoljbLlc7UQlyGVZ6TaLgoBxK+OmUXxBNbj69u4dmacRRNDKoNDKuH7HV2pUXTVRLhPWJOAW9+9bgH/L30FV/66qL7l/rwLWAMNKJmEB3L1kGT/4/f2sfsd56lv9Tis/+P393L3Enm5qnazMJVn11IirGNL03Ag696rW1kQRVTlK3XOjUqPqqolyKZD3qepq9+83gfeF7SwihwC9gVc8w//pmrauEpF0jaGLxNX3PsLW9u435tb27Vx97yNlksgoFVk1Iip0csuZZoIMRfmKIUzxBZl5wpRLUERVY0AL3t369+/huyk2lWZurEaKZsISkfuBXX02fc/7QlVVRAINoiIyHLgVmKKquWDz7+Aont7ALBzz1yUBx08HpgOMGDEi4btIx5vv+N+AQeNGbZFFI6Kop/sk5dfzCQrxhZ6RXECgmSeqxIlfRFVYUchSY33PC6doCkRVjw7aJiJvichwVV3tKog1AfsNAO4Gvqeqj3nOnVu9tInIzcA3Q+SYhaNkGDt2bJzyOAWz6+D+rPZRFrsOthvTiEeY7yDKVh/WHyS/lpQXP8V3xM2zQkNtc9eLG1GVy4rPlWxvFIlsDlUs4padN4IplwlrLjDF/XsKMCd/BxHpDfwR+J98Z7mrdBARwfGfvFBUaRNy7vGH09Kru25u6dXEuccfHvscdy9ZxsQf38iHvnEVE398o/lP6owo30GYOSto9SKQ2EwUtRI63630O7ilxXc/vyZSdy5b2hWF1aHaI1y4VJFR1ve8cMoVhXUZcIeIfAn4J3AKgIiMBc5S1TPdsY8DQ0TkDPe4M1T1GeA2ERmG8514BjirxPKHkou2ShuFlXPC5/woOSe899xGbeM1KcV9us+RpWkmrNptbnxVayu9ROjV0NCtpEmSJlK5qLBSR0ZZ3/PCKIsCUdV1QI8Soaq6GDjT/fs3wG8Cjv9EUQUskKQhvPn7b2lrD3TCmwKpH3KTW9JM7CxNM0FZ6vm24HZVBvXuTd/evVM1kcqNxw07NioDK2WSMUlXD377B2FO+PokqUIotLRJ1LmCVkQb29p46stfDT1f1OrIIqOqC1MgGRMWwuunQPz2D8Kc8PVJGoXg1xL3iJtnpVIo+ecqpDbV+JH7BJaVz53DIqOqB1MgGZM0hDfuqiKpE96oLQqx1WftV0hrIss50L3KQ6BbFJZFRlUXVkwxY4JWCUnHB/ZtZvhgJzpk+OD+/OCzR5v/w0hF1hnXaaOX/ORQnDpchZ7bKA+2AsmYc48/vJtPA8JXD0H7f+ffxpvCMBLjVz+rGH6FNCuiuHJYZFT1YAokY5KG8ObG/+tPC9m42WkJmp9DYhhxCDJVDWpp6VExF0rvVzD/Ru1hM1UROHHM6MSrh7b2jq6/N2zeankfRmKCTFXNjY30aWoqu1/B/Bu1h/lAKgArvlj7dG6eS+eao+h8c5Tze/PczK8RZCLa2NZWEX4F82/UHrYCqQCs+GJt07l5Lrz7fcA1I3Wugne/TyfQ0PfkzK4TZiKqFL9CpchhZIOtQCqApBFaRpWx6Wd0KY8utrrj2WGtW41SYyuQMpIrYeKXfW55HzVE5+pk4ynJMgPdMOJgCqRM5Jcw8TLcWuDWFg3DHbOV33jGmInIKCWmQMpEUAmT4YP7M//7Z5ZBIqNo9Du/uw8EgBZn3DCqGFMgZcIc5/VDQ9+T6QTH59G52ll59Ds/Uwe6YZQDUyBlwroW1hcNfU8GUxhGjWEKpEx4S5gcv//fmfHxx9l1wCbaOobRuXkXezo1DKPiMQVSJnIO8meX/zfnjnuIPr0cf0ifprVFyREwDMPIGlMgZeTEMaM5fs+noDPfme7mCJgCMQyjgrFEwnJTohwBwzCMrDEFUm6CcgGKkCNgGIaRJaZAyk2/84GWvEHLETAMo/IpiwIRkZ1F5D4Recn9PThgvw4Recb9mesZ31tEHheRl0XkdyLSu3TSZ0tD35NhwI+hYTdAnN8DfmwOdMMwKp5yrUC+DSxQ1f2ABe5rP7ao6kHuj3dG/Qlwlaq+H3gH+FJxxS0uDX1PpmGXB2nYdbnz25SHYRhVQLkUyCTgFvfvW4B/i3ugiAjwCeAPaY43DMMwsqFcCuR9qpoLM3oTeF/Afi0islhEHhORnJIYAmxQ1Vzs6+vA7kEXEpHp7jkWr127NhPhDcMwjCLmgYjI/cCuPpu+532hqioiGnCavVT1DRHZB3hARJ4HNiaRQ1VnAbMAxo4dG3QdwzAMIyFFUyCqenTQNhF5S0SGq+pqERkOrAk4xxvu7xUi8iDwEeB/gUEi0uSuQvYA3sj8DRiGYRihlMuENReY4v49BZiTv4OIDBaRZvfvocDhwIuqqsBC4DNhxxuGYRjFRZz5uMQXFRkC3AGMAP4JnKKq60VkLHCWqp4pIocBvwSnLBTwc1X9lXv8PsDtwM7A08DnVbUtxnXXuterFIYCb5dbiAIw+cuLyV9e6kn+vVR1WP5gWRSI4SAii1V1bLnlSIvJX15M/vJi8lsmumEYhpESUyCGYRhGKkyBlJdZ5RagQEz+8mLyl5e6l998IIZhGEYqbAViGIZhpMIUiGEYhpEKUyAlREQ+KyJLRaTTzXkJ2u84EVnulqsPqlRccgotw18uoj5PEWl22wK87LYJGFl6KYOJIf8ZIrLW85mfWQ45/RCRm0RkjYi8ELBdRGSm+96eE5GDSy1jGDHkP0pENno++4tKLWMYIrKniCwUkRfduedcn33S/w9U1X5K9AOMBkYBDwJjA/ZpBF4B9gF6A88CB5Rbdle2y4Fvu39/H9YUzgAABvlJREFUG/hJwH6byi1rks8T+Apwg/v3acDvyi13QvnPAK4pt6wB8n8cOBh4IWD7CcC9gAAfAx4vt8wJ5T8K+L9yyxki/3DgYPfv/sDffe6f1P8DW4GUEFVdpqrLI3Y7BHhZVVeo6jacjPtJxZcuFqnL8JeROJ+n9339AZjgtg2oBCr5fohEVf8CrA/ZZRLwP+rwGE6du4rp5xxD/opGVVer6lPu363AMnpWL0/9PzAFUnnsDrzmeR1arr7EFFKGv1zE+Ty79lGnQOdGnLYBlUDc++HTrvnhDyKyZ2lEy4RKvt/j8q8i8qyI3CsiB5ZbmCBc0+xHgMfzNqX+HxStGm+9ElbGXlUrvuhjscrwq+orWctqdHEX8FtVbRORL+Ospj5RZpnqhadw7vdNInIC8CdgvzLL1AMR6YdTyfzrqvpuVuc1BZIxGlLGPiZvAN4nyJKWqw+Tv8Ay/OVSIHE+z9w+r4tIEzAQWFca8SKJlF9VvbLeiOOrqhbKer8XincyVtV7ROQ6ERmqqhVTZFFEeuEoj9tU9U6fXVL/D8yEVXk8CewnInuLSG8cp27ZI5lcUpfhL5mEPYnzeXrf12eAB9T1LlYAkfLn2atPxrFzVwtzgS+6kUAfAzZ6zKQVj4jsmvOXicghOHNqpTx85FqA/wpYpqo/C9gt/f+g3FEC9fQD/DuOfbENeAuY547vBtzj2e8EnGiJV3BMX2WX3ZVrCLAAeAm4H9jZHR8L3Oj+fRjwPE600PPAlypA7h6fJ3AJcLL7dwvwe+Bl4Algn3LLnFD+/wKWup/5QmD/csvskf23wGqg3b33vwSchdO2AZzIn2vd9/Y8AdGJFSz/Vz2f/WPAYeWWOU/+IwAFngOecX9OyOp/YKVMDMMwjFSYCcswDMNIhSkQwzAMIxWmQAzDMIxUmAIxDMMwUmEKxDAMw0iFKRCjavBU+X1BRH4vIn0D9ns05fnHisjMAuTbFDC+q4jcLiKviMgSEblHRP4l7XUqAbcK7WEB2/YXkb+KSJuIfLPUshmlwxSIUU1sUdWDVPUDwDacWPYu3CxyVNV3YotCVRer6ozCxewmkwB/BB5U1X1VdQzwHYLriFULR+Hk/PixHpgB/LRk0hhlwRSIUa0sAt7vPgkvEqfvyIuwYyXgbnvQLTD4NxG5zZM1/FERedQtgveEiPR39/8/d/sPRORW90n6JRH5f+54PxFZICJPicjzIhJVGXc80K6qN+QGVPVZVV3kZv5e4a6onheRUz1yPyQic0RkhYhcJiKnu3I+LyL7uvv9WkRucAtX/l1EPumOt4jIze6+T4vIeHf8DBG5U0T+7L6nrpInIjLRfa9Puau7fu74ShH5oef97i9OUb6zgPPcFeE47xtW1TWq+iRO8p1Rw1gtLKPqcFcaxwN/docOBj6gqv/w2f0jwIHAKuAR4HAReQL4HXCqqj4pIgOALT7HfginP8JOwNMicjdO/a9/V9V33VItj4nIXA3OyP0AsCRg26eAg4APA0OBJ0XkL+62D+P0j1kPrMDJ9D9EnIZAXwO+7u43Eqfk+77AQhF5P3AOTr3LD4rI/sB8j8nsIPczaQOWi8gv3Pf+feBoVX1PRL4FnI+T7Q7wtqoeLCJfAb6pqmeKyA04fV9slVHHmAIxqok+IvKM+/cinBo/hwFPBCgP3G2vA7jHjsQp177afUpG3YJ40rMFyBxV3QJsEZGFOBP13cClIvJxoBOn7PX7cMrbJ+UInCq6HcBbIvIQ8FHgXeBJdesRicgrwHz3mOdxVjU57lDVTuAlEVkB7O+e9xfue/ubiPwTyCmQBaq60T3vi8BewCDgAOAR9zPoDfzVc41cAb4lOErPMABTIEZ1sUVVD/IOuBPeeyHHtHn+7iDZPZ+/qlDgdGAYMEZV20VkJU4trSCW4hRoTIpX7k7P6066vwc/GeOeN/d5CHCfqn4u4pikn59R45gPxKhHlgPDReSjAK7/w29inOT6E4bgOI2fxCn1vsZVHuNxnuDDeABoFpHpuQER+ZDrN1gEnCoijSIyDKd96hMJ38tnRaTB9Yvs4763RTiKDtd0NcIdD+IxHNPe+91jdpLoKLFWnBapRh1jCsSoO9RpDXsq8AsReRa4D/9VxHM41W0fA36kqquA24CxIvI88EXgbxHXUpwqzEeLE8a7FKd67ps40VnP4VRyfQC4UFWTmsJexVE69+JUV90KXAc0uDL+DjhDVduCTqCqa3H6qv9WRJ7DMV/tH3Hdu4B/93OiixO2/DqOH+X7IvK662cyagyrxmsYPojID6hwJ7GI/Br4P1X9Q7llMeoTW4EYhmEYqbAViGEYhpEKW4EYhmEYqTAFYhiGYaTCFIhhGIaRClMghmEYRipMgRiGYRip+P9sOLtU/rvPuwAAAABJRU5ErkJggg==\n", 168 | "text/plain": [ 169 | "
" 170 | ] 171 | }, 172 | "metadata": { 173 | "tags": [], 174 | "needs_background": "light" 175 | } 176 | }, 177 | { 178 | "output_type": "display_data", 179 | "data": { 180 | "image/png": "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\n", 181 | "text/plain": [ 182 | "
" 183 | ] 184 | }, 185 | "metadata": { 186 | "tags": [], 187 | "needs_background": "light" 188 | } 189 | } 190 | ] 191 | } 192 | ] 193 | } --------------------------------------------------------------------------------