python寻找近义词:预训练模型 nltk+20newsbydate / gensim glove 转 word2vec

本文用python寻找英文近义词(中文:https://github.com/huyingxi/Synonyms

使用的都是预训练模型


方法一、nltk+20newsbydate

(运行时下载太慢/失败见下文)

from sklearn.datasets import fetch_20newsgroups
from bs4 import BeautifulSoup
from gensim.models import word2vec
import numpy
import nltk
import re
import os

if os.path.exists(r'sentences.npy'):
    # 将预处理后的"词库"从文件中读出,便于调试
    numpy_array = numpy.load('sentences.npy', allow_pickle=True)
    sentences = numpy_array.tolist()
else:
    news = fetch_20newsgroups(subset='all')
    X, y = news.data, news.target
    print("OK")

    # 把段落分解成由句子组成的list(每个句子又被分解成词语)
    def news_to_sentences(news):
        news_text = BeautifulSoup(news, 'lxml').get_text()
        tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
        raw_sentences = tokenizer.tokenize(news_text)

        # 对每个句子进行处理,分解成词语
        sentences = []
        for sent in raw_sentences:
            sentences.append(re.sub('[^a-zA-Z]', ' ', sent.lower().strip()).split())
        return sentences


    sentences = []

    for x in X:
        sentences += news_to_sentences(x)

    # 将预处理过的"词库"保存到文件中,便于调试
    numpy_array = numpy.array(sentences)
    numpy.save('sentences.npy', numpy_array)

if os.path.exists(r'word2vec.model'):
    model = word2vec.Word2Vec.load('word2vec.model')
else:
    num_features = 300
    min_word_count = 20
    num_workers = 2
    context = 5
    downsampling = 1e-3

    model = word2vec.Word2Vec(sentences, workers=num_workers, size=num_features, min_count=min_word_count,
                              window=context, sample=downsampling)

    model.init_sims(replace=True)  # 模型锁定,可以提高模型和后续任务的速度,同时也使得模型不能训练了,read only

    model.save('word2vec.model')  # 保存模型

# 保存word2vec训练参数便于调试
# model.wv.save_word2vec_format('word2vec_model.bin', binary=True)
# model.wv.load_word2vec_format('word2vec_model.bin', binary=True)

print('词语相似度计算:')
print('morning vs morning:')
print(model.wv.n_similarity('morning', 'morning'))
print('morning vs afternoon:')
print(model.wv.n_similarity('morning', 'afternoon'))
print('morning vs hello:')
print(model.wv.n_similarity('morning', 'hellow'))
print('morning vs shell:')
print(model.wv.n_similarity('morning', 'shell'))
"""
词语相似度计算:
morning vs morning:
1.0
morning vs afternoon:
0.871482091583
morning vs hello:
0.731609166442
morning vs shell:
0.709714434122
"""
print(model.wv.most_similar('sum'))
"""
[('crop', 0.5935108661651611),
 ('rapid', 0.5862394571304321),
 ('edges', 0.571550726890564),
 ('size', 0.5690909028053284),
 ('acceleration', 0.5680683851242065),
 ('chopped', 0.5644211769104004),
 ('depth', 0.5643296837806702),
 ('chunk', 0.5604238510131836),
 ('ratio', 0.5565502047538757),
 ('tube', 0.55369633436203)]
"""

# 以上是用 20newsbydate 和 nltk 的模型,效果很一般
  • nltk 的使用:

官网 http://www.nltk.org/data.html

使用官方的 nltk.download() 很慢,可以使用离线下载安装数据

离线下载:

github  https://github.com/nltk/nltk_data

百度云  https://pan.baidu.com/s/17ZgkoQeMosWwHNlUvXvTdw 密码:lxmh

下载下来的文件夹包括 chunkers, grammars, misc, sentiment, taggers, corpora, help, models, stemmers, tokenizers 十个文件夹

 

在以下目录创建文件夹 nltk_data (以下为默认文件夹,可以装在 nltk.download()  时出现的那些文件夹中的任何一个)

windows  C:\nltk_data

mac  /usr/local/share/nltk_data

Unix  /usr/share/nltk_data

把下载好的文件放到 nltk_data 中即可

  • 20newsbydate 数据集的下载

https://ndownloader.figshare.com/files/5975967 (14 MB)

在报错中点击或者在文件夹中找到

../anaconda3/lib/python3.7/site-packages/sklearn/datasets/twenty_newsgroups.py

找到 _download_20newsgroups 函数,把开头部分改成如下

def _download_20newsgroups(target_dir, cache_path):
    """Download the 20 newsgroups data and stored it as a zipped pickle."""
    train_path = os.path.join(target_dir, TRAIN_FOLDER)
    test_path = os.path.join(target_dir, TEST_FOLDER)

    if not os.path.exists(target_dir):
        os.makedirs(target_dir)
    """
    logger.info("Downloading dataset from %s (14 MB)", ARCHIVE.url)
    archive_path = _fetch_remote(ARCHIVE, dirname=target_dir)
    """
    archive_path = r'你的下载文件路径'  # /Users/a123/scikit_learn_data/20news_home/20news-bydate.tar.gz
    logger.debug("Decompressing %s", archive_path)
    tarfile.open(archive_path, "r:gz").extractall(path=target_dir)
    os.remove(archive_path)

    .....

由于使用的数据较小,模型效果一般,有些完全就是字符串匹配,长得像的相似度就高

 

方法二、gensim glove 转 word2vec 加载预训练模型

glove 和 word2vec 是两个很好的把词语用向量表示的库

在 https://github.com/RaRe-Technologies/gensim-data 有更多预训练模型

在 Model 那里,各种大小都有

这里我使用的是 https://nlp.stanford.edu/projects/glove/ 中的 glove.6B.zip,迅雷下了半个小时

以下代码来自https://radimrehurek.com/gensim/scripts/glove2word2vec.html

要使用的库

from gensim.test.utils import datapath, get_tmpfile
from gensim.models import KeyedVectors
from gensim.scripts.glove2word2vec import glove2word2vec

在命令行下看看 tmp_file 的值,就是转换后文件的存放位置

glove_file = datapath('/你的下载路径/glove.6B.300d.txt')
# 输出文件
tmp_file = get_tmpfile("word2vec_300d.txt")
# 这里的 tmp_file 是一个字符串,是存放转换文件的路径
# 转换完成后就来这里找转换后的txt文件

 开始转换

# 开始转换
print(glove2word2vec(glove_file, tmp_file))
# 打印出来是(400000, 300)

转换完成后,就可以只用转换后文件用 word2vec 加载模型

其中的 tmp_file 可以是你自己的存放了转换后文件的位置

# 转换的文件就是在glove下载的txt这个文件的最开头,加上两个数
# 第一个数指明一共有多少个向量,第二个数指明每个向量有多少维,就能直接用word2vec的load函数加载了
model = KeyedVectors.load_word2vec_format(tmp_file)

 

到此就已经完成模型的加载了,试一下效果

查找两个词语之间的相似度

model.similarity('dog','cat')
Out[71]: 0.68167466
model.similarity('cut','cat')
Out[72]: 0.082896836
model.similarity('people','person')
Out[73]: 0.5712259
model.similarity('people','apple')
Out[74]: 0.14102192

查找一个词的近义词

model.most_similar('funny')
Out[69]: 
[('hilarious', 0.7324165105819702),
 ('amusing', 0.6964851021766663),
 ('witty', 0.6262085437774658),
 ('humorous', 0.6112722754478455),
 ('fun', 0.6088972091674805),
 ('laugh', 0.6085041761398315),
 ('humor', 0.6043205261230469),
 ('wonderfully', 0.6033899784088135),
 ('silly', 0.6012822389602661),
 ('joke', 0.588691771030426)]

在给定的列表中找指定词最相近的词语

model.most_similar_to_given('funny', ['interesting', 'dog', 'such'])
Out[66]: 'interesting'

效果还不错

模型的保存与加载(保存成model会比较大,但是读起来快)

model.save('glove2word2vev.model')
model = KeyedVectors.load('glove2word2vev.model')

关于其他保存形式和更多word2vec的方法可以看

https://blog.csdn.net/HUSTHY/article/details/103164934

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值