TensorFlow 机器学习秘籍第二版:1~5(5)

本文涉及的产品
图像搜索,7款服务类型 1个月
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: TensorFlow 机器学习秘籍第二版:1~5(5)

TensorFlow 机器学习秘籍第二版:1~5(4)https://developer.aliyun.com/article/1426834

top_k_xvals, top_k_indices = tf.nn.top_k(tf.negative(distance), k=k) 
x_sums = tf.expand_dims(tf.reduce_sum(top_k_xvals, 1),1) 
x_sums_repeated = tf.matmul(x_sums,tf.ones([1, k], tf.float32)) 
x_val_weights = tf.expand_dims(tf.divide(top_k_xvals,x_sums_repeated), 1) 
top_k_yvals = tf.gather(y_target_train, top_k_indices) 
prediction = tf.squeeze(tf.batch_matmul(x_val_weights,top_k_yvals), squeeze_dims=[1]) 
mse = tf.divide(tf.reduce_sum(tf.square(tf.subtract(prediction, y_target_test))), batch_size)
  1. 现在,我们将遍历测试数据并存储预测和准确率值:
num_loops = int(np.ceil(len(x_vals_test)/batch_size)) 
for i in range(num_loops): 
    min_index = i*batch_size 
    max_index = min((i+1)*batch_size,len(x_vals_train)) 
    x_batch = x_vals_test[min_index:max_index] 
    y_batch = y_vals_test[min_index:max_index] 
    predictions = sess.run(prediction, feed_dict={x_data_train: x_vals_train, x_data_test: x_batch, y_target_train: y_vals_train, y_target_test: y_batch}) 
    batch_mse = sess.run(mse, feed_dict={x_data_train: x_vals_train, x_data_test: x_batch, y_target_train: y_vals_train, y_target_test: y_batch}) 
    print('Batch #' + str(i+1) + ' MSE: ' + str(np.round(batch_mse,3))) 
Batch #1 MSE: 23.153
  1. 另外,我们可以查看实际目标值与预测值的直方图。看待这一点的一个原因是要注意这样一个事实:使用平均方法,我们无法预测目标的极端:
bins = np.linspace(5, 50, 45) 
plt.hist(predictions, bins, alpha=0.5, label='Prediction') 
plt.hist(y_batch, bins, alpha=0.5, label='Actual') 
plt.title('Histogram of Predicted and Actual Values') 
plt.xlabel('Med Home Value in $1,000s') 
plt.ylabel('Frequency') 
plt.legend(loc='upper right') 
plt.show()

然后我们将获得直方图,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EeDqAblx-1681566813076)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/tf-ml-cookbook-2e-zh/img/9900e23a-473d-4a23-8864-30cfcc69e691.png)]

图 1:KNN 的预测值和实际目标值的直方图(其中k=4

一个难以确定的是k的最佳值。对于上图和预测,我们将k=4用于我们的模型。我们之所以选择这个,是因为它给了我们最低的 MSE。这通过交叉验证来验证。如果我们在k的多个值上使用交叉验证,我们将看到k=4给我们一个最小的 MSE。我们在下图中说明了这一点。绘制预测值的方差也是值得的,以表明它会随着我们平均的邻居越多而减少:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WshbdZHz-1681566813076)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/tf-ml-cookbook-2e-zh/img/7320b5e5-e41d-4431-9ef1-7fa0b43a5187.png)]

图 2:各种k值的 KNN 预测的 MSE。我们还绘制了测试集上预测值的方差。请注意,随着k的增加,方差会减小。

工作原理

使用最近邻算法,模型是训练集。因此,我们不必在模型中训练任何变量。唯一的参数k是通过交叉验证确定的,以最大限度地减少我们的 MSE。

更多

对于 KNN 的加权,我们选择直接按距离加权。还有其他选择我们也可以考虑。另一种常见方法是通过反平方距离加权。

使用基于文本的距离

最近邻比处理数字更通用。只要我们有一种方法来测量特征之间的距离,我们就可以应用最近邻算法。在本文中,我们将介绍如何使用 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之间的其他文本距离:

名称 描述 公式
汉明距离 相同位置的相等字符的数量。仅在字符串长度相等时有效。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4wy8hFiJ-1681566813077)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/tf-ml-cookbook-2e-zh/img/3f9a30b1-0aff-4c8d-b1ca-f00744f177cf.png)],其中I是相等字符的指示函数。
余弦距离 k差异的点积除以k差异的 L2 范数。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DOKF3Txi-1681566813077)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/tf-ml-cookbook-2e-zh/img/0015e197-fc53-491a-82a0-9d1acfc4b795.png)]
雅克卡距离 共同的字符数除以两个字符串中的字符总和。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LHxVz1kB-1681566813077)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/tf-ml-cookbook-2e-zh/img/b9646b5b-e1cf-4fc1-9099-9dd1c9813b07.png)]

使用混合距离函数的计算

在处理具有多个特征的数据观察时,我们应该意识到特征可以在不同的尺度上以不同的方式缩放。在这个方案中,我们将考虑到这一点,以改善我们的住房价值预测。

准备

扩展最近邻算法很重要,要考虑不同缩放的变量。在这个例子中,我们将说明如何缩放不同变量的距离函数。具体来说,我们将距离函数作为特征方差的函数进行缩放。

加权距离函数的关键是使用权重矩阵。用矩阵运算写的距离函数变为以下公式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ltJfzReg-1681566813077)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/tf-ml-cookbook-2e-zh/img/4b4a519d-305e-4b3b-85b9-2b05a51aaeb7.png)]

这里,A是一个对角线权重矩阵,我们将用它来缩放每个特征的距离度量。

在本文中,我们将尝试在波士顿住房价值数据集上改进我们的 MSE。该数据集是不同尺度上的特征的一个很好的例子,并且最近邻算法将受益于缩放距离函数。

操作步骤

我们将按如下方式处理秘籍:

  1. 首先,我们将加载必要的库并启动图会话:
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import requests
sess = tf.Session()
  1. 接下来,我们将加载数据并将其存储在 NumPy 数组中。再次注意,我们只会使用某些列进行预测。我们不使用 id,也不使用方差非常低的变量:
housing_url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data' 
housing_header = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV'] 
cols_used = ['CRIM', 'INDUS', 'NOX', 'RM', 'AGE', 'DIS', 'TAX', 'PTRATIO', 'B', 'LSTAT'] 
num_features = len(cols_used) 
housing_file = requests.get(housing_url) 
housing_data = [[float(x) for x in y.split(' ') if len(x)>=1] for y in housing_file.text.split('\n') if len(y)>=1] 
y_vals = np.transpose([np.array([y[13] for y in housing_data])]) 
x_vals = np.array([[x for i,x in enumerate(y) if housing_header[i] in cols_used] for y in housing_data])
  1. 现在,我们将x值缩放到 0 到 1 之间,最小 - 最大缩放:
x_vals = (x_vals - x_vals.min(0)) / x_vals.ptp(0)
  1. 然后,我们将创建对角线权重矩阵,该矩阵将通过特征的标准偏差提供距离度量的缩放:
weight_diagonal = x_vals.std(0) 
weight_matrix = tf.cast(tf.diag(weight_diagonal), dtype=tf.float32)
  1. 现在,我们将数据分成训练和测试集。我们还将声明k,最近邻的数量,并使批量大小等于测试集大小:
train_indices = np.random.choice(len(x_vals), round(len(x_vals)*0.8), replace=False) 
test_indices = np.array(list(set(range(len(x_vals))) - set(train_indices))) 
x_vals_train = x_vals[train_indices] 
x_vals_test = x_vals[test_indices] 
y_vals_train = y_vals[train_indices] 
y_vals_test = y_vals[test_indices] 
k = 4 
batch_size=len(x_vals_test)
  1. 我们将声明接下来需要的占位符。我们有四个占位符 - 训练和测试集的[HTG0] - 输入和y - 目标:
