Weka算法Classifier-tree-J48源码分析(三)ModelSelection

机器学习:WEKA的应用之 J48(C4.5) 对于机器学习分类问题的解决方法除了SVM(支持向量机)、maxent(最大熵)还有J48和Adaboost,这两项工具箱都有集成在weka里,下面先说一下对J48即C4.5的应用 weka的下载与安装 什么是J48(C4.5) weka中J48(C4.5)的应用 一、weka的下载与安装 下载地址:weka下载地址(SourceForge) 我用的是win7的32位系统, 阅读详情


ModelSelection主要是用于选择合适的列对数据集进行分割,结合上一篇J48的主流程,发现用到的ModelSelection有 C45ModelSelection以及BinC45ModelSelection,先来分析C45ModelSelection。


一、C45ModelSelection

首先作为一个ModelSelection接口,实现的主要方法有两个,分别是selectModel(Instances)和selectionModel(Instances,Instances)。C45ModelSelection的后一个方法如下:

  public final ClassifierSplitModel selectModel(Instances train, Instances test) {

    return selectModel(train);
  }
可以看到就是忽略了test测试集直接调用selectModel方法而已,因此主要分词selectModel方法。

先放出整段代码,然后对该段代码进行分析:

public final ClassifierSplitModel selectModel(Instances data){

    double minResult;
    double currentResult;
    C45Split [] currentModel;
    C45Split bestModel = null;
    NoSplit noSplitModel = null;
    double averageInfoGain = 0;
    int validModels = 0;
    boolean multiVal = true;
    Distribution checkDistribution;
    Attribute attribute;
    double sumOfWeights;
    int i;
    
    try{

      // Check if all Instances belong to one class or if not
      // enough Instances to split.
      checkDistribution = new Distribution(data);
      noSplitModel = new NoSplit(checkDistribution);
      if (Utils.sm(checkDistribution.total(),2*m_minNoObj) ||
	  Utils.eq(checkDistribution.total(),
		   checkDistribution.perClass(checkDistribution.maxClass())))
	return noSplitModel;

      // Check if all attributes are nominal and have a 
      // lot of values.
      if (m_allData != null) {
	Enumeration enu = data.enumerateAttributes();
	while (enu.hasMoreElements()) {
	  attribute = (Attribute) enu.nextElement();
	  if ((attribute.isNumeric()) ||
	      (Utils.sm((double)attribute.numValues(),
			(0.3*(double)m_allData.numInstances())))){
	    multiVal = false;
	    break;
	  }
	}
      } 

      currentModel = new C45Split[data.numAttributes()];
      sumOfWeights = data.sumOfWeights();

      // For each attribute.
      for (i = 0; i < data.numAttributes(); i++){
	
	// Apart from class attribute.
	if (i != (data).classIndex()){
	  
	  // Get models for current attribute.
	  currentModel[i] = new C45Split(i,m_minNoObj,sumOfWeights);
	  currentModel[i].buildClassifier(data);
	  
	  // Check if useful split for current attribute
	  // exists and check for enumerated attributes with 
	  // a lot of values.
	  if (currentModel[i].checkModel())
	    if (m_allData != null) {
	      if ((data.attribute(i).isNumeric()) ||
		  (multiVal || Utils.sm((double)data.attribute(i).numValues(),
					(0.3*(double)m_allData.numInstances())))){
		averageInfoGain = averageInfoGain+currentModel[i].infoGain();
		validModels++;
	      } 
	    } else {
	      averageInfoGain = averageInfoGain+currentModel[i].infoGain();
	      validModels++;
	    }
	}else
	  currentModel[i] = null;
      }
      
      // Check if any useful split was found.
      if (validModels == 0)
	return noSplitModel;
      averageInfoGain = averageInfoGain/(double)validModels;

      // Find "best" attribute to split on.
      minResult = 0;
      for (i=0;i<data.numAttributes();i++){
	if ((i != (data).classIndex()) &&
	    (currentModel[i].checkModel()))
	  
	  // Use 1E-3 here to get a closer approximation to the original
	  // implementation.
	  if ((currentModel[i].infoGain() >= (averageInfoGain-1E-3)) &&
	      Utils.gr(currentModel[i].gainRatio(),minResult)){ 
	    bestModel = currentModel[i];
	    minResult = currentModel[i].gainRatio();
	  } 
      }

      // Check if useful split was found.
      if (Utils.eq(minResult,0))
	return noSplitModel;
      
      // Add all Instances with unknown values for the corresponding
      // attribute to the distribution for the model, so that
      // the complete distribution is stored with the model. 
      bestModel.distribution().
	  addInstWithUnknown(data,bestModel.attIndex());
      
      // Set the split point analogue to C45 if attribute numeric.
      if (m_allData != null)
	bestModel.setSplitPoint(m_allData);
      return bestModel;
    }catch(Exception e){
      e.printStackTrace();
    }
    return null;
  }
