【精通特征工程】學(xué)習(xí)筆記Day2&2.5&D3章&P33-51頁(yè)
3序苏、文本數(shù)據(jù):扁平化、過濾和分塊
3.1 元素袋:將自然文本轉(zhuǎn)換為扁平向量
3.1.1 詞袋
一個(gè)特征就是一個(gè)單詞,一個(gè)特征向量由這個(gè)單詞在每篇文檔中出現(xiàn)的次數(shù)組成
3.1.2 n 元詞袋
n-gram(n 元詞)是由 n 個(gè)標(biāo)記 (token)組成的序列筑公。
1-gram 就是一個(gè)單詞(word),又稱為一元詞(unigram)。
n越大躏救,能表示的信息越豐富,相應(yīng)的成本也會(huì)越高螟蒸。
- eg:計(jì)算 n-gram
>>> import pandas
>>> import json
>>> from sklearn.feature_extraction.text import CountVectorizer
# 加載前10 000條點(diǎn)評(píng)
>>> f = open('data/yelp/v6/yelp_academic_dataset_review.json') >>> js = []
>>> for i in range(10000):
... js.append(json.loads(f.readline()))
>>> f.close()
>>> review_df = pd.DataFrame(js)
# 創(chuàng)建一元詞盒使、二元詞和三元詞的特征轉(zhuǎn)換器。
# 默認(rèn)情況下七嫌,會(huì)忽略單字母詞少办,這非常有實(shí)際意義, # 因?yàn)闀?huì)除去無(wú)意義的詞诵原。但在這個(gè)例子中英妓,
# 出于演示的目的,我們會(huì)顯式地包含這些詞皮假。
>>> bow_converter = CountVectorizer(token_pattern='(?u)\\b\\w+\\b')
>>> bigram_converter = CountVectorizer(ngram_range=(2,2),
... token_pattern='(?u)\\b\\w+\\b')
>>> trigram_converter = CountVectorizer(ngram_range=(3,3),
... token_pattern='(?u)\\b\\w+\\b')
# 擬合轉(zhuǎn)換器鞋拟,查看詞匯表大小
>>> bow_converter.fit(review_df['text'])
>>> words = bow_converter.get_feature_names()
>>> bigram_converter.fit(review_df['text'])
>>> bigrams = bigram_converter.get_feature_names() >>> trigram_converter.fit(review_df['text'])
>>> trigrams = trigram_converter.get_feature_names() >>> print (len(words), len(bigrams), len(trigrams)) 26047 346301 847545
# 看一下n-gram
>>> words[:10]
['0', '00', '000', '0002', '00am', '00ish', '00pm', '01', '01am', '02']
>>> bigrams[-10:]
['zucchinis at',
'zucchinis took',
'zucchinis we',
'zuma over',
'zuppa di',
'zuppa toscana',
'zuppe di',
'zurich and',
'zz top',
'a? la']
>>> trigrams[:10]
['0 10 definitely',
'0 2 also',
'0 25 per',
'0 3 miles',
'0 30 a',
'0 30 everything',
'0 30 lb',
'0 35 tip',
'0 5 curry',
'0 5 pork']
Yelp 數(shù)據(jù)集前 10 000 條點(diǎn)評(píng)中唯一 n-gram 的數(shù)量:
3.2 使用過濾獲取清潔特征
3.2.1 停用詞
停用詞列表
3.2.2 基于頻率的過濾
- 高頻詞
- 罕見詞
3.2.3 詞干提取
- eg:Python 的 NLTK 包運(yùn)行 Porter stemmer 的例子。它適用于很多情況惹资,但不是萬(wàn)能的贺纲。
如:“goes”被映射到了“goe”,而“go”被映射到了它本身褪测。
>>> import nltk
>>> stemmer = nltk.stem.porter.PorterStemmer()
>>> stemmer.stem('flowers')
u'flower'
>>> stemmer.stem('zeroes')
u'zero'
>>> stemmer.stem('stemmer')
u'stem'
>>> stemmer.stem('sixties')
u'sixti'
>>> stemmer.stem('sixty')
u'sixty'
>>> stemmer.stem('goes')
u'goe'
>>> stemmer.stem('go')
u'go'
詞干提取并不是非做不可
3.3 意義的單位:從單詞猴誊、n 元詞到短語(yǔ)
3.3.1 解析與分詞
-
解析
- 半結(jié)構(gòu)化文檔,比如 JSON 字符串或 HTML 頁(yè)面
- 網(wǎng)頁(yè)侮措,那么解析程序還需要處理 URL
- 電子郵件懈叹,像發(fā)件人、收件人和標(biāo)題這些域都需要特殊處理
- 否則這些信息在最終計(jì)數(shù)中就會(huì)和普通詞一樣分扎,也就失去作用了
-
分詞
- 空格
- 標(biāo)點(diǎn)符號(hào)
3.3.2 通過搭配提取進(jìn)行短語(yǔ)檢測(cè)
基于頻率的方法
用于搭配提取的假設(shè)檢驗(yàn)
- 通過似然比檢驗(yàn)這種分析方法來檢測(cè)常見短語(yǔ)的算法如下:
(1) 計(jì)算出所有單詞的出現(xiàn)概率:P(w)澄成。
(2) 對(duì)所有的唯一二元詞,計(jì)算出成對(duì)單詞出現(xiàn)的條件概率:P(w2 | w1)。
(3) 對(duì)所有的唯一二元詞,計(jì)算出似然比 log λ。
(4) 按照似然比為二元詞排序最住。
(5) 將似然比最小的二元詞作為特征霎箍。
- 文本分塊和詞性標(biāo)注
文本分塊要比找出 n 元詞復(fù)雜一些,它要使用基于規(guī)則的模型并基于詞性生成標(biāo)記序列。
為了找出這些短語(yǔ),我們先切分出所有帶詞性的單詞,然后檢查這些標(biāo)記的鄰近詞包吝,找出按詞性組合的詞組,這些詞組又稱為“塊”源葫。將單詞映射到詞性的模型通常與特定的語(yǔ)言有關(guān)诗越。一些開源的 Python 程序庫(kù)(比如 NLTK、spaCy 和
TextBlob)中帶有適用于多種語(yǔ)言的模型臼氨。eg:詞性標(biāo)注和文本分塊
>>> import pandas as pd
>>> import json
# 加載前10條點(diǎn)評(píng)
>>> f = open('data/yelp/v6/yelp_academic_dataset_review.json') >>> js = []
>>> for i in range(10):
... js.append(json.loads(f.readline()))
>>> f.close()
>>> review_df = pd.DataFrame(js)
# 首先使用spaCy中的函數(shù) >>> import spacy
# 預(yù)先加載語(yǔ)言模型
>>> nlp = spacy.load('en')
# 我們可以創(chuàng)建一個(gè)spaCy nlp變量的Pandas序列 >>> doc_df = review_df['text'].apply(nlp)
# spaCy可以使用(.pos_)提供細(xì)粒度的詞性掺喻,
# 使用(.tag_)提供粗粒度的詞性
>>> for doc in doc_df[4]:
... print([doc.text, doc.pos_, doc.tag_])
Got VERB VBP
a DET DT
letter NOUN NN
in ADP IN
the DET DT
mail NOUN NN
last ADJ JJ
week NOUN NN
that ADJ WDT
said VERB VBD
Dr. PROPN NNP
Goldberg PROPN NNP
is VERB VBZ
moving VERB VBG
to ADP IN
Arizona PROPN NNP
to PART TO
take VERB VB
a DET DT
new ADJ JJ
position NOUN NN
there ADV RB
in ADP IN
June PROPN NNP
. PUNCT .
SPACE SP
He PRON PRP
will VERB MD
be VERB VB
missed VERB VBN
very ADV RB
much ADV RB
. PUNCT .
SPACE SP
I PRON PRP
think VERB VBP
finding VERB VBG
a DET DT
new ADJ JJ
doctor NOUN NN
in ADP IN
NYC PROPN NNP
that ADP IN
you PRON PRP
actually ADV RB
like INTJ UH
might VERB MD
almost ADV RB
be VERB VB
as ADV RB
awful ADJ JJ
as ADP IN
trying VERB VBG
to PART TO
find VERB VB
a DET DT
date NOUN NN
! PUNCT .
# spaCy還可以進(jìn)行基本的名詞分塊
>>> print([chunk for chunk in doc_df[4].noun_chunks])
[a letter, the mail, Dr. Goldberg, Arizona, a new position, June, He, I, a new doctor, NYC, you, a date]
#####
# 我們還可以使用TextBlob實(shí)現(xiàn)同樣的特征轉(zhuǎn)換 from textblob import TextBlob
# TextBlob中的默認(rèn)標(biāo)記器使用PatternTagger,在這個(gè)例子中是沒有問題的储矩。 # 你還可以指定使用NLTK標(biāo)記器感耙,它對(duì)于不完整的句子效果更好。
>>> blob_df = review_df['text'].apply(TextBlob)
>>> blob_df[4].tags
[('Got', 'NNP'),
('a', 'DT'),
('letter', 'NN'),
('in', 'IN'),
('the', 'DT'),
('mail', 'NN'),
('last', 'JJ'),
('week', 'NN'),
('that', 'WDT'),
('said', 'VBD'),
('Dr.', 'NNP'),
('Goldberg', 'NNP'),
('is', 'VBZ'),
('moving', 'VBG'),
('to', 'TO'),
('Arizona', 'NNP'),
('to', 'TO'),
('take', 'VB'),
('a', 'DT'),
('new', 'JJ'),
('position', 'NN'),
('there', 'RB'),
('in', 'IN'),
('June', 'NNP'),
('He', 'PRP'),
('will', 'MD'),
('be', 'VB'),
('missed', 'VBN'),
('very', 'RB'),
('much', 'JJ'),
('I', 'PRP'),
('think', 'VBP'),
('finding', 'VBG'),
('a', 'DT'),
('new', 'JJ'),
('doctor', 'NN'),
('in', 'IN'),
('NYC', 'NNP'),
('that', 'IN'),
('you', 'PRP'),
('actually', 'RB'),
('like', 'IN'),
('might', 'MD'),
('almost', 'RB'),
('be', 'VB'),
('as', 'RB'),
('awful', 'JJ'),
('as', 'IN'),
('trying', 'VBG'),
('to', 'TO'),
('find', 'VB'),
('a', 'DT'),
('date', 'NN')]
>>> print([np for np in blob_df[4].noun_phrases])
['got', 'goldberg', 'arizona', 'new position', 'june', 'new doctor', 'nyc']
參考:《精通特征工程》愛麗絲·鄭·阿曼達(dá)·卡薩麗
面向機(jī)器學(xué)習(xí)的特征工程學(xué)習(xí)筆記:
【精通特征工程】學(xué)習(xí)筆記(一)