在之前介绍的kNN算法属于一种分类算法,之后会介绍的决策树也是属于分类算法。分类算法的目的就是根据训练集的特征将新的数据进行预测,当然能够找到特征之间的联系越多那么最后的分类结果也就应该越准确。但是有没有一个比较简单的算法,能够使用极少的特征就能够进行简单的分类呢?那就是OneR算法了。


OneR算法介绍。

OneR的全称为:One Rule,顾名思义也就是一条规则的意思。也就是说我们最终仅仅根据训练集中的一个特征就能够实现对数据的分类。如果只是使用一条规则的话,很显然这个分类的准确度不会很高,但是在某些特定的数据集中这个简单的算法也能够得到比较好的表现。

为了明白这个算法的工作原理,首先举一个比较简单的例子:就拿人的身高和眼睛大小以及肤色的数据对人进行分类是男是女。其中的编号不属于特征范畴,只是为了后续介绍数据使用。

编号 身高 眼睛大小 肤色 性别
1 180 正常 偏白
2 175 较大 偏黑
3 170 正常 偏黑
4 170 较大 偏黑
5 165 正常 偏白
6 160 较大 偏白

上述表格中随机写了一系列数据,我们来根据这些数据介绍一下OneR算法。

既然OneR算法是根据一个规则,也就是某一个特征来进行分类的,那么如何找到这个规则就比较重要了。

就拿上述的例子来看,我们有:身高、眼睛大小、肤色这三种特征,身高是属于连续值的范畴,眼睛大小是属于离散数据为:正常、较大,肤色也是离散数据:偏白、偏黑。

我们首先使用简单的方法将其转换为离散值,将大于(或等于)身高平均值的记为1,小于身高平均值的记为0,那么现在的数据就是这样。

编号 身高 眼睛大小 肤色 性别
1 1 正常 偏白
2 1 较大 偏黑
3 1 正常 偏黑
4 1 较大 偏黑
5 0 正常 偏白
6 0 较大 偏白

接下来我们就需要根据这些数据找到一个可以用来分类的特征规则。这个特征究竟是根据身高、眼睛大小、肤色呢?

其实根据我们的生活常识,知道在这三种特征中身高的可靠性比较高的。但是如何根据计算找到身高这个特征呢?


如何找到用来分类的规则(特征)。

其实简单的想一下就知道了,当然是使用这个特征之后我们的划分结果的正确率是最高的。我们需要进行一些简单的计算,要确保使用这个特征进行分类得到的准确率最高。因为只有准确率最高我们才能够得到比较正确的分类结果,所以我们的任务就可以转换为找到一个特征,根据这个特征进行分类的时候能够得到最高的正确率。

但是要明白,某个特征可能会有多个特征值,所以计算特征的准确率的话,需要包含其中的所有特征值可能性。也就是说这个特征的准确率是根据所有的特征值计算出来的。而对于某个特征对应的特征值来看,当然是选择分类最多的那个作为本次特征值的分类结果,然后再根据本次特征值的分类结果计算出错误个数。最后汇总到一起计算出该特征的准确率。