第一部分,主要是对局部变量的一些定义。

    double minResult;//最小的信息增益率
    double currentResult;//当前信息增益率
    C45Split [] currentModel;//存放所有未分类属性产生的模型
    C45Split bestModel = null;//目前为止的最好模型
    NoSplit noSplitModel = null;//代表不用分的模型
    double averageInfoGain = 0;//各模型(currentModel)的平均信息增益
    int validModels = 0;//是否存在有效模型
    boolean multiVal = true;//是否多值
    Distribution checkDistribution;//训练数据集的分布
    Attribute attribute;//属性列集合
    double sumOfWeights;//训练数据集的weight的和
    int i;//循环变量

第二部分,递归出口。

 checkDistribution = new Distribution(data);
      noSplitModel = new NoSplit(checkDistribution);
      if (Utils.sm(checkDistribution.total(),2*m_minNoObj) ||
	  Utils.eq(checkDistribution.total(),
		   checkDistribution.perClass(checkDistribution.maxClass())))
	return noSplitModel;
可以看到,如果当前数据集数量小于2*m_minNoObj(这个值默认是2),或者当前数据集已经全在同一个分类中,就返回noSplitModel代表不用分,这就是整个C45分类树节点停止分裂的条件。

第三部分,判断是否是多值:

      if (m_allData != null) {
	Enumeration enu = data.enumerateAttributes();
	while (enu.hasMoreElements()) {
	  attribute = (Attribute) enu.nextElement();
	  if ((attribute.isNumeric()) ||
	      (Utils.sm((double)attribute.numValues(),
			(0.3*(double)m_allData.numInstances())))){
	    multiVal = false;
	    break;
	  }
	}
      } 
如果属性中,任意一列是数值型,或者其取值的数量小于训练集数量*0.3,则不是多值,否则按多值处理。是否是多值影响到后面某些逻辑。

第四部分,对于每一列属性构造Spliter。

    for (i = 0; i < data.numAttributes(); i++){
	
	// Apart from class attribute.
	if (i != (data).classIndex()){
	  
	  // Get models for current attribute.
	  currentModel[i] = new C45Split(i,m_minNoObj,sumOfWeights);
	  currentModel[i].buildClassifier(data);
	  
	  // Check if useful split for current attribute
	  // exists and check for enumerated attributes with 
	  // a lot of values.
	  if (currentModel[i].checkModel())
	    if (m_allData != null) {
	      if ((data.attribute(i).isNumeric()) ||
		  (multiVal || Utils.sm((double)data.attribute(i).numValues(),
					(0.3*(double)m_allData.numInstances())))){
		averageInfoGain = averageInfoGain+currentModel[i].infoGain();
		validModels++;
	      } 
	    } else {
	      averageInfoGain = averageInfoGain+currentModel[i].infoGain();
	      validModels++;
	    }
	}else
	  currentModel[i] = null;
      }

对于每一列属性,如果不是存放分类的值得话,则构造C45Split对象,在该对象上进行分类,然后算出信息增益,相加到averageInfoGain上。对于C45Split的构造,稍后再看。

