使用LSTM进行文本分类

2023-11-06

说明

之前写过用lstm模型做的文本分类,但是代码结构非常混乱。读过Bert源码后,决定模仿Bert的结构,自己重新写一遍使用lstm模型的代码。只作为熟悉tensorflow各个api与一个比较清楚的NLP模型结构的练手用,不求更高的准确率。

使用包含10个商品类别,60000+数据的,已标注正负情感的商品评论数据作为训练语料。原文件为csv格式,包含3个字段:cat(类别)、label(正负情感)、review(实际的评论文字)。其既可作为正负情感分类的二分类训练语料,也可以(勉强)作为商品类别分类的10分类训练语料。

数据取自https://github.com/SophonPlus/ChineseNlpCorpus,非常感谢

已按大约8:2的比例得到了训练集与测试集并将其转为了tsv文件。

使用结巴分词作为切词工具。

一、得到词典txt文件

由于我一直没有找到合适的中文词典文件,Bert中的词典文件又是以字作为最小单位的,故这里暂时只是对待训练的语料做切词、去重的处理,得到一个比较小的字典文件。

def create_vocab():

    raw_df = pd.read_csv(RAW_DATA)                          # 读原始文件为dataframe
    # 热水器有一条数据有问题,不要热水器的数据
    raw_df = raw_df[raw_df.cat != '热水器']

    raw_document = raw_df['review'].tolist()                # 原始语料(list形式)

    # 加载停用词列表
    # with open(STOPWORDS, 'r', encoding='utf-8') as s:
    #     stopwords = [word.strip() for word in s.readlines()]

    document_words = []                                     # 原始语料完成切词
    for sentence in raw_document:
        cut_sentence = [word for word in jieba.lcut(sentence)]
        document_words.extend(cut_sentence)
    vocab_list = set(document_words)

    with open(VOCAB, 'w', encoding='utf-8') as f:
        f.write('[PAD]' + '\n')
        f.write('[UNK]' + '\n')
        for vocab in vocab_list:
            f.write(vocab + '\n')

二、Tokenization

这一块完全基于Bert源码,做了非常多的精简。只满足:to_unicode、读取词典、切词、词语转id、id转词语的基本功能。没什么好说的。

import collections
import tensorflow as tf
import jieba


def convert_to_unicode(text):
    """Converts `text` to Unicode (if it's not already), assuming utf-8 input."""
    if isinstance(text, str):
        return text
    elif isinstance(text, bytes):
        return text.decode("utf-8", "ignore")
    else:
        raise ValueError("Unsupported string type: %s" % (type(text)))


# 将词典中的词构成(词,index)的collections.OrderedDict形式
def load_vocab(vocab_file):
    """Loads a vocabulary file into a dictionary."""
    vocab = collections.OrderedDict()
    index = 0
    with tf.gfile.GFile(vocab_file, "r") as reader:
        while True:
            token = convert_to_unicode(reader.readline())
            if not token:
                break
            token = token.strip()
            vocab[token] = index
            index += 1
    return vocab


def convert_by_vocab(vocab, items):
    """Converts a sequence of [tokens|ids] using the vocab."""
    output = []
    for item in items:
        output.append(vocab.get(item, vocab['[UNK]']))
    return output


class FullTokenizer(object):
    """Runs end-to-end tokenziation."""

    def __init__(self, vocab_file):
        # 根据vocab文件,得到形如(词,index)的字典
        self.vocab = load_vocab(vocab_file)
        # 变成 index: 词 的形式
        self.inv_vocab = {v: k for k, v in self.vocab.items()}

    # 将句子变成词列表
    @staticmethod
    def tokenize(text):
        split_tokens = jieba.lcut(text)
        return split_tokens

    def convert_tokens_to_ids(self, tokens):
        return convert_by_vocab(self.vocab, tokens)

    def convert_ids_to_tokens(self, ids):
        return convert_by_vocab(self.inv_vocab, ids)

三、建立模型结构

模型的mode参数可取train、eval、predict三类,取eval时只返回cost与accuracy,取predict时只返回logits。别的不用多说了。

import tensorflow as tf
import json
import six