x_data_train = tf.placeholder(shape=[None, num_features], dtype=tf.float32) 
x_data_test = tf.placeholder(shape=[None, num_features], dtype=tf.float32) 
y_target_train = tf.placeholder(shape=[None, 1], dtype=tf.float32) 
y_target_test = tf.placeholder(shape=[None, 1], dtype=tf.float32)
  1. 现在,我们可以声明我们的距离函数。为了便于阅读,我们将把距离函数分解为其组件。请注意,我们必须按批量大小平铺权重矩阵,并使用batch_matmul()函数在批量大小中执行批量矩阵乘法:
subtraction_term =  tf.subtract(x_data_train, tf.expand_dims(x_data_test,1)) 
first_product = tf.batch_matmul(subtraction_term, tf.tile(tf.expand_dims(weight_matrix,0), [batch_size,1,1])) 
second_product = tf.batch_matmul(first_product, tf.transpose(subtraction_term, perm=[0,2,1])) 
distance = tf.sqrt(tf.batch_matrix_diag_part(second_product))
  1. 在我们计算每个测试点的所有训练距离之后,我们将需要返回顶部 KNN。我们可以使用top_k()函数执行此操作。由于此函数返回最大值,并且我们想要最小距离,因此我们返回最大的负距离值。然后,我们将预测作为顶部k邻居的距离的加权平均值:
top_k_xvals, top_k_indices = tf.nn.top_k(tf.neg(distance), k=k) 
x_sums = tf.expand_dims(tf.reduce_sum(top_k_xvals, 1),1) 
x_sums_repeated = tf.matmul(x_sums,tf.ones([1, k], tf.float32)) 
x_val_weights = tf.expand_dims(tf.div(top_k_xvals,x_sums_repeated), 1) 
top_k_yvals = tf.gather(y_target_train, top_k_indices) 
prediction = tf.squeeze(tf.batch_matmul(x_val_weights,top_k_yvals), squeeze_dims=[1])
  1. 为了评估我们的模型,我们将计算预测的 MSE:
mse = tf.divide(tf.reduce_sum(tf.square(tf.subtract(prediction, y_target_test))), batch_size)
  1. 现在,我们可以遍历我们的测试批次并计算每个的 MSE:
num_loops = int(np.ceil(len(x_vals_test)/batch_size))
for i in range(num_loops):
    min_index = i*batch_size
    max_index = min((i+1)*batch_size,len(x_vals_train))
    x_batch = x_vals_test[min_index:max_index]
    y_batch = y_vals_test[min_index:max_index]
    predictions = sess.run(prediction, feed_dict={x_data_train: x_vals_train, x_data_test: x_batch, y_target_train: y_vals_train, y_target_test: y_batch})
    batch_mse = sess.run(mse, feed_dict={x_data_train: x_vals_train, x_data_test: x_batch, y_target_train: y_vals_train, y_target_test: y_batch})
    print('Batch #' + str(i+1) + ' MSE: ' + str(np.round(batch_mse,3))) 
Batch #1 MSE: 21.322
  1. 作为最终比较,我们可以使用以下代码绘制实际测试集的住房值分布和测试集的预测:
bins = np.linspace(5, 50, 45) 
plt.hist(predictions, bins, alpha=0.5, label='Prediction') 
plt.hist(y_batch, bins, alpha=0.5, label='Actual') 
plt.title('Histogram of Predicted and Actual Values') 
plt.xlabel('Med Home Value in $1,000s') 
plt.ylabel('Frequency') 
plt.legend(loc='upper right') 
plt.show()

我们将获得前面代码的以下直方图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cucNSBge-1681566813077)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/tf-ml-cookbook-2e-zh/img/5d0b3e2a-6c96-4934-9065-a903836c40e9.png)]

图 3:波士顿数据集上预测房屋价值和实际房屋价值的两个直方图;这一次,我们为每个特征不同地缩放了距离函数

工作原理

我们通过引入一种缩放每个特征的距离函数的方法来减少测试集上的 MSE。在这里,我们通过特征标准偏差的因子来缩放距离函数。这提供了更准确的测量视图,其中测量哪些点是最近的邻居。由此,我们还将顶部k邻域的加权平均值作为距离的函数,以获得住房价值预测。

