欢迎光临散文网 会员登陆 & 注册

Java 人工智能 - Weka - 分类算法

2021-10-01 14:53 作者:开源开发者  | 我要投稿

数据样本



加载数据


Weka 接收的格式为 ARRF


数据源对象

ConverterUtils.DataSource source = new ConverterUtils.DataSource(AnimalClassify.class.getClassLoader().getResource("data/zoo.arff").getPath());


从数据源对象获取数据集

Instances dataSet = source.getDataSet();


打印数据集数据量

System.out.println(dataSet.numInstances() + " instances loaded.");




打印整个数据集

System.out.println(dataSet.toString());


@relation zoo

@attribute animal {aardvark,antelope,bass,bear,boar,buffalo,calf,carp,catfish,cavy,cheetah,chicken,chub,clam,crab,crayfish,crow,deer,dogfish,dolphin,dove,duck,elephant,flamingo,flea,frog,fruitbat,giraffe,girl,gnat,goat,gorilla,gull,haddock,hamster,hare,hawk,herring,honeybee,housefly,kiwi,ladybird,lark,leopard,lion,lobster,lynx,mink,mole,mongoose,moth,newt,octopus,opossum,oryx,ostrich,parakeet,penguin,pheasant,pike,piranha,pitviper,platypus,polecat,pony,porpoise,puma,pussycat,raccoon,reindeer,rhea,scorpion,seahorse,seal,sealion,seasnake,seawasp,skimmer,skua,slowworm,slug,sole,sparrow,squirrel,starfish,stingray,swan,termite,toad,tortoise,tuatara,tuna,vampire,vole,vulture,wallaby,wasp,wolf,worm,wren}

@attribute hair {false,true}

@attribute feathers {false,true}

@attribute eggs {false,true}

@attribute milk {false,true}

@attribute airborne {false,true}

@attribute aquatic {false,true}

@attribute predator {false,true}

@attribute toothed {false,true}

@attribute backbone {false,true}

@attribute breathes {false,true}

@attribute venomous {false,true}

@attribute fins {false,true}

@attribute legs numeric

@attribute tail {false,true}

@attribute domestic {false,true}

@attribute catsize {false,true}

@attribute type {mammal,bird,reptile,fish,amphibian,insect,invertebrate}

@data

aardvark,true,false,false,true,false,false,true,true,true,true,false,false,4,false,false,true,mammal

antelope,true,false,false,true,false,false,false,true,true,true,false,false,4,true,false,true,mammal

bass,false,false,true,false,false,true,true,true,true,false,false,true,0,true,false,false,fish

bear,true,false,false,true,false,false,true,true,true,true,false,false,4,false,false,true,mammal

boar,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

buffalo,true,false,false,true,false,false,false,true,true,true,false,false,4,true,false,true,mammal

calf,true,false,false,true,false,false,false,true,true,true,false,false,4,true,true,true,mammal

carp,false,false,true,false,false,true,false,true,true,false,false,true,0,true,true,false,fish

catfish,false,false,true,false,false,true,true,true,true,false,false,true,0,true,false,false,fish

cavy,true,false,false,true,false,false,false,true,true,true,false,false,4,false,true,false,mammal

cheetah,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

chicken,false,true,true,false,true,false,false,false,true,true,false,false,2,true,true,false,bird

chub,false,false,true,false,false,true,true,true,true,false,false,true,0,true,false,false,fish

clam,false,false,true,false,false,false,true,false,false,false,false,false,0,false,false,false,invertebrate

crab,false,false,true,false,false,true,true,false,false,false,false,false,4,false,false,false,invertebrate

crayfish,false,false,true,false,false,true,true,false,false,false,false,false,6,false,false,false,invertebrate

crow,false,true,true,false,true,false,true,false,true,true,false,false,2,true,false,false,bird

deer,true,false,false,true,false,false,false,true,true,true,false,false,4,true,false,true,mammal

dogfish,false,false,true,false,false,true,true,true,true,false,false,true,0,true,false,true,fish

