fn predict(&self, k: usize) -> Result<Label, ()> {
        if k > self.neighbors.len() {
            return Err(());
        }

        // TODO: remember prediction counts for some k,
        // and update them when add_example() is called?

        // If the k-th element does not exist or has distance larger
        // than the (k-1)-th element then we don't split ties.
        let ties_d = self.neighbors[k - 1].distance;
        let no_ties = (self.neighbors.len() <= k) || (self.neighbors[k].distance > ties_d);
        // Do self.extra_ties play a part in this prediction?
        let extra_ties_matter = !self.extra_ties.is_empty() && (k == self.neighbors.len());

        if no_ties && !extra_ties_matter {
            return self.predict_no_ties(k);
        }

        // Behold!
        // Follows a couple of hours worth of code craziness which makes
        // our ties splitting code run in O(max_k) (in fact, it's usually going
        // to run in O(k+k_ties), where k_ties is the number of ties,
        // and generally k+k_ties << max_k).
        // We keep two hash maps: one accounting for labels' count (with
        // a placeholder symbol std::usize::MAX when a label is part of ties),
        // and the other one counting labels in ties.
        let mut label_count = HashMap::new();
        let mut ties_label_count = HashMap::new();

        let mut y_pred = 0;
        let mut y_count = 0;
        let mut ties_y_pred = 0;
        let mut ties_y_count = 0;
        // "Symbolic" value for ties label.
        const TIES_LABEL: usize = std::usize::MAX;

        for (i, neigh) in self.neighbors.iter().enumerate() {
            if !approx_eq!(f64, neigh.distance, ties_d) {
                if i >= k {
                    break;
                }
                let count = label_count.entry(neigh.label).or_insert(0);
                *count += 1;
                if *count > y_count {
                    y_pred = neigh.label;
                    y_count = *count;
                }
            } else {
                // Count labels within ties.
                let count = ties_label_count.entry(neigh.label).or_insert(0);
                *count += 1;
                if *count > ties_y_count {
                    ties_y_pred = neigh.label;
                    ties_y_count = *count;
                }
                // We have a special "symbol" for counting
                // how many elements with ties exist: ties_y.
                // However, we only count them up to k.
                let count = label_count.entry(TIES_LABEL).or_insert(0);
                if i >= k {
                    continue;
                }
                *count += 1;
                if *count > y_count {
                    y_pred = TIES_LABEL;
                    y_count = *count;
                }
            }
        }

        // Include self.extra_ties, if extra ties have the same distance
        // as ties_d.
        if Some(ties_d) == self.extra_ties_dist {
            for (y, extra_count) in &self.extra_ties {
                let count = ties_label_count.entry(*y).or_insert(0);
                *count += extra_count;
                if *count > ties_y_count {
                    ties_y_pred = *y;
                    ties_y_count = *count;
                }
            }
        }

        // If the predicted label is the same as the TIES_LABEL placeholder,
        // we can output the best label among ties. Otherwise, we need to
        // count which is the most frequent overall.
        if y_pred == TIES_LABEL {
            y_pred = ties_y_pred;
        } else {
            let mut count = *label_count
                .get(&TIES_LABEL)
                .expect("[!] unexpected error in splitting ties");
            if let Some(c) = label_count.get(&ties_y_pred) {
                count += c;
            }

            if count > y_count {
                y_pred = ties_y_pred;
            }
        }

        Ok(y_pred)
    }
