patrickschur / language-detection
PHP语言检测库。从给定的文本字符串中检测语言。
Requires
- php: ^7.4 || ^8.0
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^9.5.0
README
此库可以检测给定文本字符串的语言。它可以将给定的训练文本解析成多个不同语法的N-gram,并在PHP中构建数据库文件用于检测阶段。然后它可以使用在训练阶段生成的先前数据库检测给定文本的语言。此库包含用于训练和检测110种语言文本的文本样本。
目录
使用Composer安装
注意:此库需要多字节字符串扩展才能运行。
$ composer require patrickschur/language-detection
如何从3.y.z
升级到4.y.z
?
重要:仅适用于使用自定义目录并拥有自己翻译文件的用户。
从版本4.y.z
开始,我们已更新了资源文件。出于性能原因,我们现在使用PHP而不是JSON作为格式。这意味着想要使用4.y.z
且之前使用过3.y.z
的人,必须将他们的JSON文件升级为PHP。要升级资源文件,您必须再次生成语言配置文件。JSON文件此后将不再需要。
您可以使用以下命令在Linux下删除不必要的JSON文件。
rm resources/*/*.json
基本用法
为了正确检测语言,输入文本的长度应至少包含一些句子。
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
)
数组访问
您还可以直接将对象作为数组访问。
$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许可证条款的约束。