更多

该缩放因子还可以用于最近邻距离计算中的向下加权或向上加权的特征。这在我们比某些特征更信任某些特征的情况下非常有用。

使用地址匹配的示例

现在我们已经测量了数值和文本距离,我们将花一些时间学习如何将它们组合起来测量具有文本和数字特征的观察之间的距离。

准备

最近邻是一种用于地址匹配的好算法。地址匹配是一种记录匹配,其中我们在多个数据集中具有地址并且想要匹配它们。在地址匹配中,我们可能在地址,不同城市或不同的邮政编码中存在拼写错误,但它们可能都指向相同的地址。在地址的数字和字符组件上使用最近邻算法可以帮助我们识别实际上相同的地址。

在此示例中,我们将生成两个数据集。每个数据集将包含街道地址和邮政编码。但是,一个数据集在街道地址中存在大量拼写错误。我们将非拼写数据集作为我们的黄金标准,并将为每个拼写错误地址返回一个地址,该地址最接近字符串距离(对于街道)和数字距离(对于邮政编码)的函数。

代码的第一部分将侧重于生成两个数据集。然后,代码的第二部分将运行测试集并返回训练集中最接近的地址。

操作步骤

我们将按如下方式处理秘籍:

  1. 我们将从加载必要的库开始:
import random 
import string 
import numpy as np 
import tensorflow as tf
  1. 我们现在将创建参考数据集。为了显示简洁的输出,我们只会使每个数据集由10地址组成(但它可以运行更多):
n = 10 street_names = ['abbey', 'baker', 'canal', 'donner', 'elm']
street_types = ['rd', 'st', 'ln', 'pass', 'ave'] 
rand_zips = [random.randint(65000,65999) for i in range(5)] 
numbers = [random.randint(1, 9999) for i in range(n)] 
streets = [random.choice(street_names) for i in range(n)] 
street_suffs = [random.choice(street_types) for i in range(n)] 
zips = [random.choice(rand_zips) for i in range(n)] 
full_streets = [str(x) + ' ' + y + ' ' + z for x,y,z in zip(numbers, streets, street_suffs)] 
reference_data = [list(x) for x in zip(full_streets,zips)]
  1. 要创建测试集,我们需要一个函数,它将在字符串中随机创建一个拼写错误并返回结果字符串:
def create_typo(s, prob=0.75):
    if random.uniform(0,1) < prob:
        rand_ind = random.choice(range(len(s)))
        s_list = list(s)
        s_list[rand_ind]=random.choice(string.ascii_lowercase)
        s = ''.join(s_list)
    return s
typo_streets = [create_typo(x) for x in streets]
typo_full_streets = [str(x) + ' ' + y + ' ' + z for x,y,z in zip(numbers, typo_streets, street_suffs)]
test_data = [list(x) for x in zip(typo_full_streets,zips)]
  1. 现在,我们可以初始化图会话并声明我们需要的占位符。我们在每个测试和参考集中需要四个占位符,我们需要一个地址和邮政编码占位符:
sess = tf.Session() 
test_address = tf.sparse_placeholder( dtype=tf.string) 
test_zip = tf.placeholder(shape=[None, 1], dtype=tf.float32) 
ref_address = tf.sparse_placeholder(dtype=tf.string) 
ref_zip = tf.placeholder(shape=[None, n], dtype=tf.float32)
  1. 现在,我们将声明数字拉链距离和地址字符串的编辑距离:
zip_dist = tf.square(tf.subtract(ref_zip, test_zip)) 
address_dist = tf.edit_distance(test_address, ref_address, normalize=True)
  1. 我们现在将拉链距离和地址距离转换为相似之处。对于相似性,当两个输入完全相同时,我们想要1的相似性,当它们非常不同时,我们想要0附近。对于拉链距离,我们可以通过获取距离,从最大值减去,然后除以距离的范围来实现。对于地址相似性,由于距离已经在01之间缩放,我们只需从 1 中减去它以获得相似性:
zip_max = tf.gather(tf.squeeze(zip_dist), tf.argmax(zip_dist, 1)) 
zip_min = tf.gather(tf.squeeze(zip_dist), tf.argmin(zip_dist, 1)) 
zip_sim = tf.divide(tf.subtract(zip_max, zip_dist), tf.subtract(zip_max, zip_min)) 
address_sim = tf.subtract(1., address_dist)
  1. 为了结合两个相似度函数,我们将采用两者的加权平均值。对于这个秘籍,我们对地址和邮政编码给予同等重视。我们可以根据我们对每个特征的信任程度来改变这一点。然后,我们将返回参考集的最高相似度的索引:
address_weight = 0.5 
zip_weight = 1\. - address_weight 
weighted_sim = tf.add(tf.transpose(tf.multiply(address_weight, address_sim)), tf.multiply(zip_weight, zip_sim)) 
top_match_index = tf.argmax(weighted_sim, 1)
  1. 为了在 TensorFlow 中使用编辑距离,我们必须将地址字符串转换为稀疏向量。在本章的先前秘籍中,使用基于文本的距离,我们创建了以下函数,我们也将在此秘籍中使用它:
def sparse_from_word_vec(word_vec): 
    num_words = len(word_vec) 
    indices = [[xi, 0, yi] for xi,x in enumerate(word_vec) for yi,y in enumerate(x)] 
    chars = list(''.join(word_vec)) 
    # Now we return our sparse vector 
    return tf.SparseTensorValue(indices, chars, [num_words,1,1])
  1. 我们需要将参考数据集中的地址和邮政编码分开,以便在循环测试集时将它们提供给占位符:
reference_addresses = [x[0] for x in reference_data] 
reference_zips = np.array([[x[1] for x in reference_data]])
  1. 我们需要使用我们在步骤 8 中创建的函数创建稀疏张量参考地址集:
sparse_ref_set = sparse_from_word_vec(reference_addresses)
  1. 现在,我们可以循环遍历测试集的每个条目,并返回它最接近的引用集的索引。我们将为每个条目打印测试和参考集。如您所见,我们在此生成的数据集中获得了很好的结果:
for i in range(n): 
    test_address_entry = test_data[i][0] 
    test_zip_entry = [[test_data[i][1]]] 
    # Create sparse address vectors 
    test_address_repeated = [test_address_entry] * n 
    sparse_test_set = sparse_from_word_vec(test_address_repeated) 
    feeddict={test_address: sparse_test_set, 
               test_zip: test_zip_entry, 
               ref_address: sparse_ref_set, 
               ref_zip: reference_zips} 
    best_match = sess.run(top_match_index, feed_dict=feeddict)
    best_street = reference_addresses[best_match[0]]
    [best_zip] = reference_zips[0][best_match]
    [[test_zip_]] = test_zip_entry
    print('Address: ' + str(test_address_entry) + ', ' + str(test_zip_))
    print('Match : ' + str(best_street) + ', ' + str(best_zip))

我们将得到以下结果:

Address: 8659 beker ln, 65463 
Match  : 8659 baker ln, 65463 
Address: 1048 eanal ln, 65681 
Match  : 1048 canal ln, 65681 
Address: 1756 vaker st, 65983 
Match  : 1756 baker st, 65983 
Address: 900 abbjy pass, 65983 
Match  : 900 abbey pass, 65983 
Address: 5025 canal rd, 65463 
Match  : 5025 canal rd, 65463 
Address: 6814 elh st, 65154 
Match  : 6814 elm st, 65154 
Address: 3057 cagal ave, 65463 
Match  : 3057 canal ave, 65463 
Address: 7776 iaker ln, 65681 
Match  : 7776 baker ln, 65681 
Address: 5167 caker rd, 65154
Match  : 5167 baker rd, 65154 
Address: 8765 donnor st, 65154 
Match  : 8765 donner st, 65154

工作原理