/// Predict label according to k-NN rule, for specified k.
Predict label according to k-NN rule, for specified k.
Predict label according to k - NN rule for specified k .
fn predict(&self, k: usize) -> Result<Label, ()> {
        if k > self.neighbors.len() {
            return Err(());
        }
        // TODO: remember prediction counts for some k,
        // and update them when add_example() is called?
        // If the k-th element does not exist or has distance larger
        // than the (k-1)-th element then we don't split ties.
        let ties_d = self.neighbors[k - 1].distance;
        let no_ties = (self.neighbors.len() <= k) || (self.neighbors[k].distance > ties_d);
        // Do self.extra_ties play a part in this prediction?
        let extra_ties_matter = !self.extra_ties.is_empty() && (k == self.neighbors.len());
        if no_ties && !extra_ties_matter {
            return self.predict_no_ties(k);
        }
        // Behold!
        // Follows a couple of hours worth of code craziness which makes
        // our ties splitting code run in O(max_k) (in fact, it's usually going
        // to run in O(k+k_ties), where k_ties is the number of ties,
        // and generally k+k_ties << max_k).
        // We keep two hash maps: one accounting for labels' count (with
        // a placeholder symbol std::usize::MAX when a label is part of ties),
        // and the other one counting labels in ties.
        let mut label_count = HashMap::new();
        let mut ties_label_count = HashMap::new();
        let mut y_pred = 0;
        let mut y_count = 0;
        let mut ties_y_pred = 0;
        let mut ties_y_count = 0;
        // "Symbolic" value for ties label.
        const TIES_LABEL: usize = std::usize::MAX;
        for (i, neigh) in self.neighbors.iter().enumerate() {
            if !approx_eq!(f64, neigh.distance, ties_d) {
                if i >= k {
                    break;
                }
                let count = label_count.entry(neigh.label).or_insert(0);
                *count += 1;
                if *count > y_count {
                    y_pred = neigh.label;
                    y_count = *count;
                }
            } else {
                // Count labels within ties.
                let count = ties_label_count.entry(neigh.label).or_insert(0);
                *count += 1;
                if *count > ties_y_count {
                    ties_y_pred = neigh.label;
                    ties_y_count = *count;
                }
                // We have a special "symbol" for counting
                // how many elements with ties exist: ties_y.
                // However, we only count them up to k.
                let count = label_count.entry(TIES_LABEL).or_insert(0);
                if i >= k {
                    continue;
                }
                *count += 1;
                if *count > y_count {
                    y_pred = TIES_LABEL;
                    y_count = *count;
                }
            }
        }
        // Include self.extra_ties, if extra ties have the same distance
        // as ties_d.
        if Some(ties_d) == self.extra_ties_dist {
            for (y, extra_count) in &self.extra_ties {
                let count = ties_label_count.entry(*y).or_insert(0);
                *count += extra_count;
                if *count > ties_y_count {
                    ties_y_pred = *y;
                    ties_y_count = *count;
                }
            }
        }
        // If the predicted label is the same as the TIES_LABEL placeholder,
        // we can output the best label among ties. Otherwise, we need to
        // count which is the most frequent overall.
        if y_pred == TIES_LABEL {
            y_pred = ties_y_pred;
        } else {
            let mut count = *label_count
                .get(&TIES_LABEL)
                .expect("[!] unexpected error in splitting ties");
            if let Some(c) = label_count.get(&ties_y_pred) {
                count += c;
            }
            if count > y_count {
                y_pred = ties_y_pred;
            }
        }
        Ok(y_pred)
    }
fn predict ( & self , k : usize ) -> Result < Label , ( ) > { if k > self . neighbors . len ( ) { return Err ( ( ) ) ; } // TODO: remember prediction counts for some k, // and update them when add_example() is called? // If the k-th element does not exist or has distance larger // than the (k-1)-th element then we don't split ties. let ties_d = self . neighbors [ k - 1 ] . distance ; let no_ties = ( self . neighbors . len ( ) <= k ) || ( self . neighbors [ k ] . distance > ties_d ) ; // Do self.extra_ties play a part in this prediction? let extra_ties_matter = ! self . extra_ties . is_empty ( ) && ( k == self . neighbors . len ( ) ) ; if no_ties && ! extra_ties_matter { return self . predict_no_ties ( k ) ; } // Behold! // Follows a couple of hours worth of code craziness which makes // our ties splitting code run in O(max_k) (in fact, it's usually going // to run in O(k+k_ties), where k_ties is the number of ties, // and generally k+k_ties << max_k). // We keep two hash maps: one accounting for labels' count (with // a placeholder symbol std::usize::MAX when a label is part of ties), // and the other one counting labels in ties. let mut label_count = HashMap :: new ( ) ; let mut ties_label_count = HashMap :: new ( ) ; let mut y_pred = 0 ; let mut y_count = 0 ; let mut ties_y_pred = 0 ; let mut ties_y_count = 0 ; // "Symbolic" value for ties label. const TIES_LABEL : usize = std :: usize :: MAX ; for ( i , neigh ) in self . neighbors . iter ( ) . enumerate ( ) { if ! approx_eq ! ( f64 neigh distance ties_d ) { if i >= k { break ; } let count = label_count . entry ( neigh . label ) . or_insert ( 0 ) ; * count += 1 ; if * count > y_count { y_pred = neigh . label ; y_count = * count ; } } else { // Count labels within ties. let count = ties_label_count . entry ( neigh . label ) . or_insert ( 0 ) ; * count += 1 ; if * count > ties_y_count { ties_y_pred = neigh . label ; ties_y_count = * count ; } // We have a special "symbol" for counting // how many elements with ties exist: ties_y. // However, we only count them up to k. let count = label_count . entry ( TIES_LABEL ) . or_insert ( 0 ) ; if i >= k { continue ; } * count += 1 ; if * count > y_count { y_pred = TIES_LABEL ; y_count = * count ; } } } // Include self.extra_ties, if extra ties have the same distance // as ties_d. if Some ( ties_d ) == self . extra_ties_dist { for ( y , extra_count ) in & self . extra_ties { let count = ties_label_count . entry ( * y ) . or_insert ( 0 ) ; * count += extra_count ; if * count > ties_y_count { ties_y_pred = * y ; ties_y_count = * count ; } } } // If the predicted label is the same as the TIES_LABEL placeholder, // we can output the best label among ties. Otherwise, we need to // count which is the most frequent overall. if y_pred == TIES_LABEL { y_pred = ties_y_pred ; } else { let mut count = * label_count . get ( & TIES_LABEL ) . expect ( " " ) ; if let Some ( c ) = label_count . get ( & ties_y_pred ) { count += c ; } if count > y_count { y_pred = ties_y_pred ; } } Ok ( y_pred ) }
Predict label according to k-NN rule, for specified k.
Predict label according to k - NN rule for specified k .
&self
k
usize
&self
k
usize