NLP-基础知识-001
一、文本分析流程
?Pipeline
原始文本(網頁文本、新聞、...) ->? 分詞(中文、英文) -> 清洗(無用的標簽 !¥ 停用詞.....)? -> 標準化(英文時態等) -> 特征提取(tf-idf、word2vec) -> 建模(分類算法、相似度算法) -> 評估過程
二、分詞工具
英文沒有分詞、中文主要以下工具進行分詞
jieba分詞? ? ??https://github.com/fxsjy/jieba
SnowNLP? ? https://github.com/isnowfy/snownlp
HanNLP? ? ? https://github.com/hankcs/HanLP
分詞方法:
(一)最大匹配(Max Matching)
? 前向最大匹配(forward-max matching)
? 例子: 我們經常有意見分歧(輸入) max-len = 5
? 詞典: ["我們","經常","有","有意見","意見","分歧"]
? 流程:
? ? ? ?1、【我們經常有】意見分歧? 未在詞典
? ? ? ? ? ? 【我們經常】有意見分歧
? ? ? ? ? ? 【我們經】常有意見分歧
? ? ? ? ? ? 【我們】經常有意見分歧? 【我們】在詞典中
? ? ? ?2、【經常有意見】-》【經常有意】見 -》【經常有】意見 -> 【經常】有意見
? ? ? ?3、【有意見分歧】-》【有意見分】歧 -》?【有意見】分歧?
? ? ? ?4、【分歧】
? ? ? 分詞結果:我們 | 經常 | 有意見 | 分歧
? ? ? 貪心算法-局部最優? ?動態規劃-全局最優
? ? ? max-len 一般設置為5-10 ,或者畫圖看一下字典里面的詞語長度橫坐標為詞的長度,縱坐標為該詞的長度的個數? ? ?
(二) 后向最大匹配
? ? ?例子: 我們經常有意見分歧
? ? ?詞典: ["我們","經常","有","有意見","意見","分歧"]
? ? ?流程:
? ? ? 1、[有意見分歧] -> [意見分歧] -> [見分歧] -> [分歧]
? ? ? 2、[經常有意見] -> [常有意見] -> [有意見]
? ? ? 3、[我們經常] -> [們經常]? -> [經常]
? ? ? 4、[我們]
? ? 分詞結果: 我們 | 經常 | 有意見 | 分歧
?
? ? 前向匹配和后向匹配結果是一樣的(90%)
? ? 最大匹配的缺點:
? ? ? ? ? ? ? 1)不能考慮短詞語的情況? ?
? ? ? ? ? ? ? 2)? 貪心算法-> 局部最優? ?
? ? ? ? ? ? ? 3)? ?效率比較低 依賴于超參數max-len?
? ? ? ? ? ? ? 4)? 不能更好地處理歧義的情況(不考慮語義)
(三) 基于語義的分詞工具
? ? 例子: 經常有意見分歧
? ? 詞典: 【'有',"有意見","意見",”分歧“,"見","意","經常"】
? ??語言模型
? ? ?輸入? ?---->? ? step 1 -? 生成所有可能的分割 (遞歸 + 匹配)? ----->? ?step 2 - 選擇其中最好的(語言模型)
? ? 語言模型? - unigram model
? ? ?s1: 經常 | 有 | 意見 | 分歧
? ? ?s2: 經常 | 有意見 | 分歧
? ? ?p(s1) = p(經常) * p(有) * p(意見) * p(分歧)
? ? ?p(s2) = p(經常) * p(有意見) * p(分歧)
? ? ?p(s1) >= p(s2)
? ? ?Underflow:數值超出類型范圍的最小值,所以上述概率兩邊需要同時去對數,避免underflow的情況
? ? ?logp(s1) = logp(經常)? + logp(有)? + logp(意見) + log?p(分歧)
? ??p(經常) 、p(有) 、?p(意見) 、?p(分歧) 單詞概率會在所有語料中統計得到
? ?缺點:生成所有分割,可能性太多,效率比較低
(四) 維特比算法
? ?第一步和第二步融合一下,加快效率? ? -----? ? 維特比算法
分詞小結:
? ? ?-? 基于匹配規則的方法
? ? ?-? 基于概率統計的方法(LM,HMM,CRF....)
? ? ?-? 分詞可以認為是已經解決的問題
三、拼寫糾錯(Spell Correction)
? ? ? (一) 識別錯別字
? ? ? ? ? ? 例如:
? ? ? ? ? ? ? ? ? ? ? 用戶輸入:? ?天起? ?-----> 改正------> 天氣
? ? ? ? ? ? ?改正過程具體做法:
? ? ? ? ? ? ?定義三個操作: Add Delete Replace
| 用戶輸入 | 候選 | 編輯距離(Edit Distance) str1 -> str2 |
| therr | there | 1 |
| ? | thesis theirs the ? 詞典 | 2 2 2 ? ...... |
? ? ? ? ? ? 1) query 單詞與詞庫進行匹配? ? ?2)找出編輯距離最小的單詞
Alternative Way:
? ? 之前的方法: 用戶輸入? -->? 從詞典中尋找編輯距離最小的? ? -->? ?返回
? ? 現在的方法: 用戶輸入? -->? 生成編輯距離為1,2的字符串 (Candidate)? ?---> 過濾 (filter)?----> 返回
""" 生成編輯距離為1和2的字符串 """def generate_edit_one(str1):"""給定一個字符串, 生成編輯距離為1的字符串"""letters = 'abcdefghijklmnopqrstuvwxyz'splits = [(str1[:i],str1[i:]) for i in range(len(str1) + 1)]inserts = [L + c + R for L,R in splits for c in letters]deletes = [L + R[1:] for L,R in splits if R]replaces = [L + c + R[1:] for L,R in splits if R for c in letters]return set(inserts + deletes + replaces)def generate_edit_two(str1):"""給定一個字符串,生成編輯距離小于等于2的字符串"""return [e2 for e1 in generate_edit_one(str1) for e2 in generate_edit_one(e1)]? 過濾:
? ? ? 問題定義: 給定一個字符串s, 我們要找出最有可能成為正確的字符串c, 也就是c' = argmaxp(c|s)
? ? ? 簡化:c' = argmax p(c|s)? ? ?=>? ? c' = argmax p(s|c) * p(c) / p(s)? ?(p(s)常數)? =>? ?c' = argmax ?p(s|c) * p(c)
? ? ???p(s|c) 、p(c)基于已有詞庫統計得到
? ? ??
? ? ? (二) 用錯單詞(基于上下文語義-語言模型)??
?
四、過濾詞(Filtering Words)
? ? 對于NLP應用,我們通常先把停用詞、出現頻率很低的詞匯過濾掉
? ? 不同的應用需要修正停用詞庫-類似特征篩選的過程
?
五、Stemming算法 英文用的比較多、中文比較少? one way to normalize
? ? went,go,going
? ? fly,flies
? ? deny,denied,denying
? ? fast,faster,fastest
? ?不同形態單詞歸成一個單詞
"""應用例子"""from nltk.stem.porter import *stemmer = PorterStemmer()test_strs = ['flies','dies']singles = [stemmer.stem(word) for word in test_strs]print(' '.join(singles))六、文本表示(Word Representation)
?文本表示-(單詞表示、句子表示)
one-hot representation詞典:[我們、去、爬山、今天、你們、昨天、跑步]每個單詞的表示:我們: [1,0,0,0,0,0,0] 爬山: [0,0,1,0,0,0,0] 跑步: [0,0,0,0,0,0,1] 昨天: [0,0,0,0,0,1,0]句子的表示方法(sentence representation - boolean):我們 今天 去 爬山: [1,1,1,1,0,0,0] 你們 昨天 跑步: [0,0,0,0,1,1,1] 你們 又 去 爬山 又 去 跑步 : [0,1,1,1,0,1,0,1]句子的表示方法(sentence representation - count):你們 又 去 爬山 又 去 跑步 : [0,2,2,1,0,1,0,1]缺點:1、不考慮單詞順序 2、稀疏矩陣 3、頻繁出現無用的詞為了防止某些無用的詞頻比較大,可以使用log(item+1)Sentence Similarity1、計算距離(歐式距離):d = |s1-s2|s1 = (1,0,1,1,0,0,0,0) s2 = (0,0,0,0,0,1,1,1) d(s1,s2) = (1^2 + 0^2 + .....)^(1/2)歐式距離只考慮大小,不考慮方向,常用的相似度是余弦相似度2、計算相似度(余弦相似度):sim = s1*s2/*(|s1|*|s2|)總結:詞出現的越多并不一定是越重要,并不是出現的越少越不重要解決辦法:不僅需要考慮詞,還需要考慮詞的權重Tf-idf Representationtfidf(w) = tf(d,w)*idf(w)tf(d,w) -次數 文檔d中w的詞頻 idf(w) =log N/N(w) - 詞的重要性N:語料庫中的文檔總數 N(w):詞語W出現在多少個文檔例子:文檔1: 今天 上 NLP 課程 文檔2:今天 的 課程 有 意思 文檔3:數據 課程 也 有 意思step 1: 詞庫的構建dic = {今天,上,NLP, 課程, 的,有,意思,數據,也}從詞典中看,d2 = (1*log3/2,上沒有出現-0,0,1*log3/3,log3/1,log3/2,log3/2,0,0)七、詞向量
語義之間的相似度我們 爬山 運動 昨天我們: [0,1,0,0,0,0] 爬山: [0,0,1,0,0,0] 運動: [1,0,0,0,0,0] 昨天: [0,0,0,1,0,0]1、歐式距離d(我們,爬山) = d(爬山,運動) = ..... = 2^(1/2)說明歐式距離相似度針對one-hot不適合做兩個詞語義之間的相似度的,因為都是2^(1/2)2、余弦距離d(我們,爬山) = d(我們,運動) = d(運動,爬山) = .... = 0 說明余弦相似度針對one-hot不適合做兩個詞語義之間的相似度的,因為都是0所以如果單詞采用one-hot表示,不能表達單詞之間的相似度還存在另一個問題:稀疏性向量的大小是與詞典的大小相同的,如果詞典比較大,句子比較短,會出現大量的0小結:onehot不能表示語義之間的相似性,存在稀疏性從one-hot 表示 到 分布式 表示One-hot 表示:我們: [1,0,0,0,0,0,0] 爬山: [0,0,1,0,0,0,0] 運動: [0,0,0,0,0,0,1] 昨天: [0,0,0,0,0,1,0]分布式表示:我們: [0.1,0.2,0.4,0.2] 爬山: [0.2,0.3,0.7,0.1] 運動: [0.2,0.3,0.6,0.2] 昨天: [0.5,0.9,0.1,0.3]one-hot 向量長度是詞典長度,分布式向量長度是自己定義的長度,可以為100,200,300,解決了稀疏性問題針對分布式表示,計算兩個詞之間的相似度:d(我們,爬山) = (0.12)^(1/2)d(運動,爬山) = (0.02)^(1/2)d(我們,爬山) > d(運動,爬山)分布式表示方法-針對單詞,稱為詞向量(Word2Vec)詞向量是分布式表示方法的一種Q1:100維的One-hot表示法最多可以表達多少個不同的單詞? -100個Q2:100維的分布式表示法最多可以表達多少個不同的單詞? -無數個分布式表示是怎么學習來的?學習詞向量:輸入(Input):字符串(將所有文本的分詞之后的單詞匯總集合) -> 深度模型(Skip-Gram、Glove、CBOW、RNN、LSTM、MF-矩陣分解、Gaussian Embedding)訓練長短 -> 詞的分布式表示 事先需要定義一下詞向量維度詞向量(Word2vec)某種意義上理解成詞的意思(Meaning)從詞向量到句向量:"我們去運動"我們:(0.1,0.2,0.1,0.3) 去:(0.3,0.2,0.15,0.2) 運動:(0.2,0.15,0.4,0.7)"我們去運動" 句子向量:平均法則:sentence_embedding = avg_embedding = (0.6/3,0.55/3,0.65/3,1.2/3) = (0.2,0.18,0.22,0.4)八、QA System
How do you like NLP?Question ----> 相似度匹配 ------> 知識庫(<Question1,answer1>,<Question2,answer2>.....) <---- 返回相似度比較高的 <------存在問題:每個相似度需要計算O(N) 不滿足實時的要求核心思路:層次過濾思想Question -----> 過濾器 ----> 知識庫(<question1,answer1>,<question2,answer2>..) ----> 相似度匹配(<question2,answer2>,<question18,answer18>.....)過濾器主要做法--倒排表背景:搜索引擎爬取文檔例如:四個文檔doc_1、我們、今天、運動 doc_2、我們、昨天、運動 -----> 詞典:[我們、今天、運動、昨天、上、課、什么] ---> 我們:[doc_1,dic_2],今天:[doc_1],運動:[doc_1,doc_2],昨天:[doc_2] ..... doc_3、你們、上課 doc_4、你們、上、什么、課如:百度的搜索引擎:用戶輸入:運動 如果按照原來的方法需要遍歷所有文檔,但是按照倒排表只需要遍歷doc_1,doc_2,按照pagerank值展示出來相關網頁即可用戶輸入句子: 我們 課我們: [doc_1,doc_2] 課:[doc_3,doc_4]我們 & 上課 = None直接返回: [doc_1,doc_2,doc_3,doc_4]"How do you like NLPCamp?"Question -----> 過濾器 ----> 知識庫(<question1,answer1>,<question2,answer2>..) ----> 相似度匹配(<question2,answer2>,<question18,answer18>.....)How do you like => 包含這些詞的Question(原100,篩選之后可能剩余20, 至少包含其中一個單詞) MLPCamp?
?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的NLP-基础知识-001的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu18.04下安装MySQL
- 下一篇: NLP-基础知识-002 (语言模型)