机器学习和生物信息学实验室联盟

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 5222|回复: 7
打印 上一主题 下一主题

工厂模式+单例模式封装WekaFactory来构造Weka中各种对象

  [复制链接]
跳转到指定楼层
楼主
发表于 2012-1-17 21:30:40 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
本帖最后由 chenwq 于 2012-2-20 10:52 编辑

更方便更简单起见,封装了Weka。虽然我不懂Weka


// 测试WekaFactory

  1. package cn.edu.xmu.bdm.wekainjava.utils;

  2. import java.io.File;

  3. import weka.classifiers.Classifier;
  4. import weka.classifiers.Evaluation;
  5. import weka.classifiers.trees.J48;
  6. import weka.core.Instances;

  7. public class TestWekaFactory {

  8.         /**
  9.          * @param args
  10.          * @throws Exception
  11.          */
  12.         public static void main(String[] args) throws Exception {
  13.                 File trainFile = new File(
  14.                                 "C:\\Program Files\\Weka-3-6\\data\\cpu.with.vendor.arff");
  15.                 File testFile = new File(
  16.                                 "C:\\Program Files\\Weka-3-6\\data\\cpu.with.vendor.arff");
  17.                 /**
  18.                  * 1. 获取weka工厂类
  19.                  */
  20.                 WekaFactory wi = WekaFactoryImpl.getInstance();
  21.                 /**
  22.                  * 2. 从工厂中获取分类器 具体使用哪一种特定的分类器可以选择 这样就构建了一个简单的分类器
  23.                  */
  24.                 Classifier j48 = (Classifier) wi.getClassifier(J48.class);

  25.                 /**
  26.                  * 3. 从工厂中获取训练样本和测试样本实例
  27.                  */
  28.                 Instances instancesTrain = wi.getInstance(trainFile);
  29.                 instancesTrain.setClassIndex(0);

  30.                 Instances instancesTest = wi.getInstance(testFile);
  31.                 instancesTest.setClassIndex(0);

  32.                 /**
  33.                  * 4.使用训练样本训练分类器
  34.                  */
  35.                 j48.buildClassifier(instancesTrain);

  36.                 /**
  37.                  * 5. 从工厂中获取使用Evaluation,测试样本测试分类器的学习效果
  38.                  */
  39.                 double sum = instancesTrain.numInstances();
  40.                 Evaluation testingEvaluation = wi.getEvaluation(j48, instancesTrain);
  41.                 int length = instancesTest.numInstances();
  42.                 for (int i = 0; i < length; i++) {
  43.                         // 通过这个方法来用每个测试样本测试分类器的效果
  44.                         testingEvaluation.evaluateModelOnceAndRecordPrediction(j48,
  45.                                         instancesTest.instance(i));
  46.                 }
  47.                                 System.out.println(testingEvaluation.toSummaryString());
  48.                 System.out.println("分类器的正确率:" + (1 - testingEvaluation.errorRate()));
  49.         }

  50. }
复制代码
工厂模式封装的优点:
    1. 良好的封装性,代码结构清晰
    2. 扩展性很好
    3. 屏蔽weka具体类
    4. 典型的解耦框架

单例模式的优点:
   1. 减少内存开支
    2. 减少系统性能开销
    3. 避免对资源的多重占用
    4. 可以在系统设置全局访问点,优化和共享资源访问

单例的创建使用双重检查加锁方式,延迟加载以及线程安全

  1. package cn.edu.xmu.bdm.wekainjava.utils;

  2. import java.io.File;

  3. import weka.classifiers.Classifier;
  4. import weka.classifiers.Evaluation;
  5. import weka.core.Instances;

  6. /**
  7. * desc:weka各种类工厂
  8. * <code>WekaFactory</code>
  9. * @version 1.0
  10. * @author chenwq
  11. *
  12. */
  13. public abstract  class WekaFactory {
  14.         /**
  15.          * java.lang.Object
  16.            *                 ——weka.core.Instances
  17.          * @param clazz
  18.          * @return
  19.          */
  20.         public abstract <T extends Classifier> T getClassifier(Class<T> clazz);
  21.        
  22.         /**
  23.          * 从.arff文件中获取样本Instances;
  24.          * @param fileName 获得instances的文件名
  25.          * @return
  26.          */
  27.         public abstract <T extends Instances> T getInstance(String fileName);
  28.         /**
  29.          * 从.arff文件中获取样本Instances;
  30.          * @param file 获得instances的File对象
  31.          * @return
  32.          */
  33.         public abstract <T extends Instances> T getInstance(File file);
  34.        
  35.         /**
  36.          * 获得一个Evaluation对象
  37.          * @param h 一个已经训练过的分类器
  38.          * @param ins  测试样本
  39.          * @return
  40.          */
  41.         public abstract <T extends Evaluation> T getEvaluation(Classifier h, Instances ins);
  42. }
