เพื่อนบ้านที่ใกล้ที่สุดในข้อมูลมิติสูง?


163

ฉันได้ถามคำถามสองสามวันย้อนหลังเกี่ยวกับวิธีค้นหาเพื่อนบ้านที่ใกล้ที่สุดสำหรับเวกเตอร์ที่กำหนด เวกเตอร์ของฉันตอนนี้มีขนาด 21 มิติและก่อนที่ฉันจะดำเนินการต่อไปเนื่องจากฉันไม่ได้มาจากโดเมนของการเรียนรู้ของเครื่องจักรและคณิตศาสตร์ฉันเริ่มถามคำถามพื้นฐานบางอย่างกับตัวเอง:

  • ระยะทางแบบยุคลิดเป็นตัวชี้วัดที่ดีสำหรับการค้นหาเพื่อนบ้านที่ใกล้ที่สุดหรือไม่? ถ้าไม่ใช่ตัวเลือกของฉันคืออะไร
  • นอกจากนี้แล้วจะมีวิธีการอย่างไรในการตัดสินใจเลือกขีด จำกัด ที่ถูกต้องในการพิจารณา k-neighbour มีการวิเคราะห์บางอย่างที่สามารถทำได้เพื่อหาค่านี้หรือไม่?
  • ก่อนหน้านี้ฉันได้รับคำแนะนำให้ใช้ kd-Trees แต่หน้าวิกิพีเดียกล่าวอย่างชัดเจนว่าสำหรับมิติสูง kd-Tree นั้นเกือบจะเทียบเท่ากับการค้นหาที่โหดร้าย ในกรณีนั้นวิธีที่ดีที่สุดในการค้นหาเพื่อนบ้านที่ใกล้ที่สุดในชุดข้อมูลจุดล้านอย่างมีประสิทธิภาพคืออะไร?

ใครช่วยอธิบายคำถามข้างต้นบางส่วน (หรือทั้งหมด) ได้บ้าง


ลองถามที่ metaoptimize.com
pajton

4
"มิติสูง" คือ 20 สำหรับบางคนและบางข้อมูล 50 หรือ 100 หรือ 1,000 สำหรับคนอื่น ๆ โปรดให้หมายเลขถ้าคุณทำได้เช่น "ฉันได้ทำแต้มข้อมูล 21, 1000000 โดยใช้ xx" แล้ว
ปฏิเสธ

kD-Tree แยกข้อมูลเป็นสองมิติพร้อมกันในแต่ละมิติ หากคุณมีมิติข้อมูล 20 จุดและมีเพียง 1M จุดข้อมูลคุณจะได้รับต้นไม้ประมาณ 1 ระดับโดยที่ระดับหมายถึงการแบ่งในทุกแกน เนื่องจากไม่มีความลึกที่แท้จริงคุณจะไม่ได้รับประโยชน์จากการเพิกเฉยกิ่งก้านของต้นไม้ มันมีประโยชน์ที่จะไม่คิดว่ามันจะมากพอ ๆ กับต้นไม้ไบนารี แต่เหมือนต้นไม้รูปสี่เหลี่ยมต้นไม้แปดสิบต้นและอื่น ๆ แม้ว่ามันจะถูกนำมาใช้เหมือนต้นไม้ไบนารี
phkahler

@denis เป็น 'dim 21, 1000000 data points' สำหรับชุดข้อมูล Higgs หรือไม่
nikk

1
นี่คือลิงค์สำหรับดาวน์โหลดชุดข้อมูล Higgs 11 ล้านข้อสังเกตที่มี 28 คุณสมบัติ คอลัมน์สุดท้ายคือป้ายกำกับ: 1 สำหรับสัญญาณ, ศูนย์สำหรับเสียง archive.ics.uci.edu/ml/datasets/HIGGS
nikk

คำตอบ:


179

ฉันกำลังศึกษาปัญหาดังกล่าว - การจำแนกประเภทการค้นหาเพื่อนบ้านที่ใกล้ที่สุด - เพื่อดึงข้อมูลเพลง

