โต๊ะ:
บทนำ
Naive Bayes เป็นอัลกอริธึมการเรียนรู้ของเครื่องจำแนกประเภทซึ่งอิงตามทฤษฎีบทของ Bayes มีประสิทธิภาพมากโดยเฉพาะอย่างยิ่งเมื่อต้องจัดการกับข้อมูลที่เป็นข้อความ เช่น การวิเคราะห์ความรู้สึก การตรวจจับสแปม และการจัดประเภทข้อความ
อัลกอริทึมนี้เรียกว่า "ไร้เดียงสา" เนื่องจากการสันนิษฐานว่าตัวแปรชุดข้อมูลทั้งหมดมีความเป็นอิสระ ซึ่งไม่ได้เป็นเช่นนั้นเสมอไป
ก่อนที่จะอธิบายเพิ่มเติมว่า Naive bayes ทำงานอย่างไร เราต้องแน่ใจว่าเราเข้าใจสิ่งต่อไปนี้:
ความน่าจะเป็นแบบมีเงื่อนไข
อัลกอริธึม Naive Bayes ขึ้นอยู่กับทฤษฎีบทของ Bayes ซึ่งก่อตั้งขึ้นจากความน่าจะเป็นแบบมีเงื่อนไข นั่นคือความน่าจะเป็นที่เหตุการณ์ A จะเกิดขึ้น โดยพิจารณาว่าเหตุการณ์ B ได้เกิดขึ้นแล้ว
ตัวอย่าง:
ให้มีขวดสองใบที่มีลูกบอลสี:
-
โถที่ 1 มีลูกบอลสีน้ำเงิน 3 ลูก สีแดง 2 ลูก และสีเขียว 4 ลูก
-
โถที่ 2 มีลูกบอลสีน้ำเงิน 1 ลูก สีแดง 4 ลูก และสีเขียว 3 ลูก
เราต้องการคำนวณความน่าจะเป็นในการสุ่มเลือกลูกบอลสีน้ำเงินจากขวดโหลใบใดใบหนึ่ง
ไม่ใช่อะไรอื่นนอกจากผลรวมของความน่าจะเป็นในการเลือกลูกบอลสีน้ำเงินจาก Jar1 หรือ Jar2
ตอนนี้ เราต้องการคำนวณความน่าจะเป็นในการเลือกลูกบอลสีน้ำเงินเนื่องจากเราเลือก Jar1:
สุดท้าย เราต้องการคำนวณความน่าจะเป็นในการเลือก Jar1 เนื่องจากเราสุ่มลูกบอลสีน้ำเงิน ที่นี่เราใช้ทฤษฎีบทของเบย์ซึ่งระบุไว้ดังต่อไปนี้:
การจำแนกประเภทไร้เดียงสาเบย์
ในลักษณนาม Naive Bayes เราต้องการค้นหาคลาสที่เพิ่มความน่าจะเป็นแบบมีเงื่อนไขให้สูงสุดโดยกำหนดเวกเตอร์อินพุต X ดังนั้น Naive Bayes สามารถกำหนดได้ดังนี้:
เมื่อใช้ทฤษฎีบทเบย์ ฟังก์ชันจะกลายเป็น:
ในสูตรนี้ ง่ายต่อการคำนวณ P(Ci) ซึ่งไม่ใช่สิ่งอื่นใดนอกจากความน่าจะเป็นของคลาส Ci และง่ายต่อการคำนวณ P(x) ซึ่งเป็นความน่าจะเป็นของเหตุการณ์ x ที่เกิดขึ้น
สิ่งที่ยากในการคำนวณคือ P(x|Ci); ความน่าจะเป็นของเหตุการณ์ x เมื่อพิจารณาจากคลาส Ci เพื่อให้ง่ายขึ้น เราจำเป็นต้องถือว่าตัวแปรอินพุตทั้งหมดมีความเป็นอิสระ ดังนั้นเราสามารถเขียนได้:
และจริงๆ แล้วเป็นเพราะสมมติฐานนี้ที่เราเรียกตัวแยกประเภทนี้ว่า "ไร้เดียงสา" เนื่องจากเราไม่สามารถรับประกันความเป็นอิสระของตัวแปรอินพุตได้เสมอไป ตัวแยกประเภท Naive Bayes กลายเป็น:
ที่จริงแล้ว เราสามารถทำให้สูตรนี้ง่ายขึ้นได้อีกโดยการกำจัด P(x) เพราะมันเหมือนกันสำหรับทุกคลาส:
ตอนนี้เรามาดูตัวอย่างกัน:
- สภาพอากาศ | เวลา | วันในสัปดาห์ | อาหารเย็น |
-
ล้าง | ค่ำ | สุดสัปดาห์ | พ่อครัว |
-
มีเมฆมาก | กลางคืน | วันธรรมดา | คำสั่งซื้อ |
-
ฝนตก | กลางคืน | วันธรรมดา | คำสั่งซื้อ |
-
ฝนตก | เที่ยงวัน | วันธรรมดา | คำสั่งซื้อ |
-
มีเมฆมาก | เที่ยงวัน | สุดสัปดาห์ | พ่อครัว |
-
ล้าง | กลางคืน | สุดสัปดาห์ | พ่อครัว |
-
เต็มไปด้วยหิมะ | ค่ำ | สุดสัปดาห์ | คำสั่งซื้อ |
-
ล้าง | กลางคืน | วันธรรมดา | พ่อครัว |
-
ล้าง | เที่ยงคืน | สุดสัปดาห์ | คำสั่งซื้อ |
ที่นี่ เรามีชุดข้อมูลขนาดเล็กที่มีตัวแปรอินพุต 3 ตัว ได้แก่ สภาพอากาศ เวลา และวันในสัปดาห์ และตัวแปรเป้าหมาย 1 ตัว ได้แก่ "อาหารค่ำ" ที่ระบุว่าบุคคลนั้นปรุงอาหารหรือสั่งอาหารเย็นของตน เราต้องการค้นหาคลาสของอินพุต x={Clear, Evening, Weekend}:
เราจำเป็นต้องคำนวณความน่าจะเป็นแบบมีเงื่อนไขสำหรับคลาส “Cooks” และคลาส “Orders” โดยให้อินพุต x={Clear, Evening, Weekend} คลาสที่ทำนายคือคลาสที่มีความน่าจะเป็นแบบมีเงื่อนไขสูงสุด
เราเริ่มต้นด้วยการคำนวณความน่าจะเป็นแบบมีเงื่อนไขของคลาส "Cooks":
ตอนนี้เราคำนวณความน่าจะเป็นแบบมีเงื่อนไขแต่ละรายการด้วยตัวมันเอง:
ความน่าจะเป็นของ weather=”Clear” โดยที่คลาสคือ “Cooks” คือจำนวนบรรทัดที่มีสภาพอากาศ “Clear” และคลาส “Cooks” มากกว่าจำนวนบรรทัดทั้งหมดที่มีคลาส “Cooks”
เช่นเดียวกับความน่าจะเป็นแบบมีเงื่อนไขอื่นๆ:
ตอนนี้สำหรับความน่าจะเป็น P(Cooks) มันคือจำนวนบรรทัดที่มีคลาส "Cooks" ต่อจำนวนบรรทัดทั้งหมด:
ตอนนี้เราคำนวณผลคูณของความน่าจะเป็นเหล่านี้:
นั่นคือสำหรับชั้นเรียน "Cooks" ตอนนี้เราต้องทำเช่นเดียวกันกับชั้นเรียน "Orders":
เราคำนวณความน่าจะเป็นส่วนบุคคล:
และในที่สุดเราก็คำนวณผลคูณของความน่าจะเป็น:
ในที่สุดเราก็เข้าชั้นเรียนที่มีความน่าจะเป็นสูงสุดซึ่งก็คือคลาส “Cooks”:
ข้อดีและข้อจำกัดของอัลกอริทึมนี้
ข้อดี:
-
เป็นลักษณนามที่รวดเร็วมาก
-
มันง่ายต่อการปฏิบัติ
-
ไม่มีขั้นตอนการฝึกอบรม แต่เป็นเพียงการอนุมานเท่านั้น
-
ไม่จำเป็นต้องมีข้อมูลจำนวนมากในการอนุมาน
ข้อจำกัด:
- Naive Bayes ถือว่าตัวแปรอินพุตมีความเป็นอิสระ ซึ่งไม่เป็นความจริงเสมอไป
- Naive Bayes ประสบปัญหาความถี่เป็นศูนย์ ซึ่งเป็นช่วงที่ตัวแปรอินพุตกำหนดความน่าจะเป็นเป็นศูนย์ นี่จะทำให้ความน่าจะเป็นแบบมีเงื่อนไขทั้งหมดเป็นศูนย์ P(C|x) เคล็ดลับประการหนึ่งเพื่อหลีกเลี่ยงปัญหานี้คือการใช้ความถี่ขั้นต่ำ 1 ( แทน 0 ) กับตัวแปรทั้งหมด
ออกกำลังกาย
นี่คือ dataframe ของชุดข้อมูลเดียวกันกับที่เราเคยเห็นในตัวอย่าง
งานของคุณคือนำ Naive Bayes ไปใช้ด้วยตัวเองโดยใช้ python:
import pandas as pd
dataset = pd.DataFrame()
dataset['Weather'] = ['Clear', 'Cloudy', 'Rainy', 'Rainy', 'Cloudy', 'Clear', 'Snowy', 'Clear', 'Clear']
dataset['Time'] = ['Evening', 'Night', 'Night', 'Midday', 'Midday', 'Night', 'Evening', 'Night', 'Midnight']
dataset['Day'] = ['Weekend', 'Weekday', 'Weekday', 'Weekday', 'Weekend', 'Weekend', 'Weekend', 'Weekday', 'Weekend']
dataset['Class'] = ['Cooks', 'Orders', 'Orders', 'Orders', 'Cooks', 'Cooks', 'Orders', 'Cooks', 'Orders']
def naive_bayes(weather, time, day):
# res_dict = {class1: probability of class 1, class1: probability of class 1
return res_dict
สารละลาย
def naive_bayes(x_weather, x_time, x_day):
TARGET = 'Dinner' # The name of the target variable
CLASSES = list(dataset['Dinner'].unique()) # The classes of the target variable
len_dataset = len(dataset) # The length of the dataset
res_dict = {} # res_dict = {class1:probability1, ..., class_n:probability_n}
# for each class of the target classes, we calculate the it's conditional probability
for class_name in CLASSES:
# the number of lines that belong to the class "class_name"
len_c = len(dataset[ (dataset[TARGET] == class_name) ])
# the number of lines that belong to the class "class_name" and have weather="x_weather"
n_weather = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Weather'] == x_weather) ])
# the number of lines that belong to the class "class_name" and have time="x_time"
n_time = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Time'] == x_time) ])
# the number of lines that belong to the class "class_name" and have day="x_day"
n_day = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Day'] == x_day) ])
# We calculate the conditional probability:
# P(class|x) = P(weather|class) x P(time|class) x P(day|class) x P(class)
p = (n_weather / len_c) * (n_time / len_c) * (n_day / len_c) * (len_c / len_dataset) res_dict[class_name] = p
return res_dict