第五部分,选出最优模型。

 if (validModels == 0)
	return noSplitModel;
      averageInfoGain = averageInfoGain/(double)validModels;

      // Find "best" attribute to split on.
      minResult = 0;
      for (i=0;i<data.numAttributes();i++){
	if ((i != (data).classIndex()) &&
	    (currentModel[i].checkModel()))
	  
	  // Use 1E-3 here to get a closer approximation to the original
	  // implementation.
	  if ((currentModel[i].infoGain() >= (averageInfoGain-1E-3)) &&
	      Utils.gr(currentModel[i].gainRatio(),minResult)){ 
	    bestModel = currentModel[i];
	    minResult = currentModel[i].gainRatio();
	  } 

如果存在有效模型,则选出有效模型。注意这个选出最优模型的逻辑,并不是单纯的选出gainRatio最大的,而是在基础上必须还要大于平均信息增益,这也是和传统的c45算法不一样的一点。

从上述过程来看,Weka在实现C45的时候做了一个小的变动,并没有从“还没有使用的”属性列中找出最合理的列最为分割属性,而是在“所有的列”中找出最合理的列作为分割属性,虽然这二者在结果上肯定是等价的(之前是有过的属性不和能有很好的信息增益率),但效率上个人对Weka的做法持保留意见。


二、C45Spliter

在ModelSelection中真正根据属性对训练集进行分割、计算信息增益和信息增益率的是C45Spliter,首先也从其buildClassifier方法入手进行分析。

public void buildClassifier(Instances trainInstances) 
       throws Exception {

    // Initialize the remaining instance variables.
    m_numSubsets = 0;
    m_splitPoint = Double.MAX_VALUE;
    m_infoGain = 0;
    m_gainRatio = 0;

    // Different treatment for enumerated and numeric
    // attributes.
    if (trainInstances.attribute(m_attIndex).isNominal()) {
      m_complexityIndex = trainInstances.attribute(m_attIndex).numValues();
      m_index = m_complexityIndex;
      handleEnumeratedAttribute(trainInstances);
    }else{
      m_complexityIndex = 2;
      m_index = 0;
      trainInstances.sort(trainInstances.attribute(m_attIndex));
      handleNumericAttribute(trainInstances);
    }
  }    
可以看到,对于枚举型和数值型的属性是分开处理的,枚举型调用handlEnumeratedAttribute,数值型调用handleNumericAttribute,值得注意的是,在处理数值型之前,按照相应列进行排序,同时设置m_complexityIndex也就是期望分裂的节点数设定为2。

首先来看枚举类型是如何处理的。

private void handleEnumeratedAttribute(Instances trainInstances)
       throws Exception {
    
    Instance instance;

    m_distribution = new Distribution(m_complexityIndex,
			      trainInstances.numClasses());
    
    // Only Instances with known values are relevant.
    Enumeration enu = trainInstances.enumerateInstances();
    while (enu.hasMoreElements()) {
      instance = (Instance) enu.nextElement();
      if (!instance.isMissing(m_attIndex))
	m_distribution.add((int)instance.value(m_attIndex),instance);
    }
    
    // Check if minimum number of Instances in at least two
    // subsets.
    if (m_distribution.check(m_minNoObj)) {
      m_numSubsets = m_complexityIndex;
      m_infoGain = infoGainCrit.
	splitCritValue(m_distribution,m_sumOfWeights);
      m_gainRatio = 
	gainRatioCrit.splitCritValue(m_distribution,m_sumOfWeights,
				     m_infoGain);
    }
  }
大概流程是新建一个分布,遍历所有instance,如果该instance对应的分裂的属性不为空的话,则放到不同的bag里,之后检查一下这个分布是否满足要求,要求就是最多允许有一个bag里的数据数量小于m_minNoObj,如果通过检查,就设置subset的数量,计算信息增益和信息增益率,否则subset默认会是0,上层调用checkModel就会返回false代表这是一个无效模型。

接下来看数值型是如何处理的:

 private void handleNumericAttribute(Instances trainInstances)
       throws Exception {
  
    int firstMiss;//最后一个有效instance的下标
    int next = 1;//下一个instance的index
    int last = 0;//当前instance的index
    int splitIndex = -1;//分裂点
    double currentInfoGain;//当前信息增益
    double defaultEnt;//分割之前的信息熵
    double minSplit;
    Instance instance;
    int i;

//首先新建一个分布,数值型默认处理为2维分布,也就可以理解为小于某个值放到一个Bag里,其余的放到另外一个Bag里
    m_distribution = new Distribution(2,trainInstances.numClasses());
    Enumeration enu = trainInstances.enumerateInstances();
    i = 0;
<pre name="code" class="cpp">//注意instances传入的时候是排好序的,这个排序保证了missingValue放在最后面,所以读到了missingValue其之后肯定都是miss//ingValue,换言之,firstMiss在循环之后代表了最后一个有效的instance的下标。
while (enu.hasMoreElements()) { instance = (Instance) enu.nextElement(); if (instance.isMissing(m_attIndex))break; m_distribution.add(1,instance); i++; } firstMiss = i;//循环结束后,m_distribution里放入了所有的有效instance,并全放入了bag1里。

//minSplit是最后分类好每个Bag里最小的数据的量,也就是0.1*每个类的均值。
    minSplit =  0.1*(m_distribution.total())/
      ((double)trainInstances.numClasses());
    if (Utils.smOrEq(minSplit,m_minNoObj)) 
      minSplit = m_minNoObj;
    else
      if (Utils.gr(minSplit,25)) 
	minSplit = 25;
	
//如果有效数据总量不到2*minSplit,换言之无论怎么分均不能保证2个bag里的数量大于minSplit,就直接返回。
    if (Utils.sm((double)firstMiss,2*minSplit))
      return;
    
//defaultEnt代表旧的信息熵,也就是对该属性进行分类之前,Indexclass对应的信息熵。
    defaultEnt = infoGainCrit.oldEnt(m_distribution);
    while (next < firstMiss) {
	  
      if (trainInstances.instance(next-1).value(m_attIndex)+1e-5 < 
	  trainInstances.instance(next).value(m_attIndex)) { 
	<pre name="code" class="cpp">//Instances里的记录是升序排列的,加上这个条件默认把值相差很小的Instance就当做同一个instance处理了
//last代表当前,next代表下一个,默认next=1,last=0,所以shiftRange可以理解成把当前记录从bag1移动到bag0中
<span style="font-family: Arial, Helvetica, sans-serif;">//注意一开始初始化时候所有的都是在bag1里面的。	</span>
m_distribution.shiftRange(1,0,trainInstances,last,next);if (Utils.grOrEq(m_distribution.perBag(0),minSplit) && //如果两个bag都满足最小数据集的数量minSplit Utils.grOrEq(m_distribution.perBag(1),minSplit)) { currentInfoGain = infoGainCrit. splitCritValue(m_distribution,m_sumOfWeights, //算一下信息增益 defaultEnt);

	  if (Utils.gr(currentInfoGain,m_infoGain)) {
	    m_infoGain = currentInfoGain;//如果信息增益比当前最大的要大,则替换当前最大的值,并记录splitIndex
	    splitIndex = next-1;
	  }
	  m_index++;
	}
	last = next;
      }
      next++;
    }
    
    if (m_index == 0)
      return; //执行到这里说明没找到一个合适的分裂点,直接返回。
    
    // 计算最佳信息增益
    m_infoGain = m_infoGain-(Utils.log2(m_index)/m_sumOfWeights);
    if (Utils.smOrEq(m_infoGain,0))
      return; //如果信息增益是0也说明没找到合适的分裂点,直接返回。
    
    //剩下的就是根据分裂点进行属性的划分。
    m_numSubsets = 2;
    m_splitPoint = 
      (trainInstances.instance(splitIndex+1).value(m_attIndex)+
       trainInstances.instance(splitIndex).value(m_attIndex))/2;

    // In case we have a numerical precision problem we need to choose the
    // smaller value
    if (m_splitPoint == trainInstances.instance(splitIndex + 1).value(m_attIndex)) {
      m_splitPoint = trainInstances.instance(splitIndex).value(m_attIndex);
    }

    // Restore distributioN for best split.
    m_distribution = new Distribution(2,trainInstances.numClasses());
    m_distribution.addRange(0,trainInstances,0,splitIndex+1);
    m_distribution.addRange(1,trainInstances,splitIndex+1,firstMiss);

    // Compute modified gain ratio for best split.
    m_gainRatio = gainRatioCrit.
      splitCritValue(m_distribution,m_sumOfWeights,
		     m_infoGain);
  }
这个函数有点复杂,具体逻辑也写到代码注释里了。


三、BinC45ModelSelection

该函数只负责生成二元分类树的模型,selectModel方法和C45ModelSelection几乎一样,不在多说,不同点在于其使用BinC45Spliter而不是C45Spliter。


四、BinC45Spliter

 handleNumericAttribute对于数值类型的属性处理和C45Spliter完全一样。下面只分析一下handleEnumeratedAttribute。

 private void handleEnumeratedAttribute(Instances trainInstances)
       throws Exception {
    
    Distribution newDistribution,secondDistribution;
    int numAttValues;
    double currIG,currGR;
    Instance instance;
    int i;

    numAttValues = trainInstances.attribute(m_attIndex).numValues();
    newDistribution = new Distribution(numAttValues,
				       trainInstances.numClasses());
    
    // Only Instances with known values are relevant.
    Enumeration enu = trainInstances.enumerateInstances();
    while (enu.hasMoreElements()) {
      instance = (Instance) enu.nextElement();
      if (!instance.isMissing(m_attIndex))
	newDistribution.add((int)instance.value(m_attIndex),instance);
    }
    m_distribution = newDistribution;

    // For all values
    for (i = 0; i < numAttValues; i++){

      if (Utils.grOrEq(newDistribution.perBag(i),m_minNoObj)){
	secondDistribution = new Distribution(newDistribution,i);
	
	// Check if minimum number of Instances in the two
	// subsets.
	if (secondDistribution.check(m_minNoObj)){
	  m_numSubsets = 2;
	  currIG = m_infoGainCrit.splitCritValue(secondDistribution,
					       m_sumOfWeights);
	  currGR = m_gainRatioCrit.splitCritValue(secondDistribution,
						m_sumOfWeights,
						currIG);
	  if ((i == 0) || Utils.gr(currGR,m_gainRatio)){
	    m_gainRatio = currGR;
	    m_infoGain = currIG;
	    m_splitPoint = (double)i;
	    m_distribution = secondDistribution;
	  }
	}
      }
    }
可以看出,上一段代码根据该属性的不同的取值,在已有分布基础上,建立一个新的分布secondeDistribution,
secondDistribution = new Distribution(newDistribution,i);
该分布包含两列,属性下标为i的,其余的,在这个分布的基础上计算信息增益和信息增益率,并选出最优的。

换句话说,离散值分类的二元化处理就是选出其中一列当做一个branch,其余的当做另外一个branch。虽然从结构上来讲这肯定不是最优的选择,但简单易用就够了。


到这里基本分析完了J48的两个ModelSelection,下一篇文章将对classifierInstance过程进行分析,并给出一个简单的总结。






Weka算法Classifier-tree-J48源码分析(一)算法和基本数据结构 Weka分类树J48源码解析 阅读详情

相关推荐

COMSOL报错调试总结(不定期更新)

COMSOL报错调试总结1. 可定位错误1.1 除零错误1.2 未定义变量值1.3 边界条件/材料属性等缺失2. 难定位错误2.1. 装配期间内存不足 官方给的案例总是非常完美,运行流畅,结果完美。但是自己做模型时候就总是报错,而且不像自己coding的程序那样可以明确定位哪里出了bug。这里把我碰到的一些报错问题以及调试方法记录下来~ 部分来源于以下参考来源: http://wap.sciencenet.cn/blog-1467490-1118453.html?mobile=1 1. 可定位错误 以下错误

jessica0307的博客 8万+

java-无法在artff文件weka中使用字符串属性并构建分类器

嗨,我正在使用Weka进行机器学习,我的artff文件格式如下 `@relation datastest @attribute fwoh {what, when, where, how, who, why} @attribute parameter {color, performance} @attribute object { power, cost} @attribute m...

weixin_44109689的博客 779

MacOS Intel芯片实战:Docker Compose一键部署Dify全流程解析

本文详细解析了在搭载Intel芯片的MacOS系统上,使用Docker Compose一键部署开源LLM应用开发平台Dify的全流程。内容涵盖环境准备、Docker配置与镜像加速、代码拉取与配置初始化、服务启动与问题排查,以及访问验证与初步探索,旨在帮助开发者快速在本地搭建私有化AI应用开发环境。

ik678901234的博客 620

java jdbc.idbdriver_错误在java代码中使用WEKA API时:类属性未设置?

我试图在我的java代码中使用weka API。我使用J48树分类来分类我的数据库在MySQL数据库,但我有这个错误:Trying to add database driver (JDBC): RmiJdbc.RJDriver - Error, not in CLASSPATH?Trying to add database driver (JDBC): jdbc.idbDriver - Error...

weixin_30388485的博客 213

Lede(OpenWrt)安装和双宽带叠加

LEDE是一个专为路由器和嵌入式设备设计的自由和开源的操作系统。LEDE是OpenWRT项目的一个分支项目。LEDE操作系统包括许多路由器有用的功能,如网络地址转换、防火墙、端口转发、DHCP服务器等。

我的博客 6441

告别效率低谷:用ADS仿真手把手教你设计高回退Doherty功放(附1:2非对称案例)

本文详细解析了如何使用ADS仿真设计高回退Doherty功放,特别针对1:2非对称架构进行深入探讨。通过优化功率分配比、峰值管开启阈值等关键参数,显著提升功放在9dB回退点的效率至75%以上,适用于LTE等高PAPR信号场景。文章还提供了ADS仿真环境搭建、参数优化及工程化设计的实用技巧。

weixin_33743248的博客 457

weka中的J48

private void handleNumericAttribute(Instances trainInstances) throws Exception { int firstMiss;//最后一个有效instance的下标 int next = 1;//下一个instance的index int last = 0;//当前instance的index

u010007619的博客 1389

攻防世界:Crypto习题之easy_RSA

在非对称加密算法中,单向函数被广泛应用,用于确保从公钥加密后的密文无法轻易推导出私钥,从而保证数据的安全性。而其中最著名的算法便是 RSA 加密算法。首先设φm:=∣1≤k≤mgcdkm1∣为欧拉函数(Euler’sche Phi-function)。pqn:=pqpqφnnpqpqφnp−1q−1e∈12...φn−1gcdφne1ended≡1φn假设我们现在有明文x以及公钥en。

qq_52789488的博客 1572

代码-Weka的决策树类J48

package kit.weka; /** * desc:试试Weka的决策树类 * <code>J48Test</code> * */ import java.io.File; import java.io.IOException; import we...

weixin_30298497的博客 438

⑩电子产品拆解分析-家用无线遥控开关433Mhz

①免布线随意贴,装上就能使用解决单线开关烦恼;②遥控配对简单,无线通讯距离长,信号可穿墙;

a6662580的博客 4705

SAP_MM模块非限制库存转冻结库存

项目非限制 → 冻结事务码移动类型343影响库存不可用,不参与MRP常见用途质量问题封存、盘点冻结、待退货品通过本文,我们了解了 SAP 的[SAP_MM模块非限制库存转冻结库存]的基本概念和应用方法。希望这些信息能帮助您在实际工作中更好地使用 SAP 系统,提高工作效率和管理水平。更多SAP文章请点击更多SAP文章更新,大家一起学习进步!!!文章中如有错误。敬请指正!搜索公众号:SAP资料文库微信号:SPRO_PP时间:2025-10-14。

我小时候很黑的博客 586

weka java svm_使用LibSVM在Java代码中出现Weka错误“无法处理数字类”

我正在尝试使用基于LibSVM的分类器使用Weka,但是我遇到了这个错误:Exception in thread "main" weka.core.UnsupportedAttributeTypeException:weka.classifiers.functions.LibSVM: Cannot handle numeric class!at weka.core.Capabilities.tes...

weixin_42114580的博客 466

车载软件刷写工具vFlash --- 自动化接口(Automation API)应用简介

车载软件刷写工具vFlash --- 自动化接口(Automation API)应用简介

Soly_kun的博客 361

Weka算法Classifier-tree-J48源代码分析(一个)基本数据结构和算法

大约一年,我没有照顾的博客,再次拿起笔不知从何写上,想来想去手从最近使用Weka要正确书写。 Weka为一个Java基础上的机器学习工具。上手简单,并提供图形化界面。提供如分类、聚类、频繁项挖掘等工具。本篇文章主要写一下分类器算法中的J48算法及事实上现。 一、算法 J48是基于C4.5实现的决策树算法。对于C4.5算法相关资料太多了。笔者在这里...

weixin_33759269的博客 336

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Weka算法Classifier-tree-J48源码分析(二)ClassifierTree

一、问题 主要带着四个问题去研究J48的实现。 1、如何控制分类树的精度。 2、如何处理缺失的值(MissingValue) 3、如何对连续值进行离散化。 4、如何进行分类树的剪枝。 二、BuildClassifier 每一个分类器都会实现这个方法,传入一个Instances对象,在这个对象基础上进行来构建分类树。核心代码如下:

chenlinqing03的专栏 218

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

java weka 分类_从java中调用weka中的分类函数的问题

下面是问题java,请高手帮忙改下,本人不是很了解,谢谢~~~~比较急提示问题是:weka.core.UnassignedClassException:weka.classifiers.trees.j48.C45PruneableClassifierTree:Classat...下面是问题java,请高手帮忙改下,本人不是很了解,谢谢~~~~比较急提示问题是:weka.core.Unassigne...

weixin_39790760的博客 313

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Weka开发 -J48源代码介绍

<br />这次介绍一下J48的源码,分析J48的源码似乎真还是有用的,同学改造J48写过VFDT,我自己用J48进行特征选择(当然很失败)。<br />J48的buildClassfier函数:<br />publicvoid buildClassifier(Instances instances) throws Exception {<br />    ModelSelection modSelection;<br /> <br />    if (m_binarySplits)<br />      

licj_0721的专栏 2433

C4.5(weka又称为J48)算法原理详解

C4.5(weka又称为J48)算法原理详解1. 信息增益率ID3算法有以下几个缺点: + 1个属性取值越多,则此属性的信息增益率越大,越有可能被ID3选为当前分类属性。然而取值较多的属性并不一定最优。(例如一个属性的每个子节点都只有1个样本,此时信息增益率达到最大,但是用这样的属性却没有任何意义) ID3只能处理离散型属性 可以处理缺失数据 可以对树进行剪枝 针对ID3算法的不足,Quinlan

Abraham Ben 2万+

Weka一些基础内容

<br />无意间在网上看到了:http://weka.wiki.sourceforge.net/Use+Weka+in+your+Java+code,相对我写的代码,它的当然更有权威性。翻译完了,第一次翻译,术语的汉语很多不清楚。还没有校对,有什么错误请告诉我。<br />你可能要用的最常用的组件(components)是:<br />l  Instances 你的数据<br />l  Filter 对数据的预处理<br />l  Classifiers/Clusterer 被建立在预处理的数据上,分类/

Wayne's Road to Rome! 4461

Weka分类---J48

利用iris数据集用weka只带的J48训练分类器详细见程序注释package wekaTest;import weka.classifiers.meta.FilteredClassifier; import weka.classifiers.trees.J48; import weka.core.Instances; import weka.core.converters.ConverterUti

水滴石穿 4080

weka java 分类算法_调用Weka算法实现文本分类

1介绍:嵌入式机器学习,在自己的算法中调用Weka实现文本分类,是一个小的数据挖掘程序,虽然实用价值不是很大,但对于Weka的理解和使用是有帮助的。本例子来自《数据挖掘:实用机器学习技术》第2版(好像是倒数第三章)。大家可以到http://blogger.org.cn/blog/message.asp?name=DMman#23691下载该书察看对算法的详细解释。算法中作了详细的注释,虽然是英文的...

weixin_31317351的博客 804
上一篇: Weka算法Classifier-tree-J48源码分析(二)ClassifierTree
下一篇: Weka算法Classifier-tree-J48源码分析(四)总结
ROger__Wong
博客等级 码龄14年 250粉丝 78原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值