คุณอาจสนใจอัลกอริทึมใกล้เคียงที่สุดที่ใกล้เคียง ( ANN ) แนวคิดคือคุณอนุญาตให้อัลกอริทึมกลับมาใกล้เพื่อนบ้านอย่างเพียงพอ(อาจไม่ใช่เพื่อนบ้านที่ใกล้ที่สุด) ในการทำเช่นนี้คุณลดความซับซ้อน คุณพูดถึงkd-tree ; นั่นคือตัวอย่างหนึ่ง แต่อย่างที่คุณบอกว่าkd-treeทำงานได้ไม่ดีในมิติที่สูง ในความเป็นจริงเทคนิคการจัดทำดัชนีทั้งหมดในปัจจุบัน (ขึ้นอยู่กับการแบ่งพื้นที่) ทำให้การค้นหาเชิงเส้นสำหรับมิติที่สูงเพียงพอ [1] [2] [3]

ในบรรดาอัลกอริทึมของANN ที่นำเสนอเมื่อเร็ว ๆ นี้บางทีสิ่งที่ได้รับความนิยมมากที่สุดคือLocal-Sensitive Hashing ( LSH ) ซึ่งทำแผนที่ชุดของจุดในพื้นที่สูงมิติเข้าไปในชุดของถังขยะเช่นตารางแฮช [1] [3] แต่แตกต่างจากแฮชแบบดั้งเดิมแฮชที่ไวต่อท้องที่วางจุดใกล้เคียงลงในถังขยะเดียวกัน

LSHมีข้อดีมากมาย ครั้งแรกมันง่าย คุณเพียงแค่คำนวณแฮชสำหรับทุกจุดในฐานข้อมูลของคุณจากนั้นสร้างตารางแฮชจากจุดเหล่านั้น หากต้องการสอบถามเพียงคำนวณแฮชของจุดสอบถามจากนั้นดึงข้อมูลคะแนนทั้งหมดในถังเดียวกันจากตารางแฮช

ประการที่สองมีทฤษฎีที่เข้มงวดซึ่งสนับสนุนการทำงานของมัน ก็สามารถที่จะแสดงให้เห็นว่าเวลาแบบสอบถามsublinearในขนาดของฐานข้อมูลคือเร็วกว่าการค้นหาเชิงเส้น ความเร็วขึ้นอยู่กับว่าเราสามารถทนได้เท่าไหร่

สุดท้ายLSHเข้ากันได้กับใด ๆ บรรทัดฐาน Lp 0 < p <= 2สำหรับ ดังนั้นเพื่อตอบคำถามแรกของคุณคุณสามารถใช้LSHกับตัวชี้วัดระยะทางแบบยุคลิดหรือคุณสามารถใช้กับตัวชี้วัดระยะทางแมนฮัตตัน (L1) นอกจากนี้ยังมีตัวแปรสำหรับระยะทาง Hamming และความคล้ายคลึงกันของโคไซน์

ภาพรวมที่ดีเขียนโดย Malcolm Slaney และ Michael Casey สำหรับนิตยสารการประมวลผลสัญญาณ IEEE ในปี 2008 [4]

LSHถูกนำไปใช้อย่างดูเหมือนทุกที่ คุณอาจต้องการที่จะลอง


[1] Datar, Indyk, Immorlica, Mirrokni, "แผนการ Hashing ความละเอียดอ่อนในท้องถิ่นตามการกระจาย p-Stable" 2004

[2] Weber, Schek, Blott, "การวิเคราะห์เชิงปริมาณและการศึกษาประสิทธิภาพสำหรับวิธีการค้นหาความเหมือนกันในช่องว่างมิติสูง" 1998

[3] Gionis, Indyk, Motwani, "การค้นหาความเหมือนกันในมิติที่สูงผ่านการบีบอัด" 1999

[4] Slaney, Casey, "hashing ที่ไวต่อสถานที่สำหรับการค้นหาเพื่อนบ้านที่ใกล้ที่สุด", 2008


1
@Steve: ขอบคุณสำหรับการตอบกลับ คุณมีคำแนะนำเกี่ยวกับการใช้ LSH บ้างไหม? สิ่งเดียวที่ฉันเห็นคือจาก MIT มีแพ็คเกจอื่น ๆ ที่ลอยอยู่รอบ ๆ ?
ตำนาน

