檔案建立日期: 2019/12/19
最後修訂日期: None
相關軟體資訊:
Win 10 | Python 3.7.2 | Numpy 1.17.3 | sklearn 0.21.3 |
matplotlib 3.1.1 | pandas 0.25.1 | nltk 3.4.5 |
參考檔案: AI with Python Tutorial
說明: 所有內容歡迎引用, 只需註明來源及作者, 本文內容如有錯誤或用詞不當, 敬請指正.
標題: 人工智慧 (06) 自然語言處理
自然語言處理 ( NLP, Natural Language Processing )
自然語言理解 NLU ( Natural Language Understanding )
- 將自然語言的給定輸入映像為有用的表示形式。
- 分析語言的不同方面。
自然語言生成 NLG ( Natural Language Generation )
- 文字計劃 - 從知識庫中檢索相關內容。
- 句子計劃 - 選擇所需的單詞,形成有意義的短語,設定句子的語氣。
- 文字實現 - 句子計劃映像到句子結構中。
自然語言生成的困難
- 詞彙歧義 - 同一詞彙, 不同的解析.
- 語法級別歧義 - 同一句子, 不同解釋.
- 參照歧義 - 代名詞參照何物.
自然語言術語
- 語音學 ( Phonology ) - 這是系統地組織聲音的研究。
- 形態 ( Morphology ) - 這是從原始有意義單位構造單詞的研究。
- 語素 ( Morpheme ) - 它是語言中意義的原始單位。
- 語法 ( Syntax ) - 指安排單片語成句子。 它還涉及確定單詞在句子和短語中的結構作用。
- 語義 ( Semantics ) - 它關注單詞的含義以及如何將單片語合為有意義的短語和句子。
- 語用學 ( Pragmatics ) - 它處理和理解不同情況下的句子,以及如何影響句子的解釋。
- 話語 ( Discourse ) - 它處理緊接在前的句子如何影響下一個句子的解釋。
- 世界知識 ( World Knowledge ) - 它包括有關世界的常識。
NLP中的步驟
- 詞法分析 ( Lexical Analysis ) - 詞法分析將txt的整個片段分為段落,句子和單詞。
- 句法分析 ( Syntactic Analysis, Parsing ) - 分析句子中的單詞以進行語法分析,並以顯示單詞之間關係的方式排列單詞。
- 語義分析 ( Semantic Analysis ) - 從文字中得出確切的含義或字典的含義。檢查文字是否有意義。
- 話語整合 ( Discourse Integration ) - 任何句子的含義取決於其前面句子的含義, 還有後面句子的含義。
- 語用分析 ( Pragmatic Analysis ) - 在此期間,所說的內容將根據其實際含義進行重新解釋。
自然語言工具包 ( NLTK, Natural Language Toolkit Package )
下載NLTK資料
除了安裝nltk外, 還有其他相關的庫及包, 可以使用NLTK的下載器nltk.download()
標記化 ( Tokenization ),詞幹 ( Stemming ) 和詞法化 ( Lemmatization ) 的概念
- 令牌化 ( Tokenization ) - 將給定文字即字元序列分解為稱為令牌的較小單元的過程。令牌可以是單詞,數字或標點符號。也稱為分詞。
- 詞幹 ( Stemming ) - 詞幹是透過切掉單詞的結尾來提取單詞基本形式的啟發式過程。
- 詞法化 ( Lemmatization ) - 透過詞彙的詞彙和詞法分析來完成透過詞法提取詞
- 分塊 ( Chunking ):將資料分為塊, 分塊展示句子的結構
- 向上分塊 ( Chunking up ) - 物件,事物等逐漸趨於通用,語言也變得更加抽象。
- 向下分塊 ( Chunking down ) - 物件,事物等朝著更加具體的方向發展,並且語言也得到了更深入的滲透。 更深層次的結構將在細分中進行檢查。
- 名詞短語分塊
- 定義分塊的語法。 它由我們需要遵循的規則組成。
- 建立一個分塊解析器。 它將解析語法並給出輸出。
- 輸出以樹格式生成。
- 單詞袋(BoW, Bag of Word)模型 - 從文字中提取特徵。該模型從文檔案中的所有單詞中提取詞彙。然後,透過使用文件術語矩陣,建立一個模型。BoW僅將文件表示為單詞包。有關文檔案中單詞順序或結構的任何資訊都將被丟棄。
- 詞頻 ( Term Frequency ) - Inverse Document Frequency (TF-IDF)
- 詞頻 ( TF, Term Frequency ) - 衡量每個單詞在文檔案中出現的頻率。
- 反檔案頻率(IDF, Inverse Document Frequency)- 衡量單詞在給定文件集中對該文件的唯一性的量度。
解決問題
- 類別預測 ( Category Prediction )
- 性別搜尋器 ( Gender Finder )
主題建模:識別文字資料中的模式
在給定的文檔案集中發現抽象主題或隱藏結構的技術。
* 文字分類 ( Text Classification ) - 分類將相似的單片語合在一起
* 推薦系統 ( Recommender Systems ) - 使用相似性度量來構建
主題建模演算法 ( Algorithms for Topic Modeling )
- 潛在狄利克雷分配 ( LDA, Latent Dirichlet Allocation ) - 使用機率圖形模型來實現主題建模。
- 潛在語義分析 ( LDA, Latent Semantic Analysis )或潛在語義索引 ( LSI, Latent Semantic Indexing ) - 基於線性代數。 在文件術語矩陣上使用奇異值分解 ( SVD, Singular Value Decomposition ) 的概念。
- 非負矩陣分解 ( NMF, Non-Negative Matrix Factorization ) - 基於線性代數。
示例 1. 詞法分析
# -----------------------------------------------------------------------------
# NLTK - Natural Language Toolkit
# -----------------------------------------------------------------------------
import nltk
# nltk.download() # 下載 NLTK 的相闗資料
sentence = [("a" , "DT"),("clever","JJ" ), # DT - 限定符,
("fox" ,"NN" ),("was" ,"VBP"), # IN - 介詞或從屬連詞
("jumping","VBP"),("over" ,"IN" ), # JJ - 形容詞或序數詞
("the" ,"DT" ),("wall" ,"NN" )] # NN - 單數常用名詞
# VBP - 過去分詞
# RegexpParser使用正規表示式模式來指定解析器的行為
grammar = "NP:{<DT>?<JJ>*<NN>}" # NP - 名詞短語
parser_chunking=nltk.RegexpParser(grammar) # 建立解析器
Output_chunk=parser_chunking.parse(sentence) # 解析句子
Output_chunk.draw() # 顯示句子圖
例 2. 單詞袋
# -----------------------------------------------------------------------------
# Building a Bag of Words Model in NLTK
# -----------------------------------------------------------------------------
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() # 建立詞頻向量器
term_text = vectorizer_count.fit_transform(Sentences) # 訓練
features_text = ter_text.todense() # 18字緊縮到13個字
print(vectorizer_count.vocabulary_) # 詞對應到索引
例 3. 類別預測
# -----------------------------------------------------------------------------
# Category Prediction
# -----------------------------------------------------------------------------
from sklearn.datasets import fetch_20newsgroups # 20個新聞群檔案集
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( # 下載新聞資料集(14MB)
subset='train', # 訓練資料資料集
categories=category_map.keys(), # 新聞分類
shuffle=True, # 打亂順多序
random_state=5) # 隨機數種子
vectorizer_count = CountVectorizer() # 建立詞頻向量器
train_tc = vectorizer_count.fit_transform(training_data.data) # 訓練得詞頻
tfidf = TfidfTransformer() # Tf-idf詞頻轉換器
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, Refrigerator all uses electricity']
classifier = MultinomialNB().fit( # 用於多項模型的樸素貝葉斯分類器
train_tfidf, # 訓練
training_data.target)
input_tc = vectorizer_count.transform(input_data) # 先作詞頻轉換
input_tfidf = tfidf.transform(input_tc) # 轉換成Tf-idf
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]])
例 4. 性別搜尋器
# -----------------------------------------------------------------------------
# Gender Finder
# -----------------------------------------------------------------------------
import random
from nltk import NaiveBayesClassifier
from nltk.classify import accuracy as nltk_accuracy
from nltk.corpus import names
def extract_features(word, N=2):
last_n_letters = word[-N:]
return {'feature': last_n_letters.lower()}
# 下載男人和女人的資料集, 建立資料列表, 並打亂順序
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)
train_sample = int(0.8 * len(data)) # 80%資料作為訓練集
# 取出資料集中後面1~5個字, 性別, 重新建立訓練用資料集(80%)及測試用資料集(20%)
# 使用樸素貝葉斯分類器檢測不同字數資料集的準確率
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) + '%')
# 不同長度名字的資料集所訓練出來的分類器, 對新名字的分類
namesInput = ['Rajesh', 'Gaurav', 'Swati', 'Shubha']
for name in namesInput:
print(name, '==>', classifier.classify(extract_features(name, i)))
本作品採用《CC 協議》,轉載必須註明作者和本文連結