精华内容
下载资源
问答
  • 2019-06-14 17:22:24

    情感/观点/评论 倾向性分析

    数据集数据概览下载地址
    ChnSentiCorp_htl_all7000 多条酒店评论数据,5000 多条正向评论,2000 多条负向评论点击查看
    waimai_10k某外卖平台收集的用户评价,正向 4000 条,负向 约 8000 条点击查看
    online_shopping_10_cats10 个类别,共 6 万多条评论数据,正、负向评论各约 3 万条,
    包括书籍、平板、手机、水果、洗发水、热水器、蒙牛、衣服、计算机、酒店
    点击查看
    weibo_senti_100k10 万多条,带情感标注 新浪微博,正负向评论约各 5 万条点击查看
    simplifyweibo_4_moods36 万多条,带情感标注 新浪微博,包含 4 种情感,
    其中喜悦约 20 万条,愤怒、厌恶、低落各约 5 万条
    点击查看
    dmsc_v228 部电影,超 70 万 用户,超 200 万条 评分/评论 数据点击查看
    yf_dianping24 万家餐馆,54 万用户,440 万条评论/评分数据点击查看
    yf_amazon52 万件商品,1100 多个类目,142 万用户,720 万条评论/评分数据点击查看

    中文命名实体识别

    数据集数据概览下载地址
    dh_msra5 万多条中文命名实体识别标注数据(包括地点、机构、人物)点击查看

    推荐系统

    数据集数据概览下载地址
    ez_douban5 万多部电影(3 万多有电影名称,2 万多没有电影名称),2.8 万 用户,280 万条评分数据点击查看
    dmsc_v228 部电影,超 70 万 用户,超 200 万条 评分/评论 数据点击查看
    yf_dianping24 万家餐馆,54 万用户,440 万条评论/评分数据点击查看
    yf_amazon52 万件商品,1100 多个类目,142 万用户,720 万条评论/评分数据点击查看

    FAQ 问答系统

    数据集数据概览下载地址
    保险知道8000 多条保险行业问答数据,包括用户提问、网友回答、最佳回答点击查看
    安徽电信知道15.6 万条电信问答数据,包括用户提问、网友回答、最佳回答点击查看
    金融知道77 万条金融行业问答数据,包括用户提问、网友回答、最佳回答点击查看
    法律知道3.6 万条法律问答数据,包括用户提问、网友回答、最佳回答点击查看
    联通知道20.3 万条联通问答数据,包括用户提问、网友回答、最佳回答点击查看
    农行知道4 万条农业银行问答数据,包括用户提问、网友回答、最佳回答点击查看
    保险知道58.8 万条保险行业问答数据,包括用户提问、网友回答、最佳回答点击查看
    更多相关内容
  • 中文语料库构建过程详细教程

    千次阅读 2020-11-26 08:02:42
    简介今天我想简单记录一下自己构建语料库的过程, 方便自己查看和方便协作. 在工作中我们经常遇到一个问题就是每个研究者都有自己的语料库, 存储格式不同, 有用mysql这种结构化数据库的, 也有mogodb这种文档型数据库,...

    简介

    今天我想简单记录一下自己构建语料库的过程, 方便自己查看和方便协作. 在工作中我们经常遇到一个问题就是每个研究者都有自己的语料库, 存储格式不同, 有用mysql这种结构化数据库的, 也有mogodb这种文档型数据库, 还有更多的是使用文本文件, 不管哪种形式, 都会导致数据交换出现困难. 他人使用这个语料库的时候需要自己写语料库的预处理函数, 否则语料库是不能进入计算的. 为了减少这种不必要的重复劳动, 我们就使用gensim.corpora.textcorpus.TextDirectoryCorpus类来管理语料. 也就是说, 我们的语料保存在文件夹中, 设置lines_are_documents=False来保证每个文件是一篇文档. 如果我们都以相同的方式管理语料库, 那么我们的协作就更顺畅.

    目录结构

    因为TextDirectoryCorpus可以支持嵌套的文件夹, 只要指定max_depth和min_depth两个参数就能控制文件夹深度. 我通常是使用一个文件夹放所有文本文件. 比如我有这样一个目录作为语料库:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12└─test-corpus # 根目录

    │ dictionary.model # 字典数据

    │ meta.csv # 元信息

    └─corpus # 存放文档

    01.txt

    02.txt

    03.txt

    04.txt

    05.txt

    06.txt

    07.txt

    1

    2

    3import re

    re.compile('.*\.txt')

    输出:

    re.compile(r'.*\.txt', re.UNICODE)

    TextDirectoryCorpus简单使用

    先看以下基本用法:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38# 引入用到的库

    from gensim.corpora.textcorpus import TextDirectoryCorpus

    import locale

    locale.setlocale(locale.LC_ALL, 'en_US.utf-8')

    # 数据所在路径

    dpath = r'D:\mysites\notebooks\data\test-corpus'

    class MyTextDirCorpus(TextDirectoryCorpus):

    # 为了强制使用'utf8'编码, 我们复写了这个方法

    def getstream(self):

    """Yield documents from the underlying plain text collection (of one or more files).

    Each item yielded from this method will be considered a document by subsequent

    preprocessing methods.

    If `lines_are_documents` was set to True, items will be lines from files. Otherwise

    there will be one item per file, containing the entire contents of the file.

    """

    num_texts = 0

    for path in self.iter_filepaths():

    with open(path, 'rt', encoding='utf8') as f:

    if self.lines_are_documents:

    for line in f:

    yield line.strip()

    num_texts += 1

    else:

    content = f.read().strip()

    yield content

    num_texts += 1

    self.length = num_texts

    # 实例化一个语料库,

    # 遍历的最小深度是1

    # 设置lines_are_documents为False

    # 后缀为txt的文件才会被当作是一个文档

    corpus = MyTextDirCorpus(dpath, min_depth=1, pattern='.*\.txt', lines_are_documents=False)

    print('语料库计数:', len(corpus))

    print('第一条:',next(corpus.get_texts()))

    输出:

    语料库计数: 7

    第一条: ['树中路径的交集图']

    分词和词典生成

    为了让同事之间的工作更有一致性, 我们通常要预先对语料库进行分词, 使得不同的人具有相同的分词结果. 我们就用最简单的方法, 使用pyltp模块进行分词, 然后生成一个词典.

    我们先来看看pyltp是如何进行分词的:

    1

    2

    3

    4

    5

    6

    7

    8

    9# 分词测试

    from pyltp import Segmentor

    new_doc = '实验室中测量无序响应中时间'

    model_path = r'D:\mysites\text-characters\tcharacters\ltp\ltp_data\cws.model'

    segmentor = Segmentor() # 初始化实例

    segmentor.load(model_path)

    new_tokens = segmentor.segment(new_doc)

    print('Tokens:', '\t'.join(new_tokens))

    segmentor.release() # 释放模型

    输出:

    Tokens: 实验室中测量无序响应中时间

    实现一个分词器:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61class MyTextDirCorpus(TextDirectoryCorpus):

    def __init__(self, input, **kwargs):

    kwargs['tokenizer'] = self.tokenizer

    super().__init__(input, **kwargs)

    def tokenizer(self, text):

    if not hasattr(self, '_segmentor'):

    model_path = r'D:\mysites\text-characters\tcharacters\ltp\ltp_data\cws.model'

    segmentor = Segmentor() # 初始化实例

    segmentor.load(model_path)

    self._segmentor = segmentor

    segmentor = self._segmentor

    return segmentor.segment(text)

    def __del__(self):

    '''释放资源'''

    if hasattr(self, '_segmentor'):

    self._segmentor.release()

    try:

    super().__del__()

    except AttributeError:

    pass

    # 为了强制使用'utf8'编码, 我们复写了这个方法

    def getstream(self):

    """Yield documents from the underlying plain text collection (of one or more files).

    Each item yielded from this method will be considered a document by subsequent

    preprocessing methods.

    If `lines_are_documents` was set to True, items will be lines from files. Otherwise

    there will be one item per file, containing the entire contents of the file.

    """

    num_texts = 0

    for path in self.iter_filepaths():

    with open(path, 'rt', encoding='utf8') as f:

    if self.lines_are_documents:

    for line in f:

    yield line.strip()

    num_texts += 1

    else:

    content = f.read().strip()

    yield content

    num_texts += 1

    self.length = num_texts

    # 实例化一个语料库

    # 注意我们传入了一个token_filters参数, 实际上是一个空列表, 意思是, 不要过滤词, 所有词都要

    # 当然在有需要的情况下, 我们需要定义自己的token_filters

    corpus = MyTextDirCorpus(dpath, min_depth=1,

    pattern='.*\.txt',

    lines_are_documents=False,

    tokenizer=tokenizer,

    token_filters=[])

    # 保存词典到本地硬盘

    dict_path = r'D:\mysites\notebooks\data\test-corpus\dictionary.model'

    corpus.dictionary.save_as_text(fname=dict_path)

    # 查看词典内容

    corpus.dictionary.token2id

    输出:

    {'中': 0,

    '交集图': 1,

    '树': 2,

    '的': 3,

    '路径': 4,

    '\ufeff': 5,

    '无序': 6,

    '生成': 7,

    '随机二进制': 8,

    '与': 9,

    '关系': 10,

    '响应': 11,

    '感知': 12,

    '时间': 13,

    '测量': 14,

    '用户': 15,

    '误差': 16,

    'eps': 17,

    '人体': 18,

    '和': 19,

    '测试': 20,

    '系统': 21,

    '系统工程': 22,

    '界面': 23,

    '管理': 24,

    '对': 25,

    '看法': 26,

    '计算机': 27,

    '调查': 28,

    '实验室': 29,

    '应用': 30}

    你可以在dict_path这个路径下看到我们的字典内容, 使用任意一个文本编辑器即可打开, 如下图, 三列数据分别表示id/词/计数.

    dictionary-example.png

    词典的使用

    生成了词典以后, 我们以后再使用语料库的时候, 可以不必每次都重新计算词典, 这个过程非常耗费资源, 所以我们使用已经存储在硬盘的词典数据.

    1from gensim.corpora.dictionary import Dictionary

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10%%timeit

    # 预加载字典

    dic = Dictionary.load_from_text(dict_path)

    MyTextDirCorpus(dpath,

    dictionary=dic,

    min_depth=1,

    pattern='.*\.txt',

    lines_are_documents=False,

    tokenizer=tokenizer,

    token_filters=[])

    输出:

    122 µs ± 435 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

    1

    2

    3

    4

    5

    6

    7

    8%%timeit

    # 每次生成词典

    MyTextDirCorpus(dpath,

    min_depth=1,

    pattern='.*\.txt',

    lines_are_documents=False,

    tokenizer=tokenizer,

    token_filters=[])

    输出:

    190 ms ± 116 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

    通过上面的测试, 我们发现两种方式的差别很大, 这还是在小语料库上测试的, 如果是大语料库, 这个差别就是几个数量级的差别了.

    预先分词

    其实, 很多人协作的情况下, 保证大家的分词结果的一致性是很有必要的, 不然很多结果都没有可比性. 与其每个人都分一遍词, 不如从一开始就分好词. 所以我们可以把词分好, 然后保存到硬盘.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18import pickle

    from pathlib import Path

    dic = Dictionary.load_from_text(dict_path)

    corpus = MyTextDirCorpus(dpath,

    dictionary=dic,

    min_depth=1,

    pattern='.*\.txt$',

    lines_are_documents=False,

    tokenizer=tokenizer,

    token_filters=[])

    for fpath in corpus.iter_filepaths():

    fpath = Path(fpath)

    token_path = fpath.parent / (fpath.name + '.cached_tokens')

    txt = fpath.read_text(encoding='utf8').strip()

    tokens = corpus.tokenizer(txt)

    token_path.write_bytes(pickle.dumps(list(tokens)))

    使用预先分好的词, 可以再给我们的MyTextDirCorpus添加一个方法get_texts_from_tokens

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51class MyTextDirCorpus(TextDirectoryCorpus):

    def __init__(self, input, **kwargs):

    kwargs['tokenizer'] = self.tokenizer

    super().__init__(input, **kwargs)

    def tokenizer(self, text):

    if not hasattr(self, '_segmentor'):

    model_path = r'D:\mysites\text-characters\tcharacters\ltp\ltp_data\cws.model'

    segmentor = Segmentor() # 初始化实例

    segmentor.load(model_path)

    self._segmentor = segmentor

    segmentor = self._segmentor

    return segmentor.segment(text)

    def __del__(self):

    '''释放资源'''

    if hasattr(self, '_segmentor'):

    self._segmentor.release()

    try:

    super().__del__()

    except AttributeError:

    pass

    # 为了强制使用'utf8'编码, 我们复写了这个方法

    def getstream(self):

    """Yield documents from the underlying plain text collection (of one or more files).

    Each item yielded from this method will be considered a document by subsequent

    preprocessing methods.

    If `lines_are_documents` was set to True, items will be lines from files. Otherwise

    there will be one item per file, containing the entire contents of the file.

    """

    num_texts = 0

    for path in self.iter_filepaths():

    with open(path, 'rt', encoding='utf8') as f:

    if self.lines_are_documents:

    for line in f:

    yield line.strip()

    num_texts += 1

    else:

    content = f.read().strip()

    yield content

    num_texts += 1

    self.length = num_texts

    def get_texts_from_tokens(self):

    for fpath in self.iter_filepaths():

    fpath = Path(fpath)

    token_path = fpath.parent / (fpath.name + '.cached_tokens')

    yield pickle.loads(token_path.read_bytes())

    测试以下我们新的方法是不是更节省时间:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13%%timeit

    dic = Dictionary.load_from_text(dict_path)

    corpus = MyTextDirCorpus(dpath,

    dictionary=dic,

    min_depth=1,

    pattern='.*\.txt$',

    lines_are_documents=False,

    tokenizer=tokenizer,

    token_filters=[])

    for i in corpus.get_texts():

    pass

    输出:

    154 ms ± 2.82 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13%%timeit

    dic = Dictionary.load_from_text(dict_path)

    corpus = MyTextDirCorpus(dpath,

    dictionary=dic,

    min_depth=1,

    pattern='.*\.txt$',

    lines_are_documents=False,

    tokenizer=tokenizer,

    token_filters=[])

    for i in corpus.get_texts_from_tokens():

    pass

    输出:

    969 µs ± 7.14 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

    测试显示, 时间还是差了几个数量级, 而且第二种方法的好处是, 我们使用语料库时不必再依赖分词模块pyltp.

    总结

    现在我们基本上已经构建了一个标准统一的语料库, 而且预先进行了分词和词典生成. 现在我们把所有用到的代码都封装到MyTextDirCorpus类中. 看代码:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68# author: mlln.cn

    # email: xxxspy@126.com

    # qq: 675495787

    class MyTextDirCorpus(TextDirectoryCorpus):

    def __init__(self, input, **kwargs):

    kwargs['tokenizer'] = self.tokenizer

    super().__init__(input, **kwargs)

    def tokenizer(self, text):

    if not hasattr(self, '_segmentor'):

    model_path = r'D:\mysites\text-characters\tcharacters\ltp\ltp_data\cws.model'

    segmentor = Segmentor() # 初始化实例

    segmentor.load(model_path)

    self._segmentor = segmentor

    segmentor = self._segmentor

    return segmentor.segment(text)

    def __del__(self):

    '''释放资源'''

    if hasattr(self, '_segmentor'):

    self._segmentor.release()

    try:

    super().__del__()

    except AttributeError:

    pass

    # 为了强制使用'utf8'编码, 我们复写了这个方法

    def getstream(self):

    """Yield documents from the underlying plain text collection (of one or more files).

    Each item yielded from this method will be considered a document by subsequent

    preprocessing methods.

    If `lines_are_documents` was set to True, items will be lines from files. Otherwise

    there will be one item per file, containing the entire contents of the file.

    """

    num_texts = 0

    for path in self.iter_filepaths():

    with open(path, 'rt', encoding='utf8') as f:

    if self.lines_are_documents:

    for line in f:

    yield line.strip()

    num_texts += 1

    else:

    content = f.read().strip()

    yield content

    num_texts += 1

    self.length = num_texts

    def get_texts_from_tokens(self):

    for fpath in self.iter_filepaths():

    fpath = Path(fpath)

    token_path = fpath.parent / (fpath.name + '.cached_tokens')

    yield pickle.loads(token_path.read_bytes())

    def save_tokens(self):

    '''保存tokens到硬盘, 只需要运行一次'''

    for fpath in self.iter_filepaths():

    fpath = Path(fpath)

    token_path = fpath.parent / (fpath.name + '.cached_tokens')

    txt = fpath.read_text(encoding='utf8').strip()

    tokens = self.tokenizer(txt)

    token_path.write_bytes(pickle.dumps(list(tokens)))

    def save_dictionary(self, dpath):

    '''把字典保存到硬盘'''

    self.dictionary.save_as_text(fname=dpath)

    本为由mlln.cn原创, 转载请注明出处(mlln.cn), 本站保留版权. 欢迎童鞋在下方留言反馈.

    注意

    本文由jupyter notebook转换而来, 您可以在这里下载notebook

    有问题可以直接在下方留言

    或者给我发邮件675495787[at]qq.com

    请记住我的网址: mlln.cn 或者 jupyter.cn

    展开全文
  • 1.下载bert源代码和中文预训练模型 ...依旧采用上一节中使用的ai挑战赛用户评论信息。对于自己使用的场景按照对应的格式处理好即可。例如这边样本格式如下(正文+标签): (说明 此处用的标签...
    1.下载bert源代码和中文预训练模型

    bert代码
    模型下载

    Chinese Simplified and Traditional, 12-layer, 768-hidden, 12-heads, 110M parameters

    2.准备样本

    依旧采用上一节中使用的ai挑战赛用户评论信息。对于自己使用的场景按照对应的格式处理好即可。例如这边样本格式如下(正文+标签):
    在这里插入图片描述
    (说明 此处用的标签含义是从-2~1 共4种代表不同的情感标签,是个4分类。为了便于处理,会将标签投影到1~4 data.others_overall_experience = data.others_overall_experience + 3)

    将样本分成三个文件,且放置于同一个文件夹下:

    • train.tsv:训练集
    • dev.tsv:验证集
    • test.tsv:测试集

    样本打乱之后按照比例划分。新建一个preprocess.py的文件用于数据预处理。

    import os
    from sklearn.model_selection import train_test_split
    from sklearn.utils import shuffle
    def train_valid_test_split(x_data, y_data, validation_size = 0.1, test_size = 0.1):
        x_, x_test, y_, y_test = train_test_split(x_data, y_data, test_size=test_size)
        valid_size = validation_size / (1.0 - test_size)
        x_train, x_valid, y_train, y_valid = train_test_split(x_, y_, test_size=valid_size)
        return x_train, x_valid, x_test, y_train, y_valid, y_test
    
    pd_all = pd.read_csv("./sample.csv"))
    pd_all = shuffle(pd_all)
    x_data, y_data = pd_all.content, pd_all.others_overall_experience
    
    x_train, x_valid, x_test, y_train, y_valid, y_test = train_valid_test_split(x_data, y_data, 0.1, 0.1)
    
    train = pd.DataFrame({'label': y_train, 'x_train': x_train})
    train.to_csv("./train.csv", index=False,  encoding='utf-8',sep='\t')
    valid = pd.DataFrame({'label': y_valid, 'x_valid': x_valid})
    valid.to_csv("./dev.csv", index=False,  encoding='utf-8',sep='\t')
    test = pd.DataFrame({'label': y_test, 'x_test': x_test})
    test.to_csv("./test.csv", index=False, encoding='utf-8',sep='\t')
    
    3.修改bert代码

    run_classifier.py

    添加自定义的数据处理模块,默认内部已经存在了几个。

    class CommentProcessor(DataProcessor):
        """Processor for the WeiBo data set ."""
    
        def get_train_examples(self, data_dir):
            """See base class."""
            return self._create_examples(
                self._read_tsv(os.path.join(data_dir, "train.csv"), quotechar='"'), "train")
    
        def get_dev_examples(self, data_dir):
            """See base class."""
            return self._create_examples(
                self._read_tsv(os.path.join(data_dir, "dev.csv"), quotechar='"'), "dev")
    
        def get_test_examples(self, data_dir):
            """See base class."""
            return self._create_examples(
                self._read_tsv(os.path.join(data_dir, "test.csv"), quotechar='"'), "test")
    
        def get_labels(self):#这里返回了数据样本中定义标签枚举 即1~4
            """See base class."""
            return ["1", "2", "3", "4"]
    
        def _create_examples(self, lines, set_type):
            """Creates examples for the training and dev sets."""
            examples = []
            for (i, line) in enumerate(lines):
                # All sets have a header
                if i == 0: continue
                guid = "%s-%s" % (set_type, i)
                text_a = tokenization.convert_to_unicode(line[1])#读取第二列正文
                label = tokenization.convert_to_unicode(line[0])#读取第一列标签
                examples.append(
                    InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
            return examples
    #
    # .........
    #
    def main(_):
      tf.logging.set_verbosity(tf.logging.INFO)
    
      processors = {
          "cola": ColaProcessor,
          "mnli": MnliProcessor,
          "mrpc": MrpcProcessor,
          "xnli": XnliProcessor,
          "comment": CommentProcessor,#新增数据处理模块
      }
    
    

    注:

    self._read_tsv是继承于DataProcessor方法所以数据的处理需要注意下该方法实现的默认参数。

    例如此处csv.reader delimiter是按照\t分割

    self._read_tsv(os.path.join(data_dir, "train.csv"), quotechar='"') 这里的quotechar引用符,如果正文中存在嵌套的双引号就会出错了。

      @classmethod
      def _read_tsv(cls, input_file, quotechar=None):
        """Reads a tab separated value file."""
        with tf.gfile.Open(input_file, "r") as f:
          reader = csv.reader(f, delimiter="\t", quotechar=quotechar)
          lines = []
          for line in reader:
            lines.append(line)
          print(len(lines))
          return lines
    
    4.run
    python run_classifier.py -data_dir=/bert/bert-demo/bert/data/  --task_name=news  --do_train=true  --do_eval=true  --data_dir=/bert/bert-demo/bert/data/  --vocab_file=/bert/model/chinese_L-12_H-768_A-12/vocab.txt  --bert_config_file=/bert/model/chinese_L-12_H-768_A-12/bert_config.json  --init_checkpoint=/bert/model/chinese_L-12_H-768_A-12/bert_model.ckpt  --max_seq_length=128  --train_batch_size=32  --learning_rate=2e-5  --num_train_epochs=3.0  --output_dir=/output
    

    涉及到路径/bert/xxx加载的是数据和模型 按照实际的路径修改即可

    do_train 是否训练

    do_eval 是否验证

    结果:

    /output/model.ckpt-7875
    INFO:tensorflow:evaluation_loop marked as finished
    INFO:tensorflow:***** Eval results *****
    INFO:tensorflow:  eval_accuracy = 0.73209524
    INFO:tensorflow:  eval_loss = 0.7203514
    INFO:tensorflow:  global_step = 7875
    INFO:tensorflow:  loss = 0.72009945
    
    5.总结

    与上小节lstm 和cnn 相比,bert的精度和损失更具有优势训练集和验证集均为随机,没有使用完全相同的分组可能存在一点差异
    自然语言几个重要的模型 这一节中最后提到 ERNIE更适合中文场景进行的词MASK,这也是待优化的点。

    展开全文
  • 在我看来,Dialogflow 更多的是供个体开发者或普通用户体验或开发,并不适用于太大规模的软件开发使用。匹配的精确度根据个人的需求会有很大的不同,且由于匹配和训练都是在网页上完成,且需要连接外网,在实际应用...

    工作快一年,平时做的并不是什么太有技术含量的事情,但突然有一天突发奇想,很想把工作中的一些东西记录下来,于是打算开始在这里记录,当做平时的工作总结吧。

    大学毕业一年,目前在一家小型公司进行人工智能聊天机器人的对话设计工作。平时 主要使用的智能对话工具主要包括 Google 的 Dialogflow,以及 AIML 文件编写两种方式。

    今天首先想写的是 Dialogflow 这种智能聊天设计工具。

    Dialogflow 的基本用法:一问一答,Training Phrase 和 Response

    Dialogflow 是一个设计智能聊天对话的网站,使用时需要连接外网。且普遍用于英语对话的设计。

    Dialogflow 的使用方法十分简单,主要包括 Agent、Intent、Entity 三部分。Agent 就是存放同一个话题中所有对话的域,可以统一导出成 Json 包的形式保存。一个 Agent 中的对话语句以 Intent 的形式训练出来。每个 Intent 相当于一条语句,对应聊天者的一个意图,训练对话语句时,首先需要新建一个 Agent,Agent 的名字之能是英文数字或下划线,且不能有空格。紧接着我们新建一个 Inent,Intent 名称设定的要求更宽泛一点,它允许有空格。然后,在 Intent 中的 Training Phrase 中输入我们预先设定的可能会说的话,并可以在下方的 Response 一栏中写出对应的回答,如,在 Training Phrase 中输入‘Hello’,按下回车,就会形成一条预定输入,然后在 Response 中输入‘Hi’,这样,当我们在页面右边的 train 面板中输入‘Hello’时,界面就会返回‘Hi’,这就相当于完成了一次简单的对话。

    Response 中,一条语句就是一个回复,如果在 Response 中设定了多个语句,那么在输出时,就可以随机出现 Response 中的一句作为回复输出。

    Entity:关键词匹配实现泛化

    当然,如果每次对话都需要精确地将每一句可能会说到的话都列举出来,那么显然智能的含量就会大打折扣,于是,在 Dialogflow 中,就存在一种最重要的训练方式,使用 Entity 泛化。

    我们可以预先在最左侧 Entity 一栏中添加我们所需的聊天单词的分类。如,我们可以添加一类叫做 sports 的 Entity,并在其中加入 basketball、 football、 baseball 等运动单词。之后就可以去 Intent 中进行训练。利用 Entity, 我们就可以只需对某一类句式进行训练,只需一句话,就可以对多句话做出回答。如,‘I like basketball’。按下回车后,系统会自动识别 basketball 这个单词,并关联出其所在的 Entity 显示在下方。这样,之后如果在 右侧 Train 一栏中输入‘I like football’ 或 ‘I like baseball’ 等,都可以输出这个 Intent 中的 Response 的内容。当然,在训练时,有时系统并不会自动显示出语句中相关单词带有的 Entity,这时,我们可以自己设定,只需要在训练成功的语句上双击相应的单词,界面上就会自动显示可以添加的 Entity 分类,点击选择就可以了。

    Dialogflow 中为我们预先提供了很多常用的 Entity,如时间,数字,日期等,这些 Entity 在使用时,无需我们手动添加相应的 Entity 内容,系统会在你输入相关单词进行训练时,自动识别并为你添加训练语句中带有的预设 Entity。

    Entity 在设定时,每一个 Entity 都对应一个 value,这是 Entity 在系统中被识别使用的值,且可以在 Response 中返回和继承,我们可以在 Response 中使用 $+Entity 的名称来拿到并输出 Entity 的值,同时,为了提高 Entity 匹配到的几率,更大程度上解决有歧义的单词的输入麻烦,也为了满足多种情况下相匹配同一个 Entity 的需求,我们在设定 Entity 时,可以在后面设定很多个同义项,这样,在匹配 sport 这个词时,我们不仅可以输入 basketball,同时也可以输入 sports,以方便我们的使用。

    另外,一个 Intent 中包含的 Entity 的数量不可过多,我曾经因为要对相应的单词数量进行识别以确定语言等级,所以计划给每句话的主谓宾都加上了 Entity,由此就会导致系统紊乱,出现匹配不到或匹配错误等问题。

    Follow-up:为相关语句添加上下文

    在 Dialogflow 中还有一个上下文的设定,就是 Intent 界面中最上面的 Follow-up。我们可以在主界面点击 Intent 为他添加 Follow-up Intent,也可以在 Intent 语句训练界面直接在 context 中输入 相关上下文的 Intent 的名称。这样,我们在进行父 Intent 的对话时,匹配到后就可以直接进入 Follow-up 对话中继续进行下面的对话,且 Follow-up Intent 尤其生效的生存周期,也就是 Context 前面显示的数字,在这个时间段内,我们的对话将一直保持在当前的对话环境中,不会匹配到别的 Intent 去。

    在添加 Follow-up 时,会有许多个选项,我们可以选择普通 Intent,也可以使用 Yes 或 No 判断,从而实现语句树形分支。当对一个问题的回答因 yes or no 不同时,可以走向不同的 Follow-up Intent。

    Action:扩展用标记文本输入

    在 Intent 中还有一个 Action 的空档,在我的工作中,Action 主要被我用于填写一些标识符以供程序扩展,连接实现外部相应的功能,至于其更多的用处,我并没有使用到。

    Dialogflow 中预置的 Agent

    Dialogflow 中,系统为我们预先训练好了许多个实用 Agent,有闹钟,Small-talk 等等,有时,我们可以直接使用这些 Agent 用于我们自己的对话,方便快捷。

    当然,在训练 Intent 时我们也会发现,在每个 Intent 中都有内置的 Small-Talk 开关,如果想在这个 Intent 中也可以匹配到 Hi,Hello 等日常打招呼用语时,我们便可以打开此开关。

    Dialogflow Agent 的数量限制

    Dialogflow 的使用需要用 Google 账号登录,且每个账号最多可设置十个到十二个 Agent,所以,如果你想真对多个不同的话题进行聊天,为了创建多个 Agent,你就需要多个 Google 账号,或申请 Google Cloud 空间了。

    Dialogflow 匹配阀值的设置

    在 Dialogflow Agent 的设置界面,我们可以根据需要设置相应的匹配阀值,来调节匹配的概率和精确度。

    Dialogflow Agent 的导出和导入

    Dialogflow 中的 Agent 可以导出为一个 Json 包,同时也可以将预置的 Json 包导入到 新的 Agent,同样在设置栏中可以找到。

    更多

    在我看来,Dialogflow 更多的是供个体开发者或普通用户体验或开发,并不适用于太大规模的软件开发使用。匹配的精确度根据个人的需求会有很大的不同,且由于匹配和训练都是在网页上完成,且需要连接外网,在实际应用中会根据网络状况存在不同程度的延时,影响开发和使用。

    当然,Dialogflow 自己的官网也有相应的解释说明文档,使用时可以参考查看。

    如有读者,感谢阅读。

    展开全文
  • Seq2Seq实现闲聊机器人

    2021-04-18 13:35:57
    1.小黄鸡的聊天语料:噪声很大 2.微博的标题和评论:质量相对较高 2. 数据的处理和保存 由于数据中存到大量的噪声,可以对其进行基础的处理,然后分别把input和target使用两个文件保存,即inp.
  • 前不久,OPPO 旗下的人工智能助手“小布助手”月度活跃用户数突破一亿,成为国内首个月活用户数破亿的手机语音助手。 经过 2 年多的成长,小布助手在能力上实现大幅升级,也融入了我们身边便捷的服务功能。小布团队...
  • 市面目前的闲聊机器人汇总对比

    千次阅读 2020-02-24 11:16:12
    成熟,响应快,以前项目中的闲聊接口有用过这个API。缺点是收费,认证用户100次/天,如果商业使用99元/月(1000次/天),699¥/年 3、功能: 智能工具:图片搜索,数字计算,语料库,中英互译,聊天对话 娱乐休闲: ...
  • 以下内容总结自《自然语言处理实践与聊天机器人原理应用与实践》 基于生成的闲聊系统较基于对话库检索的闲聊系统更复杂,其能够通过已有的语料生成新文本作为回答。基于生成的闲聊系统通常基于与机器翻译相关的技术...
  • 闲聊系统概述 闲聊系统与问答系统,面向任务的对话系统三者均为聊天机器人的典型应用。但应用任务目标和实现方式均有较大不同目前,大量聊天机器人产品定位于闲聊系统,如微软推出的「小冰」。值得一提的是,2018 年...
  • 例如,我们可能会使用模仿和/或监督学习方法(如果存在大量的人与人之间的会话语料库)来获得合理的良好代理,应用RL继续改进它。 在本文的其余部分,我们将研究这些机器学习方法及其在训练对话系统中的用途。 ...
  • 闲聊机器人的优化

    2021-04-25 17:23:11
    闲聊机器人的优化 1. seq2seq中使用teacher forcing 在前面的seq2seq的案例中,介绍了teacher frocing是什么,当时输入和输出很相似,所以当时我们的teacher forcing是在每个time step中实现的,那么现在我们的...
  • 对于闲聊的机器人呢,语料比较好收集,一些电影台词,平时一些社交网络上的对话都可以,不过它的应用更多的是娱乐性质的,而且模型比较难评价。 基于任务型的聊天机器人主要包含四个模块: Spoken Language ...
  • 不知道穿梭在各个空间的你是否注意,日常生活中的我们已经逐渐成为很多机器人服务的对象。随着人工智能与各行业的融合,AI 技术在更多应用场景成功落地,...面向各种对话场景,提供对话/问答技能搭建、语料标注、对
  • 小姜机器人、python、tensorflow、chatbot、dialog、fuzzywuzzy、搜索、检索式、生成式、聊天、闲聊、对话、问答、多轮、单轮、开放、封闭、任务、垂直等等描述,都属于自动问答领域。而且已经有了比较大的应用,...
  • 实现流程 3.1 整体架构 整个流程的描述如下: 接受用户的问题之后,对问题进行基础的处理 对处理后的问题进行分类,判断其意图 如果用户希望闲聊,那么调用闲聊模型返回结果 如果用户希望咨询问题,那么调用问答...
  • 用户模拟器基础用户模拟器产生背景用户模拟器的基本结构2. 用户模拟器的实现方法基于规则的方法基于模型学习的方法3. 用户模拟器的评价方式4. 用户模拟器面临的挑战5. 总结6. 参考文献 1. 用户模拟器基础 用户...
  • SeConD

    2021-03-21 14:20:12
    大多数现有的多轮对话数据集都是从闲聊或简短对话中提取的,由于缺乏文本和注释的多样性而受到限制(例如,表情符号和分步说明几乎无法在现有数据集)。网络安全对话为用户提供了有关如何采取针对网络攻击的安全措施...
  • Rasa 聊天机器人Rasa_NLU_Chi

    千次阅读 2021-11-12 11:02:18
    Rasa NLU :用于理解用户消息,包括意图识别和实体识别,它会把用户的输入转换为结构化的数据。 Rasa Core:是一个对话管理平台,用于举行对话和决定下一步做什么。 Rasa X是一个工具,可帮助您构建、改进和部署由...
  • 闲聊:类似微软小冰这种,实际应用场景较少。 其中,基于问答对是最为简单的方案,能让我们快速建立一个可用的聊天机器人,其中里面最关键的技术就是语义匹配。我们要首先根据业务场景定义一批【标准问】以及它们...
  • 大概就是用了很多的开源的对话语聊训练了一个中文版本的GPT闲聊对话模型。 我应该吧GPT简单的介绍一下。 GPT(Generative Pre-Training),是OpenAI在2018年提出的模型,利用Transformer模型来解决各种自然语言问题,...
  • 最新综述:对话系统之用户模拟器

    千次阅读 2019-08-05 18:15:26
    作者丨唐呈光、戴音培、李永彬、孙健单位丨阿里巴巴智能服务事业部小蜜北京团队用户模拟器基础用户模拟器产生背景近几年来,强化学习在任务导向型对话系统中得到了广泛的应用,对话系...
  • 深入理解“用于中文闲聊的GPT2模型”项目论文部分提炼DIALOGPT : Large-Scale Generative Pre-trainingfor Conversational Response Generation摘要介绍数据集方法模型结构 本文为对于GPT2 for Chinese chitchat...
  • 设计一个智能客服系统

    万次阅读 2017-03-14 17:55:37
    AliceBot负责闲聊,这里用了开源的语料,也可以添加语料到DB,基于AIML。 AbilityBot主要负责公司业务上的咨询和办理,它提供了不同的能力接口,供外系统交互。 predict模块用于预测响应。 train模块用于训练客服...
  • 机器人是如何实现对话的?

    千次阅读 2020-05-02 14:17:45
    而一般的智能客服厂商,为了更好的衔接对话,也为了让用户有一个更好的对话体验,一般也会加入一定量级的闲聊语料库,但这个库一般却是不允许编辑的,里面涉及一些敏感词的管理,以及运营成本的考虑。 而这个闲聊...
  • 现在的大多数机器人还都是基于语料库检索匹配的。没有什么理解能力,因此智障是难免的。朋友帮我推荐了一家机器人,道翰天琼的认知智能机器人的确很聪明。比我想想的要好很多。老板也很满意,客户也很满意。下面把...
  • 在项目准备阶段我们知道,用户说了一句话后,会判断其意图,如果是想进行闲聊,那么就会调用闲聊模型返回结果。 目前市面上的常见闲聊机器人有微软小冰这种类型的模型,很久之前还有小黄鸡这种体验更差的模型 常见的...
  • 目前有很多 App 里支持自动聊天回复,聊天机器人也被广泛应用在电商、呼叫中心、汽车等场景中,这些炫酷的聊天机器人是如何实现的呢?如何训练一个机器人认识自己的名字?其实我想说,动手去实现就 ok 了。...
  • 导读:随着Bert的发布,预训练 ( pre-train ) 成为NLP领域最为热门的方向之一,大规模的无监督语料加上少量有标注的语料成为了NLP模型的标配。本文将介绍几种常见的语言模型的基本原理和使用方式,以及语言模型在...
  • 他们是认知智能机器人,全新一代技术体系,的确很智能,据说没有语料,无需训练。的确不一样。废话不多说。直接上代码: 认知智能是计算机科学的一个分支科学,是智能科学发展的高级阶段,它以人类认知体系为基础,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 848
精华内容 339
关键字:

用户闲聊语料