【发布时间】:2018-12-02 08:37:01
【问题描述】:
我有一个包含两列的数据集:客户id 和addresses:
id addresses
1111 asturias 32, benito juarez, CDMX
1111 JOSE MARIA VELASCO, CDMX
1111 asturias 32 DEPT 401, INSURGENTES, CDMX
1111 deportes
1111 asturias 32, benito juarez, MIXCOAC, CDMX
1111 cd. de los deportes
1111 deportes, wisconsin
2222 TORRE REFORMA LATINO, CDMX
2222 PERISUR 2890
2222 WE WORK, CDMX
2222 WEWORK, TORRE REFORMA LATINO, CDMX
2222 PERISUR: 2690, COYOCAN
2222 TORRE REFORMA LATINO
我有兴趣为每个客户找到不同地址的数量。比如客户id1111,有3个不同的地址:
[asturias 32, benito juarez, CDMX, asturias 32 DEPT 401, INSURGENTES, CDMX, asturias 32, benito juarez, MIXCOAC, CDMX][JOSE MARIA VELASCO, CDMX][deportes, cd. de los deportes, deportes, wisconsin]
我用python写了一段代码,只能显示两个连续行之间的相似性:行i和行i+1(0分表示完全不同,1表示完全相似)。
id addresses score
1111 asturias 32, benito juarez, CDMX 0
1111 JOSE MARIA VELASCO, CDMX 0
1111 asturias 32 DEPT 401, INSURGENTES, CDMX 0
1111 deportes 0
1111 asturias 32, benito juarez, MIXCOAC, CDMX 0
1111 cd. de los deportes 0.21
1111 deportes, wisconsin 0
2222 TORRE REFORMA LATINO, CDMX 0
2222 PERISUR 2890 0
2222 WE WORK, CDMX 0.69
2222 WEWORK, TORRE REFORMA LATINO, CDMX 0
2222 PERISUR: 2690, COYOCAN 0
2222 TORRE REFORMA LATINO
如果分数 > 0.20,我认为它们是两个不同的地址。以下是我的代码:
import nltk
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import re
import unicodedata
import unidecode
import string
from sklearn.feature_extraction.text import TfidfVectorizer
data=pd.read_csv('address.csv')
nltk.download('punkt')
stemmer = nltk.stem.porter.PorterStemmer()
remove_punctuation_map = dict((ord(char), None) for char in string.punctuation)
def stem_tokens(tokens):
return [stemmer.stem(item) for item in tokens]
'''remove punctuation, lowercase, stem'''
def normalize(text):
return stem_tokens(
nltk.word_tokenize(text.lower().translate(remove_punctuation_map)))
vectorizer = TfidfVectorizer(tokenizer=normalize, stop_words='english')
def cosine_sim(text1, text2):
tfidf = vectorizer.fit_transform([text1, text2])
return ((tfidf * tfidf.T).A)[0, 1]
cnt = np.array(np.arange(0, 5183))
indx = []
for i in cnt:
print cosine_sim(data['address'][i], data['address'][i + 1])
但上面的代码无法比较特定客户id 的每个可能行。我想要如下输出:
id unique address
1111 3
2222 3
3333 2
【问题讨论】:
-
对于地址,首先确定地址的标准元素会更好吗?城镇、邮政编码、街道等,然后将它们分类到单独的列中:例如为街道名称编写正则表达式:
re.compile(r'([0-9]+[A-z]?) ([-\.A-z0-9 ]+ (?:street|place|close))'),如果您使用来自有限数量国家的数据等,请使用所有城市名称的列表 -
您的问题是什么?您是要解析数据还是要询问多维余弦差异?
-
我想做多维余弦差分。例如,如果客户进行了 4 笔交易,有 4 个地址,比如 add1、add2、add3、add4,我想计算 4C2 = 6 个组合的余弦差:(add1, ad2), (add1, add3), (add1 , add4), (add2, add3), (add2, add4), (add3, add4)。我想为每一位客户做这件事。
-
你试过我的答案了吗?
标签: python numpy scikit-learn nlp nltk