【自然語言處理基礎技能(NLP)】jieba中文文本處理

1.基本分詞函數與用法

# jieba.cut 以及 jieba.cut_for_search 返回的結構都是一個可迭代的 generator,可以使用 for 循環來獲得分詞後得到的每一個詞語(unicode)
# 
# jieba.cut 方法接受三個輸入參數:
# 
# 需要分詞的字符串
# cut_all 參數用來控制是否採用全模式
# HMM 參數用來控制是否使用 HMM 模型
# jieba.cut_for_search 方法接受兩個參數
# 
# 需要分詞的字符串
# 是否使用 HMM 模型。
# 該方法適合用於搜索引擎構建倒排索引的分詞,粒度比較細


#jieba中文文本處理
# encoding=utf-8
import jieba
#jieba.cut和jieba.cut_for_search:返回的是一個可迭代的genertor,可使用for循環獲得分詞後的每一個詞語。
seg_list = jieba.cut("我在學習自然語言處理", cut_all=True)
#print (seg_list)
print("Full Mode: " + "/ ".join(seg_list))  # 全模式

seg_list = jieba.cut("我在學習自然語言處理", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))  # 精確模式

seg_list = jieba.cut("他畢業於上海交通大學,在百度深度學習研究院進行研究")  # 默認是精確模式
print(", ".join(seg_list))

seg_list = jieba.cut_for_search("小明碩士畢業於中國科學院計算所,後在哈佛大學深造")  # 搜索引擎模式
print(", ".join(seg_list))


#jieba.lcut以及jieba.lcut_for_search直接返回 list

result_lcut = jieba.lcut("小明碩士畢業於中國科學院計算所,後在哈佛大學深造")
print(result_lcut) 
print (" ".join(result_lcut))
print (" ".join(jieba.lcut_for_search("小明碩士畢業於中國科學院計算所,後在哈佛大學深造")))


#專業領域的分詞處理:
# 添加用戶自定義詞典
# 很多時候我們需要針對自己的場景進行分詞,會有一些領域內的專有詞彙。
# 
# 1.可以用jieba.load_userdict(file_name)加載用戶字典
# 2.少量的詞彙可以自己用下面方法手動添加:
# 用 add_word(word, freq=None, tag=None) 和 del_word(word) 在程序中動態修改詞典
# 用 suggest_freq(segment, tune=True) 可調節單個詞語的詞頻,使其能(或不能)被分出來。


print('/'.join(jieba.cut('如果放到舊字典中將出錯。', HMM=False)))
jieba.suggest_freq(('中', '將'), True)
print('/'.join(jieba.cut('如果放到舊字典中將出錯。', HMM=False)))

2.關鍵詞提取

      2.1基於 TF-IDF 算法的關鍵詞抽取

   

# 關鍵詞提取
# 基於 TF-IDF 算法的關鍵詞抽取
# import jieba.analyse
# 
# jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
# sentence 爲待提取的文本
# topK 爲返回幾個 TF/IDF 權重最大的關鍵詞,默認值爲 20
# withWeight 爲是否一併返回關鍵詞權重值,默認值爲 False
# allowPOS 僅包括指定詞性的詞,默認值爲空,即不篩選

import jieba.analyse as analyse
#以下代碼犯過錯誤:1.文件路徑問題 2.編碼問題,txt爲gbk格式文件,需要先轉化爲utf-8格式,才能拿過來用。
lines = open('E:/DMtest/Jupytertest/NBA.txt',encoding='utf-8').read()

print ("  ".join(analyse.extract_tags(lines, topK=20, withWeight=False, allowPOS=())))

#注意:以下文件操作出項過錯誤:txt自身文件不爲utf-8時,需要採用另存爲的方式改爲utf-8
lines1 = open('E:/DMtest/Jupytertest/西遊記.txt',encoding='utf-8').read()
print ("  ".join(analyse.extract_tags(lines1, topK=20, withWeight=False, allowPOS=())))

 

import jieba
import jieba.analyse
#讀取文件,返回一個字符串,使用utf-8編碼方式讀取,該文檔位於此python同以及目錄下
content  = open('人民的名義.txt','r',encoding='utf-8').read()
tags = jieba.analyse.extract_tags(content,topK=10) 
print(",".join(tags))

 

      2.2關於TF-IDF 算法的關鍵詞抽取補充

