Gaussian Naive Bayes อธิบาย

Gaussian Naive Bayes อธิบาย

โหนดต้นทาง: 2021431

Gaussian Naive Bayes อธิบาย
ขอบเขตการตัดสินใจของลักษณนามว่า Bayes ไร้เดียงสาแบบเกาส์เซียน รูปภาพโดยผู้เขียน

 

ฉันคิดว่านี่เป็นเรื่องคลาสสิกในช่วงเริ่มต้นของอาชีพด้านวิทยาศาสตร์ข้อมูลแต่ละอาชีพ: Naive Bayes ลักษณนาม. หรือฉันควรจะพูดว่า ครอบครัว ของลักษณนามว่า Bayes ที่ไร้เดียงสา เนื่องจากมีหลายรสชาติ ตัวอย่างเช่น มี Bayes ไร้เดียงสาหลายชื่อ, Bayes ไร้เดียงสาของ Bernoulli และตัวแยกประเภท Bayes ไร้เดียงสาแบบ Gaussian ซึ่งแต่ละอย่างแตกต่างกันในรายละเอียดเล็ก ๆ น้อย ๆ อย่างที่เราจะค้นพบ อัลกอริทึมไร้เดียงสาของ Bayes นั้นค่อนข้างเรียบง่ายในการออกแบบ แต่ได้รับการพิสูจน์แล้วว่ามีประโยชน์ในสถานการณ์จริงที่ซับซ้อนมากมาย

ในบทความนี้ คุณสามารถเรียนรู้

  • ตัวแยกประเภท Bayes ที่ไร้เดียงสาทำงานอย่างไร
  • เหตุใดจึงเหมาะสมที่จะกำหนดพวกเขาในแบบที่พวกเขาเป็นและ
  • วิธีนำไปใช้ใน Python โดยใช้ NumPy

คุณสามารถหารหัสได้ที่ Github ของฉัน.

การตรวจสอบไพรเมอร์ของฉันเกี่ยวกับสถิติแบบเบย์อาจช่วยได้เล็กน้อย บทนำอย่างนุ่มนวลสำหรับการอนุมานแบบเบย์ เพื่อให้คุ้นเคยกับสูตรเบส์ เนื่องจากเราจะใช้ตัวแยกประเภทในลักษณะที่สอดคล้องกับการเรียนรู้ของ scikit จึงควรตรวจสอบบทความของฉันด้วย สร้างการถดถอยแบบ scikit-learn ของคุณเอง. อย่างไรก็ตาม ค่าใช้จ่ายในการเรียนรู้ของ scikit ค่อนข้างน้อย และคุณควรจะทำตามต่อไปได้

เราจะเริ่มสำรวจทฤษฎีที่เรียบง่ายอย่างน่าอัศจรรย์ของการจำแนกประเภทแบบไร้เดียงสาของเบส์ แล้วจึงหันไปสู่การนำไปใช้

เราสนใจอะไรมากเมื่อจำแนกประเภท? เรากำลังทำอะไรอยู่ อินพุตและเอาต์พุตคืออะไร คำตอบนั้นง่าย:

จากจุดข้อมูล x ความน่าจะเป็นที่ x เป็นของคลาส c คืออะไร

นั่นคือทั้งหมดที่เราต้องการตอบด้วย ใด การจัดหมวดหมู่. คุณสามารถจำลองคำสั่งนี้เป็นความน่าจะเป็นแบบมีเงื่อนไขได้โดยตรง: p(c|x).

เช่น ถ้ามี

  • เรียน 3 ค₁ค₂ค₃และ
  • ประกอบด้วย 2 คุณสมบัติ x₁x₂,

ผลลัพธ์ของตัวแยกประเภทอาจเป็นดังนี้ p(ค₁|x₁x₂)=0.3, p(ค₂|x₁x₂)=0.5 และ p(ค₃|x₁x₂)=0.2. หากเราสนใจป้ายกำกับเดียวเป็นผลลัพธ์ เราจะเลือกป้ายกำกับที่มีความน่าจะเป็นสูงสุด เช่น ค₂ ด้วยความน่าจะเป็น 50% ที่นี่

