ในการเขียนโปรแกรมแบบดั้งเดิมจะมุ่งเน้นที่โค้ด ในโครงการแมชชีนเลิร์นนิง เปลี่ยนประเด็นไปที่การนำเสนอ วิธีหนึ่งที่นักพัฒนาซอฟต์แวร์พัฒนาโมเดล คือการเพิ่มและปรับปรุงฟีเจอร์ต่างๆ
การจับคู่ข้อมูลดิบกับฟีเจอร์
ด้านซ้ายของรูปที่ 1 แสดงข้อมูลดิบจากแหล่งข้อมูลอินพุต ด้านขวาแสดงเวกเตอร์ของฟีเจอร์ ซึ่งเป็นชุดค่าจุดลอยตัวซึ่งประกอบด้วยตัวอย่างในชุดข้อมูล วิศวกรรมคุณลักษณะ หมายถึง การแปลงข้อมูลดิบเป็นเวกเตอร์ของจุดสนใจ คาดไว้ได้เลยว่าจะใช้เวลาจำนวนมากไปกับ การทำงานด้านวิศวกรรมฟีเจอร์
โมเดลแมชชีนเลิร์นนิงจำนวนมากต้องแสดงจุดสนใจเป็นเวกเตอร์ที่มีเลขจริง เนื่องจากค่าฟีเจอร์ต้องคูณด้วยน้ำหนักของโมเดล
รูปที่ 1 วิศวกรรมฟีเจอร์จะแมปข้อมูลดิบกับฟีเจอร์ของ ML
การจับคู่ค่าตัวเลข
ข้อมูลที่เป็นจำนวนเต็มและจุดลอยตัวไม่จำเป็นต้องใช้การเข้ารหัสพิเศษ เนื่องจากสามารถคูณด้วยน้ำหนักที่เป็นตัวเลขได้ ตามคำแนะนำในรูปที่ 2 การแปลงค่าจำนวนเต็ม 6 ดิบ เป็นค่าฟีเจอร์ 6.0 นั้นน้อยมาก
รูปที่ 2 การแมปค่าจำนวนเต็มกับค่าทศนิยม
การแมปค่าเชิงหมวดหมู่
ฟีเจอร์เชิงหมวดหมู่มีชุดค่าที่เป็นไปได้ซึ่งแยกจากกัน
ตัวอย่างเช่น อาจมีฟีเจอร์ที่มีชื่อว่า street_name
พร้อมด้วยตัวเลือกดังต่อไปนี้
{'Charleston Road', 'North Shoreline Boulevard', 'Shorebird Way', 'Rengstorff Avenue'}
เนื่องจากโมเดลไม่สามารถคูณสตริงด้วยน้ำหนักที่เรียนรู้ได้ เราจึงใช้วิศวกรรมฟีเจอร์เพื่อแปลงสตริงเป็นค่าตัวเลข
เราทำเช่นนี้ได้โดยกำหนดการแมปจากค่าฟีเจอร์ ซึ่งเราจะเรียกว่าคำศัพท์ของค่าที่เป็นไปได้ แทนจำนวนเต็ม เนื่องจากถนนบางสายในโลกจะไม่ปรากฏในชุดข้อมูล เราจึงจัดกลุ่มถนนอื่นๆ ทั้งหมดไว้ในหมวดหมู่ "อื่นๆ" ได้ทั้งหมด ซึ่งเรียกว่าที่เก็บข้อมูลนอกระบบ (OOV)
ต่อไปนี้เป็นวิธีที่เราสามารถจับคู่ชื่อถนนกับตัวเลข:
- ทำแผนที่ถนนชาร์ลสตันกับ 0
- ทำแผนที่ถนน North Shoreline Boulevard แถว 1
- ทำแผนที่ถนน Shorebird Way to 2
- ทำแผนที่ Rengstorff Avenue กับ 3
- แมปส่วนอื่นทั้งหมด (OOV) กับ 4
แต่หากเรารวมหมายเลขดัชนีเหล่านี้ลงในโมเดลโดยตรง ข้อจำกัดที่อาจก่อให้เกิดปัญหาคือ
เราจะเรียนรู้น้ำหนักข้อมูลหนึ่งที่ใช้กับถนนทุกสาย เช่น ถ้าเราคำนวณน้ำหนักของ
street_name
ได้เท่ากับ 6 เราจะนำไปคูณ 0 สำหรับถนน Charleston คูณ 1 สำหรับถนน North Shoreline Boulevard 2 สำหรับ Shorebird Way เป็นต้น ลองพิจารณาโมเดลที่คาดการณ์ราคาบ้านโดยใช้street_name
เป็นฟีเจอร์ ไม่น่าจะมีการปรับราคาแบบเชิงเส้นตามชื่อถนน และยิ่งไปกว่านั้น เราจะถือว่าคุณสั่งซื้อถนนตามราคาบ้านโดยเฉลี่ยของถนนแต่ละเส้น โมเดลของเราต้องการความยืดหยุ่นในการเรียนรู้เรื่องน้ำหนักที่ต่างกันสำหรับถนนแต่ละสายที่จะนำไปบวกกับราคาที่ประเมินไว้โดยใช้ฟีเจอร์อื่นๆเราไม่พิจารณากรณีที่
street_name
อาจมีค่าหลายค่า เช่น บ้านหลายหลังอยู่ที่มุมถนน 2 สาย และจะไม่มีการเข้ารหัสข้อมูลนั้นในค่าstreet_name
หากค่ามีดัชนีเดียว
ในการนำข้อจำกัดทั้ง 2 อย่างออก เราสามารถสร้างเวกเตอร์ไบนารีสำหรับฟีเจอร์เชิงหมวดหมู่แต่ละรายการในโมเดลของเราแทน ซึ่งจะแสดงค่าดังต่อไปนี้
- สำหรับค่าที่ใช้กับตัวอย่าง ให้กำหนดองค์ประกอบเวกเตอร์ที่สมนัยเป็น
1
- ตั้งค่าองค์ประกอบอื่นๆ ทั้งหมดเป็น
0
ความยาวของเวกเตอร์นี้เท่ากับจำนวนองค์ประกอบในคำศัพท์ การนำเสนอนี้เรียกว่าการเข้ารหัสแบบ Hot-Hot เมื่อค่าเดียวเป็น 1 และการเข้ารหัสแบบ Multi-Hot เมื่อค่าหลายค่าเป็น 1
รูปที่ 3 แสดงการเข้ารหัสแบบร้อนจัดของถนนเส้นหนึ่ง: Shorebird Way
องค์ประกอบในเวกเตอร์ไบนารีสำหรับ Shorebird Way มีค่าเป็น 1
ในขณะที่องค์ประกอบสำหรับถนนอื่นๆ ทั้งหมดมีค่าเป็น 0
รูปที่ 3 การจับคู่ที่อยู่โดยใช้การเข้ารหัสแบบครั้งเดียว
วิธีนี้สร้างตัวแปรบูลีนสำหรับค่าฟีเจอร์ทุกค่าอย่างมีประสิทธิภาพ (เช่น ชื่อถนน) ถ้าบ้านอยู่ใน Shorebird Way ค่าไบนารีจะเป็น 1 สำหรับ Shorebird Way เท่านั้น ดังนั้น โมเดลจึงใช้เฉพาะน้ำหนักสำหรับ Shorebird Way
ในทำนองเดียวกัน หากบ้านอยู่ที่มุมถนน 2 เส้น ค่าฐานสอง 2 ค่าจะถูกตั้งค่าเป็น 1 และโมเดลจะใช้น้ำหนักทั้งสองแบบตามลำดับ
การแทนค่าบางส่วน
สมมติว่าคุณมีชื่อถนนที่แตกต่างกัน 1,000,000 ชื่อในชุดข้อมูลซึ่งคุณต้องการรวมไว้เป็นค่าสำหรับ street_name
การสร้างเวกเตอร์ไบนารีขององค์ประกอบ 1,000,000 องค์ประกอบที่เป็นจริงเพียง 1 หรือ 2 องค์ประกอบเท่านั้น เป็นการนำเสนอที่ไร้ประสิทธิภาพอย่างมากในแง่ของพื้นที่เก็บข้อมูลและเวลาในการคำนวณเมื่อประมวลผลเวกเตอร์เหล่านี้ ในสถานการณ์นี้ แนวทางทั่วไปคือการใช้
การแสดงแบบกระจัดกระจายซึ่งเก็บเฉพาะค่าที่ไม่ใช่ 0 เท่านั้น ในการแสดงข้อมูลบางส่วน ระบบยังคงเรียนรู้น้ำหนักของโมเดลอิสระสำหรับค่าแต่ละค่าของฟีเจอร์ ดังที่อธิบายไว้ข้างต้น