>  기사  >  백엔드 개발  >  PHP의 기계 학습을 위한 Naive Bayes 알고리즘에 대한 자세한 설명

PHP의 기계 학습을 위한 Naive Bayes 알고리즘에 대한 자세한 설명

jacklove
jacklove원래의
2018-07-06 17:58:031715검색

이 글에서는 주로 PHP의 머신러닝을 위한 Naive Bayes 알고리즘을 소개합니다. Naive Bayes 알고리즘의 개념, 원리, PHP 구현 기술을 예제 형식으로 자세히 분석합니다. 이 기사에서는 PHP가 기계 학습을 위한 Naive Bayes 알고리즘을 구현하는 방법을 설명합니다. 참고할 수 있도록 모든 사람과 공유하세요. 세부 사항은 다음과 같습니다.

머신 러닝은 우리 삶 곳곳에 자리잡고 있습니다. 집에 있을 때 작동하는 온도 조절 장치부터 스마트 자동차와 주머니에 있는 스마트폰에 이르기까지 모든 것이 있습니다. 머신러닝은 어디에나 있는 것처럼 보이며 탐구할 가치가 있는 영역입니다. 그런데 머신러닝이란 무엇일까요? 일반적으로 머신러닝은 시스템이 지속적으로 새로운 문제를 학습하고 예측할 수 있도록 하는 것입니다. 쇼핑 품목의 간단한 예측부터 복잡한 디지털 비서 예측까지.

이 글에서는 Naive Bayes 알고리즘 Clasifier를 클래스로 소개하겠습니다. 이는 구현하기 쉽고 만족스러운 결과를 제공하는 간단한 알고리즘입니다. 하지만 이 알고리즘을 이해하려면 약간의 통계적 지식이 필요합니다. 기사의 마지막 부분에서는 몇 가지 예제 코드를 확인하고 직접 기계 학습을 시도해 볼 수도 있습니다.

시작하기 그렇다면 이 분류기는 어떤 기능을 수행하는 데 사용됩니까? 실제로 이는 주어진 진술이 긍정적인지 부정적인지를 판단하는 데 주로 사용됩니다. 예를 들어, "Symfony가 최고입니다"는 긍정적인 설명이고 "No Symfony is bad"는 부정적인 설명입니다. 따라서 명령문을 제공한 후 이 분류자가 새로운 규칙을 제공하지 않고 명령문 유형을 반환하기를 원합니다.

Classifier를 같은 이름의 클래스로 명명하고 추측 방법을 포함했습니다. 이 메소드는 명령문을 입력으로 받아들이고 명령문이 긍정적인지 부정적인지를 반환합니다. 클래스는 다음과 같습니다.

class Classifier
{
 public function guess($statement)
 {}
}

나는 반환 값에 문자열 대신 열거형 클래스를 사용하는 것을 선호합니다. 이 열거형 유형의 클래스 이름을 Type으로 지정했으며 여기에는 POSITIVE와 NEGATIVE라는 두 개의 상수가 포함되어 있습니다. 이 두 상수는 추측 메소드의 반환 값으로 사용됩니다.

class Type
{
 const POSITIVE = 'positive';
 const NEGATIVE = 'negative';
}

초기화 작업이 완료되었으며 다음 단계는 예측을 위한 알고리즘을 작성하는 것입니다.

Naive Bayes

Naive Bayes 알고리즘은 훈련 세트를 기반으로 작동하며 이 훈련 세트를 기반으로 해당 예측을 수행합니다. 이 알고리즘은 간단한 통계와 약간의 수학을 사용하여 결과를 계산합니다. 예를 들어 훈련 세트는 다음 4개의 텍스트로 구성됩니다.


# 🎜🎜# PhpStorm은 훌륭합니다일타르가 불평을 많이 한다
语句 类型
심포니가 최고야 긍정적# 🎜🎜#
긍정적# 🎜🎜 #
부정적
심포니도 나쁘지 않아요 부정적


如果给定语句是“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 방법에 대한 설명

PHP 구현 방법에 대한 자세한 설명 조셉 링 문제

위 내용은 PHP의 기계 학습을 위한 Naive Bayes 알고리즘에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.