13

腾讯 800 万中文词向量 API Demo 搭建

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MjM5ODkzMzMwMQ%3D%3D&%3Bmid=2650411944&%3Bidx=3&%3Bsn=be92a801fabefbbc73ea79420f9f37dd
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作者:李大雷

原文链接:

https://zhuanlan.zhihu.com/p/94124468

1. 前言

鹅厂 18 年 10 月开源了一份包含 800 万中文词的词向量模型。

官方的介绍中显示其能覆盖一些很低频的词。如 喀拉喀什河 ,一些网络新词如 因吹斯汀 竟然也可以查到对应的词向量,以及输入 马云也 可以在最相似词中找到 马爸爸 等词。

总体来说这个模型在 覆盖率新鲜度准确性 上都有不错的表现。

比较欠缺的是,其训练模型中有一定比例的词并非是词。如马云的 top 相似词结果中有 :马云和、马云说、如马云等词。以及对于未登录词无法增量训练。

本文尝试基于 python 3 + flask + gensim 搭建一个简易的 api 服务,让你可以在实验环境中试玩这个模型。

2. 模型下载

该模型压缩后 6.4 GB ,解压后 16 GB,在内存中展开 18.5 GB,全量模型加载需要 26 min 左右。

搭建前确保机器资源充足,另外如果只是试玩建议对原始模型做裁剪,如只加载前 10 w 词。

全量模型下载:https://ai.tencent.com/ailab/nlp/embedding.html

精简版下载(全量模型的前 10w 个词):

链接: https://pan.baidu.com/share/init?surl=NidB4Rsy-tqY49QsysUgMw

提取码: tmda

第3、4步骤是虚拟环境搭建以及依赖安装,已经就绪的同学可以直接跳到步骤 5 运行代码。

3. virtualenv 环境搭建

  • 安装 virtualenv

pip3 install virtualenv
  • 创建 virtualenv(以 /tmp/work 为例)

cd  /tmp/work/
virtualenv -p python3 w2v_venv
  • 进入 virtualenv

source w2vAPI/bin/activate

4. 依赖安装

  • 将以下数据,保存为 requirements.txt 。

boto==2.49.0
boto3==1.10.26
botocore==1.13.26
certifi==2019.9.11
chardet==3.0.4
Click==7.0
docutils==0.15.2
Flask==1.1.1
gensim==3.8.1
idna==2.8
itsdangerous==1.1.0
Jinja2==2.10.3
jmespath==0.9.4
MarkupSafe==1.1.1
numpy==1.17.4
python-dateutil==2.8.0
requests==2.22.0
s3transfer==0.2.1
scipy==1.3.3
six==1.13.0
smart-open==1.9.0
urllib3==1.25.7
Werkzeug==0.16.0
  • 执行安装

pip3 install -r requirements.txt

5. 运行

  • 将以下数据,保存为 w2v.py 。

import json
from flask import Flask, request
from gensim.models import KeyedVectors
from flask import jsonify
import argparse
import sys
import socket
import time
import logging


logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s;%(levelname)s: %(message)s",
                              "%Y-%m-%d %H:%M:%S")
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
console.setFormatter(formatter)
logger.addHandler(console)


app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

def isNoneWords(word):
    if word is None or len(word)==0 or word not in model.vocab:
        return True
    else:
        return False

@app.route("/", methods=['GET'])
def welcome():

    vecAPI="http://"+localIp+":"+str(port)+"/vec?word=淘宝"
    simAPI="http://"+localIp+":"+str(port)+"/sim?word1=淘宝&word2=京东"
    topSimAPI="http://"+localIp+":"+str(port)+"/top_sim?word=淘宝"

    return "Welcome to word2vec api . <br/>\
    try this api below:<br/> \
    1. vec api:    <a href='"+vecAPI+"'>"+vecAPI+"</a> <br/>\
    2. sim api:    <a href='"+simAPI+"'>"+simAPI+"</a> <br/>\
    3. top sim api:    <a href='"+topSimAPI+"'>"+topSimAPI+"</a> <br/>\
    "

@app.route("/vec", methods=['GET'])
def vec_route():
    word = request.args.get("word")
    if isNoneWords(word):
        return jsonify("word is null or not in model!")
    else:
        return jsonify({'word':word,'vector': model.word_vec(word).tolist()})

