![](/img/trans.png)
[英]String Matching Using TF-IDF, NGrams and Cosine Similarity in Python
[英]Matching Company names in Python through Cosine Similarity, TF-IDF and pyspark
我试图将两个列表中的公司名称匹配在一起,以便检查列表A中的公司是否确实在列表B中列出。由于公司名称的书写形式多种多样,我倾向于使用cosing相似。 为此,我遵循了Ran Tavory在此博客上的注释: Link Here
以下是一般概述:
- 在驱动程序上计算TF-IDF矩阵。
- 并行化矩阵A; 广播矩阵B
- 现在,每个工作人员通过将其矩阵A的块与整个矩阵B相乘来平整其工作块。因此,如果一个工作人员在A [0:99]上进行操作,则它将这100行相乘并返回结果,例如A [13 ]匹配在B [21]中找到的名称。 乘法是使用numpy完成的。
- 驱动程序将收集来自不同工作人员的所有结果,并将索引(A [13]和B [21])与原始数据集中的实际名称进行匹配-我们完成了!
我能够运行注释中描述的确切代码,但是其中一部分似乎有点奇怪: b_mat_dist = broadcast_matrix(a_mat)
在广播a_mat以及并行化a_mat时,我得到了每个公司名称都完全匹配的逻辑结果(因为我们正在寻找相同的来源)。
当我尝试广播b_mat时:b_mat_dist = broadcast_matrix(b_mat),出现以下错误: Incompatible dimension for X and Y matrices: X.shape[1] == 56710 while Y.shape[1] == 2418
任何帮助将不胜感激! 提前致谢 !
这是我的代码:
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from pyspark.sql import SQLContext, SparkSession
from pyspark import SparkContext
from scipy.sparse import csr_matrix
vectorizer = TfidfVectorizer()
if 'sc' in locals():
sc.stop()
sc = SparkContext("local", "Simple App")
pd.set_option('display.max_colwidth', -1)
RefB = pd.read_excel('Ref.xlsx')
ToMatchB = pd.read_excel('ToMatch.xlsx')
Ref = RefB['CLT_company_name']
ToMatch = ToMatchB ['Name1']
a_mat = vectorizer.fit_transform(Ref)
b_mat = vectorizer.fit_transform(ToMatch)
def find_matches_in_submatrix(sources, targets, inputs_start_index,
threshold=.8):
cosimilarities = cosine_similarity(sources, targets)
for i, cosimilarity in enumerate(cosimilarities):
cosimilarity = cosimilarity.flatten()
# Find the best match by using argsort()[-1]
target_index = cosimilarity.argsort()[-1]
source_index = inputs_start_index + i
similarity = cosimilarity[target_index]
if cosimilarity[target_index] >= threshold:
yield (source_index, target_index, similarity)
def broadcast_matrix(mat):
bcast = sc.broadcast((mat.data, mat.indices, mat.indptr))
(data, indices, indptr) = bcast.value
bcast_mat = csr_matrix((data, indices, indptr), shape=mat.shape)
return bcast_mat
def parallelize_matrix(scipy_mat, rows_per_chunk=100):
[rows, cols] = scipy_mat.shape
i = 0
submatrices = []
while i < rows:
current_chunk_size = min(rows_per_chunk, rows - i)
submat = scipy_mat[i:i + current_chunk_size]
submatrices.append((i, (submat.data, submat.indices,
submat.indptr),
(current_chunk_size, cols)))
i += current_chunk_size
return sc.parallelize(submatrices)
a_mat_para = parallelize_matrix(a_mat, rows_per_chunk=100)
b_mat_dist = broadcast_matrix(b_mat)
results = a_mat_para.flatMap(
lambda submatrix:
find_matches_in_submatrix(csr_matrix(submatrix[1],
shape=submatrix[2]),
b_mat_dist,
submatrix[0]))
尝试均衡两个TfidVectorizer对象的词汇量:
vect = CountVectorizer()
vocabulary = vect.fit(Ref + ToMatch).vocabulary_
vectorizer = TfidfVectorizer(vocabulary=vocabulary)
同样基于您的目标是:
a_mat = vectorizer.fit_transform(ToMatch)
b_mat = vectorizer.fit_transform(Ref)
对我来说似乎是一个更好的选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.