对于人工智能而言,人工智能算法将向量看作一维数组,每个数组或是每个向量都代表着一组数据.
衡量两个向量的相似程度就需要使用到距离算法.和我们现实世界中的距离类似,越相似的两个向量投影在现实空间中自然离得很近.
例如鸢尾花的五个量值:
5.1,3.5,1.4,0.2,Iris-Setosa
转为向量就变成了
[5.1, 3.5, 1.4, 0.2, 1, 0, 0]
这本质上仍然是一个一维数组.对计算机而言没有区别,只是线性代数将其称作为向量.
向量计算
欧氏距离
在外面熟知的笛卡尔坐标系中,两点间的距离为
这个距离公式是用于处理两个点的距离,换言之,就是两个维度,但是我们需要处理的大部分数据都不止两个维度。
例如我们有三个向量,a,b,c;
a和b之间的欧氏距离为10
ac之间的欧氏距离为20,那么a显然距离b更近,我们就认为a和b更相似。
根据上式的推广,我们可以得出对于任意两个向量的欧氏距离d:
能看出,欧式距离和起点无关,不论是qp还剩pq他们的距离是等价的。
#include <iostream>#include <cmath>const int N = 3; //length or dimensiondouble v1[N],v2[N];double euclidean(double pos1[], double pos2[]){double sum = 0.0;double d = 0.0;for(int i = 0;i < N;i++){d = pos1[i] - pos2[i];sum = sum + d * d;}return sqrt(sum);}int main(){int n = 3;while(--n){v1[n] = n; // 2,1,0v2[n] = n + 10; // 12,11,10}std::cout << euclidean(v1,v2);}
曼哈顿距离
对于欧氏距离而言,欧式距离更像是两个点之间的直线距离,但是在现实生活中或是计算机中,路径的存在都让直线距离很难处理。例如司机需要根据道路来规划路线,不能点到点直线驾驶。计算机也需要规定特定线路或逻辑距离。
为了解决这个问题,在矩阵中“按照路线”行走的距离便是曼哈顿距离
而对于曼哈顿距离的计算也非常简单,只需要将两点间的维度的绝对距离相加即可。
如下:
和欧氏距离一样,传入的参数位置并不影响结果.
#include <iostream>#include <cmath>const int N = 3; //length or dimensiondouble v1[N],v2[N];double manhattan(double pos1[], double pos2[]){double sum = 0.0;double d = 0.0;for(int i = 0;i < N;i++){d = abs(pos1[i] - pos2[i]);sum = sum + d;}return sum;}int main(){int n = 3;while(--n){v1[n] = n;// 2,1,0v2[n] = n + 10;// 12,11,10}std::cout << manhattan(v1,v2);}
切比雪夫距离
切比雪夫距离标明了该点在各维度中的最大值,例如象棋棋盘中需要移动的步数.
在计算机中,有一个更加适合的模型,就是在广度优先搜索中的层数.
例如在目标点的周围所有点都是BFS中的第一层,那么这些围绕着目标点的点距离目标点就都是1.
如下:
#include <iostream>#include <cmath>const int N = 3; //length or dimensiondouble v1[N],v2[N];double max(double a,double b){return a>b?a:b;}double chebyshev(double pos1[], double pos2[]){double result = 0.0;double d = 0.0;for(int i = 0;i < N;i++){d = abs(pos1[i] - pos2[i]);result = max(result, d);}return result;}int main(){int n = 3;while(--n){v1[n] = n;v2[n] = n + 10;}std::cout << chebyshev(v1,v2) <<std::endl;}