class LstmConfig(object):

    def __init__(self,
                 vocab_size,                # 词典中的词数
                 hidden_size=128,
                 keep_prob=0.9,
                 embedding_keep_prob=0.9,   # 词向量不被dropout的比例
                 max_grad_norm=5,
                 num_of_classes=2,          # 分类数
                 num_of_layers=2,           # lstm网络层数
                 initializer_range=0.02):   # 初始化范围
        self.vocab_size = vocab_size
        self.hidden_size = hidden_size
        self.keep_prob = keep_prob
        self.embedding_keep_prob = embedding_keep_prob
        self.max_grad_norm = max_grad_norm
        self.num_of_classes = num_of_classes
        self.num_of_layers = num_of_layers
        self.initializer_range = initializer_range

    @classmethod
    def from_dict(cls, json_object):
        """Constructs a `BertConfig` from a Python dictionary of parameters."""
        config = LstmConfig(vocab_size=None)
        for (key, value) in six.iteritems(json_object):
            config.__dict__[key] = value
        return config

    @classmethod
    def from_json_file(cls, json_file):
        """Constructs a `BertConfig` from a json file of parameters."""
        with tf.gfile.GFile(json_file, "r") as reader:
            text = reader.read()
        return cls.from_dict(json.loads(text))


# 双向LSTM网络模型
class LstmModel(object):

    # 构建网格结构
    def __init__(self, config, mode):
        self.config = config
        self.embedding_keep_prob = config.embedding_keep_prob
        self.mode = mode
        output_keep_prob = config.keep_prob if mode == 'train' else 1.0

        # 词向量
        self.word_embedding = tf.get_variable('word_emb', shape=[config.vocab_size, config.hidden_size])

        # lstm网络结构
        # 前向网络变量
        lstm_cells_fw = [tf.nn.rnn_cell.DropoutWrapper(tf.nn.rnn_cell.BasicLSTMCell(config.hidden_size),
                                                       output_keep_prob=output_keep_prob)
                         for _ in range(config.num_of_layers)]
        self.lstm_fw = tf.nn.rnn_cell.MultiRNNCell(lstm_cells_fw)
        # 反向网络
        lstm_cells_bw = [tf.nn.rnn_cell.DropoutWrapper(tf.nn.rnn_cell.BasicLSTMCell(config.hidden_size),
                                                       output_keep_prob=output_keep_prob)
                         for _ in range(config.num_of_layers)]
        self.lstm_bw = tf.nn.rnn_cell.MultiRNNCell(lstm_cells_bw)

        # Softmax层变量
        self.weight = tf.get_variable('weight', [config.hidden_size * 2, config.num_of_classes])
        self.bias = tf.get_variable('bias', [config.num_of_classes])

    # 定义模型的前向计算图
    def forward(self, src_input, src_size, label):

        # 将输入的序号化单词转成词向量
        inputs = tf.nn.embedding_lookup(self.word_embedding, src_input)
        if self.mode == 'train':
            inputs = tf.nn.dropout(inputs, self.embedding_keep_prob)

        # LSTM网络计算
        with tf.variable_scope('lstm'):
            outputs, states = tf.nn.bidirectional_dynamic_rnn(self.lstm_fw,
                                                              self.lstm_bw,
                                                              inputs,
                                                              dtype=tf.float32,
                                                              sequence_length=src_size)
            final_outputs = tf.concat(outputs, 2)
            final_outputs = final_outputs[:, -1, :]
            # 取平均值
            # final_outputs = tf.reduce_mean(tf.concat(outputs, 2), 1)

        # 全连接层计算
        with tf.variable_scope('fc'):
            logits = tf.matmul(final_outputs, self.weight) + self.bias

        if self.mode == 'predict':
            return logits

        # 损失函数
        with tf.variable_scope('loss'):
            loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=label,
                                                                  logits=logits)
            cost = tf.reduce_mean(loss)

        # 准确率
        with tf.variable_scope('accuracy'):
            correct_prediction = tf.equal(tf.argmax(logits, 1), label)
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

        if self.mode == 'eval':
            return cost, accuracy

        # 定义反向操作
        trainable_variables = tf.trainable_variables()

        # 控制梯度大小,定义优化方法和训练步骤
        grads = tf.gradients(cost, trainable_variables)
        grads, _ = tf.clip_by_global_norm(grads, self.config.max_grad_norm)
        optimizer = tf.train.GradientDescentOptimizer(learning_rate=self.config.learning_rate)

        train_op = optimizer.apply_gradients(zip(grads, trainable_variables))
        return logits, cost, accuracy, train_op

四、分类主程序

我命名为run_classifier,完全照搬Bert。

首先是tf.flag,用于导入参数

flags = tf.flags
FLAGS = flags.FLAGS

