Python 字典提供有效率的鍵值查詢機制,適用於詞性標注等自然語言處理任務。詞性標注旨在標記文字中每個詞彙的詞性,例如名詞、動詞、形容詞等。利用 Python 字典,可以將詞彙對映到其對應的詞性標籤。NLTK 提供更進階的工具,例如 defaultdict
可設定預設值,簡化低頻詞彙處理或詞性頻率統計。處理 Brown 語料函式庫時,能有效統計詞性標籤和後續詞彙的頻率。除了詞性標注,字典也支援反轉操作,能根據值查詢鍵,包含單值和多值對應的情況。自動詞性標注技術包含預設標注器、正規表示式標注器等,並可透過正確率評估效能。實務上可組合多種標注器提升準確性。
使用Python字典將詞語對映到屬性 | 191
當我們說某個詞的詞性是形容詞時,具體來說,就是在字典pos
中,鍵'colorless'
被賦予了值'ADJ'
。讓我們來檢查pos
的值:
>>> pos = {'colorless': 'ADJ', 'ideas': 'N', 'sleep': 'V', 'furiously': 'ADV'}
>>> pos['ideas']
'N'
>>> pos['colorless']
'ADJ'
當然,我們可能會不小心使用一個尚未被指定的鍵:
>>> pos['green']
Traceback (most recent call last):
File "<stdin>", line 1, in ?
KeyError: 'green'
這引出了一個重要問題。與列表和字串不同,我們可以使用len()
來確定哪些整數是合法的索引,但我們如何確定字典中的合法鍵?如果字典不是太大,我們可以直接檢查變數pos
的內容。就像我們之前看到的那樣,這會給我們鍵-值對。請注意,它們的順序與最初輸入的順序不同,因為字典不是序列,而是對映(見圖5-3),並且鍵本身沒有內在順序。
內容解密:
上述程式碼展示瞭如何使用Python字典來儲存詞語及其對應的詞性標籤。字典是一種鍵-值對的集合,允許我們透過鍵來檢索值。在這個例子中,詞語是鍵,而詞性標籤是值。
取得字典中的鍵和值
要取得字典中的鍵或值,我們可以將字典轉換為列表,或者在需要列表的上下文中使用字典,例如作為sorted()
的引數,或在for
迴圈中使用:
>>> list(pos)
['colorless', 'furiously', 'sleep', 'ideas']
>>> sorted(pos)
['colorless', 'furiously', 'ideas', 'sleep']
>>> [w for w in pos if w.endswith('s')]
['colorless', 'ideas']
內容解密:
這段程式碼展示瞭如何取得字典中的鍵和值。list(pos)
傳回字典中的所有鍵,而sorted(pos)
傳回按順序排列的鍵列表。列表推導式[w for w in pos if w.endswith('s')]
則用於找出所有以’s’結尾的詞語。
遍歷字典
我們可以使用for
迴圈遍歷字典中的所有鍵,就像列印列表一樣:
>>> for word in sorted(pos):
... print(word + ":", pos[word])
...
colorless: ADJ
furiously: ADV
ideas: N
sleep: V
內容解密:
這段程式碼展示瞭如何使用for
迴圈遍歷字典中的所有鍵,並列印預出每個鍵及其對應的值。sorted(pos)
確保鍵是按順序遍歷的。
字典方法
字典方法keys()
、values()
和items()
允許我們將鍵、值和鍵-值對作為單獨的列表存取。我們甚至可以對元組進行排序,這將根據它們的第一個元素(以及如果第一個元素相同時根據第二個元素)對它們進行排序:
>>> pos.keys()
['colorless', 'furiously', 'sleep', 'ideas']
>>> pos.values()
['ADJ', 'ADV', 'V', 'N']
>>> pos.items()
[('colorless', 'ADJ'), ('furiously', 'ADV'), ('sleep', 'V'), ('ideas', 'N')]
>>> for key, val in sorted(pos.items()):
... print(key + ":", val)
...
colorless: ADJ
furiously: ADV
ideas: N
sleep: V
內容解密:
這段程式碼展示瞭如何使用字典方法來存取鍵、值和鍵-值對。keys()
、values()
和items()
方法分別傳回字典中的鍵、值和鍵-值對列表。sorted(pos.items())
則傳回按鍵排序的鍵-值對列表。
定義字典
我們可以使用相同的鍵-值對格式來建立字典。有幾種方法可以做到這一點,我們通常使用第一種方法:
>>> pos = {'colorless': 'ADJ', 'ideas': 'N', 'sleep': 'V', 'furiously': 'ADV'}
>>> pos = dict(colorless='ADJ', ideas='N', sleep='V', furiously='ADV')
內容解密:
這段程式碼展示瞭如何定義字典。第一種方法是直接使用鍵-值對格式建立字典,而第二種方法是使用dict()
函式建立字典。
鍵的型別限制
請注意,字典鍵必須是不可變型別,如字串和元組。如果我們嘗試使用可變鍵定義字典,將會得到TypeError
:
>>> pos = {['ideas', 'blogs', 'adventures']: 'N'}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
內容解密:
這段程式碼展示了字典鍵的型別限制。由於列表是可變的,因此不能用作字典鍵。
預設字典
如果我們嘗試存取字典中不存在的鍵,將會得到錯誤。然而,通常如果字典能夠自動為這個新鍵建立一個條目並給出一個預設值(如零或空列表),將會非常有用。自Python 2.5以來,一種特殊的字典,稱為defaultdict
,已經可用了。要使用它,我們必須提供一個引數,該引數可用於建立預設值,例如int
、float
、str
、list
、dict
、tuple
:
>>> frequency = nltk.defaultdict(int)
>>> frequency['colorless'] = 4
>>> frequency['ideas']
0
>>> pos = nltk.defaultdict(list)
>>> pos['sleep'] = ['N', 'V']
>>> pos['ideas']
[]
內容解密:
這段程式碼展示瞭如何使用defaultdict
來建立預設字典。defaultdict
允許我們指定一個預設值,當存取不存在的鍵時,將自動建立該鍵並賦予預設值。
自定義預設值
上述例子指定了字典條目的預設值是特定資料型別的預設值。然而,我們可以指定任何我們喜歡的預設值,只需提供一個函式的名字,該函式可以在沒有引數的情況下呼叫以建立所需的值。讓我們回到我們的詞性例子,並建立一個預設值為'N'
的字典。當我們存取一個不存在的條目時,它將自動新增到字典中:
>>> pos = nltk.defaultdict(lambda: 'N')
>>> pos['colorless'] = 'ADJ'
>>> pos['blog']
'N'
內容解密:
這段程式碼展示瞭如何自定義預設值。我們使用lambda
函式來建立一個預設值為'N'
的字典。當我們存取不存在的鍵時,它將自動建立該鍵並賦予預設值'N'
。
此圖示
graph LR; A[開始] --> B{檢查鍵是否存在}; B -->|是| C[傳回對應值]; B -->|否| D[丟擲KeyError]; E[使用defaultdict] --> F[自動建立鍵並賦予預設值];
圖表翻譯:
此圖示展示了存取字典中的鍵時可能出現的兩種情況。如果鍵存在,則傳回對應的值;如果鍵不存在,則丟擲KeyError
。使用defaultdict
可以自動建立鍵並賦予預設值。
使用Python字典進行詞性標注與詞彙屬性對映
在自然語言處理(NLP)任務中,詞性標注(Part-of-Speech Tagging)是一個基礎且重要的步驟。詞性標注是指為文字中的每個詞彙標註其詞性(如名詞、動詞、形容詞等)。本篇文章將探討如何使用Python字典來進行詞性標注和詞彙屬性對映,並提供詳細的程式碼範例和解析。
預備知識
在開始之前,我們需要了解一些基本的概念:
- 詞性標注(POS Tagging):為文字中的詞彙標註其詞性。
- Python字典:一種資料結構,用於儲存鍵值對。
- NLTK(Natural Language Toolkit):一個用於NLP任務的Python函式庫。
使用預設字典進行詞彙替換
在處理文字時,我們經常需要處理低頻詞彙。一個常見的做法是將低頻詞彙替換為一個特殊的標記,如"UNK"。我們可以使用nltk.defaultdict
來實作這一功能。
程式碼範例1:使用預設字典替換低頻詞彙
import nltk
from nltk.corpus import gutenberg
# 載入文字資料
alice = nltk.corpus.gutenberg.words('carroll-alice.txt')
# 統計詞頻
vocab = nltk.FreqDist(alice)
# 取得前1000個高頻詞
v1000 = list(vocab)[:1000]
# 建立預設字典,將低頻詞替換為"UNK"
mapping = nltk.defaultdict(lambda: 'UNK')
for v in v1000:
mapping[v] = v
# 替換文字中的低頻詞
alice2 = [mapping[v] for v in alice]
# 列印替換後的文字前100個詞
print(alice2[:100])
# 列印替換後文字的詞彙數量
print(len(set(alice2)))
內容解密:
- 載入文字資料:使用
nltk.corpus.gutenberg.words
載入《愛麗絲夢遊仙境》的文字資料。 - 統計詞頻:使用
nltk.FreqDist
統計文字中的詞頻。 - 建立預設字典:使用
nltk.defaultdict
建立一個預設字典,將低頻詞替換為"UNK"。高頻詞則保持不變。 - 替換文字中的低頻詞:使用列表推導式將文字中的低頻詞替換為"UNK"。
- 列印結果:列印替換後的文字前100個詞和詞彙數量。
增量更新字典
在詞性標注任務中,我們經常需要統計詞性標籤的頻率。我們可以使用nltk.defaultdict
來實作這一功能。
程式碼範例2:增量更新字典統計詞性標籤頻率
import nltk
from nltk.corpus import brown
from operator import itemgetter
# 初始化預設字典,用於統計詞性標籤頻率
counts = nltk.defaultdict(int)
# 載入Brown語料函式庫中的詞性標注資料
for (word, tag) in brown.tagged_words(categories='news'):
counts[tag] += 1
# 列印名詞(N)的頻率
print(counts['N'])
# 按頻率排序詞性標籤
sorted_counts = sorted(counts.items(), key=itemgetter(1), reverse=True)
# 列印排序後的詞性標籤
print(sorted_counts)
# 取得排序後的詞性標籤列表
sorted_tags = [t for t, c in sorted_counts]
print(sorted_tags)
內容解密:
- 初始化預設字典:使用
nltk.defaultdict(int)
初始化一個預設字典,用於統計詞性標籤的頻率。 - 載入詞性標注資料:使用
brown.tagged_words
載入Brown語料函式庫中的詞性標注資料。 - 統計詞性標籤頻率:遍歷詞性標注資料,增量更新預設字典中的詞性標籤頻率。
- 按頻率排序:使用
sorted
函式按頻率排序詞性標籤,並使用itemgetter(1)
指定按頻率排序。 - 列印結果:列印排序後的詞性標籤列表。
複雜鍵值對的使用
在某些情況下,我們需要使用複雜的鍵值對來儲存資料。例如,我們可以使用一個預設字典來儲存詞性標籤和其後續詞彙的頻率。
程式碼範例3:使用複雜鍵值對儲存詞性標籤和後續詞彙的頻率
import nltk
from nltk.corpus import brown
# 初始化預設字典,用於儲存詞性標籤和後續詞彙的頻率
pos = nltk.defaultdict(lambda: nltk.defaultdict(int))
# 載入Brown語料函式庫中的詞性標注資料
brown_news_tagged = brown.tagged_words(categories='news', simplify_tags=True)
# 遍歷詞性標注資料,統計詞性標籤和後續詞彙的頻率
for ((w1, t1), (w2, t2)) in nltk.ibigrams(brown_news_tagged):
pos[(t1, w2)][t2] += 1
# 列印詞性標籤和後續詞彙的頻率
print(pos[('DET', 'right')])
內容解密:
- 初始化預設字典:使用
nltk.defaultdict(lambda: nltk.defaultdict(int))
初始化一個預設字典,用於儲存詞性標籤和其後續詞彙的頻率。 - 載入詞性標注資料:使用
brown.tagged_words
載入Brown語料函式庫中的詞性標注資料。 - 統計詞性標籤和後續詞彙的頻率:遍歷詞性標注資料,增量更新預設字典中的詞性標籤和後續詞彙的頻率。
- 列印結果:列印詞性標籤和後續詞彙的頻率。
Mermaid詞性標注流程圖
graph LR A[文字輸入] --> B[詞性標注] B --> C[統計詞性標籤頻率] C --> D[使用預設字典儲存結果] D --> E[輸出結果]
圖表翻譯: 此圖示展示了詞性標注的流程,包括文字輸入、詞性標注、統計詞性標籤頻率和使用預設字典儲存結果,最終輸出結果。
程式碼註解
在上述程式碼範例中,我們使用了nltk.defaultdict
來實作預設字典的功能。預設字典是一種特殊的字典,它為不存在的鍵提供了一個預設值。在我們的例子中,我們使用了lambda
函式來定義預設值。
例如,在程式碼範例1中,我們使用了nltk.defaultdict(lambda: 'UNK')
來建立一個預設字典,將低頻詞替換為"UNK"。這樣,當我們遇到一個不存在的鍵時,預設字典會自動傳回"UNK"。
同樣地,在程式碼範例2中,我們使用了nltk.defaultdict(int)
來建立一個預設字典,用於統計詞性標籤的頻率。這樣,當我們遇到一個不存在的鍵時,預設字典會自動傳回0。
在程式碼範例3中,我們使用了nltk.defaultdict(lambda: nltk.defaultdict(int))
來建立一個預設字典,用於儲存詞性標籤和其後續詞彙的頻率。這樣,當我們遇到一個不存在的鍵時,預設字典會自動傳回一個新的預設字典,用於儲存後續詞彙的頻率。
透過使用預設字典,我們可以簡化程式碼並提高效率。預設字典是Python中一個非常有用的資料結構,在自然語言處理任務中非常有用。
詞典反轉與自動詞性標注技術解析
在自然語言處理(NLP)領域,詞典(Dictionary)的使用是基礎且關鍵的一環。詞典支援高效的鍵值查詢,但有時我們需要進行反向查詢,即根據值查詢對應的鍵。本文將探討詞典反轉的技術,並進一步介紹自動詞性標注(Automatic Tagging)的相關方法。
詞典反轉技術
詞典是一種鍵值對的資料結構,通常用於快速查詢。在某些情況下,我們需要根據值來查詢鍵,這就需要進行詞典反轉。詞典反轉有兩種主要情況:當所有鍵對應的值都是唯一時,和當多個鍵對應相同的值時。
唯一值情況下的詞典反轉
在鍵值一一對應的情況下,詞典反轉相對簡單。我們可以透過遍歷原詞典的鍵值對,建立一個新的詞典,將原詞典的值作為鍵,鍵作為值。
pos = {'colorless': 'ADJ', 'ideas': 'N', 'sleep': 'V', 'furiously': 'ADV'}
pos2 = dict((value, key) for (key, value) in pos.items())
print(pos2['N']) # 輸出:ideas
多個鍵對應相同值情況下的詞典反轉
當多個鍵對應相同的值時,我們需要將具有相同值的鍵儲存在一個列表中。這時可以使用defaultdict
來實作。
from collections import defaultdict
pos = {'colorless': 'ADJ', 'ideas': 'N', 'sleep': 'V', 'furiously': 'ADV', 'cats': 'N', 'scratch': 'V', 'peacefully': 'ADV', 'old': 'ADJ'}
pos2 = defaultdict(list)
for key, value in pos.items():
pos2[value].append(key)
print(pos2['ADV']) # 輸出:['furiously', 'peacefully']
或者使用NLTK提供的Index
功能:
pos2 = nltk.Index((value, key) for (key, value) in pos.items())
print(pos2['ADV']) # 輸出:['furiously', 'peacefully']
自動詞性標注
自動詞性標注是NLP中的一個重要任務,涉及為文字中的每個詞分配正確的詞性標籤。我們將介紹幾種自動詞性標注的方法。
預設標注器(Default Tagger)
最簡單的標注器是預設標注器,它為每個詞分配相同的標籤。通常,這個標籤是文字中最常見的詞性標籤。
from nltk.corpus import brown
tags = [tag for (word, tag) in brown.tagged_words(categories='news')]
default_tag = nltk.FreqDist(tags).max()
default_tagger = nltk.DefaultTagger(default_tag)
正規表示式標注器(Regular Expression Tagger)
正規表示式標注器根據詞的模式來分配標籤。例如,可以根據詞尾來判斷詞性。
patterns = [
(r'.*ing$', 'VBG'), # 動名詞
(r'.*ed$', 'VBD'), # 過去式
(r'.*es$', 'VBZ'), # 第三人稱單數現在式
(r'.*ould$', 'MD'), # 情態動詞
(r'.*\'s$', 'NN$'), # 所有格名詞
(r'.*s$', 'NNS'), # 複數名詞
(r'^-?[0-9]+(.[0-9]+)?$', 'CD'), # 基數詞
(r'.*', 'NN') # 名詞(預設)
]
regexp_tagger = nltk.RegexpTagger(patterns)
效能評估
評估標注器的效能通常使用正確率指標。
brown_tagged_sents = brown.tagged_sents(categories='news')
default_tagger.evaluate(brown_tagged_sents)
regexp_tagger.evaluate(brown_tagged_sents)
結合多種標注方法
在實際應用中,可以結合多種標注方法來提高準確性。例如,可以先使用正規表示式標注器,然後對未能正確標注的詞使用預設標注器。
詞典反轉未來方向
未來,我們可以進一步探索更高效的詞典反轉演算法,特別是在處理大規模資料時。同時,針對特定領域的詞典反轉技術也將有更廣泛的應用。
自動詞性標注未來方向
自動詞性標注技術將繼續朝著更高準確性和更廣泛的語言覆寫方向發展。深度學習技術的引入將為自動詞性標注帶來新的突破。
參考資料
- NLTK官方檔案
- 《Natural Language Processing with Python》
透過深入理解和應用詞典反轉和自動詞性標注技術,我們可以為NLP領域的研究和應用提供更有力的支援。未來,這些技術將在更多領域展現其價值。