I. การวัดระยะทาง
ขั้นแรกจำนวนคุณลักษณะ (คอลัมน์) ในชุดข้อมูลไม่ได้เป็นปัจจัยในการเลือกตัวชี้วัดระยะทางสำหรับใช้ใน kNN มีงานวิจัยที่ได้รับการตีพิมพ์ไม่กี่ฉบับที่มุ่งตรงไปยังคำถามนี้อย่างแม่นยำและฐานปกติสำหรับการเปรียบเทียบคือ
การกระจายข้อมูลเชิงสถิติพื้นฐานของคุณ
ความสัมพันธ์ระหว่างคุณลักษณะที่ประกอบด้วยข้อมูลของคุณ (เป็นอิสระหรือไม่เช่นเมทริกซ์ความแปรปรวนร่วมมีลักษณะอย่างไร) และ
พื้นที่ประสานงานที่ได้รับข้อมูลของคุณ
ถ้าคุณมีความรู้ก่อนไม่มีของการกระจาย (s) จากการที่ข้อมูลของคุณเป็นตัวอย่างอย่างน้อยหนึ่ง (เอกสารที่ดีและทั่วถึง) การศึกษาสรุปว่าระยะทางยุคลิดเป็นตัวเลือกที่ดีที่สุด
ตัวชี้วัด YEuclidean ใช้ในเครื่องมือแนะนำเว็บขนาดใหญ่เช่นเดียวกับในการวิจัยทางวิชาการในปัจจุบัน ระยะทางที่คำนวณโดย Euclidean นั้นมีความหมายที่เข้าใจง่ายและการคำนวณตาชั่ง - เช่นระยะทางแบบยุคลิดถูกคำนวณแบบเดียวกันไม่ว่าจุดสองจุดนั้นจะอยู่ในสองมิติหรือในมิติที่ยี่สิบสอง
มันล้มเหลวเพียงไม่กี่ครั้งสำหรับฉันแต่ละกรณีระยะทางแบบยุคลิดล้มเหลวเพราะระบบพิกัด (คาร์ทีเซียน) เป็นทางเลือกที่น่าสงสาร และคุณมักจะจำสิ่งนี้ได้เช่นในกรณีที่ความยาวเส้นทาง (ระยะทาง) ไม่ได้เพิ่มขึ้นอีกต่อไปเช่นเมื่อพื้นที่ตัวชี้วัดเป็นกระดานหมากรุกระยะแมนฮัตตันดีกว่าแบบยุคลิดเช่นกันเมื่อพื้นที่ตัวชี้วัดเป็นโลกและระยะทางของคุณ - เที่ยวบินข้ามทวีปตัวชี้วัดระยะทางที่เหมาะสำหรับระบบพิกัดเชิงขั้วเป็นความคิดที่ดี (เช่นลอนดอนถึงเวียนนาคือ 2.5 ชั่วโมงเวียนนาถึงเซนต์ปีเตอร์สเบิร์กอีก 3 ชั่วโมงขึ้นไปในทิศทางเดียวกัน แต่ลอนดอนถึงเซนต์ . ปีเตอร์สเบิร์กไม่ถึง 5.5 ชั่วโมงแทนที่จะใช้เวลา 3 ชั่วโมง)
แต่นอกเหนือจากกรณีที่ข้อมูลของคุณอยู่ในระบบพิกัดที่ไม่ใช่คาร์ทีเซียนตัวเลือกการวัดระยะทางมักไม่ใช่วัสดุ (ดูนี้โพสต์บล็อกจากนักเรียน CS เปรียบเทียบตัวชี้วัดระยะทางหลายโดยการตรวจสอบผลกระทบต่อ kNN ลักษณนาม - ไคสแควร์ให้ผลลัพธ์ที่ดีที่สุด แต่ความแตกต่างไม่ได้ขนาดใหญ่มีการศึกษาที่ครอบคลุมมากขึ้นอยู่ในกระดาษวิชาการศึกษาเปรียบเทียบ ฟังก์ชั่นระยะทางสำหรับเพื่อนบ้านที่ใกล้ที่สุด --Mahalanobis (ส่วนใหญ่ Euclidean ที่ปรับให้เป็นมาตรฐานโดยคำนึงถึงมิติความแปรปรวนร่วม) เป็นสิ่งที่ดีที่สุดในการศึกษานี้
เงื่อนไขสำคัญหนึ่งประการ: สำหรับการคำนวณระยะทางที่มีความหมายคุณจะต้องปรับขนาดใหม่ข้อมูลของคุณ - เป็นไปได้ยากที่จะสร้างแบบจำลอง kNN เพื่อสร้างการทำนายที่แม่นยำโดยไม่ต้องทำสิ่งนี้ ตัวอย่างเช่นหากคุณกำลังสร้างแบบจำลอง kNN เพื่อทำนายประสิทธิภาพการกีฬาและตัวแปรความคาดหวังของคุณคือความสูง (ซม.), น้ำหนัก (กก.), น้ำหนักตัว (%) และชีพจรพัก (จังหวะต่อนาที) จุดข้อมูลทั่วไปอาจ ดูเป็นอย่างนี้: [180.4, 66.1, 11.3, 71] เห็นได้ชัดว่าการคำนวณระยะทางจะถูกครอบงำด้วยความสูงในขณะที่การสนับสนุนจาก bodyfat% จะเล็กน้อยมาก ใส่อีกวิธีหนึ่งหากมีการรายงานข้อมูลที่แตกต่างกันดังนั้นน้ำหนักตัวเป็นกรัมแทนที่จะเป็นกิโลกรัมจากนั้นค่าดั้งเดิมที่ 86.1 จะเป็น 86,100 ซึ่งจะมีผลอย่างมากต่อผลลัพธ์ของคุณซึ่งเป็นสิ่งที่คุณไม่ต้องการ ไม่ต้องการ
X_new = (X_old - mu) / sigma
ครั้งที่สอง โครงสร้างข้อมูล
หากคุณกังวลเกี่ยวกับประสิทธิภาพของโครงสร้าง kd-tree A Voronoi Tessellationเป็นคอนเทนเนอร์ที่เรียบง่าย แต่มีแนวคิดที่จะปรับปรุงประสิทธิภาพและสเกลได้ดีกว่า kd-Trees
นี่ไม่ใช่วิธีทั่วไปในการยืนยันข้อมูลการฝึกอบรม kNN แม้ว่าการใช้ VT สำหรับวัตถุประสงค์นี้รวมถึงข้อได้เปรียบด้านประสิทธิภาพที่ตามมาจะได้รับการบันทึกไว้เป็นอย่างดี (ดูเช่นรายงานการวิจัยของ Microsoft ) ความสำคัญเชิงปฏิบัติของสิ่งนี้คือให้คุณใช้ภาษา 'กระแสหลัก' (เช่นในดัชนี TIOBE ) จากนั้นคุณควรหาห้องสมุดเพื่อดำเนินการ VT ฉันรู้ใน Python และ R มีหลายตัวเลือกสำหรับแต่ละภาษา (เช่นแพ็คเกจvoronoiสำหรับ R มีในCRAN )
การใช้ VT สำหรับ kNN ทำงานเช่นนี้ ::
จากข้อมูลของคุณเลือกสุ่มจุด w - นี่คือศูนย์ Voronoi ของคุณ เซลล์ Voronoi สรุปประเด็นที่อยู่ใกล้เคียงทั้งหมดที่ใกล้ที่สุดกับแต่ละศูนย์ ลองนึกภาพถ้าคุณกำหนดสีที่แตกต่างให้กับแต่ละศูนย์ Voronoi เพื่อให้แต่ละจุดที่กำหนดให้กับศูนย์ที่กำหนดนั้นถูกทาสีด้วยสีนั้น ตราบใดที่คุณมีความหนาแน่นเพียงพอการทำเช่นนี้จะแสดงขอบเขตของศูนย์กลาง Voronoi แต่ละศูนย์ (เป็นขอบเขตที่แยกสองสี)
วิธีการเลือก Voronoi Centres? ฉันใช้แนวทางแบบสองมุมฉาก หลังจากสุ่มเลือกคะแนน w แล้วให้คำนวณ VT สำหรับข้อมูลการฝึกของคุณ ตรวจสอบจำนวนจุดข้อมูลที่กำหนดให้กับแต่ละศูนย์ Voronoi - ค่าเหล่านี้ควรจะเหมือนกัน (ให้มีความหนาแน่นของจุดสม่ำเสมอในพื้นที่ข้อมูลของคุณ) ในสองมิตินี้จะทำให้ VT ที่มีขนาดเท่ากันนี่เป็นกฎข้อแรกนี่เป็นครั้งที่สอง เลือก w โดยการวนซ้ำ - รันอัลกอริทึม kNN ของคุณด้วย w เป็นพารามิเตอร์ตัวแปรและวัดประสิทธิภาพ (เวลาที่ต้องการเพื่อส่งกลับการทำนายโดยการสอบถาม VT)
ลองจินตนาการว่าคุณมีจุดข้อมูลหนึ่งล้านจุดถ้าจุดนั้นยังคงอยู่ในโครงสร้างข้อมูล 2D ทั่วไปหรือใน kd-tree คุณจะทำการคำนวณระยะทางเฉลี่ยสองล้านครั้งสำหรับแต่ละจุดจุดข้อมูลใหม่ที่มีตัวแปรตอบสนองที่คุณต้องการทำนาย แน่นอนการคำนวณเหล่านั้นจะดำเนินการในชุดข้อมูลเดียว ด้วย V / T การค้นหาเพื่อนบ้านที่ใกล้ที่สุดจะดำเนินการในสองขั้นตอนหนึ่งหลังจากที่อื่น ๆ กับสองประชากรที่แตกต่างกันของข้อมูล - ครั้งแรกกับศูนย์ Voronoi จากนั้นเมื่อพบศูนย์ที่ใกล้ที่สุดจุดภายในเซลล์ที่สอดคล้องกับ ศูนย์กลางนั้นถูกค้นหาเพื่อค้นหาเพื่อนบ้านที่ใกล้ที่สุดจริง ๆ (โดยการคำนวณระยะทางต่อเนื่อง) รวมการค้นหาทั้งสองนี้เร็วกว่าการค้นหาแบบเดียรัจฉาน เป็นเรื่องง่ายที่จะเห็น: สำหรับจุดข้อมูล 1M สมมติว่าคุณเลือกศูนย์ Voronoi 250 ศูนย์เพื่อจัดการพื้นที่ข้อมูลของคุณ โดยเฉลี่ยเซลล์ Voronoi แต่ละเซลล์จะมีจุดข้อมูล 4,000 จุด ดังนั้นแทนที่จะทำการคำนวณโดยเฉลี่ย 500,000 ระยะทาง (แรงเดรัจฉาน) คุณทำได้น้อยลงโดยเฉลี่ยเพียง 125 + 2,000
สาม. การคำนวณผลลัพธ์ (ตัวแปรตอบสนองที่คาดการณ์ไว้)
มีสองขั้นตอนในการคำนวณค่าที่คาดการณ์จากชุดข้อมูลการฝึกอบรม kNN อันแรกคือการระบุ n หรือจำนวนเพื่อนบ้านที่ใกล้ที่สุดที่จะใช้สำหรับการคำนวณนี้ ประการที่สองคือวิธีถ่วงน้ำหนักการมีส่วนร่วมของพวกเขากับค่าที่คาดการณ์
W / r / t องค์ประกอบแรกคุณสามารถกำหนดค่าที่ดีที่สุดของ n โดยการแก้ปัญหาการเพิ่มประสิทธิภาพ (คล้ายกับการเพิ่มประสิทธิภาพกำลังสองน้อยที่สุด) นั่นคือทฤษฎี ในทางปฏิบัติผู้คนส่วนใหญ่ใช้ n = 3 ไม่ว่าในกรณีใดมันง่ายที่จะรันอัลกอริทึม kNN ของคุณบนชุดของอินสแตนซ์ทดสอบ (เพื่อคำนวณค่าที่คาดการณ์) สำหรับ n = 1, n = 2, n = 3, ฯลฯ และพล็อตข้อผิดพลาดเป็นฟังก์ชันของ n หากคุณต้องการให้ค่าที่เป็นไปได้สำหรับ n เริ่มต้นใช้งานอีกครั้งเพียงใช้ n = 3
องค์ประกอบที่สองคือวิธีถ่วงน้ำหนักการมีส่วนร่วมของแต่ละเพื่อนบ้าน (สมมติว่า n> 1)
เทคนิคการถ่วงน้ำหนักที่ง่ายที่สุดคือการคูณแต่ละเพื่อนบ้านด้วยสัมประสิทธิ์การถ่วงน้ำหนักซึ่งเป็นเพียง 1 / (dist * K) หรือการผกผันของระยะทางจากเพื่อนบ้านนั้นไปยังอินสแตนซ์การทดสอบที่คูณด้วยค่าคงตัวที่ได้จากประจักษ์ ฉันไม่ได้เป็นแฟนของเทคนิคนี้เพราะมักจะทำให้เพื่อนบ้านที่อยู่ใกล้ที่สุดมีน้ำหนักมากขึ้น (และทำให้น้ำหนักที่อยู่ห่างไกลกันมากขึ้น) ความสำคัญของสิ่งนี้คือการคาดการณ์ที่กำหนดสามารถขึ้นอยู่กับเพื่อนบ้านเพียงคนเดียวซึ่งจะเพิ่มความไวของอัลกอริทึมต่อเสียง
ฟังก์ชันที่ต้องมีน้ำหนักที่ดีกว่าซึ่งหลีกเลี่ยงข้อ จำกัด นี้อย่างมีนัยสำคัญคือฟังก์ชัน gaussianซึ่งในไพ ธ อนมีลักษณะดังนี้:
def weight_gauss(dist, sig=2.0) :
return math.e**(-dist**2/(2*sig**2))
ในการคำนวณค่าที่ทำนายโดยใช้รหัส kNN ของคุณคุณจะต้องระบุ n เพื่อนบ้านที่ใกล้ที่สุดไปยังจุดข้อมูลที่ตัวแปรตอบสนองที่คุณต้องการคาดการณ์ ('ตัวอย่างทดสอบ') จากนั้นเรียกใช้ฟังก์ชัน weight_gauss หนึ่งครั้งสำหรับแต่ละเพื่อนบ้าน n ผ่าน ในระยะห่างระหว่างเพื่อนบ้านแต่ละจุดทดสอบฟังก์ชั่นนี้จะส่งกลับน้ำหนักสำหรับแต่ละเพื่อนบ้านซึ่งจะใช้เป็นค่าสัมประสิทธิ์ของเพื่อนบ้านในการคำนวณค่าเฉลี่ยถ่วงน้ำหนัก