<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 如何開發一種預測電影評論情感的詞嵌入模型 > 原文: [https://machinelearningmastery.com/develop-word-embedding-model-predicting-movie-review-sentiment/](https://machinelearningmastery.com/develop-word-embedding-model-predicting-movie-review-sentiment/) #### 開發一個深度學習模型,使用 Keras 自動將電影評論 分類為 Python 中的正面或負面,一步一步。 單詞嵌入是用于表示文本的技術,其中具有相似含義的不同單詞具有類似的實值向量表示。 它們是一項重大突破,它使神經網絡模型在一系列具有挑戰性的自然語言處理問題上表現出色。 在本教程中,您將了解如何為神經網絡開發單詞嵌入模型以對電影評論進行分類。 完成本教程后,您將了解: * 如何使用深度學習方法準備電影評論文本數據進行分類。 * 如何學習嵌入詞作為擬合深度學習模型的一部分。 * 如何學習獨立的單詞嵌入以及如何在神經網絡模型中使用預先訓練的嵌入。 讓我們開始吧。 **注**:摘錄自:“[深度學習自然語言處理](https://machinelearningmastery.com/deep-learning-for-nlp/)”。 看一下,如果你想要更多的分步教程,在使用文本數據時充分利用深度學習方法。 ![How to Develop a Word Embedding Model for Predicting Movie Review Sentiment](img/eb22780eed5923389f03e367a305ea48.jpg) 如何開發用于預測電影評論情感的詞嵌入模型 照片由 [Katrina Br *?#*!@ nd](https://www.flickr.com/photos/fuzzyblue/6351564408/) ,保留一些權利。 ## 教程概述 本教程分為 5 個部分;他們是: 1. 電影評論數據集 2. 數據準備 3. 訓練嵌入層 4. 訓練 word2vec 嵌入 5. 使用預先訓練的嵌入 ### Python 環境 本教程假設您安裝了 Python SciPy 環境,理想情況下使用 Python 3。 您必須安裝帶有 TensorFlow 或 Theano 后端的 Keras(2.2 或更高版本)。 本教程還假設您安裝了 scikit-learn,Pandas,NumPy 和 Matplotlib。 如果您需要有關環境的幫助,請參閱本教程: * [如何使用 Anaconda 設置用于機器學習和深度學習的 Python 環境](https://machinelearningmastery.com/setup-python-environment-machine-learning-deep-learning-anaconda/) 本教程不需要 GPU,但您可以在 Amazon Web Services 上以低成本方式訪問 GPU。在本教程中學習如何: * [如何設置 Amazon AWS EC2 GPU 以訓練 Keras 深度學習模型(循序漸進)](https://machinelearningmastery.com/develop-evaluate-large-deep-learning-models-keras-amazon-web-services/) 讓我們潛入。 ## 1.電影評論數據集 電影評論數據是 Bo Pang 和 Lillian Lee 在 21 世紀初從 imdb.com 網站上檢索到的電影評論的集合。收集的評論作為他們自然語言處理研究的一部分。 評論最初于 2002 年發布,但更新和清理版本于 2004 年發布,稱為“v2.0”。 該數據集包含 1,000 個正面和 1,000 個負面電影評論,這些評論來自 [imdb.com](http://reviews.imdb.com/Reviews) 上托管的 rec.arts.movi??es.reviews 新聞組的存檔。作者將此數據集稱為“極性數據集”。 > 我們的數據包含 2000 年之前寫的 1000 份正面和 1000 份負面評論,每位作者的評論上限為 20(每位作者共 312 位)。我們將此語料庫稱為極性數據集。 - [感傷教育:基于最小削減的主觀性總結的情感分析](http://xxx.lanl.gov/abs/cs/0409058),2004。 數據已經有所清理,例如: * 數據集僅包含英語評論。 * 所有文本都已轉換為小寫。 * 標點符號周圍有空格,如句號,逗號和括號。 * 文本每行被分成一個句子。 該數據已用于一些相關的自然語言處理任務。對于分類,機器學習模型(例如支持向量機)對數據的表現在高 70%到低 80%(例如 78%-82%)的范圍內。 更復雜的數據準備可以看到高達 86%的結果,交叉驗證 10 倍。如果我們想在現代方法的實驗中使用這個數據集,這給了我們 80 年代中期的球場。 > ...根據下游極性分類器的選擇,我們可以實現高度統計上的顯著改善(從 82.8%到 86.4%) - [感傷教育:基于最小削減的主觀性總結的情感分析](http://xxx.lanl.gov/abs/cs/0409058),2004。 您可以從此處下載數據集: * [電影評論 Polarity Dataset](http://www.cs.cornell.edu/people/pabo/movie-review-data/review_polarity.tar.gz) (review_polarity.tar.gz,3MB) 解壓縮文件后,您將有一個名為“ _txt_sentoken_ ”的目錄,其中包含兩個子目錄,其中包含文本“ _neg_ ”和“ _pos_ ”的負數和積極的評論。對于每個 neg 和 pos,每個文件存儲一個評論,命名約定為 cv000 到 cv999。 接下來,我們來看看加載和準備文本數據。 ## 2.數據準備 在本節中,我們將看看 3 件事: 1. 將數據分成訓練和測試集。 2. 加載和清理數據以刪除標點符號和數字。 3. 定義首選詞匯的詞匯。 ### 分為訓練和測試裝置 我們假裝我們正在開發一種系統,可以預測文本電影評論的情感是積極的還是消極的。 這意味著在開發模型之后,我們需要對新的文本評論進行預測。這將要求對這些新評論執行所有相同的數據準備,就像對模型的訓練數據執行一樣。 我們將通過在任何數據準備之前拆分訓練和測試數據集來確保將此約束納入我們模型的評估中。這意味著在準備用于訓練模型的數據時,測試集中的數據中的任何知識可以幫助我們更好地準備數據(例如,所使用的單詞)。 話雖如此,我們將使用最近 100 次正面評論和最后 100 次負面評論作為測試集(100 條評論),其余 1,800 條評論作為訓練數據集。 這是 90%的訓練,10%的數據分割。 通過使用評論的文件名可以輕松實現拆分,其中評論為 000 至 899 的評論用于訓練數據,而評論為 900 以上的評論用于測試。 ### 裝載和清潔評論 文本數據已經非常干凈;沒有太多準備工作。 如果您不熟悉清理文本數據,請參閱此帖子: * [如何使用 Python 清理機器學習文本](https://machinelearningmastery.com/clean-text-machine-learning-python/) 如果沒有太多陷入細節,我們將使用以下方式準備數據: * 在白色空間的分裂標記。 * 從單詞中刪除所有標點符號。 * 刪除所有不完全由字母字符組成的單詞。 * 刪除所有已知停用詞的單詞。 * 刪除長度為&lt; = 1 個字符的所有單詞。 我們可以將所有這些步驟放入一個名為 _clean_doc()_ 的函數中,該函數將從文件加載的原始文本作為參數,并返回已清理的標記列表。我們還可以定義一個函數 _load_doc()_,它從文件中加載文件,以便與 _clean_doc()_ 函數一起使用。 下面列出了清理第一次正面評價的示例。 ```py from nltk.corpus import stopwords import string # load doc into memory def load_doc(filename): # open the file as read only file = open(filename, 'r') # read all text text = file.read() # close the file file.close() return text # turn a doc into clean tokens def clean_doc(doc): # split into tokens by white space tokens = doc.split() # remove punctuation from each token table = str.maketrans('', '', string.punctuation) tokens = [w.translate(table) for w in tokens] # remove remaining tokens that are not alphabetic tokens = [word for word in tokens if word.isalpha()] # filter out stop words stop_words = set(stopwords.words('english')) tokens = [w for w in tokens if not w in stop_words] # filter out short tokens tokens = [word for word in tokens if len(word) > 1] return tokens # load the document filename = 'txt_sentoken/pos/cv000_29590.txt' text = load_doc(filename) tokens = clean_doc(text) print(tokens) ``` 運行該示例會打印一長串清潔令牌。 我們可能想要探索更多清潔步驟,并將其留作進一步練習。 我很想知道你能想出什么。 最后在評論中發布您的方法和結果。 ```py ... 'creepy', 'place', 'even', 'acting', 'hell', 'solid', 'dreamy', 'depp', 'turning', 'typically', 'strong', 'performance', 'deftly', 'handling', 'british', 'accent', 'ians', 'holm', 'joe', 'goulds', 'secret', 'richardson', 'dalmatians', 'log', 'great', 'supporting', 'roles', 'big', 'surprise', 'graham', 'cringed', 'first', 'time', 'opened', 'mouth', 'imagining', 'attempt', 'irish', 'accent', 'actually', 'wasnt', 'half', 'bad', 'film', 'however', 'good', 'strong', 'violencegore', 'sexuality', 'language', 'drug', 'content'] ``` ### 定義詞匯表 在使用詞袋或嵌入模型時,定義已知單詞的詞匯表很重要。 單詞越多,文檔的表示越大,因此將單詞限制為僅被認為具有預測性的單詞是很重要的。這很難事先知道,并且通常重要的是測試關于如何構建有用詞匯的不同假設。 我們已經看到了如何從上一節中的詞匯表中刪除標點符號和數字。我們可以對所有文檔重復此操作,并構建一組所有已知單詞。 我們可以開發一個詞匯表作為計數器,這是一個單詞及其計數的字典映射,允許我們輕松更新和查詢。 每個文檔都可以添加到計數器(一個名為 _add_doc_to_vocab()_ 的新函數),我們可以跳過負目錄中的所有評論,然后是肯定目錄(一個名為 _process_docs 的新函數) ()_)。 下面列出了完整的示例。 ```py from string import punctuation from os import listdir from collections import Counter from nltk.corpus import stopwords # load doc into memory def load_doc(filename): # open the file as read only file = open(filename, 'r') # read all text text = file.read() # close the file file.close() return text # turn a doc into clean tokens def clean_doc(doc): # split into tokens by white space tokens = doc.split() # remove punctuation from each token table = str.maketrans('', '', punctuation) tokens = [w.translate(table) for w in tokens] # remove remaining tokens that are not alphabetic tokens = [word for word in tokens if word.isalpha()] # filter out stop words stop_words = set(stopwords.words('english')) tokens = [w for w in tokens if not w in stop_words] # filter out short tokens tokens = [word for word in tokens if len(word) > 1] return tokens # load doc and add to vocab def add_doc_to_vocab(filename, vocab): # load doc doc = load_doc(filename) # clean doc tokens = clean_doc(doc) # update counts vocab.update(tokens) # load all docs in a directory def process_docs(directory, vocab, is_trian): # walk through all files in the folder for filename in listdir(directory): # skip any reviews in the test set if is_trian and filename.startswith('cv9'): continue if not is_trian and not filename.startswith('cv9'): continue # create the full path of the file to open path = directory + '/' + filename # add doc to vocab add_doc_to_vocab(path, vocab) # define vocab vocab = Counter() # add all docs to vocab process_docs('txt_sentoken/neg', vocab, True) process_docs('txt_sentoken/pos', vocab, True) # print the size of the vocab print(len(vocab)) # print the top words in the vocab print(vocab.most_common(50)) ``` 運行該示例表明我們的詞匯量為 43,476 個單詞。 我們還可以看到電影評論中前 50 個最常用單詞的樣本。 請注意,此詞匯表僅基于訓練數據集中的那些評論構建。 ```py 44276 [('film', 7983), ('one', 4946), ('movie', 4826), ('like', 3201), ('even', 2262), ('good', 2080), ('time', 2041), ('story', 1907), ('films', 1873), ('would', 1844), ('much', 1824), ('also', 1757), ('characters', 1735), ('get', 1724), ('character', 1703), ('two', 1643), ('first', 1588), ('see', 1557), ('way', 1515), ('well', 1511), ('make', 1418), ('really', 1407), ('little', 1351), ('life', 1334), ('plot', 1288), ('people', 1269), ('could', 1248), ('bad', 1248), ('scene', 1241), ('movies', 1238), ('never', 1201), ('best', 1179), ('new', 1140), ('scenes', 1135), ('man', 1131), ('many', 1130), ('doesnt', 1118), ('know', 1092), ('dont', 1086), ('hes', 1024), ('great', 1014), ('another', 992), ('action', 985), ('love', 977), ('us', 967), ('go', 952), ('director', 948), ('end', 946), ('something', 945), ('still', 936)] ``` 我們可以逐步瀏覽詞匯表并刪除所有發生率較低的單詞,例如僅在所有評論中使用一次或兩次。 例如,以下代碼段將僅檢索在所有評論中出現 2 次或更多次的令牌。 ```py # keep tokens with a min occurrence min_occurane = 2 tokens = [k for k,c in vocab.items() if c >= min_occurane] print(len(tokens)) ``` 使用此添加運行上面的示例表明,詞匯量大小略大于其大小的一半(從 43,476 到 25,767 個單詞)。 ```py 25767 ``` 最后,詞匯表可以保存到一個名為 _vocab.txt_ 的新文件中,以后我們可以加載并使用它來過濾電影評論,然后再編碼進行建模。我們定義了一個名為 _save_list()_ 的新函數,它將詞匯表保存到文件中,每個文件只有一個單詞。 例如: ```py # save list to file def save_list(lines, filename): # convert lines to a single blob of text data = '\n'.join(lines) # open file file = open(filename, 'w') # write text file.write(data) # close file file.close() # save tokens to a vocabulary file save_list(tokens, 'vocab.txt') ``` 在詞匯表上運行最小出現過濾器并將其保存到文件,您現在應該有一個名為 _vocab.txt_ 的新文件,其中只包含我們感興趣的詞。 文件中的單詞順序會有所不同,但應如下所示: ```py aberdeen dupe burt libido hamlet arlene available corners web columbia ... ``` 我們現在準備從評論中查看學習功能。 ## 3.訓練嵌入層 在本節中,我們將在分類問題上訓練神經網絡時學習嵌入一詞。 單詞嵌入是表示文本的一種方式,其中詞匯表中的每個單詞由高維空間中的實值向量表示。以這樣的方式學習向量:具有相似含義的單詞在向量空間中具有相似的表示(在向量空間中接近)。對于文本而言,這是一種更具表現力的表達,而不是像詞袋這樣的經典方法,其中單詞或標記之間的關系被忽略,或者在 bigram 和 trigram 方法中被強制使用。 在訓練神經網絡時可以學習單詞的實值向量表示。我們可以使用[嵌入層](https://keras.io/layers/embeddings/)在 Keras 深度學習庫中完成此操作。 如果您不熟悉單詞嵌入,請參閱帖子: * [什么是詞嵌入文本?](https://machinelearningmastery.com/what-are-word-embeddings/) 如果您不熟悉 Keras 中的字嵌入層,請參閱帖子: * [如何使用 Keras 深入學習使用詞嵌入層](https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/) 第一步是加載詞匯表。我們將用它來過濾我們不感興趣的電影評論中的單詞。 如果你已完成上一節,你應該有一個名為' _vocab.txt_ '的本地文件,每行一個單詞。我們可以加載該文件并構建一個詞匯表作為檢查令牌有效性的集合。 ```py # load doc into memory def load_doc(filename): # open the file as read only file = open(filename, 'r') # read all text text = file.read() # close the file file.close() return text # load the vocabulary vocab_filename = 'vocab.txt' vocab = load_doc(vocab_filename) vocab = vocab.split() vocab = set(vocab) ``` 接下來,我們需要加載所有訓練數據電影評論。為此,我們可以調整上一節中的 _process_docs()_ 來加載文檔,清理它們,并將它們作為字符串列表返回,每個字符串有一個文檔。我們希望每個文檔都是一個字符串,以便以后簡單編碼為整數序列。 清理文檔涉及根據空白區域拆分每個評論,刪除標點符號,然后過濾掉不在詞匯表中的所有標記。 更新的 _clean_doc()_ 功能如下所示。 ```py # turn a doc into clean tokens def clean_doc(doc, vocab): # split into tokens by white space tokens = doc.split() # remove punctuation from each token table = str.maketrans('', '', punctuation) tokens = [w.translate(table) for w in tokens] # filter out tokens not in vocab tokens = [w for w in tokens if w in vocab] tokens = ' '.join(tokens) return tokens ``` 更新的 _process_docs()_ 然后可以為' _pos_ '和' _neg_ '目錄中的每個文檔調用 _clean_doc()_ 在我們的訓練數據集中。 ```py # load all docs in a directory def process_docs(directory, vocab, is_trian): documents = list() # walk through all files in the folder for filename in listdir(directory): # skip any reviews in the test set if is_trian and filename.startswith('cv9'): continue if not is_trian and not filename.startswith('cv9'): continue # create the full path of the file to open path = directory + '/' + filename # load the doc doc = load_doc(path) # clean doc tokens = clean_doc(doc, vocab) # add to list documents.append(tokens) return documents # load all training reviews positive_docs = process_docs('txt_sentoken/pos', vocab, True) negative_docs = process_docs('txt_sentoken/neg', vocab, True) train_docs = negative_docs + positive_docs ``` 下一步是將每個文檔編碼為整數序列。 Keras 嵌入層需要整數輸入,其中每個整數映射到單個標記,該標記在嵌入中具有特定的實值向量表示。這些向量在訓練開始時是隨機的,但在訓練期間對網絡有意義。 我們可以使用 Keras API 中的 [Tokenizer](https://keras.io/preprocessing/text/#tokenizer) 類將訓練文檔編碼為整數序列。 首先,我們必須構造一個類的實例,然后在訓練數據集中的所有文檔上訓練它。在這種情況下,它開發了訓練數據集中所有標記的詞匯表,并開發了從詞匯表中的單詞到唯一整數的一致映射。我們可以使用我們的詞匯表文件輕松地開發此映射。 ```py # create the tokenizer tokenizer = Tokenizer() # fit the tokenizer on the documents tokenizer.fit_on_texts(train_docs) ``` 現在已經準備好了單詞到整數的映射,我們可以使用它來對訓練數據集中的評論進行編碼。我們可以通過調用 Tokenizer 上的 _texts_to_sequences()_ 函數來實現。 ```py # sequence encode encoded_docs = tokenizer.texts_to_sequences(train_docs) ``` 我們還需要確保所有文檔具有相同的長度。 這是 Keras 對高效計算的要求。我們可以將評論截斷為最小尺寸或零填充(具有值'0'的填充)評論到最大長度,或者某些混合。在這種情況下,我們將所有評論填充到訓練數據集中最長評論的長度。 首先,我們可以使用訓練數據集上的 _max()_ 函數找到最長的評論并獲取其長度。然后,我們可以調用 Keras 函數 _pad_sequences()_,通過在末尾添加 0 值將序列填充到最大長度。 ```py # pad sequences max_length = max([len(s.split()) for s in train_docs]) Xtrain = pad_sequences(encoded_docs, maxlen=max_length, padding='post') ``` 最后,我們可以定義訓練數據集的類標簽,以適應監督的神經網絡模型來預測評論的情感。 ```py # define training labels ytrain = array([0 for _ in range(900)] + [1 for _ in range(900)]) ``` 然后我們可以對測試數據集進行編碼和填充,稍后需要在我們訓練之后評估模型。 ```py # load all test reviews positive_docs = process_docs('txt_sentoken/pos', vocab, False) negative_docs = process_docs('txt_sentoken/neg', vocab, False) test_docs = negative_docs + positive_docs # sequence encode encoded_docs = tokenizer.texts_to_sequences(test_docs) # pad sequences Xtest = pad_sequences(encoded_docs, maxlen=max_length, padding='post') # define test labels ytest = array([0 for _ in range(100)] + [1 for _ in range(100)]) ``` 我們現在準備定義我們的神經網絡模型。 該模型將使用嵌入層作為第一個隱藏層。嵌入需要規范詞匯量大小,實值向量空間的大小以及輸入文檔的最大長度。 詞匯量大小是我們詞匯表中的單詞總數,加上一個未知單詞。這可以是用于對文檔進行整數編碼的標記器內的詞匯集長度或詞匯大小,例如: ```py # define vocabulary size (largest integer value) vocab_size = len(tokenizer.word_index) + 1 ``` 我們將使用 100 維向量空間,但您可以嘗試其他值,例如 50 或 150.最后,最大文檔長度在填充期間使用的 _max_length_ 變量中計算。 下面列出了完整的模型定義,包括嵌入層。 我們使用卷積神經網絡(CNN),因為它們已經證明在文檔分類問題上是成功的。保守的 CNN 配置與 32 個濾波器(用于處理字的并行字段)和具有整流線性('relu')激活功能的 8 的內核大小一起使用。接下來是一個池化層,它將卷積層的輸出減少一半。 接下來,將來自模型的 CNN 部分的 2D 輸出展平為一個長 2D 向量,以表示由 CNN 提取的“特征”。模型的后端是標準的多層感知器層,用于解釋 CNN 功能。輸出層使用 sigmoid 激活函數為評論中的消極和積極情感輸出介于 0 和 1 之間的值。 有關文本分類的有效深度學習模型配置的更多建議,請參閱帖子: * [深度學習文檔分類的最佳實踐](https://machinelearningmastery.com/best-practices-document-classification-deep-learning/) ```py # define model model = Sequential() model.add(Embedding(vocab_size, 100, input_length=max_length)) model.add(Conv1D(filters=32, kernel_size=8, activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(10, activation='relu')) model.add(Dense(1, activation='sigmoid')) print(model.summary()) ``` 僅運行此片段可提供已定義網絡的摘要。 我們可以看到嵌入層需要長度為 442 個單詞的文檔作為輸入,并將文檔中的每個單詞編碼為 100 個元素向量。 ```py _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding_1 (Embedding) (None, 442, 100) 2576800 _________________________________________________________________ conv1d_1 (Conv1D) (None, 435, 32) 25632 _________________________________________________________________ max_pooling1d_1 (MaxPooling1 (None, 217, 32) 0 _________________________________________________________________ flatten_1 (Flatten) (None, 6944) 0 _________________________________________________________________ dense_1 (Dense) (None, 10) 69450 _________________________________________________________________ dense_2 (Dense) (None, 1) 11 ================================================================= Total params: 2,671,893 Trainable params: 2,671,893 Non-trainable params: 0 _________________________________________________________________ ``` 接下來,我們使網絡適應訓練數據。 我們使用二元交叉熵損失函數,因為我們正在學習的問題是二元分類問題。使用隨機梯度下降的高效 Adam 實現,除了訓練期間的損失之外,我們還跟蹤準確性。該模型訓練 10 個時期,或 10 次通過訓練數據。 通過一些試驗和錯誤找到了網絡配置和訓練計劃,但對于此問題并不是最佳選擇。如果您可以使用其他配置獲得更好的結果,請告訴我們。 ```py # compile network model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # fit network model.fit(Xtrain, ytrain, epochs=10, verbose=2) ``` 在擬合模型之后,在測試數據集上對其進行評估。此數據集包含我們以前從未見過的單詞和在訓練期間未看到的評論。 ```py # evaluate loss, acc = model.evaluate(Xtest, ytest, verbose=0) print('Test Accuracy: %f' % (acc*100)) ``` 我們可以將所有這些結合在一起。 完整的代碼清單如下。 ```py from string import punctuation from os import listdir from numpy import array from keras.preprocessing.text import Tokenizer from keras.preprocessing.sequence import pad_sequences from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers import Embedding from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # load doc into memory def load_doc(filename): # open the file as read only file = open(filename, 'r') # read all text text = file.read() # close the file file.close() return text # turn a doc into clean tokens def clean_doc(doc, vocab): # split into tokens by white space tokens = doc.split() # remove punctuation from each token table = str.maketrans('', '', punctuation) tokens = [w.translate(table) for w in tokens] # filter out tokens not in vocab tokens = [w for w in tokens if w in vocab] tokens = ' '.join(tokens) return tokens # load all docs in a directory def process_docs(directory, vocab, is_trian): documents = list() # walk through all files in the folder for filename in listdir(directory): # skip any reviews in the test set if is_trian and filename.startswith('cv9'): continue if not is_trian and not filename.startswith('cv9'): continue # create the full path of the file to open path = directory + '/' + filename # load the doc doc = load_doc(path) # clean doc tokens = clean_doc(doc, vocab) # add to list documents.append(tokens) return documents # load the vocabulary vocab_filename = 'vocab.txt' vocab = load_doc(vocab_filename) vocab = vocab.split() vocab = set(vocab) # load all training reviews positive_docs = process_docs('txt_sentoken/pos', vocab, True) negative_docs = process_docs('txt_sentoken/neg', vocab, True) train_docs = negative_docs + positive_docs # create the tokenizer tokenizer = Tokenizer() # fit the tokenizer on the documents tokenizer.fit_on_texts(train_docs) # sequence encode encoded_docs = tokenizer.texts_to_sequences(train_docs) # pad sequences max_length = max([len(s.split()) for s in train_docs]) Xtrain = pad_sequences(encoded_docs, maxlen=max_length, padding='post') # define training labels ytrain = array([0 for _ in range(900)] + [1 for _ in range(900)]) # load all test reviews positive_docs = process_docs('txt_sentoken/pos', vocab, False) negative_docs = process_docs('txt_sentoken/neg', vocab, False) test_docs = negative_docs + positive_docs # sequence encode encoded_docs = tokenizer.texts_to_sequences(test_docs) # pad sequences Xtest = pad_sequences(encoded_docs, maxlen=max_length, padding='post') # define test labels ytest = array([0 for _ in range(100)] + [1 for _ in range(100)]) # define vocabulary size (largest integer value) vocab_size = len(tokenizer.word_index) + 1 # define model model = Sequential() model.add(Embedding(vocab_size, 100, input_length=max_length)) model.add(Conv1D(filters=32, kernel_size=8, activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(10, activation='relu')) model.add(Dense(1, activation='sigmoid')) print(model.summary()) # compile network model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # fit network model.fit(Xtrain, ytrain, epochs=10, verbose=2) # evaluate loss, acc = model.evaluate(Xtest, ytest, verbose=0) print('Test Accuracy: %f' % (acc*100)) ``` 運行該示例在每個訓練時期結束時打印損失和準確性。我們可以看到該模型很快就能在訓練數據集上實現 100%的準確性。 在運行結束時,模型在測試數據集上達到了 84.5%的準確度,這是一個很好的分數。 鑒于神經網絡的隨機性,您的具體結果會有所不同。考慮運行幾次示例并將平均分數作為模型的技能。 ```py ... Epoch 6/10 2s - loss: 0.0013 - acc: 1.0000 Epoch 7/10 2s - loss: 8.4573e-04 - acc: 1.0000 Epoch 8/10 2s - loss: 5.8323e-04 - acc: 1.0000 Epoch 9/10 2s - loss: 4.3155e-04 - acc: 1.0000 Epoch 10/10 2s - loss: 3.3083e-04 - acc: 1.0000 Test Accuracy: 84.500000 ``` 我們剛剛看到一個例子,說明我們如何學習嵌入字作為擬合神經網絡模型的一部分。 接下來,讓我們看看如何有效地學習我們以后可以在神經網絡中使用的獨立嵌入。 ## 4.訓練 word2vec 嵌入 在本節中,我們將了解如何使用名為 word2vec 的高效算法學習獨立的單詞嵌入。 學習單詞嵌入作為網絡一部分的缺點是它可能非常慢,特別是對于非常大的文本數據集。 word2vec 算法是一種以獨立方式從文本語料庫中學習單詞嵌入的方法。該方法的好處是它可以在空間和時間復雜性方面非常有效地產生高質量的字嵌入。 第一步是準備好文檔以便學習嵌入。 這涉及與前一節相同的數據清理步驟,即通過空白區域分割文檔,刪除標點符號,以及過濾掉不在詞匯表中的標記。 word2vec 算法逐句處理文檔。這意味著我們將在清潔期間保留基于句子的結構。 我們開始像以前一樣加載詞匯表。 ```py # load doc into memory def load_doc(filename): # open the file as read only file = open(filename, 'r') # read all text text = file.read() # close the file file.close() return text # load the vocabulary vocab_filename = 'vocab.txt' vocab = load_doc(vocab_filename) vocab = vocab.split() vocab = set(vocab) ``` 接下來,我們定義一個名為 _doc_to_clean_lines()_ 的函數來逐行清理已加載的文檔并返回已清理行的列表。 ```py # turn a doc into clean tokens def doc_to_clean_lines(doc, vocab): clean_lines = list() lines = doc.splitlines() for line in lines: # split into tokens by white space tokens = line.split() # remove punctuation from each token table = str.maketrans('', '', punctuation) tokens = [w.translate(table) for w in tokens] # filter out tokens not in vocab tokens = [w for w in tokens if w in vocab] clean_lines.append(tokens) return clean_lines ``` 接下來,我們調整 process_docs()函數來加載和清理文件夾中的所有文檔,并返回所有文檔行的列表。 該函數的結果將是 word2vec 模型的訓練數據。 ```py # load all docs in a directory def process_docs(directory, vocab, is_trian): lines = list() # walk through all files in the folder for filename in listdir(directory): # skip any reviews in the test set if is_trian and filename.startswith('cv9'): continue if not is_trian and not filename.startswith('cv9'): continue # create the full path of the file to open path = directory + '/' + filename # load and clean the doc doc = load_doc(path) doc_lines = doc_to_clean_lines(doc, vocab) # add lines to list lines += doc_lines return lines ``` 然后我們可以加載所有訓練數據并將其轉換為一長串的“句子”(令牌列表),以便為 word2vec 模型擬合。 ```py # load training data positive_lines = process_docs('txt_sentoken/pos', vocab, True) negative_lines = process_docs('txt_sentoken/neg', vocab, True) sentences = negative_docs + positive_docs print('Total training sentences: %d' % len(sentences)) ``` 我們將使用 Gensim Python 庫中提供的 word2vec 實現。具體是 [Word2Vec 類](https://radimrehurek.com/gensim/models/word2vec.html)。 有關使用 Gensim 訓練獨立單詞的更多信息,請參閱帖子: * [如何使用 Gensim](https://machinelearningmastery.com/develop-word-embeddings-python-gensim/) 在 Python 中開發詞嵌入 在構造類時,該模型是合適的。我們從訓練數據中傳入干凈的句子列表,然后指定嵌入向量空間的大小(我們再次使用 100),在學習如何在訓練句子中嵌入每個單詞時要查看的相鄰單詞的數量(我們使用 5 個鄰居),在擬合模型時使用的線程數(我們使用 8,但是如果你有更多或更少的 CPU 核心則更改它),以及詞匯表中要考慮的單詞的最小出現次數(我們將其設置為 1 因為我們已經準備好了詞匯表)。 在模型擬合之后,我們打印學習詞匯的大小,這應該與我們在 25,767 個令牌的 vocab.txt 中的詞匯量相匹配。 ```py # train word2vec model model = Word2Vec(sentences, size=100, window=5, workers=8, min_count=1) # summarize vocabulary size in model words = list(model.wv.vocab) print('Vocabulary size: %d' % len(words)) ``` 最后,我們使用模型的' _wv_ '(字向量)屬性上的 [save_word2vec_format()](https://radimrehurek.com/gensim/models/keyedvectors.html)將學習的嵌入向量保存到文件中。嵌入以 ASCII 格式保存,每行一個字和向量。 下面列出了完整的示例。 ```py from string import punctuation from os import listdir from gensim.models import Word2Vec # load doc into memory def load_doc(filename): # open the file as read only file = open(filename, 'r') # read all text text = file.read() # close the file file.close() return text # turn a doc into clean tokens def doc_to_clean_lines(doc, vocab): clean_lines = list() lines = doc.splitlines() for line in lines: # split into tokens by white space tokens = line.split() # remove punctuation from each token table = str.maketrans('', '', punctuation) tokens = [w.translate(table) for w in tokens] # filter out tokens not in vocab tokens = [w for w in tokens if w in vocab] clean_lines.append(tokens) return clean_lines # load all docs in a directory def process_docs(directory, vocab, is_trian): lines = list() # walk through all files in the folder for filename in listdir(directory): # skip any reviews in the test set if is_trian and filename.startswith('cv9'): continue if not is_trian and not filename.startswith('cv9'): continue # create the full path of the file to open path = directory + '/' + filename # load and clean the doc doc = load_doc(path) doc_lines = doc_to_clean_lines(doc, vocab) # add lines to list lines += doc_lines return lines # load the vocabulary vocab_filename = 'vocab.txt' vocab = load_doc(vocab_filename) vocab = vocab.split() vocab = set(vocab) # load training data positive_lines = process_docs('txt_sentoken/pos', vocab, True) negative_lines = process_docs('txt_sentoken/neg', vocab, True) sentences = negative_docs + positive_docs print('Total training sentences: %d' % len(sentences)) # train word2vec model model = Word2Vec(sentences, size=100, window=5, workers=8, min_count=1) # summarize vocabulary size in model words = list(model.wv.vocab) print('Vocabulary size: %d' % len(words)) # save model in ASCII (word2vec) format filename = 'embedding_word2vec.txt' model.wv.save_word2vec_format(filename, binary=False) ``` 運行該示例從訓練數據中加載 58,109 個句子,并為 25,767 個單詞的詞匯表創建嵌入。 您現在應該在當前工作目錄中有一個帶有學習向量的文件'embedding_word2vec.txt'。 ```py Total training sentences: 58109 Vocabulary size: 25767 ``` 接下來,讓我們看看在我們的模型中使用這些學習過的向量。 ## 5.使用預先訓練的嵌入 在本節中,我們將使用在非常大的文本語料庫上準備的預訓練的單詞嵌入。 我們可以使用前一節中開發的預訓練單詞嵌入和之前部分開發的 CNN 模型。 第一步是將單詞嵌入作為單詞目錄加載到向量。單詞嵌入保存在包含標題行的所謂' _word2vec_ '格式中。加載嵌入時我們將跳過此標題行。 下面名為 _load_embedding()_ 的函數加載嵌入并返回映射到 NumPy 格式的向量的單詞目錄。 ```py # load embedding as a dict def load_embedding(filename): # load embedding into memory, skip first line file = open(filename,'r') lines = file.readlines()[1:] file.close() # create a map of words to vectors embedding = dict() for line in lines: parts = line.split() # key is string word, value is numpy array for vector embedding[parts[0]] = asarray(parts[1:], dtype='float32') return embedding ``` 現在我們已經在內存中擁有了所有向量,我們可以按照匹配 Keras Tokenizer 準備的整數編碼的方式對它們進行排序。 回想一下,我們在將審閱文檔傳遞給嵌入層之前對它們進行整數編碼。整數映射到嵌入層中特定向量的索引。因此,重要的是我們將向量放置在嵌入層中,使得編碼的單詞映射到正確的向量。 下面定義了一個函數 _get_weight_matrix()_,它將加載的嵌入和 tokenizer.word_index 詞匯表作為參數,并返回一個矩陣,其中的單詞 vector 位于正確的位置。 ```py # create a weight matrix for the Embedding layer from a loaded embedding def get_weight_matrix(embedding, vocab): # total vocabulary size plus 0 for unknown words vocab_size = len(vocab) + 1 # define weight matrix dimensions with all 0 weight_matrix = zeros((vocab_size, 100)) # step vocab, store vectors using the Tokenizer's integer mapping for word, i in vocab.items(): weight_matrix[i] = embedding.get(word) return weight_matrix ``` 現在我們可以使用這些函數為我們的模型創建新的嵌入層。 ```py ... # load embedding from file raw_embedding = load_embedding('embedding_word2vec.txt') # get vectors in the right order embedding_vectors = get_weight_matrix(raw_embedding, tokenizer.word_index) # create the embedding layer embedding_layer = Embedding(vocab_size, 100, weights=[embedding_vectors], input_length=max_length, trainable=False) ``` 請注意,準備好的權重矩陣 _embedding_vectors_ 作為參數傳遞給新的嵌入層,并且我們將'_ 可訓練 _'參數設置為' _False_ '以確保網絡不會嘗試將預先學習的向量作為訓練網絡的一部分。 我們現在可以將此層添加到我們的模型中。我們還有一個稍微不同的模型配置,在 CNN 模型中有更多的過濾器(128),以及在開發 word2vec 嵌入時匹配用作鄰居的 5 個單詞的內核。最后,簡化了模型的后端。 ```py # define model model = Sequential() model.add(embedding_layer) model.add(Conv1D(filters=128, kernel_size=5, activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(1, activation='sigmoid')) print(model.summary()) ``` 通過一些試驗和錯誤發現了這些變化。 完整的代碼清單如下。 ```py from string import punctuation from os import listdir from numpy import array from numpy import asarray from numpy import zeros from keras.preprocessing.text import Tokenizer from keras.preprocessing.sequence import pad_sequences from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers import Embedding from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # load doc into memory def load_doc(filename): # open the file as read only file = open(filename, 'r') # read all text text = file.read() # close the file file.close() return text # turn a doc into clean tokens def clean_doc(doc, vocab): # split into tokens by white space tokens = doc.split() # remove punctuation from each token table = str.maketrans('', '', punctuation) tokens = [w.translate(table) for w in tokens] # filter out tokens not in vocab tokens = [w for w in tokens if w in vocab] tokens = ' '.join(tokens) return tokens # load all docs in a directory def process_docs(directory, vocab, is_trian): documents = list() # walk through all files in the folder for filename in listdir(directory): # skip any reviews in the test set if is_trian and filename.startswith('cv9'): continue if not is_trian and not filename.startswith('cv9'): continue # create the full path of the file to open path = directory + '/' + filename # load the doc doc = load_doc(path) # clean doc tokens = clean_doc(doc, vocab) # add to list documents.append(tokens) return documents # load embedding as a dict def load_embedding(filename): # load embedding into memory, skip first line file = open(filename,'r') lines = file.readlines()[1:] file.close() # create a map of words to vectors embedding = dict() for line in lines: parts = line.split() # key is string word, value is numpy array for vector embedding[parts[0]] = asarray(parts[1:], dtype='float32') return embedding # create a weight matrix for the Embedding layer from a loaded embedding def get_weight_matrix(embedding, vocab): # total vocabulary size plus 0 for unknown words vocab_size = len(vocab) + 1 # define weight matrix dimensions with all 0 weight_matrix = zeros((vocab_size, 100)) # step vocab, store vectors using the Tokenizer's integer mapping for word, i in vocab.items(): weight_matrix[i] = embedding.get(word) return weight_matrix # load the vocabulary vocab_filename = 'vocab.txt' vocab = load_doc(vocab_filename) vocab = vocab.split() vocab = set(vocab) # load all training reviews positive_docs = process_docs('txt_sentoken/pos', vocab, True) negative_docs = process_docs('txt_sentoken/neg', vocab, True) train_docs = negative_docs + positive_docs # create the tokenizer tokenizer = Tokenizer() # fit the tokenizer on the documents tokenizer.fit_on_texts(train_docs) # sequence encode encoded_docs = tokenizer.texts_to_sequences(train_docs) # pad sequences max_length = max([len(s.split()) for s in train_docs]) Xtrain = pad_sequences(encoded_docs, maxlen=max_length, padding='post') # define training labels ytrain = array([0 for _ in range(900)] + [1 for _ in range(900)]) # load all test reviews positive_docs = process_docs('txt_sentoken/pos', vocab, False) negative_docs = process_docs('txt_sentoken/neg', vocab, False) test_docs = negative_docs + positive_docs # sequence encode encoded_docs = tokenizer.texts_to_sequences(test_docs) # pad sequences Xtest = pad_sequences(encoded_docs, maxlen=max_length, padding='post') # define test labels ytest = array([0 for _ in range(100)] + [1 for _ in range(100)]) # define vocabulary size (largest integer value) vocab_size = len(tokenizer.word_index) + 1 # load embedding from file raw_embedding = load_embedding('embedding_word2vec.txt') # get vectors in the right order embedding_vectors = get_weight_matrix(raw_embedding, tokenizer.word_index) # create the embedding layer embedding_layer = Embedding(vocab_size, 100, weights=[embedding_vectors], input_length=max_length, trainable=False) # define model model = Sequential() model.add(embedding_layer) model.add(Conv1D(filters=128, kernel_size=5, activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(1, activation='sigmoid')) print(model.summary()) # compile network model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # fit network model.fit(Xtrain, ytrain, epochs=10, verbose=2) # evaluate loss, acc = model.evaluate(Xtest, ytest, verbose=0) print('Test Accuracy: %f' % (acc*100)) ``` 運行該示例顯示表現未得到改善。 事實上,表現差得多。結果表明訓練數據集是成功學習的,但對測試數據集的評估非常差,準確度僅略高于 50%。 測試表現差的原因可能是因為選擇了 word2vec 配置或選擇的神經網絡配置。 ```py ... Epoch 6/10 2s - loss: 0.3306 - acc: 0.8778 Epoch 7/10 2s - loss: 0.2888 - acc: 0.8917 Epoch 8/10 2s - loss: 0.1878 - acc: 0.9439 Epoch 9/10 2s - loss: 0.1255 - acc: 0.9750 Epoch 10/10 2s - loss: 0.0812 - acc: 0.9928 Test Accuracy: 53.000000 ``` 嵌入層中的權重可以用作網絡的起始點,并且在網絡訓練期間進行調整。我們可以通過在創建嵌入層時設置' _trainable = True_ '(默認值)來實現。 使用此更改重復實驗顯示略微更好的結果,但仍然很差。 我鼓勵您探索嵌入和網絡的備用配置,看看您是否可以做得更好。讓我知道你是怎么做的。 ```py ... Epoch 6/10 4s - loss: 0.0950 - acc: 0.9917 Epoch 7/10 4s - loss: 0.0355 - acc: 0.9983 Epoch 8/10 4s - loss: 0.0158 - acc: 1.0000 Epoch 9/10 4s - loss: 0.0080 - acc: 1.0000 Epoch 10/10 4s - loss: 0.0050 - acc: 1.0000 Test Accuracy: 57.500000 ``` 可以使用在非常大的文本數據集上準備的預訓練的單詞向量。 例如,Google 和 Stanford 都提供了可以下載的預訓練單詞向量,分別使用高效的 word2vec 和 GloVe 方法進行訓練。 讓我們嘗試在我們的模型中使用預先訓練的向量。 您可以從斯坦福網頁下載[預訓練的 GloVe 載體](https://nlp.stanford.edu/projects/glove/)。具體來說,訓練維基百科數據的向量: * [手套.6B.zip](http://nlp.stanford.edu/data/glove.6B.zip) (822 兆字節下載) 解壓縮文件,您將找到各種不同尺寸的預先訓練嵌入。我們將在文件' _glove.6B.100d.txt_ '中加載 100 維版本 Glove 文件不包含頭文件,因此在將嵌入加載到內存時我們不需要跳過第一行。下面列出了更新的 _load_embedding()_ 功能。 ```py # load embedding as a dict def load_embedding(filename): # load embedding into memory, skip first line file = open(filename,'r') lines = file.readlines() file.close() # create a map of words to vectors embedding = dict() for line in lines: parts = line.split() # key is string word, value is numpy array for vector embedding[parts[0]] = asarray(parts[1:], dtype='float32') return embedding ``` 加載的嵌入可能不包含我們選擇的詞匯表中的所有單詞。因此,在創建嵌入權重矩陣時,我們需要跳過在加載的 GloVe 數據中沒有相應向量的單詞。以下是 _get_weight_matrix()_ 功能的更新,更具防御性的版本。 ```py # create a weight matrix for the Embedding layer from a loaded embedding def get_weight_matrix(embedding, vocab): # total vocabulary size plus 0 for unknown words vocab_size = len(vocab) + 1 # define weight matrix dimensions with all 0 weight_matrix = zeros((vocab_size, 100)) # step vocab, store vectors using the Tokenizer's integer mapping for word, i in vocab.items(): vector = embedding.get(word) if vector is not None: weight_matrix[i] = vector return weight_matrix ``` 我們現在可以像以前一樣加載 GloVe 嵌入并創建嵌入層。 ```py # load embedding from file raw_embedding = load_embedding('glove.6B.100d.txt') # get vectors in the right order embedding_vectors = get_weight_matrix(raw_embedding, tokenizer.word_index) # create the embedding layer embedding_layer = Embedding(vocab_size, 100, weights=[embedding_vectors], input_length=max_length, trainable=False) ``` 我們將使用與以前相同的模型。 下面列出了完整的示例。 ```py from string import punctuation from os import listdir from numpy import array from numpy import asarray from numpy import zeros from keras.preprocessing.text import Tokenizer from keras.preprocessing.sequence import pad_sequences from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers import Embedding from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # load doc into memory def load_doc(filename): # open the file as read only file = open(filename, 'r') # read all text text = file.read() # close the file file.close() return text # turn a doc into clean tokens def clean_doc(doc, vocab): # split into tokens by white space tokens = doc.split() # remove punctuation from each token table = str.maketrans('', '', punctuation) tokens = [w.translate(table) for w in tokens] # filter out tokens not in vocab tokens = [w for w in tokens if w in vocab] tokens = ' '.join(tokens) return tokens # load all docs in a directory def process_docs(directory, vocab, is_trian): documents = list() # walk through all files in the folder for filename in listdir(directory): # skip any reviews in the test set if is_trian and filename.startswith('cv9'): continue if not is_trian and not filename.startswith('cv9'): continue # create the full path of the file to open path = directory + '/' + filename # load the doc doc = load_doc(path) # clean doc tokens = clean_doc(doc, vocab) # add to list documents.append(tokens) return documents # load embedding as a dict def load_embedding(filename): # load embedding into memory, skip first line file = open(filename,'r') lines = file.readlines() file.close() # create a map of words to vectors embedding = dict() for line in lines: parts = line.split() # key is string word, value is numpy array for vector embedding[parts[0]] = asarray(parts[1:], dtype='float32') return embedding # create a weight matrix for the Embedding layer from a loaded embedding def get_weight_matrix(embedding, vocab): # total vocabulary size plus 0 for unknown words vocab_size = len(vocab) + 1 # define weight matrix dimensions with all 0 weight_matrix = zeros((vocab_size, 100)) # step vocab, store vectors using the Tokenizer's integer mapping for word, i in vocab.items(): vector = embedding.get(word) if vector is not None: weight_matrix[i] = vector return weight_matrix # load the vocabulary vocab_filename = 'vocab.txt' vocab = load_doc(vocab_filename) vocab = vocab.split() vocab = set(vocab) # load all training reviews positive_docs = process_docs('txt_sentoken/pos', vocab, True) negative_docs = process_docs('txt_sentoken/neg', vocab, True) train_docs = negative_docs + positive_docs # create the tokenizer tokenizer = Tokenizer() # fit the tokenizer on the documents tokenizer.fit_on_texts(train_docs) # sequence encode encoded_docs = tokenizer.texts_to_sequences(train_docs) # pad sequences max_length = max([len(s.split()) for s in train_docs]) Xtrain = pad_sequences(encoded_docs, maxlen=max_length, padding='post') # define training labels ytrain = array([0 for _ in range(900)] + [1 for _ in range(900)]) # load all test reviews positive_docs = process_docs('txt_sentoken/pos', vocab, False) negative_docs = process_docs('txt_sentoken/neg', vocab, False) test_docs = negative_docs + positive_docs # sequence encode encoded_docs = tokenizer.texts_to_sequences(test_docs) # pad sequences Xtest = pad_sequences(encoded_docs, maxlen=max_length, padding='post') # define test labels ytest = array([0 for _ in range(100)] + [1 for _ in range(100)]) # define vocabulary size (largest integer value) vocab_size = len(tokenizer.word_index) + 1 # load embedding from file raw_embedding = load_embedding('glove.6B.100d.txt') # get vectors in the right order embedding_vectors = get_weight_matrix(raw_embedding, tokenizer.word_index) # create the embedding layer embedding_layer = Embedding(vocab_size, 100, weights=[embedding_vectors], input_length=max_length, trainable=False) # define model model = Sequential() model.add(embedding_layer) model.add(Conv1D(filters=128, kernel_size=5, activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(1, activation='sigmoid')) print(model.summary()) # compile network model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # fit network model.fit(Xtrain, ytrain, epochs=10, verbose=2) # evaluate loss, acc = model.evaluate(Xtest, ytest, verbose=0) print('Test Accuracy: %f' % (acc*100)) ``` 運行該示例顯示了更好的表現。 同樣,訓練數據集很容易學習,模型在測試數據集上達到 76%的準確度。這很好,但不如使用學習的嵌入層。 這可能是由于在更多數據上訓練的更高質量的向量和/或使用稍微不同的訓練過程的原因。 鑒于神經網絡的隨機性,您的具體結果可能會有所不同。嘗試運行幾次示例。 ```py ... Epoch 6/10 2s - loss: 0.0278 - acc: 1.0000 Epoch 7/10 2s - loss: 0.0174 - acc: 1.0000 Epoch 8/10 2s - loss: 0.0117 - acc: 1.0000 Epoch 9/10 2s - loss: 0.0086 - acc: 1.0000 Epoch 10/10 2s - loss: 0.0068 - acc: 1.0000 Test Accuracy: 76.000000 ``` 在這種情況下,似乎學習嵌入作為學習任務的一部分可能是比使用專門訓練的嵌入或更一般的預訓練嵌入更好的方向。 ## 進一步閱讀 如果您要深入了解,本節將提供有關該主題的更多資源。 ### 數據集 * [電影評論數據](http://www.cs.cornell.edu/people/pabo/movie-review-data/) * [一種感傷教育:基于最小削減的主觀性總結的情感分析](http://xxx.lanl.gov/abs/cs/0409058),2004。 * [電影評論 Polarity Dataset](http://www.cs.cornell.edu/people/pabo/movie-review-data/review_polarity.tar.gz) (。tgz) * 數據集自述文件 [v2.0](http://www.cs.cornell.edu/people/pabo/movie-review-data/poldata.README.2.0.txt) 和 [v1.1](http://www.cs.cornell.edu/people/pabo/movie-review-data/README.1.1) 。 ### 蜜蜂 * [集合 API - 容器數據類型](https://docs.python.org/3/library/collections.html) * [Tokenizer Keras API](https://keras.io/preprocessing/text/#tokenizer) * [嵌入 Keras API](https://keras.io/layers/embeddings/) * [Gensim Word2Vec API](https://radimrehurek.com/gensim/models/word2vec.html) * [Gensim WordVector API](https://radimrehurek.com/gensim/models/keyedvectors.html) ### 嵌入方法 * Google 代碼上的 [word2vec](https://code.google.com/archive/p/word2vec/) * [斯坦福大學](https://nlp.stanford.edu/projects/glove/) ### 相關文章 * [在 Keras 模型中使用預訓練的字嵌入](https://blog.keras.io/using-pre-trained-word-embeddings-in-a-keras-model.html),2016。 * [在 TensorFlow](http://www.wildml.com/2015/12/implementing-a-cnn-for-text-classification-in-tensorflow/) ,2015 年實施 CNN 進行文本分類。 ## 摘要 在本教程中,您了解了如何為電影評論的分類開發單詞嵌入。 具體來說,你學到了: * 如何使用深度學習方法準備電影評論文本數據進行分類。 * 如何學習嵌入詞作為擬合深度學習模型的一部分。 * 如何學習獨立的單詞嵌入以及如何在神經網絡模型中使用預先訓練的嵌入。 你有任何問題嗎? 在下面的評論中提出您的問題,我會盡力回答。 **注**:這篇文章摘錄自:“[深度學習自然語言處理](https://machinelearningmastery.com/deep-learning-for-nlp/)”。看一下,如果您想要在使用文本數據時獲得有關深入學習方法的更多分步教程。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看