1
นอกจากนั้นฉันไม่รู้จักคนอื่น ฉันสิ้นสุดการเขียนของฉันเองใน Python สำหรับวัตถุประสงค์เฉพาะของฉัน โดยพื้นฐานแล้วตารางแฮชแต่ละคนจะถูกนำมาใช้เป็นพจนานุกรมหลามdซึ่งเป็นหนึ่งในถังที่มีคีย์d[k] มีป้ายชื่อของทุกจุดกัญชาซึ่งเป็น จากนั้นคุณเพียงแค่ต้องคำนวณแฮชสำหรับแต่ละจุด ดูสมการ (1) ใน [4] หรือส่วนที่ 3 ใน [1] kd[k]k
Steve Tjoa

@ Steve: ขอบคุณสำหรับความช่วยเหลือของคุณ ฉันจะเริ่มนำไปใช้ทันที คุณมีความคิดใด ๆ เกี่ยวกับวิธีการทำงานของชุดข้อมูลขนาดใหญ่โดยโอกาสใด ๆ
ตำนาน

1
อ้างอิงอีก LSH สนับสนุน: การเปรียบเทียบที่ใกล้ที่สุดอัลกอริทึมเพื่อนบ้านในพื้นที่สูงมิติ , Hendra Gunadi 2011 cs.anu.edu.au/student/projects/11S2/Reports/Hendra%20Gunadi.pdf
โอลิเวอร์โคลแมน

1
@SteveTjoa: พบว่ายากที่จะเข้าใจคำหลักและสูตรฝังตัว เนื่องจากคุณมีไฮไลต์เดียวของ LSH ฉันจึงเสริม ด้วยความตั้งใจที่ดีที่สุดเท่านั้น แต่คุณสามารถกลับมาใช้ใหม่ได้ฟรี มันเป็นคำตอบของคุณ :)
Regexident

81

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 ผ่าน ในระยะห่างระหว่างเพื่อนบ้านแต่ละจุดทดสอบฟังก์ชั่นนี้จะส่งกลับน้ำหนักสำหรับแต่ละเพื่อนบ้านซึ่งจะใช้เป็นค่าสัมประสิทธิ์ของเพื่อนบ้านในการคำนวณค่าเฉลี่ยถ่วงน้ำหนัก


2
คำตอบที่ดี! ครอบคลุมและถูกต้องสัมพันธ์กับประสบการณ์ของฉัน
Ted Dunning

คำตอบที่ดี +1 ฉันได้เพิ่มคำตอบล่าสุดใหม่ที่นี่มันดีไหม
gsamaras

1
"ลองจินตนาการว่าคุณมีจุดข้อมูลหนึ่งล้านจุด ..... ถ้าจุดนั้นยังคงอยู่ในโครงสร้างข้อมูล 2D ธรรมดาหรือใน kd-treeคุณจะทำการคำนวณระยะทางเฉลี่ยสองล้านล้านครั้งสำหรับแต่ละจุดข้อมูลใหม่ที่ตอบสนอง ตัวแปรที่คุณต้องการทำนาย " ไม่เห็นด้วย สามารถพิสูจน์ได้ว่าต้นไม้ KD มีO(sqrt(n))ความซับซ้อนในการค้นหาแบบ 2D
แอนทอน

16

สิ่งที่คุณกำลังเผชิญเป็นที่รู้จักกันเป็นคำสาปแช่งของมิติ บางครั้งมีประโยชน์ในการเรียกใช้อัลกอริทึมเช่น PCA หรือICAเพื่อให้แน่ใจว่าคุณต้องการมิติทั้งหมด 21 และอาจพบการแปลงเชิงเส้นซึ่งจะช่วยให้คุณใช้น้อยกว่า 21 ที่มีคุณภาพผลลัพธ์ประมาณเดียวกัน