ลักษณนาม Bayes ที่ไร้เดียงสาพยายามคำนวณความน่าจะเป็นเหล่านี้โดยตรง

ไร้เดียงสา Bayes

ตกลงเพื่อให้จุดข้อมูล xเราต้องการคำนวณ p(c|x) สำหรับทุกชั้นเรียน แล้วส่งออก c ด้วยความเป็นไปได้สูงสุด ในสูตรคุณมักจะเห็นสิ่งนี้เป็น

 

Gaussian Naive Bayes อธิบาย
รูปภาพโดยผู้เขียน

 

หมายเหตุ แม็กซ์ p(c|x) ส่งกลับค่าความน่าจะเป็นสูงสุดในขณะที่ argmax p(c|x) ส่งคืนค่า c ด้วยความเป็นไปได้สูงสุดนี้

แต่ก่อนที่เราจะปรับให้เหมาะสม p(c|x) เราต้องสามารถคำนวณได้ สำหรับสิ่งนี้เราใช้ ทฤษฎีบทของเบย์:

 

Gaussian Naive Bayes อธิบาย
ทฤษฎีบทเบส์ รูปภาพโดยผู้เขียน

 

นี่เป็นส่วนหนึ่งของ Bayes ของ Bayes ที่ไร้เดียงสา แต่ตอนนี้เรามีปัญหาดังต่อไปนี้: คืออะไร p(x|c) and p(c)?

นี่คือความหมายของการฝึกลักษณนามว่า Bayes ที่ไร้เดียงสา

การฝึกอบรม

เพื่อแสดงทุกอย่าง ให้เราใช้ชุดข้อมูลของเล่นกับ คุณสมบัติที่แท้จริงสองประการ x₁x₂และ สามชั้น ค₁ค₂ค₃ ในต่อไปนี้

 

Gaussian Naive Bayes อธิบาย
ข้อมูลเป็นภาพ รูปภาพโดยผู้เขียน

 

คุณสามารถสร้างชุดข้อมูลที่แน่นอนนี้ได้ทาง

from sklearn.datasets import make_blobs X, y = make_blobs(n_samples=20, centers=[(0,0), (5,5), (-5, 5)], random_state=0)

ให้เราเริ่มต้นด้วย ความน่าจะเป็นของชั้นเรียน p(c) ความน่าจะเป็นที่บางชั้น c ถูกสังเกตในชุดข้อมูลที่มีป้ายกำกับ วิธีที่ง่ายที่สุดในการประมาณนี้คือการคำนวณความถี่สัมพัทธ์ของคลาสและใช้เป็นค่าความน่าจะเป็น เราสามารถใช้ชุดข้อมูลของเราเพื่อดูว่าสิ่งนี้หมายความว่าอย่างไร

มี 7 จาก 20 คะแนนติดป้ายชื่อชั้น ค₁ (สีน้ำเงิน) ในชุดข้อมูล ดังนั้นเราจึงพูดว่า p(ค₁)=7/20. เรามี 7 คะแนนสำหรับชั้นเรียน ค₂ (สีแดง) ด้วย เพราะฉะนั้นเราจึงกำหนด p(ค₂)=7/20. ชั้นสุดท้าย ค₃ (สีเหลือง) มีเพียง 6 คะแนนเท่านั้น p(ค₃)=6/20.

การคำนวณความน่าจะเป็นของคลาสอย่างง่ายนี้คล้ายกับแนวทางความเป็นไปได้สูงสุด อย่างไรก็ตาม คุณสามารถใช้อย่างอื่นได้เช่นกัน ก่อน การกระจายถ้าคุณต้องการ ตัวอย่างเช่น หากคุณทราบว่าชุดข้อมูลนี้ไม่ได้เป็นตัวแทนของประชากรจริงเนื่องจากคลาส ค₃ ควรปรากฏใน 50% ของกรณี จากนั้นคุณตั้งค่า p(ค₁)=0.25, p(ค₂)=0.25 และ p(ค₃)=0.5. อะไรก็ตามที่ช่วยให้คุณปรับปรุงประสิทธิภาพของชุดทดสอบ