dolphin,false,false,false,true,false,true,true,true,true,true,false,true,0,true,false,true,mammal

dove,false,true,true,false,true,false,false,false,true,true,false,false,2,true,true,false,bird

duck,false,true,true,false,true,true,false,false,true,true,false,false,2,true,false,false,bird

elephant,true,false,false,true,false,false,false,true,true,true,false,false,4,true,false,true,mammal

flamingo,false,true,true,false,true,false,false,false,true,true,false,false,2,true,false,true,bird

flea,false,false,true,false,false,false,false,false,false,true,false,false,6,false,false,false,insect

frog,false,false,true,false,false,true,true,true,true,true,false,false,4,false,false,false,amphibian

frog,false,false,true,false,false,true,true,true,true,true,true,false,4,false,false,false,amphibian

fruitbat,true,false,false,true,true,false,false,true,true,true,false,false,2,true,false,false,mammal

giraffe,true,false,false,true,false,false,false,true,true,true,false,false,4,true,false,true,mammal

girl,true,false,false,true,false,false,true,true,true,true,false,false,2,false,true,true,mammal

gnat,false,false,true,false,true,false,false,false,false,true,false,false,6,false,false,false,insect

goat,true,false,false,true,false,false,false,true,true,true,false,false,4,true,true,true,mammal

gorilla,true,false,false,true,false,false,false,true,true,true,false,false,2,false,false,true,mammal

gull,false,true,true,false,true,true,true,false,true,true,false,false,2,true,false,false,bird

haddock,false,false,true,false,false,true,false,true,true,false,false,true,0,true,false,false,fish

hamster,true,false,false,true,false,false,false,true,true,true,false,false,4,true,true,false,mammal

hare,true,false,false,true,false,false,false,true,true,true,false,false,4,true,false,false,mammal

hawk,false,true,true,false,true,false,true,false,true,true,false,false,2,true,false,false,bird

herring,false,false,true,false,false,true,true,true,true,false,false,true,0,true,false,false,fish

honeybee,true,false,true,false,true,false,false,false,false,true,true,false,6,false,true,false,insect

housefly,true,false,true,false,true,false,false,false,false,true,false,false,6,false,false,false,insect

kiwi,false,true,true,false,false,false,true,false,true,true,false,false,2,true,false,false,bird

ladybird,false,false,true,false,true,false,true,false,false,true,false,false,6,false,false,false,insect

lark,false,true,true,false,true,false,false,false,true,true,false,false,2,true,false,false,bird

leopard,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

lion,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

lobster,false,false,true,false,false,true,true,false,false,false,false,false,6,false,false,false,invertebrate

lynx,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

mink,true,false,false,true,false,true,true,true,true,true,false,false,4,true,false,true,mammal

mole,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,false,mammal

mongoose,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

moth,true,false,true,false,true,false,false,false,false,true,false,false,6,false,false,false,insect

newt,false,false,true,false,false,true,true,true,true,true,false,false,4,true,false,false,amphibian

octopus,false,false,true,false,false,true,true,false,false,false,false,false,8,false,false,true,invertebrate

opossum,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,false,mammal

oryx,true,false,false,true,false,false,false,true,true,true,false,false,4,true,false,true,mammal

ostrich,false,true,true,false,false,false,false,false,true,true,false,false,2,true,false,true,bird

parakeet,false,true,true,false,true,false,false,false,true,true,false,false,2,true,true,false,bird

penguin,false,true,true,false,false,true,true,false,true,true,false,false,2,true,false,true,bird

pheasant,false,true,true,false,true,false,false,false,true,true,false,false,2,true,false,false,bird

pike,false,false,true,false,false,true,true,true,true,false,false,true,0,true,false,true,fish

piranha,false,false,true,false,false,true,true,true,true,false,false,true,0,true,false,false,fish

pitviper,false,false,true,false,false,false,true,true,true,true,true,false,0,true,false,false,reptile