在像这样的地址匹配问题中要弄清楚的一个难点是权重的值以及如何缩放距离。这可能需要对数据本身进行一些探索和洞察。此外,在处理地址时,我们应该考虑除此处使用的组件之外的组件。我们可以将街道号码视为街道地址的独立组成部分,甚至可以包含其他组成部分,例如城市和州。

处理数字地址组件时,请注意它们可以被视为数字(具有数字距离)或字符(具有编辑距离)。由您决定选择哪个。请注意,如果我们认为邮政编码中的拼写错误来自人为错误而不是计算机映射错误,我们可以考虑使用邮政编码的编辑距离。

为了了解拼写错误如何影响结果,我们鼓励读者更改拼写错误函数以进行更多拼写错误或更频繁的拼写错误,并增加数据集大小以查看此算法的工作情况。

使用最近邻进行图像识别

最近邻也可用于图像识别。图像识别数据集的问题世界是 MNIST 手写数字数据集。由于我们将在后面的章节中将此数据集用于各种神经网络图像识别算法,因此将结果与非神经网络算法进行比较将会很棒。

准备

MNIST 数字数据集由数千个大小为28×28像素的标记图像组成。虽然这被认为是一个小图像,但它对于最近邻算法总共有 784 个像素(或特征)。我们将通过考虑最近的k邻居(k=4,在该示例中)的模式预测来计算该分类问题的最近邻预测。

操作步骤

我们将按如下方式处理秘籍:

  1. 我们将从加载必要的库开始。请注意,我们还将导入 Python 图像库(PIL),以便能够绘制预测输出的样本。 TensorFlow 有一个内置方法来加载我们将使用的 MNIST 数据集,如下所示:
import random 
import numpy as np 
import tensorflow as tf 
import matplotlib.pyplot as plt 
from PIL import Image 
from tensorflow.examples.tutorials.mnist import input_data
  1. 现在,我们将启动图会话并以单热编码形式加载 MNIST 数据:
sess = tf.Session() 
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

单热编码是更适合数值计算的分类值的数值表示。这里,我们有 10 个类别(数字 0-9),并将它们表示为长度为 10 的 0-1 向量。例如,类别 0 由向量1,0,0,0,0,0表示,类别 1 用0,1,0,0,0,0表示,依此类推。

  1. 因为 MNIST 数据集很大并且计算数万个输入上的 784 个特征之间的距离在计算上是困难的,所以我们将采样一组较小的图像来训练。此外,我们将选择一个可被 6 整除的测试集编号,仅用于绘图目的,因为我们将绘制最后一批六个图像以查看结果的示例:
train_size = 1000 
test_size = 102 
rand_train_indices = np.random.choice(len(mnist.train.images), train_size, replace=False) 
rand_test_indices = np.random.choice(len(mnist.test.images), test_size, replace=False) 
x_vals_train = mnist.train.images[rand_train_indices] 
x_vals_test = mnist.test.images[rand_test_indices] 
y_vals_train = mnist.train.labels[rand_train_indices] 
y_vals_test = mnist.test.labels[rand_test_indices]
  1. 我们将声明我们的k值和批量大小:
k = 4 
batch_size=6
  1. 现在,我们将初始化将添加到图中的占位符:
x_data_train = tf.placeholder(shape=[None, 784], dtype=tf.float32) 
x_data_test = tf.placeholder(shape=[None, 784], dtype=tf.float32) 
y_target_train = tf.placeholder(shape=[None, 10], dtype=tf.float32) 
y_target_test = tf.placeholder(shape=[None, 10], dtype=tf.float32)
  1. 然后我们将声明我们的距离度量。在这里,我们将使用 L1 度量(绝对值):
distance = tf.reduce_sum(tf.abs(tf.subtract(x_data_train, tf.expand_dims(x_data_test,1))), reduction_indices=2)

请注意,我们也可以使用以下代码来改变距离函数:distance = tf.sqrt(tf.reduce_sum(tf.square(tf.subtract(x_data_train, tf.expand_dims(x_data_test,1))), reduction_indices=1))

  1. 现在,我们将找到最接近的顶级k图像并预测模式。该模式将在单热编码索引上执行,计数最多:
