Java 人工智能 - Weka - 分类算法
数据样本
加载数据
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());
}
}