基本概念理解:

      背景:有一篇很長的文章,我要用計算機提取它的關鍵詞(Automatic Keyphrase extraction),完全不加以人工干預,請問怎樣才能正確做到?這個問題涉及到數據挖掘、文本處理、信息檢索等很多計算機前沿領域,但是出乎意料的是,有一個非常簡單的經典算法,可以給出令人相當滿意的結果。它簡單到都不需要高等數學,普通人只用10分鐘就可以理解,這就是我今天想要介紹的TF-IDF算法。讓我們從一個實例開始講起。假定現在有一篇長文《中國的蜜蜂養殖》,我們準備用計算機提取它的關鍵詞。
    詞頻:停用詞:逆文檔頻率:

    一個容易想到的思路,就是找到出現次數最多的詞。如果某個詞很重要,它應該在這篇文章中多次出現。於是,我們進行"詞頻"(Term Frequency,縮寫爲TF)統計。結果你肯定猜到了,出現次數最多的詞是—-“的”、”是”、”在”—-這一類最常用的詞。它們叫做"停用詞"(stop words),表示對找到結果毫無幫助、必須過濾掉的詞。假設我們把它們都過濾掉了,只考慮剩下的有實際意義的詞。這樣又會遇到了另一個問題,我們可能發現”中國”、”蜜蜂”、”養殖”這三個詞的出現次數一樣多。這是不是意味着,作爲關鍵詞,它們的重要性是一樣的?顯然不是這樣。因爲"中國"是很常見的詞,相對而言,"蜜蜂"和"養殖"不那麼常見。如果這三個詞在一篇文章的出現次數一樣多,有理由認爲,”蜜蜂”和”養殖”的重要程度要大於”中國”,也就是說,在關鍵詞排序上面,”蜜蜂”和”養殖”應該排在”中國”的前面。所以,我們需要一個重要性調整係數,衡量一個詞是不是常見詞。如果某個詞比較少見,但是它在這篇文章中多次出現,那麼它很可能就反映了這篇文章的特性,正是我們所需要的關鍵詞。用統計學語言表達,就是在詞頻的基礎上,要對每個詞分配一個”重要性”權重。最常見的詞(”的”、”是”、”在”)給予最小的權重,較常見的詞(”中國”)給予較小的權重,較少見的詞(”蜜蜂”、”養殖”)給予較大的權重。這個權重叫做"逆文檔頻率"(Inverse Document Frequency,縮寫爲IDF),它的大小與一個詞的常見程度成反比。知道了”詞頻”(TF)和”逆文檔頻率”(IDF)以後,將這兩個值相乘,就得到了一個詞的TF-IDF值。某個詞對文章的重要性越高,它的TF-IDF值就越大。所以,排在最前面的幾個詞,就是這篇文章的關鍵詞。

   計算:

第一步,計算詞頻。

考慮到文章有長短之分,爲了便於不同文章的比較,進行”詞頻”標準化,這樣就使用一個比例來減少了每篇文章數量不一致的影響。

或者

第二步,計算逆文檔頻率。
這時,需要一個語料庫(corpus),用來模擬語言的使用環境。

如果一個詞越常見,那麼分母就越大,逆文檔頻率就越小越接近0。分母之所以要加1,是爲了避免分母爲0(即所有文檔都不包含該詞)。log表示對得到的值取對數。附一個wiki百科對數的鏈接

第三步,計算TF-IDF。


可以看到,TF-IDF與一個詞在文檔中的出現次數成正比,與該詞在整個語言中的出現次數成反比。所以,自動提取關鍵詞的算法就很清楚了,就是計算出文檔的每個詞的TF-IDF值,然後按降序排列,取排在最前面的幾個詞。

 

關鍵詞提取所使用逆向文件頻率(IDF)文本語料庫可以切換成自定義語料庫的路徑

  • 用法: jieba.analyse.set_idf_path(file_name) # file_name爲自定義語料庫的路徑

    自定義語料庫示例
勞動防護 13.900677652 勞動防護 13.900677652 生化學 13.900677652 生化學 13.900677652 奧薩貝爾 13.900677652 奧薩貝爾 13.900677652 考察隊員 13.900677652 考察隊員 13.900677652 崗上 11.5027823792 崗上 11.5027823792 倒車檔 12.2912397395 倒車檔 12.2912397395 編譯 9.21854642485 編譯 9.21854642485 蝶泳 11.1926274509 外委 11.8212361103

 

import jieba
import jieba.analyse
#讀取文件,返回一個字符串,使用utf-8編碼方式讀取,該文檔位於此python同以及目錄下
content  = open('idf.txt.big','r',encoding='utf-8').read()
tags = jieba.analyse.extract_tags(content, topK=10)
print(",".join(tags))

 

關鍵詞提取所使用停止詞(Stop Words)文本語料庫可以切換成自定義語料庫的路徑

  • 用法: jieba.analyse.set_stop_words(file_name) # file_name爲自定義語料庫的路徑
  • 自定義語料庫示例:
!
"
#
$
%
&
'
(
)
*
+
,
-
--
.
..
...
......
...................
./
.一
記者
數
年
月
日
時
分
秒
/
//
0
1
2
3
4

 

import jieba
import jieba.analyse
#讀取文件,返回一個字符串,使用utf-8編碼方式讀取,該文檔位於此python同以及目錄下
content  = open(u'人民的名義.txt','r',encoding='utf-8').read()
jieba.analyse.set_stop_words("stopwords.txt")
tags = jieba.analyse.extract_tags(content, topK=10)
print(",".join(tags))

關鍵詞一併返回關鍵詞權重值示例

 

