文本預(yù)處理的一般流程&jieba分詞&jieba關(guān)鍵詞提取

1.jieba分詞

注意:使用jieba以前斜纪,數(shù)據(jù)預(yù)處理很重要汇荐,清除空值重複值以後掏击,同時(shí)也要判斷數(shù)據(jù)是否為字符串,如果不是字符應(yīng)該刪除該條數(shù)據(jù)悼粮。

如果讀取出現(xiàn)中文亂碼可以直接這樣打開闲勺,python2X3X通用

import codecs
with codecs.open('h.csv', 'rb', 'gb2312') as csvfile:
    for line in csvfile:
        print line

文本預(yù)處理的一般流程

#讀取數(shù)據(jù)
df1 = pd.read_excel('ManMade.xlsx')
#選出文本部分並且把非字符串索引存到列表

#如果只需要去除缺失值的話,有下面兩種方法:
#第一種把非空部分另存一列再處理
#df1['data'] = df['content'][df['content'].notnull()]
#第二種用dropna函數(shù)以后再重新排序
#df = df.dropna(subset=["content"])#subset代表需要看的列矮锈,如果content列中某一行為空霉翔,刪除該行
#重新排序,drop默認(rèn)為False則索引列會(huì)被還原為普通列,否則會(huì)丟失苞笨。改為True,刪除原先的索引使用新的從0開始的索引
#df = df.reset_index(drop = True)

list0 = df1.content.apply(lambda x: len(x) > 2)
#統(tǒng)計(jì)長度小于二的個(gè)數(shù)並且記錄下他們的索引(因?yàn)槿绻募荂SV格式子眶,
#所有非空內(nèi)容讀出來都是字符串格式瀑凝,比如錯(cuò)誤的記錄導(dǎo)致的空格或者數(shù)字用pandas讀取出來都是字符串格式,
#例如' '或者'0'臭杰,用isinstance(x, str)無法分辨粤咪,雖然jieba分詞只要是字符串格式都能切詞,
#但是如果jieba分詞來讀取渴杆,則會(huì)把它當(dāng)成int或者float格式寥枝,剔除這種數(shù)據(jù),最簡單的方法就是去除長度過小的數(shù)據(jù)磁奖,
#但是如果是xlsx格式囊拜,0讀取出來就是int格式,用len(x)就會(huì)報(bào)錯(cuò)
#那么就可以先用list1中的isinstance(x, str)來篩選)
list1 = df1.content.apply(lambda x: isinstance(x, str))
#另外:null部分會(huì)直接跳過比搭,所以一開始一定要先dropna去掉空白部分)
#統(tǒng)計(jì)非字符串的個(gè)數(shù)並且記錄下他們的索引
count_a = 0
list2 = []
for i in range(len(list1)):
    if list1[i]==False:
        list2.append(i)
        count_a += 1
    else:
        pass
#刪除所有非字符串的部分
df2 = df1.drop(list2,axis=0)
#重新排序
df2.reset_index()
#把列表里的內(nèi)容存到一個(gè)字符串里
list_content = [i for i in df2.content]
content = ''.join(list_content)
print(len(content))
##如果有需要也可以對每個(gè)文章只選出他的漢字部分冠跷,介紹兩種常用方法:
#方法1:
#漢字的編碼范圍是['\u4e00','\u9fa5'],取出一個(gè)切完詞的文本列表中的全部漢字可以用范圍來限定
list1 = ['一堆','漢字','和','?!#','符號(hào)']
X,Y = ['\u4e00','\u9fa5']
list2 = [i for i in list1 if X <= i <= Y and i not in stopwords]
#方法2:
#正則表達(dá)式
import  re

test='fuck you! 8婆婊子!要啥bike自行車懊弁小抄囚!'

result1=re.findall(u'[\u4e00-\u9fa5]',test)  
print (result1)
print (''.join(result1))
#['婆', '婊', '子', '要', '啥', '自', '行', '車', '啊']
#婆婊子要啥自行車啊
result2=re.findall(r'[0-9]',test)
print (''.join(result2))
#8
result3=re.findall(r'[a-z]',test)
print (''.join(result3))
#fuckyoubike

使用 suggest_freq(segment, tune=True) 可調(diào)節(jié)單個(gè)詞語的詞頻,使其能(或不能)被分出來橄务。

