如何在 php-ml 上使用朴素贝叶斯将新样本添加到同一标签?

How add new samples to the same label using Naive Bayes on php-ml?

我是文本分类方面的新手,我正在尝试创建一些概念验证以使用 PHP 更好地理解 ML 的概念。 所以我得到了 this example,并且我尝试向 "reinforce" 我的标签(类别)之一添加一个新的小文本,在本例中为 Japan

<?php
include_once './vendor/autoload.php';
//source: https://www.softnix.co.th/2018/08/19/naive-bays-text-classification-with-php/
use Phpml\Classification\NaiveBayes;
use Phpml\FeatureExtraction\TokenCountVectorizer;
use Phpml\Tokenization\WhitespaceTokenizer;
use Phpml\Tokenization\WordTokenizer;
use Phpml\FeatureExtraction\TfIdfTransformer;

$arr_text = [
    "London bridge is falling down",
    "japan samurai Universal Studio spider man",
    "china beijing",
    "thai Chiangmai",
    "Universal Studio Hollywood",
    "2020 Olympic games"
];
$arr_label = [
    "London","Japan","China","Thailand","USA","Japan"
];

$tokenize = new WordTokenizer();
$vectorizer = new TokenCountVectorizer($tokenize);

$vectorizer->fit($arr_text);
$vocabulary = $vectorizer->getVocabulary();
$arr_transform = $arr_text;
$vectorizer->transform($arr_transform);

$transformer = new TfIdfTransformer($arr_transform);
$transformer->transform($arr_transform);

$classifier = new NaiveBayes();
$classifier->train($arr_transform, $arr_label);

$arr_testset = [
    'Hello Chiangmai I am Siam',
    'I want to go Universal Studio',
    'I want to go Universal Studio because I want to watch spider man',
    'Sonic in 2020'
];

$vectorizer->transform($arr_testset);
$transformer->transform($arr_testset);
$result = $classifier->predict($arr_testset);
var_dump($result);

问题是,在标签数组上再次添加日本后,结果是:

array (size=4)
  0 => string 'Japan' (length=5)
  1 => string 'Japan' (length=5)
  2 => string 'Japan' (length=5)
  3 => string 'Japan' (length=5)

但我期待:

array (size=4)
  0 => string 'Thailand' (length=8)
  1 => string 'USA' (length=3)
  2 => string 'Japan' (length=5)
  3 => string 'Japan' (length=5)

那么,如何将新样本添加到同一个标签?

你的训练数据集有两个问题:

  1. 太小了,代表性不足
  2. 与其他标签相比,您在训练 Japan 标签时提供了两倍的数据

因此,Japan label 的模型是在两个完全不相关且不重复的句子上训练的。其他标签仅在一个短句上进行训练。

这导致 underfitted Japan 标签模型具有来自训练数据的 "not learned enough",并且无法正确地对训练数据建模,也无法推广到新数据。换句话说,它太笼统了,几乎任何句子都会触发。 Rest 标签的模型是 overfitted - 它们对训练数据的建模太好了,只会触发那些非常接近训练集数据的句子。

所以 Japan 标签几乎可以捕获任何句子。在你的标签列表的开头,它会在列表中它后面的任何标签发生变化以评估一个句子之前捕获所有句子。当然,您可以在列表末尾移动 Japan 个标签,但更好的解决方案是 - 扩大所有标签的训练数据集。

您还可以评估过度拟合的标签模型效果 - 例如尝试添加到您的测试集 "London bridge down" 和 "London down" 句子 - 第一个给你 London,第二个 - Japan,因为第一个句子足够接近 London 标签的句子训练集,而第二个 - 不是。

所以一直按照这种方式添加训练集数据,让你的训练集足够大,足够有代表性。