platypus,true,false,true,true,false,true,true,false,true,true,false,false,4,true,false,true,mammal

polecat,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

pony,true,false,false,true,false,false,false,true,true,true,false,false,4,true,true,true,mammal

porpoise,false,false,false,true,false,true,true,true,true,true,false,true,0,true,false,true,mammal

puma,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

pussycat,true,false,false,true,false,false,true,true,true,true,false,false,4,true,true,true,mammal

raccoon,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

reindeer,true,false,false,true,false,false,false,true,true,true,false,false,4,true,true,true,mammal

rhea,false,true,true,false,false,false,true,false,true,true,false,false,2,true,false,true,bird

scorpion,false,false,false,false,false,false,true,false,false,true,true,false,8,true,false,false,invertebrate

seahorse,false,false,true,false,false,true,false,true,true,false,false,true,0,true,false,false,fish

seal,true,false,false,true,false,true,true,true,true,true,false,true,0,false,false,true,mammal

sealion,true,false,false,true,false,true,true,true,true,true,false,true,2,true,false,true,mammal

seasnake,false,false,false,false,false,true,true,true,true,false,true,false,0,true,false,false,reptile

seawasp,false,false,true,false,false,true,true,false,false,false,true,false,0,false,false,false,invertebrate

skimmer,false,true,true,false,true,true,true,false,true,true,false,false,2,true,false,false,bird

skua,false,true,true,false,true,true,true,false,true,true,false,false,2,true,false,false,bird

slowworm,false,false,true,false,false,false,true,true,true,true,false,false,0,true,false,false,reptile

slug,false,false,true,false,false,false,false,false,false,true,false,false,0,false,false,false,invertebrate

sole,false,false,true,false,false,true,false,true,true,false,false,true,0,true,false,false,fish

sparrow,false,true,true,false,true,false,false,false,true,true,false,false,2,true,false,false,bird

squirrel,true,false,false,true,false,false,false,true,true,true,false,false,2,true,false,false,mammal

starfish,false,false,true,false,false,true,true,false,false,false,false,false,5,false,false,false,invertebrate

stingray,false,false,true,false,false,true,true,true,true,false,true,true,0,true,false,true,fish

swan,false,true,true,false,true,true,false,false,true,true,false,false,2,true,false,true,bird

termite,false,false,true,false,false,false,false,false,false,true,false,false,6,false,false,false,insect

toad,false,false,true,false,false,true,false,true,true,true,false,false,4,false,false,false,amphibian

tortoise,false,false,true,false,false,false,false,false,true,true,false,false,4,true,false,true,reptile

tuatara,false,false,true,false,false,false,true,true,true,true,false,false,4,true,false,false,reptile

tuna,false,false,true,false,false,true,true,true,true,false,false,true,0,true,false,true,fish

vampire,true,false,false,true,true,false,false,true,true,true,false,false,2,true,false,false,mammal

vole,true,false,false,true,false,false,false,true,true,true,false,false,4,true,false,false,mammal

vulture,false,true,true,false,true,false,true,false,true,true,false,false,2,true,false,true,bird

wallaby,true,false,false,true,false,false,false,true,true,true,false,false,2,true,false,true,mammal

wasp,true,false,true,false,true,false,false,false,false,true,true,false,6,false,false,false,insect

wolf,true,false,false,true,false,false,true,true,true,true,false,false,4,true,false,true,mammal

worm,false,false,true,false,false,false,false,false,false,true,false,false,0,false,false,false,invertebrate

wren,false,true,true,false,true,false,false,false,true,true,false,false,2,true,false,false,bird 


我们预测 Animal 属性


因为对于新样本 我们只知道其他属性 不知道 Animal 属性


所以要从数据集中去除该属性


实例化一个移除属性对象

Remove remove = new Remove();



实例化一个字符串数组对象

-R 为移除属性

1 为移除第一个属性

String[] opts = new String[]{"-R", "1"};


设置字符串数组对象

remove.setOptions(opts);

设置数据集