อัปเดต: ฉันพบพวกเขาในหนังสือที่ชื่อว่าการประมวลผลสัญญาณชีวการแพทย์โดย Rangayyan (ฉันหวังว่าฉันจำได้ถูกต้อง) ICA ไม่ใช่เทคนิคที่ไม่สำคัญ แต่ถูกพัฒนาโดยนักวิจัยในฟินแลนด์และฉันคิดว่ารหัส Matlab สำหรับการดาวน์โหลดนั้นเป็นแบบสาธารณะ PCA เป็นเทคนิคที่ใช้กันอย่างแพร่หลายและฉันเชื่อว่าคุณควรจะสามารถหา R หรือการใช้งานซอฟต์แวร์อื่น ๆ PCA ดำเนินการโดยการแก้สมการเชิงเส้นซ้ำ ๆ ฉันทำไปนานเกินไปแล้วที่จะจำได้อย่างไร =)

แนวคิดก็คือคุณแบ่งสัญญาณของคุณออกเป็นไอเก็นนักเอกเทศอิสระ (eigenfunctions ไม่ต่อเนื่องจริงๆ) และค่าลักษณะเฉพาะของมัน 21 ในกรณีของคุณ ค่าไอเกนแต่ละค่าจะแสดงจำนวนเงินบริจาคที่ไอเกนฟังก์ชันแต่ละตัวมีให้กับการวัดแต่ละค่าของคุณ หากค่าลักษณะเฉพาะมีขนาดเล็กคุณสามารถแสดงสัญญาณได้อย่างใกล้ชิดโดยไม่ต้องใช้ฟังก์ชั่น eigen ที่สอดคล้องกันและนั่นคือวิธีที่คุณกำจัดมิติข้อมูล


+1 ขอบคุณ นี่เป็นข้อเสนอแนะที่น่าสนใจมากและสมเหตุสมผลดี ตามคำขอขั้นสุดท้ายคุณคุ้นเคยกับการสอนแบบภาคปฏิบัติ (ใน python หรือ R หรือภาษาอื่น ๆ ) ที่อธิบายวิธีการทำสิ่งนี้แบบโต้ตอบ (ฉันหมายถึงการอธิบายทีละขั้นตอนในกระบวนการทั้งหมด) ฉันอ่านเอกสารสองสามฉบับตั้งแต่เมื่อวานนี้ แต่ส่วนใหญ่ดูเหมือนจะเข้าใจไม่ได้ ข้อเสนอแนะใด ๆ
ตำนาน

4
Nitpicking: ICA ไม่ใช่วิธีลดขนาด ไม่ทราบวิธีการให้คะแนนส่วนประกอบและไม่ควรใช้เช่นนี้
Gael Varoquaux

12

ตอบสูงสุดเป็นสิ่งที่ดี แต่เก่าดังนั้นฉันต้องการที่จะเพิ่มขึ้นคำตอบ 2016


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


หัวข้อยอดนิยมที่อาจมีค่า:

  1. วิธีการที่ทันสมัยของLSHเช่นRazenshteyn 's
  2. RKD- สนามบินป่า : ป่า (s) ของแบบสุ่ม kd ต้นไม้ (RKD- สนามบิน) ที่อธิบายไว้ในFlannหรือในวิธีการที่เมื่อเร็ว ๆ นี้ผมเป็นส่วนหนึ่งของKD-GeRaF
  3. LOPQซึ่งย่อมาจากการเพิ่มประสิทธิภาพเฉพาะ Quantization สินค้าตามที่อธิบายไว้ที่นี่ มันจะคล้ายกับใหม่ Babenko + Lemptitsky ของวิธีการ

คุณสามารถตรวจสอบคำตอบที่เกี่ยวข้องของฉัน:

  1. จุดที่มีมิติสูงสองชุด: ค้นหาเพื่อนบ้านที่ใกล้ที่สุดในอีกชุดหนึ่ง
  2. การเปรียบเทียบรันไทม์ของเคียวรีเพื่อนบ้านที่ใกล้ที่สุดกับโครงสร้างข้อมูลที่แตกต่างกัน
  3. การใช้ PCL kd-tree ช้ามาก

8

