精华内容
下载资源
问答
  • Java中的异常有哪几类

    万次阅读 多人点赞 2018-01-30 10:32:30
    总体上我们根据Javac对异常的处理要求,将异常类分为2。 非检查异常 (unckecked exception):Error 和 RuntimeException 以及他们的子类。javac在编译时,不会提示和发现这样的异常,不要求在程序处理这些...

    Java中的异常和处理详解

    简介

    程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?。
     
    Java提供了更加优秀的解决办法:异常处理机制。
     
    异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。
    Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手动抛出的,只要在Java程序中产生了异常,就会用一个对应类型的异常对象来封装异常,JRE就会试图寻找异常处理程序来处理异常。
     
    Throwable类是Java异常类型的顶层父类,一个对象只有是 Throwable 类的(直接或者间接)实例,他才是一个异常对象,才能被异常处理机制识别。JDK中内建了一些常用的异常类,我们也可以自定义异常。

    Java异常的分类和类结构图

    Java标准裤内建了一些通用的异常,这些类以Throwable为顶层父类。

    Throwable又派生出Error类和Exception类。

    错误:Error类以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。

    异常:Exception以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

     

    总体上我们根据Javac对异常的处理要求,将异常类分为2类。

    非检查异常(unckecked exception):Error 和 RuntimeException 以及他们的子类。javac在编译时,不会提示和发现这样的异常,不要求在程序处理这些异常。所以如果愿意,我们可以编写代码处理(使用try...catch...finally)这样的异常,也可以不处理。对于这些异常,我们应该修正代码,而不是去通过异常处理器处理 。这样的异常发生的原因多半是代码写的有问题。如除0错误ArithmeticException,错误的强制类型转换错误ClassCastException,数组索引越界ArrayIndexOutOfBoundsException,使用了空对象NullPointerException等等。

     

    检查异常(checked exception):除了Error 和 RuntimeException的其它异常。javac强制要求程序员为这样的异常做预备处理工作(使用try...catch...finally或者throws)。在方法中要么用try-catch语句捕获它并处理,要么用throws子句声明抛出它,否则编译不会通过。这样的异常一般是由程序的运行环境导致的。因为程序可能被运行在各种未知的环境下,而程序员无法干预用户如何使用他编写的程序,于是程序员就应该为这样的异常时刻准备着。如SQLException , IOException,ClassNotFoundException 等。

    需要明确的是:检查和非检查是对于javac来说的,这样就很好理解和区分了。

    初识异常

    下面的代码会演示2个异常类型:ArithmeticException 和 InputMismatchException。前者由于整数除0引发,后者是输入的数据不能被转换为int类型引发。

     

    package com.example;
    import java. util .Scanner ;
    public class AllDemo
    {
          public static void main (String [] args )
          {
                System . out. println( "----欢迎使用命令行除法计算器----" ) ;
                CMDCalculate ();
          }
          public static void CMDCalculate ()
          {
                Scanner scan = new Scanner ( System. in );
                int num1 = scan .nextInt () ;
                int num2 = scan .nextInt () ;
                int result = devide (num1 , num2 ) ;
                System . out. println( "result:" + result) ;
                scan .close () ;
          }
          public static int devide (int num1, int num2 ){
                return num1 / num2 ;
          }
    }
    

    异常是在执行某个函数时引发的,而函数又是层级调用,形成调用栈的,因为,只要一个函数发生了异常,那么他的所有的caller都会被异常影响。当这些被影响的函数以异常信息输出时,就形成的了异常追踪栈

    异常最先发生的地方,叫做异常抛出点

     

     

    从上面的例子可以看出,当devide函数发生除0异常时,devide函数将抛出ArithmeticException异常,因此调用他的CMDCalculate函数也无法正常完成,因此也发送异常,而CMDCalculate的caller——main 因为CMDCalculate抛出异常,也发生了异常,这样一直向调用栈的栈底回溯。这种行为叫做异常的冒泡,异常的冒泡是为了在当前发生异常的函数或者这个函数的caller中找到最近的异常处理程序。由于这个例子中没有使用任何异常处理机制,因此异常最终由main函数抛给JRE,导致程序终止。

    上面的代码不使用异常处理机制,也可以顺利编译,因为2个异常都是非检查异常。但是下面的例子就必须使用异常处理机制,因为异常是检查异常。

    代码中我选择使用throws声明异常,让函数的调用者去处理可能发生的异常。但是为什么只throws了IOException呢?因为FileNotFoundException是IOException的子类,在处理范围内。

     

    @Test
    public void testException() throws IOException
    {
        //FileInputStream的构造函数会抛出FileNotFoundException
        FileInputStream fileIn = new FileInputStream("E:\\a.txt");
        
        int word;
        //read方法会抛出IOException
        while((word =  fileIn.read())!=-1) 
        {
            System.out.print((char)word);
        }
        //close方法会抛出IOException
        fileIn.close()
    }

    异常处理的基本语法

    在编写代码处理异常时, 对于检查异常,有2种不同的处理方式:使用try...catch...finally语句块处理它。或者,在函数签名中使用throws 声明交给函数调用者caller去解决。
     

    try...catch...finally语句块

     

    try{
         //try块中放可能发生异常的代码。
         //如果执行完try且不发生异常,则接着去执行finally块和finally后面的代码(如果有的话)。
         //如果发生异常,则尝试去匹配catch块。
    
    }catch(SQLException SQLexception){
        //每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java7中可以将多个异常声明在一个catch中。
        //catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
        //在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。
        //如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个函数的外部caller中去匹配异常处理器。
        //如果try中没有发生异常,则所有的catch块将被忽略。
    
    }catch(Exception exception){
        //...
    }finally{
       
        //finally块通常是可选的。
       //无论异常是否发生,异常是否匹配被处理,finally都会执行。
       //一个try至少要有一个catch块,否则, 至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获异常。
      //finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。 
    }

    需要注意的地方

    1、try块中的局部变量和catch块中的局部变量(包括异常变量),以及finally中的局部变量,他们之间不可共享使用。
     
    2、每一个catch块用于处理一个异常。异常匹配是按照catch块的顺序从上往下寻找的,只有第一个匹配的catch会得到执行。匹配时,不仅运行精确匹配,也支持父类匹配,因此, 如果同一个try块下的多个catch异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面,这样保证每个catch块都有存在的意义。
     
    3、java中,异常处理的任务就是将执行控制流从异常发生的地方转移到能够处理这种异常的地方去 。也就是说:当一个函数的某条语句发生异常时,这条语句的后面的语句不会再执行,它失去了焦点。执行流跳转到最近的匹配的异常处理catch代码块去执行,异常被处理完后,执行流会接着在“处理了这个异常的catch代码块”后面接着执行。
    有的编程语言当异常被处理后,控制流会恢复到异常抛出点接着执行,这种策略叫做: resumption model of exception handling(恢复式异常处理模式 )
    而Java则是让执行流恢复到处理了异常的catch块后接着执行,这种策略叫做: termination model of exception handling(终结式异常处理模式)
     
    public static void main(String[] args){
            try {
                foo();
            }catch(ArithmeticException ae) {
                System.out.println("处理异常");
            }
    }
    public static void foo(){
            int a = 5/0;  //异常抛出点
            System.out.println("为什么还不给我涨工资!!!");  //不会执行
    }

     

    throws 函数声明

    throws声明:如果一个方法内部的代码会抛出检查异常(checked exception),而方法自己又没有完全处理掉,则javac保证你必须在方法的签名上使用throws关键字声明这些可能抛出的异常,否则编译不通过。

    throws是另一种处理异常的方式,它不同于try...catch...finally,throws仅仅是将函数中可能出现的异常向调用者声明,而自己则不具体处理。

    采取这种异常处理的原因可能是:方法本身不知道如何处理这样的异常,或者说让调用者处理更好,调用者需要为可能发生的异常负责。

     

    public void foo() throws ExceptionType1 , ExceptionType2 ,ExceptionTypeN
    { 
         //foo内部可以抛出 ExceptionType1 , ExceptionType2 ,ExceptionTypeN 类的异常,或者他们的子类的异常对象。
    }

    finally块

    finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。

    良好的编程习惯是:在try块中打开资源,在finally块中清理释放这些资源。

    需要注意的地方:

    1、finally块没有处理异常的能力。处理异常的只能是catch块。

    2、在同一try...catch...finally块中 ,如果try中抛出异常,且有匹配的catch块,则先执行catch块,再执行finally块。如果没有catch块匹配,则先执行finally,然后去外面的调用者中寻找合适的catch块。

    3、在同一try...catch...finally块中 ,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去外围调用者中寻找合适的catch块。

    这是正常的情况,但是也有特例。关于finally有很多恶心,偏、怪、难的问题,我在本文最后统一介绍了,电梯速达->finally块和return

     

    throw 异常抛出语句

    throw exceptionObject

    程序员也可以通过throw语句手动显式的抛出一个异常。throw语句的后面必须是一个异常对象。

    throw 语句必须写在函数中,执行throw 语句的地方就是一个异常抛出点,它和由JRE自动形成的异常抛出点没有任何差别。

     

    public void save(User user)
    {
          if(user  == null) 
              throw new IllegalArgumentException("User对象为空");
          //......
            
    }
    

    异常的链化

    在一些大型的,模块化的软件开发中,一旦一个地方发生异常,则如骨牌效应一样,将导致一连串的异常。假设B模块完成自己的逻辑需要调用A模块的方法,如果A模块发生异常,则B也将不能完成而发生异常,但是B在抛出异常时,会将A的异常信息掩盖掉,这将使得异常的根源信息丢失。异常的链化可以将多个模块的异常串联起来,使得异常信息不会丢失。

    异常链化:以一个异常对象为参数构造新的异常对象。新的异对象将包含先前异常的信息。这项技术主要是异常类的一个带Throwable参数的函数来实现的。这个当做参数的异常,我们叫他根源异常(cause)。

    查看Throwable类源码,可以发现里面有一个Throwable字段cause,就是它保存了构造时传递的根源异常参数。这种设计和链表的结点类设计如出一辙,因此形成链也是自然的了。

     

    public class Throwable implements Serializable {
        private Throwable cause = this;
       
        public Throwable(String message, Throwable cause) {
            fillInStackTrace();
            detailMessage = message;
            this.cause = cause;
        }
         public Throwable(Throwable cause) {
            fillInStackTrace();
            detailMessage = (cause==null ? null : cause.toString());
            this.cause = cause;
        }
        
        //........
    } 

    下面是一个例子,演示了异常的链化:从命令行输入2个int,将他们相加,输出。输入的数不是int,则导致getInputNumbers异常,从而导致add函数异常,则可以在add函数中抛出

    一个链化的异常。

     

    public static void main(String[] args)
    {
        
        System.out.println("请输入2个加数");
        int result;
        try
        {
            result = add();
            System.out.println("结果:"+result);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    //获取输入的2个整数返回
    private static List<Integer> getInputNumbers()
    {
        List<Integer> nums = new ArrayList<>();
        Scanner scan = new Scanner(System.in);
        try {
            int num1 = scan.nextInt();
            int num2 = scan.nextInt();
            nums.add(new Integer(num1));
            nums.add(new Integer(num2));
        }catch(InputMismatchException immExp){
            throw immExp;
        }finally {
            scan.close();
        }
        return nums;
    }
    
    //执行加法计算
    private static int add() throws Exception
    {
        int result;
        try {
            List<Integer> nums =getInputNumbers();
            result = nums.get(0)  + nums.get(1);
        }catch(InputMismatchException immExp){
            throw new Exception("计算失败",immExp);  /链化:以一个异常对象为参数构造新的异常对象。
        }
        return  result;
    }
    
    /*
    请输入2个加数
    r 1
    java.lang.Exception: 计算失败
        at practise.ExceptionTest.add(ExceptionTest.java:53)
        at practise.ExceptionTest.main(ExceptionTest.java:18)
    Caused by: java.util.InputMismatchException
        at java.util.Scanner.throwFor(Scanner.java:864)
        at java.util.Scanner.next(Scanner.java:1485)
        at java.util.Scanner.nextInt(Scanner.java:2117)
        at java.util.Scanner.nextInt(Scanner.java:2076)
        at practise.ExceptionTest.getInputNumbers(ExceptionTest.java:30)
        at practise.ExceptionTest.add(ExceptionTest.java:48)
        ... 1 more
    
    */

     

    自定义异常

    如果要自定义异常类,则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。

    按照国际惯例,自定义的异常应该总是包含如下的构造函数:

    • 一个无参构造函数
    • 一个带有String参数的构造函数,并传递给父类的构造函数。
    • 一个带有String参数和Throwable参数,并都传递给父类构造函数
    • 一个带有Throwable 参数的构造函数,并传递给父类的构造函数。
     下面是IOException类的完整源代码,可以借鉴。

     

    public class IOException extends Exception
    {
        static final long serialVersionUID = 7818375828146090155L;
    
        public IOException()
        {
            super();
        }
    
        public IOException(String message)
        {
            super(message);
        }
    
        public IOException(String message, Throwable cause)
        {
            super(message, cause);
        }
    
        
        public IOException(Throwable cause)
        {
            super(cause);
        }
    }

    异常的注意事项

    1、当子类重写父类的带有 throws声明的函数时,其throws声明的异常必须在父类异常的可控范围内——用于处理父类的throws方法的异常处理器,必须也适用于子类的这个带throws方法 。这是为了支持多态。

    例如,父类方法throws 的是2个异常,子类就不能throws 3个及以上的异常。父类throws IOException,子类就必须throws IOException或者IOException的子类。

     至于为什么?我想,也许下面的例子可以说明。

     

    class Father
    {
        public void start() throws IOException
        {
            throw new IOException();
        }
    }
    
    class Son extends Father
    {
        public void start() throws Exception
        {
            throw new SQLException();
        }
    }
    /**********************假设上面的代码是允许的(实质是错误的)***********************/
    class Test
    {
        public static void main(String[] args)
        {
            Father[] objs = new Father[2];
            objs[0] = new Father();
            objs[1] = new Son();
    
            for(Father obj:objs)
            {
            //因为Son类抛出的实质是SQLException,而IOException无法处理它。
            //那么这里的try。。catch就不能处理Son中的异常。
            //多态就不能实现了。
                try {
                     obj.start();
                }catch(IOException)
                {
                     //处理IOException
                }
             }
       }
    }

     

    2、Java程序可以是多线程的。每一个线程都是一个独立的执行流,独立的函数调用栈。如果程序只有一个线程,那么没有被任何代码处理的异常 会导致程序终止。如果是多线程的,那么没有被任何代码处理的异常仅仅会导致异常所在的线程结束。

    也就是说,Java中的异常是线程独立的,线程的问题应该由线程自己来解决,而不要委托到外部,也不会直接影响到其它线程的执行。

     

    finally块和return

    首先一个不容易理解的事实:在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。

    public static void main(String[] args)
    {
        int re = bar();
        System.out.println(re);
    }
    private static int bar() 
    {
        try{
            return 5;
        } finally{
            System.out.println("finally");
        }
    }
    /*输出:
    finally
    5
    */
    


     很多人面对这个问题时,总是在归纳执行的顺序和规律,不过我觉得还是很难理解。我自己总结了一个方法。用如下GIF图说明。

     也就是说:try...catch...finally中的return 只要能执行,就都执行了,他们共同向同一个内存地址(假设地址是0x80)写入返回值,后执行的将覆盖先执行的数据,而真正被调用者取的返回值就是最后一次写入的。那么,按照这个思想,下面的这个例子也就不难理解了。

    finally中的return 会覆盖 try 或者catch中的返回值。

    public static void main(String[] args)
        {
            int result;
            
            result  =  foo();
            System.out.println(result);     /2
            
            result = bar();
            System.out.println(result);    /2
        }
    
        @SuppressWarnings("finally")
        public static int foo()
        {
            trz{
                int a = 5 / 0;
            } catch (Exception e){
                return 1;
            } finally{
                return 2;
            }
    
        }
    
        @SuppressWarnings("finally")
        public static int bar()
        {
            try {
                return 1;
            }finally {
                return 2;
            }
        }

    finally中的return会抑制(消灭)前面try或者catch块中的异常

     

    class TestException
    {
        public static void main(String[] args)
        {
            int result;
            try{
                result = foo();
                System.out.println(result);           //输出100
            } catch (Exception e){
                System.out.println(e.getMessage());    //没有捕获到异常
            }
            
            
            try{
                result  = bar();
                System.out.println(result);           //输出100
            } catch (Exception e){
                System.out.println(e.getMessage());    //没有捕获到异常
            }
        }
        
        //catch中的异常被抑制
        @SuppressWarnings("finally")
        public static int foo() throws Exception
        {
            try {
                int a = 5/0;
                return 1;
            }catch(ArithmeticException amExp) {
                throw new Exception("我将被忽略,因为下面的finally中使用了return");
            }finally {
                return 100;
            }
        }
        
        //try中的异常被抑制
        @SuppressWarnings("finally")
        public static int bar() throws Exception
        {
            try {
                int a = 5/0;
                return 1;
            }finally {
                return 100;
            }
        }
    }
    

    finally中的异常会覆盖(消灭)前面try或者catch中的异常

     

    class TestException
    {
        public static void main(String[] args)
        {
            int result;
            try{
                result = foo();
            } catch (Exception e){
                System.out.println(e.getMessage());    //输出:我是finaly中的Exception
            }
            
            
            try{
                result  = bar();
            } catch (Exception e){
                System.out.println(e.getMessage());    //输出:我是finaly中的Exception
            }
        }
        
        //catch中的异常被抑制
        @SuppressWarnings("finally")
        public static int foo() throws Exception
        {
            try {
                int a = 5/0;
                return 1;
            }catch(ArithmeticException amExp) {
                throw new Exception("我将被忽略,因为下面的finally中抛出了新的异常");
            }finally {
                throw new Exception("我是finaly中的Exception");
            }
        }
        
        //try中的异常被抑制
        @SuppressWarnings("finally")
        public static int bar() throws Exception
        {
            try {
                int a = 5/0;
                return 1;
            }finally {
                throw new Exception("我是finaly中的Exception");
            }
            
        }
    }

     

    上面的3个例子都异于常人的编码思维,因此我建议:

    • 不要在fianlly中使用return。
    • 不要在finally中抛出异常。
    • 减轻finally的任务,不要在finally中做一些其它的事情,finally块仅仅用来释放资源是最合适的。
    • 将尽量将所有的return写在函数的最后面,而不是try ... catch ... finally中。

     

    作者:代码钢琴家-lulipro 
    出处:http://www.cnblogs.com/lulipro/ 
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。为了获得更好的阅读体验,请访问原博客地址。限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。


    展开全文
  • Java中的异常有哪几类?分别怎么使用

    千次阅读 2017-12-20 22:46:20
    java程序在运行时发生的不正常情况,而异常就是按照面向对象的思想对不正常情况进行封装,将这些情况封装成为对象。Throwable 定义了问题的共性的功能它的两...其中异常为Exception,它分为,编译时会被检测的异常

    java程序在运行时发生的不正常情况,而异常就是按照面向对象的思想对不正常情况进行封装,将这些情况封装成为对象。

    Throwable 定义了问题的共性的功能

    它的两个子类

    1. Exception:由JVM发生的,并告知使用者。可以进行针对性的处理。
    2. Error:由系统底层发生的,告知JVM,JVM告知使用者。不做针对性处理,直接修改代码。

    其中异常为Exception,它分为两类,编译时会被检测的异常 和 运行时异常(编译时不会被检测)RuntimeException及其子类。

    1. 被检查的异常,是编写程序之前就能够遇见的可能发生的异常,在方法中将预知的对象声明出去直到jvm。对于那些能够或者知道处理办法的用 try catch 代码块进行处理。
    2. 运行时异常,可能在执行方法期间抛出但未被捕获的 ,也被称为是‘’不受检查异常‘’RuntimeException 的任何子类都无需在 throws 子句中进行声明。当发生异常的时候程序,就会被Java虚拟机抛出。
        if( t == null){
            throw new NullPointerException();
        }
        空指针异常就是一种常见的运行时异常。
    展开全文
  • NLP之文本分类

    万次阅读 2018-09-26 15:08:07
    决策树是一棵树,树的根结点是整个数据集合空间,每个结点是对一个单一变量的测试,该测试将数据集合空间分割成两个或更多个类别,即决策树可以是二叉树也可以是多叉树。每个叶结点是属于单一类别的记录。构造决策...

    文本自动分类简称文本分类(text categorization),是模式识别与自然语言处理密切结合的研究课题。传统的文本分类是基于文本内容的,研究如何将文本自动划分成政治的、经济的、军事的、体育的、娱乐的等各种类型。

    目录

    文本表示

    文本向量化

    向量的相似性度量(similarity)

    文本特征选择方法

    特征权重计算方法

    分类器设计

    文本分类评测指标


    文本分类是在预定义的分类体系下,根据文本的特征(内容或属性),将给定文本与一个或多个类别相关联的过程。因此,文本分类研究涉及文本内容理解和模式分类等若干自然语言理解和模式识别问题。

    文本分类任务的最终目的是要找到一个有效的映射函数,准确地实现域D×C到值T或F的映射,这个映射函数实际上就是我们通常所说的分类器。因此,文本分类中有两个关键问题:一个是文本的表示,另一个就是分类器设计。

    根据分类知识获取方法的不同,文本自动分类系统大致可分为两种类型:基于知识工程(knowledge engineering, KE)的分类系统和基于机器学习(machine learning, ML)的分类系统。90年代以后,基于统计机器学习的文本分类方法日益受到重视,这种方法在准确率和稳定性方面具有明显的优势。系统使用训练样本进行特征选择和分类器参数训练,根据选择的特征对待分类的输入样本进行形式化,然后输入到分类器进行类别判定,最终得到输入样本的类别。

    文本表示

    文本向量化

    一个文本表现为一个由文字和标点符号组成的字符串,由字或字符组成词,由词组成短语,进而形成句、段、节、章、篇的结构。要使计算机能够高效地处理真实文本,就必须找到一种理想的形式化表示方法,这种表示一方面要能够真实地反映文档的内容(主题、领域或结构等),另一方面,要有对不同文档的区分能力。

    目前文本表示通常采用向量空间模型(vecto rspace model,VSM)。

    下面首先给出VSM涉及的一些基本概念。
    文档(document):通常是文章中具有一定规模的片段,如句子、句群、段落、段落组直至整篇文章。
    项/特征项(term/feature term):特征项是VSM中最小的不可分的语言单元,可以是字、词、词组或短语等。一个文档的内容被看成是它含有的特征项所组成的集合。
    项的权重(term weight):对于含有n个特征项的文档,每一特征项tk都依据一定的原则被赋予一个权重wk,表示它们在文档中的重要程度。

    这样一个文档D可用它含有的特征项及其特征项所对应的权重所表示。

    一个文档在上述约定下可以看成是n维空间中的一个向量,这就是向量空间模型的由来。

    因此采用向量空间模型进行文本表示时,需要经过以下两个主要步骤:
    ①根据训练样本集生成文本表示所需要的特征项序列D={t1,t2,…,td};
    ②依据文本特征项序列,对训练文本集和测试样本集中的各个文档进行权重赋值、规范化等处理,将其转化为机器学习算法所需的特征向量。

    向量的相似性度量(similarity)

    任意两个文档D1和D2之间的相似系数Sim(D1,D2)指两个文档内容的相关程度(degree of relevance)。设文档D1和D2表示VSM中的两个向量:
    D1=D1(w11,w12,…,w1n)
    D2=D2(w21,w22,…,w2n)

    那么,可以借助于n维空间中两个向量之间的某种距离来表示文档间的相似系数,常用的方法是使用向量之间的内积来计算。

    如果考虑向量的归一化,则可使用两个向量夹角的余弦值来表示相似系数:

    文本特征选择方法

    在向量空间模型中,表示文本的特征项可以选择字、词、短语,甚至“概念”等多种元素。但是,如何选取特征,各种特征应该赋予多大的权重,选取不同的特征对文本分类系统的性能有什么影响等,很多问题都值得深入研究。目前已有的特征选取方法比较多,常用的方法有:基于文档频率(document frequency, DF)的特征提取法、信息增益(information gain, IG)法、χ2统计量(CHI)法和互信息(mutual information, MI)方法等。

    1.基于文档频率的特征提取法

    文档频率(DF)是指出现某个特征项的文档的频率。基于文档频率的特征提取法通常的做法是:从训练语料中统计出包含某个特征的文档的频率(个数),然后根据设定的阈值,当该特征项的DF值小于某个阈值时,从特征空间中去掉该特征项,因为该特征项使文档出现的频率太低,没有代表性;当该特征项的DF值大于另外一个阈值时,从特征空间中也去掉该特征项,因为该特征项使文档出现的频率太高,没有区分度。

    基于文档频率的特征选择方法可以降低向量计算的复杂度,并可能提高分类的准确率,因为按这种选择方法可以去掉一部分噪声特征。这种方法简单、易行。但严格地讲,这种方法只是一种借用算法,其理论根据不足。根据信息论我们知道,某些特征虽然出现频率低,但往往包含较多的信息,对于分类的重要性很大。对于这类特征就不应该使用DF方法将其直接排除在向量特征之外。

    2.信息增益法

    信息增益(IG)法依据某特征项ti为整个分类所能提供的信息量多少来衡量该特征项的重要程度,从而决定对该特征项的取舍。某个特征项ti的信息增益是指有该特征或没有该特征时,为整个分类所能提供的信息量的差别,其中,信息量的多少由熵来衡量。因此,信息增益即不考虑任何特征时文档的熵和考虑该特征后文档的熵的差值

    从信息增益的定义可知,一个特征的信息增益实际上描述的是它包含的能够帮助预测类别属性的信息量。从理论上讲,信息增益应该是最好的特征选取方法,但实际上由于许多信息增益比较高的特征出现频率往往较低,所以,当使用信息增益选择的特征数目比较少时,往往会存在数据稀疏问题,此时分类效果也比较差。因此,有些系统实现时,首先对训练语料中出现的每个词(以词为特征)计算其信息增益,然后指定一个阈值,从特征空间中移除那些信息增益低于此阈值的词条,或者指定要选择的特征个数,按照增益值从高到低的顺序选择特征组成特征向量。

    3.χ2统计量

     χ2统计量(CHI)衡量的是特征项ti和类别Cj之间的相关联程度,并假设ti和Cj之间符合具有一阶自由度的χ2分布。特征对
    于某类的χ2统计值越高,它与该类之间的相关性越大,携带的类别信息也较多,反之则越少。

    4.互信息法

    互信息(MI)法的基本思想是:互信息越大,特征ti和类别Cj共现的程度越大。

    以上是文本分类中比较经典的一些特征选取方法,实际上还有很多其他文本特征选取方法,例如,DTP(distance to transition point)方法,期望交叉熵法、文本证据权法、优势率方法,以及国内学者提出的“类别区分词”的特征提取方法,组合特征提取方法,基于粗糙集(rough set)的特征提取方法TFACQ,以及利用自然语言文本所隐含规律等多种信息的强类信息词(strong information class word, SCIW)的特征选取方法等等。

    另外需要指出的是,无论选择什么作为特征项,特征空间的维数都是非常高的,在汉语文本分类中问题表现得更为突出。这样的高维特征向量对后面的分类器存在不利的影响,很容易出现模式识别中的“维数灾难”现象。而且,并不是所有的特征项对分类都是有利的,很多提取出来的特征可能是噪声。因此,如何降低特征向量的维数,并尽量减少噪声,仍然是文本特征提取中的两个关键问题。

    特征权重计算方法

    特征权重用于衡量某个特征项在文档表示中的重要程度或者区分能力的强弱。权重计算的一般方法是利用文本的统计信息,主要是词频,给特征项赋予一定的权重。

    我们将一些常用的权重计算方法归纳为表13-2所示的形式。表中各变量的说明如下:wij表示特征项ti在文本Dj中的权重,tfij表示特征项ti在训练文本Dj中出现的频度;ni是训练集中出现特征项ti的文档数,N是训练集中总的文档数;M为特征项的个数,nti为特征项ti在训练语料中出现的次数。


    倒排文档频度(inverse document frequency, IDF)法是1972年Spark Jones提出的计算词与文献相关权重的经典计算方法,其在信息检索中占有重要地位。该方法在实际使用中,常用公式L+log ((N-ni)/ni)替代,其中,常数L为经验值,一般取为1。IDF方法的权重值随着包含 某个特征的文档数量ni的变化呈反向变化,在极端情况下,只在一篇文档中出现的特征含有最高的IDF值。TF-IDF方法中公式有多种表达形式,TFC方法和ITC方法都是TF-IDF方法的变种。

    TF-IWF(inverse word frequency)权重算法也是在TF-IDF算法的基础上由Basili et al.(1999)提出来的。TF-IWF与TF-IDF的不同主要体现在两个方面:①TF-IWF算法中用特征频率倒数的对数值IWF代替IDF; ②TF-IWF算法中采用了IWF的平方,而不像IDF中采用的是一次方。R.Basili等认为IDF的一次方给了特征频率太多的倚重,所以用IWF的平方来平衡权重值对于特征频率的倚重。

    除了上面介绍的这些比较常用的方法以外,还有很多其他权重计算方法。例如:Dagan et al.(1997)提出的基于错误驱动的(mistake-driven)特征权重算法,这种算法的类权重向量不是通过一个表达式直接计算出来的,而是首先为每个类指定一个初始权重向量,不断输入训练文本,并根据对训练文本的分类结果调整类权重向量的值,直到类权重向量的值大致不再改变为止。

    方法。例如:Dagan et al.(1997)提出的基于错误驱动的(mistake-driven)特征权重算法,这种算法的类权重向量不是通过一个表达式直接计算出来的,而是首先为每个类指定一个初始权重向量,不断输入训练文本,并根据对训练文本的分类结果调整类权重向量的值,直到类权重向量的值大致不再改变为止。

    分类器设计

    文本分类本身是一个分类问题,因此,一般的模式分类方法都可用于文本分类研究。常用的分类算法包括:朴素的贝叶斯分类法
    (naΪve Bayesian classifier)、基于支持向量机(support vector machines, SVM)的分类器、k-最近邻法(k-nearest neighbor, kNN)、神经网络法(neural network, NNet)、决策树(decision tree)分类法、模糊分类法(fuzzy classifier)、Rocchio分类方法和Boosting算法等。

    1.朴素贝叶斯分类器

    朴素贝叶斯分类器的基本思想是利用特征项和类别的联合概率来估计给定文档的类别概率。

    假设文本是基于词的一元模型,即文本中当前词的出现依赖于文本类别,但不依赖于其他词及文本的长度,也就是说,词与词之间是独立的。根据贝叶斯公式,文档Doc属于Ci类的概率为 

    在具体实现时,通常又分为两种情况:
    (1)文档Doc采用DF向量表示法,即文档向量V的分量为一个布尔值,0表示相应的特征在该文档中未出现,1表示特征在文档中出现。
    (2)若文档Doc采用TF向量表示法,即文档向量V的分量为相应特征在该文档中出现的频度。

    2.基于支持向量机的分类器

    基于支持向量机(support vector machine, SVM)的分类方法主要用于解决二元模式分类问题。

    SVM的基本思想是在向量空间中找到一个决策平面(decision surface),这个平面能“最好”地分割两个分类中的数据点。支持向量机分类法就是要在训练集中找到具有最大类间界限(margin)的决策平面。

    由于支持向量机算法是基于两类模式识别问题的,因而,对于多类模式识别问题通常需要建立多个两类分类器。与线性判别函数一样,它的结果强烈地依赖于已知模式样本集的构造,当样本容量不大时,这种依赖性尤其明显。此外,将分界面定在最大类间隔的中间,对于许多情况来说也不是最优的。对于线性不可分问题也可以采用类似于广义线性判别函数的方法,通过事先选择好的非线性映射将输入模式向量映射到一个高维空间,然后在这个高维空间中构造最优分界超平面。

    根据Yang and Liu (1999)的实验结果,SVM的分类效果要好于NNet、贝叶斯分类器、Rocchio和LLSF(linear least-square fit)分类器的效果,与kNN方法的效果相当。

    3.k-最近邻法

    kNN方法的基本思想是:给定一个测试文档,系统在训练集中查找离它最近的k个邻近文档,并根据这些邻近文档的分类来给该文档的候选类别评分。把邻近文档和测试文档的相似度作为邻近文档所在类别的权重,如果这k个邻近文档中的部分文档属于同一个类别,则将该类别中每个邻近文档的权重求和,并作为该类别和测试文档的相似度。然后,通过对候选分类评分的排序,给出一个阈值。

    4.基于神经网络的分类器

    神经网络(NNet)是人工智能中比较成熟的技术之一,基于该技术的分类器的基本思想是:给每一类文档建立一个神经网络,输入通常是单词或者是更为复杂的特征向量,通过机器学习获得从输入到分类的非线性映射。

    根据Yang and Liu (1999)的实验结果,NNet分类器的效果要比kNN分类器和SVM分类器的效果差,而且训练NNet的时间开销远远超过其他分类方法,所以,实际应用并不广泛。

    5.线性最小平方拟合法

    线性最小平方拟合(linear least-squares fit, LLSF)是一种映射方法其出发点是从训练集和分类文档中学习得到多元回归模型
    (multivariate regression model)。其中训练数据用输入/输出向量表示,输入向量是用传统向量空间模型表示的文档
    (词和对应的权重),输出向量则是文档对应的分类(带有0-1权重)。通过在向量的训练对上求解线性最小平方拟合,得到一个“单词-分类”的回归系数矩阵。

    根据Yang and Liu (1999)的实验结果,LLSF算法的分类效果稍逊于kNN和SVM算法的效果。

    6.决策树分类器

    决策树分类器也是模式识别研究的基本方法之一,其出发点是:大量复杂系统的组成普遍存在着等级分层现象,或者说复杂任务是可以通过等级分层分解完成的,文本处理过程也不例外。

    决策树是一棵树,树的根结点是整个数据集合空间,每个分结点是对一个单一变量的测试,该测试将数据集合空间分割成两个或更多个类别,即决策树可以是二叉树也可以是多叉树。每个叶结点是属于单一类别的记录。构造决策树分类器时,首先要通过训练生成决策树,然后再通过测试集对决策树进行修剪。一般可通过递归分割的过程构建决策树,其生成过程通常是自上而下的,选择分割的方法有多种,但是目标都是一致的,就是对目标文档进行最佳分割。从根结点到叶结点都有一条路径,这条路径就是一条决策“规则”。

    在决定哪个属性域(field)作为目前最佳的分类属性时,一般的做法是穷尽所有的属性域,对每个属性域分裂的好坏进行量化,从而计算出最佳分裂。信息增益是决策树训练中常用的衡量给定属性区分训练样本能力的定量标准。

    7.模糊分类器

    按照模糊分类方法的观点,任何一个文本或文本类都可以通过其特征关键词来描述其内容特征,因此,可以用一个定义在特征关键词类上的模糊集来描述它们。

    判定分类文本T所属的类别可以通过计算文本T的模糊集FT分别与其他每个文本类的模糊集Fk的关联度SR实现,两个类的关联度越大说明这两个类越贴近。

    8.Rocchio分类器

    Rocchio分类器是情报检索领域经典的算法,其基本思想是,首先为每一个训练文本C建立一个特征向量,然后使用训练文本的特征向量为每个类建立一个原型向量(类向量)。当给定一个待分类文本时,计算待分类文本与各个类别的原型向量(类向量)之间的距离,其距离可以是向量点积、向量之间夹角的余弦值或者其他相似度计算函数,根据计算出来的距离值决定待分类文本属于哪一类别。

    Rocchio分类方法的特点是计算简单、易行,其分类效果仅次于kNN方法和SVM方法。

    9.基于投票的分类方法

    基于投票的分类方法是在研究多分类器组合时提出的,其核心思想是:k个专家判断的有效组合应该优于某个专家个人的判断结果。
    投票算法主要有两种:Bagging算法和Boosting算法。

    Bagging算法
    训练R个分类器fi(i=1,2,…,R),其中,fi是利用从训练集(N篇文档)中随机抽取(取出后再放回)N次文档构成的训练集训练得到的。对于新文档D,用这R个分类器分别对D划分类别,得到的最多的那个类别作为D的最终判别类别。

    Boosting算法
    与Bagging算法类似,该算法需要训练多个分类器,但训练每个分量分类器的训练样本不再是随机抽取,每个分类器的训练集由其他各个分类器所给出的“最富信息”的样本点组成。基于Boosting方法有许多不同的变形,其中最流行的一种就是AdaBoost方法,该方法在文本分类领域中有着非常广泛的应用。

    文本分类评测指标

    针对不同的目的,人们提出了多种文本分类器性能评价方法,包括召回率、正确率、F-测度值、微平均和宏平均、平衡点(break-even point)、11点平均正确率(11-point average precision)等。

    一般地讲,正确率和召回率是一对相互矛盾的物理量,提高正确率往往要牺牲一定的召回率,反之亦然。在很多情况下,单独考虑正确率或者召回率来对分类器进行评价都是不全面的。因此,1999提出了通过调整分类器的阈值,调整正确率和召回率的值,使其达到一个平衡点的评测方法。

    Taghva et al.(2004)为了更加全面地评价一个分类器在不同召回率情况下的分类效果,调整阈值使得分类器的召回率分别为:0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1,然后计算出对应的11个正确率,取其平均值,这个平均值即为11点平均正确率,用这个平均正确率衡量分类器的性能。

     

    展开全文
  • 按照扫描方向的不同,串匹配分词方法可以分为正向匹配和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与标注相...

    1、 基于字符串匹配的分词方法

    这种方法又叫做机械分词方法,它是按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行配,若在词典中找到某个字符串,则匹配成功(识别出一个词)。按照扫描方向的不同,串匹配分词方法可以分为正向匹配和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与标注相结合的一体化方法。常用的几种机械分词方法如下;

    1) 、正向最大匹配

    2) 、逆向最大匹配

    3) 、最少切分(使每一句中切出的词数最小)

    还可以将上述各种方法相互组合,例如,可以将正向最大匹配方法和逆向最大匹配方法结合起来构成双向匹配法。由于汉语单字成词的特点,正向最小匹配和逆向最小匹配一般很少使用。一般说来,逆向匹配的切分精度略高于正向匹配,遇到的歧义现象也较少。统计结果表明,单纯使用正向最大匹配的错误率为1/169,单纯使用逆向最大匹配的错误率为1/245。但这种精度还远远不能满足实际的需要。由于分词是一个智能决策过程,机械分词方法无法解决分词阶段的两大基本问题:歧义切分问题和未登录词识别问题。实际使用的分词系统,都是把机械分词作为一种初分手段,还需通过利用各种其它的语言信息来进一步提高切分的准确率。
    一种方法是改进扫描方式,称为特征扫描或标志切分,优先在待分析字符串中识别和切分出一些带有明显特征的词,以这些词作为断点,可将原字符串分为较小的串再来进机械分词,从而减少匹配的错误率。
    另一种方法是将分词和词类标注结合起来,利用丰富的词类信息对分词决策提供帮助,并且在标注过程中又反过来对分词结果进行检验、调整,从而极大地提高切分的准确率。

    对于机械分词方法,可以建立一个一般的模型,形式地表示为ASM(d,a,m),即Automatic Segmentation Model。其中,
    d:匹配方向,+1表示正向,-1表示逆向;
    a:每次匹配失败后增加/减少字串长度(字符数),+1为增字,-1为减字;
    m:最大/最小匹配标志,+1为最大匹配,-1为最小匹配。

    例如,ASM(+, -, +)就是正向减字最大匹配法(即MM方法),ASM(-, -, +)就是逆向减字最大匹配法(即RMM方法),等等。对于现代汉语来说,只有m=+1是实用的方法。用这种模型可以对各种方法的复杂度进行比较,假设在词典的匹配过程都使用顺序查找和相同的计首字索引查找方法,则在不记首字索引查找次数(最小为log<汉字总数> » 12~14)和词典读入内存时间的情况下,对于典型的词频分布,减字匹配ASM(d,-,m)的复杂度约为12.3次,增字匹配ASM(d,+,m)的复杂度约为10.6。

    另外,还可以证明,早期曾流行一时的“切分标志字串”预处理方法是一个毫无必要的技术,它增加了一遍扫描“切分标志词典”的时空复杂性,却并没有提高分词精度,因为所谓的切分标志其实都已经隐含在词典之中,是对词典功能的重复。实际上“切分标志”也没有标记歧义字段的任何信息。因此,在近来的分词系统中,已经基本上废弃了这种“切分标志”预处理方法。

    2、基于理解的分词方法

    通常的分析系统,都力图在分词阶段消除所有歧义切分现象。而有些系统则在后续过程中来处理歧义切分问题,其分词过程只是整个语言理解过程的一小部分。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得有关词、句子等的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程。这种分词方法需要使用大量的语言知识和信息。由于汉语语言知识的笼统、复杂性,难以将各种语言信息组织成机器可直接读取的形式,因此目前基于理解的分词系统还处在试验阶段。

    3、基于统计的分词方法

    从形式上看,词是稳定的字的组合,因此在上下文中,相邻的字同时出现的次数越多,就越有可能构成一个词。因此字与字相邻共现的频率或概率能够较好的反映成词的可信度。可以对语料中相邻共现的各个字的组合的频度进行统计,计算它们的互现信息。定义两个字的互现信息为: ,其中 是汉字X、Y的相邻共现概率, 、 分别是X、Y在语料中出现的概率。互现信息体现了汉字之间结合关系的紧密程度。当紧密程度高于某一个阈值时,便可认为此字组可能构成了一个词。这种方法只需对语料中的字组频度进行统计,不需要切分词典,因而又叫做无词典分词法或统计取词方法。但这种方法也有一定的局限性,会经常抽出一些共现频度高、但并不是词的常用字组,例如“这一”、“之一”、“有的”、“我的”、“许多的”等,并且对常用词的识别精度差,时空开销大。实际应用的统计分词系统都要使用一部基本的分词词典(常用词词典)进行串匹配分词,同时使用统计方法识别一些新的词,即将串频统计和串匹配结合起来,既发挥匹配分词切分速度快、效率高的特点,又利用了无词典分词结合上下文识别生词、自动消除歧义的优点。

    人工智能、大数据、云计算和物联网的未来发展值得重视,均为前沿产业,多智时代专注于人工智能和大数据的入门和科谱,在此为你推荐几篇优质好文:
    如何快速入门NLP自然语言处理概述
    http://www.duozhishidai.com/article-11742-1.html
    自然语言理解过程主要有哪些层次,各层次的功能是怎么样?
    http://www.duozhishidai.com/article-1726-1.html
    从语言学到深度学习NLP,一文概述自然语言处理
    http://www.duozhishidai.com/article-1120-1.html


    多智时代-人工智能大数据学习入门网站|人工智能、大数据、物联网云计算的学习交流网站

    多智时代-人工智能大数据学习入门网站|人工智能、大数据、云计算、物联网的学习服务的好平台
    展开全文
  • Linux驱动简介及分类

    千次阅读 2019-12-16 16:01:35
    Linux驱动主要具有如下点作用: 系统调用是应用程序和内核之间的接口,驱动程序是内核和硬件之间的接口; 驱动程序接受上层软件(应用程序、内核)的请求,完成对硬件的操作,屏蔽了硬件的细节; 驱动程序将硬件...
  • 最优化算法概述以及常见分类

    千次阅读 2020-07-10 09:57:58
    1 最优化问题概述 通俗的来说,最优化问题就是在一定的条件约束下,使得效果最好。最优化问题是一种数学问题,是研究在给定的约束之下...最优化问题可以分为函数优化问题和组合优化问题两大。函数优化问题的对象是一
  • 计算机语言的种分类

    万次阅读 2017-10-31 12:39:18
    常见的种分类 高级语言和低级语言 动态类型和静态类型 强制类型和弱类型 编译型,解释型,半编译半解释 面向对象型和面向过程型
  • 数据挖掘之分类

    千次阅读 2015-10-04 10:51:14
    根据选择属性的顺序可以将决策树算法分为ID3,C4.5等。其中,决策树算法CART只产生二元划分,它们考虑创建K个属性的二元划分的所有2 k-1 -1种方法。图1显示了把婚姻状况的属性值划分为两个子集的三种不同的分组方法。...
  • 从数据挖掘算法所依托的数理基础角度归类,目前数据挖掘算法主要分为三大:机器学习方法、统计方法与神经网络方法。机器学习方法分为决策树、基于范例学习、规则归纳与遗传算法等:统计方法细分为回归分析、时间序列...
  • 机器学习:种分类识别问题

    千次阅读 2018-11-04 20:56:12
    分类和识别是机器学习领域非常常见的一问题,比如之前非常火热的 ImageNet 挑战赛,还有人脸识别,人脸表情识别等,接触机器学习的一般来说,都是从识别开始,因为识别比较简单直观,而且大家都对目前识别领域比较...
  • 由于颜色是物体必备的视觉特性,同一物体一般会有相似的色彩特征,所以人们就根据这一点用色彩来对图像内容进行区分。颜色直方图能够描述不同色彩在整个图像中所占的比例,即使图像内容发生了大小、旋转上的变化,...
  • 推荐算法分类

    千次阅读 2018-10-24 15:25:11
    推荐算法具有非常多的应用场景和商业价值,因此对推荐算法值得好好研究。推荐算法种类很多,但是目前应用最广泛的应该是协同过滤...概括来说,可以分为以下5种: 1)基于内容的推荐:这一一般依赖于自然语言处理NL...
  • 主要有三不同的学习方法:监督学习(Supervised learning)、非监督学习(Unsupervised learning)、半监督学习(Semi-supervised learning)。 监督学习:通过已有的一部分输入数据与输出数据之间的相应关系。生成一个...
  • 正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十张数据库表。 其中的核心业务模块主要包括用户模块、部门...
  • 1.基于概率统计的Bayes分类器 因为在实际分类中由于考虑的侧重点不同或者关心的点...在Bayes分类器中将不同的侧重分为错误率和风险俩个方面,最终通过取舍选择不同决策以求达到自己最理想的分类。先验概率P(w) 即...
  • (一)图像分割方法的分类

    万次阅读 2017-07-24 11:57:48
    阈值法的基本思想是基于图像的灰度特征来计算一个或多个灰度阈值,并将图像中每个像素的灰度值与阈值相比较,最后将像素据比较结果到合适的类别中。因此,该方法最为关键的一步就是按照某个准则函数来求解最佳...
  • 集成学习分类和区别

    千次阅读 2017-08-08 10:34:00
    集成学习 1.1 定义 ...所谓集成学习(ensemble learning),是指通过构建多个弱学习器,然后...下图显示了集成学习的整个流程:首次按产生一组“个体学习器”,这些个体学习器可以是同质的(homogeneous)(例如
  • Java面试题大全(2020版)

    万次阅读 多人点赞 2019-11-26 11:59:06
    java 中 IO 流分为几种? 按功能来:输入流(input)、输出流(output)。 按类型来:字节流和字符流。 字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位...
  • 数据挖掘的任务是从数据集中发现模式,可以发现的模式有很多种,按功能可以分为两大:预测性(Predictive)模式和描述性(Descriptive)模式。在应用中往往根据模式的实际作用细分为以下种:分类,估值,预测,...
  • java设计模式之三大分类,六大原则

    千次阅读 2017-03-11 11:18:19
    一.设计模式定义(Design Patterns) 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让...项目中合理的运用设计模式可以完美的解决
  • SVM的实现多分类的种方法以及优缺点详解

    万次阅读 多人点赞 2018-08-22 16:17:50
    转载自: ... ... SVM本身是一个二值分类器  SVM算法最初是为二值分类问题设计的,当处理多问题时,就需要构造合适的多分类器。  目前,构造SVM多分类器的方法主要有两 ...
  • 算法思想有很多,业界公认的常用算法思想有8种,分别是枚举、递推、递归、分治、贪心、试探法、动态迭代和模拟。当然8种只是一个大概的划分,是一个“仁者见仁、智者见智”的问题。 1.1 枚举算法思想 知识点讲解...
  • 目标跟踪算法的分类(一)

    万次阅读 多人点赞 2015-09-14 11:41:37
    通常情况下,摄像机的运动形式可以分为两种:a)摄像机的支架固定,但摄像机可以偏转、俯仰以及缩放; b)将摄像机装在某个移动的载体上。由于以上两种情况下的背景及前景图像都在做全局运动,要准确检测运动目标的...
  • 【数据可视化】数据可视化分类

    千次阅读 2015-06-01 22:03:10
    数据可视化分为:科学可视化、信息可视化,可视化分析学这三个主要分支。  科学可视化,处理科学数据,面向科学和工程领域的科学可视化,研究带有空间坐标和几何信息的三维空间测量数据、计算模拟数据和医疗影像...
  • 种常见的排序思想

    千次阅读 2017-07-13 16:01:53
    本文只记录排序思想和图解,没有贴相应代码。
  • 学习SVM(二) 如何理解支持向量机的最大分类间隔

    万次阅读 多人点赞 2017-06-24 16:01:45
    学习SVM(四) 理解SVM中的支持向量(Support Vector)SVM算法在在1995年正式发表,在针对中小型数据规模的分类任务上有着卓越的效果,同时有着完整的理论证明,在20世纪末的年和21世纪初的10年完胜神经网络,吴...
  • 操作系统的分类及介绍

    万次阅读 2018-03-19 09:58:31
    操作系统分类:1)按用户界面的使用环境和功能特征分为... 3)时系统:它的设计思想是,CPU的时间划分为若干个小片段,每个任务依次执行一小片段。主要应用于多用户操作,如linux. 4)实时操作系统:实时操作系统...
  • 计算机编程语言的分类

    千次阅读 2019-02-18 17:31:58
    Table of Contents 前言 机器语言 ...为什么软件项目会分为前端和后端? java和javascrip有什么关系和区别? C#和.Net有什么关系和区别? 前言 所有的工程师在接触编程有一段时间了之后,必...
  • 细粒度图像分类(FGVC)---综述

    万次阅读 多人点赞 2019-04-28 16:28:02
    细粒度图像分类问题是对大下的子类进行识别。细粒度图像分析任务相对通用图像(General/Generic Images)任务的区别和难点在于其图像所属类别的粒度更为精细。 以图1为例,通用图像分类其任务诉求是将“袋鼠”和...
  • 语音识别是完成语音到文字的转换。...机器翻译系统的输入通常是印刷文本,计算 机能清楚地区单词和单词串。而语音识别系统的输入是语音,其复杂度要大得多,特别是口语 有很多的不确定性。人与人交流时,往...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 319,439
精华内容 127,775
关键字:

思想可以分为哪几类