前言及序章
本书的主要内容:原理简述+问题实例+实际代码+运行效果
机器学习:把无序的数据转换成有用的东西
数据分析与挖掘的基本技能:针对具体任务,搞懂所有相关数据的意义
如何选择合适的算法:(1)想要算法满足什么任务?(2)需要分析或收集的数据是什么?
发现最佳算法的关键环节:反复试错
开发机器学习应用程序的步骤:(1)收集数据,(2)准备输入数据(数据格式),(3)分析输入数据(缺失值、异常值、可视化展示),(4)训练算法,(5)测试算法,(6)使用算法(将其转为应用程序,执行实际任务)
Numpy函数库(有待学习)
第一部分:分类
1. k-近邻算法
优点:精度高、对异常值不敏感、无数据输入假定
缺点:计算复杂度高、空间复杂度高
适用数据范围:数值型与标称型
k近邻算法(核心)
def classifier0(inX, dataset, labels, k):
datasetSize = dataset.shape[0]
diffMat = tile(inX, (datasetSize, 1)) - dataset
distance = ((diffMat**2).sum(axis=1))**0.5
sortedDistIndicies = distance.argsort()
classcount = {}
for i in range(k):
voteILabel = labels[sortedDistIndicies[i]]
classcount[voteILabel] = classcount.get(voteILabel, 0) + 1
sortedClassCount = sorted(classcount.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
算法中所使用的函数
tile(A,(m,n)),将数组A在行上重复m次、在列上重复n次,构成一个新的数组
numpy.argsort(),返回数组值从小到大的索引值
dict.get(key, default=None),返回指定键的值,如果值不在字典中返回默认值None
sorted(iterable[, cmp[, key[, reverse]]])
iterable可迭代对象。
cmp比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,大于则返回1,小于则返回-1,等于则返回0。
key主要是用来进行比较的元素,只有一个参数,取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
reverse排序规则,True降序,False升序(默认)
详细代码见链接:https://blog.youkuaiyun.com/hu_pengxue/article/details/80894279
小结:k-近邻算法是基于实例的学习,使用算法使必须有接近实际数据的训练样本数据。k-近邻必须保存全部数据,有时候会使用大量的存储空间,同时计算数据集中每个数据的距离值也非常耗时。此外,k-近邻无法给出数据的基础结构信息,无法得知平均实例样本与典型实例样本有什么特征。
2. 决策树
优点:计算复杂度不高,输出结果容易理解,对中间值的缺失不敏感,可以处理不相关特征数据。
缺点:可能会产生过度匹配
适用数据类型:数值型与标称型。
创建分支的伪代码createBranch()
检测数据集中所有数据是否数据同一个分类:
if 属于同一个分类,返回分类标签
else
寻找划分数据的最佳特征
划分数据集,创建分支节点
for 每个划分的子集
调用创建分支的代码createBranch()
返回分支节点
如何寻找划分数据集的最好特征?
对每个特征划分数据集的结果计算一次信息熵,根据信息增益最大化选择最佳划分特征。
相关知识补充:
集合信息的度量方式称为“信息熵”,定义如下:
符号的信息为:,其中
是选择该分类的概率
所有类别所有可能值包含的信息为:
熵越大,集合的混乱程度/无序程度越大
集合无序程度的另外一种度量方法是“基尼不纯度”,定义如下:
从一个数据集中随机选择子项,度量其被错误分类到其他组的概率
基尼不纯度越大,集合的混乱程度/无序程度越大
决策树程序的几个难点
1) 递归:创建与使用决策树时都用到了递归函数(或者说这两个函数都是递归函数)。伪代码中关于递归的思路非常清晰,就是在划分的子集中在调用函数本身,但是在写代码时很容易陷入细节中想不明白。
2) 决策树的数据结构比较复杂,多看几次,结合图形好好理解即可。
{'nosurfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
决策树详细代码见链接:https://blog.youkuaiyun.com/hu_pengxue/article/details/80902693
绘制决策树详细代码见链接:https://blog.youkuaiyun.com/hu_pengxue/article/details/80902704
3. 朴素贝叶斯
优点:在数据较少的情况下依然有效,可以处理多类别问题,计算量比较小
缺点:对于输入数据的准备方式比较敏感
适用的数据类型:标称型数据
贝叶斯决策理论
数据点(x ,y)属于类别1的概率为p1(x ,y),属于类别2的概率为p2(x ,y)
如果p1(x ,y)> p2(x ,y),数据点(x ,y)属于类别1
如果p2(x ,y)> p1(x ,y),数据点(x ,y)属于类别2
条件概率
使用条件概率来分类
给定数据点(x, y),该数据点来自类别ci的概率是多少?
如果,数据点属于c1
朴素贝叶斯分类器的假设
(1) 特征之间相互独立,即一个特征出现的可能性与其他特征是否出现无关。
(2) 每个特征同等重要
注:使用朴素贝叶斯分类器进行文档分类时其实并没有满足这两个假设,但实际效果却很好。
使用条件概率来进行文本分类
(1)数据准备:
从文本中构建词向量
词集模式(set-of-words)单词是否出现为特征(0没出现,1出现)
词袋模式(bag-of-words)单词出现次数为特征
(2)算法原理:
w为文本的与单词有关的特征,即w=(w0,w1,w2,w3…wn)
根据特征相互独立的假设,可以计算多个概率的乘积来获得文档处于某个类别的概率。(构造与使用朴素贝叶斯分类器时不用求p(w),只计算分子即可)
(3)根据现实修改分类器
如果某个概率为0,最后的乘积也为0。为了降低这种影响,将所有词出现数初始化为1,分母初始化为2
另外,太多很小的数相乘将造成下溢出,最后四舍五入为0。解决这个问题可以对乘积取自然对数ln(a*b)=ln(a)+ln(b)
从网站信息中获取区域倾向
RSS(Really Simple Syndication)简易信息集合,使用RSS订阅能更快地速获取信息和获取网站内容的最新更新,可以通过阅读器一次一起阅读所有你订阅了的网站的最新内容。每个 RSS 和 Atom 订阅源都包含一个标题(d.feed.title)和一组文章条目(d.entries)。通常,每个文章条目都有一段摘要(d.entries[i].summary),或者是包含了条目中实际文本的描述性标签(d.entries[i].description)。
feedparser是Python中最常用的RSS程序库,可以从任何 RSS 或 Atom 订阅源得到标题、链接和文章的条目等信息。核心函数parse() 用于解析 URL 地址,返回entries, feed,encoding,vision等
Craigslist个人广告链接已经找不到了,改用该网站的社会事件event与政治politics的RSS源
https://newyork.craigslist.org/search/eve?format=rss&sale_date=2018-06-11
https://losangeles.craigslist.org/search/eve?format=rss&sale_date=2018-06-11
https://newyork.craigslist.org/search/pol?format=rss
https://sfbay.craigslist.org/search/pol?format=rss
垃圾邮件过滤错误率仅2%,而根据网站信息推断地域的错误率在30%-45%之间。可能是社会事件与政治信息的区域差异不大。Q:是否还有其他原因?
去除高频词对分类结果的影响。高频词如果是语法辅助词,如the,在所有文本中的出现频率都很高,去除后会降低预测错误率;但如果高频词反映了某类文本的特征,去除后会降低预测错误率。何去何从?经验很重要。
详细代码见链接:https://blog.youkuaiyun.com/hu_pengxue/article/details/80909616
(未完待续)