top_k_xvals, top_k_indices = tf.nn.top_k(tf.negative(distance), k=k) 
prediction_indices = tf.gather(y_target_train, top_k_indices) 
count_of_predictions = tf.reduce_sum(prediction_indices, reduction_indices=1) 
prediction = tf.argmax(count_of_predictions)
  1. 我们现在可以遍历我们的测试集,计算预测并存储它们,如下所示:
num_loops = int(np.ceil(len(x_vals_test)/batch_size)) 
test_output = [] 
actual_vals = [] 
for i in range(num_loops): 
    min_index = i*batch_size 
    max_index = min((i+1)*batch_size,len(x_vals_train)) 
    x_batch = x_vals_test[min_index:max_index] 
    y_batch = y_vals_test[min_index:max_index] 
    predictions = sess.run(prediction, feed_dict={x_data_train: x_vals_train, x_data_test: x_batch, y_target_train: y_vals_train, y_target_test: y_batch}) 
    test_output.extend(predictions) 
    actual_vals.extend(np.argmax(y_batch, axis=1))
  1. 现在我们已经保存了实际和预测的输出,我们可以计算出准确率。由于我们对测试/训练数据集进行随机抽样,这会发生变化,但最终我们的准确率值应该在 80%-90% 左右:
accuracy = sum([1./test_size for i in range(test_size) if test_output[i]==actual_vals[i]]) 
print('Accuracy on test set: ' + str(accuracy)) 
Accuracy on test set: 0.8333333333333325
  1. 以下是绘制前面批量结果的代码:
actuals = np.argmax(y_batch, axis=1) 
Nrows = 2 
Ncols = 3 
for i in range(len(actuals)): 
    plt.subplot(Nrows, Ncols, i+1) 
    plt.imshow(np.reshape(x_batch[i], [28,28]), cmap='Greys_r') 
    plt.title('Actual: ' + str(actuals[i]) + ' Pred: ' + str(predictions[i]), fontsize=10) 
    frame = plt.gca() 
    frame.axes.get_xaxis().set_visible(False) 
    frame.axes.get_yaxis().set_visible(False)

结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EC6Yi8jJ-1681566813078)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/tf-ml-cookbook-2e-zh/img/37d1bd73-254f-4a86-b749-9d0b476f388b.png)]

图 4:我们运行最近邻预测的最后一批六个图像。我们可以看到,我们并没有完全正确地获得所有图像。

工作原理

给定足够的计算时间和计算资源,我们可以使测试和训练集更大。这可能会提高我们的准确率,也是防止过拟合的常用方法。另外,请注意,此算法需要进一步探索理想的k值进行选择。可以在数据集上进行一组交叉验证实验后选择k值。

更多

我们还可以使用最近邻算法来评估用户看不见的数字。有关使用此模型评估用户输入数字的方法,请参阅在线仓库

在本章中,我们探讨了如何使用 KNN 算法进行回归和分类。我们讨论了距离函数的不同用法,以及如何将它们混合在一起。我们鼓励读者探索不同的距离度量,权重和k值,以优化这些方法的准确率。