import jieba
import jieba.analyse
#讀取文件,返回一個字符串,使用utf-8編碼方式讀取,該文檔位於此python同以及目錄下
content  = open(u'人民的名義.txt','r',encoding='utf-8').read()
jieba.analyse.set_stop_words("stopwords.txt")
tags = jieba.analyse.extract_tags(content, topK=10,withWeight=True)
for tag in tags:
	print("tag:%s\t\t weight:%f"%(tag[0],tag[1]))

         2.3.基於 TextRank 算法的關鍵詞抽取

1.基本介紹:

TextRank 算法是一種用於文本的基於圖的排序算法,通過把文本分割成若干組成單元(句子),構建節點連接圖,用句子之間的相似度作爲邊的權重,通過循環迭代計算句子的TextRank值,最後抽取排名高的句子組合成文本摘要。本文介紹了抽取型文本摘要算法TextRank,並使用Python實現TextRank算法在多篇單領域文本數據中抽取句子組成摘要的應用。

文本摘要可以大致分爲兩類——抽取型摘要和抽象型摘要:

  • 抽取型摘要:這種方法依賴於從文本中提取幾個部分,例如短語、句子,把它們堆疊起來創建摘要。因此,這種抽取型的方法最重要的是識別出適合總結文本的句子。

  • 抽象型摘要:這種方法應用先進的NLP技術生成一篇全新的總結。可能總結中的文本甚至沒有在原文中出現。

本文,我們將關注於抽取式摘要方法。

2.引入:

在開始使用TextRank算法之前,我們還應該熟悉另一種算法——PageRank算法。事實上它啓發了TextRank!PageRank主要用於對在線搜索結果中的網頁進行排序。讓我們通過一個例子快速理解這個算法的基礎。

PageRank算法簡介:

圖 1 PageRank算法

假設我們有4個網頁——w1,w2,w3,w4。這些頁面包含指向彼此的鏈接。有些頁面可能沒有鏈接,這些頁面被稱爲懸空頁面。

  • w1有指向w2、w4的鏈接

  • w2有指向w3和w1的鏈接

  • w4僅指向w1

  • w3沒有指向的鏈接,因此爲懸空頁面

爲了對這些頁面進行排名,我們必須計算一個稱爲PageRank的分數。這個分數是用戶訪問該頁面的概率。

爲了獲得用戶從一個頁面跳轉到另一個頁面的概率,我們將創建一個正方形矩陣M,它有n行和n列,其中n是網頁的數量。

矩陣中得每個元素表示從一個頁面鏈接進另一個頁面的可能性。比如,如下高亮的方格包含的是從w1跳轉到w2的概率。

如下是概率初始化的步驟:

1. 從頁面i連接到頁面j的概率,也就是M[i][j],初始化爲1/頁面i的出鏈接總數wi 

2. 如果頁面i沒有到頁面j的鏈接,那麼M[i][j]初始化爲0

3. 如果一個頁面是懸空頁面,那麼假設它鏈接到其他頁面的概率爲等可能的,因此M[i][j]初始化爲1/頁面總數

因此在本例中,矩陣M初始化後如下:

最後,這個矩陣中的值將以迭代的方式更新,以獲得網頁排名。

3.TextRank算法

現在我們已經掌握了PageRank,讓我們理解TextRank算法。我列舉了以下兩種算法的相似之處:

  • 用句子代替網頁

  • 任意兩個句子的相似性等價於網頁轉換概率

  • 相似性得分存儲在一個方形矩陣中,類似於PageRank的矩陣M

TextRank算法是一種抽取式的無監督的文本摘要方法。讓我們看一下我們將遵循的TextRank算法的流程:

1. 第一步是把所有文章整合成文本數據

2. 接下來把文本分割成單個句子

3. 然後,我們將爲每個句子找到向量表示(詞向量)。

4. 計算句子向量間的相似性並存放在矩陣中

5. 然後將相似矩陣轉換爲以句子爲節點、相似性得分爲邊的圖結構,用於句子TextRank計算。

6. 最後,一定數量的排名最高的句子構成最後的摘要。

4.實踐

我決定設計一個系統,通過掃描多篇文章爲我提供一個要點整合的摘要。如何着手做這件事?這就是我將在本教程中向大家展示的內容。我們將在一個爬取得到的文章集合的文本數據集上應用TextRank算法,以創建一個漂亮而簡潔的文章摘要。

數據集下載鏈接:

https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2018/10/tennis_articles_v4.csv

 

 

import numpy as np
import pandas as pd
import nltk
# 理解nltk.download('punkt'):
# 要下載特定的數據集/模型,請使用nltk.download()函數,例如如果您要下載punkt句子標記生成器,請使用:
# $python3
# >>> import nltk
# >>> nltk.download('punkt')
nltk.download('punkt')
import re
#讀取數據
df=pd.read_csv('tennis_articles_v4.csv')
#輸出,查看數據
print(df.head())
print(df['article_text'][0])
print(df['article_text'][1])
print(df['article_text'][2])

#將文本分割爲單個句子
from nltk.tokenize import sent_tokenize
sentences=[]
for s in df['article_text']:
    sentences.append(sent_tokenize(s))

sentences=[y for x in sentences for y in x]
#打印查看:
print('sentences[:5]')

