人工智慧 (06) 自然語言處理

Jason990420發表於2019-12-19

檔案建立日期: 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 )

  1. 將自然語言的給定輸入映像為有用的表示形式。
  2. 分析語言的不同方面。

自然語言生成 NLG ( Natural Language Generation )

  1. 文字計劃 - 從知識庫中檢索相關內容。
  2. 句子計劃 - 選擇所需的單詞,形成有意義的短語,設定句子的語氣。
  3. 文字實現 - 句子計劃映像到句子結構中。

自然語言生成的困難

  1. 詞彙歧義 - 同一詞彙, 不同的解析.
  2. 語法級別歧義 - 同一句子, 不同解釋.
  3. 參照歧義 - 代名詞參照何物.

自然語言術語

  1. 語音學 ( Phonology ) - 這是系統地組織聲音的研究。
  2. 形態 ( Morphology ) - 這是從原始有意義單位構造單詞的研究。
  3. 語素 ( Morpheme ) - 它是語言中意義的原始單位。
  4. 語法 ( Syntax ) - 指安排單片語成句子。 它還涉及確定單詞在句子和短語中的結構作用。
  5. 語義 ( Semantics ) - 它關注單詞的含義以及如何將單片語合為有意義的短語和句子。
  6. 語用學 ( Pragmatics ) - 它處理和理解不同情況下的句子,以及如何影響句子的解釋。
  7. 話語 ( Discourse ) - 它處理緊接在前的句子如何影響下一個句子的解釋。
  8. 世界知識 ( World Knowledge ) - 它包括有關世界的常識。

NLP中的步驟

  1. 詞法分析 ( Lexical Analysis ) - 詞法分析將txt的整個片段分為段落,句子和單詞。
  2. 句法分析 ( Syntactic Analysis, Parsing ) - 分析句子中的單詞以進行語法分析,並以顯示單詞之間關係的方式排列單詞。
  3. 語義分析 ( Semantic Analysis ) - 從文字中得出確切的含義或字典的含義。檢查文字是否有意義。
  4. 話語整合 ( Discourse Integration ) - 任何句子的含義取決於其前面句子的含義, 還有後面句子的含義。
  5. 語用分析 ( Pragmatic Analysis ) - 在此期間,所說的內容將根據其實際含義進行重新解釋。

自然語言工具包 ( NLTK, Natural Language Toolkit Package )

下載NLTK資料

除了安裝nltk外, 還有其他相關的庫及包, 可以使用NLTK的下載器nltk.download()

標記化 ( Tokenization ),詞幹 ( Stemming ) 和詞法化 ( Lemmatization ) 的概念

  1. 令牌化 ( Tokenization ) - 將給定文字即字元序列分解為稱為令牌的較小單元的過程。令牌可以是單詞,數字或標點符號。也稱為分詞。
  2. 詞幹 ( Stemming ) - 詞幹是透過切掉單詞的結尾來提取單詞基本形式的啟發式過程。
  3. 詞法化 ( Lemmatization ) - 透過詞彙的詞彙和詞法分析來完成透過詞法提取詞
  4. 分塊 ( Chunking ):將資料分為塊, 分塊展示句子的結構
    • 向上分塊 ( Chunking up ) - 物件,事物等逐漸趨於通用,語言也變得更加抽象。
    • 向下分塊 ( Chunking down ) - 物件,事物等朝著更加具體的方向發展,並且語言也得到了更深入的滲透。 更深層次的結構將在細分中進行檢查。
  5. 名詞短語分塊
    • 定義分塊的語法。 它由我們需要遵循的規則組成。
    • 建立一個分塊解析器。 它將解析語法並給出輸出。
    • 輸出以樹格式生成。
  6. 單詞袋(BoW, Bag of Word)模型 - 從文字中提取特徵。該模型從文檔案中的所有單詞中提取詞彙。然後,透過使用文件術語矩陣,建立一個模型。BoW僅將文件表示為單詞包。有關文檔案中單詞順序或結構的任何資訊都將被丟棄。
  7. 詞頻 ( Term Frequency ) - Inverse Document Frequency (TF-IDF)
    • 詞頻 ( TF, Term Frequency ) - 衡量每個單詞在文檔案中出現的頻率。
    • 反檔案頻率(IDF, Inverse Document Frequency)- 衡量單詞在給定文件集中對該文件的唯一性的量度。

解決問題

  1. 類別預測 ( Category Prediction )
  2. 性別搜尋器 ( Gender Finder )

主題建模:識別文字資料中的模式

在給定的文檔案集中發現抽象主題或隱藏結構的技術。
* 文字分類 ( Text Classification ) - 分類將相似的單片語合在一起
* 推薦系統 ( Recommender Systems ) - 使用相似性度量來構建

主題建模演算法 ( Algorithms for Topic Modeling )

  1. 潛在狄利克雷分配 ( LDA, Latent Dirichlet Allocation ) - 使用機率圖形模型來實現主題建模。
  2. 潛在語義分析 ( LDA, Latent Semantic Analysis )或潛在語義索引 ( LSI, Latent Semantic Indexing ) - 基於線性代數。 在文件術語矩陣上使用奇異值分解 ( SVD, Singular Value Decomposition ) 的概念。
  3. 非負矩陣分解 ( 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()                             # 顯示句子圖

人工智慧 (06) 自然語言處理

例 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 協議》,轉載必須註明作者和本文連結
Jason Yang

相關文章