使用word2vec对类别中的单词进行分类
Using word2vec to classify words in categories
背景
我有一些带有样本数据的向量,每个向量都有一个类别名称(地点、颜色、名称)。
['john','jay','dan','nathan','bob'] -> 'Names'
['yellow', 'red','green'] -> 'Colors'
['tokyo','bejing','washington','mumbai'] -> 'Places'
我的 objective 是训练一个模型,该模型接受一个新的输入字符串并预测它属于哪个类别。例如,如果新输入是 "purple",那么我应该能够预测 'Colors' 是正确的类别。如果新输入是 "Calgary",它应该将 'Places' 预测为正确的类别。
方法
我做了一些研究并发现了 Word2vec。这个库有一个我可以使用的 "similarity" 和 "mostsimilarity" 函数。所以我想到的一种蛮力方法如下:
- 接受新的输入。
- 计算它与每个向量中每个单词的相似度并取平均值。
因此,例如对于输入 "pink" 我可以计算它与向量中单词的相似度 "names" 取平均值,然后对其他 2 个向量也这样做。给我最高相似度平均值的向量将是输入所属的正确向量。
问题
鉴于我在 NLP 和机器学习方面的知识有限,我不确定这是否是最好的方法,因此我正在寻求帮助和建议以更好地解决我的问题。我乐于接受所有建议,也请指出我可能犯的任何错误,因为我是机器学习和 NLP 世界的新手。
如果您正在寻找最简单/最快的解决方案,那么我建议您使用预训练的词嵌入(Word2Vec 或 GloVe)并在其上构建一个简单的查询系统。这些向量已经在庞大的语料库上进行了训练,并且可能包含与您的领域数据足够好的近似值。
下面是我的解决方案:
import numpy as np
# Category -> words
data = {
'Names': ['john','jay','dan','nathan','bob'],
'Colors': ['yellow', 'red','green'],
'Places': ['tokyo','bejing','washington','mumbai'],
}
# Words -> category
categories = {word: key for key, words in data.items() for word in words}
# Load the whole embedding matrix
embeddings_index = {}
with open('glove.6B.100d.txt') as f:
for line in f:
values = line.split()
word = values[0]
embed = np.array(values[1:], dtype=np.float32)
embeddings_index[word] = embed
print('Loaded %s word vectors.' % len(embeddings_index))
# Embeddings for available words
data_embeddings = {key: value for key, value in embeddings_index.items() if key in categories.keys()}
# Processing the query
def process(query):
query_embed = embeddings_index[query]
scores = {}
for word, embed in data_embeddings.items():
category = categories[word]
dist = query_embed.dot(embed)
dist /= len(data[category])
scores[category] = scores.get(category, 0) + dist
return scores
# Testing
print(process('pink'))
print(process('frank'))
print(process('moscow'))
为了 运行 它,您必须从 here 下载并解压预训练的 GloVe 数据(小心,800Mb!)。在 运行ning 之后,它应该产生如下内容:
{'Colors': 24.655489603678387, 'Names': 5.058711671829224, 'Places': 0.90213905274868011}
{'Colors': 6.8597321510314941, 'Names': 15.570847320556641, 'Places': 3.5302454829216003}
{'Colors': 8.2919375101725254, 'Names': 4.58830726146698, 'Places': 14.7840416431427}
...这看起来很合理。就是这样!如果不需要这么大的模型,可以根据tf-idf分值过滤glove
里的词。请记住,模型大小仅取决于您拥有的数据和您可能希望能够查询的词。
另外,现在 PyTorch has a good and faster implementation 的 Glove 值多少钱。
背景
我有一些带有样本数据的向量,每个向量都有一个类别名称(地点、颜色、名称)。
['john','jay','dan','nathan','bob'] -> 'Names'
['yellow', 'red','green'] -> 'Colors'
['tokyo','bejing','washington','mumbai'] -> 'Places'
我的 objective 是训练一个模型,该模型接受一个新的输入字符串并预测它属于哪个类别。例如,如果新输入是 "purple",那么我应该能够预测 'Colors' 是正确的类别。如果新输入是 "Calgary",它应该将 'Places' 预测为正确的类别。
方法
我做了一些研究并发现了 Word2vec。这个库有一个我可以使用的 "similarity" 和 "mostsimilarity" 函数。所以我想到的一种蛮力方法如下:
- 接受新的输入。
- 计算它与每个向量中每个单词的相似度并取平均值。
因此,例如对于输入 "pink" 我可以计算它与向量中单词的相似度 "names" 取平均值,然后对其他 2 个向量也这样做。给我最高相似度平均值的向量将是输入所属的正确向量。
问题
鉴于我在 NLP 和机器学习方面的知识有限,我不确定这是否是最好的方法,因此我正在寻求帮助和建议以更好地解决我的问题。我乐于接受所有建议,也请指出我可能犯的任何错误,因为我是机器学习和 NLP 世界的新手。
如果您正在寻找最简单/最快的解决方案,那么我建议您使用预训练的词嵌入(Word2Vec 或 GloVe)并在其上构建一个简单的查询系统。这些向量已经在庞大的语料库上进行了训练,并且可能包含与您的领域数据足够好的近似值。
下面是我的解决方案:
import numpy as np
# Category -> words
data = {
'Names': ['john','jay','dan','nathan','bob'],
'Colors': ['yellow', 'red','green'],
'Places': ['tokyo','bejing','washington','mumbai'],
}
# Words -> category
categories = {word: key for key, words in data.items() for word in words}
# Load the whole embedding matrix
embeddings_index = {}
with open('glove.6B.100d.txt') as f:
for line in f:
values = line.split()
word = values[0]
embed = np.array(values[1:], dtype=np.float32)
embeddings_index[word] = embed
print('Loaded %s word vectors.' % len(embeddings_index))
# Embeddings for available words
data_embeddings = {key: value for key, value in embeddings_index.items() if key in categories.keys()}
# Processing the query
def process(query):
query_embed = embeddings_index[query]
scores = {}
for word, embed in data_embeddings.items():
category = categories[word]
dist = query_embed.dot(embed)
dist /= len(data[category])
scores[category] = scores.get(category, 0) + dist
return scores
# Testing
print(process('pink'))
print(process('frank'))
print(process('moscow'))
为了 运行 它,您必须从 here 下载并解压预训练的 GloVe 数据(小心,800Mb!)。在 运行ning 之后,它应该产生如下内容:
{'Colors': 24.655489603678387, 'Names': 5.058711671829224, 'Places': 0.90213905274868011}
{'Colors': 6.8597321510314941, 'Names': 15.570847320556641, 'Places': 3.5302454829216003}
{'Colors': 8.2919375101725254, 'Names': 4.58830726146698, 'Places': 14.7840416431427}
...这看起来很合理。就是这样!如果不需要这么大的模型,可以根据tf-idf分值过滤glove
里的词。请记住,模型大小仅取决于您拥有的数据和您可能希望能够查询的词。
另外,现在 PyTorch has a good and faster implementation 的 Glove 值多少钱。