ตอนนี้เราหันไป ความเป็นไปได้ p(x|c)=p(x₁x₂|c). วิธีหนึ่งในการคำนวณความเป็นไปได้นี้คือการกรองชุดข้อมูลสำหรับตัวอย่างที่มีป้ายกำกับ จากนั้นลองหาการแจกแจง (เช่น Gaussian 2 มิติ) ที่รวบรวมคุณลักษณะต่างๆ x₁x₂.

น่าเสียดายที่โดยปกติแล้ว เรามีตัวอย่างต่อคลาสไม่เพียงพอที่จะประเมินความเป็นไปได้อย่างเหมาะสม

เพื่อให้สามารถสร้างโมเดลที่แข็งแกร่งขึ้นได้ เราจึงสร้าง สมมติฐานที่ไร้เดียงสา ซึ่งคุณสมบัติ x₁x₂ เป็น อิสระแบบสุ่มได้รับ c. นี่เป็นเพียงวิธีง่ายๆ ในการทำให้คณิตศาสตร์ง่ายขึ้น

 

Gaussian Naive Bayes อธิบาย
รูปภาพโดยผู้เขียน

 

สำหรับทุกชั้นเรียน c. นี่คือจุดที่ ไร้เดียงสา ส่วนหนึ่งของความไร้เดียงสา Bayes มาจากเพราะสมการนี้ไม่ถือเป็นเรื่องทั่วไป ถึงกระนั้น Bayes ที่ไร้เดียงสาก็ให้ผลลัพธ์ที่ดีบางครั้งก็โดดเด่นในทางปฏิบัติ โดยเฉพาะอย่างยิ่งสำหรับปัญหา NLP ด้วยคุณสมบัติถุงคำ Bayes ไร้เดียงสาแบบพหุนาม

อาร์กิวเมนต์ที่ระบุข้างต้นจะเหมือนกันสำหรับลักษณนามว่า Bayes ที่ไร้เดียงสาใดๆ ที่คุณพบ ตอนนี้มันขึ้นอยู่กับว่าคุณสร้างแบบจำลองอย่างไร p(x₁|c₁), p(x₁|c₁), p(x₁|c₂), p(x₂|c₂), p(x₁|c₃) และ  พี(x₂|c₃).

หากคุณลักษณะของคุณเป็น 0 และ 1 เท่านั้น คุณสามารถใช้ การกระจายเบอร์นูลลี. ถ้าเป็นจำนวนเต็ม ก การกระจายพหุนาม. อย่างไรก็ตาม เรามีค่าคุณลักษณะจริงและตัดสินใจเลือก เสียน การกระจายดังนั้นชื่อ Gaussian naive Bayes เราถือว่ารูปแบบต่อไปนี้

 

Gaussian Naive Bayes อธิบาย
รูปภาพโดยผู้เขียน

 

ที่ไหน μᵢ,ⱼ เป็นค่าเฉลี่ยและ ซิก,ⱼ คือค่าเบี่ยงเบนมาตรฐานที่เราต้องประมาณจากข้อมูล ซึ่งหมายความว่าเราได้รับหนึ่งค่าเฉลี่ยสำหรับแต่ละคุณสมบัติ i ควบคู่กับชั้นเรียน คⱼ, ในกรณีของเรา 2*3=6 หมายถึง เช่นเดียวกับส่วนเบี่ยงเบนมาตรฐาน สิ่งนี้เรียกร้องให้เป็นตัวอย่าง

ลองประมาณกันดูครับ ไมโคร₂,₁ และ  ซิ₂,₁. เพราะ j=1 เราสนใจแต่ในชั้นเรียนเท่านั้น ค₁ให้เราเก็บตัวอย่างที่มีฉลากนี้เท่านั้น เหลือตัวอย่างต่อไปนี้:

# samples with label = c_1 array([[ 0.14404357, 1.45427351], [ 0.97873798, 2.2408932 ], [ 1.86755799, -0.97727788], [ 1.76405235, 0.40015721], [ 0.76103773, 0.12167502], [-0.10321885, 0.4105985 ], [ 0.95008842, -0.15135721]])

ตอนนี้ เนื่องจาก i=2 เราต้องพิจารณาคอลัมน์ที่สองเท่านั้น μ₂,₁ คือค่าเฉลี่ย และ ซิ₂,₁ ส่วนเบี่ยงเบนมาตรฐานสำหรับคอลัมน์นี้ เช่น μ₂,₁ = 0.49985176 และ ซิ₂,₁ = 0.9789976.

ตัวเลขเหล่านี้สมเหตุสมผลถ้าคุณดูแผนการกระจายจากด้านบนอีกครั้ง คุณสมบัติ x₂ ของกลุ่มตัวอย่างจากชั้นเรียน ค₁ อยู่ที่ประมาณ 0.5 ดังที่คุณเห็นจากภาพ

ตอนนี้เราคำนวณค่านี้สำหรับชุดค่าผสมอีก XNUMX ชุดและทำเสร็จแล้ว!

ใน Python คุณสามารถทำได้ดังนี้:

from sklearn.datasets import make_blobs
import numpy as np # Create the data. The classes are c_1=0, c_2=1 and c_3=2.
X, y = make_blobs( n_samples=20, centers=[(0, 0), (5, 5), (-5, 5)], random_state=0
) # The class probabilities.
# np.bincounts counts the occurence of each label.
prior = np.bincount(y) / len(y) # np.where(y==i) returns all indices where the y==i.
# This is the filtering step.
means = np.array([X[np.where(y == i)].mean(axis=0) for i in range(3)])
stds = np.array([X[np.where(y == i)].std(axis=0) for i in range(3)])

พวกเราได้รับ

# priors
array([0.35, 0.35, 0.3 ])
# means array([[ 0.90889988, 0.49985176], [ 5.4111385 , 4.6491892 ], [-4.7841679 , 5.15385848]])
# stds
array([[0.6853714 , 0.9789976 ], [1.40218915, 0.67078568], [0.88192625, 1.12879666]])

นี่เป็นผลมาจากการฝึกลักษณนามว่า Bayes ไร้เดียงสาแบบเกาส์เซียน

การทำนายผล

สูตรการทำนายที่สมบูรณ์คือ

 

Gaussian Naive Bayes อธิบาย
รูปภาพโดยผู้เขียน

 

สมมติว่าเป็นจุดข้อมูลใหม่ x*=(-2, 5) เข้ามา

 

Gaussian Naive Bayes อธิบาย
รูปภาพโดยผู้เขียน

 

หากต้องการดูว่าอยู่ในคลาสใดให้เราคำนวณ p(c|x*) สำหรับทุกชั้นเรียน จากภาพน่าจะเป็นของคลาส ค₃ = 2 แต่มาดูกัน ให้เราละเว้นตัวส่วน p(x) เป็นเวลาหนึ่งวินาที การใช้ลูปต่อไปนี้คำนวณผู้เสนอชื่อสำหรับ j = 1, 2, 3.

x_new = np.array([-2, 5]) for j in range(3): print( f"Probability for class {j}: {(1/np.sqrt(2*np.pi*stds[j]**2)*np.exp(-0.5*((x_new-means[j])/stds[j])**2)).prod()*p[j]:.12f}" )

พวกเราได้รับ

Probability for class 0: 0.000000000263
Probability for class 1: 0.000000044359
Probability for class 2: 0.000325643718