# GloVe詞向量是單詞的向量表示。這些詞向量將用於生成表示句子的特徵向量。我們也可以使用Bag-of-Words或TF-IDF方法來爲句子生成特徵,但這些方法忽略了單詞的順序,並且通常這些特徵的數量非常大。
# 我們將使用預訓練好的Wikipedia 2014 + Gigaword 5 (補充鏈接)GloVe向量,文件大小是822 MB。
# GloVe詞向量下載鏈接:
# https://nlp.stanford.edu/data/glove.6B.zip
#提取詞向量:
word_embeddings={}
f=open('glove.6B.100d.txt',encoding='utf-8')
for line in f:
    values=line.split()
    word=values[0]
    coefs=np.asarray(values[1:],dtype='float32')
    word_embeddings[word]=coefs
f.close()
print(len(word_embeddings))

#文本預處理:
#儘可能減少文本數據的噪聲是一個好習慣,所以我們做一些基本的文本清洗(包括移除標點符號、數字、特殊字符,統一成小寫字母)。
clean_sentences=pd.Series(sentences).str.replace("[^a-zA-Z]"," ")
clean_sentences=[s.lower() for s in clean_sentences]
#去掉句子中出現的停用詞(一種語言的常用詞——is,am,of,in等)。如果尚未下載nltk-stop,則執行以下代碼行:
nltk.download('stopwords')
#導入停用詞:
from nltk.corpus import stopwords
stopwords=stopwords.words('english')
#定義移除我們的數據集中停用詞的函數
def remove_stopwords(sen):
    sen_new=" ".join([i for i in sen if i not in stopwords])
    return sen_new
#將在GloVe詞向量的幫助下用clean_sentences(程序中用來保存句子的列表變量)來爲我們的數據集生成特徵向量。
clean_sentences=[remove_stopwords(r.split()) for r in clean_sentences]

#句子的特徵向量
#現在,來爲我們的句子生成特徵向量。我們首先獲取每個句子的所有組成詞的向量(從GloVe詞向量文件中獲取,每個向量大小爲100個元素),然後取這些向量的平均值,得出這個句子的合併向量爲這個句子的特徵向量。
sentence_vectors=[]
for i in clean_sentences:
    if len(i) != 0:
        v=sum([word_embeddings.get(w,np.zeros((100,))) for w in i.split()])/(len(i.split())+0.001)
    else:
        v=np.zeros((100,))
    sentence_vectors.append(v)

#相似矩陣準備
#下一步是找出句子之間的相似性,我們將使用餘弦相似性來解決這個問題。讓我們爲這個任務創建一個空的相似度矩陣,並用句子的餘弦相似度填充它。
#首先定義一個n乘n的零矩陣,然後用句子間的餘弦相似度填充矩陣,這裏n是句子的總數。
sim_mat=np.zeros([len(sentences),len(sentences)])
#用餘弦相似度計算兩個句子之間的相似度。
from sklearn.metrics.pairwise import  cosine_similarity
#用餘弦相似度初始化這個相似度矩陣。
for i in range(len(sentences)):
    for j in range(len(sentences)):
        if i!=j:
            sim_mat[i][j]=cosine_similarity(sentence_vectors[i].reshape(1,100),sentence_vectors[j].reshape(1,100))[0,0]


# 應用PageRank算法
#
# 在進行下一步之前,我們先將相似性矩陣sim_mat轉換爲圖結構。這個圖的節點爲句子,邊用句子之間的相似性分數表示。在這個圖上,我們將應用PageRank算法來得到句子排名。
import networkx as nx
nx_graph=nx.from_numpy_array(sim_mat)
scores=nx.pagerank(nx_graph)
# 摘要提取
# 最後,根據排名提取前N個句子,就可以用於生成摘要了。
ranked_sentences=sorted(((scores[i],s) for i,s in enumerate(sentences)),reverse=True)

for i in range(10):
    print(ranked_sentences[i][1])

結果顯示:

[nltk_data] Downloading package punkt to
[nltk_data]     C:\Users\帥比\AppData\Roaming\nltk_data...
[nltk_data]   Package punkt is already up-to-date!
   article_id  ...                                             source
0           1  ...  https://www.tennisworldusa.org/tennis/news/Mar...
1           2  ...  http://www.tennis.com/pro-game/2018/10/copil-s...
2           3  ...  https://scroll.in/field/899938/tennis-roger-fe...
3           4  ...  http://www.tennis.com/pro-game/2018/10/nishiko...
4           5  ...  https://www.express.co.uk/sport/tennis/1036101...