@app.route("/sim", methods=['GET'])
def similarity_route():
    word1 = request.args.get("word1")
    word2 = request.args.get("word2")
    if isNoneWords(word1) or isNoneWords(word2):
        return jsonify("word is null or not in model!")
    else:
        return jsonify({'word1':word1,'word2':word2,'similarity':float(model.similarity(word1, word2))})

@app.route("/top_sim", methods=['GET'])
def top_similarity_route():
    word = request.args.get("word")
    if isNoneWords(word):
        return jsonify("word is null or not in model!")
    else:
        return jsonify({'word':word,'top_similar_words':model.similar_by_word(word, topn=20, restrict_vocab=None)})

def getLocalIP():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    ip=s.getsockname()[0]
    s.close()
    return ip

def main():
    global model
    global port
    global localIp
    for arg in sys.argv[1:]:
        logger.debug(arg)
    p = argparse.ArgumentParser()
    p.add_argument("--model", help="Path to the trained model")
    p.add_argument("--host", help="Host name (default: localhost)")
    p.add_argument("--port", help="Port (default: 8888)")
    args = p.parse_args()
    host = args.host if args.host else "localhost"
    port = int(args.port) if args.port else 8888
    localIp = getLocalIP()
    if not args.model:
        logger.debug("Usage: w2v.py --model model_path [--host host --port 8888]")
        sys.exit(1)
    logger.debug("start load model:" + str(args.model))
    start_time = time.time()
    model = KeyedVectors.load_word2vec_format(args.model, binary=False)
    logger.debug("end load model:" + str(args.model))
    # app.run(host=host, port=port,debug=True)
    app.run(host=host, port=port)
if __name__ == "__main__":
    main()
  • 启动 api 服务

nohup python3 w2v.py --model /opt/cuiyulei/Tencent_AILab_ChineseEmbedding.txt --host 你的ip 2>&1 &

6. 结果

  • 浏览器中键入

http://你的ip:8888/
  • 提示如下,表示搭建完成

Welcome to word2vec api .
try this api below:
1. vec api: http://ip:8888/vec?word=淘宝
2. sim api: http://ip:8888/sim?word1=淘宝&word2=京东
3. top sim api: http://ip:8888/top_sim?word=淘宝
  • 运行效果

input:

http://ip:8888/top_sim?word=红烧肉

output:

{
     "top_similar_words":[
        [
           "糖醋排骨",
           0.8907967209815979
        ],
        [
           "红烧排骨",
           0.8726683259010315
        ],
        [
           "回锅肉",
           0.858664333820343
        ],
        [
           "红烧鱼",
           0.8542774319648743
        ],
        [
           "梅菜扣肉",
           0.8500987887382507
        ],
        [
           "糖醋小排",
           0.8475514650344849
        ],
        [
           "小炒肉",
           0.8435966968536377
        ],
        [
           "红烧五花肉",
           0.8424086570739746
        ],
        [
           "红烧肘子",
           0.8400496244430542
        ],
        [
           "糖醋里脊",
           0.8381932377815247
        ],
        [
           "红烧猪蹄",
           0.8374584913253784
        ],
        [
           "青椒炒肉",
           0.8344883918762207
        ],
        [
           "粉蒸肉",
           0.8337559700012207
        ],
        [
           "水煮肉片",
           0.8311598300933838
        ],
        [
           "青椒肉丝",
           0.8294434547424316
        ],
        [
           "鱼香茄子",
           0.8291393518447876
        ],
        [
           "烧茄子",
           0.8272593021392822
        ],
        [
           "梅干菜扣肉",
           0.8267726898193359
        ],
        [
           "土豆炖牛肉",
           0.8263725638389587
        ],
        [
           "红烧茄子",
           0.8244959115982056
        ]
     ],
     "word":"红烧肉"
  }

7. 相关文章

腾讯AI Lab开源大规模高质量中文词向量数据,800万中文词随你用 UBN3men.jpg!web AINLP 的公众号接口

本文由作者授权AINLP原创发布于公众号平台,点击'阅读原文'直达原文链接,欢迎投稿,AI、NLP均可。

推荐阅读

关于AINLP

AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLP君微信(id:AINLP2),备注工作/研究方向+加群目的。

qIR3Abr.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK