PHP での機械学習のための Naive Bayes アルゴリズムの詳細な説明

jacklove
リリース: 2023-04-02 19:18:02
オリジナル
1628 人が閲覧しました

この記事では主に、PHP での機械学習のためのナイーブ ベイズ アルゴリズムを紹介します。ナイーブ ベイズ アルゴリズムの概念、原理、PHP 実装テクニックを例の形式で詳細に分析します。必要な友人は参考にしてください。

この記事の例では、PHP で機械学習を実装するための Naive Bayes アルゴリズムについて説明します。参考のために皆さんと共有してください。詳細は次のとおりです:

機械学習は私たちの生活の至る所に浸透しています。在宅時に作動するサーモスタットから、スマートカーやポケットの中にあるスマートフォンに至るまで、あらゆるものが対象となります。機械学習はどこにでもあるようで、探索する価値のある分野です。しかし、機械学習とは何でしょうか?一般に、機械学習とは、システムが継続的に学習し、新しい問題を予測できるようにすることです。ショッピングアイテムの単純な予測から複雑なデジタルアシスタントの予測まで。

この記事では、Naive Bayes アルゴリズム Clasifier をクラスとして紹介します。これは実装が簡単で満足のいく結果が得られるシンプルなアルゴリズムです。ただし、このアルゴリズムを理解するには、少しの統計知識が必要です。記事の最後の部分では、いくつかのサンプルコードを参照し、独自の機械学習を試すこともできます。

はじめに

それでは、この分類子はどのような機能を実現するために使用されるのでしょうか?実際、これは主に、特定のステートメントが肯定的か否定的かを判断するために使用されます。たとえば、「Symfony は最高です」は肯定的な発言であり、「Symfony は悪くない」は否定的な発言です。したがって、ステートメントを与えた後、この Classifier が新しいルールを与えずにステートメントの種類を返すようにしたいと考えています。

Classifier に同じ名前のクラスを付け、推測メソッドを含めました。このメソッドはステートメントを入力として受け入れ、ステートメントが肯定的であるか否定的であるかを返します。クラスは次のようになります。

class Classifier
{
 public function guess($statement)
 {}
}
ログイン後にコピー

私は戻り値に文字列の代わりに列挙型クラスを使用することを好みます。この列挙型のクラスに Type という名前を付け、これには 2 つの定数 (POSITIVE と NEGATIVE の 1 つ) が含まれています。これら 2 つの定数は、guess メソッドの戻り値として使用されます。

class Type
{
 const POSITIVE = 'positive';
 const NEGATIVE = 'negative';
}
ログイン後にコピー

初期化作業は完了しました。次のステップは、予測用のアルゴリズムを作成することです。

Naive Bayes

Naive Bayes アルゴリズムはトレーニング セットに基づいて機能し、このトレーニング セットに基づいて対応する予測を行います。このアルゴリズムは、単純な統計と少しの数学を使用して結果を計算します。たとえば、トレーニング セットは次の 4 つのテキストで構成されます:

#PhpStorm は素晴らしいですIltar はよく不満を言います
#ステートメントタイプ
Symfony は最高です肯定的
ポジティブ
否定的
Symfonyが悪いわけではありません ###ネガティブ########################


如果给定语句是“Symfony is the best”,那么你可以说这个语句是积极地。你平常也会根据之前学习到的相应知识做出对应的决定,朴素贝叶斯算法也是同样的道理:它根据之前的训练集来决定哪一个类型更加相近。

学习

在这个算法正式工作之前,它需要大量的历史信息作为训练集。它需要知道两件事:每一个类型对应的词产生了多少次和每一个语句对应的类型是什么。我们在实施的时候会将这两种信息存储在两个数组当中。一个数组包含每一类型的词语统计,另一个数组包含每一个类型的语句统计。所有的其他信息都可以从这两个数组中聚合。代码就像下面的一样:

function learn($statement, $type)
{
 $words = $this->getWords($statement);
 foreach ($words as $word) {
 if (!isset($this->words[$type][$word])) {
  $this->words[$type][$word] = 0;
 }
 $this->words[$type][$word]++; // 增加类型的词语统计
 }
 $this->documents[$type]++; // 增加类型的语句统计
}
ログイン後にコピー

有了这个集合以后,现在这个算法就可以根据历史数据接受预测训练了。

定义

为了解释这个算法是如何工作的,几个定义是必要的。首先,让我们定义一下输入的语句是给定类型中的一个的概率。这个将会表示为P(Type)。它是以已知类型的数据的类型作为分子,还有整个训练集的数据数量作为分母来得出的。一个数据就是整个训练集中的一个。到现在为止,这个方法可以将会命名为totalP,像下面这样:

function totalP($type)
{
 return ($this->documents[$type] + 1) / (array_sum($this->documents) + 1);
}
ログイン後にコピー

请注意,在这里分子和分母都加了1。这是为了避免分子和分母都为0的情况。

根据上面的训练集的例子,积极和消极的类型都会得出0.6的概率。每中类型的数据都是2个,一共是4个数据所以就是(2+1)/(4+1)。

第二个要定义的是对于给定的一个词是属于哪个确定类型的概率。这个我们定义成P(word,Type)。首先我们要得到一个词在训练集中给出确定类型出现的次数,然后用这个结果来除以整个给定类型数据的词数。这个方法我们定义为p:

function p($word, $type)
{
 $count = isset($this->words[$type][$word]) ? $this->words[$type][$word] : 0;
 return ($count + 1) / (array_sum($this->words[$type]) + 1);
}
ログイン後にコピー

在本次的训练集中,“is”的是积极类型的概率为0.375。这个词在整个积极的数据中的7个词中占了两次,所以结果就是(2+1)/(7+1)。

最后,这个算法应该只关心关键词而忽略其他的因素。一个简单的方法就是将给定的字符串中的单词分离出来:

function getWords($string)
{
 return preg_split('/\s+/', preg_replace('/[^A-Za-z0-9\s]/', '', strtolower($string)));
}
ログイン後にコピー

准备工作都做好了,开始真正实施我们的计划吧!

预测

为了预测语句的类型,这个算法应该计算所给定语句的两个类型的概率。像上面一样,我们定义一个P(Type,sentence)。得出概率高的类型将会是Classifier类中算法返回的结果。

为了计算P(Type,sentence),算法当中将用到贝叶斯定理。算法像这样被定义:P(Type,sentence)= P(Type)* P(sentence,Type)/ P(sentence)。这意味着给定语句的类型概率和给定类型语句概率除以语句的概率的结果是相同的。

那么算法在计算每一个相同语句的P(Tyoe,sentence),P(sentence)是保持一样的。这意味着算法就可以省略其他因素,我们只需要关心最高的概率而不是实际的值。计算就像这样:P(Type,sentence) = P(Type)* P(sentence,Type)。

最后,为了计算P(sentence,Type),我们可以为语句中的每个词添加一条链式规则。所以在一条语句中如果有n个词的话,它将会和P(word_1,Type)* P(word_2,Type)* P(word_3,Type)* .....*P(word_n,Type)是一样的。每一个词计算结果的概率使用了我们前面看到的定义。

好了,所有的都说完了,是时候在php中实际操作一下了:

function guess($statement)
{
 $words = $this->getWords($statement); // 得到单词
 $best_likelihood = 0;
 $best_type = null;
 foreach ($this->types as $type) {
 $likelihood = $this->pTotal($type); //计算 P(Type)
 foreach ($words as $word) {
  $likelihood *= $this->p($word, $type); // 计算 P(word, Type)
 }
 if ($likelihood > $best_likelihood) {
  $best_likelihood = $likelihood;
  $best_type = $type;
 }
 }
 return $best_type;
}
ログイン後にコピー

这就是所有的工作,现在算法可以预测语句的类型了。你要做的就是让你的算法开始学习:

$classifier = new Classifier();
$classifier->learn('Symfony is the best', Type::POSITIVE);
$classifier->learn('PhpStorm is great', Type::POSITIVE);
$classifier->learn('Iltar complains a lot', Type::NEGATIVE);
$classifier->learn('No Symfony is bad', Type::NEGATIVE);
var_dump($classifier->guess('Symfony is great')); // string(8) "positive"
var_dump($classifier->guess('I complain a lot')); // string(8) "negative"
ログイン後にコピー

所有的代码我已经上传到了GIT上,https://github.com/yannickl88/blog-articles/blob/master/src/machine-learning-naive-bayes/Classifier.php

github上完整php代码如下:

 [], Type::NEGATIVE => []];
 private $documents = [Type::POSITIVE => 0, Type::NEGATIVE => 0];
 public function guess($statement)
 {
 $words  = $this->getWords($statement); // get the words
 $best_likelihood = 0;
 $best_type = null;
 foreach ($this->types as $type) {
  $likelihood = $this->pTotal($type); // calculate P(Type)
  foreach ($words as $word) {
  $likelihood *= $this->p($word, $type); // calculate P(word, Type)
  }
  if ($likelihood > $best_likelihood) {
  $best_likelihood = $likelihood;
  $best_type = $type;
  }
 }
 return $best_type;
 }
 public function learn($statement, $type)
 {
 $words = $this->getWords($statement);
 foreach ($words as $word) {
  if (!isset($this->words[$type][$word])) {
  $this->words[$type][$word] = 0;
  }
  $this->words[$type][$word]++; // increment the word count for the type
 }
 $this->documents[$type]++; // increment the document count for the type
 }
 public function p($word, $type)
 {
 $count = 0;
 if (isset($this->words[$type][$word])) {
  $count = $this->words[$type][$word];
 }
 return ($count + 1) / (array_sum($this->words[$type]) + 1);
 }
 public function pTotal($type)
 {
 return ($this->documents[$type] + 1) / (array_sum($this->documents) + 1);
 }
 public function getWords($string)
 {
 return preg_split('/\s+/', preg_replace('/[^A-Za-z0-9\s]/', '', strtolower($string)));
 }
}
$classifier = new Classifier();
$classifier->learn('Symfony is the best', Type::POSITIVE);
$classifier->learn('PhpStorm is great', Type::POSITIVE);
$classifier->learn('Iltar complains a lot', Type::NEGATIVE);
$classifier->learn('No Symfony is bad', Type::NEGATIVE);
var_dump($classifier->guess('Symfony is great')); // string(8) "positive"
var_dump($classifier->guess('I complain a lot')); // string(8) "negative"
ログイン後にコピー

结束语

尽管我们只进行了很少的训练,但是算法还是应该能给出相对精确的结果。在真实环境,你可以让机器学习成百上千的记录,这样就可以给出更精准的结果。你可以下载查看这篇文章(英文):朴素贝叶斯已经被证明可以给出情绪统计的结果。

而且,朴素贝叶斯不仅仅可以运用到文本类的应用。希望通过这篇文章可以拉近你和机器学习的一点点距离。

原文地址:https://stovepipe.systems/post/machine-learning-naive-bayes

興味があるかもしれない記事:

PHP での単一リンク リストの反転操作の例の説明

PHP 実装 2 つの順序配列をマージする方法の説明

#ジョセフ リング問題を PHP で実装する方法の詳細説明

##

以上がPHP での機械学習のための Naive Bayes アルゴリズムの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!