flags.DEFINE_integer("train_batch_size", 32, "Total batch size for training.")
flags.DEFINE_integer("eval_batch_size", 8, "Total batch size for eval.")
flags.DEFINE_integer("predict_batch_size", 8, "Total batch size for predict.")
flags.DEFINE_integer("num_train_epochs", 4, "Total epoches for train.")
flags.DEFINE_string(
    "data_dir", "E:/NLP/NLP_Deep_Learning_Summary/datasets",
    "The input data dir. Should contain the .tsv files (or other data files) for the task.")
flags.DEFINE_string("init_checkpoint", None, "Initial checkpoint")
flags.DEFINE_string("vocab_file", "./vocab.txt", "The vocabulary file.")
flags.DEFINE_string("output_file", "./model1", "The output file for trained model.")

flags.DEFINE_bool("do_train", True, "Whether to run training.")
flags.DEFINE_bool("do_eval", True, "Whether to run eval on the dev set.")
flags.DEFINE_bool("do_predict", False, "Whether to run the model in inference mode on the test set.")

定义Example、Feature与DataProcessor类

为了从训练/测试数据中获得tfrecord文件,需要做Example与Feature类的处理。DataProcessor与Bert源码几乎相同,功能为从tsv文件中得到example类的数据。

tsv文件的各个字段为:index(id)、category(商品类别)、polarity(情感,0或1)、text(原始文字)。

class InputExample(object):
    """A single training/test example for simple sequence classification."""

    def __init__(self, guid, text, label=None):
        """Constructs a InputExample."""
        self.guid = guid
        self.text = text
        self.label = label

由于使用的是lstm,其特征包含:每条语料原始的词id、原始的长度(即词数)与原始的分类标签。

class InputFeatures(object):
    def __init__(self, input_ids, input_size, label):
        self.input_ids = input_ids
        self.input_size = input_size
        self.label = label
class DataProcessor(object):

    def get_train_examples(self, data_dir):
        lines = self._read_tsv(os.path.join(data_dir, "online_shopping_train.tsv"))
        return self._create_examples(lines, 'train')

    def get_dev_examples(self, data_dir):
        lines = self._read_tsv(os.path.join(data_dir, "online_shopping_dev.tsv"))
        return self._create_examples(lines, 'dev')

    def get_test_examples(self, data_dir):
        lines = self._read_tsv(os.path.join(data_dir, "online_shopping_test.tsv"))
        return self._create_examples(lines, 'test')

    @staticmethod
    def get_labels():
        return ["0", "1"]
        # return ['蒙牛', '水果', '洗发水', '平板', '酒店', '手机', '计算机', '书籍', '衣服', '热水器']

    @staticmethod
    def _create_examples(lines, set_type):
        examples = []
        for (i, line) in enumerate(lines):
            if i == 0:
                continue
            guid = "%s-%s" % (set_type, i)
            text = tokenization.convert_to_unicode(line[3])
            label = tokenization.convert_to_unicode(line[2])
            examples.append(
                InputExample(guid=guid, text=text, label=label))
        return examples

    @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)
            return lines

得到tfrecord文件

也是模仿Bert的写法写的(甚至保留了打印前五条example)。

# 将一个example类的训练数据转成feature类
def convert_single_example(ex_index, example, tokenizer):
    text = example.text
    tokens = tokenizer.tokenize(text)
    input_ids = tokenizer.convert_tokens_to_ids(tokens)
    input_size = len(input_ids)
    label = int(example.label)
    # 打印前5条转换的记录
    if ex_index < 5:
        tf.logging.info("*** Example ***")
        tf.logging.info("guid: %s" % example.guid)
        tf.logging.info("input_ids: %s" % " ".join([str(x) for x in input_ids]))
        tf.logging.info("input_size: %s" % input_size)
        tf.logging.info("label: %s" % label)
    feature = InputFeatures(input_ids=input_ids, input_size=input_size, label=label)
    return feature


# 将准备喂入模型的数据存成tfrecord文件
def file_based_convert_examples_to_features(examples, tokenizer, output_file):
    writer = tf.python_io.TFRecordWriter(output_file)
    for (ex_index, example) in enumerate(examples):
        if ex_index % 10000 == 0:
            tf.logging.info("Writing example %d of %d" % (ex_index, len(examples)))
        feature = convert_single_example(ex_index, example, tokenizer)

        def create_int_feature(values):
            f = tf.train.Feature(int64_list=tf.train.Int64List(value=list(values)))
            return f

        features = collections.OrderedDict()
        features['input_ids'] = create_int_feature(feature.input_ids)
        features['input_size'] = create_int_feature([feature.input_size])
        features['label'] = create_int_feature([feature.label])

        tf_example = tf.train.Example(features=tf.train.Features(feature=features))
        writer.write(tf_example.SerializeToString())
    writer.close()

