nlp代码 - CSDN
精华内容
参与话题
  • chqiwang/convseg,基于CNN做中文分词,提供数据和代码。 对应的论文Convolutional Neural Network with Word Embeddings for Chinese Word SegmentationIJCNLP2017. 2.词预测 Word Prediction Kyubyong/w...

     

    1.分词 Word Segmentation

    chqiwang/convseg ,基于CNN做中文分词,提供数据和代码。

    对应的论文Convolutional Neural Network with Word Embeddings for Chinese Word Segmentation IJCNLP2017.

     

    2.词预测 Word Prediction

    Kyubyong/word_prediction ,基于CNN做词预测,提供数据和代码。

     

    3. 文本蕴涵 Textual Entailment

    Steven-Hewitt/Entailment-with-Tensorflow,基于Tensorflow做文本蕴涵,提供数据和代码。

     

    4. 语音识别 Automatic Speech Recognition

    buriburisuri/speech-to-text-wavenet,基于DeepMind WaveNet和Tensorflow做句子级语音识别。

    5. 自动摘要 Automatic Summarisation

    PKULCWM/PKUSUMSUM,北大万小军老师团队的自动摘要方法汇总,包含了他们大量paper的实现,支持单文档摘要、多文档摘要、topic-focused多文档摘要。

     

    6. 文本纠错 Text Correct

    atpaino/deep-text-corrector,基于深度学习做文本纠错,提供数据和代码。

     

    7.字音转换 Grapheme to Phoneme

    cmusphinx/g2p-seq2seq,基于网红transformer做, 提供数据和代码。

     

    8. 复述检测 Paraphrase Detection 和 问答 Question Answering

    Paraphrase-Driven Learning for Open Question Answering, 基于复述驱动学习的开放域问答。

     

    9. 音汉互译 Pinyin-To-Chinese

    Kyubyong/neural_chinese_transliterator,基于CNN做音汉互译。

     

    10. 情感分析 Sentiment Analysis

    情感分析包括的内容太多了,目前没发现比较全的。推荐两个适合练手的吧:Deeply Moving: Deep Learning for Sentiment Analysishttp://sentic.net/about/

     

    11. 手语识别 Sign Language Recognition

    Home - SignAll, 该项目在手语识别做的非常成熟。

     

    12. 词性标注(POS)、 命名实体识别(NER)、 句法分析(parser)、 语义角色标注(SRL) 等。

    HIT-SCIR/ltp, 包括代码、模型、数据,还有详细的文档,而且效果还很好。

     

    13. 词干 Word Stemming

    snowballstem/snowball, 实现的词干效果还不错。

     

    14. 语言识别 Language Identification

    https://github.com/saffsd/langid.py,语言识别比较好的开源工具。

     

    15. 机器翻译 Machine Translation

    OpenNMT/OpenNMT-py, 基于PyTorch的神经机器翻译,很适合练手。

     

    16. 复述生成 Paraphrase Generation

    vsuthichai/paraphraser,基于Tensorflow的句子级复述生成,适合练手。

     

    17. 关系抽取 Relationship Extraction

    ankitp94/relationship-extraction,基于核方法的关系抽取。

     

    18. 句子边界消歧 Sentence Boundary Disambiguation

    https://github.com/Orekhov/SentenceBreaking,很有意思。

     

    19.事件抽取 Event Extraction

    liuhuanyong/ComplexEventExtraction, 中文复合事件抽取,包括条件事件、因果事件、顺承事件、反转事件等事件抽取,并形成事理图谱。

     

    20. 词义消歧 Word Sense Disambiguation

    alvations/pywsd,代码不多,方法简单,适合练手。

     

    21. 命名实体消歧 Named Entity Disambiguation

    dice-group/AGDISTIS,实体消歧是很重要的,尤其对于实体融合(比如知识图谱中多源数据融合)、实体链接。

     

    22. 幽默检测 Humor Detection

    pln-fing-udelar/pghumor

     

    23. 讽刺检测 Sarcasm Detection

    AniSkywalker/SarcasmDetection,基于神经网络的讽刺检测。

     

    24. 实体链接 Entity Linking

    hasibi/EntityLinkingRetrieval-ELR, 实体链接用途非常广,非常适合练手。

     

    25. 指代消歧 Coreference Resolution

    huggingface/neuralcoref,基于神经网络的指代消歧。

     

    26. 关键词/短语抽取和社会标签推荐 Keyphrase Extraction and Social Tag Suggestion

    thunlp/THUTag, 用多种方法 实现了多种关键词/短语抽取和社会标签推荐。

    参考:https://zhuanlan.zhihu.com/p/51279338

    展开全文
  • NLP】:1.文本分类之代码

    千次阅读 2019-01-08 22:10:08
    文本分类是商业问题中常见的自然语言处理任务,目标是自动将文本文件分到一个或多个已定义好的类别中。文本分类的一些例子如下: 分析社交媒体中的大众情感 鉴别垃圾邮件和非垃圾邮件 自动标注客户问询 将...

    代码我放在我的github:https://github.com/JackKuo666/csdn/blob/master/text_classfier/text_classfier.ipynb

    引言

    文本分类是商业问题中常见的自然语言处理任务,目标是自动将文本文件分到一个或多个已定义好的类别中。文本分类的一些例子如下:

    分析社交媒体中的大众情感
    
    鉴别垃圾邮件和非垃圾邮件
    
    自动标注客户问询
    
    将新闻文章按主题分类
    
    #导入数据集预处理、特征工程和模型训练所需的库
    
    from sklearn import model_selection, preprocessing, linear_model, naive_bayes, metrics, svm
    
    from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
    
    from sklearn import decomposition, ensemble
    
    
    import pandas, xgboost, numpy, textblob, string
    
    from keras.preprocessing import text, sequence
    
    from keras import layers, models, optimizers
    
    Using TensorFlow backend.
    

    一、准备数据集

    在本文中,我使用亚马逊的评论数据集,它可以从这个链接下载:

    https://gist.github.com/kunalj101/ad1d9c58d338e20d09ff26bcc06c4235
    

    这个数据集包含3.6M的文本评论内容及其标签,我们只使用其中一小部分数据。首先,将下载的数据加载到包含两个列(文本和标签)的pandas的数据结构(dataframe)中。

    #加载数据集
    
    data = open('data/corpus').read()
    
    labels, texts = [], []
    
    for i, line in enumerate(data.split("\n")):
    
        content = line.split()
        
        #print(content)
        #print(content[1])
    
        labels.append(content[0])
    
        texts.append(content[1])
    
    
    #创建一个dataframe,列名为text和label
    
    trainDF = pandas.DataFrame()
    
    trainDF['text'] = texts
    
    trainDF['label'] = labels
    
    
    #print texts[:10],labels[:10]
    

    每一个content的数据是这样的:
    [’__label__2’, ‘Stuning’, ‘even’, ‘for’, ‘the’, ‘non-gamer:’, ‘This’, ‘sound’, ‘track’, ‘was’, ‘beautiful!’, ‘It’, ‘paints’, ‘the’, ‘senery’, ‘in’, ‘your’, ‘mind’, ‘so’, ‘well’, ‘I’, ‘would’, ‘recomend’, ‘it’, ‘even’, ‘to’, ‘people’, ‘who’, ‘hate’, ‘vid.’, ‘game’, ‘music!’, ‘I’, ‘have’, ‘played’, ‘the’, ‘game’, ‘Chrono’, ‘Cross’, ‘but’, ‘out’, ‘of’, ‘all’, ‘of’, ‘the’, ‘games’, ‘I’, ‘have’, ‘ever’, ‘played’, ‘it’, ‘has’, ‘the’, ‘best’, ‘music!’, ‘It’, ‘backs’, ‘away’, ‘from’, ‘crude’, ‘keyboarding’, ‘and’, ‘takes’, ‘a’, ‘fresher’, ‘step’, ‘with’, ‘grate’, ‘guitars’, ‘and’, ‘soulful’, ‘orchestras.’, ‘It’, ‘would’, ‘impress’, ‘anyone’, ‘who’, ‘cares’, ‘to’, ‘listen!’, ‘_’]

    值得注意的是:texts里边存的是每个样本的第一个单词,我不知道这个是作者故意的还是疏忽?

    texts[:10]和labels[:10]的数据是这样的:
    [‘Stuning’, ‘The’, ‘Amazing!:’, ‘Excellent’, ‘Remember,’, ‘an’, ‘Buyer’, ‘Glorious’, ‘A’, ‘Whispers’]
    [’__label__2’, ‘__label__2’, ‘__label__2’, ‘__label__2’, ‘__label__2’, ‘__label__2’, ‘__label__1’, ‘__label__2’, ‘__label__2’, ‘__label__2’]

    接下来,我们将数据集分为训练集和验证集,这样我们可以训练和测试分类器。另外,我们将编码我们的目标列,以便它可以在机器学习模型中使用:

    #将数据集分为训练集和验证集
    
    train_x, valid_x, train_y, valid_y = model_selection.train_test_split(trainDF['text'], trainDF['label'])
    
    #print(trainDF,train_x,valid_x)
    #将trainDF(10000)个样本和标签打乱拆分成train_x(7500)个,valid_x(2500)个
    
    # label编码为目标变量
    
    encoder = preprocessing.LabelEncoder()
    
    #print train_y
    train_y = encoder.fit_transform(train_y)
    #print train_y
    #将label编码由3451    __label__1 6228    __label__2形式为[0 1 0 。。。]形式
    
    valid_y = encoder.fit_transform(valid_y)
    

    二、特征工程

    接下来是特征工程,在这一步,原始数据将被转换为特征向量,另外也会根据现有的数据创建新的特征。为了从数据集中选出重要的特征,有以下几种方式:

    1.计数向量作为特征
    
    2.TF-IDF向量作为特征
    
        2.1单个词语级别
    
        2.2多个词语级别(N-Gram)
    
        2.3词性级别
    
    3.词嵌入作为特征
    
    4.基于文本/NLP的特征
    
    5.主题模型作为特征
    

    2.1 计数向量作为特征

    计数向量是数据集的矩阵表示,其中每行代表来自语料库的文档,每列表示来自语料库的术语,并且每个单元格表示特定文档中特定术语的频率计数:

    #创建一个向量计数器对象
    
    count_vect = CountVectorizer(analyzer='word', token_pattern=r'\w{1,}')
    
    count_vect.fit(trainDF['text'])
    
    CountVectorizer(analyzer='word', binary=False, decode_error=u'strict',
            dtype=<type 'numpy.int64'>, encoding=u'utf-8', input=u'content',
            lowercase=True, max_df=1.0, max_features=None, min_df=1,
            ngram_range=(1, 1), preprocessor=None, stop_words=None,
            strip_accents=None, token_pattern='\\w{1,}', tokenizer=None,
            vocabulary=None)
    
    #使用向量计数器对象转换训练集和验证集
    
    xtrain_count =  count_vect.transform(train_x)
    
    
    xvalid_count =  count_vect.transform(valid_x)
    

    2.2 TF-IDF向量作为特征

    TF-IDF的分数代表了词语在文档和整个语料库中的相对重要性。TF-IDF分数由两部分组成:第一部分是计算标准的词语频率(TF),第二部分是逆文档频率(IDF)。其中计算语料库中文档总数除以含有该词语的文档数量,然后再取对数就是逆文档频率。

    TF(t)=(该词语在文档出现的次数)/(文档中词语的总数)

    IDF(t)= log_e(文档总数/出现该词语的文档总数)

    TF-IDF向量可以由不同级别的分词产生(单个词语,词性,多个词(n-grams))

    词语级别TF-IDF:矩阵代表了每个词语在不同文档中的TF-IDF分数。
    
    N-gram级别TF-IDF: N-grams是多个词语在一起的组合,这个矩阵代表了N-grams的TF-IDF分数。
    
    词性级别TF-IDF:矩阵代表了语料中多个词性的TF-IDF分数。
    
    #词语级tf-idf
    
    tfidf_vect = TfidfVectorizer(analyzer='word', token_pattern=r'\w{1,}', max_features=5000)
    
    tfidf_vect.fit(trainDF['text'])
    
    xtrain_tfidf =  tfidf_vect.transform(train_x)
    
    xvalid_tfidf =  tfidf_vect.transform(valid_x)
    
    
    # ngram 级tf-idf
    
    tfidf_vect_ngram = TfidfVectorizer(analyzer='word', token_pattern=r'\w{1,}', ngram_range=(2,3), max_features=5000)
    
    tfidf_vect_ngram.fit(trainDF['text'])
    
    xtrain_tfidf_ngram =  tfidf_vect_ngram.transform(train_x)
    
    xvalid_tfidf_ngram =  tfidf_vect_ngram.transform(valid_x)
    
    
    #词性级tf-idf
    
    tfidf_vect_ngram_chars = TfidfVectorizer(analyzer='char', token_pattern=r'\w{1,}', ngram_range=(2,3), max_features=5000)
    
    tfidf_vect_ngram_chars.fit(trainDF['text'])
    
    xtrain_tfidf_ngram_chars =  tfidf_vect_ngram_chars.transform(train_x) 
    
    xvalid_tfidf_ngram_chars =  tfidf_vect_ngram_chars.transform(valid_x) 
    

    2.3 词嵌入

    词嵌入是使用稠密向量代表词语和文档的一种形式。向量空间中单词的位置是从该单词在文本中的上下文学习到的,词嵌入可以使用输入语料本身训练,也可以使用预先训练好的词嵌入模型生成,词嵌入模型有:Glove, FastText,Word2Vec。它们都可以下载,并用迁移学习的方式使用。想了解更多的词嵌入资料,可以访问:

    https://www.analyticsvidhya.com/blog/2017/06/word-embeddings-count-word2veec/
    

    接下来介绍如何在模型中使用预先训练好的词嵌入模型,主要有四步:

    1. 加载预先训练好的词嵌入模型

    2. 创建一个分词对象

    3. 将文本文档转换为分词序列并填充它们

    4. 创建分词和各自嵌入的映射

    #加载预先训练好的词嵌入向量
    
    embeddings_index = {}
    
    for i, line in enumerate(open('/home/kuo/data/wiki-news-300d-1M.vec')):
    
        values = line.split()
    #     if i == 0:
    #         print values  #['999994', '300']
    
        embeddings_index[values[0]] = numpy.asarray(values[1:], dtype='float32')
    
    
    #创建一个分词器
    
    token = text.Tokenizer()
    
    token.fit_on_texts(trainDF['text'])
    
    word_index = token.word_index
    
    
    #将文本转换为分词序列,并填充它们保证得到相同长度的向量
    
    train_seq_x = sequence.pad_sequences(token.texts_to_sequences(train_x), maxlen=70)
    
    valid_seq_x = sequence.pad_sequences(token.texts_to_sequences(valid_x), maxlen=70)
    
    
    #创建分词嵌入映射
    
    embedding_matrix = numpy.zeros((len(word_index) + 1, 300))
    
    for word, i in word_index.items():
    
        embedding_vector = embeddings_index.get(word)
    
    if embedding_vector is not None:
    
        embedding_matrix[i] = embedding_vector
    

    print len(train_seq_x[0])

    70

    print (train_seq_x[0])

    [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 220]

    print len(embedding_matrix[0])

    300

    2.4 基于文本/NLP的特征

    创建许多额外基于文本的特征有时可以提升模型效果。比如下面的例子:

    文档的词语计数—文档中词语的总数量
    
    文档的词性计数—文档中词性的总数量
    
    文档的平均字密度--文件中使用的单词的平均长度
    
    完整文章中的标点符号出现次数--文档中标点符号的总数量
    
    整篇文章中的大写次数—文档中大写单词的数量
    
    完整文章中标题出现的次数—文档中适当的主题(标题)的总数量
    
    词性标注的频率分布
    
        名词数量
    
        动词数量
    
        形容词数量
    
        副词数量
    
        代词数量
    

    这些特征有很强的实验性质,应该具体问题具体分析。

    trainDF['char_count'] = trainDF['text'].apply(len)
    
    trainDF['word_count'] = trainDF['text'].apply(lambda x: len(x.split()))
    
    trainDF['word_density'] = trainDF['char_count'] / (trainDF['word_count']+1)
    
    trainDF['punctuation_count'] = trainDF['text'].apply(lambda x: len("".join(_ for _ in x if _ in string.punctuation))) 
    
    trainDF['title_word_count'] = trainDF['text'].apply(lambda x: len([wrd for wrd in x.split() if wrd.istitle()]))
    
    trainDF['upper_case_word_count'] = trainDF['text'].apply(lambda x: len([wrd for wrd in x.split() if wrd.isupper()]))
    
    
    trainDF['char_count'] = trainDF['text'].apply(len)
    
    trainDF['word_count'] = trainDF['text'].apply(lambda x: len(x.split()))
    
    trainDF['word_density'] = trainDF['char_count'] / (trainDF['word_count']+1)
    
    trainDF['punctuation_count'] = trainDF['text'].apply(lambda x: len("".join(_ for _ in x if _ in string.punctuation))) 
    
    trainDF['title_word_count'] = trainDF['text'].apply(lambda x: len([wrd for wrd in x.split() if wrd.istitle()]))
    
    trainDF['upper_case_word_count'] = trainDF['text'].apply(lambda x: len([wrd for wrd in x.split() if wrd.isupper()]))
    
    pos_family = {
        'noun' : ['NN','NNS','NNP','NNPS'],
        'pron' : ['PRP','PRP$','WP','WP$'],
        'verb' : ['VB','VBD','VBG','VBN','VBP','VBZ'],
        'adj' :  ['JJ','JJR','JJS'],
        'adv' : ['RB','RBR','RBS','WRB']
    }
    
    
    #检查和获得特定句子中的单词的词性标签数量
    
    def check_pos_tag(x, flag):
        cnt = 0
        try:
            wiki = textblob.TextBlob(x)
            for tup in wiki.tags:
                ppo = list(tup)[1]
                if ppo in pos_family[flag]:
                    cnt += 1
        except:
            pass
        return cnt
    
    
    trainDF['noun_count'] = trainDF['text'].apply(lambda x: check_pos_tag(x, 'noun'))
    
    trainDF['verb_count'] = trainDF['text'].apply(lambda x: check_pos_tag(x, 'verb'))
    
    trainDF['adj_count'] = trainDF['text'].apply(lambda x: check_pos_tag(x, 'adj'))
    
    trainDF['adv_count'] = trainDF['text'].apply(lambda x: check_pos_tag(x, 'adv'))
    
    trainDF['pron_count'] = trainDF['text'].apply(lambda x: check_pos_tag(x, 'pron'))
    

    2.5 主题模型作为特征

    主题模型是从包含重要信息的文档集中识别词组(主题)的技术,我已经使用LDA生成主题模型特征。LDA是一个从固定数量的主题开始的迭代模型,每一个主题代表了词语的分布,每一个文档表示了主题的分布。虽然分词本身没有意义,但是由主题表达出的词语的概率分布可以传达文档思想。如果想了解更多主题模型,请访问:

    https://www.analyticsvidhya.com/blog/2016/08/beginners-guide-to-topic-modeling-in-python/
    

    我们看看主题模型运行过程:

    #训练主题模型
    
    lda_model = decomposition.LatentDirichletAllocation(n_components=20, learning_method='online', max_iter=20)
    
    X_topics = lda_model.fit_transform(xtrain_count)
    
    topic_word = lda_model.components_ 
    
    vocab = count_vect.get_feature_names()
    
    
    #可视化主题模型
    
    n_top_words = 10
    
    topic_summaries = []
    
    for i, topic_dist in enumerate(topic_word):
        topic_words = numpy.array(vocab)[numpy.argsort(topic_dist)][:-(n_top_words+1):-1]
        topic_summaries.append(' '.join(topic_words))
    

    三、建模

    文本分类框架的最后一步是利用之前创建的特征训练一个分类器。关于这个最终的模型,机器学习中有很多模型可供选择。我们将使用下面不同的分类器来做文本分类:

    朴素贝叶斯分类器
    
    线性分类器
    
    支持向量机(SVM)
    
    Bagging Models
    
    Boosting Models
    
    浅层神经网络
    
    深层神经网络
    
        卷积神经网络(CNN)
    
        LSTM
    
        GRU
    
        双向RNN
    
        循环卷积神经网络(RCNN)
    
        其它深层神经网络的变种
    

    接下来我们详细介绍并使用这些模型。下面的函数是训练模型的通用函数,它的输入是分类器、训练数据的特征向量、训练数据的标签,验证数据的特征向量。我们使用这些输入训练一个模型,并计算准确度。

    def train_model(classifier, feature_vector_train, label, feature_vector_valid, is_neural_net=False):
        # fit the training dataset on the classifier
        classifier.fit(feature_vector_train, label)
        
        # predict the labels on validation dataset
        predictions = classifier.predict(feature_vector_valid)
        
        if is_neural_net:
            predictions = predictions.argmax(axis=-1)
        
        return metrics.accuracy_score(predictions, valid_y)
    

    3.1 朴素贝叶斯

    利用sklearn框架,在不同的特征下实现朴素贝叶斯模型。

    朴素贝叶斯是一种基于贝叶斯定理的分类技术,并且假设预测变量是独立的。朴素贝叶斯分类器假设一个类别中的特定特征与其它存在的特征没有任何关系。

    想了解朴素贝叶斯算法细节可点击:
    https://www.analyticsvidhya.com/blog/2017/09/naive-bayes-explained/

    #特征为计数向量的朴素贝叶斯
    accuracy = train_model(naive_bayes.MultinomialNB(), xtrain_count, train_y, xvalid_count)
    print "NB, Count Vectors: ", accuracy
    
    #特征为词语级别TF-IDF向量的朴素贝叶斯
    accuracy = train_model(naive_bayes.MultinomialNB(), xtrain_tfidf, train_y, xvalid_tfidf)
    print "NB, WordLevel TF-IDF: ", accuracy
    
    #特征为多个词语级别TF-IDF向量的朴素贝叶斯
    accuracy = train_model(naive_bayes.MultinomialNB(), xtrain_tfidf_ngram, train_y, xvalid_tfidf_ngram)
    print "NB, N-Gram Vectors: ", accuracy
    
    #特征为词性级别TF-IDF向量的朴素贝叶斯
    accuracy = train_model(naive_bayes.MultinomialNB(), xtrain_tfidf_ngram_chars, train_y, xvalid_tfidf_ngram_chars)
    print "NB, CharLevel Vectors: ", accuracy
    
    NB, Count Vectors:  0.6996
    NB, WordLevel TF-IDF:  0.6976
    NB, N-Gram Vectors:  0.498
    NB, CharLevel Vectors:  0.6704
    

    3.2 线性分类器

    实现一个线性分类器(Logistic Regression):Logistic回归通过使用logistic / sigmoid函数估计概率来度量类别因变量与一个或多个独立变量之间的关系。如果想了解更多关于logistic回归,请访问:

    https://www.analyticsvidhya.com/blog/2015/10/basics-logistic-regression/
    
    #特征为计数向量的线性分类器
    accuracy = train_model(linear_model.LogisticRegression(), xtrain_count, train_y, xvalid_count)
    print "LR, Count Vectors: ", accuracy
    
    #特征为词语级别TF-IDF向量的线性分类器
    accuracy = train_model(linear_model.LogisticRegression(), xtrain_tfidf, train_y, xvalid_tfidf)
    print "LR, WordLevel TF-IDF: ", accuracy
    
    #特征为多个词语级别TF-IDF向量的线性分类器
    accuracy = train_model(linear_model.LogisticRegression(), xtrain_tfidf_ngram, train_y, xvalid_tfidf_ngram)
    print "LR, N-Gram Vectors: ", accuracy
    
    #特征为词性级别TF-IDF向量的线性分类器
    accuracy = train_model(linear_model.LogisticRegression(), xtrain_tfidf_ngram_chars, train_y, xvalid_tfidf_ngram_chars)
    print "LR, CharLevel Vectors: ", accuracy
    
    LR, Count Vectors:  0.7012
    LR, WordLevel TF-IDF:  0.6988
    LR, N-Gram Vectors:  0.4992
    LR, CharLevel Vectors:  0.698
    

    3.3 实现支持向量机模型

    支持向量机(SVM)是监督学习算法的一种,它可以用来做分类或回归。该模型提取了分离两个类的最佳超平面或线。如果想了解更多关于SVM,请访问:

    https://www.analyticsvidhya.com/blog/2017/09/understaing-support-vector-machine-example-code/
    
    #特征为多个词语级别TF-IDF向量的SVM
    accuracy = train_model(svm.SVC(), xtrain_tfidf_ngram, train_y, xvalid_tfidf_ngram)
    print "SVM, N-Gram Vectors: ", accuracy
    
    SVM, N-Gram Vectors:  0.496
    

    3.4 Bagging Model

    实现一个随机森林模型:随机森林是一种集成模型,更准确地说是Bagging model。它是基于树模型家族的一部分。如果想了解更多关于随机森林,请访问:

    https://www.analyticsvidhya.com/blog/2014/06/introduction-random-forest-simplified/
    
    #特征为计数向量的RF
    accuracy = train_model(ensemble.RandomForestClassifier(), xtrain_count, train_y, xvalid_count)
    print "RF, Count Vectors: ", accuracy
    
    #特征为词语级别TF-IDF向量的RF
    accuracy = train_model(ensemble.RandomForestClassifier(), xtrain_tfidf, train_y, xvalid_tfidf)
    print "RF, WordLevel TF-IDF: ", accuracy
    
    RF, Count Vectors:  0.702
    RF, WordLevel TF-IDF:  0.6972
    

    3.5 Boosting Model

    实现一个Xgboost模型:Boosting model是另外一种基于树的集成模型。Boosting是一种机器学习集成元算法,主要用于减少模型的偏差,它是一组机器学习算法,可以把弱学习器提升为强学习器。其中弱学习器指的是与真实类别只有轻微相关的分类器(比随机猜测要好一点)。如果想了解更多,请访问:

    https://www.analyticsvidhya.com/blog/2016/01/xgboost-algorithm-easy-steps/
    
    #特征为计数向量的Xgboost
    accuracy = train_model(xgboost.XGBClassifier(), xtrain_count.tocsc(), train_y, xvalid_count.tocsc())
    print "Xgb, Count Vectors: ", accuracy
    
    #特征为词语级别TF-IDF向量的Xgboost
    accuracy = train_model(xgboost.XGBClassifier(), xtrain_tfidf.tocsc(), train_y, xvalid_tfidf.tocsc())
    print "Xgb, WordLevel TF-IDF: ", accuracy
    
    #特征为词性级别TF-IDF向量的Xgboost
    accuracy = train_model(xgboost.XGBClassifier(), xtrain_tfidf_ngram_chars.tocsc(), train_y, xvalid_tfidf_ngram_chars.tocsc())
    print "Xgb, CharLevel Vectors: ", accuracy
    
    Xgb, Count Vectors:  0.6268
    Xgb, WordLevel TF-IDF:  0.63
    Xgb, CharLevel Vectors:  0.6592
    

    3.6 浅层神经网络

    神经网络被设计成与生物神经元和神经系统类似的数学模型,这些模型用于发现被标注数据中存在的复杂模式和关系。一个浅层神经网络主要包含三层神经元-输入层、隐藏层、输出层。如果想了解更多关于浅层神经网络,请访问:

    https://www.analyticsvidhya.com/blog/2017/05/neural-network-from-scratch-in-python-and-r/
    
    def create_model_architecture(input_size):
        # create input layer 
        input_layer = layers.Input((input_size, ), sparse=True)
        
        # create hidden layer
        hidden_layer = layers.Dense(100, activation="relu")(input_layer)
        
        # create output layer
        output_layer = layers.Dense(1, activation="sigmoid")(hidden_layer)
    
        classifier = models.Model(inputs = input_layer, outputs = output_layer)
        classifier.compile(optimizer=optimizers.Adam(), loss='binary_crossentropy')
        return classifier 
    
    classifier = create_model_architecture(xtrain_tfidf_ngram.shape[1])
    accuracy = train_model(classifier, xtrain_tfidf_ngram, train_y, xvalid_tfidf_ngram, is_neural_net=True)
    print "NN, Ngram Level TF IDF Vectors",  accuracy
    
    Epoch 1/1
    7500/7500 [==============================] - 8s - loss: 0.6913     
    NN, Ngram Level TF IDF Vectors 0.496
    

    3.7 深层神经网络

    深层神经网络是更复杂的神经网络,其中隐藏层执行比简单Sigmoid或Relu激活函数更复杂的操作。不同类型的深层学习模型都可以应用于文本分类问题。

    %E5%9B%BE%E7%89%87.png

    卷积神经网络

    卷积神经网络中,输入层上的卷积用来计算输出。本地连接结果中,每一个输入单元都会连接到输出神经元上。每一层网络都应用不同的滤波器(filter)并组合它们的结果。

    %E5%9B%BE%E7%89%87.png

    如果想了解更多关于卷积神经网络,请访问:

    https://www.analyticsvidhya.com/blog/2017/06/architecture-of-convolutional-neural-networks-simplified-demystified/
    
    def create_cnn():
        # Add an Input Layer
        input_layer = layers.Input((70, ))
    
        # Add the word embedding Layer
        embedding_layer = layers.Embedding(len(word_index) + 1, 300, weights=[embedding_matrix], trainable=False)(input_layer)
        embedding_layer = layers.SpatialDropout1D(0.3)(embedding_layer)
    
        # Add the convolutional Layer
        conv_layer = layers.Convolution1D(100, 3, activation="relu")(embedding_layer)
    
        # Add the pooling Layer
        pooling_layer = layers.GlobalMaxPool1D()(conv_layer)
    
        # Add the output Layers
        output_layer1 = layers.Dense(50, activation="relu")(pooling_layer)
        output_layer1 = layers.Dropout(0.25)(output_layer1)
        output_layer2 = layers.Dense(1, activation="sigmoid")(output_layer1)
    
        # Compile the model
        model = models.Model(inputs=input_layer, outputs=output_layer2)
        model.compile(optimizer=optimizers.Adam(), loss='binary_crossentropy')
        
        return model
    
    classifier = create_cnn()
    accuracy = train_model(classifier, train_seq_x, train_y, valid_seq_x, is_neural_net=True)
    print "CNN, Word Embeddings",  accuracy
    
    Epoch 1/1
    7500/7500 [==============================] - 22s - loss: 0.6930    
    CNN, Word Embeddings 0.496
    
    
    循环神经网络-LSTM
    

    与前馈神经网络不同,前馈神经网络的激活输出仅在一个方向上传播,而循环神经网络的激活输出在两个方向传播(从输入到输出,从输出到输入)。因此在神经网络架构中产生循环,充当神经元的“记忆状态”,这种状态使神经元能够记住迄今为止学到的东西。RNN中的记忆状态优于传统的神经网络,但是被称为梯度弥散的问题也因这种架构而产生。这个问题导致当网络有很多层的时候,很难学习和调整前面网络层的参数。为了解决这个问题,开发了称为LSTM(Long Short Term Memory)模型的新型RNN:
    %E5%9B%BE%E7%89%87.png
    如果想了解更多关于LSTM,请访问:

    https://www.analyticsvidhya.com/blog/2017/12/fundamentals-of-deep-learning-introduction-to-lstm/
    
    
    def create_rnn_lstm():
    
        # Add an Input Layer
        input_layer = layers.Input((70, ))
    
        # Add the word embedding Layer
        embedding_layer = layers.Embedding(len(word_index) + 1, 300, weights=[embedding_matrix], trainable=False)(input_layer)
        embedding_layer = layers.SpatialDropout1D(0.3)(embedding_layer)
    
        # Add the LSTM Layer
        lstm_layer = layers.LSTM(100)(embedding_layer)
    
        # Add the output Layers
        output_layer1 = layers.Dense(50, activation="relu")(lstm_layer)
        output_layer1 = layers.Dropout(0.25)(output_layer1)
        output_layer2 = layers.Dense(1, activation="sigmoid")(output_layer1)
    
        # Compile the model
        model = models.Model(inputs=input_layer, outputs=output_layer2)
        model.compile(optimizer=optimizers.Adam(), loss='binary_crossentropy')
        
        return model
    
    classifier = create_rnn_lstm()
    accuracy = train_model(classifier, train_seq_x, train_y, valid_seq_x, is_neural_net=True)
    print "RNN-LSTM, Word Embeddings",  accuracy
    
    
    
    Epoch 1/1
    7500/7500 [==============================] - 56s - loss: 0.6931    
    RNN-LSTM, Word Embeddings 0.496
    
    
    循环神经网络-GRU
    

    门控递归单元是另一种形式的递归神经网络,我们在网络中添加一个GRU层来代替LSTM。

    
    def create_rnn_gru():
    
        # Add an Input Layer
        input_layer = layers.Input((70, ))
    
        # Add the word embedding Layer
        embedding_layer = layers.Embedding(len(word_index) + 1, 300, weights=[embedding_matrix], trainable=False)(input_layer)
        embedding_layer = layers.SpatialDropout1D(0.3)(embedding_layer)
    
        # Add the GRU Layer
        lstm_layer = layers.GRU(100)(embedding_layer)
    
        # Add the output Layers
        output_layer1 = layers.Dense(50, activation="relu")(lstm_layer)
        output_layer1 = layers.Dropout(0.25)(output_layer1)
        output_layer2 = layers.Dense(1, activation="sigmoid")(output_layer1)
    
        # Compile the model
        model = models.Model(inputs=input_layer, outputs=output_layer2)
        model.compile(optimizer=optimizers.Adam(), loss='binary_crossentropy')
        
        return model
    
    classifier = create_rnn_gru()
    accuracy = train_model(classifier, train_seq_x, train_y, valid_seq_x, is_neural_net=True)
    print "RNN-GRU, Word Embeddings",  accuracy
    
    
    
    Epoch 1/1
    7500/7500 [==============================] - 35s - loss: 0.6930    
    RNN-GRU, Word Embeddings 0.496
    
    
    双向RNN
    

    RNN层也可以被封装在双向层中,我们把GRU层封装在双向RNN网络中。

    
    def create_bidirectional_rnn():
    
        # Add an Input Layer
        input_layer = layers.Input((70, ))
    
        # Add the word embedding Layer
        embedding_layer = layers.Embedding(len(word_index) + 1, 300, weights=[embedding_matrix], trainable=False)(input_layer)
        embedding_layer = layers.SpatialDropout1D(0.3)(embedding_layer)
    
        # Add the LSTM Layer
        lstm_layer = layers.Bidirectional(layers.GRU(100))(embedding_layer)
    
        # Add the output Layers
        output_layer1 = layers.Dense(50, activation="relu")(lstm_layer)
        output_layer1 = layers.Dropout(0.25)(output_layer1)
        output_layer2 = layers.Dense(1, activation="sigmoid")(output_layer1)
    
        # Compile the model
        model = models.Model(inputs=input_layer, outputs=output_layer2)
        model.compile(optimizer=optimizers.Adam(), loss='binary_crossentropy')
        
        return model
    
    classifier = create_bidirectional_rnn()
    accuracy = train_model(classifier, train_seq_x, train_y, valid_seq_x, is_neural_net=True)
    print "RNN-Bidirectional, Word Embeddings",  accuracy
    
    
    
    Epoch 1/1
    7500/7500 [==============================] - 55s - loss: 0.6932    
    RNN-Bidirectional, Word Embeddings 0.496
    
    
    循环卷积神经网络
    

    如果基本的架构已经尝试过,则可以尝试这些层的不同变体,如递归卷积神经网络,还有其它变体,比如:

    层次化注意力网络(Sequence to Sequence Models with Attention)
    
    具有注意力机制的seq2seq(Sequence to Sequence Models with Attention)
    
    双向循环卷积神经网络
    
    更多网络层数的CNNs和RNNs
    
    
    def create_rcnn():
    
        # Add an Input Layer
        input_layer = layers.Input((70, ))
    
        # Add the word embedding Layer
        embedding_layer = layers.Embedding(len(word_index) + 1, 300, weights=[embedding_matrix], trainable=False)(input_layer)
        embedding_layer = layers.SpatialDropout1D(0.3)(embedding_layer)
        
        # Add the recurrent layer
        rnn_layer = layers.Bidirectional(layers.GRU(50, return_sequences=True))(embedding_layer)
        
        # Add the convolutional Layer
        conv_layer = layers.Convolution1D(100, 3, activation="relu")(embedding_layer)
    
        # Add the pooling Layer
        pooling_layer = layers.GlobalMaxPool1D()(conv_layer)
    
        # Add the output Layers
        output_layer1 = layers.Dense(50, activation="relu")(pooling_layer)
        output_layer1 = layers.Dropout(0.25)(output_layer1)
        output_layer2 = layers.Dense(1, activation="sigmoid")(output_layer1)
    
        # Compile the model
        model = models.Model(inputs=input_layer, outputs=output_layer2)
        model.compile(optimizer=optimizers.Adam(), loss='binary_crossentropy')
        
        return model
    
    classifier = create_rcnn()
    accuracy = train_model(classifier, train_seq_x, train_y, valid_seq_x, is_neural_net=True)
    print "CNN, Word Embeddings",  accuracy
    
    
    
    Epoch 1/1
    7500/7500 [==============================] - 18s - loss: 0.6930    
    CNN, Word Embeddings 0.496
    

    进一步提高文本分类模型的性能

    虽然上述框架可以应用于多个文本分类问题,但是为了达到更高的准确率,可以在总体框架中进行一些改进。例如,下面是一些改进文本分类模型和该框架性能的技巧:

    1. 清洗文本:文本清洗有助于减少文本数据中出现的噪声,包括停用词、标点符号、后缀变化等。这篇文章有助于理解如何实现文本分类:

      https://www.analyticsvidhya.com/blog/2014/11/text-data-cleaning-steps-python/

    2. 组合文本特征向量的文本/NLP特征:特征工程阶段,我们把生成的文本特征向量组合在一起,可能会提高文本分类器的准确率。

    模型中的超参数调优:参数调优是很重要的一步,很多参数通过合适的调优可以获得最佳拟合模型,例如树的深层、叶子节点数、网络参数等。

    1. 集成模型:堆叠不同的模型并混合它们的输出有助于进一步改进结果。如果想了解更多关于模型集成,请访问:

      https://www.analyticsvidhya.com/blog/2015/08/introduction-ensemble-learning/

    写在最后

    本文讨论了如何准备一个文本数据集,如清洗、创建训练集和验证集。使用不同种类的特征工程,比如计数向量、TF-IDF、词嵌入、主题模型和基本的文本特征。然后训练了多种分类器,有朴素贝叶斯、Logistic回归、SVM、MLP、LSTM和GRU。最后讨论了提高文本分类器性能的多种方法。

    你从这篇文章受益了吗?可以在下面评论中分享你的观点和看法。

    原文链接:https://www.analyticsvidhya.com/blog/2018/04/a-comprehensive-guide-to-understand-and-implement-text-classification-in-python/

    
    
    展开全文
  • 代码中涉及的具体的类或函数在对应的其他分支博客下谅解~ {第一次用markdown写代码块,排版不是很好,会越来越好~} # -*- coding: utf-8 -*- print(&amp;quot;开始..............&amp;quot;) import ...

    数据集: https://pan.baidu.com/s/13IMDPMz0rf8kM1JAea53uQ
    密码: y6m4
    数据集炒鸡炒鸡大TQT~~~
    代码中涉及的具体的类或函数在对应的其他分支博客下谅解~
    {第一次用markdown写代码块,排版不是很好,会越来越好~}

    # -*- coding: utf-8 -*-
    print("开始..............")
    
    import pandas as pd
    from sklearn.linear_model import LogisticRegression
    from sklearn.feature_extraction.text import CountVectorizer
    
    df_train = pd.read_csv('./train_set.csv')
    df_test = pd.read_csv('./test_set.csv')
    df_train.drop(columns=['article','id'],inplace=True)
    #pandas的drop函数:删除表中的某一行或者某一列,当inplace手动设为True时(默认为false),改变原有的df中的数据,原数据直接就被替换。
    
    df_test.drop(columns=['article'],inplace=True)
    
    vectorizer = CountVectorizer(ngram_range=(1,2),min_df=3,max_df=0.9,max_features=100000)
    
    #文本特征提取方法:CountVectorizer,它只考虑每种词汇在该训练文本中出现的频。
    #CountVectorizer算法是将文本向量转换成稀疏表示数值向量(字符频率向量)。
    #该数值向量可以传递给其他算法,譬如LDA 。在fitting过程中,CountVectorizer将会把频率高的单词排在前面。可选参数minDF表示文本中必须出现的次数(具体分析见另一篇博客啦~)
    
    vectorizer.fit(df_train['word_seg'])
    # 先拟合训练集'word_seg'列的数据
    
    x_train = vectorizer.transform(df_train['word_seg'])
    # 再标准化训练集'word_seg'列数据,tranform()的作用是通过找中心和缩放等实现标准化
    
    x_test = vectorizer.transform(df_test['word_seg'])
    # 标准化测试集'word_seg'列数据
    
    y_train = df_train['class']-1
    #将训练集y 标签为'class'列的数据全部减一
    
    lg = LogisticRegression(C=4,dual=True)
    # 使用LogisticRegression每次指定一个正则化系数C。
    
    lg.fit(x_train,y_train)
    #Fit the model according to the given training data
    
    y_test = lg.predict(x_test)
    #根据输入的测试集x输出预测的y值
    
    df_test['class'] = y_test.tolist()
    #将预测结果转化为list赋值给测试集中'class'一列 
    
    df_test['class'] = df_test['class']+1
    #该列每一个值加一
    
    df_result = df_test.loc[:,['id','class']]
    #选取'id','class'两列作为结果集
    
    df_result.to_csv('./result.csv',index=False)
    #保存结果
    print("完成...............")

    ———-我是分隔线
    如果碰到如下报错这里写图片描述
    可尝试这么改,数据集一次读取太大了,限制下一次的读取最大值
    这里写图片描述

    展开全文
  • nlp学习code c代码

    2020-07-15 23:31:56
    语言分析 nlp学习ppt及代码
  • 待补充

    简述

    上一篇简单概述了下Relation Classification via Convolutional Deep Neural Network(2014)的论文内容,这一篇简单地阅读学习下此篇论文的复现代码(来自FrankWork from github)。
    项目结构主要如下:

    • base_model.py: 为模型设置保存、加载路径(ckpt)。
    • cnn_model.py:主要层(nonlinear、CNN)以及整体模型的实现。
    • train.py:参数及超参数设置,训练及测试实现。
    • base.py: 数据预处理及训练集、测试集的加载。

    下面主要关注前三个文件:

    base_model.py

    class BaseModel(object):
    
      @classmethod
      def set_saver(cls, save_dir):
        '''
        Args:
          save_dir: relative path to FLAGS.logdir
        '''
        # shared between train and valid model instance
        # saver
        cls.saver = tf.train.Saver(var_list=None)
        # 保存路径
        cls.save_dir = os.path.join(FLAGS.logdir, save_dir)
        # 保存文件ckpt
        cls.save_path = os.path.join(cls.save_dir, "model.ckpt")
    
      @classmethod
      def restore(cls, session):
        # 加载模型
        ckpt = tf.train.get_checkpoint_state(cls.save_dir)
        cls.saver.restore(session, ckpt.model_checkpoint_path)
    
      @classmethod
      def save(cls, session, global_step):
        # 保存模型
        cls.saver.save(session, cls.save_path, global_step)
    

    这段比较简单,设置下模型训练中基本的保存和加载路径等信息,之后BaseModel类方便CNNModel继承。

    cnn_model.py

    def linear_layer(name, x, in_size, out_size, is_regularize=False):
        # 非线性全连接层
      with tf.variable_scope(name):
          # L2正则化
        loss_l2 = tf.constant(0, dtype=tf.float32)
        w = tf.get_variable('linear_W', [in_size, out_size],
                          initializer=tf.truncated_normal_initializer(stddev=0.1))
        b = tf.get_variable('linear_b', [out_size], 
                          initializer=tf.constant_initializer(0.1))
        o = tf.nn.xw_plus_b(x, w, b) # batch_size, out_size
        if is_regularize:
            # 对W和b均使用正则化
          loss_l2 += tf.nn.l2_loss(w) + tf.nn.l2_loss(b)
        return o, loss_l2
    

    这个函数为非线性全连接层的实现,可以看到,作者简单地对W和b应用了L2正则化。这样使用正则化在较小的模型中没有问题,如果模型复杂的话,不方便这样使用,会让loss部分代码冗长。

    def cnn_forward(name, sent_pos, lexical, num_filters):
        # 文本CNN
      with tf.variable_scope(name):
        # [batch, seq_length, emb_size+2*pos_emb, 1]
        input = tf.expand_dims(sent_pos, axis=-1)
        input_dim = input.shape.as_list()[2]
    
        # convolutional layer
        pool_outputs = []
        # 3种size的卷积核
        for filter_size in [3,4,5]:
          with tf.variable_scope('conv-%s' % filter_size):
            # [ filter_size, emb_size, in_channel, num_filters ]
            conv_weight = tf.get_variable('W1', 
                                [filter_size, input_dim, 1, num_filters],
                                initializer=tf.truncated_normal_initializer(stddev=0.1))
            # [num_filters]
            conv_bias = tf.get_variable('b1', [num_filters], 
                                  initializer=tf.constant_initializer(0.1))
            # SAME考虑边界,用 0 填充
            conv = tf.nn.conv2d(input,
                                conv_weight,
                                strides=[1, 1, input_dim, 1],
                                padding='SAME')
            # [batch_size, len, 1, num_filters]
            conv = tf.nn.relu(conv + conv_bias)
            max_len = FLAGS.max_len
            # [batch_size, 1, 1, num_filters],去除与长度相关的这一维
            pool = tf.nn.max_pool(conv, 
                                  ksize= [1, max_len, 1, 1],# 池化窗口大小
                                  strides=[1, max_len, 1, 1],  #每一维度滑动步长
                                  padding='SAME') # batch_size, 1, 1, num_filters
            pool_outputs.append(pool)
        # [batch, 3*num_filters]
        pools = tf.reshape(tf.concat(pool_outputs, 3), [-1, 3*num_filters])
    
        # feature 
        feature = pools
        if lexical is not None:
          # [batch, 6*emb_size + 3*num_filters]
          feature = tf.concat([lexical, feature], axis=1)
        return feature
    

    这段是此模型中sentence level的部分的关键一层,代码作者用了3、4、5三个filter_size的各filter_num个卷积核来做普通的文本卷积,然后接了个max池化层,最后和lexical level的词向量(多个词向量concat后)进行concat。需要注意的是,这里的max polling对应的维度是seq_length这一维,论文中这样实现是为了尽量减小文本长度不一的影响。最后输出的tensor的形状是 [batch, 6emb_size + 3num_filters]。

    class CNNModel(BaseModel):
      '''
      Relation Classification via Convolutional Deep Neural Network
      http://www.aclweb.org/anthology/C14-1220
      '''
    
      def __init__(self, word_embed, data, word_dim, 
                  pos_num, pos_dim, num_relations,
                  keep_prob, num_filters,
                  lrn_rate, is_train):
        # input data
        lexical, rid, sentence, pos1, pos2 = data
    
        # embedding initialization
        w_trainable = True if FLAGS.word_dim==50 else False
        # emb_table词向量表
        word_embed = tf.get_variable('word_embed', 
                          initializer=word_embed,
                          dtype=tf.float32,
                          trainable=w_trainable)
        # [pos_num, pos_emb]
        pos1_embed = tf.get_variable('pos1_embed', shape=[pos_num, pos_dim])
        pos2_embed = tf.get_variable('pos2_embed', shape=[pos_num, pos_dim])
    
    
        # # embedding lookup
        # 词级别,[batch, 6] -> [batch, 6, emb_size]
        lexical = tf.nn.embedding_lookup(word_embed, lexical) # batch_size, 6, word_dim
        lexical = tf.reshape(lexical, [-1, 6*word_dim])     # [batch, 6*emb_size]
        self.labels = tf.one_hot(rid, num_relations)       # batch_size, num_relations
    
        # [batch, seq_length] ->[batch, seq_length, emb_size]
        sentence = tf.nn.embedding_lookup(word_embed, sentence)   # batch_size, max_len, word_dim
        pos1 = tf.nn.embedding_lookup(pos1_embed, pos1)       # batch_size, max_len, pos_dim
        pos2 = tf.nn.embedding_lookup(pos2_embed, pos2)       # batch_size, max_len, pos_dim
    
        # cnn model
        sent_pos = tf.concat([sentence, pos1, pos2], axis=2) # [batch, seq_length, emb_size+2*pos_emb]
        if is_train:
          # 句级别
          sent_pos = tf.nn.dropout(sent_pos, keep_prob)
    
        # 词级别+句级别, [batch, 6*emb_size+3*num_filters]
        feature = cnn_forward('cnn', sent_pos, lexical, num_filters)
        feature_size = feature.shape.as_list()[1]
        self.feature = feature
        
        if is_train:
          feature = tf.nn.dropout(feature, keep_prob)
    
        # Map the features to n classes
        # 非线性层
        logits, loss_l2 = linear_layer('linear_cnn', feature, 
                                      feature_size, num_relations, 
                                      is_regularize=True)
    
        prediction = tf.nn.softmax(logits) # 0<prebs<1
        prediction = tf.argmax(prediction, axis=1)
        accuracy = tf.equal(prediction, tf.argmax(self.labels, axis=1))
        accuracy = tf.reduce_mean(tf.cast(accuracy, tf.float32))
        # 平均交叉熵
        loss_ce = tf.reduce_mean(
            tf.nn.softmax_cross_entropy_with_logits(labels=self.labels, logits=logits))
    
        self.logits = logits
        self.prediction = prediction
        self.accuracy = accuracy
        # 正则化(只包含全连接层的w和b)
        self.loss = loss_ce + 0.01*loss_l2
    
        if not is_train:
          return 
    
        # global_step = tf.train.get_or_create_global_step()
        global_step = tf.Variable(0, trainable=False, name='step', dtype=tf.int32)
        optimizer = tf.train.AdamOptimizer(lrn_rate)
    
        # for Batch norm
        # 为了更新 moving_mean和moving_variance
        # tf.GraphKeys.UPDATE_OPS,
        # 这是一个tensorflow的计算图中内置的一个集合,
        # 其中会保存一些需要在训练操作之前完成的操作,
        # 并配合tf.control_dependencies函数使用。
        # 关于在batch_norm中,即为更新mean和variance的操作
        update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
        # tf.control_dependencies,该函数保证其辖域中的操作必须要在该函数所传递的参数中的操作完成后再进行
        with tf.control_dependencies(update_ops):
          self.train_op = optimizer.minimize(self.loss, global_step)
        self.global_step = global_step
    

    这一部分就是把之前写好的nonlinear层和CNN层按照论文思路组装好,CNNModel类继承了之前提到的BaseModel类(保存加载等信息),需要注意的是作者最后这里提到了使用Batch Norm,上面的注释写的很清楚了,注意想要正确使用BN的话,要利用好tf.get_collection(tf.GraphKeys.UPDATE_OPS)和tf.control_dependencies这两个API。这里的loss和L2正则化这样做加法没有问题,但当网络复杂了后会不怎么方便,推荐下述使用方法使用正则化。

    def build_train_valid_model(word_embed, train_data, test_data):
      '''Relation Classification via Convolutional Deep Neural Network'''
      # 实际调用CNN_model
      with tf.name_scope("Train"):
        with tf.variable_scope('CNNModel', reuse=None):
          m_train = CNNModel( word_embed, train_data, FLAGS.word_dim,
                        FLAGS.pos_num, FLAGS.pos_dim, FLAGS.num_relations,
                        FLAGS.keep_prob, FLAGS.num_filters, 
                        FLAGS.lrn_rate, is_train=True)
      with tf.name_scope('Valid'):
        with tf.variable_scope('CNNModel', reuse=True):
          m_valid = CNNModel( word_embed, test_data, FLAGS.word_dim,
                        FLAGS.pos_num, FLAGS.pos_dim, FLAGS.num_relations,
                        1.0, FLAGS.num_filters, 
                        FLAGS.lrn_rate, is_train=False)
      return m_train, m_valid
    

    这段函数没什么好说的,返回两个CNNModel的实例(训练用和验证用)。

    正则化

    当网络复杂的时候定义网络的结构部分和计算损失函数的部分可能不在一个函数中,这样通过上面那种简单的变量这种计算损失函数就不方便了。此时可以使用Tensorflow中提供的集合,它可以在一个计算图(tf.Graph)中保存一组实体(比如张量)。

    def get_weight(shape, lambda1):
     	# 生成一个变量
        var = tf.Variable(tf.random_normal(shape), dtype=tf.float32)
        # add_to_collection()函数将新生成变量的L2正则化损失加入集合losses
        # lambda1为正则化乘上的系数
        tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(lambda1)(var)) 
        return var # 返回生成的变量
    	
    .......
    weight = get_weight([in_dimension, out_dimension], 0.003)
    .......
    
    # 在定义神经网络前向传播的同时已经将所有的L2正则化损失加入了图上的集合,这里是损失函数的定义。 
    mean_loss = tf.reduce_mean(loss)
    # 将均方误差损失函数加入损失集合
    tf.add_to_collection('losses', mean_loss) 
    # get_collection()返回一个列表,这个列表是所有这个集合中的元素,
    # 在本样例中这些元素就是损失函数的不同部分,将他们加起来就是最终的损失函数 
    loss = tf.add_n(tf.get_collection('losses'))
    
    .......
    
    # 用优化器最小化加了L2正则的loss即可
    train_op = tf.train.AdamOptimizer(0.001).minimize(loss)
    

    train.py

    flags = tf.app.flags
    
    flags.DEFINE_string("train_file", "data/train.cln", 
                                 "original training file")
    flags.DEFINE_string("test_file", "data/test.cln", 
                                 "original test file")
    
    flags.DEFINE_string("vocab_file", "data/vocab.txt", 
                                  "vocab of train and test data")
    
    flags.DEFINE_string("google_embed300_file", 
                                 "data/embed300.google.npy", 
                                 "google news word embeddding")
    flags.DEFINE_string("google_words_file", 
                                 "data/google_words.lst", 
                                 "google words list")
    flags.DEFINE_string("trimmed_embed300_file", 
                                 "data/embed300.trim.npy", 
                                 "trimmed google embedding")
    
    flags.DEFINE_string("senna_embed50_file", 
                                 "data/embed50.senna.npy", 
                                 "senna words embeddding")
    flags.DEFINE_string("senna_words_file", 
                                 "data/senna_words.lst", 
                                 "senna words list")
    flags.DEFINE_string("trimmed_embed50_file", 
                                 "data/embed50.trim.npy", 
                                 "trimmed senna embedding")
    
    flags.DEFINE_string("train_record", "data/train.tfrecord", 
                                 "training file of TFRecord format")
    flags.DEFINE_string("test_record", "data/test.tfrecord", 
                                 "Test file of TFRecord format")
    
    
    flags.DEFINE_string("relations_file", "data/relations.txt", "relations file")
    flags.DEFINE_string("results_file", "data/results.txt", "predicted results file")
    flags.DEFINE_string("logdir", "saved_models/", "where to save the model")
    
    flags.DEFINE_integer("max_len", 96, "max length of sentences")
    flags.DEFINE_integer("num_relations", 19, "number of relations")
    flags.DEFINE_integer("word_dim", 50, "word embedding size")
    flags.DEFINE_integer("num_epochs", 200, "number of epochs")
    flags.DEFINE_integer("batch_size", 100, "batch size")
    
    flags.DEFINE_integer("pos_num", 123, "number of position feature")
    flags.DEFINE_integer("pos_dim", 5, "position embedding size")
    flags.DEFINE_integer("num_filters", 100, "cnn number of output unit")
    
    flags.DEFINE_float("lrn_rate", 1e-3, "learning rate")
    flags.DEFINE_float("keep_prob", 0.5, "dropout keep probability")
    
    flags.DEFINE_boolean('test', False, 'set True to test')
    flags.DEFINE_boolean('trace', False, 'set True to test')
    
    FLAGS = tf.app.flags.FLAGS
    
    
    def trace_runtime(sess, m_train):
      '''
      trace runtime bottleneck using timeline api
      navigate to the URL 'chrome://tracing' in a Chrome web browser, 
      click the 'Load' button and locate the timeline file.
      '''
      # 运行时记录运行信息的protocolmessage
      run_metadata=tf.RunMetadata()
      options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
      from tensorflow.python.client import timeline
      trace_file = open('timeline.ctf.json', 'w')
    
      fetches = [m_train.train_op, m_train.loss, m_train.accuracy]
      _, loss, acc = sess.run(fetches, 
                                options=options, 
                                run_metadata=run_metadata)
                                
      trace = timeline.Timeline(step_stats=run_metadata.step_stats)
      trace_file.write(trace.generate_chrome_trace_format())
      trace_file.close()
    
    
    def train(sess, m_train, m_valid):
      n = 1
      best = .0
      best_step = n
      start_time = time.time()
      orig_begin_time = start_time
    
      fetches = [m_train.train_op, m_train.loss, m_train.accuracy]
    
      while True:
        try:
          _, loss, acc = sess.run(fetches)
    
          epoch = n // 80
          if n % 80 == 0:
            now = time.time()
            duration = now - start_time
            start_time = now
            v_acc = sess.run(m_valid.accuracy)
            if best < v_acc:
              best = v_acc
              best_step = n
              m_train.save(sess, best_step)
            print("Epoch %d, loss %.2f, acc %.2f %.4f, time %.2f" % 
                                      (epoch, loss, acc, v_acc, duration))
            sys.stdout.flush()
          n += 1
        except tf.errors.OutOfRangeError:
          break
    
      duration = time.time() - orig_begin_time
      duration /= 3600
      print('Done training, best_step: %d, best_acc: %.4f' % (best_step, best))
      print('duration: %.2f hours' % duration)
      sys.stdout.flush()
    
    def test(sess, m_valid):
      m_valid.restore(sess)
      fetches = [m_valid.accuracy, m_valid.prediction]
      accuracy, predictions = sess.run(fetches)
      print('accuracy: %.4f' % accuracy)
      
      base_reader.write_results(predictions, FLAGS.relations_file, FLAGS.results_file)
    

    这段代码主要用flag设置了本模型的一些参数和超参等信息,并且设置了三个函数来调用之前写好的训练和验证用的模型类实例。

    def main(_):
      with tf.Graph().as_default():
        train_data, test_data, word_embed = base_reader.inputs()
        
        
        m_train, m_valid = cnn_model.build_train_valid_model(word_embed, 
                                                          train_data, test_data)
        
        m_train.set_saver('cnn-%d-%d' % (FLAGS.num_epochs, FLAGS.word_dim))
        
        init_op = tf.group(tf.global_variables_initializer(),
                            tf.local_variables_initializer())# for file queue
    
        # GPU config
        config = tf.ConfigProto()
        # config.gpu_options.per_process_gpu_memory_fraction = 0.9 # 占用GPU90%的显存 
        config.gpu_options.allow_growth = True
        
        # sv finalize the graph
        with tf.Session(config=config) as sess:
          sess.run(init_op)
          print('='*80)
    
          if FLAGS.trace:
            trace_runtime(sess, m_train)
          elif FLAGS.test:
            test(sess, m_valid)
          else:
            train(sess, m_train, m_valid)
    
    
    
    if __name__ == '__main__':
      # 如果你的代码中的入口函数不叫main(),而是一个其他名字的函数,
      # 如test(),则你应该这样写入口tf.app.run(test)
      # 通过处理flag解析,然后执行main函数
      tf.app.run()
    

    这里主要用了tf.app.run()这个API来训练。

    dataset的使用(待补充)

    展开全文
  • 推荐github上的一个NLP代码教程:nlp-tutorial,教程中包含常见的NLP模型代码实现(基于TensorFlow和Pytorch),而且教程中的大多数NLP...
  • 自然语言处理NLP)- 建立一个搜索引擎(信息检索系统)的点点滴滴 教程在最底下 代码: 建索引:   搜索:                       bensonrachel简书教程...
  • NLP入门实例推荐(Tensorflow实现)

    万次阅读 多人点赞 2017-11-05 16:21:46
    自然语言处理(NLP)是机器学习的应用之一,用于分析、理解和生成自然语言,以便人类与计算机,人类与人类更好的交流。自然语言处理按照任务类型可以分为分类、匹配、翻译、结构化预测、与序贯决策过程。自然语言处理...
  • 自然语言处理NLP)是数据科学中最有趣的子领域之一,越来越多的数据科学家希望能够开发出涉及非结构化文本数据的解决方案。尽管如此,许多应用数据科学家(均具有STEM和社会科学背景)依然缺乏NLP自然语言处理)...
  • 60分钟带你掌握NLP BERT理论与实战

    千人学习 2019-03-22 17:12:18
    本课程会介绍最近NLP领域取得突破性进展的BERT模型。首先会介绍一些背景知识,包括Word Embedding、RNN/LSTM/GRU、Seq2Seq模型和Attention机制等。然后介绍BERT的基础Transformer模型,这个模型最初用于机器翻译,...
  • NLP汉语自然语言处理原理与实践》郑捷代码,找了一会,方便大家: http://www.threedweb.cn/data/attachment/bigupload/NLPBook.zip 另,推荐宗成庆老师的《统计自然语言处理》,写的很好,引用文献很多,作者...
  • Python自然语言处理-BERT模型实战

    千人学习 2020-06-24 14:19:22
    Python自然语言处理-BERT模型实战课程旨在帮助同学们快速掌握当下NLP领域最核心的算法模型BERT的原理构造与应用实例。通俗讲解BERT模型中所涉及的核心知识点(Transformer,self-attention等),基于google开源BERT...
  • 之前看的论文都是基于CNN在NLP上的应用,但其实深度学习与NLP结合的领域中应用最广的应该是RNN,因为文本可以直观地被表示为输入序列,方便的被RNN处理,捕获其Long-Term依赖等信息,而且实际应用中也取得了很好的...
  • 1、自然语言处理圣经---《自然语言处理综论》2、视频课程《深度学习与自然语言处理-2018》3、Natural Language Processing (NLP)4、吴恩达经典课程 - Machine Learning —Coursera5、斯坦福 Natural Language ...
  • 60分钟带你学习PyTorch框架。

    千人学习 2020-03-11 14:39:34
    随着对于深度学习研究的逐渐深入,在自然语言处理领域,出现了很多深度学习的模型,这些模型相比于传统的机器学习方法,在准确率等指标上面有了很大的提高。本课程拟就深度学习在自然语言处理领域的应用,从基础开始...
  • NER
  • TensorFlow实战BERT

    千人学习 2020-07-28 17:12:44
    主要讲解当下非常火,应用于NLP领域的语言模型技术BERT,课程由免费内容和收费内容两部分组成,免费内容主要是讲解TransFormer技术,并且通过机器翻译案例,代码层面实现TransFormer Encoder Dncoder的所有技术...
  • 有个作业让用自然语言处理来做错别字检查,我只想到N-gram和HMM技术, 也不知道可行或者方法过时没,请大家给个思路或文章或参考。 具体就是上传一篇word文档检查出里面可能写错的字,如"果树"错写成"果数", 把...
  • 人工智能-知识图谱实战案例视频

    千人学习 2019-03-04 09:45:02
    知识图谱是AI 的一个主要方面。知识图谱实战案例完全剖析视频教程,该课程定位:系统学习知识图谱的最佳实践;系统学习:完全覆盖知识建模、图数据库、知识应用和知识获取;实战指引:一套完整的知识建模方法论;...
  • 1.CRF条件随机场 著名开源项目CRF++的NodeJS封装
1 2 3 4 5 ... 20
收藏数 213,604
精华内容 85,441
热门标签
关键字:

nlp代码