精华内容
下载资源
问答
  • 10 个最难回答的 Java 问题

    万次阅读 多人点赞 2019-10-08 19:31:08
    一个棘手的 Java 问题,如果 Java编程语言不是你设计的,你怎么能回答这个问题呢。Java编程的常识和深入了解有助于回答这种棘手的 Java 核心方面的面试问题。 为什么 wait,notify 和 notifyAll 是在 Object 中...

     1.为什么等待和通知是在 Object 类而不是 Thread 中声明的?

    一个棘手的 Java 问题,如果 Java编程语言不是你设计的,你怎么能回答这个问题呢。Java编程的常识和深入了解有助于回答这种棘手的 Java 核心方面的面试问题。

    为什么 wait,notify 和 notifyAll 是在 Object 类中定义的而不是在 Thread 类中定义

    这是有名的 Java 面试问题,招2~4年经验的到高级 Java 开发人员面试都可能碰到。

    这个问题的好在它能反映了面试者对等待通知机制的了解, 以及他对此主题的理解是否明确。就像为什么 Java 中不支持多继承或者为什么 String 在 Java 中是 final 的问题一样,这个问题也可能有多个答案。

    为什么在 Object 类中定义 wait 和 notify 方法,每个人都能说出一些理由。从我的面试经验来看, wait 和 nofity 仍然是大多数Java 程序员最困惑的,特别是2到3年的开发人员,如果他们要求使用 wait 和 notify, 他们会很困惑。因此,如果你去参加 Java 面试,请确保对 wait 和 notify 机制有充分的了解,并且可以轻松地使用 wait 来编写代码,并通过生产者-消费者问题或实现阻塞队列等了解通知的机制。

    为什么等待和通知需要从同步块或方法中调用, 以及 Java 中的 wait,sleep 和 yield 方法之间的差异,如果你还没有读过,你会觉得有趣。为何 wait,notify 和 notifyAll 属于 Object 类? 为什么它们不应该在 Thread 类中? 以下是我认为有意义的一些想法:

    1) wait 和 notify 不仅仅是普通方法或同步工具,更重要的是它们是 Java 中两个线程之间的通信机制。对语言设计者而言, 如果不能通过 Java 关键字(例如 synchronized)实现通信此机制,同时又要确保这个机制对每个对象可用, 那么 Object 类则是的正确声明位置。记住同步和等待通知是两个不同的领域,不要把它们看成是相同的或相关的。同步是提供互斥并确保 Java 类的线程安全,而 wait 和 notify 是两个线程之间的通信机制。

    2) 每个对象都可上锁,这是在 Object 类而不是 Thread 类中声明 wait 和 notify 的另一个原因。

    3) 在 Java 中为了进入代码的临界区,线程需要锁定并等待锁定,他们不知道哪些线程持有锁,而只是知道锁被某个线程持有, 并且他们应该等待取得锁, 而不是去了解哪个线程在同步块内,并请求它们释放锁定。

    4) Java 是基于 Hoare 的监视器的思想。在Java中,所有对象都有一个监视器。

    线程在监视器上等待,为执行等待,我们需要2个参数:

    • 一个线程

    • 一个监视器(任何对象)

    在 Java 设计中,线程不能被指定,它总是运行当前代码的线程。但是,我们可以指定监视器(这是我们称之为等待的对象)。这是一个很好的设计,因为如果我们可以让任何其他线程在所需的监视器上等待,这将导致“入侵”,导致在设计并发程序时会遇到困难。请记住,在 Java 中,所有在另一个线程的执行中侵入的操作都被弃用了(例如 stop 方法)。

    2.为什么Java中不支持多重继承?

    我发现这个 Java 核心问题很难回答,因为你的答案可能不会让面试官满意,在大多数情况下,面试官正在寻找答案中的关键点,如果你提到这些关键点,面试官会很高兴。在 Java 中回答这种棘手问题的关键是准备好相关主题, 以应对后续的各种可能的问题。

    这是非常经典的问题,与为什么 String 在 Java 中是不可变的很类似; 这两个问题之间的相似之处在于它们主要是由 Java 创作者的设计决策使然。

    为什么Java不支持多重继承, 可以考虑以下两点:

    1)第一个原因是围绕钻石形继承问题产生的歧义,考虑一个类 A 有 foo() 方法, 然后 B 和 C 派生自 A, 并且有自己的 foo() 实现,现在 D 类使用多个继承派生自 B 和C,如果我们只引用 foo(), 编译器将无法决定它应该调用哪个 foo()。这也称为 Diamond 问题,因为这个继承方案的结构类似于菱形,见下图:

    即使我们删除钻石的顶部 A 类并允许多重继承,我们也将看到这个问题含糊性的一面。如果你把这个理由告诉面试官,他会问为什么 C++ 可以支持多重继承而 Java不行。嗯,在这种情况下,我会试着向他解释我下面给出的第二个原因,它不是因为技术难度, 而是更多的可维护和更清晰的设计是驱动因素, 虽然这只能由 Java 言语设计师确认,我们只是推测。维基百科链接有一些很好的解释,说明在使用多重继承时,由于钻石问题,不同的语言地址问题是如何产生的。

    2)对我来说第二个也是更有说服力的理由是,多重继承确实使设计复杂化并在转换、构造函数链接等过程中产生问题。假设你需要多重继承的情况并不多,简单起见,明智的决定是省略它。此外,Java 可以通过使用接口支持单继承来避免这种歧义。由于接口只有方法声明而且没有提供任何实现,因此只有一个特定方法的实现,因此不会有任何歧义。(实用详尽的Java面试题大全,可以在Java知音公众号回复“面试题聚合”)

    3.为什么Java不支持运算符重载?

    另一个类似棘手的Java问题。为什么 C++ 支持运算符重载而 Java 不支持? 有人可能会说+运算符在 Java 中已被重载用于字符串连接,不要被这些论据所欺骗。

    与 C++ 不同,Java 不支持运算符重载。Java 不能为程序员提供自由的标准算术运算符重载,例如+, - ,*和/等。如果你以前用过 C++,那么 Java 与 C++ 相比少了很多功能,例如 Java 不支持多重继承,Java中没有指针,Java中没有引用传递。另一个类似的问题是关于 Java 通过引用传递,这主要表现为 Java 是通过值还是引用传参。虽然我不知道背后的真正原因,但我认为以下说法有些道理,为什么 Java 不支持运算符重载。

    1)简单性和清晰性。清晰性是Java设计者的目标之一。设计者不是只想复制语言,而是希望拥有一种清晰,真正面向对象的语言。添加运算符重载比没有它肯定会使设计更复杂,并且它可能导致更复杂的编译器, 或减慢 JVM,因为它需要做额外的工作来识别运算符的实际含义,并减少优化的机会, 以保证 Java 中运算符的行为。

    2)避免编程错误。Java 不允许用户定义的运算符重载,因为如果允许程序员进行运算符重载,将为同一运算符赋予多种含义,这将使任何开发人员的学习曲线变得陡峭,事情变得更加混乱。据观察,当语言支持运算符重载时,编程错误会增加,从而增加了开发和交付时间。由于 Java 和 JVM 已经承担了大多数开发人员的责任,如在通过提供垃圾收集器进行内存管理时,因为这个功能增加污染代码的机会, 成为编程错误之源, 因此没有多大意义。

    3)JVM复杂性。从JVM的角度来看,支持运算符重载使问题变得更加困难。通过更直观,更干净的方式使用方法重载也能实现同样的事情,因此不支持 Java 中的运算符重载是有意义的。与相对简单的 JVM 相比,复杂的 JVM 可能导致 JVM 更慢,并为保证在 Java 中运算符行为的确定性从而减少了优化代码的机会。

    4)让开发工具处理更容易。这是在 Java 中不支持运算符重载的另一个好处。省略运算符重载使语言更容易处理,这反过来又更容易开发处理语言的工具,例如 IDE 或重构工具。Java 中的重构工具远胜于 C++。

    4.为什么 String 在 Java 中是不可变的?

    我最喜欢的 Java 面试问题,很棘手,但同时也非常有用。一些面试者也常问这个问题,为什么 String 在 Java 中是 final 的。

    字符串在 Java 中是不可变的,因为 String 对象缓存在 String 池中。由于缓存的字符串在多个客户之间共享,因此始终存在风险,其中一个客户的操作会影响所有其他客户。例如,如果一段代码将 String “Test” 的值更改为 “TEST”,则所有其他客户也将看到该值。由于 String 对象的缓存性能是很重要的一方面,因此通过使 String 类不可变来避免这种风险。

    同时,String 是 final 的,因此没有人可以通过扩展和覆盖行为来破坏 String 类的不变性、缓存、散列值的计算等。String 类不可变的另一个原因可能是由于 HashMap。

    由于把字符串作为 HashMap 键很受欢迎。对于键值来说,重要的是它们是不可变的,以便用它们检索存储在 HashMap 中的值对象。由于 HashMap 的工作原理是散列,因此需要具有相同的值才能正常运行。如果在插入后修改了 String 的内容,可变的 String将在插入和检索时生成两个不同的哈希码,可能会丢失 Map 中的值对象。

    如果你是印度板球迷,你可能能够与我的下一句话联系起来。字符串是Java的 VVS Laxman,即非常特殊的类。我还没有看到一个没有使用 String 编写的 Java 程序。这就是为什么对 String 的充分理解对于 Java 开发人员来说非常重要。

    String 作为数据类型,传输对象和中间人角色的重要性和流行性也使这个问题在 Java 面试中很常见。

    为什么 String 在 Java 中是不可变的是 Java 中最常被问到的字符串访问问题之一,它首先讨论了什么是 String,Java 中的 String 如何与 C 和 C++ 中的 String 不同,然后转向在Java中什么是不可变对象,不可变对象有什么好处,为什么要使用它们以及应该使用哪些场景。

    这个问题有时也会问:“为什么 String 在 Java 中是 final 的”。在类似的说明中,如果你正在准备Java 面试,我建议你看看《Java程序员面试宝典(第4版) 》,这是高级和中级Java程序员的优秀资源。它包含来自所有重要 Java 主题的问题,包括多线程,集合,GC,JVM内部以及 Spring和 Hibernate 框架等。

    正如我所说,这个问题可能有很多可能的答案,而 String 类的唯一设计者可以放心地回答它。我在 Joshua Bloch 的 Effective Java 书中期待一些线索,但他也没有提到它。我认为以下几点解释了为什么 String 类在 Java 中是不可变的或 final 的:

    1)想象字符串池没有使字符串不可变,它根本不可能,因为在字符串池的情况下,一个字符串对象/文字,例如 “Test” 已被许多参考变量引用,因此如果其中任何一个更改了值,其他参数将自动受到影响,即假设

    现在字符串 B 调用 "Test".toUpperCase(), 将同一个对象改为“TEST”,所以 A 也是 “TEST”,这不是期望的结果。

    下图显示了如何在堆内存和字符串池中创建字符串。

    2)字符串已被广泛用作许多 Java 类的参数,例如,为了打开网络连接,你可以将主机名和端口号作为字符串传递,你可以将数据库 URL 作为字符串传递, 以打开数据库连接,你可以通过将文件名作为参数传递给 File I/O 类来打开 Java 中的任何文件。如果 String 不是不可变的,这将导致严重的安全威胁,我的意思是有人可以访问他有权授权的任何文件,然后可以故意或意外地更改文件名并获得对该文件的访问权限。由于不变性,你无需担心这种威胁。这个原因也说明了,为什么 String 在 Java 中是最终的,通过使 java.lang.String final,Java设计者确保没有人覆盖 String 类的任何行为。

    3)由于 String 是不可变的,它可以安全地共享许多线程,这对于多线程编程非常重要. 并且避免了 Java 中的同步问题,不变性也使得String 实例在 Java 中是线程安全的,这意味着你不需要从外部同步 String 操作。关于 String 的另一个要点是由截取字符串 SubString 引起的内存泄漏,这不是与线程相关的问题,但也是需要注意的。

    4)为什么 String 在 Java 中是不可变的另一个原因是允许 String 缓存其哈希码,Java 中的不可变 String 缓存其哈希码,并且不会在每次调用 String 的 hashcode 方法时重新计算,这使得它在 Java 中的 HashMap 中使用的 HashMap 键非常快。简而言之,因为 String 是不可变的,所以没有人可以在创建后更改其内容,这保证了 String 的 hashCode 在多次调用时是相同的。

    5)String 不可变的绝对最重要的原因是它被类加载机制使用,因此具有深刻和基本的安全考虑。如果 String 是可变的,加载“java.io.Writer” 的请求可能已被更改为加载 “mil.vogoon.DiskErasingWriter”. 安全性和字符串池是使字符串不可变的主要原因。顺便说一句,上面的理由很好回答另一个Java面试问题: “为什么String在Java中是最终的”。要想是不可变的,你必须是最终的,这样你的子类不会破坏不变性。你怎么看?

    5.为什么 char 数组比 Java 中的 String 更适合存储密码?

    另一个基于 String 的棘手 Java 问题,相信我只有很少的 Java 程序员可以正确回答这个问题。这是一个真正艰难的核心Java面试问题,并且需要对 String 的扎实知识才能回答这个问题。

    这是最近在 Java 面试中向我的一位朋友询问的问题。他正在接受技术主管职位的面试,并且有超过6年的经验。如果你还没有遇到过这种情况,那么字符数组和字符串可以用来存储文本数据,但是选择一个而不是另一个很难。但正如我的朋友所说,任何与 String 相关的问题都必须对字符串的特殊属性有一些线索,比如不变性,他用它来说服访提问的人。在这里,我们将探讨为什么你应该使用char[]存储密码而不是String的一些原因。

    字符串:

    1)由于字符串在 Java 中是不可变的,如果你将密码存储为纯文本,它将在内存中可用,直到垃圾收集器清除它. 并且为了可重用性,会存在 String 在字符串池中, 它很可能会保留在内存中持续很长时间,从而构成安全威胁。

    由于任何有权访问内存转储的人都可以以明文形式找到密码,这是另一个原因,你应该始终使用加密密码而不是纯文本。由于字符串是不可变的,所以不能更改字符串的内容,因为任何更改都会产生新的字符串,而如果你使用char[],你就可以将所有元素设置为空白或零。因此,在字符数组中存储密码可以明显降低窃取密码的安全风险。

    2)Java 本身建议使用 JPasswordField 的 getPassword() 方法,该方法返回一个 char[] 和不推荐使用的getTex() 方法,该方法以明文形式返回密码,由于安全原因。应遵循 Java 团队的建议, 坚持标准而不是反对它。

    3)使用 String 时,总是存在在日志文件或控制台中打印纯文本的风险,但如果使用 Array,则不会打印数组的内容而是打印其内存位置。虽然不是一个真正的原因,但仍然有道理。

    我还建议使用散列或加密的密码而不是纯文本,并在验证完成后立即从内存中清除它。因此,在Java中,用字符数组用存储密码比字符串是更好的选择。虽然仅使用char[]还不够,还你需要擦除内容才能更安全。(实用详尽的Java面试题大全,可以在Java知音公众号回复“面试题聚合”)

    6.如何使用双重检查锁定在 Java 中创建线程安全的单例?

    这个 Java 问题也常被问: 什么是线程安全的单例,你怎么创建它。好吧,在Java 5之前的版本, 使用双重检查锁定创建单例 Singleton 时,如果多个线程试图同时创建 Singleton 实例,则可能有多个 Singleton 实例被创建。从 Java 5 开始,使用 Enum 创建线程安全的Singleton很容易。但如果面试官坚持双重检查锁定,那么你必须为他们编写代码。记得使用volatile变量。

    为什么枚举单例在 Java 中更好

    枚举单例是使用一个实例在 Java 中实现单例模式的新方法。虽然Java中的单例模式存在很长时间,但枚举单例是相对较新的概念,在引入Enum作为关键字和功能之后,从Java5开始在实践中。本文与之前关于 Singleton 的内容有些相关, 其中讨论了有关 Singleton 模式的面试中的常见问题, 以及 10 个 Java 枚举示例, 其中我们看到了如何通用枚举可以。这篇文章是关于为什么我们应该使用Eeame作为Java中的单例,它比传统的单例方法相比有什么好处等等。

    Java 枚举和单例模式

    Java 中的枚举单例模式是使用枚举在 Java 中实现单例模式。单例模式在 Java 中早有应用, 但使用枚举类型创建单例模式时间却不长. 如果感兴趣, 你可以了解下构建者设计模式和装饰器设计模式。

    1) 枚举单例易于书写

    这是迄今为止最大的优势,如果你在Java 5之前一直在编写单例, 你知道, 即使双检查锁定, 你仍可以有多个实例。虽然这个问题通过 Java 内存模型的改进已经解决了, 从 Java 5 开始的 volatile 类型变量提供了保证, 但是对于许多初学者来说, 编写起来仍然很棘手。与同步双检查锁定相比,枚举单例实在是太简单了。如果你不相信, 那就比较一下下面的传统双检查锁定单例和枚举单例的代码:

    在 Java 中使用枚举的单例

    这是我们通常声明枚举的单例的方式,它可能包含实例变量和实例方法,但为了简单起见,我没有使用任何实例方法,只是要注意,如果你使用的实例方法且该方法能改变对象的状态的话, 则需要确保该方法的线程安全。默认情况下,创建枚举实例是线程安全的,但 Enum 上的任何其他方法是否线程安全都是程序员的责任。

    你可以通过EasySingleton.INSTANCE来处理它,这比在单例上调用getInstance()方法容易得多。

    具有双检查锁定的单例示例

    下面的代码是单例模式中双重检查锁定的示例,此处的 getInstance() 方法检查两次,以查看 INSTANCE 是否为空,这就是为什么它被称为双检查锁定模式,请记住,双检查锁定是代理之前Java 5,但Java5内存模型中易失变量的干扰,它应该工作完美。

    你可以调用DoubleCheckedLockingSingleton.getInstance() 来获取此单例类的访问权限。

    现在,只需查看创建延迟加载的线程安全的 Singleton 所需的代码量。使用枚举单例模式, 你可以在一行中具有该模式, 因为创建枚举实例是线程安全的, 并且由 JVM 进行。

    人们可能会争辩说,有更好的方法来编写 Singleton 而不是双检查锁定方法, 但每种方法都有自己的优点和缺点, 就像我最喜欢在类加载时创建的静态字段 Singleton, 如下面所示, 但请记住, 这不是一个延迟加载单例:

    单例模式用静态工厂方法

    这是我最喜欢的在 Java 中影响 Singleton 模式的方法之一,因为 Singleton 实例是静态的,并且最后一个变量在类首次加载到内存时初始化,因此实例的创建本质上是线程安全的。

    你可以调用 Singleton.getSingleton() 来获取此类的访问权限。

    2) 枚举单例自行处理序列化

    传统单例的另一个问题是,一旦实现可序列化接口,它们就不再是 Singleton, 因为 readObject() 方法总是返回一个新实例, 就像 Java 中的构造函数一样。通过使用 readResolve() 方法, 通过在以下示例中替换 Singeton 来避免这种情况:

    如果 Singleton 类保持内部状态, 这将变得更加复杂, 因为你需要标记为 transient(不被序列化),但使用枚举单例, 序列化由 JVM 进行。

    3) 创建枚举实例是线程安全的

    如第 1 点所述,因为 Enum 实例的创建在默认情况下是线程安全的, 你无需担心是否要做双重检查锁定。

    总之, 在保证序列化和线程安全的情况下,使用两行代码枚举单例模式是在 Java 5 以后的世界中创建 Singleton 的最佳方式。你仍然可以使用其他流行的方法, 如你觉得更好, 欢迎讨论。

    7. 编写 Java 程序时, 如何在 Java 中创建死锁并修复它?

    经典但核心Java面试问题之一。

    如果你没有参与过多线程并发 Java 应用程序的编码,你可能会失败。

    如何避免 Java 线程死锁?

    如何避免 Java 中的死锁?是 Java 面试的热门问题之一, 也是多线程的编程中的重口味之一, 主要在招高级程序员时容易被问到, 且有很多后续问题。尽管问题看起来非常基本, 但大多数 Java 开发人员一旦你开始深入, 就会陷入困境。

    面试问题总是以“什么是死锁?”开始

    当两个或多个线程在等待彼此释放所需的资源(锁定)并陷入无限等待即是死锁。它仅在多任务或多线程的情况下发生。

    如何检测 Java 中的死锁?

    虽然这可以有很多答案, 但我的版本是首先我会看看代码, 如果我看到一个嵌套的同步块,或从一个同步的方法调用其他同步方法, 或试图在不同的对象上获取锁, 如果开发人员不是非常小心,就很容易造成死锁。

    另一种方法是在运行应用程序时实际锁定时找到它, 尝试采取线程转储,在 Linux 中,你可以通过kill -3命令执行此操作, 这将打印应用程序日志文件中所有线程的状态, 并且你可以看到哪个线程被锁定在哪个线程对象上。

    你可以使用 fastthread.io 网站等工具分析该线程转储, 这些工具允许你上载线程转储并对其进行分析。

    另一种方法是使用 jConsole 或 VisualVM, 它将显示哪些线程被锁定以及哪些对象被锁定。

    如果你有兴趣了解故障排除工具和分析线程转储的过程, 我建议你看看 Uriah Levy 在多元视觉(PluraIsight)上《分析 Java 线程转储》课程。旨在详细了解 Java 线程转储, 并熟悉其他流行的高级故障排除工具。

    编写一个将导致死锁的Java程序?

    一旦你回答了前面的问题,他们可能会要求你编写代码,这将导致Java死锁。

    这是我的版本之一

    如果 method1() 和 method2() 都由两个或多个线程调用,则存在死锁的可能性, 因为如果线程 1 在执行 method1() 时在 Sting 对象上获取锁, 线程 2 在执行 method2() 时在 Integer 对象上获取锁, 等待彼此释放 Integer 和 String 上的锁以继续进行一步, 但这永远不会发生。

    此图精确演示了我们的程序, 其中一个线程在一个对象上持有锁, 并等待其他线程持有的其他对象锁。

    你可以看到, Thread1 需要 Thread2 持有的 Object2 上的锁,而 Thread2 希望获得 Thread1 持有的 Object1 上的锁。由于没有线程愿意放弃, 因此存在死锁, Java 程序被卡住。

    其理念是, 你应该知道使用常见并发模式的正确方法, 如果你不熟悉这些模式,那么 Jose Paumard 《应用于并发和多线程的常见 Java 模式》是学习的好起点。

    如何避免Java中的死锁?

    现在面试官来到最后一部分, 在我看来, 最重要的部分之一; 如何修复代码中的死锁?或如何避免Java中的死锁?

    如果你仔细查看了上面的代码,那么你可能已经发现死锁的真正原因不是多个线程, 而是它们请求锁的方式, 如果你提供有序访问, 则问题将得到解决。

    下面是我的修复版本,它通过避免循环等待,而避免死锁, 而不需要抢占这是需要死锁的四个条件之一。

    现在没有任何死锁,因为两种方法都按相同的顺序访问 Integer 和 String 类文本上的锁。因此,如果线程 A 在 Integer 对象上获取锁, 则线程 B 不会继续, 直到线程 A 释放 Integer 锁, 即使线程 B 持有 String 锁, 线程 A 也不会被阻止, 因为现在线程 B 不会期望线程 A 释放 Integer 锁以继续。(实用详尽的Java面试题大全,可以在Java知音公众号回复“面试题聚合”)

    8. 如果你的Serializable类包含一个不可序列化的成员,会发生什么?你是如何解决的?

    任何序列化该类的尝试都会因NotSerializableException而失败,但这可以通过在 Java中 为 static 设置瞬态(trancient)变量来轻松解决。

    Java 序列化相关的常见问题

    Java 序列化是一个重要概念, 但它很少用作持久性解决方案, 开发人员大多忽略了 Java 序列化 API。根据我的经验, Java 序列化在任何 Java核心内容面试中都是一个相当重要的话题, 在几乎所有的网面试中, 我都遇到过一两个 Java 序列化问题, 我看过一次面试, 在问几个关于序列化的问题之后候选人开始感到不自在, 因为缺乏这方面的经验。

    他们不知道如何在 Java 中序列化对象, 或者他们不熟悉任何 Java 示例来解释序列化, 忘记了诸如序列化在 Java 中如何工作, 什么是标记接口, 标记接口的目的是什么, 瞬态变量和可变变量之间的差异, 可序列化接口具有多少种方法, 在 Java 中,Serializable 和 Externalizable 有什么区别, 或者在引入注解之后, 为什么不用 @Serializable 注解或Serializalbe 接口。

     

    转载于:https://www.cnblogs.com/weirdo-lenovo/p/11418871.html

    展开全文
  • 文本分类入门(一)文本分类问题的定义 文本分类系列文章,从文本分类问题的定义开始,主要讲解文本分类系统的构成,主流的统计... 一个文本(以下基本不区分“文本”和“文档”两个词的含义)分类问题就是将一篇文档

    原博客地址:http://www.blogjava.net/zhenandaci/category/31868.html?Show=All

    文本分类入门(一)文本分类问题的定义

    文本分类系列文章,从文本分类问题的定义开始,主要讲解文本分类系统的构成,主流的统计学习方法以及较为优秀的SVM算法及其改进。

          一个文本(以下基本不区分“文本”和“文档”两个词的含义)分类问题就是将一篇文档归入预先定义的几个类别中的一个或几个,而文本的自动分类则是使用计算机程序来实现这样的分类。通俗点说,就好比你拿一篇文章,问计算机这文章要说的究竟是体育,经济还是教育,计算机答不上就打它的屁屁(……)。

    注意这个定义当中着重强调的两个事实。

    第一,用于分类所需要的类别体系是预先确定的。例如新浪新闻的分类体系,Yahoo!网页导航的分类层次。这种分类层次一旦确定,在相当长的时间内都是不可变的,或者即使要变更,也要付出相当大的代价(基本不亚于推倒并重建一个分类系统)。

    第二,一篇文档并没有严格规定只能被分配给一个类别。这与分类这个问题的主观性有关,例如找10个人判断一篇文章所陈述的主题究竟属于金融,银行还是财政政策领域,10个人可能会给出11个不同的答案(聪明的读者,您应该能看出来并没有11个答案,这只是一种修辞方法,笑),因此一篇文章很可能被分配到多个类别当中,只不过分给某些类别让人信服,而有些让人感觉模棱两可罢了(说的专业点,置信度不一样)。

    八股是一种写文章的格式,过去用于科举,现在用于科研,总之,和科学有点关系的文章就得八股,鉴于我正锻炼自己写论文的能力,所以按照标准的格式,陈述了文本分类问题的定义之后,我要说说它的应用范围。

    现在一说到文本分类,大部分人想当然的将这个问题简化为判断一篇文章说的是什么,这只是文本分类的一小部分应用,我们可以称之为“依据主题的分类”。实际上,文本分类还可以用于判断文章的写作风格,作者态度(积极?消极?),甚至判断作者真伪(例如看看《红楼梦》最后二十回到底是不是曹雪芹写的)。总而言之,凡是与文本有关,与分类有关,不管从什么角度出发,依据的是何特征,都可以叫做文本分类。

    当然,目前真正大量使用文本分类技术的,仍是依据文章主题的分类,而据此构建最多的系统,当属搜索引擎。内里的原因当然不言自明,我只是想给大家提个醒,文本分类还不完全等同于网页分类。网页所包含的信息远比含于其中的文字(文本)信息多得多,对一个网页的分类,除了考虑文本内容的分类以外,链入链出的链接信息,页面文件本身的元数据,甚至是包含此网页的网站结构和主题,都能给分类提供莫大的帮助(比如新浪体育专栏里的网页毫无疑问都是关于体育的),因此说文本分类实际上是网页分类的一个子集也毫不为过。当然,纯粹的文本分类系统与网页分类也不是一点区别都没有。文本分类有个重要前提:即只能根据文章的文字内容进行分类,而不应借助诸如文件的编码格式,文章作者,发布日期等信息。而这些信息对网页来说常常是可用的,有时起到的作用还很巨大!因此纯粹的文本分类系统要想达到相当的分类效果,必须在本身的理论基础和技术含量上下功夫。

    除了搜索引擎,诸如数字图书馆,档案管理等等要和海量文字信息打交道的系统,都用得上文本分类。另外,我的硕士论文也用得上(笑)。

    下一章和大家侃侃与文本分类有关的具体方法概览,有事您说话。

    文本分类入门(二)文本分类的方法

    文本分类问题与其它分类问题没有本质上的区别,其方法可以归结为根据待分类数据的某些特征来进行匹配,当然完全的匹配是不太可能的,因此必须(根据某种评价标准)选择最优的匹配结果,从而完成分类。

    因此核心的问题便转化为用哪些特征表示一个文本才能保证有效和快速的分类(注意这两方面的需求往往是互相矛盾的)。因此自有文本分类系统的那天起,就一直是对特征的不同选择主导着方法派别的不同。

    最早的词匹配法仅仅根据文档中是否出现了与类名相同的词(顶多再加入同义词的处理)来判断文档是否属于某个类别。很显然,这种过于简单的方法无法带来良好的分类效果。

    后来兴起过一段时间的知识工程的方法则借助于专业人员的帮助,为每个类别定义大量的推理规则,如果一篇文档能满足这些推理规则,则可以判定属于该类别。这里与特定规则的匹配程度成为了文本的特征。由于在系统中加入了人为判断的因素,准确度比词匹配法大为提高。但这种方法的缺点仍然明显,例如分类的质量严重依赖于这些规则的好坏,也就是依赖于制定规则的“人”的好坏;再比如制定规则的人都是专家级别,人力成本大幅上升常常令人难以承受;而知识工程最致命的弱点是完全不具备可推广性,一个针对金融领域构建的分类系统,如果要扩充到医疗或社会保险等相关领域,则除了完全推倒重来以外没有其他办法,常常造成巨大的知识和资金浪费。

    后来人们意识到,究竟依据什么特征来判断文本应当隶属的类别这个问题,就连人类自己都不太回答得清楚,有太多所谓“只可意会,不能言传”的东西在里面。人类的判断大多依据经验以及直觉,因此自然而然的会有人想到何让机器像人类一样自己来通过对大量同类文档的观察来自己总结经验,作为今后分类的依据。

    这便是统计学习方法的基本思想(也有人把这一大类方法称为机器学习,两种叫法只是涵盖范围大小有些区别,均无不妥)。

    统计学习方法需要一批由人工进行了准确分类的文档作为学习的材料(称为训练集,注意由人分类一批文档比从这些文档中总结出准确的规则成本要低得多),计算机从这些文档重挖掘出一些能够有效分类的规则,这个过程被形象的称为训练,而总结出的规则集合常常被称为分类器。训练完成之后,需要对计算机从来没有见过的文档进行分类时,便使用这些分类器来进行。

    现如今,统计学习方法已经成为了文本分类领域绝对的主流。主要的原因在于其中的很多技术拥有坚实的理论基础(相比之下,知识工程方法中专家的主观因素居多),存在明确的评价标准,以及实际表现良好。

    下一章就深入统计学习方法,看看这种方法的前提,相关理论和具体实现。

    文本分类入门(三)统计学习方法

    前文说到使用统计学习方法进行文本分类就是让计算机自己来观察由人提供的训练文档集,自己总结出用于判别文档类别的规则和依据。理想的结果当然是让计算机在理解文章内容的基础上进行这样的分类,然而遗憾的是,我们所说的“理解”往往指的是文章的语义甚至是语用信息,这一类信息极其复杂,抽象,而且存在上下文相关性,对这类信息如何在计算机中表示都是尚未解决的问题(往大里说,这是一个“知识表示”的问题,完全可以另写一系列文章来说了),更不要说让计算机来理解。

    利用计算机来解决问题的标准思路应该是:为这种问题寻找一种计算机可以理解的表示方法,或曰建立一个模型(一个文档表示模型);然后基于这个模型,选择各方面满足要求的算法来解决。用谭浩强的话说,程序,就是数据+算法。(啥?你不知道谭浩强是谁?上过学么?学过C么?这捣什么乱?)

    既然文本的语义和语用信息很难转换成计算机能够理解的表示形式,接下来顺理成章的,人们开始用文章中所包含的较低级别的词汇信息来表示文档,一试之下,效果居然还不错。

    统计学习方法进行文本分类(以下就简称为“统计学习方法”,虽然这个方法也可以应用到除文本分类以外的多个领域)的一个重要前提由此产生,那就是认为:文档的内容与其中所包含的词有着必然的联系,同一类文档之间总存在多个共同的词,而不同类的文档所包含的词之间差异很大[1]。

    进一步的,不光是包含哪些词很重要,这些词出现的次数对分类也很重要。

    这一前提使得向量模型(俗称的VSM,向量空间模型)成了适合文本分类问题的文档表示模型。在这种模型中,一篇文章被看作特征项集合来看,利用加权特征项构成向量进行文本表示,利用词频信息对文本特征进行加权。它实现起来比较简单,并且分类准确度也高,能够满足一般应用的要求。[5]

    而实际上,文本是一种信息载体,其所携带的信息由几部分组成:如组成元素本身的信息(词的信息)、组成元素之间顺序关系带来的信息以及上下文信息(更严格的说,还包括阅读者本身的背景和理解)[12]。

    而VSM这种文档表示模型,基本上完全忽略了除词的信息以外所有的部分,这使得它能表达的信息量存在上限[12],也直接导致了基于这种模型构建的文本分类系统(虽然这是目前绝对主流的做法),几乎永远也不可能达到人类的分类能力。后面我们也会谈到,相比于所谓的分类算法,对特征的选择,也就是使用哪些特征来代表一篇文档,往往更能影响分类的效果。

    对于扩充文档表示模型所包含的信息量,人们也做过有益的尝试,例如被称为LSI(Latent Semantic Index潜在语义索引)的方法,就被实验证明保留了一定的语义信息(之所以说被实验证明了,是因为人们还无法在形式上严格地证明它确实保留了语义信息,而且这种语义信息并非以人可以理解的方式被保留下来),此为后话。

    前文说到(就不能不用这种老旧的说法?换换新的,比如Previously on "Prison Break",噢,不对,是Previously on Text Categorizaiton……)统计学习方法其实就是一个两阶段的解决方案,(1)训练阶段,由计算机来总结分类的规则;(2)分类阶段,给计算机一些它从来没见过的文档,让它分类(分不对就打屁屁)。

    下一章就专门说说训练阶段的二三事。

    文本分类入门(四)训练Part 1

    训练,顾名思义,就是training(汗,这解释),简单的说就是让计算机从给定的一堆文档中自己学习分类的规则(如果学不对的话,还要,打屁屁?)。

    开始训练之前,再多说几句关于VSM这种文档表示模型的话。

    举个例子,假设说把我正在写的“文本分类入门”系列文章的第二篇抽出来当作一个需要分类的文本,则可以用如下的向量来表示这个文本,以便于计算机理解和处理。

    w2=(文本,5,统计学习,4,模型,0,……)

    这个向量表示在w2所代表的文本中,“文本”这个词出现了5次(这个信息就叫做词频),“统计学习”这个词出现了4次,而“模型”这个词出现了0次,依此类推,后面的词没有列出。

    而系列的第三篇文章可以表示为

    w3=(文本,9,统计学习,4,模型,10,……)

    其含义同上。如果还有更多的文档需要表示,我们都可以使用这种方式。

    只通过观察w2和w3我们就可以看出实际上有更方便的表示文本向量的方法,那就是把所有文档都要用到的词从向量中抽离出来,形成共用的数据结构(也可以仍是向量的形式),这个数据结构就叫做词典,或者特征项集合。

    例如我们的问题就可以抽离出一个词典向量

    D=(文本,统计学习,模型,……)

    所有的文档向量均可在参考这个词典向量的基础上简化成诸如

    w2=(5,4,0,……)

    w3=(9,4,10,……)

    的形式,其含义没有改变。

         5,4,10这些数字分别叫做各个词在某个文档中的权重,实际上单单使用词频作为权重并不多见,也不十分有用,更常见的做法是使用地球人都知道的TF/IDF值作为权重。(关于TF/IDF的详细解释,Google的吴军研究员写了非常通俗易懂的文章,发布于Google黑板报,链接地址是http://googlechinablog.com/2006/06/blog-post_27.html,有兴趣不妨一读)TF/IDF作为一个词对所属文档主题的贡献程度来说,是非常重要的度量标准,也是将文档转化为向量表示过程中的重要一环。

          在这个转化过程中隐含了一个很严重的问题。注意看看词典向量D,你觉得它会有多大?或者说,你觉得它会包含多少个词?

    假设我们的系统仅仅处理汉语文本,如果不做任何处理,这个词典向量会包含汉语中所有的词汇,我手头有一本商务印书馆出版的《现代汉语词典》第5版(2005年5月出版),其中收录了65,000个词,D大致也应该有这么大,也就是说,D是一个65,000维的向量,而所有的文本向量w2,w3,wn也全都是65,000维的!(这是文本分类这一问题本身的一个特性,称为“高维性”)想一想,大部分文章仅仅千余字,包含的词至多几百,为了表示这样一个文本,却要使用65,000维的向量,这是对存储资源和计算能力多大的浪费呀!(这又是文本分类问题的另一个特性,称为“向量稀疏性”,后面会专门有一章讨论这些特性,并指出解决的方法,至少是努力的方向)

    中国是一个人口众多而资源稀少的国家,我们不提倡一味发展粗放型的经济,我们所需要的可持续发展是指资源消耗少,生产效率高,环境污染少……跑题了……

    这么多的词汇当中,诸如“体育”,“经济”,“金融”,“处理器”等等,都是极其能够代表文章主题的,但另外很多词,像“我们”,“在”,“事情”,“里面”等等,在任何主题的文章中都很常见,根本无法指望通过这些词来对文本类别的归属作个判断。这一事实首先引发了对文本进行被称为“去停止词”的预处理步骤(对英文来说还有词根还原,但这些与训练阶段无关,不赘述,会在以后讲述中英文文本分类方法区别的章节中讨论),与此同时,我们也从词典向量D中把这些词去掉。

           但经过停止词处理后剩下的词汇仍然太多,使用了太多的特征来表示文本,就是常说的特征集过大,不仅耗费计算资源,也因为会引起“过拟合问题”而影响分类效果[22]。

    这个问题是训练阶段要解决的第一个问题,即如何选取那些最具代表性的词汇(更严格的说法应该是,那些最具代表性的特征,为了便于理解,可以把特征暂时当成词汇来想象)。对这个问题的解决,有人叫它特征提取,也有人叫它降维。

    特征提取实际上有两大类方法。一类称为特征选择(Term Selection),指的是从原有的特征(那许多有用无用混在一起的词汇)中提取出少量的,具有代表性的特征,但特征的类型没有变化(原来是一堆词,特征提取后仍是一堆词,数量大大减少了而已)。另一类称为特征抽取(Term Extraction)的方法则有所不同,它从原有的特征中重构出新的特征(原来是一堆词,重构后变成了别的,例如LSI将其转为矩阵,文档生成模型将其转化为某个概率分布的一些参数),新的特征具有更强的代表性,并耗费更少的计算资源。(特征提取的各种算法会有专门章节讨论)

    训练阶段,计算机根据训练集中的文档,使用特征提取找出最具代表性的词典向量(仍然是不太严格的说法),然后参照这个词典向量把这些训练集文档转化为向量表示,之后的所有运算便都使用这些向量进行,不再理会原始的文本形式的文档了(换言之,失宠了,后后)。

    下一章继续训练,咱们之间还没完。(怎么听着像要找人寻仇似的)

    文本分类入门(五)训练Part 2

    将样本数据成功转化为向量表示之后,计算机才算开始真正意义上的“学习”过程。

    再重复一次,所谓样本,也叫训练数据,是由人工进行分类处理过的文档集合,计算机认为这些数据的分类是绝对正确的,可以信赖的(但某些方法也有针对训练数据可能有错误而应对的措施)。接下来的一步便是由计算机来观察这些训练数据的特点,来猜测一个可能的分类规则(这个分类规则也可以叫做分类器,在机器学习的理论著作中也叫做一个“假设”,因为毕竟是对真实分类规则的一个猜测),一旦这个分类满足一些条件,我们就认为这个分类规则大致正确并且足够好了,便成为训练阶段的最终产品——分类器!再遇到新的,计算机没有见过的文档时,便使用这个分类器来判断新文档的类别。

    举一个现实中的例子,人们评价一辆车是否是“好车”的时候,可以看作一个分类问题。我们也可以把一辆车的所有特征提取出来转化为向量形式。在这个问题中词典向量可以为:

    D=(价格,最高时速,外观得分,性价比,稀有程度)

    则一辆保时捷的向量表示就可以写成

    vp=(200万,320,9.5,3,9)

    而一辆丰田花冠则可以写成

    vt=(15万,220,6.0,8,3)

    找不同的人来评价哪辆车算好车,很可能会得出不同的结论。务实的人认为性价比才是评判的指标,他会认为丰田花冠是好车而保时捷不是;喜欢奢华的有钱人可能以稀有程度来评判,得出相反的结论;喜欢综合考量的人很可能把各项指标都加权考虑之后才下结论。

    可见,对同一个分类问题,用同样的表示形式(同样的文档模型),但因为关注数据不同方面的特性而可能得到不同的结论。这种对文档数据不同方面侧重的不同导致了原理和实现方式都不尽相同的多种方法,每种方法也都对文本分类这个问题本身作了一些有利于自身的假设和简化,这些假设又接下来影响着依据这些方法而得到的分类器最终的表现,可谓环环相连,丝丝入扣,冥冥之中自有天意呀(这都什么词儿……)。

             比较常见,家喻户晓,常年被评为国家免检产品(?!)的分类算法有一大堆,什么决策树,Rocchio,朴素贝叶斯,神经网络,支持向量机,线性最小平方拟合,kNN,遗传算法,最大熵,Generalized Instance Set等等等等(这张单子还可以继续列下去)。在这里只挑几个最具代表性的算法侃一侃。

    Rocchio算法

    Rocchio算法应该算是人们思考文本分类问题时最先能想到,也最符合直觉的解决方法。基本的思路是把一个类别里的样本文档各项取个平均值(例如把所有“体育”类文档中词汇“篮球”出现的次数取个平均值,再把“裁判”取个平均值,依次做下去),可以得到一个新的向量,形象的称之为“质心”,质心就成了这个类别最具代表性的向量表示。再有新文档需要判断的时候,比较新文档和质心有多么相像(八股点说,判断他们之间的距离)就可以确定新文档属不属于这个类。稍微改进一点的Rocchio算法不尽考虑属于这个类别的文档(称为正样本),也考虑不属于这个类别的文档数据(称为负样本),计算出来的质心尽量靠近正样本同时尽量远离负样本。Rocchio算法做了两个很致命的假设,使得它的性能出奇的差。一是它认为一个类别的文档仅仅聚集在一个质心的周围,实际情况往往不是如此(这样的数据称为线性不可分的);二是它假设训练数据是绝对正确的,因为它没有任何定量衡量样本是否含有噪声的机制,因而也就对错误数据毫无抵抗力。

    不过Rocchio产生的分类器很直观,很容易被人类理解,算法也简单,还是有一定的利用价值的(做汉奸状),常常被用来做科研中比较不同算法优劣的基线系统(Base Line)。

    朴素贝叶斯算法(Naive Bayes)

    贝叶斯算法关注的是文档属于某类别概率。文档属于某个类别的概率等于文档中每个词属于该类别的概率的综合表达式。而每个词属于该类别的概率又在一定程度上可以用这个词在该类别训练文档中出现的次数(词频信息)来粗略估计,因而使得整个计算过程成为可行的。使用朴素贝叶斯算法时,在训练阶段的主要任务就是估计这些值。

          朴素贝叶斯算法的公式只有一个

    wps_clip_image-20922

    其中P(d| Ci)=P(w1|Ci) P(w2|Ci) …P(wi|Ci) P(w1|Ci) …P(wm|Ci) (式1)

          P(wi|Ci)就代表词汇wi属于类别Ci的概率。

    这其中就蕴含着朴素贝叶斯算法最大的两个缺陷。

    首先,P(d| Ci)之所以能展开成(式1)的连乘积形式,就是假设一篇文章中的各个词之间是彼此独立的,其中一个词的出现丝毫不受另一个词的影响(回忆一下概率论中变量彼此独立的概念就可以知道),但这显然不对,即使不是语言学专家的我们也知道,词语之间有明显的所谓“共现”关系,在不同主题的文章中,可能共现的次数或频率有变化,但彼此间绝对谈不上独立。

    其二,使用某个词在某个类别训练文档中出现的次数来估计P(wi|Ci)时,只在训练样本数量非常多的情况下才比较准确(考虑扔硬币的问题,得通过大量观察才能基本得出正反面出现的概率都是二分之一的结论,观察次数太少时很可能得到错误的答案),而需要大量样本的要求不仅给前期人工分类的工作带来更高要求(从而成本上升),在后期由计算机处理的时候也对存储和计算资源提出了更高的要求。

    kNN算法

          kNN算法则又有所不同,在kNN算法看来,训练样本就代表了类别的准确信息(因此此算法产生的分类器也叫做“基于实例”的分类器),而不管样本是使用什么特征表示的。其基本思想是在给定新文档后,计算新文档特征向量和训练文档集中各个文档的向量的相似度,得到K篇与该新文档距离最近最相似的文档,根据这K篇文档所属的类别判定新文档所属的类别(注意这也意味着kNN算法根本没有真正意义上的“训练”阶段)。这种判断方法很好的克服了Rocchio算法中无法处理线性不可分问题的缺陷,也很适用于分类标准随时会产生变化的需求(只要删除旧训练文档,添加新训练文档,就改变了分类的准则)。

           kNN唯一的也可以说最致命的缺点就是判断一篇新文档的类别时,需要把它与现存的所有训练文档全都比较一遍,这个计算代价并不是每个系统都能够承受的(比如我将要构建的一个文本分类系统,上万个类,每个类即便只有20个训练样本,为了判断一个新文档的类别,也要做20万次的向量比较!)。一些基于kNN的改良方法比如Generalized Instance Set就在试图解决这个问题。

    下一节继续讲和训练阶段有关的话题,包括概述已知性能最好的SVM算法。明儿见!(北京人儿,呵呵)

    文本分类入门(六)训练Part 3

    SVM算法

    支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本、非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合等其他机器学习问题中[10]。

    支持向量机方法是建立在统计学习理论的VC 维理论和结构风险最小原理基础上的,根据有限的样本信息在模型的复杂性(即对特定训练样本的学习精度,Accuracy)和学习能力(即无错误地识别任意样本的能力)之间寻求最佳折衷,以期获得最好的推广能力[14](或称泛化能力)。

          SVM 方法有很坚实的理论基础,SVM 训练的本质是解决一个二次规划问题(Quadruple Programming,指目标函数为二次函数,约束条件为线性约束的最优化问题),得到的是全局最优解,这使它有着其他统计学习技术难以比拟的优越性。SVM 分类器的文本分类效果很好,是最好的分类器之一。同时使用核函数将原始的样本空间向高维空间进行变换,能够解决原始样本线性不可分的问题。其缺点是核函数的选择缺乏指导,难以针对具体问题选择最佳的核函数;另外SVM 训练速度极大地受到训练集规模的影响,计算开销比较大,针对SVM 的训练速度问题,研究者提出了很多改进方法,包括Chunking 方法、Osuna 算法、SMO 算法和交互SVM 等等[14]。

          SVM分类器的优点在于通用性较好,且分类精度高、分类速度快、分类速度与训练样本个数无关,在查准和查全率方面都优于kNN及朴素贝叶斯方法[8]。

    与其它算法相比,SVM算法的理论基础较为复杂,但应用前景很广,我打算专门写一个系列的文章,详细的讨论SVM算法,stay tuned!

    介绍过了几个很具代表性的算法之后,不妨用国内外的几组实验数据来比较一下他们的优劣。

    在中文语料上的试验,文献[6]使用了复旦大学自然语言处理实验室提供的基准语料对当前的基于词向量空间文本模型的几种分类算法进行了测试,这一基准语料分为20个类别,共有9804篇训练文档,以及9833篇测试文档。在经过统一的分词处理、噪声词消除等预处理之后,各个分类方法的性能指标如下。

    wps_clip_image-23468

    其中F1 测度是一种综合了查准率与召回率的指标,只有当两个值均比较大的时候,对应的F1测度才比较大,因此是比单一的查准或召回率更加具有代表性的指标。

    由比较结果不难看出,SVM和kNN明显优于朴素贝叶斯方法(但他们也都优于Rocchio方法,这种方法已经很少再参加评测了)。

    在英文语料上,路透社的Reuters-21578 “ModApt´e”是比较常用的测试集,在这个测试集上的测试由很多人做过,Sebastiani在文献[23]中做了总结,相关算法的结果摘录如下:

    分类算法在Reuters-21578 “ModApt´e”上的F1测度:

          Rocchio  0.776

    朴素贝叶斯  0.795

          kNN  0.823

          SVM  0.864

    仅以F1测度来看,kNN是相当接近SVM算法的,但F1只反映了分类效果(即分类分得准不准),而没有考虑性能(即分类分得快不快)。综合而论,SVM是效果和性能均不错的算法。

    前面也提到过,训练阶段的最终产物就是分类器,分类阶段仅仅是使用这些分类器对新来的文档分类而已,没有过多可说的东西。

    下一章节是对到目前为止出现过的概念的列表及简单的解释,也会引入一些后面会用到的概念。再之后会谈及分类问题本身的分类(绕口),中英文分类问题的相似与不同之处以及几种特征提取算法的概述和比较,路漫漫……

    文本分类入门(七)相关概念总结

    学习方法:使用样例(或称样本,训练集)来合成计算机程序的过程称为学习方法[22]。

    监督学习:学习过程中使用的样例是由输入/输出对给出时,称为监督学习[22]。最典型的监督学习例子就是文本分类问题,训练集是一些已经明确分好了类别文档组成,文档就是输入,对应的类别就是输出。

    非监督学习:学习过程中使用的样例不包含输入/输出对,学习的任务是理解数据产生的过程 [22]。典型的非监督学习例子是聚类,类别的数量,名称,事先全都没有确定,由计算机自己观察样例来总结得出。

          TSR(Term Space Reduction):特征空间的压缩,即降维,也可以叫做特征提取。包括特征选择和特征抽取两大类方法。

    分类状态得分(CSV,Categorization Status Value):用于描述将文档归于某个类别下有多大的可信度。

    准确率(Precision):在所有被判断为正确的文档中,有多大比例是确实正确的。

    召回率(Recall):在所有确实正确的文档中,有多大比例被我们判为正确。

    假设:计算机对训练集背后的真实模型(真实的分类规则)的猜测称为假设。可以把真实的分类规则想像为一个目标函数,我们的假设则是另一个函数,假设函数在所有的训练数据上都得出与真实函数相同(或足够接近)的结果。

    泛化性:一个假设能够正确分类训练集之外数据(即新的,未知的数据)的能力称为该假设的泛化性[22]。

    一致假设:一个假设能够对所有训练数据正确分类,则称这个假设是一致的[22]。

    过拟合:为了得到一致假设而使假设变得过度复杂称为过拟合[22]。想像某种学习算法产生了一个过拟合的分类器,这个分类器能够百分之百的正确分类样本数据(即再拿样本中的文档来给它,它绝对不会分错),但也就为了能够对样本完全正确的分类,使得它的构造如此精细复杂,规则如此严格,以至于任何与样本数据稍有不同的文档它全都认为不属于这个类别!

    超平面(Hyper Plane):n维空间中的线性函数唯一确定了一个超平面。一些较直观的例子,在二维空间中,一条直线就是一个超平面;在三维空间中,一个平面就是一个超平面。

    线性可分和不可分:如果存在一个超平面能够正确分类训练数据,并且这个程序保证收敛,这种情况称为线形可分。如果这样的超平面不存在,则称数据是线性不可分的[22]。

    正样本和负样本:对某个类别来说,属于这个类别的样本文档称为正样本;不属于这个类别的文档称为负样本。

    规划:对于目标函数,等式或不等式约束都是线性函数的问题称为线性规划问题。对于目标函数是二次的,而约束都是线性函数的最优化问题称为二次规划问题[22]。

    对偶问题:

    给定一个带约束的优化问题

    目标函数:min f(x)

    约束条件:C(x) ≥0

    可以通过拉格朗日乘子构造拉格朗日函数

          L(x,λ)=f(x)- λTC(x)

    令g(λ)= f(x)- λTC(x)

    则原问题可以转化为

    目标函数:max g(λ)

    约束条件:λ≥0

    这个新的优化问题就称为原问题的对偶问题(两个问题在取得最优解时达到的条件相同)。

    文本分类入门(八)中英文文本分类的异同

    从文本分类系统的处理流程来看,无论待分类的文本是中文还是英文,在训练阶段之前都要经过一个预处理的步骤,去除无用的信息,减少后续步骤的复杂度和计算负担。

    对中文文本来说,首先要经历一个分词的过程,就是把连续的文字流切分成一个一个单独的词汇(因为词汇将作为训练阶段“特征”的最基本单位),例如原文是“中华人民共和国今天成立了”的文本就要被切分成“中华/人民/共和国/今天/成立/了”这样的形式。而对英文来说,没有这个步骤(更严格的说,并不是没有这个步骤,而是英文只需要通过空格和标点便很容易将一个一个独立的词从原文中区分出来)。中文分词的效果对文本分类系统的表现影响很大,因为在后面的流程中,全都使用预处理之后的文本信息,不再参考原始文本,因此分词的效果不好,等同于引入了错误的训练数据。分词本身也是一个值得大书特书的问题,目前比较常用的方法有词典法,隐马尔科夫模型和新兴的CRF方法。

    预处理中在分词之后的“去停止词”一步对两者来说是相同的,都是要把语言中一些表意能力很差的辅助性文字从原始文本中去除,对中文文本来说,类似“我们”,“在”,“了”,“的”这样的词汇都会被去除,英文中的“ an”,“in”,“the”等也一样。这一步骤会参照一个被称为“停止词表”的数据(里面记录了应该被去除的词,有可能是以文件形式存储在硬盘上,也有可能是以数据结构形式放在内存中)来进行。

    对中文文本来说,到此就已初审合格,可以参加训练了(笑)。而英文文本还有进一步简化和压缩的空间。我们都知道,英文中同一个词有所谓词形的变化(相对的,词义本身却并没有变),例如名词有单复数的变化,动词有时态的变化,形容词有比较级的变化等等,还包括这些变化形式的某种组合。而正因为词义本身没有变化,仅仅词形不同的词就不应该作为独立的词来存储和和参与分类计算。去除这些词形不同,但词义相同的词,仅保留一个副本的步骤就称为“词根还原”,例如在一篇英文文档中,经过词根还原后,“computer”,“compute”,“computing”,“computational”这些词全都被处理成“compute”(大小写转换也在这一步完成,当然,还要记下这些词的数目作为compute的词频信息)。

    经过预处理步骤之后,原始文档转换成了非常节省资源,也便于计算的形式,后面的训练阶段大同小异(仅仅抽取出的特征不同而已,毕竟,一个是中文词汇的集合,一个是英文词汇的集合嘛)。

    下一章节侃侃分类问题本身的分类。

    文本分类入门(九)文本分类问题的分类

    开始之前首先说说分类体系。回忆一下,分类体系是指事先确定的类别的层次结构以及文档与这些类别间的关系。

    其中包含着两方面的内容:

    一,类别之间的关系。一般来说类别之间的关系都是可以表示成树形结构,这意味着一个类有多个子类,而一个子类唯一的属于一个父类。这种类别体系很常用,却并不代表它在现实世界中也是符合常识的,举个例子,“临床心理学”这个类别应该即属于“临床医学”的范畴,同时也属于“心理学”,但在分类系统中却不便于使用这样的结构。想象一下,这相当于类别的层次结构是一个有环图,无论遍历还是今后类别的合并,比较,都会带来无数的麻烦。

    二,文档与类别间的关系。一般来说,在分类系统中,我们倾向于让一篇文档唯一的属于一个类别(更严格的说,是在同一层次中仅属于一个类别,因为属于一个类别的时候,显然也属于这个类别的父类别),这使得我们只适用一个标签就可以标记这个文档的类别,而一旦允许文档属于多个类别,标签的数目便成为大小不定的变量,难于设计成高效的数据结构。这种“属于多个”类的想法更糟的地方在于文档类别表示的语义方面,试想,如果姚明给灾区捐款的新闻即属于灾区新闻,也属于体育新闻的话(这在现实中倒确实是合情合理的),当用户使用这个系统来查找文档,指定的条件是要所有“属于灾区新闻但不属于体育新闻的新闻”(有点拗口,不过正好练嘴皮子啦,笑)的时候,这篇姚明的报道是否应该包含在查询结果中呢?这是一个矛盾的问题。

    文本分类问题牵涉到如此多的主题,本身又含有如此多的属性,因此可以从多个角度对文本分类问题本身进行一下分类。

    分类系统使用何种分类算法是分类系统的核心属性。如果一个分类算法在一次分类判断时,仅仅输出一个真假值用来表示待分类的文档是否属于当前类别的话,这样的系统就可以叫做基于二元分类器的分类系统。有些分类算法天然就是独立二元的,例如支持向量机,它只能回答这个文档是或不是这个类别的。这种分类算法也常常被称为“硬分类”的算法(Hard Categorization)。而有的算法在一次判断后就可以输出文档属于多个类别的得分(假设说,得分越大,则说明越有可能属于这个类别),这类算法称为“排序分类”的算法(Ranking Categorization),也叫做m元分类算法。kNN就是典型的m元分类算法(因为kNN会找出与待分类文档最相近的训练样本,并记录下这些样本所属的分类)。

    文本分类入门(十)特征选择算法之开方检验

    前文提到过,除了分类算法以外,为分类文本作处理的特征提取算法也对最终效果有巨大影响,而特征提取算法又分为特征选择和特征抽取两大类,其中特征选择算法有互信息,文档频率,信息增益,开方检验等等十数种,这次先介绍特征选择算法中效果比较好的开方检验方法。

    大家应该还记得,开方检验其实是数理统计中一种常用的检验两个变量独立性的方法。(什么?你是文史类专业的学生,没有学过数理统计?那你做什么文本分类?在这捣什么乱?)

    开方检验最基本的思想就是通过观察实际值与理论值的偏差来确定理论的正确与否。具体做的时候常常先假设两个变量确实是独立的(行话就叫做“原假设”),然后观察实际值(也可以叫做观察值)与理论值(这个理论值是指“如果两者确实独立”的情况下应该有的值)的偏差程度,如果偏差足够小,我们就认为误差是很自然的样本误差,是测量手段不够精确导致或者偶然发生的,两者确确实实是独立的,此时就接受原假设;如果偏差大到一定程度,使得这样的误差不太可能是偶然产生或者测量不精确所致,我们就认为两者实际上是相关的,即否定原假设,而接受备择假设。

    那么用什么来衡量偏差程度呢?假设理论值为E(这也是数学期望的符号哦),实际值为x,如果仅仅使用所有样本的观察值与理论值的差值x-E之和

    wps_clip_image-23014

    来衡量,单个的观察值还好说,当有多个观察值x1,x2,x3的时候,很可能x1-E,x2-E,x3-E的值有正有负,因而互相抵消,使得最终的结果看上好像偏差为0,但实际上每个都有偏差,而且都还不小!此时很直接的想法便是使用方差代替均值,这样就解决了正负抵消的问题,即使用

    wps_clip_image-13177

    这时又引来了新的问题,对于500的均值来说,相差5其实是很小的(相差1%),而对20的均值来说,5相当于25%的差异,这是使用方差也无法体现的。因此应该考虑改进上面的式子,让均值的大小不影响我们对差异程度的判断

    wps_clip_image-28843式(1)

    上面这个式子已经相当好了。实际上这个式子就是开方检验使用的差值衡量公式。当提供了数个样本的观察值x1,x2,……xi ,……xn之后,代入到式(1)中就可以求得开方值,用这个值与事先设定的阈值比较,如果大于阈值(即偏差很大),就认为原假设不成立,反之则认为原假设成立。

    在文本分类问题的特征选择阶段,我们主要关心一个词t(一个随机变量)与一个类别c(另一个随机变量)之间是否相互独立?如果独立,就可以说词t对类别c完全没有表征作用,即我们根本无法根据t出现与否来判断一篇文档是否属于c这个分类。但与最普通的开方检验不同,我们不需要设定阈值,因为很难说词t和类别c关联到什么程度才算是有表征作用,我们只想借用这个方法来选出一些最最相关的即可。

    此时我们仍然需要明白对特征选择来说原假设是什么,因为计算出的开方值越大,说明对原假设的偏离越大,我们越倾向于认为原假设的反面情况是正确的。我们能不能把原假设定为“词t与类别c相关“?原则上说当然可以,这也是一个健全的民主主义社会赋予每个公民的权利(笑),但此时你会发现根本不知道此时的理论值该是多少!你会把自己绕进死胡同。所以我们一般都使用”词t与类别c不相关“来做原假设。选择的过程也变成了为每个词计算它与类别c的开方值,从大到小排个序(此时开方值越大越相关),取前k个就可以(k值可以根据自己的需要选,这也是一个健全的民主主义社会赋予每个公民的权利)。

    好,原理有了,该来个例子说说到底怎么算了。

    比如说现在有N篇文档,其中有M篇是关于体育的,我们想考察一个词“篮球”与类别“体育”之间的相关性(任谁都看得出来两者很相关,但很遗憾,我们是智慧生物,计算机不是,它一点也看不出来,想让它认识到这一点,只能让它算算看)。我们有四个观察值可以使用:

         1. 包含“篮球”且属于“体育”类别的文档数,命名为A

         2. 包含“篮球”但不属于“体育”类别的文档数,命名为B

         3. 不包含“篮球”但却属于“体育”类别的文档数,命名为C

         4.  既不包含“篮球”也不属于“体育”类别的文档数,命名为D

    如果有些特点你没看出来,那我说一说,首先,A+B+C+D=N(这,这不废话嘛)。其次,A+C的意思其实就是说“属于体育类的文章数量”,因此,它就等于M,同时,B+D就等于N-M。

    好,那么理论值是什么呢?以包含“篮球”且属于“体育”类别的文档数为例。如果原假设是成立的,即“篮球”和体育类文章没什么关联性,那么在所有的文章中,“篮球”这个词都应该是等概率出现,而不管文章是不是体育类的。这个概率具体是多少,我们并不知道,但他应该体现在观察结果中(就好比抛硬币的概率是二分之一,可以通过观察多次抛的结果来大致确定),因此我们可以说这个概率接近

    wps_clip_image-18245

    (因为A+B是包含“篮球”的文章数,除以总文档数就是“篮球”出现的概率,当然,这里认为在一篇文章中出现即可,而不管出现了几次)而属于体育类的文章数为A+C,在这些个文档中,应该有

    wps_clip_image-5395

    篇包含“篮球”这个词(数量乘以概率嘛)。

    但实际有多少呢?考考你(读者:切,当然是A啦,表格里写着嘛……)。

    此时对这种情况的差值就得出了(套用式(1)的公式),应该是

    wps_clip_image-582

    同样,我们还可以计算剩下三种情况的差值D12,D21,D22,聪明的读者一定能自己算出来(读者:切,明明是自己懒得写了……)。有了所有观察值的差值,就可以计算“篮球”与“体育”类文章的开方值

    wps_clip_image-5259

    把D11,D12,D21,D22的值分别代入并化简,可以得到

    词t与类别c的开方值更一般的形式可以写成

    wps_clip_image-30483  式(2)

    接下来我们就可以计算其他词如“排球”,“产品”,“银行”等等与体育类别的开方值,然后根据大小来排序,选择我们需要的最大的数个词汇作为特征项就可以了。

    实际上式(2)还可以进一步化简,注意如果给定了一个文档集合(例如我们的训练集)和一个类别,则N,M,N-M(即A+C和B+D)对同一类别文档中的所有词来说都是一样的,而我们只关心一堆词对某个类别的开方值的大小顺序,而并不关心具体的值,因此把它们从式(2)中去掉是完全可以的,故实际计算的时候我们都使用

    wps_clip_image-20127  式(3)

    好啦,并不高深对不对?

    针对英文纯文本的实验结果表明:作为特征选择方法时,开方检验和信息增益的效果最佳(相同的分类算法,使用不同的特征选择算法来得到比较结果);文档频率方法的性能同前两者大体相当,术语强度方法性能一般;互信息方法的性能最差(文献[17])。

    但开方检验也并非就十全十美了。回头想想A和B的值是怎么得出来的,它统计文档中是否出现词t,却不管t在该文档中出现了几次,这会使得他对低频词有所偏袒(因为它夸大了低频词的作用)。甚至会出现有些情况,一个词在一类文章的每篇文档中都只出现了一次,其开方值却大过了在该类文章99%的文档中出现了10次的词,其实后面的词才是更具代表性的,但只因为它出现的文档数比前面的词少了“1”,特征选择的时候就可能筛掉后面的词而保留了前者。这就是开方检验著名的“低频词缺陷“。因此开方检验也经常同其他因素如词频综合考虑来扬长避短。

    好啦,关于开方检验先说这么多,有机会还将介绍其他的特征选择算法。

    附:给精通统计学的同学多说几句,式(1)实际上是对连续型的随机变量的差值计算公式,而我们这里统计的“文档数量“显然是离散的数值(全是整数),因此真正在统计学中计算的时候,是有修正过程的,但这种修正仍然是只影响具体的开方值,而不影响大小的顺序,故文本分类中不做这种修正。

    文本分类入门(十一)特征选择方法之信息增益

    从以上讨论中可以看出,信息增益也是考虑了特征出现和不出现两种情况,与开方检验一样,是比较全面的,因而效果不错。但信息增益最大的问题还在于它只能考察特征对整个系统的贡献,而不能具体到某个类别上,这就使得它只适合用来做所谓“全局”的特征选择(指所有的类都使用相同的特征集合),而无法做“本地”的特征选择(每个类别有自己的特征集合,因为有的词,对这个类别很有区分度,对另一个类别则无足轻重)。

    看看,导出的过程其实很简单,没有什么神秘的对不对。可有的学术论文里就喜欢把这种本来很直白的东西写得很晦涩,仿佛只有读者看不懂才是作者的真正成功。

    咱们是新一代的学者,咱们没有知识不怕被别人看出来,咱们有知识也不怕教给别人。所以咱都把事情说简单点,说明白点,大家好,才是真的好。

    文本分类入门(十一)特征选择方法之信息增益

    前文提到过,除了开方检验(CHI)以外,信息增益(IG,Information Gain)也是很有效的特征选择方法。但凡是特征选择,总是在将特征的重要程度量化之后再进行选择,而如何量化特征的重要性,就成了各种方法间最大的不同。开方检验中使用特征与类别间的关联性来进行这个量化,关联性越强,特征得分越高,该特征越应该被保留。

    在信息增益中,重要性的衡量标准就是看特征能够为分类系统带来多少信息,带来的信息越多,该特征越重要。

    因此先回忆一下信息论中有关信息量(就是“熵”)的定义。说有这么一个变量X,它可能的取值有n多种,分别是x1,x2,……,xn,每一种取到的概率分别是P1,P2,……,Pn,那么X的熵就定义为:

    wps_clip_image-10494

    意思就是一个变量可能的变化越多(反而跟变量具体的取值没有任何关系,只和值的种类多少以及发生概率有关),它携带的信息量就越大(因此我一直觉得我们的政策法规信息量非常大,因为它变化很多,基本朝令夕改,笑)。

    对分类系统来说,类别C是变量,它可能的取值是C1,C2,……,Cn,而每一个类别出现的概率是P(C1),P(C2),……,P(Cn),因此n就是类别的总数。此时分类系统的熵就可以表示为:

    wps_clip_image-7054

    有同学说不好理解呀,这样想就好了,文本分类系统的作用就是输出一个表示文本属于哪个类别的值,而这个值可能是C1,C2,……,Cn,因此这个值所携带的信息量就是上式中的这么多。

    信息增益是针对一个一个的特征而言的,就是看一个特征t,系统有它和没它的时候信息量各是多少,两者的差值就是这个特征给系统带来的信息量,即增益。系统含有特征t的时候信息量很好计算,就是刚才的式子,它表示的是包含所有特征时系统的信息量。

    问题是当系统不包含t时,信息量如何计算?我们换个角度想问题,把系统要做的事情想象成这样:说教室里有很多座位,学生们每次上课进来的时候可以随便坐,因而变化是很大的(无数种可能的座次情况);但是现在有一个座位,看黑板很清楚,听老师讲也很清楚,于是校长的小舅子的姐姐的女儿托关系(真辗转啊),把这个座位定下来了,每次只能给她坐,别人不行,此时情况怎样?对于座次的可能情况来说,我们很容易看出以下两种情况是等价的:(1)教室里没有这个座位;(2)教室里虽然有这个座位,但其他人不能坐(因为反正它也不能参与到变化中来,它是不变的)。

    对应到我们的系统中,就是下面的等价:(1)系统不包含特征t;(2)系统虽然包含特征t,但是t已经固定了,不能变化。

    我们计算分类系统不包含特征t的时候,就使用情况(2)来代替,就是计算当一个特征t不能变化时,系统的信息量是多少。这个信息量其实也有专门的名称,就叫做“条件熵”,条件嘛,自然就是指“t已经固定“这个条件。

    但是问题接踵而至,例如一个特征X,它可能的取值有n多种(x1,x2,……,xn),当计算条件熵而需要把它固定的时候,要把它固定在哪一个值上呢?答案是每一种可能都要固定一下,计算n个值,然后取均值才是条件熵。而取均值也不是简单的加一加然后除以n,而是要用每个值出现的概率来算平均(简单理解,就是一个值出现的可能性比较大,固定在它上面时算出来的信息量占的比重就要多一些)。

    因此有这样两个条件熵的表达式:

    wps_clip_image-4299

    这是指特征X被固定为值xi时的条件熵,

    wps_clip_image-5245

    这是指特征X被固定时的条件熵,注意与上式在意义上的区别。从刚才计算均值的讨论可以看出来,第二个式子与第一个式子的关系就是:

    wps_clip_image-16538

    具体到我们文本分类系统中的特征t,t有几个可能的值呢?注意t是指一个固定的特征,比如他就是指关键词“经济”或者“体育”,当我们说特征“经济”可能的取值时,实际上只有两个,“经济”要么出现,要么不出现。一般的,t的取值只有t(代表t出现)和wps_clip_image-12889(代表t不出现),注意系统包含t但t 不出现与系统根本不包含t可是两回事。

    因此固定t时系统的条件熵就有了,为了区别t出现时的符号与特征t本身的符号,我们用T代表特征,而用t代表T出现,那么:

    wps_clip_image-26569

    与刚才的式子对照一下,含义很清楚对吧,P(t)就是T出现的概率,就是T不出现的概率。这个式子可以进一步展开,其中的

    wps_clip_image-8355

    另一半就可以展开为:

    wps_clip_image-16134

    因此特征T给系统带来的信息增益就可以写成系统原本的熵与固定特征T后的条件熵之差:

    wps_clip_image-19385

    公式中的东西看上去很多,其实也都很好计算。比如P(Ci),表示类别Ci出现的概率,其实只要用1除以类别总数就得到了(这是说你平等的看待每个类别而忽略它们的大小时这样算,如果考虑了大小就要把大小的影响加进去)。再比如P(t),就是特征T出现的概率,只要用出现过T的文档数除以总文档数就可以了,再比如P(Ci|t)表示出现T的时候,类别Ci出现的概率,只要用出现了T并且属于类别Ci的文档数除以出现了T的文档数就可以了。

    从以上讨论中可以看出,信息增益也是考虑了特征出现和不出现两种情况,与开方检验一样,是比较全面的,因而效果不错。但信息增益最大的问题还在于它只能考察特征对整个系统的贡献,而不能具体到某个类别上,这就使得它只适合用来做所谓“全局”的特征选择(指所有的类都使用相同的特征集合),而无法做“本地”的特征选择(每个类别有自己的特征集合,因为有的词,对这个类别很有区分度,对另一个类别则无足轻重)。

    看看,导出的过程其实很简单,没有什么神秘的对不对。可有的学术论文里就喜欢把这种本来很直白的东西写得很晦涩,仿佛只有读者看不懂才是作者的真正成功。

    咱们是新一代的学者,咱们没有知识不怕被别人看出来,咱们有知识也不怕教给别人。所以咱都把事情说简单点,说明白点,大家好,才是真的好。

    文本分类入门(番外篇)特征选择与特征权重计算的区别

    在文本分类的过程中,特征(也可以简单的理解为“词”)从人类能够理解的形式转换为计算机能够理解的形式时,实际上经过了两步骤的量化——特征选择阶段的重要程度量化和将具体文本转化为向量时的特征权重量化。初次接触文本分类的人很容易混淆这两个步骤使用的方法和各自的目的,因而我经常听到读者有类似“如何使用TFIDF做特征选择”或者“卡方检验量化权重后每篇文章都一样”等等困惑。

    文本分类本质上也是一个模式识别的问题,因此我想借用一个更直观的例子来说说特征选择和权重量化到底各自是什么东西,当然,一旦解释清楚,你马上就会觉得文本分类这东西实在白痴,实在没什么技术含量,你也就不会再继续看我的技术博客,不过我不担心,因为你已经踏上了更光明的道路(笑),我高兴还来不及。

    想想通过指纹来识别一个人的身份,只看一个人的指纹,当然说不出他姓甚名谁,识别的过程实际上是比对的过程,要与已有的指纹库比较,找出相同的,或者说相似到一定程度的那一个。

    首要的问题是,人的指纹太复杂,包含太多的位置和几何形状,要完全重现一个人的指纹,存储和计算都是大麻烦。因此第一步总是一个特征选择的问题,我们把全人类的指纹都统计一下,看看哪几个位置能够最好的区分不同的人。显然不同的位置效果很不一样,在有的位置上,我的指纹是是什么形状,其他人也大都是这个形状,这个位置就不具有区分度,或者说不具有表征性,或者说,对分类问题来说,它的重要程度低。这样的位置我们就倾向于在识别的时候根本不看它,不考虑它。

    那怎么看谁重要谁不重要呢?这就依赖于具体的选择方法如何来量化重要程度,对卡方检验和信息增益这类方法来说,量化以后的得分越大的特征就越重要(也就是说,有可能有些方法,是得分越小的越重要)。

    比如说你看10个位置,他们的重要程度分别是:

       1 2   3   4   5 6   7 8 9  10

    (20,5,10,20,30,15,4,3,7, 3)

    显然第1,第3,4,5,6个位置比其他位置更重要,而相对的,第1个位置又比第3个位置更重要。

    识别时,我们只在那些重要的位置上采样。当今的指纹识别系统,大都只用到人指纹的5个位置(惊讶么?只要5个位置的信息就可以区分60亿人),这5个位置就是经过特征选择过程而得以保留的系统特征集合。假设这个就是刚才的例子,那么该集合应该是:

    (第1个位置,第3个位置,第4个位置,第5个位置,第6个位置)

    当然,具体的第3个位置是指纹中的哪个位置你自己总得清楚。

    确定了这5个位置之后,就可以把一个人的指纹映射到这个只有5个维度的空间中,我们就把他在5个位置上的几何形状分别转换成一个具体的值,这就是特征权重的计算。依据什么来转换,就是你选择的特征权重量化方法,在文本分类中,最常用的就是TFIDF。

    我想一定是“权重“这个词误导了所有人,让大家以为TFIDF计算出的值代表的是特征的重要程度,其实完全不是。例如我们有一位男同学,他的指纹向量是:

    (10,3,4,20,5)

    你注意到他第1个位置的得分(10)比第3个位置的得分(3)高,那么能说第1个位置比第3个位置重要么?如果再有一位女同学,她的指纹向量是:

    (10,20,4,20,5)

    看看,第1个位置得分(10)又比第3个位置(20)低了,那这两个位置到底哪个更重要呢?答案是第1个位置更重要,但这不是在特征权重计算这一步体现出来的,而是在我们特征选择的时候就确定了,第1个位置比第3个位置更重要。

    因此要记住,通过TFIDF计算一个特征的权重时,该权重体现出的根本不是特征的重要程度!

    那它代表什么?再看看两位同学的指纹,放到一起:

    (10, 3,4,20,5)

    (10,20,4,20,5)

    在第三个位置上女同学的权重高于男同学,这不代表该女同学在指纹的这个位置上更“优秀“(毕竟,指纹还有什么优秀不优秀的分别么,笑),也不代表她的这个位置比男同学的这个位置更重要,3和20这两个得分,仅仅代表他们的”不同“。

    在文本分类中也是如此,比如我们的系统特征集合只有两个词:

    (经济,发展)

    这两个词是使用卡方检验(特征选择)选出来的,有一篇文章的向量形式是

    (2,5)

    另一篇

    (3,4)

    这两个向量形式就是用TFIDF算出来的,很容易看出两篇文章不是同一篇,为什么?因为他们的特征权重根本不一样,所以说权重代表的是差别,而不是优劣。想想你说“经济这个词在第二篇文章中得分高,因此它在第二篇文章中比在第一篇文章中更重要“,这句话代表什么意义呢?你自己都不知道吧(笑)。

    所以,当再说起使用TFIDF来计算特征权重时,最好把“权重“这个字眼忘掉,我们就把它说成计算得分好了(甚至”得分“也不太好,因为人总会不自觉的认为,得分高的就更重要),或者就仅仅说成是量化。

    如此,你就再也不会拿TFIDF去做特征选择了。

    小Tips:为什么有的论文里确实使用了TFIDF作特征选择呢?

    严格说来并不是不可以,而且严格说来只要有一种方法能够从一堆特征中挑出少数的一些,它就可以叫做一种特征选择方法,就连“随机选取一部分“都算是一种,而且效果并没有差到惊人的地步哦!还是可以分对一大半的哦!所以有的人就用TFIDF的得分来把特征排排序,取得分最大的几个进入系统特征集合,效果也还行(毕竟,连随机选取效果也都还行),怎么说呢,他们愿意这么干就这么干吧。就像咱国家非得实行户口制度,这个制度说不出任何道理,也不见他带来任何好处,但不也没影响二十一世纪成为中国的世纪么,呵呵。

    展开全文
  • 机器学习:线性分类问题(基础知识)

    千次阅读 多人点赞 2019-09-28 17:35:43
    {1,2,3,...,m}xi​∈C=Rn,yi​∈Y=1,2,3,...,m,要求寻找C上的决策函数 g(x):C→Yg(\mathbf x):C\to Yg(x):C→Y 含义解析 数据集中一个组合是一条数据, xi\mathbf x_ixi​表数据特征, yiy_iyi​表数据的分类结果,...


    本文属于我的机器学习/深度学习系列文章,点此查看系列文章目录

    一、超平面

    超平面不一定是一个面,它是所处向量空间的一个子空间,如立体空间中一个面,二维平面上一条线。它的作用在于将空间中的数据一分为二,达到分类的目的。

    1.1 超平面表达式

    g ( x ) = w T x + w 0 = 0 g(x) = \mathbf w^T\mathbf x+w_0 = 0\\ g(x)=wTx+w0=0

    • w = ( w 1 , w 2 , . . . , w l ) T \mathbf w = (w_1,w_2,...,w_l)^T w=(w1,w2,...,wl)T,权向量(超平面法向量)
    • x = ( x 1 , x 2 , . . . , x l ) T \mathbf x = (x_1,x_2,...,x_l)^T x=(x1,x2,...,xl)T,实例(样本向量)
    • w 0 w_0 w0,偏移量
      在实际中,w确定,因此这个方程代表所有满足的向量x(点)的集合, w T x w^Tx wTx可视为x向w的投影乘以w的模长

    这个方程的解读也可以是x向w的投影长度为 − w 0 ∣ ∣ w ∣ ∣ \frac{-w_0}{||w||} ww0的点集合。

    二、线性函数:距离刻画

    上面的超平面定义了所有在超平面上的点,那如果是不在超平面上的点与该超平面又有什么关系?

    x p x_p xp是x在超平面 w T x + w 0 = 0 \mathbf w^T\mathbf x+w_0=0 wTx+w0=0的投影点,得公式如下:
    x = x p + ( x − x p ) w T x ∣ ∣ w ∣ ∣ = w T x p ∣ ∣ w ∣ ∣ + w T ( x − x p ) ∣ ∣ w ∣ ∣ , 两 边 同 时 乘 上 w T ∣ ∣ w ∣ ∣ \mathbf x = \mathbf x_p + (\mathbf x-\mathbf x_p) \\ \frac{\mathbf w^Tx}{||\mathbf w||} = \frac{\mathbf w^T\mathbf x_p}{||\mathbf w||} + \frac{\mathbf w^T(\mathbf x - \mathbf x_p)}{||\mathbf w||}, 两边同时乘上 \frac{\mathbf w^T}{||\mathbf w||} \\ x=xp+(xxp)wwTx=wwTxp+wwT(xxp),wwT
    可绘出图例如下:
    在这里插入图片描述

    令 d = w T x p ∣ ∣ w ∣ ∣ , z = w T ( x − x p ) ∣ ∣ w ∣ ∣ 结 合   w T x p + w 0 = 0 , 有 d = − w 0 ∣ ∣ w ∣ ∣ , z = w T x + w 0 ∣ ∣ w ∣ ∣ = g ( x ) ∣ ∣ w ∣ ∣ 令d = \frac{\mathbf w^T\mathbf x_p}{||\mathbf w||},z = \frac{\mathbf w^T(\mathbf x - \mathbf x_p)}{||\mathbf w||}\\ 结合\ \mathbf w^T\mathbf x_p + w_0 = 0,\\ 有d = \frac{-w_0}{||\mathbf w||},z = \frac{\mathbf w^T\mathbf x+w_0}{||\mathbf w||} = \frac{g(\mathbf x)}{||\mathbf w||} d=wwTxp,z=wwT(xxp) wTxp+w0=0,d=ww0,z=wwTx+w0=wg(x)
    由图可知,z是任意一个向量 x \mathbf x x到超平面的距离。这个距离的作用在于让我们可以调整超平面的位置使得分类更加准确。当 x \mathbf x x方向和 w \mathbf w w一致时,该距离为正值,否则为负值,因此也可以得出结论,超平面一侧的点全是正值,另一侧全是负值,由此可以得到二分类。

    这两个概念的确立使得对于数据的分类有了依据,我们说将数据分成不同的两类,自然要有一个分界线(即超平面),而给定一个数据,如何去刻画该数据在超平面的一侧还是另一侧,依靠线性函数的符号(实现了类间分类),数据与分界线的远近由线性函数的绝对值刻画(体现了类内距离)。

    三、相似度度量

    相似度从几何的角度看就是两个样本点间距离的大小,距离越近,相似度越大。对于这个距离有好几种刻画形式,主要是不同的范式。

    • MinkovskiMetric 闵氏距离(p-范数)
      D ( x , y ) = [ ∑ i ∣ x i − y i ∣ p ] 1 p D(\mathbf x,\mathbf y) = [\sum_i|x_i-y_i|^p]^{\frac{1}{p}} D(x,y)=[ixiyip]p1

    • 欧式距离(p=2的特殊情况,2范数)
      D ( x , y ) = [ ( x − y ) T ( x − y ) ] = [ ∑ i ∣ x i − y i ∣ 2 ] D(\mathbf x,\mathbf y) = \sqrt{[(\mathbf x- \mathbf y)^T(\mathbf x - \mathbf y)]} = \sqrt{[\sum_i|x_i-y_i|^2]} D(x,y)=[(xy)T(xy)] =[ixiyi2]

    • 曼哈顿距离(p=1的特殊情况,1范数)
      D ( x , y ) = ∑ i ∣ x i − y i ∣ D(\mathbf x, \mathbf y) = \sum_i|x_i-y_i| D(x,y)=ixiyi

    • Chobychev距离(p= ∞ \infty
      D ( x , y ) = max ⁡ i ∣ x i − y i ∣ D(\mathbf x, \mathbf y) = \max_i|x_i-y_i| D(x,y)=imaxxiyi

    为什么要有这么多种距离?

    大部分情况下,一般欧式距离使用的情况较多,我们对于二维平面中的两个点,想要刻画他们的远近往往用欧式距离即可。但设想这样一种情况,假设两个点不能直达(最常见的就是生活中的街道,必须沿街道行走),这个时候用欧式距离刻画两点距离就显得不合理。

    下图为四种不同距离描述下所有到原点相同距离的点构成的图形。
    在这里插入图片描述

    四、分类问题

    4.1 定义

    • 书本定义:

      根据给定数据集 T = { ( x 1 , y 1 ) , . . . , ( x l , y l ) ) } T=\{(\mathbf x_1,y_1),...,(\mathbf x_l,y_l))\} T={(x1,y1),...,(xl,yl))},其中 x i ∈ C = R n , y i ∈ Y = 1 , 2 , 3 , . . . , m x_i\in C=R^n,y_i \in Y= {1,2,3,...,m} xiC=Rn,yiY=1,2,3,...,m,要求寻找C上的决策函数 g ( x ) : C → Y g(\mathbf x):C\to Y g(x):CY

    • 含义解析

      数据集中一个组合是一条数据, x i \mathbf x_i xi表数据特征, y i y_i yi表数据的分类结果,基于已有的 l l l条数据,训练一个从n维空间数据C到分类结果集合Y的映射函数 g ( x ) g(\mathbf x) g(x),使得在随意给定一个新的数据 ( x k , y k ) (\mathbf x_k,y_k) (xk,yk) g ( x k ) = y k ′ ( 预 期 结 果 ) g(\mathbf x_k)=y_k'(预期结果) g(xk)=yk就是其分类的结果,分类的目的就是使 y k ′ y_k' yk(预期结果)与 y k y_k yk(实际结果)尽可能相同。

    4.2 评估方法

    其实就是分训练集和测试集,训练集用于训练得到决策函数,测试集用于测试决策函数的好坏。主要包含两种方法

    1. 交叉验证法
      交叉验证法就是将数据分成两类(训练、测试),进行交叉验证,其中可以简单按比例划分(8:1,10:1等),也可以分成k类,其中1类做测试,剩余k-1类做训练,每一类训练集进行一次测试,最后取平均
    2. 自助法
      取m个随机样本,构成集合D,剩余除D以外的用于测试。

    核心是训练+测试

    4.3 性能评价

    有了测试作为评估,自然要考虑测试结果的好坏,直观来说,一般是预期与实际越相符,决策函数越好。这是采用错误率和精度作为评价标准:

    • 错误率与准确率
      所谓错误率即分类错误的样本站总样本数的比例,定义如下:
      E ( f ; D ) = 1 m ∑ i = 1 m h ( ( f ( x i ) ≠ y i ) ) h ( x ) = { 1 if  x   i s   t r u e 0 else  E(f;D) = \frac{1}{m}\sum_{i=1}^mh((f(\mathbf x_i)\ne y_i))\\ h(x) = \begin{cases} 1 &\text{if } x \ is\ true \\ 0 &\text{else } \end{cases} E(f;D)=m1i=1mh((f(xi)=yi))h(x)={10if x is trueelse 
      准确率相对于错误率,等于1-错误率,定义如下:
      a c c ( f ; D ) = 1 m ∑ i = 1 m h ( f ( x i ) = y i ) = 1 − E ( f ; D ) acc(f;D) = \frac{1}{m}\sum_{i=1}^mh(f(\mathbf x_i)=y_i) \\ =1-E(f;D) acc(f;D)=m1i=1mh(f(xi)=yi)=1E(f;D)
      以上为针对离散型分布数据,连续型分布数据(设密度函数为 p ( x ) p(\mathbf x) p(x))的E与acc如下:
      E ( f ; D ) = ∫ x ∈ D h ( f ( x ) ≠ y ) p ( x ) d x a c c ( f ; D ) = ∫ x ∈ D h ( f ( x ) = y ) p ( x ) d x = 1 − E ( f ; D ) E(f;D) = \int_{x\in D}h(f(\mathbf x) \ne y)p(\mathbf x)d\mathbf x\\ acc(f;D) = \int_{x\in D}h(f(\mathbf x) = y)p(\mathbf x)d\mathbf x\\ =1-E(f;D) E(f;D)=xDh(f(x)=y)p(x)dxacc(f;D)=xDh(f(x)=y)p(x)dx=1E(f;D)
      错误率和准确率本质上可看作一个东西,但是错误率只让我们知道了有多少样本被判别错误(例如正判成负,负判成正,都属于判别错误),但有的时候往往我们更关心判别为正的数据,因为正项数据对我们有利。这时候就需要用到查准率(precision)和查全率(recall)。

      这里举一个例子,假设判定地震是否发生,我们测得决策函数的精度在99%,即对100次测验,有99次预测成功,但是这99次我们不知道发生有多少次,不发生有多少次。假设99次均为不发生。说明你这个决策函数测地震不发生很准,但是发生的情况你测不准(容易出错),这就没有意义,因为我们更关心地震发生的情况。

    • 查准率(精度,precison)、查全率(召回率,recall)和 F 1 , F β F1,F_{\beta} F1,Fβ
      查准率和查全率更适宜被应用于类似这样的场景,如“查出的信息中有多少是用户感兴趣的”或“用户感兴趣的信息查出了多少”。在此基础上,我们引入“真正例(TP,预测结果为正,真实为正)”,“假正例(FP,预测结果正,真实为反)”,“真反例(TN,预测结果为反,真实为反)”,“假反例(FN,预测结果为反,真实为正)”的概念,由四者构成混淆矩阵如下:
      在这里插入图片描述
      由此我们得到查准率P和查全率R的定义如下:
      P = T P T P + F P R = T P T P + F N P = \frac{TP}{TP+FP}\\ R = \frac{TP}{TP+FN} P=TP+FPTPR=TP+FNTP
      从公式中可以看出查准率在于找出所有正例中真实为正的比例(将正例比做用户感兴趣内容,即所有决策函数认为用户感兴趣的内容中用户真正感兴趣的比例),查全率在于刻画有多少真实为正的内容被我们所找出(即决策函数挖掘出的用户真正感兴趣的内容占所有用户会感兴趣内容的比例)。

      事实上这两者存在矛盾性,如果我们想让尽可能多的用户感兴趣的内容被选上(提高查全率),那么必然会选上许多把握不大的内容(查准率下降);如果我们想让我们选出的东西用户必然会感兴趣(提高查准率),那么必然要放弃那些把握不大的内容,就会导致漏掉许多可能感兴趣的内容(查全率下降)。

      • P-R曲线
        我们根据学习器的预测结果对样本进行排序,将“最有可能为正例”的样本放在前面,“最不可能是正例的”样本放在最后,遍历这些样本,过程中不断计算当前的查准率和查全率(很显然一开始查准率很高,查全率会很低),得到P-R曲线如下:
        在这里插入图片描述

      A,B,C为三个不同的学习器,很显然A,B的性能要优于C,因为在任何情况下他们的查全率和查准率都要比C高。

      A,B的性能不好比较,因此需要引入另一个度量平衡点(查准率=查全率时的取值),粗略地认为,既然无法保证两者都好,就取一个两者都尽量好的位置作为学习器的代表位置,进而比较A与B的性能差异。但更常用的是 F 1 F_1 F1度量:
      F 1 = 2 1 P + 1 R F_1 = \frac{2}{\frac{1}{P}+\frac{1}{R}} F1=P1+R12
      F 1 F_1 F1度量本身求两者的调和平均,这个比简单地取两者相等位置等有说服力。但在实际应用中,我们不一定要取两者都好的情况,例如b站给用户推荐视频,肯定是希望选出的视频都是用户感兴趣的,这个时候查准率比查全率更重要。而如警方的逃犯信息检索系统,肯定希望不要漏抓一个逃犯,此时查全率更重要。所以这个时候就要根据实际需求进行选择,所以引入 F β F_{\beta} Fβ度量:
      F β = 1 + β 2 β 2 R + 1 P F_{\beta} = \frac{1+\beta^2}{\frac{\beta^2}{R}+\frac{1}{P}} Fβ=Rβ2+P11+β2
      其中 β \beta β度量了查全率对于查准率的重要性,当 β = 1 \beta=1 β=1即退化为 F 1 F_1 F1度量,当 β > 1 \beta >1 β>1,说明查全率权重更大(更重要),当 0 < β < 1 0<\beta<1 0<β<1,说明查准率权重更大(更重要)。

      查全率和查准率是十分重要的概念,相对于错误率描述你学习器的直观判别能力,查全率和查准率能够描述你学习器的是否有意义。如果判断不重要的事一判一个准,判断重要的事老是判错,准确率高与否也就失去了意义。

    • 真正例率(TPR),假正例率(FPR)
      前面P,R能够较好地体现正例样本被划分正确的效果,但我们较为关心分类对正例效果的影响时,就倾向于使用这两者。但当正例和负例样本分布均匀,两者均是我们期望能较好划分的目标时(例如男女划分),那么P,R就显得力不从心了,因此需要TPR(所有实际为正例的样本中被正确判断成正例的比例),FPR(在所有实际为负例的样本中被错误判断成正例的比例) 以及 ROC曲线(以FPR为横轴,TPR为纵轴的曲线)和AUC(ROC曲线与横轴围成的面积) 来体现了。
      T P R = T P T P + F N F P R = F P T N + F P TPR = \frac{TP}{TP+FN}\\ FPR = \frac{FP}{TN+FP} TPR=TP+FNTPFPR=TN+FPFP
      很显然,TPR就是R(召回率),而FPR则从侧面体现了负例被划分成正例的程度,可以理解为模型成本,将模型比作一台过滤器,FPR就是模型过滤错误掺入杂质的比例。很显然我们希望TPR越大越好,FPR越小越好。为了同时体现这两点,引入了ROC曲线,如下图。
      在这里插入图片描述
      要体现上面两点,就是要让曲线尽可能上凸。为此我们需要一个定量的标准去计算这个凸度,因此又引入了AUC,它时图中绿色阴影区域的面积,显然面积越大,效果越好。

      一个良好的分类器,其ROC曲线必然时在y=x之上的,否则相当于大部分负例被当成了正例,效果极差。


    关于分类评价指标更多的还可以看知乎上一篇比较好的回答

    五、线性分类问题

    上面我们讨论了一般分类问题需要考虑的部分基础知识(还有些不常用的后续添加),本节考虑分类问题中的线性分类。

    所谓线性分类,就是透过特征的线性组合来作出分类决策。对象的特征通常描述为特征值,在向量空间中则是特征向量。如果两类数据可以通过一个线性平面划分,则其分类属于线性分类问题。

    在这里插入图片描述

    5.1 线性判别函数

    线性判别函数即决策函数,在上文中已提过,其表达形式如下:
    g ( x ) = ∑ i w i x i + w 0 = w T x + w 0 g(\mathbf x) = \sum_iw_ix_i + w_0 = \mathbf w^T \mathbf x + w_0 g(x)=iwixi+w0=wTx+w0
    这个式子很容易联想到超平面(分类界):
    g ( x ) = w T x + w 0 = 0 g(\mathbf x) =\mathbf w^T \mathbf x + w_0 = 0 g(x)=wTx+w0=0
    由此对于每一个给定的特征向量 x = ( x 1 , x 2 , . . . , x n ) \mathbf x=(x_1,x_2,...,x_n) x=(x1,x2,...,xn),我们只需代入线性判别函数,观察其结果正负号即可,如下:
    x ∈ { ω 1 if  w T x + w 0 > 0 ω 2 if  w T x + w 0 < 0 \mathbf x\in \begin{cases} \omega_1 &\text{if } \mathbf w^Tx+w_0>0\\ \omega_2 &\text{if } \mathbf w^Tx+w_0 <0 \end{cases} x{ω1ω2if wTx+w0>0if wTx+w0<0

    5.2 线性分类器

    由给定训练样本 { ( x 1 , y 1 ) , . . . , ( x n , y n ) } \{(\mathbf x_1,y_1),...,(\mathbf x_n,y_n)\} {(x1,y1),...,(xn,yn)},求得线性判别函数(决策函数) g ( x ) g(\mathbf x) g(x),实际上是求 w , w 0 \mathbf w,w_0 w,w0的过程,我们要找满足以下条件的 w , w 0 \mathbf w,w_0 w,w0
    w T x i + w 0 ≥ 0 , f o r   e a c h   y i = + 1 w T x i + w 0 ≤ 0 , f o r   e a c h   y i = − 1 \mathbf w^T\mathbf x_i + w_0 \ge0,for \ each \ y_i=+1\\ \mathbf w^T \mathbf x_i+w_0 \le0,for \ each\ y_i = -1 wTxi+w00,for each yi=+1wTxi+w00,for each yi=1
    关于这样的 w , w 0 \mathbf w,w_0 w,w0参数的寻找,就有很多的线性分类器可用,如感知机,线性鉴别分析,Logistic模型等。

    六、参考资料

    • 机器学习.周志华.2016
    展开全文
  • 计算机论文答辩常见问题

    万次阅读 多人点赞 2020-01-23 10:54:10
    软件开发题目常见问题 软件工程相关问题 1.B/S结构程序与C/S结构程序各有哪些特点? 2.说明软件设计与开发过程分为哪几个阶段。每个阶段你都做了哪些工作,得到什么设计结果。 3.需求分析阶段的主要任务是什么?...

    软件开发类题目常见问题
    软件工程相关问题
    1.B/S结构程序与C/S结构程序各有哪些特点?
    2.说明软件设计与开发过程分为哪几个阶段。每个阶段你都做了哪些工作,得到什么设计结果。
    3.需求分析阶段的主要任务是什么?为了完成这些任务,你都做了哪些工作?
    4.什么是数据流图?什么是数据字典?它们的作用是什么?
    5.说明管理信息系统设计和开发的基本过程分为几个阶段?每个阶段的主要工作是什么?
    6.这个课题是你独自完成的还是团体共同完成的?
    7.简单介绍你的课题以及你主要负责的模块?有什么特点?
    8.软件的开发一般分为几个步骤?
    9.软件需求分析的目的是什么?主要分析哪些方面的需求?你采用了什么方法进行需求分析?
    10.你用的系统设计方法是什么?这种方法的基本思想是怎样的?
    11.软件测试有哪些方法?你采用了什么测试方法?
    数据库相关问题
    1.数据库的设计分为几个步骤?
    2.概念数据库设计的主要任务是什么?应该完成哪些工作?
    3.逻辑数据库设计的主要任务是什么?应该完成哪些工作?
    4.物理数据设计的主要任务是什么?应该完成哪些工作?
    5.这个课题你选用的数据库管理系统是什么?采用什么接口?为什么这么选择?
    6.关系模式范式化有什么意义?在你的设计中式如何体现的?
    7.请解释数据库的逻辑结构和物理结构的区别。
    8.解释ER图并说明ER图的作用。
    9.实体之间联系的类型有几种?详细解释它们的含义。
    10.请说明主键和外键的作用,你设定主键和外键的依据是什么?
    11.数据库/数据库管理系统/数据库系统在概念上有什么区别?结合你的设计说明。
    12.说明在数据库表中,数据之间的联系是如何体现的。
    13.你用什么方法保证数据完整性?
    14.在数据库设计阶段,你遇到的最大困难是什么?你是如何解决的?
    15.解释实现数据库结构的SQL语句。
    16.说明在设计数据库表时你是如何考虑的?
    17.你是如何创建界面与数据库的连接?

    编程相关问题
    1.演示一下你的课题成品,然后请找出实现某一功能的代码块?
    2.解释一段主要的源代码。
    3.说明应用程序访问数据库的方法。
    4.编码中用到了什么关键技术?
    其它
    1.软件开发过程中遇到什么问题?如何解决的?
    2.说下你的课题将来的应用以及在哪方面可以改进?
    3.在系统安全性方面你是如何考虑的?
    局域网规划设计类题目常见问题
    1.介绍一下您和XX学校(公司、小区)的关系?为什么选择它作为毕业设计的设计目标?
    2.这个课题是你独自完成的还是团体共同完成的?如果是团体共同完成的,你负责哪部分工作?
    3.局域网规划设计的一般步骤是什么?每个步骤都要完成哪些工作?
    4.局域网设计的需求分析包括哪些内容?你怎么做的?
    5.网络设计方案是如何体现网络设计需求的?
    6.网络设计的原则有哪些?在您的设计中如何体现这些原则的?
    7.局域网流量和带宽是怎么确定的?
    8.网络拓扑结构有哪几种?优缺点各是什么?本设计采用哪种结构?为什么?
    9.请解释论文中的网络拓扑结构图。
    10.IP地址的概念,分为几类?你用的是哪一类?你是怎么考虑的?
    11.IP地址分哪几类?怎么判断是哪一类IP地址?什么是MAC地址?IP地址、MAC地址分别是哪一层的地址?
    12.为什么要划分VLAN,其主要作用是什么?划分VLAN的方法有哪些,各有什么特点?
    13.子网和VLAN的区别是什么?
    14.NAT转换的概念?实现方法?
    15.什么是公有IP地址和私有IP地址?它们之间怎么转换?
    16.为什么要划分子网?掩码的作用是什么?
    17.网络的安全如何维护?请介绍常用的服务的端口?请介绍什么是ARP攻击、DDOS攻击及其原理?
    18.网卡、集线器、二层交换机、三层交换机、路由器的作用是什么?有什么区别?是哪一层的设备?
    19.接入internet的方式是什么?
    20.网络冗余性是如何考虑的?
    自动化专业毕设答辩常见问题
    一、××零件数控加工设计
    1.请解释一段你所编制的数控机床加工程序。
    2.数控机床坐标轴是如何命名和规定方向的?
    3.在数控编程中,绝对坐标和相对坐标有什么区别,各用什么指令?你在编程中使用的哪种坐标?
    4.什么是刀具半径补偿?它的优点是什么?
    5.数控加工中,切削用量包括哪几个参数,选择的原则是什么?
    6.数控加工时,选择工件定位和夹紧方案有哪些原则?
    7.常见的数控加工工艺文件有哪些?
    二、XXX(人事信息、考勤、仓储、办公)自动化系统的设计与实现
    1.系统开发用到了什么技术(采用的数据库及程序语言等)?
    2.请解释系统的功能结构图。
    3.请解释业务流程图。
    4.数据库设计包含哪几个环节?
    5.数据库需求分析的结果是什么?数据库概念结构设计的结果是什么?
    6.逻辑结构设计(E-R图向关系模型的转换)的结果是什么?
    7.请解释主键和外键的作用并说明它们的区别。
    8.请解释一段程序。
    9.系统测试包含哪些方面?请解释黑盒测试和白盒测试的概念。
    三、XX工业以太网的规划与设计
    1.该设计中说明计算机控制设备的数量是怎样确定的?
    2.拓扑图中各种设备的作用是什么?
    3.拓扑图中各点的速率大概是多少?
    4.组网时采用了什么样的传输介质?为什么?
    5.IP地址分哪几类?
    6.本方案采用哪一类IP地址?为什么?
    7.所设计的网络使用了何种安全措施?如何实施的?
    四、基于XX现场总线的控制(监控)系统的规划与设计
    1.本设计采用了哪种现场总线?为什么?
    2.该系统的测点个数和控制对象个数是如何确定的?测量对象是什么?
    3.请简单介绍控制(监控)系统的总体功能。
    4.请解释控制系统的整体结构图,说明为什么采用这种结构?
    5.信号采集电路(通信电路)是怎么设计的?
    6.请解释一段程序。
    7.本方案采用哪一类IP地址?为什么?
    8.现场布线方案是如何确定的?
    五、XX监测系统设计与实现
    1.软件的开发一般分为几个步骤?
    2.你用的系统设计方法是什么?这种方法的基本思想是怎样的?
    3.软件测试有哪些方法?你采用了什么测试方法?
    4.数据库的设计分为几个步骤?
    5.在数据库表中,数据之间的联系是如何体现的?举例说明。
    6.演示一下你的系统,然后请找出实现某一功能的代码块。解释一段主要的源代码。
    7.说明应用程序访问数据库的方法。
    8.请说明你所设计的检测系统的结构?包括哪些组成部分?各部分之间如何通信?
    9.请说明你所设计的检测系统的工作流程?
    10.请说明你所设计的监控系统的控制原理和控制过程?系统应用的效果如何?
    六、基于PLC控制的XX系统设计
    1.请解释被控系统的工艺流程。
    2.被控系统的电气控制要求是怎样的?
    3.解释你设计的控制系统的结构和各部分的控制功能。
    4.PLC、传感器、执行器的选型是如何考虑的?
    5.请解释PLC的I/O端口分配是如何考虑的?
    6.请解释你设计的电气控制原理图。
    7.选择一个梯形图,解释其功能,并说明参数设定依据。

    展开全文
  • 本文回答了运放中“轨至轨”运行真正含义是什么的问题
  • 在本文中,我们分析了句子对建模的几种神经网络设计(及其变体), 并在八个数据集中比较它们的性能,包括释义识别、语义文本相似性、自然语言推理和问题回答任务。 尽管这些模型中的大多数都声称具有最先进的性能,但...
  • Oracle面试常见的二十个问题回答

    万次阅读 2011-06-28 17:43:00
     解答:具体的出错信息是snapshot too old within rollback seg , 通常可以通过增大rollback seg来解决问题。当然也需要察看一下具体造成错误的SQL文本  20. 解释$ORACLE_HOME和$ORACLE_BASE的区别? ...
  • 【转】去中心化的含义

    万次阅读 2019-05-13 18:55:54
    我认为,一个具有实践意义的“去中心化”概念回答的不是一个系统在功能提供方面的问题,而是一个免信任的系统与外在于这个系统的其它资源供应系统之间的关系问题。符合该定义的系统可预期拥有更多全节点,最终实现...
  • 希望大家多补充或回答! 作 者: top1000 (天天向上) 等 级: 信 誉 值: 98 所属社区: .NET技术 C# 问题点数: 0 回复次数: 184 发表时间: 2005-9-14 21:13:57 1. C#中 property 与 attribute的...
  • 文本分类入门

    千次阅读 热门讨论 2012-03-04 02:08:57
    最近要做文本分类相关的课程project,因此上网找了一下文本分类的资料,下面这个感觉比较通俗易懂,...文本分类系列文章,从文本分类问题的定义开始,主要讲解文本分类系统的构成,主流的统计学习方法以及较为优秀的
  • Java加载机制与Tomcat加载器架构

    万次阅读 热门讨论 2017-02-26 10:58:11
    Java加载机制 加载器 虚拟机设计团队把加载阶段中的“通过一个的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的。实现这个动作的...
  • wireshark抓包常见提示含义解析

    万次阅读 多人点赞 2016-09-01 19:58:28
    wireshark抓包常见提示含义解析
  • 重新认识java(八) ---- 抽象与接口

    千次阅读 多人点赞 2017-02-10 18:40:14
    你很清楚的知道什么时候用抽象,什么时候用接口么? p.s. 多文字预警!
  • 挑战10个最难回答的Java面试题(附答案)

    万次阅读 多人点赞 2019-08-12 10:28:36
    译者:Yujiaao segmentfault.... ... 1.SpringBoot内容聚合 2.面试题内容聚合 ...3.设计模式内容聚合 ...这是我收集的10个最棘手的Java面试问题列表。这些问题主要来自 Java 核心部分 ,不涉及 Java EE 相关问题。...
  • 图像分类

    万次阅读 多人点赞 2018-01-21 15:31:47
    图像物体分类与检测算法综述 转自《计算机学报》 目录 ...图像物体分类与检测是计算机视觉研究中的两个重要的基本问题,也是图像分割、物体跟踪、行为分析...本文从物体分类与检测问题的基本定义出发,首先从实例
  • 全面掌握 Java 内部

    千次阅读 2017-05-24 16:20:16
    一直以来以为自己对 java 基础甚是清楚,然而面试时却连内部和静态内部的区别都无法回答圆满,so~重新学习一遍,彻底掌握内部。内部是一种非常有用的特性,它可以把一些逻辑相关的组织在一起,并控制位于...
  • 理解YOLOv2训练过程中输出参数含义

    万次阅读 2017-11-17 21:45:31
    原英文地址: ...本篇文章中我将尝试着去回答这个有趣的问题。刚好现在我正在训练一个YOLOv2模型,拿这个真实的例子来讨论再合适不过了,下边是我训练中使用的 .cfg...
  • "栈"(stack)的三种三种含义

    千次阅读 2014-08-07 01:19:24
    容易混淆的是,这个词其实有三种含义,适用于不同的场合,必须加以区分。 含义一:数据结构 stack的第一种含义是一组数据的存放方式,特点为LIFO,即后进先出(Last in, first out)。 在这种数据结构中,...
  • GetLastError返回代码含义

    万次阅读 2012-11-20 15:46:54
    参考http://msdn.microsoft.com/en-us/library/ms681381(v=vs.85).aspx 【0|0】-操作成功完成。 【0x1|1】-函数不正确。 【0x2|2】-系统找不到指定的文件。 ...【0x3|3】-系统找不到指定的路径。...【0x7|7】-存储控制
  • 谈谈RNN的梯度消失/爆炸问题

    千次阅读 2020-11-30 14:06:37
    尽管 Transformer 的模型已经攻占了 NLP 的多数领域,但诸如 LSTM、GRU之的 RNN模型...关于此类问题,已有不少网友做出过回答,然而笔者查找了一些文章(包括知乎上的部分回答、专栏以及经典的英文博客),发现没..
  • 理解激活函数增加非线性的含义

    千次阅读 2018-10-31 17:25:47
    转自微信公众号: 机器学习算法与自然...激活函数是用来加入非线性因素的,解决线性模型所不能解决的问题。 下面我分别从这个方面通过例子给出自己的理解~ @lee philip@颜沁睿俩位的回答已经非常好了,我举的例子也...
  • 选择器和ID选择器的区别

    千次阅读 2020-12-24 18:01:18
    的小女孩,上课从来不敢回答老师提出的问题,生怕回答错了老师会批评我。就一直没有这个 <span class="stress">勇气</span> 来回答老师提出的问题。 </p> 而下面代码是错误的: <p> 三年级...
  • 据美国新闻聚合网站Buzzfeed介绍,对于母语是英文的老外来说,回答you're welcome其实是个误会…听到 you’re welcome,歪果仁的真实感受其实是…虽然在美国,大家还是能遇到在Thank you后回答you're welcome的人...
  • BNF和EBNF的含义及其用法

    千次阅读 2012-07-02 20:13:22
    BNF 和EBNF的含义与用法 By: Lars Marius Garshol  原文参见:http://www.garshol.priv.no/download/text/bnf.html (本文是上述作者文章的翻译,原文版权归作者所有) (译者:Sunnybill) BNF 和EBNF的...
  • 面试最后一问:你有什么问题想问我吗?

    万次阅读 多人点赞 2019-10-22 09:37:08
    那么如何回答好这类问题呢?今天分享一个万能的Github上的开源项目:reverse-interview,即:反向面试。 Github地址: https://github.com/viraptor/reverse-interview 这里记录了网友们整理的如何应对反向面试...
  • 关键字const有什么含义

    千次阅读 2016-12-28 21:25:46
    如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思? Const 只是一个修饰符,不管怎么样 a 仍然是一个 int 型的变量 const int a; int const a; const int *a; int * ...
  • 由于《深入理解Android 卷一》和《深入理解Android卷二》不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容。第5章 深入理解常见本章主要内容· 分析...
  • 对于随机森林来说,它实际上拥有更广泛的含义。但是我们要更好地了解它。同样值得注意的是,如果你使用了 0.16 或之前的版本,你可以尽管这样做: >>> dt_ci = DecisionTreeClassifier(compute_importances=...
  • BNF 和EBNF的含义与用法

    千次阅读 2008-06-30 02:19:00
    BNF 和EBNF的含义与用法(感谢译者:Sunnybill)By: Lars Marius Garshol 原文参见:http://www.garshol.priv.no/download/text/bnf.html(本文是上述作者文章的翻译,原文版权归作者所有)(译者:Sunnybill)BNF 和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 51,208
精华内容 20,483
关键字:

含义类的问题怎么回答