แน่นอนเหล่านี้ ความน่าจะเป็น (เราไม่ควรเรียกแบบนั้น) อย่าบวกกันเพราะเราไม่สนใจตัวส่วน อย่างไรก็ตาม นี่ไม่ใช่ปัญหาเนื่องจากเราสามารถนำความน่าจะเป็นที่ไม่ปกติเหล่านี้มาหารด้วยผลรวม จากนั้นพวกมันจะรวมกันเป็นหนึ่ง ดังนั้น หารค่าทั้งสามนี้ด้วยผลรวมของค่าประมาณ 0.00032569 เราจะได้

 

Gaussian Naive Bayes อธิบาย
รูปภาพโดยผู้เขียน

 

ผู้ชนะที่ชัดเจนตามที่เราคาดไว้ ตอนนี้ให้เราดำเนินการ!

การใช้งานนี้ไม่ค่อยมีประสิทธิภาพ ไม่มีความเสถียรเชิงตัวเลข แต่ให้บริการเพื่อวัตถุประสงค์ทางการศึกษาเท่านั้น เราได้พูดคุยกันถึงหลายสิ่งหลายอย่าง ดังนั้นตอนนี้ควรติดตามกันโดยง่าย คุณสามารถละเว้นทั้งหมด check ฟังก์ชั่นหรืออ่านบทความของฉัน สร้าง scikit-learn ของคุณเอง หากคุณสนใจในสิ่งที่พวกเขาทำ

โปรดทราบว่าฉันใช้ไฟล์ predict_proba วิธีแรกในการคำนวณความน่าจะเป็น วิธีการ predict เพียงเรียกวิธีนี้และส่งกลับดัชนี (=คลาส) ด้วยความน่าจะเป็นสูงสุดโดยใช้ฟังก์ชัน argmax (อีกแล้ว!) ชั้นเรียนรอชั้นเรียนตั้งแต่ 0 ถึง k-1 โดยที่ k คือจำนวนชั้นเรียน

import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.utils.validation import check_X_y, check_array, check_is_fitted class GaussianNaiveBayesClassifier(BaseEstimator, ClassifierMixin): def fit(self, X, y): X, y = check_X_y(X, y) self.priors_ = np.bincount(y) / len(y) self.n_classes_ = np.max(y) + 1 self.means_ = np.array( [X[np.where(y == i)].mean(axis=0) for i in range(self.n_classes_)] ) self.stds_ = np.array( [X[np.where(y == i)].std(axis=0) for i in range(self.n_classes_)] ) return self def predict_proba(self, X): check_is_fitted(self) X = check_array(X) res = [] for i in range(len(X)): probas = [] for j in range(self.n_classes_): probas.append( ( 1 / np.sqrt(2 * np.pi * self.stds_[j] ** 2) * np.exp(-0.5 * ((X[i] - self.means_[j]) / self.stds_[j]) ** 2) ).prod() * self.priors_[j] ) probas = np.array(probas) res.append(probas / probas.sum()) return np.array(res) def predict(self, X): check_is_fitted(self) X = check_array(X) res = self.predict_proba(X) return res.argmax(axis=1)

การทดสอบการใช้งาน

แม้ว่าโค้ดจะค่อนข้างสั้น แต่ก็ยังยาวเกินไปที่จะแน่ใจได้เต็มปากว่าเราไม่ได้ทำผิดพลาดใดๆ ดังนั้น ให้เราตรวจสอบว่าค่าโดยสารเป็นอย่างไรเมื่อเทียบกับ ลักษณนาม GaussianNB scikit-learn.

my_gauss = GaussianNaiveBayesClassifier()
my_gauss.fit(X, y)
my_gauss.predict_proba([[-2, 5], [0,0], [6, -0.3]])

เอาท์พุท

array([[8.06313823e-07, 1.36201957e-04, 9.99862992e-01], [1.00000000e+00, 4.23258691e-14, 1.92051255e-11], [4.30879705e-01, 5.69120295e-01, 9.66618838e-27]])

การทำนายโดยใช้ predict วิธีการคือ

# my_gauss.predict([[-2, 5], [0,0], [6, -0.3]])
array([2, 0, 1])

