65.9K
CodeProject 正在变化。 阅读更多。
Home

检测书面文本的语言

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (72投票s)

2009年10月21日

CPOL

6分钟阅读

viewsIcon

171240

downloadIcon

7759

一篇关于如何检测书面文本语言的文章。

引言

很久以前,我发表了一篇关于如何检测给定文本编码的文章。在这篇文章中,我将描述文本分类漫漫长路上的下一步:语言检测。

给定的解决方案基于 n-gram 和词频比较。

它适用于所有使用词语的语言(这实际上并非适用于所有语言)。

根据模型和输入文本的长度,在使用“all”模型分类挪威语、瑞典语和丹麦语短文本时,准确率介于 70%(仅限短文本)和使用“default”模型时的 99.8% 之间。

背景

书面文本的语言检测可能是自然语言处理 (NLP) 中最基本的任务之一。对于任何依赖语言处理的未知文本,首先要知道的是该文本是用哪种语言编写的。幸运的是,这是 NLP 提供的更简单的挑战之一。我选择实现的这种方法广为人知且相当简单。其思想是,任何语言都有一组独特的字符(共)出现。

第一步是收集所有应可检测语言的这些统计数据。这最初听起来可能并不容易。问题在于收集大量的测试数据(纯文本),这些数据只包含一种语言,并且不是领域特定的。(只有报纸文章可能缺乏“我”这个词的使用和直接引语。使用莎士比亚戏剧不会是检测当代文本的最佳方法。医学文章往往包含太多领域特定术语,这些术语甚至不是语言特定的(major、minor、arteria 等……)。如果这还不够难,文本不应该受版权保护。(我不确定这是否是一个真正的要求。受版权保护文本的统计分析结果是否也受版权保护?)我选择使用维基百科作为我的主要来源。我不得不进行一些过滤,以“清理”来源中几乎所有文章中都存在的英文短语——无论它们是用哪种语言编写的(我实际上使用了 Babel 本身来检测英文短语)。清理工作绝非完美。维基百科包含许多专有名称(即乐队名称),这些名称通常包含“the”或“and”。这就是为什么这些词在许多语言中都会出现,即使它们不属于该语言。这不一定是一个缺点,因为英语化现象在许多语言中都广泛存在。我为每种语言创建了三种统计数据

  • 字符集
  • 有些语言具有非常特殊的字符集(例如中文、日文和俄文);对于其他语言,某些字符可以很好地提示可能是什么语言(例如德语的变音符号)。

  • N-gram
  • 在将文本标记化为单词(如果适用)后,统计了每个 1-gram、2-gram 和 3-gram 的出现次数。一些 n-gram 具有很强的语言特异性(例如,英语中的“TH”)。

  • 词表
  • 最后一个消除歧义的来源是实际使用的单词。有些语言(如葡萄牙语和西班牙语)在使用的字符和特定 n-gram 的出现频率上几乎相同。然而,不同的单词以不同的频率使用。

一组统计数据被称为一个模型。我创建了一些“所有”模型的子集,这些子集最能满足我的需求(见下表)。“common”模型包含世界上最常用的 10 种语言。“small”和“default”是基于我的使用场景。如果你来自世界的其他地方,你的偏好可能会有所不同。因此,请不要介意我选择哪些语言包含在哪个模型中。

所有统计数据按其出现次数排序和排名。在演示应用程序中,所有模型都可以详细研究。对未知文本的分类非常简单。文本被标记化,并生成三个统计表。结果表与模型中的所有表进行比较,并计算距离。与未知文本距离最小的模型中的比较表最可能是该文本的语言。

示例模型

使用代码

关于代码的简单说明

Babel 是一个更大项目的一部分。我希望 Babel 程序集能够独立工作。由于一些使用的类最初分散在许多程序集中,我使用了定义“_DIALOGUEMASTER”来指示是使用 DialogueMaster™ 程序集还是就地实现(可能更简单的)版本。

任何重要的 DialogueMaster™ 类都是可远程访问的。客户端只需要一个包含所有接口定义的程序集。这就是为什么 Babel 使用了如此多的接口,它们可能乍一看会使代码臃肿。此外,DialogueMaster™ 提供了大量的 PerformanceCounters。为了使程序集更易于使用(无需安装,无需管理员权限),我选择省略了它们。

我真正想说的是:代码不如它应该的那样可读和简洁。

分类文本

代码的使用非常简单。首先,您必须选择(或创建自己的)模型。ClassifyText 方法返回一个 ICategoryList,它是一个按分数降序排列的 ICateogry(名称-分数对)项的列表。

using System;

//
// Most simple samlple
//

class Program
{
    static void Main(string[] args)
    {
        DialogueMaster.Babel.BabelModel model = DialogueMaster.Babel.BabelModel._AllModel;
        String s = System.Console.ReadLine();
        while (s.Length > 0)
        {
            DialogueMaster.Classification.ICategoryList result = model.ClassifyText(s, 10);
            foreach (DialogueMaster.Classification.ICategory category in result)
            {
                System.Console.Out.WriteLine(" {0} : {1}", category.Name, category.Score);
            }

            s = System.Console.ReadLine();
        }
    }
}

定义您自己的模型

从现有集合中定义

要从现有语言集中定义您自己的模型,只需创建一个新的 BabelModel 并从 _AllModel 中添加所需的语言。

class Program2
{
    static void Main(string[] args)
    {
        // Create a custom model 
        DialogueMaster.Babel.BabelModel model = new DialogueMaster.Babel.BabelModel();
        model.Add("de", DialogueMaster.Babel.BabelModel._AllModel["de"]);
        model.Add("en", DialogueMaster.Babel.BabelModel._AllModel["en"]);
        model.Add("sv", DialogueMaster.Babel.BabelModel._AllModel["sv"]);

        // ask the user for some input
        String s = System.Console.ReadLine();
        while (s.Length > 0)
        {
            // classify it 
            DialogueMaster.Classification.ICategoryList result = model.ClassifyText(s, 10);
            // and dump the result
            foreach (DialogueMaster.Classification.ICategory category in result)
            {
                System.Console.Out.WriteLine(" {0} : {1}", category.Name, category.Score);
            }

            s = System.Console.ReadLine();
        }
    }
}

添加新语言

添加新语言非常简单。您所需要的只是一些学习数据文本。

class Program3
{
    static void Main(string[] args)
    {
        // Create a custom model 
        DialogueMaster.Babel.BabelModel model = new DialogueMaster.Babel.BabelModel();
        TokenTable klingonTable = new TokenTable(new FileInfo("LearnData\\Klingon.txt"));
        TokenTable vulcanTable = new TokenTable(new FileInfo("LearnData\\Vulcan.txt"));

        model.Add("kling", klingonTable);
        model.Add("vulcan", klingonTable);
        model.Add("en", DialogueMaster.Babel.BabelModel._AllModel["en"]);


        // ask the user for some input
        String s = System.Console.ReadLine();
        while (s.Length > 0)
        {
            // classify it 
            DialogueMaster.Classification.ICategoryList result = model.ClassifyText(s, 10);
            // and dump the result
            foreach (DialogueMaster.Classification.ICategory category in result)
            {
                System.Console.Out.WriteLine(" {0} : {1}", category.Name, category.Score);
            }

            s = System.Console.ReadLine();
        }
    }
}

关注点

支持的语言

语言代码 语言 质量 默认值 Common
nl Dutch 13 x   x  
en English 13 x x x x
ca 加泰罗尼亚语 13        
fr French 13 x x x x
es 西班牙语 13 x x x x
Norwegian 13 x   x  
da Danish 13 x   x  
it Italian 13     x x
sv 瑞典语 13 x   x  
de German 13 x x x x
pt 葡萄牙语 13 x x x  
ro 罗马尼亚语 13        
vi 越南语 13        
tr 土耳其语 13     x  
fi Finnish 12     x  
hu Hungarian 12     x  
cs Czech 12     x  
pl 波兰语 12     x  
el Greek 12     x  
fa 波斯语 12        
he 希伯来语 12        
sr 塞尔维亚语 12        
sl 斯洛文尼亚语 12        
ar 阿拉伯语 12   x    
nn 挪威语,新挪威语 (挪威) 12        
ru 俄语 11   x x  
et Estonian 11        
ko Korean 10        
hi 印地语 10   x    
is 冰岛语 10        
th 泰语 9        
bn 孟加拉语(孟加拉国) 9   x    
ja Japanese 9   x    
zh 中文 (简体) 8   x    
se 萨米语 (北方) (瑞典) 5        

参考文献

历史

  • 2009年10月10日:发布初始版本。
© . All rights reserved.