I. Thước đo khoảng cách
Đầu tiên, số lượng tính năng (cột) trong bộ dữ liệu không phải là yếu tố chọn số liệu khoảng cách để sử dụng trong kNN. Có khá nhiều nghiên cứu được công bố hướng chính xác đến câu hỏi này và các cơ sở thông thường để so sánh là:
phân phối thống kê cơ bản của dữ liệu của bạn;
mối quan hệ giữa các tính năng bao gồm dữ liệu của bạn (chúng độc lập - nghĩa là ma trận hiệp phương sai trông như thế nào); và
không gian tọa độ mà dữ liệu của bạn được lấy.
Nếu bạn không có kiến thức trước về (các) phân phối mà dữ liệu của bạn được lấy mẫu, thì ít nhất một nghiên cứu (được ghi chép đầy đủ và kỹ lưỡng) kết luận rằng khoảng cách Euclide là lựa chọn tốt nhất.
Số liệu YEuclid được sử dụng trong Công cụ khuyến nghị web quy mô lớn cũng như trong nghiên cứu học thuật hiện tại. Khoảng cách được tính toán bởi Euclide có ý nghĩa trực quan và thang đo tính toán - nghĩa là khoảng cách Euclide được tính theo cùng một cách, cho dù hai điểm nằm trong hai chiều hay trong không gian hai mươi hai chiều.
Nó chỉ thất bại với tôi một vài lần, mỗi trường hợp khoảng cách Euclide đều thất bại vì hệ tọa độ cơ bản (cartesian) là một lựa chọn kém. Và bạn sẽ thường nhận ra điều này bởi vì độ dài đường dẫn (khoảng cách) không còn là phụ gia - ví dụ: khi không gian số liệu là bàn cờ, khoảng cách Manhattan tốt hơn Euclide, tương tự khi không gian số liệu là Trái đất và khoảng cách của bạn là trans -Các chuyến bay lục địa, một thước đo khoảng cách phù hợp cho hệ tọa độ cực là một ý tưởng hay (ví dụ: Luân Đôn đến Vienna là 2,5 giờ, Vienna đến St. Petersburg là 3 giờ nữa, ít nhiều theo cùng một hướng, nhưng từ Luân Đôn đến St . Petersburg không phải là 5,5 giờ, thay vào đó, chỉ hơn 3 giờ một chút.)
Nhưng ngoài những trường hợp dữ liệu của bạn thuộc hệ tọa độ không phải cartes, sự lựa chọn số liệu khoảng cách thường không phải là vật chất. (Xem bài đăng trên blog này từ một sinh viên CS, so sánh một số số liệu khoảng cách bằng cách kiểm tra ảnh hưởng của chúng đối với phân loại kNN - chi bình phương cho kết quả tốt nhất, nhưng sự khác biệt không lớn; Một nghiên cứu toàn diện hơn trong bài báo học thuật, Nghiên cứu so sánh về Các hàm khoảng cách cho các hàng xóm gần nhất --Mahalanobis (về cơ bản là Euclide được chuẩn hóa bằng cách tính hiệp phương sai) là tốt nhất trong nghiên cứu này.
Một điều quan trọng: để tính toán số liệu khoảng cách có ý nghĩa, bạn phải chia tỷ lệ lạidữ liệu của bạn - hiếm khi có thể xây dựng mô hình kNN để tạo dự đoán chính xác mà không cần thực hiện việc này. Ví dụ: nếu bạn đang xây dựng mô hình kNN để dự đoán hiệu suất thể thao và các biến kỳ vọng của bạn là chiều cao (cm), cân nặng (kg), bodyfat (%) và xung nghỉ (nhịp đập mỗi phút), thì điểm dữ liệu điển hình có thể trông giống như thế này: [180.4, 66.1, 11.3, 71]. Rõ ràng việc tính toán khoảng cách sẽ bị chi phối bởi chiều cao, trong khi đóng góp của bodyfat% sẽ gần như không đáng kể. Nói cách khác, nếu thay vào đó, dữ liệu được báo cáo khác đi, sao cho trọng lượng cơ thể tính bằng gam chứ không phải kilogam, thì giá trị ban đầu là 86.1, sẽ là 86.100, có ảnh hưởng lớn đến kết quả của bạn, đó chính xác là những gì bạn không không muốn
X_new = (X_old - mu) / sigma
II. Cấu trúc dữ liệu
Nếu bạn lo ngại về hiệu suất của cấu trúc cây kd, A Voronoi Tessname là một thùng chứa đơn giản về mặt khái niệm nhưng điều đó sẽ cải thiện đáng kể hiệu suất và quy mô tốt hơn so với cây kd.
Đây không phải là cách phổ biến nhất để duy trì dữ liệu đào tạo kNN, mặc dù việc áp dụng VT cho mục đích này, cũng như các lợi thế về hiệu suất, được ghi lại rõ ràng (xem ví dụ báo cáo Nghiên cứu của Microsoft ). Ý nghĩa thực tế của điều này là, với điều kiện bạn đang sử dụng ngôn ngữ 'chính thống' (ví dụ: trong Chỉ số TIOBE ) thì bạn nên tìm một thư viện để thực hiện VT. Tôi biết trong Python và R, có nhiều tùy chọn cho mỗi ngôn ngữ (ví dụ: gói voronoi cho R có sẵn trên CRAN )
Sử dụng VT cho kNN hoạt động như thế này ::
Từ dữ liệu của bạn, chọn ngẫu nhiên các điểm w - đây là các trung tâm Voronoi của bạn. Một ô Voronoi đóng gói tất cả các điểm lân cận gần nhất với mỗi trung tâm. Hãy tưởng tượng nếu bạn chỉ định một màu khác nhau cho mỗi trung tâm Voronoi, sao cho mỗi điểm được gán cho một trung tâm nhất định được sơn màu đó. Miễn là bạn có mật độ đủ, thực hiện điều này sẽ hiển thị ranh giới của từng trung tâm Voronoi (như ranh giới phân tách hai màu.
Làm thế nào để chọn Trung tâm Voronoi? Tôi sử dụng hai hướng dẫn trực giao. Sau khi chọn ngẫu nhiên các điểm w, hãy tính VT cho dữ liệu đào tạo của bạn. Tiếp theo, hãy kiểm tra số lượng điểm dữ liệu được gán cho từng trung tâm Voronoi - các giá trị này phải giống nhau (mật độ điểm đồng nhất cho không gian dữ liệu của bạn). Trong hai chiều, điều này sẽ gây ra một VT có các ô có cùng kích thước. Đó là quy tắc đầu tiên, đây là quy tắc thứ hai. Chọn w bằng cách lặp - chạy thuật toán kNN của bạn với w làm tham số biến và đo hiệu suất (thời gian cần thiết để trả về dự đoán bằng cách truy vấn VT).
Vì vậy, hãy tưởng tượng bạn có một triệu điểm dữ liệu ..... Nếu các điểm được duy trì trong cấu trúc dữ liệu 2D thông thường hoặc trong cây kd, bạn sẽ thực hiện trung bình một vài triệu phép tính khoảng cách cho mỗi điểmđiểm dữ liệu mới có biến phản ứng mà bạn muốn dự đoán. Tất nhiên, những tính toán đó được thực hiện trên một tập dữ liệu. Với V / T, tìm kiếm lân cận gần nhất được thực hiện theo hai bước lần lượt, đối với hai quần thể dữ liệu khác nhau - đầu tiên là đối với các trung tâm Voronoi, sau đó khi tìm thấy trung tâm gần nhất, các điểm bên trong ô tương ứng với trung tâm đó được tìm kiếm để tìm người hàng xóm gần nhất thực tế (bằng cách tính toán khoảng cách liên tiếp) Kết hợp lại, hai lần tra cứu này nhanh hơn nhiều so với một lần tra cứu lực lượng vũ phu. Điều đó dễ thấy: đối với các điểm dữ liệu 1M, giả sử bạn chọn 250 trung tâm Voronoi để vận chuyển không gian dữ liệu của mình. Trung bình, mỗi ô Voronoi sẽ có 4.000 điểm dữ liệu. Vì vậy, thay vì thực hiện tính toán khoảng cách trung bình 500.000 (lực lượng vũ phu), bạn thực hiện ít hơn rất nhiều, trung bình chỉ 125 + 2.000.
III. Tính kết quả (biến phản ứng dự đoán)
Có hai bước để tính giá trị dự đoán từ một tập hợp dữ liệu đào tạo kNN. Đầu tiên là xác định n, hoặc số hàng xóm gần nhất sẽ sử dụng cho phép tính này. Thứ hai là làm thế nào để cân nhắc đóng góp của họ với giá trị dự đoán.
Với thành phần đầu tiên, bạn có thể xác định giá trị tốt nhất của n bằng cách giải quyết vấn đề tối ưu hóa (rất giống với tối ưu hóa bình phương tối thiểu). Đó là lý thuyết; Trong thực tế, hầu hết mọi người chỉ sử dụng n = 3. Trong mọi trường hợp, thật đơn giản để chạy thuật toán kNN của bạn qua một tập hợp các trường hợp thử nghiệm (để tính các giá trị dự đoán) cho n = 1, n = 2, n = 3, v.v. và vẽ lỗi là hàm của n. Nếu bạn chỉ muốn một giá trị hợp lý cho n để bắt đầu, một lần nữa, chỉ cần sử dụng n = 3.
Thành phần thứ hai là làm thế nào để cân nhắc sự đóng góp của mỗi người hàng xóm (giả sử n> 1).
Kỹ thuật trọng số đơn giản nhất chỉ là nhân mỗi hàng xóm với một hệ số trọng số, chỉ là 1 / (dist * K), hoặc nghịch đảo khoảng cách từ hàng xóm đó đến thể hiện kiểm tra thường được nhân với một hằng số dẫn xuất theo kinh nghiệm, K. I không phải là một fan hâm mộ của kỹ thuật này bởi vì nó thường quá sức với những người hàng xóm gần nhất (và đồng thời thiếu trọng lượng của những người ở xa hơn); tầm quan trọng của điều này là một dự đoán nhất định có thể gần như hoàn toàn phụ thuộc vào một người hàng xóm duy nhất, điều này làm tăng độ nhạy của thuật toán đối với nhiễu.
Hàm trọng số phải tốt hơn, về cơ bản tránh được giới hạn này là hàm gaussian , trong python, trông như thế này:
def weight_gauss(dist, sig=2.0) :
return math.e**(-dist**2/(2*sig**2))
Để tính giá trị dự đoán bằng mã kNN của bạn, bạn sẽ xác định n hàng xóm gần nhất với điểm dữ liệu có biến phản hồi mà bạn muốn dự đoán ('ví dụ kiểm tra'), sau đó gọi hàm weight_gauss, một lần cho mỗi hàng xóm n, đi qua trong khoảng cách giữa mỗi hàng xóm điểm kiểm tra. Hàm này sẽ trả lại trọng số cho mỗi hàng xóm, sau đó được sử dụng làm hệ số của hàng xóm đó trong phép tính trung bình có trọng số.