NLP系列 文字預處理1

2021-10-05 22:14:40 字數 4413 閱讀 5016

對一篇文章,一般的做法是先進行分詞,後續是對詞語進行語義特徵提取與建模,不過也有人是用句子或者單字粒度,個人實驗的結果是字元級比分詞好,句子級沒有試過。

分詞後是去除停用詞以及標點符號,停用詞表到github上搜尋一下有挺多,裡面是像咳、哇、哈這些沒啥用的詞,把他們去掉對文字語義沒什麼影響,卻可以降低文字處理的複雜度,詞的個數越少,表示乙個詞或者句子的向量維度就可以更低。

分詞一般使用jieba庫來分詞,這裡也推薦另乙個 synonyms包。他是在jieba的基礎上做的,在一些方面更方便,做一下對比:

總體感覺synonyms分詞、詞性標註一次性完成比較方便,功能也豐富。兩者也可組合使用。

注意兩個包組合使用時,jieba在前,synonyms在後,不然會報錯。

import jieba

import jieba.posseg as pseq

import synonyms

引用synonyms的時候,會發現有這麼一句輸出,可以知道裡面也是有用jieba的來分詞的

分別用jieba、synonyms分詞跟詞性標註,發現結果是一樣的。注意輸入只能是乙個字串,不能輸入多個,多個文字就用迴圈。

# 要分詞的文字

text =

'今天a區陽光明媚!'

# jieba分詞,lcut直接返回分詞列表

result1 = jieba.lcut(text)

print

('jieba分詞結果:'

,result1)

# jieba詞性標註,返回的是乙個迭代器,只能迭代一次

result2 = pseq.cut(text)

print

('jieba詞性標註結果:'

)for word in result2:

# 迭代物件包含詞、詞性兩個屬性

print

(word.word, word.flag)

輸出為

jieba分詞結果: [『今天』, 『a』, 『區』, 『陽光明媚』, 『!』]

jieba詞性標註結果:

今天 t

a eng

區 n陽光明媚 nr

! x

text =

'今天a區陽光明媚!'

# synonyms分詞、詞性標註

# 一次性返回兩個列表,第乙個列表是分詞結果,第二個是詞性標註結果

result3 = synonyms.seg(text)

print

('synonyms分詞結果:'

)print

(result3[0]

)print

('synonyms詞性標註結果:'

)print

(result3[1]

)

輸出為

synonyms分詞結果:

[『今天』, 『a』, 『區』, 『陽光明媚』, 『!』]

synonyms詞性標註結果:

[『t』, 『eng』, 『n』, 『nr』, 『x』]

對比可以發現,兩個的分詞跟詞性標註結果是一樣的。

向 『今天a區陽光明媚!』 這句話的分詞,可以發現有一些詞語是分不出來的,可能是專用詞或者特殊詞之類的,這個時候可以給jieba匯入乙個自定義詞典,他就可以將這些詞成功分出來。synonyms新增詞典也是用jieba新增即可

新增詞典有兩種方式:

# 新增單個詞

jieba.add_word(word=

'a區'

,freq=

5,tag=

'n')

# txt檔案形式新增

# 每一行表示乙個詞:詞 詞頻 詞性

jieba.load_userdict(

'./自定義詞典.txt'

)

新增詞典後的分詞結果

text =

'今天a區陽光明媚!'

# 新增詞典結果對比

result4=synonyms.seg(text)

print

('新增詞典前:'

)print

(result3[0]

,'\n'

)print

('新增詞典後:'

)print

(result4[0]

)

輸出為

新增詞典前:

[『今天』, 『a』, 『區』, 『陽光明媚』, 『!』]

新增詞典後:

[『今天』, 『a區』, 『陽光明媚』, 『!』]

可以發現新增詞典後對新語料分詞準確很多。

要去除停用詞,首先得有乙個停用詞表,這裡給github上的乙個資源。分詞後,篩選掉當中的停用詞就好了,當然也可以篩選調某些詞性或者標點符號,做法是一樣的。

用這個讀取檔案,成為乙個列表。

stopwords =

[w.strip(

)for w in

open

('停用詞表.txt'

,'r'

, encoding=

'utf-8'

).readlines(

)]

演示的用下面的代替:

stopwords =

['今天'

,'!'

]result_clean =

for word in result4[0]

:if word not

in stopwords:

print

('去除停用詞結果'

, result_clean)

輸出為:

去除停用詞結果 [『a區』, 『陽光明媚』]

預處理這裡也有看到有人用近義詞替換,我試著效果不是很好。用的是synonyms.nearby(word)

# 返回乙個元組,包含兩個列表

# 第乙個列表是近義詞

# 第二個列表是對應的相似度

word=

'交叉口'

near=synonyms.nearby(word)

print

('結果型別:'

,type

(near)

)print

('結果長度:'

,len

(near)

)print

('近義詞:'

,near[0]

)print

('相似度:'

,near[1]

)

輸出為

結果型別:

結果長度: 2

近義詞: [『交叉口』, 『路口』, 『交叉路口』, 『中山路』, 『街口』, 『交口』, 『和平路』, 『中山北路』, 『交叉處』, 『東南側』]

相似度: [1.0, 0.81871194, 0.7977913, 0.7161459, 0.6995231, 0.69011694, 0.6796811, 0.66988134, 0.6574828, 0.64784586]

line=

'未管所路**叉口至加油站路段'

line=jieba.lcut(line)

line_new=

for word in line:

near_word=synonyms.nearby(word)

for i in

range(1

,len

(near_word[0]

)):if near_word[0]

[i]in line_new and near_word[1]

[i]>

0.8:

word=near_word[0]

[i]break

print

('未替換結果:'

,line)

print

('分詞結果:'

,line_new)

輸出為

未替換結果: [『未管』, 『所』, 『路口』, 『交叉口』, 『至』, 『加油站』, 『路段』]

分詞結果: [『未管』, 『所』, 『路口』, 『路口』, 『至』, 『加油站』, 『路段』]

知乎上的乙個分詞介紹,提供了其他的分詞方法,不過沒去試過:

github上的乙個nlp專案,收集了很多資源:

NLP 中文文字預處理

jieba是乙個專門處理中文分詞的分詞庫,但其實功能比單純的分詞強大許多。中文不同於英文可以通過空格分開每個有意義的詞,對於中文需要乙個工具將完整的文字分割成更細緻的詞語,類似於英文分詞中使用的nltk工具,中文中需要使用jieba。pip install jieba 4.詞性標註 5.tokeni...

小語種nlp文字預處理 資料清洗

開始繼續完成大資料實驗室招新題 roman urdu小語種為例 link 本練習賽所用資料,是名為 roman urdu dataset 的公開資料集。這些資料,均為文字資料。原始資料的文字,對應三類情感標籤 positive,negative,netural。本練習賽,移除了標籤為netural的...

NLP文字預處理的一些方法

寫在前面 隨著bert等技術的興起,在做文字方面比賽時,對於預處理這一塊像中文分詞,停用詞過濾,詞形還原,詞幹化,標點符號處理等變的不再這麼重要。當然也可以從另乙個角度來看,這些對於文字的預處理方法相當於減少輸入的雜訊,是可以讓神經網路更具有魯棒性的。所以以下內容可以作為乙個知識儲備在這裡,在工作中...