[5 rows x 3 columns]
Maria Sharapova has basically no friends as tennis players on the WTA Tour. The Russian player has no problems in openly speaking about it and in a recent interview she said: 'I don't really hide any feelings too much. I think everyone knows this is my job here. When I'm on the courts or when I'm on the court playing, I'm a competitor and I want to beat every single person whether they're in the locker room or across the net.So I'm not the one to strike up a conversation about the weather and know that in the next few minutes I have to go and try to win a tennis match. I'm a pretty competitive girl. I say my hellos, but I'm not sending any players flowers as well. Uhm, I'm not really friendly or close to many players. I have not a lot of friends away from the courts.' When she said she is not really close to a lot of players, is that something strategic that she is doing? Is it different on the men's tour than the women's tour? 'No, not at all. I think just because you're in the same sport doesn't mean that you have to be friends with everyone just because you're categorized, you're a tennis player, so you're going to get along with tennis players. I think every person has different interests. I have friends that have completely different jobs and interests, and I've met them in very different parts of my life. I think everyone just thinks because we're tennis players we should be the greatest of friends. But ultimately tennis is just a very small part of what we do. There are so many other things that we're interested in, that we do.'
BASEL, Switzerland (AP), Roger Federer advanced to the 14th Swiss Indoors final of his career by beating seventh-seeded Daniil Medvedev 6-1, 6-4 on Saturday. Seeking a ninth title at his hometown event, and a 99th overall, Federer will play 93th-ranked Marius Copil on Sunday. Federer dominated the 20th-ranked Medvedev and had his first match-point chance to break serve again at 5-1. He then dropped his serve to love, and let another match point slip in Medvedev's next service game by netting a backhand. He clinched on his fourth chance when Medvedev netted from the baseline. Copil upset expectations of a Federer final against Alexander Zverev in a 6-3, 6-7 (6), 6-4 win over the fifth-ranked German in the earlier semifinal. The Romanian aims for a first title after arriving at Basel without a career win over a top-10 opponent. Copil has two after also beating No. 6 Marin Cilic in the second round. Copil fired 26 aces past Zverev and never dropped serve, clinching after 2 1/2 hours with a forehand volley winner to break Zverev for the second time in the semifinal. He came through two rounds of qualifying last weekend to reach the Basel main draw, including beating Zverev's older brother, Mischa. Federer had an easier time than in his only previous match against Medvedev, a three-setter at Shanghai two weeks ago.
Roger Federer has revealed that organisers of the re-launched and condensed Davis Cup gave him three days to decide if he would commit to the controversial competition. Speaking at the Swiss Indoors tournament where he will play in Sundays final against Romanian qualifier Marius Copil, the world number three said that given the impossibly short time frame to make a decision, he opted out of any commitment. "They only left me three days to decide", Federer said. "I didn't to have time to consult with all the people I had to consult. "I could not make a decision in that time, so I told them to do what they wanted." The 20-time Grand Slam champion has voiced doubts about the wisdom of the one-week format to be introduced by organisers Kosmos, who have promised the International Tennis Federation up to $3 billion in prize money over the next quarter-century. The competition is set to feature 18 countries in the November 18-24 finals in Madrid next year, and will replace the classic home-and-away ties played four times per year for decades. Kosmos is headed by Barcelona footballer Gerard Pique, who is hoping fellow Spaniard Rafael Nadal will play in the upcoming event. Novak Djokovic has said he will give precedence to the ATP's intended re-launch of the defunct World Team Cup in January 2020, at various Australian venues. Major players feel that a big event in late November combined with one in January before the Australian Open will mean too much tennis and too little rest. Federer said earlier this month in Shanghai in that his chances of playing the Davis Cup were all but non-existent. "I highly doubt it, of course. We will see what happens," he said. "I do not think this was designed for me, anyhow. This was designed for the future generation of players." Argentina and Britain received wild cards to the new-look event, and will compete along with the four 2018 semi-finalists and the 12 teams who win qualifying rounds next February. "I don't like being under that kind of pressure," Federer said of the deadline Kosmos handed him.
sentences[:5]
400000
[nltk_data] Downloading package stopwords to
[nltk_data]     C:\Users\帥比\AppData\Roaming\nltk_data...
[nltk_data]   Package stopwords is already up-to-date!
When I'm on the courts or when I'm on the court playing, I'm a competitor and I want to beat every single person whether they're in the locker room or across the net.So I'm not the one to strike up a conversation about the weather and know that in the next few minutes I have to go and try to win a tennis match.
Major players feel that a big event in late November combined with one in January before the Australian Open will mean too much tennis and too little rest.
Speaking at the Swiss Indoors tournament where he will play in Sundays final against Romanian qualifier Marius Copil, the world number three said that given the impossibly short time frame to make a decision, he opted out of any commitment.
"I felt like the best weeks that I had to get to know players when I was playing were the Fed Cup weeks or the Olympic weeks, not necessarily during the tournaments.
Currently in ninth place, Nishikori with a win could move to within 125 points of the cut for the eight-man event in London next month.
He used his first break point to close out the first set before going up 3-0 in the second and wrapping up the win on his first match point.
The Spaniard broke Anderson twice in the second but didn't get another chance on the South African's serve in the final set.
"We also had the impression that at this stage it might be better to play matches than to train.
The competition is set to feature 18 countries in the November 18-24 finals in Madrid next year, and will replace the classic home-and-away ties played four times per year for decades.
Federer said earlier this month in Shanghai in that his chances of playing the Davis Cup were all but non-existent.

Process finished with exit code 0

實踐總結:

1.導入所需要的庫

2.讀入數據

3.檢查數據

4.將文本分割成句子

5.下載GloVe詞彙量

     GloVe詞向量下載鏈接:

     https://nlp.stanford.edu/data/glove.6B.zip