jieba.cut 方法接受三個(gè)輸入?yún)?shù): 需要分詞的字符串幔托;cut_all 參數(shù)用來控制是否采用全模式;HMM 參數(shù)用來控制是否使用 HMM 模型蜂挪。
jieba.cut_for_search 方法接受兩個(gè)參數(shù):需要分詞的字符串柑司;是否使用 HMM 模型。該方法適合用于搜索引擎構(gòu)建倒排索引的分詞锅劝,粒度比較細(xì)攒驰。
待分詞的字符串可以是 unicode 或 UTF-8 字符串、GBK 字符串故爵。注意:不建議直接輸入 GBK 字符串玻粪,可能無法預(yù)料地錯(cuò)誤解碼成 UTF-8。
jieba.cut 以及 jieba.cut_for_search 返回的結(jié)構(gòu)都是一個(gè)可迭代的 generator诬垂,可以使用 for 循環(huán)來獲得分詞后得到的每一個(gè)詞語(unicode)劲室,或者用
jieba.lcut 以及 jieba.lcut_for_search 直接返回 list。
jieba.Tokenizer(dictionary=DEFAULT_DICT) 新建自定義分詞器结窘,可用于同時(shí)使用不同詞典很洋。jieba.dt 為默認(rèn)分詞器,所有全局分詞相關(guān)函數(shù)都是該分詞器的映射隧枫。

# encoding=utf-8
import jieba

seg_list = jieba.cut("我來到北京清華大學(xué)", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list))  # 全模式

seg_list = jieba.cut("我來到北京清華大學(xué)", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))  # 精確模式

seg_list = jieba.cut("他來到了網(wǎng)易杭研大廈")  # 默認(rèn)是精確模式
print(", ".join(seg_list))

seg_list = jieba.cut_for_search("小明碩士畢業(yè)于中國科學(xué)院計(jì)算所喉磁,后在日本京都大學(xué)深造")  # 搜索引擎模式
print(", ".join(seg_list))


#結(jié)果:
#【全模式】: 我/ 來到/ 北京/ 清華/ 清華大學(xué)/ 華大/ 大學(xué)

#【精確模式】: 我/ 來到/ 北京/ 清華大學(xué)

#【新詞識(shí)別】:他, 來到, 了, 網(wǎng)易, 杭研, 大廈    (此處,“杭研”并沒有在詞典中官脓,但是也被Viterbi算法識(shí)別出來了)

#【搜索引擎模式】: 小明, 碩士, 畢業(yè), 于, 中國, 科學(xué), 學(xué)院, 科學(xué)院, 中國科學(xué)院, 計(jì)算, 計(jì)算所, 后, 在, 日本, 京都, 大學(xué), 日本京都大學(xué), 深造

并行分詞

  • 原理:將目標(biāo)文本按行分隔后协怒,把各行文本分配到多個(gè) Python 進(jìn)程并行分詞,然后歸并結(jié)果卑笨,從而獲得分詞速度的可觀提升

  • 基于 python 自帶的 multiprocessing 模塊孕暇,目前暫不支持 Windows

  • 用法:

    • jieba.enable_parallel(4) # 開啟并行分詞模式,參數(shù)為并行進(jìn)程數(shù)
    • jieba.disable_parallel() # 關(guān)閉并行分詞模式
  • 例子:https://github.com/fxsjy/jieba/blob/master/test/parallel/test_file.py

  • 實(shí)驗(yàn)結(jié)果:在 4 核 3.4GHz Linux 機(jī)器上赤兴,對金庸全集進(jìn)行精確分詞妖滔,獲得了 1MB/s 的速度,是單進(jìn)程版的 3.3 倍桶良。

  • 注意:并行分詞僅支持默認(rèn)分詞器 jieba.dtjieba.posseg.dt座舍。

特點(diǎn):

  • 支持三種分詞模式
    –精確模式,試圖將句子最精確地切開艺普,適合文本分析;
    –全模式簸州,把句子中所有的可以成詞的詞語都掃描出來鉴竭,速度非常快岸浑,但不能解決歧義;
    –搜索引擎模式搏存,在精確模式的基礎(chǔ)上,對長詞再次切分矢洲,提高召回率璧眠,適合用于搜索引擎分詞。
    -支持繁體分詞
    -支持自定義詞典

算法:

基于前綴詞典實(shí)現(xiàn)高效的詞圖掃描读虏,生成句子中漢字所有可能成詞情況所構(gòu)成的有向無環(huán)圖(DAG)
采用動(dòng)態(tài)規(guī)劃查找最大概率路徑责静,找出基于詞頻的最大切分組合
對于未登錄詞,采用了基于漢字成詞能力的HMM模型盖桥,使用了Viterbi算法

添加自定義詞典:

開發(fā)者可以指定自己自定義的詞典灾螃,以便包含jieba詞庫里沒有的詞。雖然jieba有新詞識(shí)別能力揩徊,但是自行添加新詞可以保證更高的正確率
用法:jieba.load_userdict(file_name)#file_name為文件類對象 或自定義詞典的路徑
詞典格式:一個(gè)詞一行:詞語腰鬼,詞頻(可省略),詞性(可省略)塑荒,用空格隔開熄赡,順序不可顛倒。UTF-8編碼齿税。

2.關(guān)鍵詞提缺肆颉:

基于TF-IDF算法的關(guān)鍵詞抽取
import jieba.analyse

  • jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
    sentence 為待提取的文本
    topK 為返回幾個(gè) TF/IDF 權(quán)重最大的關(guān)鍵詞,默認(rèn)值為 20
    withWeight 為是否一并返回關(guān)鍵詞權(quán)重值凌箕,默認(rèn)值為 False
    allowPOS 僅包括指定詞性的詞拧篮,默認(rèn)值為空,即不篩選
    常用詞性有:["ns", "n", "vn", "v", "nr"]
    注意:選取單個(gè)詞性時(shí)結(jié)尾要用逗號(hào)陌知,
    例如["ns",]他托,如果不加逗號(hào),實(shí)際上是按照["n","s"]來取詞的仆葡。
    詞性表
  • jieba.analyse.TFIDF(idf_path=None) 新建 TFIDF 實(shí)例,idf_path 為 IDF 頻率文件

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

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

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

  • 用法: jieba.analyse.set_stop_words(file_name) file_name為自定義語料庫的路徑

基于TextRank算法的關(guān)鍵詞提取

  • jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=(‘ns’, ‘n’, ‘vn’, ‘v’)) 直接使用志笼,接口相同沿盅,注意默認(rèn)過濾詞性。
  • jieba.analyse.TextRank() 新建自定義 TextRank 實(shí)例
    –基本思想:
    1纫溃,將待抽取關(guān)鍵詞的文本進(jìn)行分詞
    2腰涧,以固定窗口大小(默認(rèn)為5,通過span屬性調(diào)整)紊浩,詞之間的共現(xiàn)關(guān)系窖铡,構(gòu)建圖
    3疗锐,計(jì)算圖中節(jié)點(diǎn)的PageRank,注意是無向帶權(quán)圖

下面寫出jieba關(guān)鍵詞提取方法例子

# -*- coding: utf-8 -*-
#基于詞語共現(xiàn)圖提取方法
import jieba

#import jieba.posseg as psg
import itertools as it
import pandas as pd
#import json
#from elasticsearch import Elasticsearch
#from pyquery import PyQuery as pq
import time

def wordweight(wc1,wc2,samecounts):
    weight = samecounts/(wc1+wc2-samecounts) # Jaccard係數(shù)费彼,交集與並集比值
    return weight

#def wordweight(wc1,wc2,samecounts):  
#   weight = samecounts/(wc1*wc2)  # PMI滑臊,互信息
#   return weight

t1 = time.time()
#讀數(shù)據(jù)&清洗數(shù)據(jù)
list_content = []
df1 = pd.read_excel('ManMade20.xlsx')
list1 = df1.content.apply(lambda x: isinstance(x, str))
count_a = 0
list2 = []
for i in range(len(list1)):
    if list1[i]==False:
        list2.append(i)
        count_a += 1
    else:
        pass
df2 = df1.drop(list2,axis=0)
df2.reset_index()
list_content = [i for i in df2.content]
content = ''.join(list_content)
print(len(content))
#print(content)
t2 = time.time()
#提取關(guān)鍵詞
#1.用jieba自帶的提取關(guān)鍵詞
#一百篇文章做速度測試
#Running time:615.9178113937378 Seconds
#詞性限制集合為["ns", "n", "vn", "v", "nr"],表示只能從詞性為地名箍铲、名詞雇卷、動(dòng)名詞、動(dòng)詞颠猴、人名這些詞性的詞中抽取關(guān)鍵詞关划。
allow_pos = ('ns', 'nr', 'n', 'vn', 'v', 'an', 'nz', 'vg')
tags = jieba.analyse.extract_tags(content,topK = 100,allowPOS = allow_pos)  # 基於 TF-IDF 算法的關(guān)鍵詞提取
# tags = jieba.analyse.textrank(content,topK=100)  # 基於 TextRank 算法的關(guān)鍵字提取

t3 = time.time()

sentence = content.split('\n') # '\n'換行,段落
sentence = [e for e in sentence if e not in ('', ' ')]  # 去出空格之類的噪聲
wordraw = []
t4 = time.time()

for i in range(len(sentence)):
    #words = [e.word for e in psg.cut(sentence[i]) if e.flag.startswith(('n','a','v'))]
    words = jieba.lcut(sentence[i])
    cleanwords = [e for e in words if e in tags]
    wordraw.append(cleanwords)