下面对上述样本集中的身高、眼睛大小、肤色分别计算准确率。

  • 身高。

    我们可以看到身高这个特征共有两种特征值:0和1。

    如果身高特征值为1的话,那么符合特征值的数据编号为:{1,2,3,4},对应的分类为:{男,男,男,女}。很明显如果身高这个特征值为1的话,在本次样本集中男生占了3/4,女生占了1/4。那么我们就选择分类结果最多的那个作为身高特征值为1的划分结果,也就是性别为男。所以现在可以简单的认为如果身高特征值为1的话,我们就简单的认为性别为男。但是很显然这个结论是有错误的,在本次样本集中这个结论的错误个数为1,因为在身高特征值为1的情况下有1样本的性别为女,与我们的结论不符。

    如果身高特征值为0的话。那么符合特征值的数据编号为:{5,6},对应的分类为:{女,女}。这个计算结果比较明显了。如果身高特征值为0的话,女生占了2/2。那么我们就选择性别为女作为身高特征值为0的分类结果。也就是说如果身高的特征值为0的话,我们就认为性别为女。这个结论可能有错误,但是在本次的数据集中是全部正确的。

    在计算完身高的全部特征值之后就可以计算准确率了,我们在身高特征值为0的情况下,我们将其划分为女,这个准确率为百分之百。在身高特征值为1的情况下我们将其划分为男,有一个数据是错误的。所以如果按照身高进行划分的话,得到的准确率为:5/6=0.833。

  • 眼睛大小。

    眼睛大小这个特征共有两种特征值:正常、较大。

    如果眼睛大小是正常的话,符合特征值的数据编号为:{1,3,5},对应的分类结果为:{男,男,女}。同样的男生占了2/3,女生占了1/3,那么就简单的认为如果眼睛大小为正常的话,就认为性别为男性。同样的在本次数据集中,这个结论的错误个数为1,因为当前特征值分类结果中有一个是女性。

    如果眼睛大小是较大的话,符合特征值的数据编号为:{2,4,6},对应的分类结果为:{女,女,男}。同样的女生占了2/3,男生占了1/3,那么就简单的认为如果眼睛大小为较大的话,就认为性别为女性。同样的在本次数据集中,这个结论的错误个数为1。

    有关眼睛大小的所有特征值计算完成之后就可以计算准确率了。我们在眼睛大小为正常的情况下,将其划分为男,这个结论在样本集中有一个数据是错误的;同样的在眼睛大小为较大的情况下,将其划分为女,这个结论在样本集中有一个数据是错误的。所以如果按照眼睛大小进行划分的话,准确率为:4/6=0.667。

  • 肤色。

    肤色特征共有两个特征值:偏黑、偏白。

    如果肤色偏黑的话,符合特征值的数据编号为:{2,3,4},对应的分类结果为:{男,男,女}。男生占了2/3,女生1/3。所以如果肤色偏黑的话,就简单认为是男生,这个结论的错误个数为1。

    如果肤色偏白的话,符合特征值的数据编号为:{1,5,6},对应的分类结果为:{男,女,女}。男生占了1/3,女生占了2/3,。所以如果肤色偏白的话,就简单的认为是女生,这个结论的错误个数为1。

    所以肤色的准确率为:4/6=0.667。

现在得到了各个特征的准确率。身高的划分准确率为:0.833;肤色和眼睛大小的准确率都为:0.667。所以我们使用身高作为划分特征。

也就是如果有新的数据,我们只看身高这一项数据就将其进行分类。但是分类器的准确率的话是需要使用测试数据进行计算的,我们计算出来的0.833只是根据训练样本集的准确率,只是为了找出用来划分的规则。


使用Python实现OneR算法。

下面使用Python实现OneR算法,我们首先回顾一下上面的计算流程。首先我们找到每个特征的所有特征值,然后根据每个特征值的分类结果对这个特征值进行了简单分类(比如肤色偏黑的情况下,我们就认为是男性),接下来找出每个特征值的分类错误个数(比如说肤色偏黑我们认为是男性,但是在样本集中存在一个女性偏黑,所以错误个数为1),最后计算出这个特征的准确率,然后找到准确率最高的作为划分规则。

1.创建数据集。