读取并解析tfrecord文件

终于又有相对原创的代码了。这里在做batch的同时对input_ids做了padding的处理。效果即input_fn_builder,只是改了名字,调整了结构。

def file_based_dataset_loader(input_file, is_training, batch_size, num_epochs):
    # TfRecord的解析函数
    def parse_func(serialized_example):
        name_to_features = {
            "input_ids": tf.VarLenFeature(tf.int64),
            "input_size": tf.FixedLenFeature(shape=(1,), dtype=tf.int64),
            "label": tf.FixedLenFeature(shape=(1,), dtype=tf.int64),
        }
        parsed_example = tf.parse_single_example(serialized_example, features=name_to_features)
        parsed_example['input_ids'] = tf.sparse_tensor_to_dense(parsed_example['input_ids'])

        input_ids = parsed_example['input_ids']
        input_size = parsed_example['input_size']
        label = parsed_example['label']

        return input_ids, input_size, label

    dataset = tf.data.TFRecordDataset(input_file)
    dataset = dataset.map(parse_func)
    if is_training:
        dataset = dataset.repeat(num_epochs).shuffle(buffer_size=100)

    padded_shapes = (tf.TensorShape([None]),  # 语料数据,None即代表batch_size
                     tf.TensorShape([None]),  # 语料数据各个句子的原始长度
                     tf.TensorShape([None]))  # 标签数据,None即代表batch_size

    # 调用padded_batch方法进行batching操作
    batched_dataset = dataset.padded_batch(batch_size, padded_shapes)
    # dataset = dataset.batch(batch_size)
    return batched_dataset

正式运行

模型运行的函数,单独拿出来。

def run_epoch(session, cost_op, accuracy_op, train_op, step):
    while True:
        try:
            cost, accuracy, _ = session.run([cost_op, accuracy_op, train_op])
            if step % 100 == 0:
                tf.logging.info('Steps: {0}, Loss value: {1},Accuracy: {2}'.format(
                    step, cost, accuracy))
            step += 1
        except tf.errors.OutOfRangeError:
            break

主程序。在config配置里直接写明了词典文件的词数。
另外,不管是在构建词典文件,处理待预测的句子,都没有做去停用词的步骤。