6.文本預處理

7.句子特徵向量處理

8.相似矩陣準備

9.應用PageRank算法

10.提取摘要

 

拓展待研究:

1. 問題導向:

  • 多領域文本摘要

  • 單個文檔的摘要

  • 跨語言文本摘要

    (文本來源是一種語言,文本總結用另一種語言)

2. 算法導向:

  • 應用RNN和LSTM的文本摘要

  • 應用加強學習的文本摘要

  • 應用生成對抗神經網絡(GAN)的文本摘要

 

3.詞性標註


# jieba.posseg.POSTokenizer(tokenizer=None) 新建自定義分詞器,tokenizer 參數可指定內部使用的 jieba.Tokenizer 分詞器。jieba.posseg.dt 爲默認詞性標註分詞器。
# 標註句子分詞後每個詞的詞性,採用和 ictclas 兼容的標記法。
# 具體的詞性對照表參見計算所漢語詞性標記集

import jieba.posseg as pseg
words = pseg.cut("我愛自然語言處理")
for word, flag in words:
    print('%s %s' % (word, flag))

 

我 r
愛 v
自然語言 l
處理 v

計算所漢語詞性標記集:

計算所漢語詞性標記集
Version 3.0

0. 說明
計算所漢語詞性標記集(共計99個,22個一類,66個二類,11個三類)主要用於中國科學院計算技術研究所研製的漢語詞法分析器、句法分析器和漢英機器翻譯系統。本標記集主要參考了以下詞性標記集:
1.   北大《人民日報》語料庫詞性標記集;
2.   北大2002新版詞性標記集(草稿);
3.   清華大學漢語樹庫詞性標記集;
4.   教育部語用所詞性標記集(國家推薦標準草案2002版);
5.   美國賓州大學中文樹庫(ChinesePennTreeBank)詞性標記集;
由於計算所的漢語詞法分析器主要採用北大《人民日報》語料庫進行參數訓練,因此本
詞性標記集主要以北大《人民日報》語料庫的詞性標記集爲藍本,並參考了北大《漢語語法信息詞典》中給出的漢語詞的語法信息。
本標記集在制定過程中主要考慮了以下幾方面的因素:
1.       有助於提高漢語詞法分析器的切分和標註正確率;
2.       有助於提高漢語句法分析器的正確率;
3.       有助於漢英機器翻譯系統進行翻譯;
4.       易於從北大《人民日報》語料庫詞性標記集進行轉換;
5.       對於語法功能不同的詞,在不造成詞法分析和句法分析歧義區分困難的情況下,儘可能細分子類。

基於以上考慮,我們在標註過程中儘量避免那些容易出錯的詞性標記,而採用那些不容易出錯、而對提高漢語詞法句法分析正確率有明顯作用的標記。例如,在動詞的子類中,我們參考了賓州大學中文樹庫的做法,把漢語動詞“是”和“有”分別做成單獨的標記,而沒有采用“系動詞”的標記。因爲同樣是“是”這個動詞,其句法功能很多,作“系動詞”只是其中一種功能,而要區分這些功能是非常困難的,會導致詞法分析的正確率下降。

在名詞子類中,我們區分了“漢語人名”、“日語人名”和“翻譯人名”,這不僅僅是因爲這三種人名要採用不同的參數進行訓練與識別,而且在漢英機器翻譯中也要採用不同的分析算法進行翻譯。又如,我們把表示時間的“數詞+‘年’”(如“1995年”)合併成一個時間詞,而表示年頭的“數詞+‘年’”分別標註爲“數詞”和“量詞”,這是因爲我們通過實驗發現這種區分在詞法分析階段通過統計方法可以達到較高的正確率,而且這種區分對於後續的句法分析和機器翻譯有非常重要的作用。

對於某些詞類(助詞和標點符號),基本上是一個封閉集,而這些詞類中各個詞的語法功能相差很大,在這種情況下,我們儘可能地細分其子類。

另外,與其他詞性標記集類似,在我們的標記體系中,小類只是大類中一些有必要區分的一些特例,但小類的劃分不滿足完備性。

