# 使用地址匹配的示例
現在我們已經測量了數值和文本距離,我們將花一些時間學習如何將它們組合起來測量具有文本和數字特征的觀察之間的距離。
## 做好準備
最近鄰是一種用于地址匹配的好算法。地址匹配是一種記錄匹配,其中我們在多個數據集中具有地址并且想要匹配它們。在地址匹配中,我們可能在地址,不同城市或不同的郵政編碼中存在拼寫錯誤,但它們可能都指向相同的地址。在地址的數字和字符組件上使用最近鄰居算法可以幫助我們識別實際上相同的地址。
在此示例中,我們將生成兩個數據集。每個數據集將包含街道地址和郵政編碼。但是,一個數據集在街道地址中存在大量拼寫錯誤。我們將非拼寫數據集作為我們的黃金標準,并將為每個拼寫錯誤地址返回一個地址,該地址最接近字符串距離(對于街道)和數字距離(對于郵政編碼)的函數。
代碼的第一部分將側重于生成兩個數據集。然后,代碼的第二部分將運行測試集并返回訓練集中最接近的地址。
## 操作步驟
我們將按如下方式處理秘籍:
1. 我們將從加載必要的庫開始:
```py
import random
import string
import numpy as np
import tensorflow as tf
```
1. 我們現在將創建參考數據集。為了顯示簡潔的輸出,我們只會使每個數據集由`10`地址組成(但它可以運行更多):
```py
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. 要創建測試集,我們需要一個函數,它將在字符串中隨機創建一個拼寫錯誤并返回結果字符串:
```py
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. 現在,我們可以初始化圖會話并聲明我們需要的占位符。我們在每個測試和參考集中需要四個占位符,我們需要一個地址和郵政編碼占位符:
```py
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 距離和地址字符串的編輯距離:
```py
zip_dist = tf.square(tf.subtract(ref_zip, test_zip))
address_dist = tf.edit_distance(test_address, ref_address, normalize=True)
```
1. 我們現在將拉鏈距離和地址距離轉換為相似之處。對于相似性,當兩個輸入完全相同時,我們想要`1`的相似性,當它們非常不同時,我們想要`0`附近。對于拉鏈距離,我們可以通過獲取距離,從最大值減去,然后除以距離的范圍來實現。對于地址相似性,由于距離已經在`0`和`1`之間縮放,我們只需從 1 中減去它以獲得相似性:
```py
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. 為了結合兩個相似度函數,我們將采用兩者的加權平均值。對于這個秘籍,我們對地址和郵政編碼給予同等重視。我們可以根據我們對每個特征的信任程度來改變這一點。然后,我們將返回參考集的最高相似度的索引:
```py
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 中使用編輯距離,我們必須將地址字符串轉換為稀疏向量。在本章的先前秘籍中,使用基于文本的距離,我們創建了以下函數,我們也將在此秘籍中使用它:
```py
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. 我們需要將參考數據集中的地址和郵政編碼分開,以便在循環測試集時將它們提供給占位符:
```py
reference_addresses = [x[0] for x in reference_data]
reference_zips = np.array([[x[1] for x in reference_data]])
```
1. 我們需要使用我們在步驟 8 中創建的函數創建稀疏張量參考地址集:
```py
sparse_ref_set = sparse_from_word_vec(reference_addresses)
```
1. 現在,我們可以循環遍歷測試集的每個條目,并返回它最接近的引用集的索引。我們將為每個條目打印測試和參考集。如您所見,我們在此生成的數據集中獲得了很好的結果:
```py
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))
```
我們將得到以下結果:
```py
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
```
```py
Match : 5167 baker rd, 65154
Address: 8765 donnor st, 65154
Match : 8765 donner st, 65154
```
## 工作原理
在像這樣的地址匹配問題中要弄清楚的一個難點是權重的值以及如何縮放距離。這可能需要對數據本身進行一些探索和洞察。此外,在處理地址時,我們應該考慮除此處使用的組件之外的組件。我們可以將街道號碼視為街道地址的獨立組成部分,甚至可以包含其他組成部分,例如城市和州。
> 處理數字地址組件時,請注意它們可以被視為數字(具有數字距離)或字符(具有編輯距離)。由您決定選擇哪個。請注意,如果我們認為郵政編碼中的拼寫錯誤來自人為錯誤而不是計算機映射錯誤,我們可以考慮使用郵政編碼的編輯距離。
為了了解拼寫錯誤如何影響結果,我們鼓勵讀者更改拼寫錯誤函數以進行更多拼寫錯誤或更頻繁的拼寫錯誤,并增加數據集大小以查看此算法的工作情況。
- TensorFlow 入門
- 介紹
- TensorFlow 如何工作
- 聲明變量和張量
- 使用占位符和變量
- 使用矩陣
- 聲明操作符
- 實現激活函數
- 使用數據源
- 其他資源
- TensorFlow 的方式
- 介紹
- 計算圖中的操作
- 對嵌套操作分層
- 使用多個層
- 實現損失函數
- 實現反向傳播
- 使用批量和隨機訓練
- 把所有東西結合在一起
- 評估模型
- 線性回歸
- 介紹
- 使用矩陣逆方法
- 實現分解方法
- 學習 TensorFlow 線性回歸方法
- 理解線性回歸中的損失函數
- 實現 deming 回歸
- 實現套索和嶺回歸
- 實現彈性網絡回歸
- 實現邏輯回歸
- 支持向量機
- 介紹
- 使用線性 SVM
- 簡化為線性回歸
- 在 TensorFlow 中使用內核
- 實現非線性 SVM
- 實現多類 SVM
- 最近鄰方法
- 介紹
- 使用最近鄰
- 使用基于文本的距離
- 使用混合距離函數的計算
- 使用地址匹配的示例
- 使用最近鄰進行圖像識別
- 神經網絡
- 介紹
- 實現操作門
- 使用門和激活函數
- 實現單層神經網絡
- 實現不同的層
- 使用多層神經網絡
- 改進線性模型的預測
- 學習玩井字棋
- 自然語言處理
- 介紹
- 使用詞袋嵌入
- 實現 TF-IDF
- 使用 Skip-Gram 嵌入
- 使用 CBOW 嵌入
- 使用 word2vec 進行預測
- 使用 doc2vec 進行情緒分析
- 卷積神經網絡
- 介紹
- 實現簡單的 CNN
- 實現先進的 CNN
- 重新訓練現有的 CNN 模型
- 應用 StyleNet 和 NeuralStyle 項目
- 實現 DeepDream
- 循環神經網絡
- 介紹
- 為垃圾郵件預測實現 RNN
- 實現 LSTM 模型
- 堆疊多個 LSTM 層
- 創建序列到序列模型
- 訓練 Siamese RNN 相似性度量
- 將 TensorFlow 投入生產
- 介紹
- 實現單元測試
- 使用多個執行程序
- 并行化 TensorFlow
- 將 TensorFlow 投入生產
- 生產環境 TensorFlow 的一個例子
- 使用 TensorFlow 服務
- 更多 TensorFlow
- 介紹
- 可視化 TensorBoard 中的圖
- 使用遺傳算法
- 使用 k 均值聚類
- 求解常微分方程組
- 使用隨機森林
- 使用 TensorFlow 和 Keras