使用基于文本的距离

最近邻居比处理数字更通用。只要我们有一种方法来测量特征之间的距离,我们就可以应用最近邻算法。在本文中,我们将介绍如何使用 TensorFlow 测量文本距离。

做好准备

在本文中,我们将说明如何在字符串之间使用 TensorFlow 的文本距离度量,Levenshtein 距离(编辑距离)。这将在本章后面重要,因为我们扩展了最近邻方法以包含带有文本的特征。

Levenshtein 距离是从一个字符串到另一个字符串的最小编辑次数。允许的编辑是插入字符,删除字符或用不同的字符替换字符。对于这个秘籍,我们将使用 TensorFlow 的 Levenshtein 距离函数edit_distance()。值得说明这个函数的用法,因为它的用法将适用于后面的章节。

请注意,TensorFlow 的edit_distance()函数仅接受稀疏张量。我们必须创建我们的字符串作为单个字符的稀疏张量。

操作步骤

  1. 首先,我们将加载 TensorFlow 并初始化图:
import tensorflow as tf 
sess = tf.Session()
  1. 然后,我们将说明如何计算两个单词'bear''beer'之间的编辑距离。首先,我们将使用 Python 的list()函数从我们的字符串创建一个字符列表。接下来,我们将从该列表中创建一个稀疏的 3D 矩阵。我们必须告诉 TensorFlow 字符索引,矩阵的形状以及我们在张量中想要的字符。之后,我们可以决定是否要使用总编辑距离(normalize=False)或标准化编辑距离(normalize=True),我们将编辑距离除以第二个单词的长度:
hypothesis = list('bear') 
truth = list('beers') 
h1 = tf.SparseTensor([[0,0,0], [0,0,1], [0,0,2], [0,0,3]], 
                     hypothesis, [1,1,1]) 
t1 = tf.SparseTensor([[0,0,0], [0,0,1], [0,0,1], [0,0,3],[0,0,4]], truth, [1,1,1]) 

print(sess.run(tf.edit_distance(h1, t1, normalize=False))) 

[[ 2.]]

TensorFlow 的文档将两个字符串视为提议(假设)字符串和基础事实字符串。我们将在这里用ht张量继续这个表示法。函数SparseTensorValue()是一种在 TensorFlow 中创建稀疏张量的方法。它接受我们希望创建的稀疏张量的索引,值和形状。

  1. 接下来,我们将说明如何将两个单词bearbeer与另一个单词beers进行比较。为了达到这个目的,我们必须复制beers以获得相同数量的可比词:
hypothesis2 = list('bearbeer') 
truth2 = list('beersbeers') 
h2 = tf.SparseTensor([[0,0,0], [0,0,1], [0,0,2], [0,0,3], [0,1,0], [0,1,1], [0,1,2], [0,1,3]], hypothesis2, [1,2,4]) 
t2 = tf.SparseTensor([[0,0,0], [0,0,1], [0,0,2], [0,0,3], [0,0,4], [0,1,0], [0,1,1], [0,1,2], [0,1,3], [0,1,4]], truth2, [1,2,5]) 

print(sess.run(tf.edit_distance(h2, t2, normalize=True))) 

[[ 0.40000001  0.2      ]]
  1. 在此示例中显示了将一组单词与另一单词进行比较的更有效方法。我们将事先为假设和基本真实字符串创建索引和字符列表:
hypothesis_words = ['bear','bar','tensor','flow'] 
truth_word = ['beers''] 
num_h_words = len(hypothesis_words) 
h_indices = [[xi, 0, yi] for xi,x in enumerate(hypothesis_words) for yi,y in enumerate(x)] 
h_chars = list(''.join(hypothesis_words)) 
h3 = tf.SparseTensor(h_indices, h_chars, [num_h_words,1,1]) 
truth_word_vec = truth_word*num_h_words 
t_indices = [[xi, 0, yi] for xi,x in enumerate(truth_word_vec) for yi,y in enumerate(x)] 
t_chars = list(''.join(truth_word_vec)) 
t3 = tf.SparseTensor(t_indices, t_chars, [num_h_words,1,1]) 

print(sess.run(tf.edit_distance(h3, t3, normalize=True))) 

[[ 0.40000001]
 [ 0.60000002]
 [ 0.80000001]
 [ 1\.        ]]
  1. 现在,我们将说明如何使用占位符计算两个单词列表之间的编辑距离。这个概念是一样的,除了我们将SparseTensorValue()而不是稀疏张量。首先,我们将创建一个从单词列表创建稀疏张量的函数:
def create_sparse_vec(word_list): 
    num_words = len(word_list) 
    indices = [[xi, 0, yi] for xi,x in enumerate(word_list) for yi,y in enumerate(x)] 
    chars = list(''.join(word_list)) 
    return(tf.SparseTensorValue(indices, chars, [num_words,1,1])) 

hyp_string_sparse = create_sparse_vec(hypothesis_words) 
truth_string_sparse = create_sparse_vec(truth_word*len(hypothesis_words)) 

hyp_input = tf.sparse_placeholder(dtype=tf.string) 
truth_input = tf.sparse_placeholder(dtype=tf.string) 

edit_distances = tf.edit_distance(hyp_input, truth_input, normalize=True) 

feed_dict = {hyp_input: hyp_string_sparse, 
             truth_input: truth_string_sparse} 

print(sess.run(edit_distances, feed_dict=feed_dict)) 

[[ 0.40000001]
 [ 0.60000002]
 [ 0.80000001]
 [ 1\.        ]]

工作原理

在这个秘籍中,我们展示了我们可以使用 TensorFlow 以多种方式测量文本距离。这对于在具有文本特征的数据上执行最近邻居非常有用。当我们执行地址匹配时,我们将在本章后面看到更多内容。

更多

我们应该讨论其他文本距离指标。这是一个定义表,描述了两个字符串s1s2之间的其他文本距离:

名称 描述 公式
汉明距离 相同位置的相等字符的数量。仅在字符串长度相等时有效。 ,其中I是相等字符的指示函数。
余弦距离 k - 差异的点积除以k - 差异的 L2 范数。
雅克卡距离 共同的字符数除以两个字符串中的字符总和。

results matching ""

    No results matching ""