1. 程式人生 > >文字處理(二)詞頻統計,jieba分詞,詞性標註,snownlp情感分析

文字處理(二)詞頻統計,jieba分詞,詞性標註,snownlp情感分析

這一篇接著上一篇處理後的資料進行操作,按照(一)中的步驟,這事應該將文字資料每一行中的高頻的正面詞去掉,因為多數是描述身體健康的短句,只有少數是描述脾臟檢查異常的,所以嘗試刪除掉描述身體健康的短句,只留下少數檢查異常的資料,對異常的檢查資料進行特徵提取,這是思路。

所以這一篇目的是找到並且去除描述正常情況的短句。

##對a和d進行分析後補充,這裡是經過一次試錯之後才發現開頭應該把這些作為片語保留並新增到分詞中去,否則,'不'和'寬'就會成為一個副詞一個形容詞,而事實上他們二者總是經常出現的用以描述正常情況的,'未見'以及'無明顯'類似
jieba.suggest_freq('未見',True)
jieba.add_word('未見',tag='d')
jieba.suggest_freq('無明顯',True)
jieba.add_word('無明顯',tag='d')
jieba.suggest_freq('不寬',True)
jieba.add_word('不寬',tag='a')
jieba.suggest_freq('不厚',True)
jieba.add_word('不厚',tag='a')

#jieba.suggest_freq('尚正常',True)
jieba.suggest_freq('不明顯',True)
jieba.add_word('不明顯',tag='a')
jieba.suggest_freq('不清',True)
jieba.add_word('不清',tag='a')
在這之後
df_clean=df['0116']##得到0116這一列資料
wordlist=[]
typelist=[]
for row in df_clean:
    words=jieba.posseg.cut(row)
    for w in words:
        wordlist.append(w.word)
        typelist.append(w.flag)

all_dic=pd.DataFrame(columns=['word','type','count'])
all_dic['word']=wordlist
all_dic['type']=typelist
all_dic['count']=1
all_dic=all_dic[all_dic['type']!='x']##剔除標點符號

df_word_count=all_dic[['word','type','count']].groupby(['word','type'],as_index=False).sum()
##上面的方式得到所有非標點符號的分詞以及其詞性type和總的計數值count,也許有更簡單的方法...
df_word_count_n=df_word_count[df_word_count['type']=='n']##得到所有名詞
df_word_count_n.sort_values(by=['count'],ascending=False,inplace=True)##對所有名詞按照count由高到低排序
#df_word_count_n.head()##得到高頻的名詞

df_word_count_a=df_word_count[df_word_count['type']=='a']##得到所有形容詞
df_word_count_a.sort_values(by=['count'],ascending=False,inplace=True)##對所有名詞按照count由高到低排序

df_word_count_d=df_word_count[df_word_count['type']=='d']##得到所有副詞
df_word_count_d.sort_values(by=['count'],ascending=False,inplace=True)

經過上面的操作,可以看到:

##這就是結果
df_word_count_a.head()
Out[258]: 
       word type  count
102      均勻    a  55749
42       光整    a  43444
170      明顯    a   2152
177  未見明顯異常    a   1594
45       光滑    a    756

df_word_count_a.head(10)
Out[259]: 
       word type  count
102      均勻    a  55749
42       光整    a  43444
170      明顯    a   2152
177  未見明顯異常    a   1594
45       光滑    a    756
139      平整    a    243
33        低    a     95
143       強    a     67
277       高    a     17
190      清晰    a     13

df_word_count_d.head(10)
Out[260]: 
    word type  count
183   正常    d  66607
130    尚    d    503
9     一致    d     98
262  進一步    d     12
15     不    d      8
179    極    d      6
206    稍    d      5
175    未    d      4
212    約    d      4
197    略    d      3

df_word_count_n.head(10)
Out[265]: 
    word type  count
240   脾臟    n  55634
146   形態    n  47149
66    包膜    n  44178
236    脾    n  16244
51     內    n  14709
46    光點    n  14598
274   靜脈    n  11550
247   血流    n   4981
125   實質    n   2910
37    訊號    n   2650

len(df[df['0116'].str.contains(r'光滑')])
Out[261]: 756

len(df[df['0116'].str.contains(r'平整')])
Out[262]: 243


from  snownlp import SnowNLP

for i in df_word_count_a['word']:
    print(i,SnowNLP(i).sentiments)##嘗試對形容詞做情感分析,數值越接近1代表越積極,數值越接近0代表越消極,可以看到大部分是對的,但依然有的判斷明顯有誤
    
均勻 0.8315683780663149
光整 0.24966090817814068##明顯有問題,所以只能手動總結
明顯 0.5262327818078083
未見明顯異常 0.742915865950905
光滑 0.6428571428571428
平整 0.5
低 0.4028629856850714
強 0.6761229314420805
高 0.6582579723940979
清晰 0.8034682080924856
清 0.6394849785407725
大 0.5319597284008428
失常 0.5
厚 0.3550724637681161
清楚 0.5262327818078083
細膩 0.8119658119658117
近 0.5892857142857142
完整 0.8095238095238096
嚴重 0.5262327818078083
弱 0.5283018867924524
團低 0.37787498705799727
偏 0.42934782608695654
較大 0.5319597284008428
不均 0.3379043168750845

這種情況下,我們無法使用snownlp來直接判斷和得到a形容詞和d副詞中哪些可以表達健康(1是對積極消極判斷不準,另一方面積極消極不能代表健康和異常),片語不多,我們通過肉眼判斷出表達身體健康的a和d(目前沒有找到哪種辦法可以做到完全自動由程式處理)

接下來將上面的片語結合re正則來刪除表達健康狀況的片語

adlist=[]
adlist+=list(df_word_count_a['word'][:6])
adlist+=list(df_word_count_d['word'][:1])##眼睛判斷的結果
adlist
##Out[348]: ['均勻', '光整', '明顯', '未見明顯異常', '光滑', '平整', '正常']

def get_restr(adlist):
    s='['
    lenth=len(adlist)
    for i in range(lenth-1):
        s+=(adlist[i])
        s+=('|')
    s+=adlist[-1]
    s+=']'
    return s

restr=get_restr(adlist)
restr
##Out[349]: '[均勻|光整|明顯|未見明顯異常|光滑|平整|正常]'
rs='(,|,|。|,|)*?([^(,|,)]+?)'+restr+'([^(,|,)]*?)(,|,|。|,)'

def delUseless(str):
    return re.sub(r''+rs,'',str)

df_0116_comlpete=str_data[['vid','0116']].dropna()
df_0116_comlpete['0116']=df_0116_comlpete['0116'].apply(delUseless)

可以看到仍然還是存在一些問題,待續...