1. 程式人生 > >中文分詞jieba python 學習

中文分詞jieba python 學習

中文分詞工具,結巴分詞很好用,以下是驗證小結。

import jieba
import jieba.analyse
import jieba.posseg as pseg
import time

filename='tianlongbabu.txt'

def file_jieba_wordcout(filename):
    file=open(filename,'r').read()
    file=jieba.cut(file)
    dict={}
    for word in file:
        if word in dict:
            dict[word]+=1
        else:
            dict[word]=1
    file.close()
    return dict

def print_top100(filename):
    words=file_jieba_wordcout(filename)
    dict1=sorted(words.items(),key=lambda item:item[1], reverse = True)
    for item in dict1[:100]:
        print(item[0],item[1])

# wordcout 前100 次
# print_top100(filename)

#基於 TF-IDF 演算法的關鍵詞抽取
# TFIDF_result=jieba.analyse.extract_tags(open(filename,'rU').read(), topK=100, withWeight=False, allowPOS=())
# print(TFIDF_result)

# 基於 TextRank 演算法的關鍵詞抽取
TextRank_result=jieba.analyse.textrank(open(filename,'rU').read(), topK=100, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'))
print(TextRank_result)
#詞性標註

print_top100(filename) 通過結果看出,單純top100結果包括了,空等無意義的停止詞。

, 87017, 62909,。 27480,的 17698,“ 16965,” 16894,: 15125,了 14420,是 9740,我 9553,你 9429,他 8770,道 8408,? 7084,在 5547,也 5088,… 5033,這 4613,那 4093,不 3790,便 3657,又 3358,、 3264,說 3261,她 3230,! 3228,得 3142,人 2845,有 2797,去 2766,來 2430,將 2427,卻 2242,都 2215,上 2162,中 2088,要 2072,但 2042,和 2037,說道 2016,到 2007,一 1959,著 1889,段譽 1881,向 1834,聽 1774,之 1624,自己 1576,已 1534,只 1518,叫 1502,虛竹 1467,一個 1383,見 1368,好 1333,給 1330,‘ 1321,’ 1319,什麼 1265,蕭峰 1231,大 1217,而 1147,下 1110,想 1099,不是 1050,再 1025,為 1020,武功 1020,等 1019,就 1018,對 1003,甚麼 997,過 996,麼 945,跟 934,還 928,沒 928,一聲 878,瞧 833,喬峰 832,可 832,從 824,王語嫣 814,誰 799,段 795,咱們 782,殺 782,慕容復 781,不知 763,與 754,師父 750,心中 746,走 743,個 742,出 740,無 718,以 718,知道 709,段正淳 706,出來 706,

基於 TF-IDF 演算法的關鍵詞抽取。可以看出當前天龍八部的詞頻比較高的詞語。可以看出主角有哪些。

段譽、虛竹、喬峰、

['段譽', '虛竹', '蕭峰', '喬峰', '慕容復', '說道', '王語嫣', '武功', '段正淳', '木婉清', '丐幫', '甚麼', '鳩摩智', '遊坦之', '阿朱', '自己', '師父', '內力', '丁春秋', '大理', '包不同', '一聲', '什麼', '阿紫', '幫主', '星宿', '心下', '少林', '咱們', '不是', '鱷神', '心中', '便是', '一個', '童姥', '不知', '姑娘', '弟子', '契丹', '爹爹', '南海', '烏老大', '心想', '段延慶', '之中', '只見', '鍾靈', '少林寺', '如何', '倘若', '突然', '出來', '見到', '當真', '登時', '身子', '眾人', '如此', '功夫', '段公子', '知道', '雲中鶴', '保定', '不敢', '聲音', '伸手', '少女', '臉上', '西夏', '女子', '當下', '慕容公子', '性命', '穴道', '兩人', '鍾萬仇', '巴天石', '左手', '眼見', '風波惡', '和尚', '耶律洪基', '只是', '當即', '跟著', '葉二孃', '之極', '方丈', '姊姊', '馬伕人', '阿紫道', '不能', '二人', '只覺', '師兄', '王姑娘', '之下', '原來', '喝道', '這般']
TF-IDF 看看金瓶梅結果

['西門慶', '月娘', '婦人', '李瓶兒', '金蓮', '伯爵', '銀子', '說道', '春梅', '兩個', '甚麼', '後邊', '那裡', '敬濟', '玳安', '淫婦', '明日', '一面', '小廝', '出來', '老爹', '潘金蓮', '房裡', '今日', '打發', '娘子', '來家', '妗子', '陳敬濟', '大姐', '只見', '嬌兒', '大舅', '屋裡', '房中', '吳月娘', '吃酒', '吩咐', '這裡', '不知', '玉樓', '一個', '因問', '桂姐', '只顧', '姐姐', '孟玉樓', '一日', '於是', '起身', '老婆', '起來', '大娘', '正是', '眾人', '一回', '玳安道', '薛嫂', '丫頭', '如今', '門首', '老人家', '書童', '奴才', '夥計', '迎春', '琴童', '晚夕', '在家', '家中', '進來', '連忙', '姑子', '姐夫', '就是', '五娘', '武松', '衣服', '罷了', '那話', '婆子', '一時', '守備', '來旺兒', '武大', '吳銀兒', '大官人', '前邊', '童兒', '春梅道', '韓道國', '人家', '王六兒', '敬濟道', '知道', '兒來', '玉簫', '那日', '平安', '親家']

基於 TextRank 演算法的關鍵詞抽取結果。

虛竹關聯性竟然最大

['說道', '虛竹', '只見', '便是', '不知', '師父', '丐幫', '大理', '弟子', '不能', '出來', '內力', '南海', '知道', '姑娘', '少林', '眾人', '契丹', '星宿', '見到', '跟著', '身子', '鱷神', '心想', '聲音', '西夏', '伸手', '不可', '不會', '女子', '幫主', '眼見', '起來', '保定', '功夫', '說話', '雙手', '對方', '大師', '不住', '兄弟', '爹爹', '右手', '來到', '沒有', '聽到', '中原', '性命', '少女', '問道', '敵人', '包不同', '無法', '方丈', '江湖', '全身', '武士', '先生', '不肯', '出去', '抓住', '公子', '就算', '穴道', '出手', '適才', '公主', '喝道', '生死', '兵刃', '段譽', '姊姊', '漢子', '不料', '不得', '不到', '聲響', '高手', '大哥', '實在', '人家', '六脈', '手掌', '手指', '還有', '皇帝', '大家', '兒子', '取出', '蘇星河', '長劍', '想到', '父親', '主人', '露出', '英雄', '鮮血', '夫人', '大叫', '不見']

['西門慶', '婦人', '說道', '銀子', '出來', '只見', '玳安', '起來', '打發', '不知', '娘子', '小廝', '吩咐', '眾人', '起身', '看見', '人家', '進來', '衣服', '敬濟', '知道', '老婆', '大姐', '淫婦', '吃酒', '學生', '坐下', '門首', '聽見', '不想', '丫頭', '姐姐', '收拾', '走來', '大舅', '飲酒', '東京', '說話', '夥計', '提刑', '出去', '書童', '出門', '老人家', '奴才', '來家', '不見', '西門', '小人', '看著', '進去', '守備', '衙門', '老爺', '方才', '坐在', '漢子', '孩子', '姐夫', '親家', '琴童', '時分', '大娘', '還有', '來到', '不得', '取出', '問道', '伺候', '走到', '婆子', '大戶', '回來', '官人', '放在', '沒有', '衣裳', '嬌兒', '不肯', '分付', '家人', '穿著', '床上', '奶奶', '雪娥', '磕頭', '迎接', '姑子', '御史', '媽媽', '哥兒', '轎子', '花子', '大人', '觀看', '花園', '丫鬟', '孩兒', '韓道國', '大門']

TF-IDF模型:

http://www.cnblogs.com/hanacode/articles/4819328.html

tf-idf模型的主要思想是:如果詞w在一篇文件d中出現的頻率高,並且在其他文件中很少出現,則認為詞w具有很好的區分能力,適合用來把文章d和其他文章區分開來。該模型主要包含了兩個因素:

1) 詞w在文件d中的詞頻tf (Term Frequency),即詞w在文件d中出現次數count(w, d)和文件d中總詞數size(d)的比值:

tf(w,d) = count(w, d) / size(d)

2) 詞w在整個文件集合中的逆向文件頻率idf (Inverse Document Frequency),即文件總數n與詞w所出現檔案數docs(w, D)比值的對數:

idf = log(n / docs(w, D))

tf-idf模型根據tf和idf為每一個文件d和由關鍵詞w[1]...w[k]組成的查詢串q計算一個權值,用於表示查詢串q與文件d的匹配度:

tf-idf(q, d)
= sum { i = 1..k | tf-idf(w[i], d) }
= sum { i = 1..k | tf(w[i], d) * idf(w[i]) }

舉個栗子

有一篇很長的文章,我要用計算機提取它的關鍵詞(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表示對得到的值取對數。

第三步,計算TF-IDF。

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

還是以《中國的蜜蜂養殖》為例,假定該文長度為1000個詞,"中國"、"蜜蜂"、"養殖"各出現20次,則這三個詞的"詞頻"(TF)都為0.02。然後,搜尋Google發現,包含"的"字的網頁共有250億張,假定這就是中文網頁總數。包含"中國"的網頁共有62.3億張,包含"蜜蜂"的網頁為0.484億張,包含"養殖"的網頁為0.973億張。則它們的逆文件頻率(IDF)和TF-IDF如下:

從上表可見,"蜜蜂"的TF-IDF值最高,"養殖"其次,"中國"最低。(如果還計算"的"字的TF-IDF,那將是一個極其接近0的值。)所以,如果只選擇一個詞,"蜜蜂"就是這篇文章的關鍵詞。

除了自動提取關鍵詞,TF-IDF演算法還可以用於許多別的地方。比如,資訊檢索時,對於每個文件,都可以分別計算一組搜尋詞("中國"、"蜜蜂"、"養殖")的TF-IDF,將它們相加,就可以得到整個文件的TF-IDF。這個值最高的文件就是與搜尋詞最相關的文件。

TF-IDF演算法的優點是簡單快速,結果比較符合實際情況。缺點是,單純以"詞頻"衡量一個詞的重要性,不夠全面,有時重要的詞可能出現次數並不多。而且,這種演算法無法體現詞的位置資訊,出現位置靠前的詞與出現位置靠後的詞,都被視為重要性相同,這是不正確的。(一種解決方法是,對全文的第一段和每一段的第一句話,給予較大的權重。)


TextRank 演算法:

https://my.oschina.net/letiantian/blog/351154

摘要: TextRank演算法基於PageRank,用於為文字生成關鍵字和摘要。 TextRank演算法基於PageRank,用於為文字生成關鍵字和摘要。其論文是:
Mihalcea R, Tarau P. TextRank: Bringing order into texts[C]. Association for Computational Linguistics, 2004.

先從PageRank講起。

PageRank


PageRank最開始用來計算網頁的重要性。整個www可以看作一張有向圖圖,節點是網頁。如果網頁A存在到網頁B的連結,那麼有一條從網頁A指向網頁B的有向邊。

構造完圖後,使用下面的公式:


S(Vi)是網頁i的中重要性(PR值)。d是阻尼係數,一般設定為0.85。In(Vi)是存在指向網頁i的連結的網頁集合。Out(Vj)是網頁j中的連結存在的連結指向的網頁的集合。|Out(Vj)|是集合中元素的個數。

PageRank需要使用上面的公式多次迭代才能得到結果。初始時,可以設定每個網頁的重要性為1。上面公式等號左邊計算的結果是迭代後網頁i的PR值,等號右邊用到的PR值全是迭代前的。

舉個例子:


上圖表示了三張網頁之間的連結關係,直覺上網頁A最重要。可以得到下面的表:

   結束\起始 A B C
A 0 1 1
B 0 0 0
C 0 0 0

橫欄代表其實的節點,縱欄代表結束的節點。若兩個節點間有連結關係,對應的值為1。

根據公式,需要將每一豎欄歸一化(每個元素/元素之和),歸一化的結果是:

   結束\起始 A B C
A 0 1 1
B 0 0 0
C 0 0 0

上面的結果構成矩陣M。我們用matlab迭代100次看看最後每個網頁的重要性:
M = [0 1 1 
    0 0 0
    0 0 0];

PR = [1; 1 ; 1];

for iter = 1:100
    PR = 0.15 + 0.85*M*PR;
    disp(iter);
    disp(PR);
end
執行結果(省略部分):

......

    95

    0.4050
    0.1500
    0.1500

    96

    0.4050
    0.1500
    0.1500

    97

    0.4050
    0.1500
    0.1500

    98

    0.4050
    0.1500
    0.1500

    99

    0.4050
    0.1500
    0.1500

   100

    0.4050
    0.1500
    0.1500
最終A的PR值為0.4050,B和C的PR值為0.1500。

如果把上面的有向邊看作無向的(其實就是雙向的),那麼:
M = [0 1 1 
    0.5 0 0
    0.5 0 0];

PR = [1; 1 ; 1];

for iter = 1:100
    PR = 0.15 + 0.85*M*PR;
    disp(iter);
    disp(PR);
end
執行結果(省略部分):

.....

    98

    1.4595
    0.7703
    0.7703

    99

    1.4595
    0.7703
    0.7703

   100

    1.4595
    0.7703
    0.7703
依然能判斷出A、B、C的重要性。

使用TextRank提取關鍵字

將原文字拆分為句子,在每個句子中過濾掉停用詞(可選),並只保留指定詞性的單詞(可選)。由此可以得到句子的集合和單詞的集合。

每個單詞作為pagerank中的一個節點。設定視窗大小為k,假設一個句子依次由下面的單片語成:

w1, w2, w3, w4, w5, ..., wn

w1, w2, ..., wkw2, w3, ...,wk+1w3, w4, ...,wk+2等都是一個視窗。在一個視窗中的任兩個單詞對應的節點之間存在一個無向無權的邊。

基於上面構成圖,可以計算出每個單詞節點的重要性。最重要的若干單詞可以作為關鍵詞。

使用TextRank提取關鍵短語


參照“使用TextRank提取關鍵詞”提取出若干關鍵詞。若原文字中存在若干個關鍵詞相鄰的情況,那麼這些關鍵詞可以構成一個關鍵短語。

例如,在一篇介紹“支援向量機”的文章中,可以找到三個關鍵詞支援、向量、機,通過關鍵短語提取,可以得到支援向量機

使用TextRank提取摘要

將每個句子看成圖中的一個節點,若兩個句子之間有相似性,認為對應的兩個節點之間有一個無向有權邊,權值是相似度。

通過pagerank演算法計算得到的重要性最高的若干句子可以當作摘要。

論文中使用下面的公式計算兩個句子Si和Sj的相似度:



分子是在兩個句子中都出現的單詞的數量。|Si|是句子i的單詞數。

由於是有權圖,PageRank公式略做修改:

實現TextRank


因為要用測試多種情況,所以自己實現了一個基於Python 2.7的TextRank針對中文文字的庫TextRank4ZH。位於:

https://github.com/someus/TextRank4ZH

下面是一個例子:

#-*- encoding:utf-8 -*-

import codecs
from textrank4zh import TextRank4Keyword, TextRank4Sentence

text = codecs.open('./text/01.txt', 'r', 'utf-8').read()
tr4w = TextRank4Keyword(stop_words_file='./stopword.data')  # 匯入停止詞

#使用詞性過濾,文字小寫,視窗為2
tr4w.train(text=text, speech_tag_filter=True, lower=True, window=2)  

print '關鍵詞:'
# 20個關鍵詞且每個的長度最小為1
print '/'.join(tr4w.get_keywords(20, word_min_len=1))  

print '關鍵短語:'
# 20個關鍵詞去構造短語,短語在原文字中出現次數最少為2
print '/'.join(tr4w.get_keyphrases(keywords_num=20, min_occur_num= 2))  
    
tr4s = TextRank4Sentence(stop_words_file='./stopword.data')

# 使用詞性過濾,文字小寫,使用words_all_filters生成句子之間的相似性
tr4s.train(text=text, speech_tag_filter=True, lower=True, source = 'all_filters')

print '摘要:'
print '\n'.join(tr4s.get_key_sentences(num=3)) # 重要性最高的三個句子
執行結果如下:
關鍵詞:
媒體/高圓圓//賓客/趙又廷/答謝/謝娜/現身/記者/新人/北京/博/展示/捧場/禮物/張傑/當晚/戴/酒店/外套
關鍵短語:
微博
摘要:
中新網北京121日電(記者 張曦) 30日晚,高圓圓和趙又廷在京舉行答謝宴,諸多明星現身捧場,其中包括張傑(微博)、謝娜(微博)夫婦、何炅(微博)、蔡康永(微博)、徐克、張凱麗、黃軒(微博)等
高圓圓身穿粉色外套,看到大批記者在場露出嬌羞神色,趙又廷則戴著鴨舌帽,十分淡定,兩人快步走進電梯,未接受媒體採訪
記者瞭解到,出席高圓圓、趙又廷答謝宴的賓客近百人,其中不少都是女方的高中同學
另外, jieba分詞提供的基於TextRank的關鍵詞提取工具。 snownlp也實現了關鍵詞提取和摘要生成。

下一步採用貝葉斯演算法再分析一把。