ในการตอบคำถามของคุณทีละคน:

  • ไม่ระยะทางแบบยุคลิดเป็นตัวชี้วัดที่ไม่ดีในพื้นที่มิติสูง โดยทั่วไปในมิติข้อมูลสูงจุดข้อมูลมีความแตกต่างกันมาก ที่ลดความแตกต่างสัมพัทธ์ในระยะห่างระหว่างจุดข้อมูลที่กำหนดและเพื่อนบ้านที่ใกล้ที่สุดและไกลที่สุด
  • มีงานวิจัย / งานวิจัยจำนวนมากอยู่ในข้อมูลมิติสูง แต่เนื้อหาส่วนใหญ่ต้องการความซับซ้อนทางคณิตศาสตร์จำนวนมาก
  • ต้นไม้ KD ไม่ดีสำหรับข้อมูลมิติสูง ... หลีกเลี่ยงโดยวิธีทั้งหมด

นี่เป็นกระดาษที่ดีที่ช่วยให้คุณเริ่มต้นในทิศทางที่ถูกต้อง " เมื่ออยู่ใกล้เพื่อนบ้านที่มีความหมาย ?" โดย Beyer และทั้งหมด

ฉันทำงานกับข้อมูลตัวอักษรขนาด 20K ขึ้นไป หากคุณต้องการคำแนะนำที่เกี่ยวข้องกับข้อความฉันอาจช่วยคุณได้


1
+1 ฉันกำลังพิมพ์เอกสารนั้นเพื่ออ่านตอนนี้ ในระหว่างนี้คุณมีข้อเสนอแนะเกี่ยวกับวิธีการคิดออกเพื่อนบ้านที่ใกล้ที่สุดหรือไม่ หากทั้งตัวชี้วัดระยะทางและคำจำกัดความของเพื่อนบ้านนั้นมีข้อบกพร่องผู้คนทั่วไปจะแก้ปัญหามิติที่สูงกว่าที่พวกเขาต้องการทำการจับคู่โดยประมาณตามเวกเตอร์คุณลักษณะได้อย่างไร ข้อเสนอแนะใด ๆ
ตำนาน

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

@BiGYaN คุณกำหนดพื้นที่ของคุณอย่างไร ฉันหมายถึง bage ของ word vector หรือ embeded vector?
user3487667

@ user3487667 พื้นที่ขึ้นอยู่กับว่าคุณกำหนดปัญหาของคุณอย่างไร ฉันกำลังพูดถึงแบบจำลองกระเป๋าคำง่ายๆ
BiGYaN

5

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

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

วิธี k ที่ใกล้เคียงที่สุดเป็นที่รู้กันว่ามีราคาแพงในการคำนวณ มันเป็นหนึ่งในเหตุผลหลักที่ผู้คนหันไปใช้อัลกอริธึมอื่น ๆ เช่นสนับสนุนเวกเตอร์แมชชีน


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

2
ทั้งสองวิธีได้รับการดูแลเนื่องจากข้อมูลการฝึกอบรมของคุณนั้นมีหมายเหตุประกอบกับคลาสที่ถูกต้อง หากคุณมีคุณสมบัติเวคเตอร์เท่านั้นและไม่ทราบว่ามีคลาสเหล่านั้นอยู่คุณไม่สามารถใช้ kNN หรือ SVM ได้ วิธีการเรียนรู้ที่ไม่ได้รับการสำรองมักจะเรียกว่าอัลกอริทึมการจัดกลุ่ม พวกเขาสามารถระบุกลุ่มของข้อมูลที่คล้ายกัน แต่พวกเขาไม่ได้บอกคุณว่ากลุ่มหมายถึงอะไร
โคลิน

ขอบคุณสำหรับการชี้แจง คุณพูดถูก แน่นอนมันเป็นเทคนิคการกำกับดูแล ฉันไม่ได้ตระหนักถึงสิ่งที่ฉันเรียกว่าหมวดหมู่เป็นชั้นเรียนจริงเกินไป :)
ตำนาน

4

