问题:

A、B、C三位用户都喜欢看电影,他们给自己所喜欢的电影类型打了如下的分:

| | A | B | C | | -------- | -------- | -------- | | 喜剧片 | 3 | 4 | 2 | | 动作片 | 4 | 3 | 5 | | 生活片 | 4 | 5 | 1 | | 恐怖片 | 1 | 1 | 3 | | 爱情片 | 4 | 5 | 1 |

B用户喜欢的电影类型是应该推荐给A还是C?

思路:

用K最近邻(k-nearest neighbours,KNN)算法来解决 找到与B最近的点,如果是A就推荐给A,是C就推荐给C

解答:

php:

<?php

$A = array(3, 4, 4, 1, 4);
$B = array(4, 3, 5, 1, 5);
$C = array(2, 5, 1, 3, 1);

// K最近邻(k-nearest neighbours,KNN)
function KNN($a, $b)
{
    $lenA = count($a);
    $lenB = count($b);
    $len = min($lenA, $lenB);
    $sum = 0;
    for ($i = 0; $i < $len; $i++) {
        $sum += pow($a[$i] - $b[$i], 2);
    }
    return sqrt($sum);
}

echo KNN($B, $A);
echo "\n";
echo KNN($B, $C);
echo "\n";

输出:

2
6.6332495807108

golang:

package main

import (
    "fmt"
    "math"
)

var A = []int{3, 4, 4, 1, 4}
var B = []int{4, 3, 5, 1, 5}
var C = []int{2, 5, 1, 3, 1}

func main() {
    fmt.Println(KNN(B, A))
    fmt.Println(KNN(B, C))
}

func KNN(a, b []int) float64 {
    lenA := len(a)
    lenB := len(b)
    minLen := int(math.Min(float64(lenA), float64(lenB)))
    sum := 0.0
    for i := 0; i < minLen; i++ {
        sum += math.Pow(float64(a[i]-b[i]), 2)
    }
    return math.Sqrt(sum)
}

输出:

2
6.6332495807108