Python 中的实用数据挖掘
来源:互联网 发布:声明一维数组大小 编辑:程序博客网 时间:2024/05/19 13:58
本文是 2014 年 12 月我在布拉格经济大学做的名为‘ Python 数据科学’讲座的笔记。欢迎通过 @RadimRehurek 进行提问和评论。
本次讲座的目的是展示一些关于机器学习的高级概念。该笔记中用具体的代码来做演示,大家可以在自己的电脑上运行(需要安装 IPython,如下所示)。
本次讲座的听众需要了解一些基础的编程(不一定是 Python),并拥有一点基本的数据挖掘背景。本次讲座不是机器学习专家的“高级演讲”。
这些代码实例创建了一个有效的、可执行的原型系统:一个使用“spam”(垃圾信息)或“ham”(非垃圾信息)对英文手机短信(”短信类型“的英文)进行分类的 app。
整套代码使用 Python 语言。 python 是一种在管线(pipeline)的所有环节(I/O、数据清洗重整和预处理、模型训练和评估)都好用的通用语言。尽管 python 不是唯一选择,但它灵活、易于开发,性能优越,这得益于它成熟的科学计算生态系统。Python 庞大的、开源生态系统同时避免了任何单一框架或库的限制(以及相关的信息丢失)。
$ ipython notebook data_science_python.ipynb
第一步:加载数据,浏览一下
第二步:数据预处理
这里的映射并非一对一的,我们要用词袋模型(bag-of-words)把每个不重复的词用一个数字来表示。
- 大写字母是否携带信息?
- 单词的不同形式(“goes”和“go”)是否携带信息?
- 叹词和限定词是否携带信息?
换句话说,我们想对文本进行更好的标准化。
我们使用 textblob 获取 part-of-speech (POS) 标签:
第三步:数据转换为向量
现在,我们将每条消息(词干列表)转换成机器学习模型可以理解的向量。
用词袋模型完成这项工作需要三个步骤:
每个向量的维度等于 SMS 语料库中包含的独立词的数量。
这里我们使用强大的 python 机器学习训练库 scikit-learn (sklearn),它包含大量的方法和选项。
我们取一个信息并使用新的 bow_tramsformer 获取向量形式的词袋模型计数:
message 4 中有 9 个独立词,它们中的两个出现了两次,其余的只出现了一次。可用性检测,哪些词出现了两次?
整个 SMS 语料库的词袋计数是一个庞大的稀疏矩阵:
最终,计数后,使用 scikit-learn 的 TFidfTransformer 实现的 TF-IDF 完成词语加权和归一化。
单词 “u” 的 IDF(逆向文件频率)是什么?单词“university”的 IDF 又是什么?
将整个 bag-of-words 语料库转化为 TF-IDF 语料库。
第四步:训练模型,检测垃圾信息
我们使用向量形式的信息来训练 spam/ham 分类器。这部分很简单,有很多实现训练算法的库文件。
这里我们使用 scikit-learn,首先选择 Naive Bayes 分类器:
我们来试着分类一个随机信息:
太棒了!你也可以用自己的文本试试。
有一个很自然的问题是:我们可以正确分辨多少信息?
有相当多的指标都可以用来评估模型性能,至于哪个最合适是由任务决定的。比如,将“spam”错误预测为“ham”的成本远低于将“ham”错误预测为“spam”的成本。
第五步:如何进行实验?
在上述“评价”中,我们犯了个大忌。为了简单的演示,我们使用训练数据进行了准确性评估。永远不要评估你的训练数据。这是错误的。
这样的评估方法不能告诉我们模型的实际预测能力,如果我们记住训练期间的每个例子,训练的准确率将非常接近 100%,但是我们不能用它来分类任何新信息。
一个正确的做法是将数据分为训练集和测试集,在模型拟合和调参时只能使用训练数据,不能以任何方式使用测试数据,通过这个方法确保模型没有“作弊”,最终使用测试数据评价模型可以代表模型真正的预测性能。
让我们回顾整个流程,将所有步骤放入 scikit-learn 的 Pipeline 中:
在这个例子里,一切进展顺利:
得分确实比训练全部数据时差一点点( 5574 个训练例子中,准确性 0.97),但是它们相当稳定:
我们自然会问,如何改进这个模型?这个得分已经很高了,电动叉车 但是我们通常如何改进模型呢?
换句话说:
- 高偏差 = 分类器比较固执。它有自己的想法,数据能够改变的空间有限。另一方面,也没有多少过度拟合的空间(左图)。
- 低偏差 = 分类器更听话,但也更神经质。大家都知道,让它做什么就做什么可能造成麻烦(右图)。
随着性能的提升,训练和交叉验证都表现良好,我们发现由于数据量较少,这个模型难以足够复杂/灵活地捕获所有的细微差别。在这种特殊案例中,不管怎样做精度都很高,这个问题看起来不是很明显。
关于这一点,我们有两个选择:
- 使用更多的训练数据,增加模型的复杂性;
- 使用更复杂(更低偏差)的模型,从现有数据中获取更多信息。
在过去的几年里,随着收集大规模训练数据越来越容易,机器越来越快。方法 1 变得越来越流行(更简单的算法,更多的数据)。简单的算法(如 Naive Bayes)也有更容易解释的额外优势(相对一些更复杂的黑箱模型,如神经网络)。
第六步:如何调整参数?
到目前为止,我们看到的只是冰山一角,还有许多其它参数需要调整。比如使用什么算法进行训练。
上面我们已经使用了 Navie Bayes,但是 scikit-learn 支持许多分类器:支持向量机、最邻近算法、决策树、Ensamble 方法等…
我们会问:IDF 加权对准确性有什么影响?消耗额外成本进行词形还原(与只用纯文字相比)真的会有效果吗?
让我们来看看:
(首先显示最佳参数组合:在这个案例中是使用 idf=True 和 analyzer=split_into_lemmas 的参数组合)
快速合理性检查
predict_proba 返回每类(ham,spam)的预测概率。在第一个例子中,消息被预测为 ham 的概率 >99%,被预测为 spam 的概率 <1%。如果进行选择模型会认为信息是 ”ham“:
在训练期间没有用到的测试集的整体得分:
让我们尝试另一个分类器:支持向量机(SVM)。SVM 可以非常迅速的得到结果,它所需要的参数调整也很少(虽然比 Navie Bayes 稍多一点),在处理文本数据方面它是个好的起点。
因此,很明显的,具有 C=1 的线性核函数是最好的参数组合。
再一次合理性检查:
这是我们使用 SVM 时可以从 spam 邮件检测流程中获得的实际预测性能。
第七步:生成预测器
生成预测器的最后一步是再次对整个数据集合进行训练,以充分利用所有可用数据。当然,我们将使用上面交叉验证找到的最好的参数。这与我们开始做的非常相似,但这次深入了解它的行为和稳定性。在不同的训练/测试子集进行评价。
最终的预测器可以序列化到磁盘,以便我们下次想使用它时,可以跳过所有训练直接使用训练好的模型:
加载的结果是一个与原始对象表现相同的对象:
生产执行的另一个重要部分是性能。经过快速、迭代模型调整和参数搜索之后,性能良好的模型可以被翻译成不同的语言并优化。可以牺牲几个点的准确性换取一个更小、更快的模型吗?是否值得优化内存使用情况,或者使用 mmap 跨进程共享内存?
请注意,优化并不总是必要的,要从实际情况出发。
还有一些需要考虑的问题,比如,生产流水线还需要考虑鲁棒性(服务故障转移、冗余、负载平衡)、监测(包括异常自动报警)、HR 可替代性(避免关于工作如何完成的“知识孤岛”、晦涩/锁定的技术、调整结果的黑艺术)。现在,开源世界都可以为所有这些领域提供可行的解决方法,由于 OSI 批准的开源许可证,今天展示的所有工具都可以免费用于商业用途。
其他实用概念
数据稀疏性
在线学习,数据流
用于内存共享的 mmap,系统“冷启动”负载时间
无监督学习
大多数数据没有结构化。了解这些数据,其中没有自带的标签(不然就成了监督学习!)。
我们如何训练没有标签的内容?这是什么魔法?
分布假设“在类似语境中出现的词倾向于具有相似的含义”。上下文=句子,文档,滑动窗口……
查看 google 关于无监督学习的 word2vec 在线演示。简单的模型、大量数据(Google 新闻,1000 亿词,没有标签)。
下一步做什么?
这个 notebook 的静态版本(非交互版本)的 HTML,地址: http://radimrehurek.com/data_science_python (你可能已经在看了,但以防万一)
交互式 notebook 源文件在 GitHub 上,
http://radimrehurek.com/data_science_python/data_science_python.ipynb(见上面的安装说明)。
- Python 中的实用数据挖掘
- 【Python数据挖掘】实用模块之Pandas
- 盘点:数据挖掘中的十大实用方法
- 数据挖掘:实用案例分析
- Python 数据挖掘小结
- python数据挖掘
- python数据挖掘orange
- python 数据挖掘
- python数据挖掘
- 利用python中的pandas,sklearn进行数据挖掘 basic_of_datamining
- 【python数据挖掘课程】十.Pandas、Matplotlib、PCA绘图实用代码补充
- python数据挖掘课程 十.Pandas、Matplotlib、PCA绘图实用代码补充
- 干货 | 数据挖掘中的十大实用方法,可能你并不一定都熟悉!
- 电子政务中的数据挖掘
- 电子政务中的数据挖掘
- 数据挖掘中的中位数
- 数据挖掘中的中位数
- 数据挖掘中的基本概念
- MessagePack简介及使用
- Java多线程学习
- (转载)JVM基础知识
- 【共享打印机遇到的各种问题】局域网内连接共享打印机—如何不用打印机路由,在多台电脑使用打印机
- 算法题:从数组找数字(网易2017校园招聘)
- Python 中的实用数据挖掘
- WebService详解
- leetcode---remove-nth-node-from-end-of-list---链表
- [LeetCode]405. Convert a Number to Hexadecimal
- ODBC连接数据库实例
- 深入理解java虚拟机-第二章:垃圾收集算法
- ue4 weapon
- android事件传递全解析
- R_ggplot2作图原理