当前位置:   article > 正文

余弦相似度公式推导及代码实现_余弦相似度的推导过程是什么

余弦相似度的推导过程是什么

1. 为什么使用余弦值相似度?

  • 空间维度上两个点之间相似定义
    • 在空间维度上两个点之间是有夹角和方向,夹角范围在 [0,180]
    • 两个点越相似方向越接近相同方向夹角应该越小,越接近0度
    • 两个点意思相反方向越接近相反方向夹角应该越大,越接近180度
    • 两个点不相似方向垂直夹角应该接近90度
  • 为什么使用余弦值不用正弦值
    • 根据上述相似定义,我们需要找到夹角范围在[0,180]单调性的函数
    • 如下图,正弦值夹角范围在 [0,180],不是单调取值 【不符合】
    • 余弦值夹角范围在 [0,180]具有单调性
      • 夹角0,应该越相似夹角值越大(1)
      • 夹角90,应该无相关性夹角值0
      • 夹角180,应该意思相反夹角值越小(-1)
        在这里插入图片描述
  • 总结
    • 余弦单调性符合我们在空间维度位置的关系,所以使用余弦相似度 【自我理解】

2. 公式推导

2.1 三角函数余弦公式推导

c o s ( θ ) = A B 2 + A C 2 − B C 2 2 ∗ A B ∗ A C

cos(θ)=AB2+AC2BC22ABAC
cos(θ)=2ABACAB2+AC2BC2
在这里插入图片描述

  • 余弦公式
    c o s ( θ ) = A D A C
    cos(θ)=ADAC
    cos(θ)=ACAD
  • 勾股定理原理可得
    A C 2 = A D 2 + C D 2 ( 1 ) B C 2 = B D 2 + C D 2 ( 2 )
    AC2=AD2+CD2(1)BC2=BD2+CD2(2)
    AC2=AD2+CD2(1)BC2=BD2+CD2(2)
  • 公式1-公式2
    A C 2 − B C 2 = A D 2 − B D 2 ( 3 )
    AC2BC2=AD2BD2(3)
    AC2BC2=AD2BD2(3)
  • A B , A D , B D AB,AD,BD AB,AD,BD之间的关系, A D AD AD未知值(但余弦公式需要参数), A B AB AB已知值,所以得到 B D BD BD相关公式,把 B D BD BD消掉
    A B = A D + B D B D = A B − A D ( 4 )
    AB=AD+BDBD=ABAD(4)
    ABBD=AD+BD=ABAD(4)
  • 公式4带入公式3
    A C 2 − B C 2 = A D 2 − ( A B − A D ) 2 A C 2 − B C 2 = A D 2 − A B 2 + 2 ∗ A B ∗ A D − A D 2 A C 2 − B C 2 = − A B 2 + 2 ∗ A B ∗ A D A D = A B 2 + A C 2 − B C 2 2 ∗ A B ( 5 )
    AC2BC2=AD2(ABAD)2AC2BC2=AD2AB2+2ABADAD2AC2BC2=AB2+2ABADAD=AB2+AC2BC22AB(5)
    AC2BC2AC2BC2AC2BC2AD=AD2(ABAD)2=AD2AB2+2ABADAD2=AB2+2ABAD=2ABAB2+AC2BC2(5)
  • 公式5带入余弦公式
    c o s ( θ ) = A D A C = A B 2 + A C 2 − B C 2 2 ∗ A B A C = A B 2 + A C 2 − B C 2 2 ∗ A B ∗ A C
    cos(θ)=ADAC=AB2+AC2BC22ABAC=AB2+AC2BC22ABAC
    cos(θ)=ACAD=AC2ABAB2+AC2BC2=2ABACAB2+AC2BC2

2.2 三角函数向量余弦公式推导

c o s ( θ ) = a ⃗ ∗ b ⃗ ∥ a ∥ ∗ ∥ b ∥

