hocvt / language-detection
一个用于PHP的语言检测库。可以从给定的文本字符串中检测语言。
Requires
- php: ^7
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^6
README
这个库可以检测给定文本字符串的语言。它可以将给定的训练文本解析成一系列N-gram,并构建一个JSON格式的数据库文件用于检测阶段。然后它可以接受一个给定的文本并使用之前在训练阶段生成的数据库来检测其语言。该库包含用于训练和检测110种语言文本的样本。
目录
使用Composer安装
注意:此库需要多字节字符串扩展才能运行。
$ composer require patrickschur/language-detection
基本用法
为了正确检测语言,输入文本的长度应至少包含一些句子。
use LanguageDetection\Language; $ld = new Language; $ld->detect('Mag het een onsje meer zijn?')->close();
结果
Array
(
"nl" => 0.66193548387097,
"af" => 0.51338709677419,
"br" => 0.49634408602151,
"nb" => 0.48849462365591,
"nn" => 0.48741935483871,
"fy" => 0.47822580645161,
"dk" => 0.47172043010753,
"sv" => 0.46408602150538,
"bi" => 0.46021505376344,
"de" => 0.45903225806452,
[...]
)
API
__construct(array $result = [], string $dirname = '')
您可以将语言数组传递给构造函数。仅与给定的语言比较所需的句子。这可以显著提高性能。另一个参数是可选的,表示翻译文件所在的目录名称。
$ld = new Language(['de', 'en', 'nl']); // Compares the sentence only with "de", "en" and "nl" language models. $ld->detect('Das ist ein Test');
whitelist(string ...$whitelist)
提供白名单。返回所需的语言列表。
$ld->detect('Mag het een onsje meer zijn?')->whitelist('de', 'nn', 'nl', 'af')->close();
结果
Array
(
"nl" => 0.66193548387097,
"af" => 0.51338709677419,
"nn" => 0.48741935483871,
"de" => 0.45903225806452
)
blacklist(string ...$blacklist)
提供黑名单。从结果中删除指定的语言。
$ld->detect('Mag het een onsje meer zijn?')->blacklist('dk', 'nb', 'de')->close();
结果
Array
(
"nl" => 0.66193548387097,
"af" => 0.51338709677419,
"br" => 0.49634408602151,
"nn" => 0.48741935483871,
"fy" => 0.47822580645161,
"sv" => 0.46408602150538,
"bi" => 0.46021505376344,
[...]
)
bestResults()
返回最佳结果。
$ld->detect('Mag het een onsje meer zijn?')->bestResults()->close();
结果
Array
(
"nl" => 0.66193548387097
)
limit(int $offset, int $length = null)
您可以指定要返回的记录数。例如,以下代码将返回前三个条目。
$ld->detect('Mag het een onsje meer zijn?')->limit(0, 3)->close();
结果
Array
(
"nl" => 0.66193548387097,
"af" => 0.51338709677419,
"br" => 0.49634408602151
)
close()
将结果作为数组返回。
$ld->detect('This is an example!')->close();
结果
Array
(
"en" => 0.5889400921659,
"gd" => 0.55691244239631,
"ga" => 0.55376344086022,
"et" => 0.48294930875576,
"af" => 0.48218125960061,
[...]
)
setTokenizer(TokenizerInterface $tokenizer)
脚本使用分词器来获取句子中的所有单词。您可以定义自己的分词器来处理数字等。
$ld->setTokenizer(new class implements TokenizerInterface { public function tokenize(string $str): array { return preg_split('/[^a-z0-9]/u', $str, -1, PREG_SPLIT_NO_EMPTY); } });
这将只返回小写字母和介于0到9之间的数字。
__toString()
返回结果中的顶级条目。注意开头的echo
。
echo $ld->detect('Das ist ein Test.');
结果
de
jsonSerialize()
将数据序列化为JSON。
$object = $ld->detect('Tere tulemast tagasi! Nägemist!'); json_encode($object, JSON_PRETTY_PRINT);
结果
{
"et": 0.5224748810153358,
"ch": 0.45817028027498674,
"bi": 0.4452670544685352,
"fi": 0.440983606557377,
"lt": 0.4382866208355367,
[...]
}
方法链
您也可以将方法相互组合。以下示例将删除黑名单中指定的所有条目并只返回前四个条目。
$ld->detect('Mag het een onsje meer zijn?')->blacklist('af', 'dk', 'sv')->limit(0, 4)->close();
结果
Array
(
"nl" => 0.66193548387097
"br" => 0.49634408602151
"nb" => 0.48849462365591
"nn" => 0.48741935483871
)
ArrayAccess
您也可以直接将对象作为数组访问。
$object = $ld->detect(Das ist ein Test'); echo $object['de']; echo $object['en']; echo $object['xy']; // does not exists
结果
0.6623339658444
0.56859582542694
NULL
支持的语言
该库目前支持110种语言。要查看所有支持的语言概述,请参阅此处。
其他语言
该库是可训练的,这意味着您可以更改、删除并添加自己的语言文件。如果您的语言不受支持,请随时添加自己的语言文件。为此,在resources
目录中创建一个新目录并将您的训练文本添加到其中。
注意:训练文本应为.txt文件。
示例
|- resources
|- ham
|- ham.txt
|- spam
|- spam.txt
如您所见,我们还可以用它来检测垃圾邮件或非垃圾邮件。
当您将翻译文件存储在resources
目录外时,您必须指定路径。
$t->learn('YOUR_PATH_HERE');
每次您更改翻译文件时,您必须首先为它生成一个语言配置文件。这可能需要几秒钟。
use LanguageDetection\Trainer; $t = new Trainer(); $t->learn();
执行后删除这些几行,现在我们可以用我们自己的训练文本按语言分类文本。
常见问题解答
我该如何改进检测阶段?
要改进检测阶段,您必须使用更多的n-gram。但请注意,这将减慢脚本。我发现当您使用大约9,000个n-gram时(默认为310),检测阶段会更好。要做到这一点,请查看下面的代码
$t = new Trainer(); $t->setMaxNgrams(9000); $t->learn();
首先您必须训练它。现在您可以根据以前的方法对文本进行分类,但您必须指定您想使用的n-gram数量。
$ld = new Language(); $ld->setMaxNgrams(9000); // "grille pain" is french and means "toaster" in english var_dump($ld->detect('grille pain')->bestResults());
结果
class LanguageDetection\LanguageResult#5 (1) {
private $result =>
array(2) {
'fr' =>
double(0.91307037037037)
'en' =>
double(0.90623333333333)
}
}
如果语言文件非常大,检测过程会更慢吗?
不是的。训练器类将仅使用该语言的最佳310个n-gram。如果您不更改此数字或添加更多语言文件,它将不会影响性能。只有创建N-gram会更慢。然而,N-gram的创建只需进行一次。检测阶段只有在您尝试检测大量文本时才会受到影响。
总结:训练阶段会更慢,但检测阶段保持不变。
贡献
请随时贡献。任何帮助都受欢迎。
许可证
本项目根据MIT许可协议许可。