kd-trees แน่นอนจะทำงานได้ไม่ดีกับข้อมูลมิติสูง เนื่องจากขั้นตอนการตัดแต่งไม่ได้ช่วยอะไรอีกต่อไปเนื่องจากขอบที่ใกล้ที่สุด - ส่วนเบี่ยงเบน 1 มิติ - จะมีขนาดเล็กกว่าการเบี่ยงเบนเต็มมิติไปยังเพื่อนบ้านที่ใกล้ที่สุดที่รู้จักกันเกือบตลอดเวลา

แต่ยิ่งไปกว่านั้น kd-trees ทำงานได้ดีกับบรรทัดฐาน Lp สำหรับทุกสิ่งที่ฉันรู้และมีผลกระทบระยะทางความเข้มข้นที่ทำให้อัลกอริทึมตามระยะทางลดลงด้วยมิติที่เพิ่มขึ้น

สำหรับข้อมูลเพิ่มเติมคุณอาจต้องการอ่านคำสาปของมิติและตัวแปรต่าง ๆ ของมัน (มีด้านใดด้านหนึ่งมากกว่า!)

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


คุณมีการอ้างอิงสำหรับย่อหน้าที่ 1 และ 2 ของคุณหรือไม่
Chuck

ไม่ แต่พวกเขาควรจะเห็นได้ชัดเจนจาก instantiations "คำสาปของมิติ" (cf, survey ) และพยายามหาต้นไม้ kd ที่สนับสนุนสิ่งอื่นนอกเหนือจาก Euclidean ... สนับสนุนระยะทางอื่น ๆ ที่เป็นไปได้ แต่ไม่ใช่เรื่องธรรมดา (ELKI อนุญาตให้ Minkowski ระยะทางทั้งหมด + กำลังสอง Euclidean แต่ส่วนใหญ่จะมี Euclidean) เพียงแค่พิจารณาว่า kd-trees ใช้หนึ่งมิติเท่านั้นสำหรับการตัดแต่งกิ่งและเปรียบเทียบกับระยะทางที่เกี่ยวข้องกับมิติทั้งหมด นอกจากนี้การแยกของคุณจะไม่สามารถแยกในแต่ละมิติ
Erich Schubert

3

หลายอย่างขึ้นอยู่กับสาเหตุที่คุณต้องการรู้จักเพื่อนบ้านที่ใกล้ที่สุด คุณอาจมองเข้าไปในอัลกอริทึมกะค่าเฉลี่ยhttp://en.wikipedia.org/wiki/Mean-shiftหากสิ่งที่คุณต้องการคือการหาโหมดของชุดข้อมูลของคุณ


2
เท่าที่ฉันรู้ Mean-Shift ไม่เหมาะสำหรับการจัดกลุ่มข้อมูลมิติสูง เค - เมียนอาจเป็นทางเลือกที่ดีกว่า
fdermishin

3

ฉันคิดว่าโคไซน์ในtf-idfของคุณสมบัติบูลีนจะทำงานได้ดีสำหรับปัญหาส่วนใหญ่ นั่นเป็นเพราะฮิวริสติกที่พิสูจน์แล้วว่าใช้เวลาในเครื่องมือค้นหาจำนวนมากเช่น Lucene ระยะทางแบบยุคลิดในประสบการณ์ของฉันแสดงผลลัพธ์ที่ไม่ดีสำหรับข้อมูลที่เป็นข้อความใด ๆ การเลือกน้ำหนักและตัวอย่าง k ที่แตกต่างกันสามารถทำได้ด้วยข้อมูลการฝึกอบรมและการเลือกพารามิเตอร์ brute-force


3

iDistance น่าจะเป็นวิธีที่ดีที่สุดสำหรับการดึง knn ที่แน่นอนในข้อมูลมิติสูง คุณสามารถดูได้เป็น Tessalation Voronoi โดยประมาณ


3

