在本章中,我們將學習如何開始使用自然語言工具包包。
Prerequisite
如果我們想用自然語言處理來構建應用程式,那麼上下文的變化會使它變得非常困難。語境因素影響機器理解特定句子的方式。因此,我們需要使用機器學習方法開發自然語言應用程式,這樣機器也可以理解人類理解上下文的方式。
爲了構建這樣的應用程式,我們將使用名爲NLTK(自然語言工具包包)的Python包。
Importing NLTK
在使用之前我們需要安裝NLTK。它可以通過以下命令安裝−
pip install nltk
要爲NLTK構建conda包,請使用以下命令−
conda install -c anaconda nltk
現在在安裝NLTK包之後,我們需要通過python命令提示符導入它。我們可以通過在Python命令提示符下編寫以下命令來導入它−
>>> import nltk
Downloading NLTK’s Data
現在在導入NLTK之後,我們需要下載所需的數據。這可以通過Python命令提示符下的以下命令完成−
>>> nltk.download()
Installing Other Necessary Packages
爲了使用NLTK構建自然語言處理應用程式,我們需要安裝必要的軟體包。包裝如下所示;
gensim
它是一個健壯的語義建模庫,對許多應用程式都很有用。我們可以通過執行以下命令來安裝它;
pip install gensim
pattern
它用於使gensim包正常工作。我們可以通過執行以下命令來安裝它
pip install pattern
Concept of Tokenization, Stemming, and Lemmatization
在本節中,我們將了解什麼是標記化、詞幹化和引理化。
Tokenization
它可以定義爲將給定文本(即字符序列)分解爲稱爲標記的較小單元的過程。標記可以是單詞、數字或標點符號。它也被稱爲分詞。下面是標記化的一個簡單示例−
輸入芒果、香蕉、菠蘿和蘋果都是水果。
輸出
打破給定文本的過程可以通過定位單詞邊界來完成。一個詞的結尾和一個新詞的開頭叫做詞的邊界。文字系統和文字的排版結構影響著邊界。
在Python NLTK模塊中,我們有不同的與標記化相關的包,可以根據我們的需求使用這些包將文本劃分爲標記。有些包裝如下所示;
sent_tokenize package
顧名思義,這個包將把輸入的文本分成句子。我們可以藉助以下Python代碼導入這個包−
from nltk.tokenize import sent_tokenize
word_tokenize package
這個包將輸入的文本分成幾個字。我們可以藉助以下Python代碼導入這個包−
from nltk.tokenize import word_tokenize
WordPunctTokenizer package
這個包將輸入的文本分爲單詞和標點符號。我們可以藉助以下Python代碼導入這個包−
from nltk.tokenize import WordPuncttokenizer
Stemming
在處理單詞時,由於語法原因,我們會遇到很多變化。這裡的變體概念意味著我們必須處理同一個詞的不同形式,如民主,民主,和民主化。機器很有必要理解這些不同的詞有相同的基本形式。這樣,當我們分析文本時,提取單詞的基本形式會很有用。
我們可以通過堵塞來實現這一點。這樣,我們可以說詞幹分析是一個啟發式的過程,它通過切掉詞尾來提取單詞的基本形式。
在Python NLTK模塊中,我們有不同的與詞幹處理相關的包。這些包可用於獲取word的基本形式。這些包使用算法。有些包裝如下所示;
PorterStemmer package
這個Python包使用Porter的算法提取基本表單。我們可以藉助以下Python代碼導入這個包−
from nltk.stem.porter import PorterStemmer
例如,如果我們將單詞'writing'作爲這個詞幹分析器的輸入,那麼我們將在詞幹分析器之後得到單詞'write'。
LancasterStemmer package
這個Python包將使用Lancaster的算法來提取基本表單。我們可以藉助以下Python代碼導入這個包−
from nltk.stem.lancaster import LancasterStemmer
例如,如果我們將單詞'writing'作爲這個詞幹分析器的輸入,那麼我們將在詞幹分析器之後得到單詞'write'。
SnowballStemmer package
這個Python包將使用snowball的算法來提取基表單。我們可以藉助以下Python代碼導入這個包−
from nltk.stem.snowball import SnowballStemmer
例如,如果我們將單詞'writing'作爲這個詞幹分析器的輸入,那麼我們將在詞幹分析器之後得到單詞'write'。
所有這些算法都有不同程度的嚴格性。如果我們比較這三種炮泥,那麼波特炮泥是最不嚴格的,蘭開斯特炮泥是最嚴格的。雪球炮泥是很好的使用方面的速度和嚴格性。
Lemmatization
我們還可以通過引理提取單詞的基形式。它基本上是通過使用詞彙和詞形分析來完成這項任務的,通常目的只是去除屈折詞尾。任何單詞的這種基形式都叫做引理。
詞幹分析和引理化的主要區別在於詞彙的使用和詞形分析。另一個區別是詞幹處理通常會摺疊派生相關的詞,而引理化通常只摺疊引理的不同屈折形式。例如,如果我們提供單詞saw作爲輸入單詞,那麼詞幹分析可能返回單詞's',但是根據標記的使用是動詞還是名詞,檸檬化將嘗試返回單詞see或saw。
在Python NLTK模塊中,我們有以下與元素化過程相關的包,可以使用它來獲得word&minus的基本形式;
WordNetLemmatizer package
這個Python包將提取單詞的基本形式,這取決於它是用作名詞還是用作動詞。我們可以藉助以下Python代碼導入這個包−
from nltk.stem import WordNetLemmatizer
Chunking: Dividing Data into Chunks
它是自然語言處理中的一個重要過程。組塊的主要工作是識別詞類和名詞短語等短語。我們已經研究了標記化的過程,即標記的創建。分塊基本上就是標記那些標記。換言之,組塊將向我們展示句子的結構。
在下一節中,我們將學習不同類型的分塊。
Types of chunking
有兩種類型的分塊。類型如下所示;
Chunking up
在這個分塊的過程中,對象、事物等變得更一般,語言變得更抽象。達成一致的可能性更大。在這個過程中,我們縮小。例如,如果我們把「汽車是用來做什麼的」這個問題分爲幾個部分?我們可能會得到答案「運輸」。
Chunking down
在這個分塊的過程中,對象、事物等變得更加具體,語言變得更加深入。更深層的結構將被分塊檢查。在這個過程中,我們放大。例如,如果我們把「具體講一輛車」這個問題刪掉?我們會得到關於這輛車的小信息。
示例
在本例中,我們將使用Python&minus中的NLTK模塊來執行名詞短語分塊,這是一種可以在句子中找到名詞短語分塊的分塊;
按照python中的以下步驟實現名詞短語分塊&minus
步驟1−在這一步中,我們需要定義分塊的語法。它將包括我們需要遵守的規則。
步驟2−在這一步中,我們需要創建一個塊解析器。它將解析語法並給出輸出。
步驟3−在最後一步中,將以樹格式生成輸出。
讓我們導入必要的NLTK包,如下所示;
import nltk
現在,我們需要定義這個句子。這裡,DT是行列式,VBP是動詞,JJ是形容詞,IN是介詞,NN是名詞。
sentence=[("a","DT"),("clever","JJ"),("fox","NN"),("was","VBP"), ("jumping","VBP"),("over","IN"),("the","DT"),("wall","NN")]
現在,我們需要給出語法。在這裡,我們將以正則表達式的形式給出語法。
grammar = "NP:{<DT>?<JJ>*<NN>}"
我們需要定義一個解析器來解析語法。
parser_chunking = nltk.RegexpParser(grammar)
語法分析器按如下方式解析該句子−
parser_chunking.parse(sentence)
接下來,我們需要得到輸出。輸出在名爲output_chunk的簡單變量中生成。
Output_chunk = parser_chunking.parse(sentence)
執行以下代碼後,我們可以以樹的形式繪製輸出。
output.draw()
Bag of Word (BoW) Model
Bag of Word (BoW), a model in natural language processing, is basically used to extract the features from text so that the text can be used in modeling such that in machine learning algorithms.
Now the question arises that why we need to extract the features from text. It is because the machine learning algorithms cannot work with raw data and they need numeric data so that they can extract meaningful information out of it. The conversion of text data into numeric data is called feature extraction or feature encoding.
How it works
This is very simple approach for extracting the features from text. Suppose we have a text document and we want to convert it into numeric data or say want to extract the features out of it then first of all this model extracts a vocabulary from all the words in the document. Then by using a document term matrix, it will build a model. In this way, BoW represents the document as a bag of words only. Any information about the order or structure of words in the document is discarded.
Concept of document term matrix
BoW算法利用文檔項矩陣建立模型。顧名思義,文檔術語矩陣是文檔中出現的各種字數的矩陣。藉助這個矩陣,文本文檔可以表示爲各種單詞的加權組合。通過設置閾值並選擇更有意義的詞,我們可以建立文檔中所有詞的直方圖,作爲特徵向量。下面是一個理解文檔項矩陣概念的示例−
示例
假設我們有以下兩句話;
Award 1&mins;we are using the bag of words model.
第2句−Bag of Words model用於提取特徵。
現在,通過考慮這兩個句子,我們得到了以下13個不同的單詞;
- we
- are
- using
- the
- bag
- of
- words
- model
- is
- used
- for
- extracting
- features
現在,我們需要使用每個句子中的單詞計數爲每個句子構建一個直方圖;
第1句−[1,1,1,1,1,1,0,0]
第2句−[0,0,0,1,1,1,1,1,1,1,1,1,1]
這樣,我們就得到了已經提取的特徵向量。每個特徵向量是13維的,因爲我們有13個不同的詞。
Concept of the Statistics
統計的概念被稱爲TermFrequency逆文檔頻率(tf-idf)。文件中的每一個字都很重要。統計數字有助於我們理解每個詞的重要性。
Term Frequency(tf)
它是衡量每個單詞在文檔中出現的頻率。它可以通過將每個單詞的數量除以給定文檔中的單詞總數來獲得。
Inverse Document Frequency(idf)
它是對給定文檔集中的單詞對文檔的唯一性的度量。在計算idf和構造特徵向量時,需要對常見詞(如)進行加權,對稀有詞進行加權。
Building a Bag of Words Model in NLTK
在本節中,我們將通過使用CountVectorizer從這些句子中創建向量來定義字符串集合。
讓我們進口必要的包裝;
from sklearn.feature_extraction.text import CountVectorizer
現在定義一組句子。
Sentences = ['We are using the Bag of Word model', 'Bag of Word model is used for extracting the features.'] vectorizer_count = CountVectorizer() features_text = vectorizer.fit_transform(Sentences).todense() print(vectorizer.vocabulary_)
上面的程序生成如下所示的輸出。結果表明,在這兩句話中,我們有13個不同的詞;
{'we': 11, 'are': 0, 'using': 10, 'the': 8, 'bag': 1, 'of': 7, 'word': 12, 'model': 6, 'is': 5, 'used': 9, 'for': 4, 'extracting': 2, 'features': 3}
這些是可用於機器學習的特徵向量(文本到數字形式)。
Solving Problems
在這一部分中,我們將解決一些相關的問題。
Category Prediction
在一組文檔中,不僅單詞而且單詞的類別也很重要;在哪一類文本中,特定的單詞屬於哪一類。例如,我們想要預測一個給定的句子是否屬於email、news、sports、computer等類別。在下面的例子中,我們將使用tf-idf來構造一個特徵向量來查找文檔類別。我們將使用來自sklearn的20個新聞組數據集的數據。
我們需要進口必要的包裝;
from sklearn.datasets import fetch_20newsgroups from sklearn.naive_bayes import MultinomialNB from sklearn.feature_extraction.text import TfidfTransformer from sklearn.feature_extraction.text import CountVectorizer
定義類別映射。我們使用了五個不同的類別,分別是宗教、汽車、體育、電子和太空。
category_map = {'talk.religion.misc':'Religion','rec.autos''Autos', 'rec.sport.hockey':'Hockey','sci.electronics':'Electronics', 'sci.space': 'Space'}
創建訓練集−
training_data = fetch_20newsgroups(subset = 'train', categories = category_map.keys(), shuffle = True, random_state = 5)
構建一個計數向量器並提取術語counts−
vectorizer_count = CountVectorizer() train_tc = vectorizer_count.fit_transform(training_data.data) print("\nDimensions of training data:", train_tc.shape)
tf-idf轉換器的創建方式如下所示;
tfidf = TfidfTransformer() train_tfidf = tfidf.fit_transform(train_tc)
現在,定義測試數據;
input_data = [ 'Discovery was a space shuttle', 'Hindu, Christian, Sikh all are religions', 'We must have to drive safely', 'Puck is a disk made of rubber', 'Television, Microwave, Refrigrated all uses electricity' ]
以上數據將有助於我們訓練一個多項式樸素貝葉斯分類器;
classifier = MultinomialNB().fit(train_tfidf, training_data.target)
使用計數矢量器轉換輸入數據;
input_tc = vectorizer_count.transform(input_data)
現在,我們將使用tfidf transformer轉換矢量化數據;
input_tfidf = tfidf.transform(input_tc)
我們將預測輸出類別;
predictions = classifier.predict(input_tfidf)
輸出如下所示;
for sent, category in zip(input_data, predictions): print('\nInput Data:', sent, '\n Category:', \ category_map[training_data.target_names[category]])
類別預測器生成以下輸出&負;
Dimensions of training data: (2755, 39297) Input Data: Discovery was a space shuttle Category: Space Input Data: Hindu, Christian, Sikh all are religions Category: Religion Input Data: We must have to drive safely Category: Autos Input Data: Puck is a disk made of rubber Category: Hockey Input Data: Television, Microwave, Refrigrated all uses electricity Category: Electronics
Gender Finder
在這個問題陳述中,將訓練分類器通過提供名稱來查找性別(男性或女性)。我們需要使用啟發式構造特徵向量並訓練分類器。我們將使用scikit學習包中標記的數據。下面是構建性別查找器的Python代碼−
讓我們進口必要的包裝;
import random from nltk import NaiveBayesClassifier from nltk.classify import accuracy as nltk_accuracy from nltk.corpus import names
現在我們需要從輸入單詞中提取最後N個字母。這些字母將充當特徵;
def extract_features(word, N = 2): last_n_letters = word[-N:] return {'feature': last_n_letters.lower()} if __name__=='__main__':
使用NLTK−中提供的標記名稱(男性和女性)創建培訓數據;
male_list = [(name, 'male') for name in names.words('male.txt')] female_list = [(name, 'female') for name in names.words('female.txt')] data = (male_list + female_list) random.seed(5) random.shuffle(data)
現在,測試數據將創建如下所示;
namesInput = ['Rajesh', 'Gaurav', 'Swati', 'Shubha']
使用以下代碼定義用於培訓和測試的樣本數
train_sample = int(0.8 * len(data))
現在,我們需要疊代不同的長度,以便可以比較精度;
for i in range(1, 6): print('\nNumber of end letters:', i) features = [(extract_features(n, i), gender) for (n, gender) in data] train_data, test_data = features[:train_sample], features[train_sample:] classifier = NaiveBayesClassifier.train(train_data)
分類器的精度可以計算如下&負;
accuracy_classifier = round(100 * nltk_accuracy(classifier, test_data), 2) print('Accuracy = ' + str(accuracy_classifier) + '%')
現在,我們可以預測產量;
for name in namesInput: print(name, '==>', classifier.classify(extract_features(name, i)))
上面的程序將生成以下輸出&負;
Number of end letters: 1 Accuracy = 74.7% Rajesh -> female Gaurav -> male Swati -> female Shubha -> female Number of end letters: 2 Accuracy = 78.79% Rajesh -> male Gaurav -> male Swati -> female Shubha -> female Number of end letters: 3 Accuracy = 77.22% Rajesh -> male Gaurav -> female Swati -> female Shubha -> female Number of end letters: 4 Accuracy = 69.98% Rajesh -> female Gaurav -> female Swati -> female Shubha -> female Number of end letters: 5 Accuracy = 64.63% Rajesh -> female Gaurav -> female Swati -> female Shubha -> female
在上面的輸出中,我們可以看到最大結束字母數的精度是2,並且隨著結束字母數的增加,精度正在下降。
Topic Modeling: Identifying Patterns in Text Data
我們知道,一般情況下,文檔是按主題分組的。有時我們需要識別文本中與特定主題對應的模式。這樣做的技術稱爲主題建模。換句話說,我們可以說主題建模是一種在給定的文檔集中發現抽象主題或隱藏結構的技術。
我們可以在以下場景中使用主題建模技術;
Text Classification
在主題建模的幫助下,分類可以得到改進,因爲它將相似的詞組合在一起,而不是將每個詞單獨用作特徵。
Recommender Systems
在主題建模的基礎上,利用相似性度量建立推薦系統。
Algorithms for Topic Modeling
主題建模可以通過算法來實現。算法如下所示;
Latent Dirichlet Allocation(LDA)
該算法是目前最流行的主題建模算法。它使用機率圖形模型來實現主題建模。我們需要在Python中導入gensim包以使用LDA slgorithm。
Latent Semantic Analysis(LDA) or Latent Semantic Indexing(LSI)
該算法基於線性代數。基本上,它在文檔項矩陣上使用SVD(奇異值分解)的概念。
Non-Negative Matrix Factorization (NMF)
它也基於線性代數。
上述所有主題建模算法都將主題數作爲參數,文檔單詞矩陣作爲輸入,WTM(單詞主題矩陣)&TDM(主題文檔矩陣)作爲輸出。