def main():

    config = modelling.LstmConfig(vocab_size=68355)
    tokenizer = tokenization.FullTokenizer(vocab_file=FLAGS.vocab_file)

    processor = DataProcessor()

    if FLAGS.do_train:

        # 定义训练用循环神经网络模型
        train_model = modelling.LstmModel(config, mode='train')

        train_examples = processor.get_train_examples(FLAGS.data_dir)

        num_train_steps = int(len(train_examples) / FLAGS.train_batch_size * FLAGS.num_train_epochs)

        train_file = r'./tmp/train.tfrecord'
        file_based_convert_examples_to_features(train_examples, tokenizer, train_file)

        # 获得训练数据
        train_data = file_based_dataset_loader(train_file,
                                               is_training=True,
                                               batch_size=FLAGS.train_batch_size,
                                               num_epochs=FLAGS.num_train_epochs)
        train_iterator = train_data.make_initializable_iterator()
        input_ids, input_sizes, labels = train_iterator.get_next()
        input_sizes = tf.reshape(input_sizes, shape=(-1,))
        labels = tf.reshape(labels, shape=(-1,))

        # 定义前向计算图,输入数据以张量的形式提供给forward函数
        _, cost_op, accuracy_op, train_op = train_model.forward(input_ids, input_sizes, labels)
        #
        # TensorFlow持久化类
        saver = tf.train.Saver()
        step = 0

        # 训练模型
        tf.logging.info("***** Running training *****")
        tf.logging.info("  Num examples = %d", len(train_examples))
        tf.logging.info("  Total training steps: {}".format(num_train_steps))
        with tf.Session() as sess:
            tf.global_variables_initializer().run()
            sess.run(train_iterator.initializer)
            run_epoch(sess, cost_op, accuracy_op, train_op, step)
            tf.logging.info("********* Training Step Finished *********")

            saver.save(sess, r'./model/lstm.ckpt')

    if FLAGS.do_eval:
        tf.reset_default_graph()
        eval_model = modelling.LstmModel(config, mode='eval')
        eval_examples = processor.get_dev_examples(FLAGS.data_dir)
        eval_file = r'./tmp/eval.tfrecord'
        file_based_convert_examples_to_features(eval_examples, tokenizer, eval_file)

        # 获得测试数据
        eval_data = file_based_dataset_loader(eval_file,
                                              is_training=False,
                                              batch_size=FLAGS.eval_batch_size,
                                              num_epochs=None)
        eval_iterator = eval_data.make_initializable_iterator()
        eval_input_ids, eval_input_sizes, eval_labels = eval_iterator.get_next()
        eval_input_sizes = tf.reshape(eval_input_sizes, shape=(-1,))
        eval_labels = tf.reshape(eval_labels, shape=(-1,))

        eval_cost_op, eval_accuracy_op = eval_model.forward(eval_input_ids, eval_input_sizes, eval_labels)

        # 测试模型
        eval_step = 0
        tf.logging.info("***** Running Eval *****")
        tf.logging.info("  Num examples = %d", len(eval_examples))
        with tf.Session() as sess_eval:
            tf.global_variables_initializer().run()
            sess_eval.run(eval_iterator.initializer)

            saver = tf.train.Saver()
            saver.restore(sess_eval, r'./model/lstm.ckpt')
            tf.logging.info("*** Restore finished ***")

            eval_cost = 0
            eval_correct = 0
            while True:
                try:
                    cost, accuracy = sess_eval.run([eval_cost_op, eval_accuracy_op])
                    eval_cost += cost / FLAGS.eval_batch_size
                    eval_correct += accuracy * FLAGS.eval_batch_size
                    eval_step += 1
                except tf.errors.OutOfRangeError:
                    break
            eval_cost = eval_cost / (len(eval_examples) / FLAGS.eval_batch_size)
            eval_accuracy = eval_correct / len(eval_examples)
        print('Eval Cost: {0}, Eval Accuracy: {1}'.format(eval_cost, eval_accuracy))
        with open(r'./model/eval_result.txt', 'w', encoding='utf-8') as f:
            f.write('Eval Cost: {0}, Eval Accuracy: {1}'.format(eval_cost, eval_accuracy))


if __name__ == '__main__':
    main()

调用模型完成预测

重新写了convert_single_example方法。
由于只是少量单句的预测,因此没有做生成tfrecord并解析的处理,而是直接做了padding的处理。

import tensorflow as tf
import tokenization
import modelling
from run_classifier import InputExample, InputFeatures

# 将一个example类的训练数据转成feature类
def convert_single_example(example, tokenizer):
    text = example.text
    tokens = tokenizer.tokenize(text)
    input_ids = tokenizer.convert_tokens_to_ids(tokens)
    input_size = len(input_ids)
    feature = InputFeatures(input_ids=input_ids, input_size=input_size, label=None)
    return feature


def main(data):
    tokenizer = tokenization.FullTokenizer(vocab_file=r'./vocab.txt')
    config = modelling.LstmConfig(vocab_size=68355)

    input_ids = []
    input_sizes = []
    max_length = 0
    for index in range(len(data)):
        guid = 'test-%d' % index
        text = tokenization.convert_to_unicode(str(data[index]))
        data_example = InputExample(guid=guid, text=text, label=None)

        data_feature = convert_single_example(example=data_example, tokenizer=tokenizer)
        print(data_feature.input_ids)
        if len(data_feature.input_ids) > max_length:
            max_length = len(data_feature.input_ids)
        input_ids.append(data_feature.input_ids)
        input_sizes.append(data_feature.input_size)

    for input_id in input_ids:
        if len(input_id) < max_length:
            input_id.extend((max_length-len(input_id)) * [0])

    input_ids = tf.convert_to_tensor(input_ids)
    input_sizes = tf.convert_to_tensor(input_sizes)

    predict_model = modelling.LstmModel(config, mode='predict')
    output_op = predict_model.forward(input_ids, input_sizes, label=None)

    with tf.Session() as sess:
        saver = tf.train.Saver()
        saver.restore(sess, r'./model/lstm.ckpt')
        output = sess.run(output_op)
        print(output)
        print(tf.argmax(output, 1).eval())


if __name__ == '__main__':

    text = ['这个房间真的很棒,又舒服又便宜', '这个房间太差了,又贵又破,不推荐', '一句很普通很中立的话']
    main(text)

结果