remove.setInputFormat(dataSet);

调用过滤器类的使用过滤器的静态方法 把数据集以及要移除的属性移除出去


dataSet = Filter.useFilter(dataSet, remove);

重新打印数据集


System.out.println(dataSet.toString());




特征选择

也叫预处理 数据清洗

也就是选择属性

从属性中选择一个子集

可以简化模型

减少训练的时间 降低过拟合风险


用属性选择算法估评属性的子集 计算出一个分数

分数可以表明属性的品质

品质分数有信息增益 基尼指数


再用搜索算法 比如穷举搜索 最佳优先搜索进行属性分类排序




信息增益 通过计算的个数等等 计算出属性重要的程度 会给出一个分数

InfoGainAttributeEval eval = new InfoGainAttributeEval();


根据分数分类属性的算法

Ranker search = new Ranker();




对象属性选择类

AttributeSelection attributeSelection = new AttributeSelection();

设置信息增益



attributeSelection.setEvaluator(eval);

设置搜索算法

attributeSelection.setSearch(search);

设置数据集

attributeSelection.SelectAttributes(dataSet);


调用 selectedAttributes 实例方法进行选择

int[] indices = attributeSelection.selectedAttributes();


打印属性索引数组

System.out.println(Arrays.toString(indices));

[12, 3, 7, 2, 0, 1, 8, 9, 13, 4, 11, 5, 15, 10, 6, 14, 16]

12 是 fins

3 是 eggs

7 是 aquatic

2 是 hair


@attribute hair {false,true}

@attribute feathers {false,true}

@attribute eggs {false,true}

@attribute milk {false,true}

@attribute airborne {false,true}

@attribute aquatic {false,true}

@attribute predator {false,true}

@attribute toothed {false,true}

@attribute backbone {false,true}

@attribute breathes {false,true}

@attribute venomous {false,true}

@attribute fins {false,true}

@attribute legs numeric

@attribute tail {false,true}

@attribute domestic {false,true}

@attribute catsize {false,true}

@attribute type {mammal,bird,reptile,fish,amphibian,insect,invertebrate}


保留的属性应该是有助于进一步改进模型


学习算法

从训练数据中学习算法

学习分类模型


J48 类 实现了 著名的 Quinlan's C4.5 决策树学习算法


剪枝 tree pruning

控制模型的复杂度


未剪枝 un-pruned tree

可以传递一个 -U 参数



创建一个 J48 决策树分类器空模型


J48 tree = new J48();

字符串数组


String[] options = new String[1];

-U 代表 未剪枝参数



options[0] = "-U";

设置决策树分离器属性


tree.setOptions(options);

调用构建分类器 存入数据集进行学习


tree.buildClassifier(dataSet);


经过训练的模型存储在tree对象当中


输出未剪枝的树

System.out.println(tree);



未剪枝数 17个节点

9个叶子节点


J48 unpruned tree

------------------


feathers = false

|   milk = false

|   |   backbone = false

|   |   |   airborne = false

|   |   |   |   predator = false

|   |   |   |   |   legs <= 2: invertebrate (2.0)

|   |   |   |   |   legs > 2: insect (2.0)

|   |   |   |   predator = true: invertebrate (8.0)

|   |   |   airborne = true: insect (6.0)

|   |   backbone = true

|   |   |   fins = false

|   |   |   |   tail = false: amphibian (3.0)

|   |   |   |   tail = true: reptile (6.0/1.0)

|   |   |   fins = true: fish (13.0)

|   milk = true: mammal (41.0)

feathers = true: bird (20.0)


Number of Leaves  : 9


Size of the tree : 17


可视化剪枝树

TreeVisualizer tv = new TreeVisualizer(null, tree.graph(), new PlaceNode2());


JFrame frame = new JFrame("Tree Visualizer");

frame.setSize(800, 500);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.getContentPane().add(tv);

frame.setVisible(true);


feathers 为根节点也称为节点

会在当前节点检查节点的属性值