ฉันประสบปัญหาเดียวกันและสามารถพูดได้ดังนี้

  1. ระยะทางแบบยุคลิดนั้นเป็นตัวชี้วัดระยะทางที่ดี แต่มันก็มีราคาแพงกว่าระยะทางแบบแมนฮัตตันและบางครั้งก็ให้ผลลัพธ์ที่แย่กว่าเล็กน้อยดังนั้นฉันจะเลือกภายหลัง

  2. ค่าของ k สามารถพบได้สังเกตุ คุณสามารถลองใช้ค่าที่แตกต่างและตรวจสอบเส้นโค้ง ROC ที่ได้หรือการวัดความแม่นยำ / การเรียกคืนอื่น ๆ เพื่อค้นหาค่าที่ยอมรับได้

  3. ทั้งระยะทางแบบยุคลิดและแมนฮัตตันเคารพในความไม่เท่าเทียมกันของสามเหลี่ยมดังนั้นคุณสามารถใช้พวกมันในต้นไม้ที่มีการวัด อันที่จริงต้นไม้ KD นั้นมีประสิทธิภาพลดลงอย่างรุนแรงเมื่อข้อมูลมีมากกว่า 10 มิติ (ฉันประสบปัญหานั้นด้วยตนเอง) ฉันพบว่าต้นไม้ VPเป็นตัวเลือกที่ดีกว่า


3

ต้นไม้ KD ทำงานได้ดีสำหรับ 21 มิติถ้าคุณออกก่อนกำหนดหลังจากดูที่ 5% ของคะแนนทั้งหมด FLANNทำเช่นนี้ (และการเร่งความเร็วอื่น ๆ ) เพื่อจับคู่เวกเตอร์ SIFT ขนาด 128-dim (แต่น่าเสียดายที่ FLANN ทำเฉพาะ Euclidean metric เท่านั้นและscipy.spatial.cKDTree ที่รวดเร็วและเป็นของแข็ง นั้นทำเฉพาะ Lp metrics ซึ่งอาจหรืออาจไม่เพียงพอสำหรับคุณข้อมูล ) แน่นอนว่าการแลกเปลี่ยนความแม่นยำนั้นมีอยู่ที่นี่

(หากคุณสามารถอธิบาย Ndata, Nquery, การกระจายข้อมูลของคุณซึ่งอาจช่วยให้ผู้คนลองใช้ข้อมูลที่คล้ายกัน)

เพิ่ม 26 เมษายน, รันไทม์สำหรับ cKDTree ด้วย cutoff บน mac ppc เครื่องเก่าของฉัน, เพื่อให้แนวคิดคร่าวๆของความเป็นไปได้:

kdstats.py p=2 dim=21 N=1000000 nask=1000 nnear=2 cutoff=1000 eps=0 leafsize=10 clustype=uniformp
14 sec to build KDtree of 1000000 points
kdtree: 1000 queries looked at av 0.1 % of the 1000000 points, 0.31 % of 188315 boxes; better 0.0042 0.014 0.1 %
3.5 sec to query 1000 points
distances to 2 nearest: av 0.131  max 0.253

kdstats.py p=2 dim=21 N=1000000 nask=1000 nnear=2 cutoff=5000 eps=0 leafsize=10 clustype=uniformp
14 sec to build KDtree of 1000000 points
kdtree: 1000 queries looked at av 0.48 % of the 1000000 points, 1.1 % of 188315 boxes; better 0.0071 0.026 0.5 %
15 sec to query 1000 points
distances to 2 nearest: av 0.131  max 0.245


0

ระยะทางแบบยุคลิดเป็นตัวชี้วัดที่ดีสำหรับการค้นหาเพื่อนบ้านที่ใกล้ที่สุดหรือไม่? ถ้าไม่ใช่ตัวเลือกของฉันคืออะไร

ฉันขอแนะนำให้ทำการจัดกลุ่ม subspace แบบนุ่มนวลซึ่งเป็นวิธีการทั่วไปในปัจจุบันที่มีการคำนวณน้ำหนักของคุณลักษณะเพื่อหาขนาดที่เกี่ยวข้องมากที่สุด คุณสามารถใช้ตุ้มน้ำหนักเหล่านี้ได้เมื่อใช้ระยะทางแบบยุคลิดเช่น ดูคำสาปของขนาดสำหรับปัญหาที่พบบ่อยและบทความนี้สามารถสอนคุณอย่างใด:

อัลกอริทึมการจัดกลุ่มประเภท k-mean สำหรับการทำคลัสเตอร์ย่อยของชุดข้อมูลตัวเลขและหมวดหมู่ผสม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.