在监督学习中,我们只需要输入给定的样本集,机器就可以推出指定目标变量的可能结果。监督学习一般使用两种类型的目标变量:标称值和数值型。标称值目标变量只在有限目标中取值,数值型目标变量则从无限的数值中取值。
分类算法:第二章:k-近邻算法,使用距离矩阵进行分类;
第三章:决策树;
第四章:讨论使用概率论建立分类器;
第五章:Logistic回归;使用最有参数正确分类原始数据,在搜索最优参数的过程中常用的集中优化算法;
第六章:支持向量机;
第七章:元算法:AdaBoost
Numpy函数库的使用基础:
>>>random.rand(4,4)
将会构造一个4*4的随机数组
Tip: Numpy函数库中会存在两种不同的数据类型(矩阵matrix和数组array),都可以用于处理行列表示的数字元素,虽然看起来很相似,但是在两个数据类型上执行相同的数学运算可能会产生不同的结果。
使用mat()函数可以将数组转化为矩阵;.I操作符可以实现矩阵求逆
下面我们将介绍本书的第一个分类算法:k—近邻算法(KNN)
简单的说,K-近邻算法采用测量不同特征值之间的距离进行分类;
优点:精度高,对异常值不敏感,无数据输入假定;
确定:计算复杂度高,空间复杂度高;
适用于数值型和标称型。
工作原理:训练样本中每个数据都有标签,即我们知道每一数据所对应所属分类的对应关系,在输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似的数据(最近邻)的分类标签。一般来说,我们只提取数据集中前K个最相似的数据,这就是K的出处(一般不大于20)。最后我们选择K个最相似数据中出现次数最多的分类作为新标签的分类。
k-近邻算法的一般流程:
(1)收集数据:任意方法收集;
(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式;
(3)分析数据:可以使用任何方法;
(4)训练算法:此步骤不适合k-近邻算法;
(5)测试算法:计算错误率;
(6)使用算法:首先需要驶入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入的数据分别属于哪一类,最后应用对计算出的分类结果执行后续的处理。
1、准备:使用python导入数据
创建KNN.py文件
from numpy import *
import operator
"""
科学计算包和运算符模块
k-近邻算法在执行排序操作是使用这个模块提供的函数
"""
def createDataset():
group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
//注意array中()内还有[],在存入各个数组
labels = ['A','A','B','B']return group,labels
为了方便,使用createDataset()函数,它用来创建数据集和标签。保存KNN.py文件,在新的模块中导入KNN.py
这里的四组数据,每组数据有两个我们已知的属性或特征值。group矩阵每行包含一个不同的数据,向量labels包含元素的个数等于group的矩阵行数。下图是带有标签的四个数据点。
2、从文本中解析数据
使用程序清单2-1的函数运行KNN算法为每组数据进行分类。该函数的功能是使用KNN算法将每组数据划分到某个类中。
首先给出KNN的算法和伪代码和实际的python代码
对未知的类别属性的数据集中的每个点依次执行一下操作:
(1)计算已知类别数据集中的点与当前点之间的距离;
(2)按照距离递增排序;
(3)选取与当前点距离最小的K个点;
(4)确定前K个点所在类别的出现频率;
(5)返回前K个点出现频率最高的类别作为当前点的预测分类。
函数classify0()如程序清单2-1所示:
import KNN
from numpy import *
import operator
group,labels = KNN.createDataset()
def classify0(inX, dataSet, labels, k):
"""
用于分类的输入向量:inX
输入训练集:dataSet
标签向量:labels
选择近邻的数目:k
"""
#标签向量的元素和矩阵dataSet的行数相同,dataSetSize为行数
dataSetSize = dataSet.shape[0]
#将inX向量按行重复dataSetSize次,列重复一次,变成与dataSet一样的形式,并计算差值diffMat
diffMat = tile(inX, (dataSetSize,1)) - dataSet
#对差值求平方
sqDiffMat = diffMat**2
#axis=1 把每一行向量的值加在一起求和
sqDistances = sqDiffMat.sum(axis=1)
#开平方
distances = sqDistances**0.5
#argsort():将x中的元素从小到大排列,提取其对应的index(索引),然后输出索引
sortedDistIndicies = distances.argsort()
classCount={}
for i in range(k):
#sortedDistIndicies[i]返回的是distances中排在第i个数值的索引
#labels[i]:即返回的是第i个位置的向量的标签存入voteIlabel
voteIlabel = labels[sortedDistIndicies[i]]
#更新字典中对应标签的数值
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
"""
sorted(iterable[, cmp[, key[, reverse]]])
参数解释:
(1)iterable指定要排序的list或者iterable,不用多说;
(2)cmp为函数,指定排序时进行比较的函数,可以指定一个函数或者lambda函数,如:
students为类对象的list,每个成员有三个域,用sorted进行比较时可以自己定cmp函数,例如这里要通过比较第三个数据成员来排序,代码可以这样写:
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
sorted(students, key=lambda student : student[2])
(3)key为函数,指定取待排序元素的哪一项进行排序,函数用上面的例子来说明,代码如下:
sorted(students, key=lambda student : student[2])
key指定的lambda函数功能是去元素student的第三个域(即:student[2]),因此sorted排序时,会以students所有元素的第三个域来进行排序。
有了上面的operator.itemgetter函数,也可以用该函数来实现,例如要通过student的第三个域排序,可以这么写:
sorted(students, key=operator.itemgetter(2))
sorted函数也可以进行多级排序,例如要根据第二个域和第三个域进行排序,可以这么写:
sorted(students, key=operator.itemgetter(1,2))
"""
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
#这里python3的写法是classCount.items()与原书不同
return sortedClassCount[0][0]
以之前创建的训练集,调用分类函数可得到的分类结果如上所示。
程序清单2-1使用欧氏距离公式,计算两个向量点xA,xB之间的距离
计算完所有的距离后,对数据按从小到大进行排序,确定前k个距离最小元素所在的主要分类。