cos(θ)=abab
cos(θ)=aba b

  • 向量公式
    c ⃗ = a ⃗ − b ⃗ ( 1 ) A C = ∥ b ⃗ ∥ ( 2 ) A B = ∥ a ⃗ ∥ ( 3 ) B C = ∥ c ⃗ ∥ ( 4 )
    c=ab(1)AC=∥b(2)AB=∥a(3)BC=∥c(4)
    c ACABBC=a b (1)=∥b (2)=∥a (3)=∥c (4)

    在这里插入图片描述
  • 公式 1 , 2 , 3 , 4 公式1,2,3,4 公式1234带入余弦公式
    c o s ( θ ) = A B 2 + A C 2 − B C 2 2 ∗ A B ∗ A C c o s ( θ ) = ∥ a ⃗ ∥ 2 + ∥ b ⃗ ∥ 2 − ( ∥ a ⃗ − b ⃗ ∥ ) 2 2 ∗ ∥ a ⃗ ∥ ∗ ∥ b ⃗ ∥ c o s ( θ ) = ∥ a ⃗ ∥ 2 + ∥ b ⃗ ∥ 2 − ∥ a ⃗ ∥ 2 + 2 ∗ a ⃗ ∗ b ⃗ − ∥ b ⃗ ∥ 2 2 ∗ ∥ a ⃗ ∥ ∗ ∥ b ⃗ ∥ c o s ( θ ) = a ⃗ ∗ b ⃗ ∥ a ∥ ∗ ∥ b ∥
    cos(θ)=AB2+AC2BC22ABACcos(θ)=a2+b2(ab)22abcos(θ)=a2+b2a2+2abb22abcos(θ)=abab
    cos(θ)cos(θ)cos(θ)cos(θ)=2ABACAB2+AC2BC2=2a b a 2+b 2(a b )2=2a b a 2+b 2a 2+2a b b 2=aba b

3. 余弦相似度代码实现

  • 代码来自于书籍:深度学习进阶:自然语言处理
    import numpy as np
    
    def preprocess(text):
        """
           语料库预处理
    
           :param text:句子字符串
           :return:
                corpus 是单词ID 列表
                word_to_id:是单词到单词 ID 的字典
                id_to_word 是单词 ID 到单词的字典
        """
        text = text.lower().replace('.', ' .') # 单词全为小写
        words = text.split(' ') # 以空格分隔
        word_to_id = {}
        id_to_word = {}
        for word in words:
         if word not in word_to_id:
             new_id = len(word_to_id)
             word_to_id[word] = new_id
             id_to_word[new_id] = word
        corpus = np.array([word_to_id[w] for w in words])
        return corpus, word_to_id, id_to_word
    def create_co_matrix(corpus, vocab_size, window_size=1):
        """
        语料库生成共现矩阵
    
           :param corpus:corpus 是单词 ID 列表
           :param vocab_size:词汇个数
           :param window_size:窗口大小
           :return:
                共现矩阵
        """
        corpus_size = len(corpus)
        co_matrix = np.zeros((vocab_size, vocab_size), dtype=np.int32)
        for idx, word_id in enumerate(corpus):
            for i in range(1, window_size + 1):
                left_idx = idx - i
                right_idx = idx + i
                if left_idx >= 0:
                    left_word_id = corpus[left_idx]
                    co_matrix[word_id, left_word_id] += 1
                if right_idx < corpus_size:
                    right_word_id = corpus[right_idx]
                    co_matrix[word_id, right_word_id] += 1
        return co_matrix
    def cos_similarity(x, y, eps=1e-8):
        """
        余弦相似度函数
    
        :param x:x坐标值
        :param y:y坐标值
        :param eps:默认值为1e-8,防止分母为0
        :return:
            余弦相似度值
        """
        nx = x / (np.sqrt(np.sum(x ** 2)) + eps)
        ny = y / (np.sqrt(np.sum(y ** 2)) + eps)
        return np.dot(nx, ny)
    text = 'I say hello and You say goodbye.'
    corpus, word_to_id, id_to_word = preprocess(text)
    print("corpus为:",corpus)
    print("word_to_id为:",word_to_id)
    print("id_to_word为:",id_to_word)
    vocab_size=len(set(corpus))
    C=create_co_matrix(corpus, vocab_size, window_size=1)
    print("共现矩阵为:",C)
    c0 = C[word_to_id['you']] # you的单词向量
    c1 = C[word_to_id['i']] # i的单词向量
    print('you和i的相似度为',cos_similarity(c0, c1))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/368151
推荐阅读