1. 名詞  (1個一類,7個二類,5個三類)
名詞分爲以下子類:
n 名詞
nr 人名
nr1 漢語姓氏
nr2 漢語名字
nrj 日語人名
nrf 音譯人名
ns 地名
nsf 音譯地名
nt 機構團體名
nz 其它專名
nl 名詞性慣用語
ng 名詞性語素
2. 時間詞(1個一類,1個二類)
t 時間詞
tg 時間詞性語素
. 處所詞(1個一類)
s 處所詞
4. 方位詞(1個一類)
f 方位詞
5. 動詞(1個一類,9個二類)
v 動詞
vd 副動詞
vn 名動詞
vshi 動詞“是”
vyou 動詞“有”
vf 趨向動詞
vx 形式動詞
vi 不及物動詞(內動詞)
vl 動詞性慣用語
vg 動詞性語素
6. 形容詞(1個一類,4個二類)
a 形容詞
ad 副形詞
an 名形詞
ag 形容詞性語素
al 形容詞性慣用語
7.  區別詞(1個一類,2個二類)
b 區別詞
bl 區別詞性慣用語
8. 狀態詞(1個一類)
z 狀態詞
9. 代詞(1個一類,4個二類,6個三類)
r 代詞
rr 人稱代詞
rz 指示代詞
rzt 時間指示代詞
rzs 處所指示代詞
rzv 謂詞性指示代詞
ry 疑問代詞
ryt 時間疑問代詞
rys 處所疑問代詞
ryv 謂詞性疑問代詞
rg 代詞性語素
10. 數詞(1個一類,1個二類)
m 數詞
mq 數量詞
11.量詞(1個一類,2個二類)
q 量詞
qv 動量詞
qt 時量詞
12.  副詞(1個一類)
d 副詞
13.介詞(1個一類,2個二類)
p 介詞
pba 介詞“把”
pbei 介詞“被”
14. 連詞(1個一類,1個二類)
c 連詞
    cc 並列連詞
15. 助詞(1個一類,15個二類)
u 助詞
uzhe 着
ule 了 嘍
uguo 過
ude1 的 底
ude2 地
ude3 得
usuo 所
udeng 等 等等 云云
uyy 一樣 一般 似的 般
udh 的話
uls 來講 來說 而言 說來
uzhi 之
ulian 連 (“連小學生都會”)
16.  嘆詞(1個一類)
e 嘆詞
17. 語氣詞(1個一類)
y 語氣詞(delete yg)
18. 擬聲詞(1個一類)
o 擬聲詞
19.前綴(1個一類)
h 前綴
20.  後綴(1個一類)
k 後綴
21. 字符串(1個一類,2個二類)
x 字符串
    xe  Email字符串