同样的训练集与测试集,在Bert上跑完的准确度是0.946,用lstm,在2个epoch上且没有调整学习率的情况下,跑完准确度有0.897。其中Bert模型在服务器上跑了三天两夜,lstm在本机cpu上跑了一个半小时。结果还可以。

To Do

tf.estimator,这个高级封装的api似乎很牛逼,Bert中也使用了这个api,要继续学习学习。牵扯到model_fn的构建。我理解应该是重新复构模型的结构。在modelling中应该只定义模型结构,对于前向传播的过程,都到model_fn中完成。但是具体的操作还需要进一步的了解。

不得不说,虽然这样的代码可能还是不算高级,但是已经比我之前自己写的初版,在结构上要清楚太多了。同时也对tf.dataset有了比较深的了解(之前的next_batch都是完全自己写的,这里用dataset的iterator就可以搞定)。やはり多读读牛逼的源码是很有用的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用LSTM进行文本分类 的相关文章

  • 添加对 CountVectorizer (sklearn) 的词干支持

    我正在尝试使用 sklearn 将词干添加到 NLP 中的管道中 from nltk stem snowball import FrenchStemmer stop stopwords words french stemmer French
  • 如何使用CNN来训练不同大小的输入数据?

    CNN 似乎主要针对固定大小的输入来实现 现在我想用CNN来训练一些不同大小的句子 有哪些常用的方法 以下建议主要与用于计算机视觉任务 特别是识别 的 CNN 相关 但也可能对您的领域有所帮助 我会看看He 等人的 用于视觉识别的深度卷积网
  • 当我在本地运行 CoreNLP 时,为什么“corenlp.run”会产生不同的结果?

    网站corenlp run http corenlp run它应该是 CoreNLP 演示站点 显示的结果与我在本地计算机上运行 CoreNLP 管道时的结果截然不同 网站上确实显示了正确的结果 而本地机版本却没有 我想知道是否有任何接近
  • 创建向量空间

    我有一个问题 我有很多文档 每一行都是由某种模式构建的 当然 我有这一系列的图案 我想创建一些向量空间 然后通过某种规则来向量这个模式 我还不知道这个规则是什么 即使这个模式像我的向量空间的 质心 然后向量当前文档的每一行 再次按照此规则
  • 训练新的 AutoTokenizer 拥抱脸部

    收到此错误 AttributeError GPT2Tokenizer 对象没有 属性 train new from iterator 与拥抱面部文档非常相似 我更改了输入 就是这样 不应该影响它 有一次就成功了 2小时后回来查看 发现并没有
  • NLTK 中的 FreqDist 未对输出进行排序

    我是 Python 新手 我正在尝试自学语言处理 python 中的 NLTK 有一个名为 FreqDist 的函数 可以给出文本中单词的频率 但由于某种原因它无法正常工作 这是教程让我写的 fdist1 FreqDist text1 vo
  • 如何在 python-gensim 中使用潜在狄利克雷分配(LDA)来抽象二元组主题而不是一元组?

    LDA 原始输出 一元语法 主题1 水肺 水 蒸汽 潜水 主题2 二氧化物 植物 绿色 碳 所需输出 二元组主题 主题1 水肺潜水 水蒸气 主题2 绿色植物 二氧化碳 任何想法 鉴于我有一个名为docs 包含文档中的单词列表 我可以使用 n
  • 如何调整 NLTK 句子标记器

    我正在使用 NLTK 来分析一些经典文本 但我在按句子标记文本时遇到了麻烦 例如 这是我从以下内容中得到的片段莫比迪克 http www gutenberg org cache epub 2701 pg2701 txt import nlt
  • 如何计算两个文本文档之间的相似度?

    我正在考虑使用任何编程语言 尽管我更喜欢 Python 来从事 NLP 项目 我想获取两个文档并确定它们的相似程度 常见的方法是将文档转换为 TF IDF 向量 然后计算它们之间的余弦相似度 任何有关信息检索 IR 的教科书都涵盖了这一点
  • 比较文本文档含义的最佳方法?

    我正在尝试找到使用人工智能和机器学习方法来比较两个文本文档的最佳方法 我使用了 TF IDF Cosine 相似度和其他相似度度量 但这会在单词 或 n gram 级别上比较文档 我正在寻找一种方法来比较meaning的文件 最好的方法是什
  • 词干函数错误:词干需要一个位置参数

    这里的stem函数显示错误 指出stem需要循环中的一个位置参数 如所讨论的 from nltk stem import PorterStemmer as ps text my name is pythonly and looking fo
  • 语音识别中如何处理同音词?

    对于那些不熟悉什么是同音字 https en wikipedia org wiki Homophone是的 我提供以下示例 我们的 是 嗨和高 到 太 二 在使用时语音API https developer apple com docume
  • 从文本文件中提取与输入单词最相似的前 N ​​个单词

    我有一个文本文件 其中包含我使用 BeautifulSoup 提取的网页内容 我需要根据给定的单词从文本文件中找到 N 个相似的单词 流程如下 从中提取文本的网站 https en wikipedia org wiki Football h
  • 如何训练斯坦福 NLP 情感分析工具

    地狱大家 我正在使用斯坦福核心 NLP 包 我的目标是对推文直播进行情感分析 按原样使用情感分析工具对文本 态度 的分析非常差 许多积极因素被标记为中性 许多消极因素被评为积极 我已经在文本文件中获取了超过一百万条推文 但我不知道如何实际获
  • Node2vec 的工作原理

    我一直在读关于node2vec https cs stanford edu jure pubs node2vec kdd16 pdf嵌入算法 我有点困惑它是如何工作的 作为参考 node2vec 由 p 和 q 参数化 并通过模拟来自节点的
  • 快速NLTK解析成语法树

    我正在尝试将数百个句子解析为语法树 我需要快速完成 问题是如果我使用 NLTK 那么我需要定义一个语法 而我不知道我只知道它会是英语 我尝试使用this https github com emilmont pyStatParser统计解析器
  • 使用正则表达式标记化进行 NLP 词干提取和词形还原

    定义一个函数 名为performStemAndLemma 它需要一个参数 第一个参数 textcontent 是一个字符串 编辑器中给出了函数定义代码存根 执行以下指定任务 1 对给出的所有单词进行分词textcontent 该单词应包含字
  • openNLP 与 Solr 集成时出现异常

    我正在尝试将 openNLP 与 Solr 6 1 0 集成 我配置了架构和 solrconfig 文件 详细信息请参见 wiki 链接 https wiki apache org solr OpenNLP https wiki apach
  • 阻止斯坦福核心 NLP 服务器输出它收到的文本

    我正在运行一个斯坦福核心自然语言处理 http stanfordnlp github io CoreNLP server java mx4g cp edu stanford nlp pipeline StanfordCoreNLPServe
  • 如何在Python中使用多处理来加速循环执行

    我有两个清单 列表 A 包含 500 个单词 列表 B 包含 10000 个单词 我正在尝试为列表 A 找到与 B 相关的相似单词 我正在使用 Spacy 的相似函数 我面临的问题是计算需要很长时间 我是多处理使用的新手 因此请求帮助 如何