ตอนนี้ให้เราใช้ scikit-learn โยนรหัสบางอย่าง

from sklearn.naive_bayes import GaussianNB gnb = GaussianNB()
gnb.fit(X, y)
gnb.predict_proba([[-2, 5], [0,0], [6, -0.3]])

อัตราผลตอบแทน

array([[8.06314158e-07, 1.36201959e-04, 9.99862992e-01], [1.00000000e+00, 4.23259111e-14, 1.92051343e-11], [4.30879698e-01, 5.69120302e-01, 9.66619630e-27]])

ตัวเลขดูคล้ายกับตัวเลขในลักษณนามของเรา แต่จะต่างกันเล็กน้อยในตัวเลขที่แสดงสองสามตัวสุดท้าย เราทำอะไรผิดหรือเปล่า? No. เวอร์ชัน scikit-learn เพียงแค่ใช้ไฮเปอร์พารามิเตอร์อื่นเท่านั้น var_smoothing=1e-09 . หากเราตั้งค่านี้เป็น เป็นศูนย์เราได้หมายเลขของเราพอดี สมบูรณ์แบบ!

ดูที่ขอบเขตการตัดสินใจของตัวแยกประเภทของเรา ฉันได้ทำเครื่องหมายสามจุดที่เราใช้ในการทดสอบด้วย จุดหนึ่งที่อยู่ใกล้ชายแดนมีโอกาสเพียง 56.9% เท่านั้นที่จะเป็นชั้นสีแดง ดังที่คุณเห็นจาก predict_proba เอาต์พุต อีกสองจุดถูกจัดประเภทด้วยความมั่นใจที่สูงกว่ามาก

 

Gaussian Naive Bayes อธิบาย

การตัดสินภูมิภาคด้วย 3 คะแนนใหม่ รูปภาพโดยผู้เขียน

 

ในบทความนี้ เราได้เรียนรู้ว่าตัวจําแนกแบบ Gaussian naive Bayes ทำงานอย่างไร และให้สัญชาตญาณว่าเหตุใดจึงได้รับการออกแบบในลักษณะนั้น ซึ่งเป็นแนวทางโดยตรงในการสร้างแบบจำลองความน่าจะเป็นที่น่าสนใจ เปรียบเทียบสิ่งนี้กับการถดถอยโลจิสติก: ที่นั่น ความน่าจะเป็นถูกสร้างแบบจำลองโดยใช้ฟังก์ชันเชิงเส้นที่มีฟังก์ชันซิกมอยด์วางอยู่ด้านบน ยังคงเป็นแบบจำลองที่ง่าย แต่ไม่รู้สึกเป็นธรรมชาติเหมือนลักษณนามว่า Bayes ที่ไร้เดียงสา

เราดำเนินการต่อโดยการคำนวณตัวอย่างบางส่วนและรวบรวมโค้ดที่เป็นประโยชน์บางส่วนในระหว่างทาง สุดท้าย เราได้ใช้ลักษณนาม Gaussian naive Bayes ที่สมบูรณ์ในวิธีที่ใช้งานได้ดีกับ scikit-learn ซึ่งหมายความว่าคุณสามารถใช้ในไปป์ไลน์หรือการค้นหากริด เป็นต้น

ในตอนท้าย เราได้ตรวจสอบสุขภาพจิตเล็กน้อยโดยการนำเข้าลักษณนามว่า Gaussian naive Bayes ของ scikit-learns และทดสอบว่าลักษณนามทั้งสองของเราและของ scikit-learn ให้ผลลัพธ์เหมือนกันหรือไม่ การทดสอบนี้ประสบความสำเร็จ

 
 
ดร.โรเบิร์ต คูเบลอร์ เป็นนักวิทยาศาสตร์ข้อมูลที่ Publicis Media และผู้แต่งที่ Towards Data Science

 
Original. โพสต์ใหม่โดยได้รับอนุญาต
 

ประทับเวลา:

เพิ่มเติมจาก KD นักเก็ต