def createDataSetForPerson():"""使用身高、眼睛大小、肤色作为数据集:return:"""dataSet = [# 1[1, '正常', '偏白', '男'],# 2[1, '较大', '偏黑', '男'],# 3[1, '正常', '偏黑', '男'],# 4[1, '较大', '偏黑', '女'],# 5[0, '正常', '偏白', '女'],# 6[0, '较大', '偏白', '女'],]# 特征值列表labels = ['身高', '眼睛大小', '肤色']dataSet = np.array(dataSet)# 得到分类结果classify = dataSet[:, -1]# 去除分类之后的数据集dataSet = dataSet[:, :-1]return dataSet, classify, labels

查看一下该函数的返回结果:

2.对某个特征的特征值进行分类和计算错误个数。

def train_feature_value(dataSet, classify, feature_index, value):"""根据传入的样本集和分类集,计算某个特征等于目标特征值时最可能属于哪一个分类,计算出错误个数:param dataSet: 数据集:param classify: 数据集对应的分类结果:param feature_index: 特征下标:param value: 特征值:return:"""# 用来保存每个分类的个数class_counts = defaultdict(int)# 遍历所有的样本数据和对应的标签for sample, label in zip(dataSet, classify):# 如果当前样本的指定特征等于目标特征值的话if sample[feature_index] == value:# 对应的特征值个数加一class_counts[label] += 1# 根据分类的值排序,从大到小sorted_class_sounts = sorted(class_counts.items(), key=operator.itemgetter(1), reverse=True)# 找到对多的分类,也就是我们的目标分类most_class = sorted_class_sounts[0][0]# 在分类结果中找到分类不等于目标分类的incorrect_predictions = [class_count for class_value, class_count in class_counts.items()if class_value != most_class]# 计算出错误个数error = sum(incorrect_predictions)return most_class, error

使用该函数的返回结果:

第一个参数就是数据集,第二个参数是对应的分类结果,第三个参数是进行计算的特征下标,0对应的就是身高,第四个参数对应的就是当前特征的特征值,也就是说身高为1的情况。(这里用str类型的1是因为numpy中的就为str)

输出结果:


也就是说如果身高为1的情况下,我们会将其划分为男性,但是会有1个错误,这个与我们上面的计算结果一致。

当我们更换为其他的数据之后,也会得到与上面计算相同的结果:

3.计算某个特征划分的正确率(在这里计算的最小的错误率)。

我们在计算完某个特征的全部特征值之后,就需要根据对应的错误个数计算出这个特征划分的正确率。我们在这里计算的是错误率,所以如果正确率最高的话,错误率应该就是最低的了。

def train_on_feature(dataSet, classify, feature_index):"""计算某一个特征的总错误率:param dataSet: 样本集:param classify: 样本集对应的分类结果:param feature_index: 特征下标:return:"""# 得到该特征对应的所有可能性current_feature_full = set(dataSet[:, feature_index])# 用来存放当前特征的所有特征值的预测分类predictors = {}# 用来存放所有特征的错误个数errors = []# 遍历所有的特征可能性for current_feature in current_feature_full:# 计算当前特征值的预测分类和错误个数most_class, error = train_feature_value(dataSet, classify, feature_index, current_feature)# 将最可能划分的结果加入到预测结果中predictors[current_feature] = most_classerrors.append(error)# 计算出当前特征值分类的错误率error_chance = sum(errors)/float(len(dataSet))return predictors, error_chance

编写一个测试代码,使用上述的函数对身高计算正确率:

输出结果:

能够看到,该函数有两个返回值,第一个就是对应特征值的预测分类,例如:{1,男,0:女}就是如果身高的特征值为1的话,我们就认为是男的,如果身高的特征值为0的话,我们就认为是女的。第二个返回值就是这个特征的错误率,使用1减去错误率之后就是正确率得到0.833,与上面的计算结果一致。

4.找到最好的划分特征,创建model。

下面就需要计算所有的特征准确率,然后找到准确率最高的哪一个作为OneR算法的划分规则。

def createModel(dataSet, classify):"""实现OneR算法,找到特征错误率最低的特征作为划分结果,建立模型:param dataSet: 样本集:param classify: 样本集对应的分类:return:"""# 用来存放所有的预测特征all_predictors = {}# 用来存放所有预测特征的错误率errors = {}# 遍历所有的特征for feature_index in range(dataSet.shape[1]):# 使用当前特征进行预测predictors, total_error = train_on_feature(dataSet, classify, feature_index)# 存放当前的特征预测all_predictors[feature_index] = predictors# 存放当前的特征预测错误率errors[feature_index] = total_error# 找出错误率最低的一个,用来划分特征best_feature, best_error = sorted(errors.items(), key=operator.itemgetter(1))[0]# 建立模型model = {'variable': best_feature, 'predictor': all_predictors[best_feature]}return model

测试代码:

输出结果:

能够看到这个model的输出内容,其中variable就是用来进行划分的那一个特征规则下标,其中predictor就是使用这个特征的话每个特征值的分类结果。比如图中的输出variable是0,就是身高的下标,所以predictor的输出内容就是当身高特征值为0的情况下我们认为是女,当身高特征值为1的情况下我们认为是男。

到现在为止,我们已经使用代码实现了OneR算法,并且建立了模型。也正如oneR算法那样描述的一样,仅仅根据身高这一项特征进行分类。

5.使用model进行预测。

创建完model之后,我们就可以使用model对数据进行分类预测了。

def classifyOneR(inX, model):"""使用OneR进行预测分类:param inX: 要进行预测的数据:param model: 建立的模型:return:"""# 拿到模型中用来分类的特征下标variable = model['variable']# 拿到特征对应的划分集predictor = model['predictor']# 进行分类classify = predictor[inX[variable]]return classify

我们对一个新的数据进行预测:

能够看到输出结果为:男。

总结。

OneR算法是很简单的一个分类方法,能够快速的建立模型进行分类预测。主要的核心思想就是在数据集的所有特征中,找到最重要的那个特征进行分类。当然这个最重要的特征就是根据数据集中的每个特征划分的准确性进行查找。

由于OneR算法会找到最主要的那个特征,从而忽略了其他的特征,并不能完全的利用好数据的全部特征。所以其准确率相对就比较低了,但是在某些情况下,往往会存在某个最重要的特征条件。比如就是例子中的情况,在人类中对男女的身高体重差异还是比明显的,其他特征在这两种特征下就显得稍微不足。但是仅仅根据身高体重来划分也不会太准确,如果能够利用好其他的特征,找到其中的关系的话分类结果会准确很多。

除了文中使用的数据集之外,本人还使用了西瓜书中的西瓜数据和sklearn自带的Iris职务分类数据集进行测试,代码地址:OneR实现代码。

简单明了的分类算法:OneR。相关推荐

  1. Python数据挖掘入门与实践-OneR分类算法

    Python数据挖掘入门与实践-OneR分类算法 OneR算法 OneR算法是根据已有的数据中,具有相同特征值的个体最可能属于哪个类别进行分类. 在本例中,只需选区Iris是个特征中分类效果最好的一个 ...

  2. 朴素贝叶斯Naïve Bayes分类算法在Hadoop上的实现

    1. Naïve Bayes算法介绍 Naïve Bayes是一个简单有效的分类算法,已经得到广泛使用.本文讨论了海量数据(TB级)下Naïve Bayes算法的实现方法,并给出了Hadoop上的实现 ...

  3. [Python从零到壹] 十四.机器学习之分类算法五万字总结全网首发(决策树、KNN、SVM、分类对比实验)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  4. 数据挖掘分类算法的学习总结

    一.中文摘要 大数据时代的我们每时每刻都在产生海量数据,如何快速准确获取其中有价值的数据一直是亟待解决的问题.数据挖掘技术的应运而生为该问题提供了解决手段,作为数据挖掘核心内容之一的分类算法同样发挥了 ...

  5. python分类算法的应用_Python基于sklearn库的分类算法简单应用示例

    Python基于sklearn库的分类算法简单应用示例 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  Python基于sklearn库的分类算法简单应用示例.tx ...

  6. python分类算法的应用_Python使用sklearn库实现的各种分类算法简单应用小结

    本文实例讲述了Python使用sklearn库实现的各种分类算法简单应用.分享给大家供大家参考,具体如下: KNN from sklearn.neighbors import KNeighborsCl ...

  7. 分类算法学习(二)——贝叶斯算法的原理及简单实现

    1.3.贝叶斯分类的基础--贝叶斯定理 每次提到贝叶斯定理,我心中的崇敬之情都油然而生,倒不是因为这个定理多高深,而是因为它特别有用.这个定理解决了现实生活里经常遇到的问题:已知某条件概率,如何得到两 ...

  8. SVM分类算法的基本理论问题

    1.引言  随着网络技术的飞速发展和普及,进入了信息大爆炸的时代.信息无处不在,给我们的学习生活带来了诸多便捷,由于堪称海量的信息量,我们从中获取有用的信息变得困难,解决这一难题就是要对这些大量的信息 ...

  9. 基于Adaboost的音乐情绪分类算法

    基于Adaboost的音乐情绪分类算法-2015实习设计总结 ========================================= 基于Adaboost的音乐情绪分类算法-2015实习设 ...

最新文章

  1. shanghai road map and the operational time for 12306 system
  2. NYOJ 士兵杀敌(二) 树状数组
  3. Java Arrays.asList()方法详解
  4. HDU4321(位运算二进制1的统计)
  5. JQuery-Dialog(弹出窗口,遮蔽窗口)
  6. 继续深入更新shell脚本容易出错的地方
  7. 无人机rtmp推流直播解决方案
  8. Perl面向对象编程
  9. mysql的备份与还原步骤_MySQL备份与还原
  10. CSS特效八:开关按钮
  11. Java复习攻略02
  12. 点集的读入与输出操作
  13. 智能相机与工业相机_使用智能手机相机后如何移动到专用相机
  14. 方方格子excel工具箱 Excel表格处理必备
  15. 华为云WeLink是什么软件?什么远程办公软件好用?
  16. 订单交期迟滞,销售回应慢,怎么解决客户问题?
  17. 基于QGraphicsView的简易画板EasyCanvas -- 第一版
  18. 树莓派+神经计算棒2部署Openvino的human_pose_estimation_demo实例
  19. web常见攻击及防范措施
  20. 在线短视频秒播优化之视频文件格式之MP4文件Moov box的位置

热门文章

  1. Python+Vue计算机毕业设计网上美妆购物商城8k7w5(源码+程序+LW+部署)
  2. Amy-Tabb机器人世界手眼标定(1、环境搭配)
  3. 蛮荒搜神记服务器在维护,蛮荒搜神记法宝洗练图文教程 蛮荒搜神记如何提升战斗力?-游侠网...
  4. 安装glib2.6x
  5. 【第二章 语言及文法】形式语言与自动机第二章个人总结复习笔记分享!(含文件、持续更新...)
  6. 物联网iot私有云平台搭建
  7. Swift教程-视频拍摄教程
  8. Mac OS X系统下修改wifi共享的默认网段
  9. 利用pyppeteer自动购买某麦网演唱会门票
  10. 上顿号符号_顿号在键盘上怎么打 常见的电脑符号输入方法说明