随机推荐

  • 大三,改变生活的一年

    国庆假期在偶然看到了去年假期画的stm32开发板的PCB 当时接触还没有一个月 想到了大三这一年来的点点滴滴 突然就想写下点什么 对于过去的一年的总结 又提醒自己还是给小白 要继续加油 首先我先说一下自己的情况 我是一个很普通的本科生 真的
  • 《人类染色体与染色体病》学习笔记

    染色质与染色体 染色质为细丝状 当细胞分裂时 染色质复制反复盘绕高度压缩 凝集形成兴泰特定的条状染色体 以保证DNA能准确分配到两个子细胞中 染色质和染色体的化学组成 DNA和组蛋白占染色质化学总量98 以上 染色质的种类 染色质由于其折叠
  • 消息通知系统

    using UnityEngine using System Collections using System Collections Generic public delegate void NotificationDelegate No
  • 华为OD机试真题-单词接龙-2023年OD统一考试(B卷)

    题目描述 单词接龙的规则是 可用于接龙的单词首字母必须要前一个单词的尾字母相同 当存在多个首字母相同的单词时 取长度最长的单词 如果长度也相等 则取字典序最小的单词 已经参与接龙的单词不能重复使用 现给定一组全部由小写字母组成单词数组 并指
  • hive错误:Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Permission denied

    用不同用户去登录hive 可能会报如下错误 Exception in thread main java lang RuntimeException java io IOException Permission denied at org a
  • 嵌入式开发中的通讯协议(UART、SPI、CAN、I2C)

    一 UART UART是一种通用串行数据总线 用于异步通信 该总线双向通信 可以实现全双工传输和接收 1 1接口 两根线 UART TX 发送 UART RX 接收 1 2如何传输 UART作为异步串口通信协议的一种 工作原理是将传输数据的
  • Spring事务传播问题 — PROPAGATION_REQUIRES_NEW

    一 描述Spring遇到嵌套事务时 当被嵌套的事务被定义为 PROPAGATION REQUIRES NEW 时 内层Service的方法被调用时 外层方法的事务被挂起 内层事务相对于外层事务是完全独立的 有独立的隔离性等等 二 实验但实验
  • 区块链中节点和区块的关系&区块链的基本概念

    可以用数学知识来理解 节点是点 区块是线 区块链是面 节点是区块链应用技术里处理信息的基本单位 很多的结点处理完信息后 会被打上时间戳 生成数据区块 把区块按时间先后顺序连接起来就区块链 区块链是一个分布式分类账本 每个区块都是账本中的一页
  • PCB该怎样布局布线,这个小小案例,让你快速了解设计思路!

    在电路设计过程中 应用工程师往往会忽视印刷电路板 PCB 的布局 通常遇到的问题是 电路的原理图是正确的 但并不起作用 或仅以低性能运行 在本文中 我将向您介绍如何正确地布设运算放大器的电路板以确保其功能 性能和稳健性 最近 我与一名实习生
  • 16进制转化为10进制总结

    十六进制转换有16进制每一位上可以是从小到大为0 1 2 3 4 5 6 7 8 9 A B C D E F16个大小不同的数 即逢16进1 其中用A B C D E F 字母不区分大小写 这六个字母来分别表示10 11 12 13 14
  • Android Https相关完全解析 当OkHttp遇到Https

    http blog csdn net lmj623565791 article details 48129405
  • 初始化MySQL时可能遇到的问题

    之前自己第一次初始化数据库时一切顺利 基本过程也已经记录在这里 然而今天换了个环境重新配置数据库的时候 出现了许许多多的问题 趁自己还记得 简单做一下记录 1 Install时出错 在输入指令 mysqld install 时出错 出错内容
  • 如何控制步进电机速度(即,如何计算脉冲频率):

    两相步进电机介绍 实际步进电机控制很简单 应用都是傻瓜了 厂家做好步进电机的驱动器 步进电机如何工作由驱动器来控制 我们不需要对步进电机做深入的了解 只要知道步进电机驱动器的应用方法即可 当然简单的步进电机工作特性 还是必须知道的 下面我会
  • python代码~玫瑰花小练习

    完整代码如下 RoseDraw py import turtle as t 定义一个曲线绘制函数 def DegreeCurve n r d 1 for i in range n t left d t circle r abs d 初始位置
  • C++中 struct tm 和 time_t 时间和日期的使用方法

    1 概念 在C C 中 对字符串的操作有很多值得注意的问题 同样 C C 对时间的操作也有许多值得大家注意的地方 下面主要介绍在C C 中时间和日期的使用方法 通过学习C C 库 你会发现有很多操作 使用时间的方法 但在这之前你需要了解一些
  • C语言指针学习

    开始好好学习C语言啦 指针是C语言比较难的地方 但是非常重要 所以单独在此记录一下 有执念的人最可怕 一定要好好学习哇 C语言指针学习 1 指针是什么 2 null指针 3 指针的运算 4 数组指针 一维数组指针 二维数组指针 5 指针数组
  • 2023年网络安全比赛--网络安全应急响应中职组(超详细)

    一 竞赛时间 180分钟 共计3小时 二 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 1 找出被黑客修改的系统别名 并将倒数第二个别名作为Flag值提交 2 找出系统中被植入的后门用户删除掉 并将后门用户的账号作为Flag值提交
  • 对1bit的脉冲信号进行展宽,转为32bit位宽,并产生有效信号

    如题 Verilog实现 奉上拙见 对1bit的脉冲信号进行展宽 转为32bit位宽 并产生有效信号 module zhankuan input clk input rst n input pulse in output reg pulse
  • Detected problems with API compatibility(visit g.co/dev/appcompat for more info)

    最近手机升级了Android 9 在写应用程序的时候进场会弹出一个弹框 如下在这里插入图片描述 吓得我一身冷汗 在对应的网站上看了下信息 原来是在android限制调用hide注解的api 注意这种现在并非原来的在sdk中简单去掉hide注
  • 使用LSTM进行文本分类

    说明 之前写过用lstm模型做的文本分类 但是代码结构非常混乱 读过Bert源码后 决定模仿Bert的结构 自己重新写一遍使用lstm模型的代码 只作为熟悉tensorflow各个api与一个比较清楚的NLP模型结构的练手用 不求更高的准确