xs 微博會話分隔符
xm 表情符合
xu 網址URL
22.標點符號(1個一類,16個二類)
w 標點符號
wkz 左括號,全角:( 〔  [  {  《 【  〖 〈   半角:( [ { <
wky 右括號,全角:) 〕  ] } 》  】 〗 〉 半角: ) ] { >
wyz 左引號,全角:“ ‘ 『 
wyy 右引號,全角:” ’ 』
wj 句號,全角:。
ww 問號,全角:? 半角:?
wt 歎號,全角:! 半角:!
wd 逗號,全角:, 半角:,
wf 分號,全角:; 半角: ;
wn 頓號,全角:、
wm 冒號,全角:: 半角: :
ws 省略號,全角:……  …
wp 破折號,全角:――   --   ――-   半角:---  ----
wb 百分號千分號,全角:% ‰   半角:%
wh 單位符號,全角:¥ $ £  °  ℃  半角:$

 

4.並行分詞

【本部分未進行實踐:(設備有要求)】

原理:將目標文本按行分隔後,把各行文本分配到多個 Python 進程並行分詞,然後歸併結果,從而獲得分詞速度的可觀提升 基於 python 自帶的 multiprocessing 模塊,目前暫不支持 Windows

用法:

jieba.enable_parallel(4) # 開啓並行分詞模式,參數爲並行進程數
jieba.disable_parallel() # 關閉並行分詞模式

實驗結果:在 4 核 3.4GHz Linux 機器上,對金庸全集進行精確分詞,獲得了 1MB/s 的速度,是單進程版的 3.3 倍。

注意:並行分詞僅支持默認分詞器 jieba.dt 和 jieba.posseg.dt。

import sys
import time
import jieba

jieba.enable_parallel()
content = open(u'西遊記.txt',"r").read()
t1 = time.time()
words = "/ ".join(jieba.cut(content))
t2 = time.time()
tm_cost = t2-t1
print('並行分詞速度爲 %s bytes/second' % (len(content)/tm_cost))

jieba.disable_parallel()
content = open(u'西遊記.txt',"r").read()
t1 = time.time()
words = "/ ".join(jieba.cut(content))
t2 = time.time()
tm_cost = t2-t1
print('非並行分詞速度爲 %s bytes/second' % (len(content)/tm_cost))

5.Tokenize:返回詞語在原文的起止位置

#注意,輸入參數只接受 unicode
import jieba
print ("這是默認模式的tokenize")
result = jieba.tokenize(u'自然語言處理非常有用')
for tk in result:
    print("%s\t\t start: %d \t\t end:%d" % (tk[0],tk[1],tk[2]))

print ("\n-----------我是神奇的分割線------------\n")

print ("這是搜索模式的tokenize")
result = jieba.tokenize(u'自然語言處理非常有用', mode='search')
for tk in result:
    print("%s\t\t start: %d \t\t end:%d" % (tk[0],tk[1],tk[2]))

 

這是默認模式的tokenize
自然語言		 start: 0 		 end:4
處理		 start: 4 		 end:6
非常		 start: 6 		 end:8
有用		 start: 8 		 end:10

-----------我是神奇的分割線------------

這是搜索模式的tokenize
自然		 start: 0 		 end:2
語言		 start: 2 		 end:4
自然語言		 start: 0 		 end:4
處理		 start: 4 		 end:6
非常		 start: 6 		 end:8
有用		 start: 8 		 end:10

6.ChineseAnalyzer for Whoosh 搜索引擎

from jieba.analyse import ChineseAnalyzer

# -*- coding: UTF-8 -*-
from __future__ import unicode_literals
import sys,os
sys.path.append("../")
from whoosh.index import create_in,open_dir
from whoosh.fields import *
from whoosh.qparser import QueryParser

analyzer = jieba.analyse.ChineseAnalyzer()
schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT(stored=True, analyzer=analyzer))
    
if not os.path.exists("tmp"):
    os.mkdir("tmp")

ix = create_in("tmp", schema) # for create new index
#ix = open_dir("tmp") # for read only
writer = ix.writer()

writer.add_document(
    title="document1",
    path="/a",
    content="This is the first document we’ve added!"
)

writer.add_document(
    title="document2",
    path="/b",
    content="The second one 你 中文測試中文 is even more interesting! 喫水果"
)

writer.add_document(
    title="document3",
    path="/c",
    content="買水果然後來世博園。"
)

writer.add_document(
    title="document4",
    path="/c",
    content="工信處女幹事每月經過下屬科室都要親口交代24口交換機等技術性器件的安裝工作"
)

writer.add_document(
    title="document4",
    path="/c",
    content="咱倆交換一下吧。"
)

writer.commit()
searcher = ix.searcher()
parser = QueryParser("content", schema=ix.schema)

for keyword in ("水果世博園","你","first","中文","交換機","交換"):
    print(keyword+"的結果爲如下:")
    q = parser.parse(keyword)
    results = searcher.search(q)
    for hit in results:
        print(hit.highlights("content"))
    print("\n--------------我是神奇的分割線--------------\n")

for t in analyzer("我的好朋友是李明;我愛北京天安門;IBM和Microsoft; I have a dream. this is intetesting and interested me a lot"):
    print(t.text)
水果世博園的結果爲如下:
買<b class="match term0">水果</b>然後來<b class="match term1">世博園</b>

--------------我是神奇的分割線--------------

你的結果爲如下:
second one <b class="match term0">你</b> 中文測試中文 is even more interesting

--------------我是神奇的分割線--------------

first的結果爲如下:
<b class="match term0">first</b> document we’ve added

--------------我是神奇的分割線--------------

中文的結果爲如下:
second one 你 <b class="match term0">中文</b>測試<b class="match term0">中文</b> is even more interesting

--------------我是神奇的分割線--------------

交換機的結果爲如下:
幹事每月經過下屬科室都要親口交代24口<b class="match term0">交換機</b>等技術性器件的安裝工作

--------------我是神奇的分割線--------------

交換的結果爲如下:
咱倆<b class="match term0">交換</b>一下吧
幹事每月經過下屬科室都要親口交代24口<b class="match term0">交換</b>機等技術性器件的安裝工作

--------------我是神奇的分割線--------------

我
好
朋友
是
李明
我
愛
北京
天安
天安門
ibm
microsoft
dream
intetest
interest
me
lot

 

7.命令行分詞

 

使用示例:python -m jieba news.txt > cut_result.txt

命令行選項(翻譯):

使用: python -m jieba [options] filename

結巴命令行界面。

固定參數:
  filename              輸入文件

可選參數:
  -h, --help            顯示此幫助信息並退出
  -d [DELIM], --delimiter [DELIM]
                        使用 DELIM 分隔詞語,而不是用默認的' / '。
                        若不指定 DELIM,則使用一個空格分隔。
  -p [DELIM], --pos [DELIM]
                        啓用詞性標註;如果指定 DELIM,詞語和詞性之間
                        用它分隔,否則用 _ 分隔
  -D DICT, --dict DICT  使用 DICT 代替默認詞典
  -u USER_DICT, --user-dict USER_DICT
                        使用 USER_DICT 作爲附加詞典,與默認詞典或自定義詞典配合使用
  -a, --cut-all         全模式分詞(不支持詞性標註)
  -n, --no-hmm          不使用隱含馬爾可夫模型
  -q, --quiet           不輸出載入信息到 STDERR
  -V, --version         顯示版本信息並退出

如果沒有指定文件名,則使用標準輸入。

--help 選項輸出:

$> python -m jieba --help
Jieba command line interface.

positional arguments:
  filename              input file

optional arguments:
  -h, --help            show this help message and exit
  -d [DELIM], --delimiter [DELIM]
                        use DELIM instead of ' / ' for word delimiter; or a
                        space if it is used without DELIM
  -p [DELIM], --pos [DELIM]
                        enable POS tagging; if DELIM is specified, use DELIM
                        instead of '_' for POS delimiter
  -D DICT, --dict DICT  use DICT as dictionary
  -u USER_DICT, --user-dict USER_DICT
                        use USER_DICT together with the default dictionary or
                        DICT (if specified)
  -a, --cut-all         full pattern cutting (ignored with POS tagging)
  -n, --no-hmm          don't use the Hidden Markov Model
  -q, --quiet           don't print loading messages to stderr
  -V, --version         show program's version number and exit

If no filename specified, use STDIN instead.

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章