相关文章
|
8天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
28 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
19天前
|
机器学习/深度学习 TensorFlow API
机器学习实战:TensorFlow在图像识别中的应用探索
【10月更文挑战第28天】随着深度学习技术的发展,图像识别取得了显著进步。TensorFlow作为Google开源的机器学习框架,凭借其强大的功能和灵活的API,在图像识别任务中广泛应用。本文通过实战案例,探讨TensorFlow在图像识别中的优势与挑战,展示如何使用TensorFlow构建和训练卷积神经网络(CNN),并评估模型的性能。尽管面临学习曲线和资源消耗等挑战,TensorFlow仍展现出广阔的应用前景。
47 5
|
1月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
56 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
2月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
107 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
3月前
|
持续交付 测试技术 jenkins
JSF 邂逅持续集成,紧跟技术热点潮流,开启高效开发之旅,引发开发者强烈情感共鸣
【8月更文挑战第31天】在快速发展的软件开发领域,JavaServer Faces(JSF)这一强大的Java Web应用框架与持续集成(CI)结合,可显著提升开发效率及软件质量。持续集成通过频繁的代码集成及自动化构建测试,实现快速反馈、高质量代码、加强团队协作及简化部署流程。以Jenkins为例,配合Maven或Gradle,可轻松搭建JSF项目的CI环境,通过JUnit和Selenium编写自动化测试,确保每次构建的稳定性和正确性。
62 0
|
3月前
|
缓存 开发者 测试技术
跨平台应用开发必备秘籍:运用 Uno Platform 打造高性能与优雅设计兼备的多平台应用,全面解析从代码共享到最佳实践的每一个细节
【8月更文挑战第31天】Uno Platform 是一种强大的工具,允许开发者使用 C# 和 XAML 构建跨平台应用。本文探讨了 Uno Platform 中实现跨平台应用的最佳实践,包括代码共享、平台特定功能、性能优化及测试等方面。通过共享代码、采用 MVVM 模式、使用条件编译指令以及优化性能,开发者可以高效构建高质量应用。Uno Platform 支持多种测试方法,确保应用在各平台上的稳定性和可靠性。这使得 Uno Platform 成为个人项目和企业应用的理想选择。
66 0
|
3月前
|
API UED 开发者
如何在Uno Platform中轻松实现流畅动画效果——从基础到优化,全方位打造用户友好的动态交互体验!
【8月更文挑战第31天】在开发跨平台应用时,确保用户界面流畅且具吸引力至关重要。Uno Platform 作为多端统一的开发框架,不仅支持跨系统应用开发,还能通过优化实现流畅动画,增强用户体验。本文探讨了Uno Platform中实现流畅动画的多个方面,包括动画基础、性能优化、实践技巧及问题排查,帮助开发者掌握具体优化策略,提升应用质量与用户满意度。通过合理利用故事板、减少布局复杂性、使用硬件加速等技术,结合异步方法与预设缓存技巧,开发者能够创建美观且流畅的动画效果。
81 0
|
3月前
|
UED 存储 数据管理
深度解析 Uno Platform 离线状态处理技巧:从网络检测到本地存储同步,全方位提升跨平台应用在无网环境下的用户体验与数据管理策略
【8月更文挑战第31天】处理离线状态下的用户体验是现代应用开发的关键。本文通过在线笔记应用案例,介绍如何使用 Uno Platform 优雅地应对离线状态。首先,利用 `NetworkInformation` 类检测网络状态;其次,使用 SQLite 实现离线存储;然后,在网络恢复时同步数据;最后,通过 UI 反馈提升用户体验。
94 0
|
3月前
|
开发者 算法 虚拟化
惊爆!Uno Platform 调试与性能分析终极攻略,从工具运用到代码优化,带你攻克开发难题成就完美应用
【8月更文挑战第31天】在 Uno Platform 中,调试可通过 Visual Studio 设置断点和逐步执行代码实现,同时浏览器开发者工具有助于 Web 版本调试。性能分析则利用 Visual Studio 的性能分析器检查 CPU 和内存使用情况,还可通过记录时间戳进行简单分析。优化性能涉及代码逻辑优化、资源管理和用户界面简化,综合利用平台提供的工具和技术,确保应用高效稳定运行。
84 0
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
阿里云人工智能平台 PAI 团队发表的图像编辑算法论文在 MM2024 上正式亮相发表。ACM MM(ACM国际多媒体会议)是国际多媒体领域的顶级会议,旨在为研究人员、工程师和行业专家提供一个交流平台,以展示在多媒体领域的最新研究成果、技术进展和应用案例。其主题涵盖了图像处理、视频分析、音频处理、社交媒体和多媒体系统等广泛领域。此次入选标志着阿里云人工智能平台 PAI 在图像编辑算法方面的研究获得了学术界的充分认可。
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024

热门文章

最新文章

下一篇
无影云桌面