wordlist = [list(set(x)) for x in wordraw]  # 文章段落同個(gè)詞可能出現(xiàn)多次(詞頻統(tǒng)計(jì)基本單位:段落)
#map(lambda x: list(set(x)), wordlist)  #去除第二層list裡面重複值
wordlist = [x for x in wordlist if len(x) > 1]
#filter(lambda x: len(x) > 1, wordlist)  #過濾掉空格和len1的字符串
#把3個(gè)以上的詞拆分進(jìn)行兩兩組合
wordlist1 = [list(it.combinations(x,2)) for x in wordlist]
#map(lambda x: list(it.combinations(x,2)), wordlist)
#拆分組合中的list加到大list中
wordcorpus = [wordlist1[i][j] for i in range(len(wordlist1)) for j in range(len(wordlist1[i]))]
wordcorpus = [sorted(x) for x in wordcorpus]
#print(len(wordcorpus))
#map(lambda x: sorted(x), wordcorpus) #對list名詞進(jìn)行排序
#wordcorpus = sorted(wordcorpus) #對list中元組進(jìn)行排序
#wordcorpus = [tuple(x) for x in wordcorpus]
#map(lambda x: tuple(x), wordcorpus)#對名詞進(jìn)行tuple轉(zhuǎn)化
#corpus = list(set(wordcorpus)) #排重得到新list翘瓮,方便后面計(jì)算count
keywords={}
#countwords = jieba.lcut(content)
countwords = []

t5 = time.time()

for i in wordraw:
    countwords.extend(i)
    
t6 = time.time()

for i in tags:
    keywords[i] = countwords.count(i)
source = []
target = []
weight = []

t7 = time.time()
for j in range(len(wordcorpus)):
    source.append(list(wordcorpus[j])[0])
    target.append(list(wordcorpus[j])[1])
    weight.append(wordweight(keywords[wordcorpus[j][0]],keywords[wordcorpus[j][1]],wordcorpus.count(wordcorpus[j])))
df={'source':source,'target':target,'weight':weight}
frame = pd.DataFrame(df,columns=['source','target','weight'])
sourceFreq = []
targetFreq = []

t8 = time.time()
for i in range(len(frame)):
    sourceFreq.append(keywords[frame['source'][i]])
    targetFreq.append(keywords[frame['target'][i]])
frame.insert(3,'sourceFreq',sourceFreq)
frame.insert(4,'targetFreq',targetFreq)
jsondata = frame.to_dict(orient='records')
t9 = time.time()

print(jsondata)
print('Running time1: %s Seconds'%(t2-t1))
print('Running time2: %s Seconds'%(t3-t2))
print('Running time3: %s Seconds'%(t4-t3))
print('Running time4: %s Seconds'%(t5-t4))
print('Running time5: %s Seconds'%(t6-t5))
print('Running time6: %s Seconds'%(t7-t6))
print('Running time7: %s Seconds'%(t8-t7))
print('Running time8: %s Seconds'%(t9-t8))
print('Running time0: %s Seconds'%(t9-t1))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贮折,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子资盅,更是在濱河造成了極大的恐慌调榄,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件律姨,死亡現(xiàn)場離奇詭異振峻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)择份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門扣孟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荣赶,你說我怎么就攤上這事凤价。” “怎么了拔创?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵利诺,是天一觀的道長。 經(jīng)常有香客問我剩燥,道長慢逾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任灭红,我火速辦了婚禮侣滩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘变擒。我一直安慰自己君珠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布娇斑。 她就那樣靜靜地躺著策添,像睡著了一般材部。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上唯竹,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天乐导,我揣著相機(jī)與錄音,去河邊找鬼摩窃。 笑死兽叮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的猾愿。 我是一名探鬼主播鹦聪,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蒂秘!你這毒婦竟也來了泽本?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對情侶失蹤姻僧,失蹤者是張志新(化名)和其女友劉穎规丽,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撇贺,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赌莺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了松嘶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艘狭。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖翠订,靈堂內(nèi)的尸體忽然破棺而出巢音,到底是詐尸還是另有隱情,我是刑警寧澤尽超,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布官撼,位于F島的核電站,受9級(jí)特大地震影響似谁,放射性物質(zhì)發(fā)生泄漏傲绣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一巩踏、第九天 我趴在偏房一處隱蔽的房頂上張望斜筐。 院中可真熱鬧,春花似錦蛀缝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗤练。三九已至,卻和暖如春在讶,著一層夾襖步出監(jiān)牢的瞬間煞抬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國打工构哺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留革答,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓曙强,卻偏偏與公主長得像残拐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子碟嘴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353