会先检查feathers的属性的值

如果feathers的属性值存在 会进入右手分支

遍历为bird是叶子节点就会输出当前有多少个bird 样本 当前有 20个


如果 feathers 属性值不存在 会进入左手分支 到达下一个属性 milk

继续检查milk属性值

然后进入属性值相匹配的分支 不断重复这个过程 直到到达叶子节点



预测新数据


有其他属性的未知动物的标签

可以用已经分类过的模型进行预测


构造一个特征向量

double[] vals = new double[dataSet.numAttributes()];

vals[0] = 1.0; // hair {false, true}

vals[1] = 0.0; // feathers {false, true}

vals[2] = 0.0; // eggs {false, true}

vals[3] = 1.0; // milk {false, true}

vals[4] = 0.0; // airborne {false, true}

vals[5] = 0.0; // aquatic {false, true}

vals[6] = 0.0; // predator {false, true}

vals[7] = 1.0; // toothed {false, true}

vals[8] = 1.0; // backbone {false, true}

vals[9] = 1.0; // breathes {false, true}

vals[10] = 1.0; // venomous {false, true}

vals[11] = 0.0; // fins {false, true}

vals[12] = 4.0; // legs INTEGER [0,9]

vals[13] = 1.0; // tail {false, true}

vals[14] = 1.0; // domestic {false, true}

vals[15] = 0.0; // catsize {false, true}

Instance myUnicorn = new DenseInstance(1.0,vals);

myUnicorn.setDataset(dataSet);

调用模型的classifyInstance方法获取样本的值 并返回标签的索引

result的值为索引

模型训练之后会存在各个样本的标签的索引

可以遍历模型的标签索引


double result = tree.classifyInstance(myUnicorn);

System.out.println(result);

System.out.println(dataSet.classAttribute().value((int)result));


0.0

0.0

预测的标签结果为

mammal


评估模型的预测误差以及性能

Classifier cl = new J48();

实现交叉验证的类


Evaluation eval_roc = new Evaluation(dataSet);

cl 为模型 dataSet 提供数据集 10为折数 random 随机种子

eval_roc.crossValidateModel(cl, dataSet, 10, new Random(1), new Object[]{});

打印评估结果

System.out.println(eval_roc.toSummaryString());


Correctly Classified Instances          93               92.0792 %

Incorrectly Classified Instances         8                7.9208 %

Kappa statistic                          0.8955

Mean absolute error                      0.0225

Root mean squared error                  0.14  

Relative absolute error                 10.2478 %

Root relative squared error             42.4398 %

Coverage of cases (0.95 level)          96.0396 %

Mean rel. region size (0.95 level)      15.4173 %

Total Number of Instances              101    


正确数为 93

错误数为 8



混淆矩阵

查看特定的错误分类出现在什么地方

一个特定类值是如何进行预测的


double[][] confusionMatrix = eval_roc.confusionMatrix();

System.out.println(eval_roc.toMatrixString());


=== Confusion Matrix ===


 a  b  c  d  e  f  g   <-- classified as

41  0  0  0  0  0  0 |  a = mammal

 0 20  0  0  0  0  0 |  b = bird

 0  0  3  1  0  1  0 |  c = reptile

 0  0  0 13  0  0  0 |  d = fish

 0  0  1  0  3  0  0 |  e = amphibian

 0  0  0  0  0  5  3 |  f = insect

 0  0  0  0  0  2  8 |  g = invertebrate



第一行的字母为分类模型指派的标签 对应于分类后的索引

其他行对应一个实际值为真的类值

比如说第二行是mammal的标签 所有的都正确分类为该标签为哺乳动物

第4行为爬行动物 有3个样本被正确分类为reptile

一个分类为fish 一个被分类为insect 



package com.osrcd.weka;

import weka.attributeSelection.AttributeSelection;

import weka.attributeSelection.InfoGainAttributeEval;

import weka.attributeSelection.Ranker;

import weka.classifiers.Classifier;