复制代码
  1. package cn.edu.xmu.bdm.wekainjava.utils;

  2. import java.io.File;

  3. import weka.classifiers.Classifier;
  4. import weka.classifiers.Evaluation;
  5. import weka.core.Instance;
  6. import weka.core.Instances;
  7. import weka.core.converters.ArffLoader;

  8. /**
  9. *@see cn.edu.xmu.bdm.wekainjava.utils.WekaFactory
  10. */
  11. public class WekaFactoryImpl extends WekaFactory{
  12.         private volatile static WekaFactoryImpl instance = null;

  13.         private WekaFactoryImpl() {
  14.         }

  15.         public synchronized static WekaFactoryImpl getInstance() {
  16.                 if (instance == null) {
  17.                         instance = new WekaFactoryImpl();
  18.                 }
  19.                 return instance;
  20.         }
  21.        
  22.         @Override
  23.         /**
  24.          * @
  25.          */
  26.         public <T extends Classifier> T getClassifier(Class<T> clazz) {
  27.                 Classifier classifier  = null;
  28.                 try{
  29.                         classifier = (Classifier)Class.forName(clazz.getName()).newInstance();
  30.                 }catch(Exception e){
  31.                         //TODO:创建Classifier异常处理
  32.                 }
  33.                 return (T)classifier;
  34.         }

  35.         @Override
  36.         public <T extends Instances> T getInstance(String fileName) {
  37.                 File file = new File(fileName);
  38.                 return getInstance(file);
  39.         }

  40.         @Override
  41.         public <T extends Instances> T getInstance(File file) {
  42.                 Instances inst = null;
  43.                 try {
  44.                         ArffLoader loader = new ArffLoader();
  45.                         loader.setFile(file);
  46.                         inst = loader.getDataSet();
  47.                 } catch (Exception e) {
  48.                         //TODO:创建Instances异常处理
  49.                 }
  50.                 return (T)inst;
  51.         }

  52.         @Override
  53.         public <T extends Evaluation> T getEvaluation(Classifier h, Instances ins) {
  54.                 try {
  55.                         Instance testInst;
  56.                         /*
  57.                          * Evaluation: Class for evaluating machine learning models
  58.                          * 即它是用于检测分类模型的类
  59.                          */
  60.                         Evaluation testingEvaluation = new Evaluation(ins);
  61.                         int length = ins.numInstances();
  62.                         for (int i = 0; i < length; i++) {
  63.                                 testInst = ins.instance(i);
  64.                                 // 通过这个方法来用每个测试样本测试分类器的效果
  65.                                 testingEvaluation.evaluateModelOnceAndRecordPrediction(h,
  66.                                                 testInst);
  67.                         }
  68.                         return (T)testingEvaluation;
  69.                 } catch (Exception e) {
  70.                         System.out.println("haha bug!");
  71.                         System.out.println(e);
  72.                 }
  73.                 return null;
  74.         }
  75. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享
回复

使用道具 举报

8#
发表于 2012-2-27 20:13:53 | 只看该作者
学习了+1
回复 支持 反对

使用道具 举报

7#
 楼主| 发表于 2012-2-27 10:38:08 | 只看该作者
本帖最后由 chenwq 于 2012-2-27 10:38 编辑

Category Pattern http://c2.com/cgi/wiki?CategoryPattern
回复 支持 反对

使用道具 举报

6#
发表于 2012-2-20 16:12:10 | 只看该作者
支持强哥做报告!
回复 支持 反对

使用道具 举报

5#
 楼主| 发表于 2012-2-20 10:53:03 | 只看该作者
tangzk 发表于 2012-2-19 09:52
貌似找到个小错误。
TestWekaFactory.java类中的Line48:
Evaluation testingEvaluation = wi.getEvaluat ...

已修改。
感谢@tangzk 纠错!
回复 支持 反对

使用道具 举报

地板
发表于 2012-2-19 09:52:39 | 只看该作者
貌似找到个小错误。
TestWekaFactory.java类中的Line48:
Evaluation testingEvaluation = wi.getEvaluation(j48, instancesTest);
应该是:
Evaluation testingEvaluation = wi.getEvaluation(j48, instancesTrain);   // 使用训练集训练模型
吧?
回复 支持 反对

使用道具 举报

板凳
发表于 2012-1-18 23:57:25 | 只看该作者
真是太棒了,chenwq下学期能不能做个报告,给大家讲讲工厂模式、封装与抽象。

我们的java基本都是自学,没系统的讲过课,好多东西都不懂。
回复 支持 反对

使用道具 举报

沙发
发表于 2012-1-18 08:39:27 | 只看该作者
学习了!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

机器学习和生物信息学实验室联盟  

GMT+8, 2024-11-23 12:18 , Processed in 0.076880 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表