import weka.classifiers.Evaluation;

import weka.classifiers.trees.J48;

import weka.core.DenseInstance;

import weka.core.Instance;

import weka.core.Instances;

import weka.core.converters.ConverterUtils;

import weka.filters.Filter;

import weka.filters.unsupervised.attribute.Remove;

import weka.gui.treevisualizer.PlaceNode2;

import weka.gui.treevisualizer.TreeVisualizer;

import javax.swing.*;

import java.util.Arrays;

import java.util.Enumeration;

import java.util.Random;

public class AnimalClassify {

   public static void main(String[] args) throws Exception {

       // 加载数据

       ConverterUtils.DataSource source = new ConverterUtils.DataSource(AnimalClassify.class.getClassLoader().getResource("data/zoo.arff").getPath());

       Instances dataSet = source.getDataSet();

       System.out.println(dataSet.numInstances() + " instances loaded.");

       System.out.println(dataSet.toString());

       Remove remove = new Remove();

       String[] opts = new String[]{"-R", "1"};

       remove.setOptions(opts);

       remove.setInputFormat(dataSet);

       dataSet = Filter.useFilter(dataSet, remove);

       System.out.println(dataSet.toString());

       // 特征选择 预处理 数据清洗

       // 信息增益 通过计算的个数等等 计算出属性重要的程度 会给出一个分数

       InfoGainAttributeEval eval = new InfoGainAttributeEval();

       // 根据分数分类属性的算法

       Ranker search = new Ranker();

       AttributeSelection attributeSelection = new AttributeSelection();

       attributeSelection.setEvaluator(eval);

       attributeSelection.setSearch(search);

       attributeSelection.SelectAttributes(dataSet);

       int[] indices = attributeSelection.selectedAttributes();

       System.out.println(Arrays.toString(indices));

       // 学习算法

       J48 tree = new J48();

       String[] options = new String[1];

       options[0] = "-U";

       tree.setOptions(options);

       tree.buildClassifier(dataSet);

       System.out.println(tree);

       TreeVisualizer tv = new TreeVisualizer(null, tree.graph(), new PlaceNode2());

       JFrame frame = new JFrame("Tree Visualizer");

       frame.setSize(800, 500);

       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       frame.getContentPane().add(tv);

       frame.setVisible(true);

       double[] vals = new double[dataSet.numAttributes()];

       vals[0] = 1.0; // hair {false, true}

       vals[1] = 0.0; // feathers {false, true}

       vals[2] = 0.0; // eggs {false, true}

       vals[3] = 1.0; // milk {false, true}

       vals[4] = 0.0; // airborne {false, true}

       vals[5] = 0.0; // aquatic {false, true}

       vals[6] = 0.0; // predator {false, true}

       vals[7] = 1.0; // toothed {false, true}

       vals[8] = 1.0; // backbone {false, true}

       vals[9] = 1.0; // breathes {false, true}

       vals[10] = 1.0; // venomous {false, true}

       vals[11] = 0.0; // fins {false, true}

       vals[12] = 4.0; // legs INTEGER [0,9]

       vals[13] = 1.0; // tail {false, true}

       vals[14] = 1.0; // domestic {false, true}

       vals[15] = 0.0; // catsize {false, true}

       Instance myUnicorn = new DenseInstance(1.0,vals);

       myUnicorn.setDataset(dataSet);

       double result = tree.classifyInstance(myUnicorn);

       System.out.println(result);

       System.out.println(dataSet.classAttribute().value((int)result));

       Classifier cl = new J48();

       Evaluation eval_roc = new Evaluation(dataSet);

       eval_roc.crossValidateModel(cl, dataSet, 10, new Random(1), new Object[]{});

       System.out.println(eval_roc.toSummaryString());

       double[][] confusionMatrix = eval_roc.confusionMatrix();

       System.out.println(eval_roc.toMatrixString());

   }

}







Java 人工智能 - Weka - 分类算法的评论 (共 条)

分享到微博请遵守国家法律