中文自然语言处理(NLP)(三)运用python jieba模块计算知识点当中关键词的词频
? ?
前兩次鏈接:中文自然語言處理(NLP)(一)python jieba模塊的初步使用? ? ? ?中文自然語言處理(NLP)(二)python jieba模塊的進一步學習和xlrd模塊? 續上次的隨筆之后,我已經基本掌握了jieba和xlrd的基本操作,現在開始運用這兩個模塊對數據進行一些處理。
? 情景大概如下:excel文件當中存有一些題目,這些題目標注了其所屬的知識點,現在需要獲取的數據有:每一道題目當中的關鍵詞(通過分詞獲得);這些關鍵詞在各個知識點當中出現的概率;每個知識點當中這些關鍵詞出現的百分比,這三項內容。
? 第一項目標數據只要對各個題目進行分詞操作,再對停用詞表人工地調整一下即可,主要在于獲取后兩項百分比。
? 第一次考慮到這個問題,由于對python不夠熟悉,我想到用字典(dict)這種數據結構來存儲數據,也就是以關鍵詞作為字典名,每一個知識點作為該字典的一個鍵值,這個關鍵詞在知識點所屬的題目當中出現一次就將字典當中相應鍵值的數值加1,這樣就獲得了一組以所有出現過的關鍵詞為名的字典,再將字典當中的頻率除以總次數就可以得到概率了。但是通過這個字典組,能夠得到的只是某一個關鍵詞在各個知識點當中出現的概率,要想得到某個知識點當中,各個關鍵詞出現的概率,還需要建立另外的一個以知識點為名的字典組,這是非常繁瑣的。而且假設有m個關鍵詞,n個知識點的話,這種方法就要占用2*m*n的空間。
? 下面貼的代碼是建立以關鍵詞為名的字典組的代碼,寫的很垃圾所以很冗長,沒什么時間就不用看了,大致流程就是:提取所有需要分詞的文本、同時提取所有的知識點>將這些文本進行分詞以獲取所有出現的關鍵詞>將這些關鍵詞、知識點去重,獲得了所有關鍵詞和知識點的索引>for循環遍歷這些關鍵詞來構建詞典。同樣的流程再將另外的詞典組構建出來即可。
1 def striped(excel_path): 2 3 #在excel當中已經借助excel自帶的排序功能將數據按照三級知識點進行了排序,意思是數據是分片連續的 4 #這里先暫時只做單一三級知識點的題目 5 excel_file=xlrd.open_workbook(excel_path)#為xlrd庫設置工作路徑 6 sheet=excel_file.sheet_by_index(0)#這里選取excel文件當中的sheet1:教輔題目作為樣本 7 countRow=sheet.nrows#獲取總行數 8 text_num=1#題干對應第2列,編號應當為1 9 knowledge_num=11#三級知識點對應第十列,編號列應當為9 10 #先為各個知識點創建一個列表 11 knowledge_points=[] 12 stop_list=set_stop_dict_txt('D:/+大創/數學題庫/stop_words1.txt') 13 #先加載停用詞表 14 #第一個for循環實際上是為了獲取所有的單知識點索引 15 all_txt='D:/+大創/數學題庫/demo2/all_text.txt' 16 for x in range(1,countRow): 17 listrow=sheet.row(x) 18 knowedge_point=listrow[knowledge_num].value 19 divi=knowedge_point.split('^.^') 20 if len(divi)==1 and divi[0] not in knowledge_points: 21 knowledge_points.append(divi[0]) 22 #將單知識點添加進去,條件限制為:單知識點并且是第一次出現,防止重復之后還要進行去重復操作 23 all_file=open('D:/+大創/數學題庫/demo2/all_text.txt','w',encoding='utf-8') 24 for i in range(1,countRow): 25 listrow=sheet.row(i) 26 knowedge_point=listrow[knowledge_num].value 27 divi=knowedge_point.split('^.^') 28 if len(divi)==1: 29 que_data=listrow[1].value 30 ss='%s'%que_data 31 all_file.write(ss+'\n') 32 all_file.close() 33 read_txt=open('D:/+大創/數學題庫/demo2/all_text.txt',encoding='utf-8').read() 34 all_words_with_attr=[(x.word,x.flag)for x in psg.cut(read_txt) if x.flag=='n' and x.word not in stop_list] 35 num_of_words=len(all_words_with_attr) 36 word_list=[] 37 word_is_apprared={} 38 word_apprared_num={} 39 for x in all_words_with_attr: 40 word_is_apprared[x]=False 41 word_apprared_num[x]=0 42 for x in all_words_with_attr: 43 if word_is_apprared[x]==False: 44 word_is_apprared[x]=True 45 word_apprared_num[x]=word_apprared_num[x]+1 46 word_list.append(x) 47 else: 48 word_apprared_num[x]=word_apprared_num[x]+1 49 #現在詞典word_apprared_num當中存儲的就是每一個詞語的出現次數,列表word_list當中存儲的就是所有的詞語 50 51 52 appeared={}#創建字典來記錄知識點是否出現過,方便之后統計知識點出現的次數 53 num_of_points={}#創建字典來記錄知識點出現的次數 54 has_appeared={} 55 num_of_all={}#存儲每一個詞在所有分詞結果當中的出現次數 56 for x in knowledge_points: 57 appeared[x]=False#初始值賦為假 58 num_of_points[x]=0#出現次數初值賦為0 59 has_appeared[x]=False#這個字典創建的目的是方便之后的題干提取工作 60 for i in range(1,countRow): 61 listrow=sheet.row(i) 62 point=listrow[knowledge_num].value 63 point_divi=point.split('^.^') 64 if len(point_divi)==1: 65 if appeared[point_divi[0]]==False: 66 appeared[point_divi[0]]=True 67 num_of_points[point_divi[0]]=num_of_points[point_divi[0]]+1 68 #出現狀況設置為真,出現次數自加 69 else: 70 #已經出現過一次,出現次數自加就完事了 71 num_of_points[point_divi[0]]=num_of_points[point_divi[0]]+1 72 point_texts={} 73 for i in range(1,countRow): 74 list_row=sheet.row(i) 75 know_point=list_row[knowledge_num].value 76 if know_point in knowledge_points: 77 #這個知識點是單知識點中的一個 78 if has_appeared[know_point]==False: 79 #說明這個知識點是第一次出現 80 has_appeared[know_point]=True 81 texts_list=[]#創建一個列表來存儲題干信息 82 text=list_row[text_num].value#將對應的題干單元格的內容提取出來 83 texts_list.append(text)#將文本存入list當中 84 point_texts[know_point]=texts_list#以這個文本為相應的知識點創建字典詞條,一個知識點對應一個列表,之后加入進來的題干就在list里面添加 85 #向下一行的知識點進行檢測,看它是否是一個新的,沒出現過的知識點 86 #但是還是要注意我們現在要的是單一的知識點 87 i=i+1 88 list_row=sheet.row(i) 89 next_point=list_row[knowledge_num].value 90 next_divi=next_point.split('^.^') 91 if len(next_divi)==1: 92 while has_appeared[next_point]==True: 93 texts_list.append(list_row[text_num].value) 94 #這時是出現過的狀況,將這一行對應的題干也要添加進去 95 #接下來繼續向下一行進行檢測 96 i=i+1 97 list_row=sheet.row(i) 98 next_point=list_row[knowledge_num].value 99 next_divi=next_point.split('^.^') 100 if len(next_divi)!=1: 101 break#這就相當于是檢測到了另外的知識點,不再循環下去 102 with open('D:/+大創/數學題庫/demo2/striped.txt','w+',encoding='utf-8')as f: 103 for x in knowledge_points: 104 f.write('{0}:{1}\n'.format(x,point_texts[x])) 105 f.close() 106 #現在已經將同一個知識點下的題干信息保存在txt文件當中了,格式為:"知識點:題干+題干+。。。" 107 #接下來進行分詞 108 #考慮到txt文件一行的最大長度為1024個字,但是有的題干信息過長,就會導致折行,用readlines()方法就會有不必要的麻煩 109 #所以這里分詞的文本獲取就使用寫文件之前的詞典,生成的txt文件僅做展示和代碼檢測用 110 point_words={} 111 words_num_of_point={} 112 result_path='D:\+大創\數學題庫\demo2\striped_with_fre.txt' 113 result_path_big='D:\+大創\數學題庫\demo2\striped_with_fre_big.txt' 114 f=open(result_path_big,'w+',encoding='utf-8') 115 for point in knowledge_points: 116 text_to_cut=point_texts[point]#這是這個知識點應當被分詞的文本 117 str_to_cut1=[]#將列表類型轉換為str類型而設置的空列表 118 for sen in text_to_cut: 119 str_sen=str(sen) 120 str_to_cut1.append(str_sen) 121 str_to_cut="".join(str_to_cut1) 122 cut_text=[(x.word,x.flag)for x in psg.cut(str_to_cut) if (x.flag=='n' or x.flag=='l') and x.word not in stop_list] 123 cut_list=list(cut_text) 124 #在分詞結果當中僅僅使用詞性為名詞的詞語,并且這個詞本身不在停用詞表當中 125 point_words[point]=cut_text 126 words_num_of_point[point]=len(cut_list)#jieba.cut()返回的是一個generator,這里將其轉化為list方便統計長度(也就是知識點的關鍵詞總數) 127 #這樣就可以將所有的分詞結果按知識點存入詞典當中 128 #格式為:[('詞1','詞性'),('詞2','n')...] 129 #但是這里的分詞結果當中還是有重復的,還是要進行去重和計數工作 130 word_apprared={}#創建詞典存儲知識點的詞匯的出現情況 131 word_num={}#這個詞典中存儲的是詞在這個知識點的次數 132 word_frequency={}#創建詞典存儲詞匯的出現頻率,計算公式為:詞匯在這個知識點中的出現次數/這個知識點的詞匯總數 133 words_only=[] 134 for word in cut_text: 135 word_apprared[word[0]]=False 136 word_num[word[0]]=0 137 for word in cut_text: 138 if word_apprared[word[0]]==False: 139 #這是這個詞語第一次出現 140 word_apprared[word[0]]=True 141 word_num[word[0]]=word_num[word[0]]+1 142 words_only.append(word[0]) 143 else: 144 #這個詞語不是第一次出現 145 word_num[word[0]]=word_num[word[0]]+1 146 words_with_fre=[] 147 for x in words_only: 148 pair=[] 149 pair.append(x) 150 fre=word_num[x]/len(cut_list) 151 pair.append(fre) 152 words_with_fre.append(str(pair)) 153 #f.write(point+':'+x+','+fre+'\n') 154 #print(point+':'+','.join(words_with_fre)) 155 f.write(point+':'+','.join(words_with_fre)+'\n') 156 f.close()? 這次的隨筆當中涉及的方法不是最好的,下次把改進過的方法寫出來(也很麻煩就是了),由于學藝不精,寫的代碼很繁瑣,如果有不同的看法的話,還請大家不吝賜教。
轉載于:https://www.cnblogs.com/aLieb/p/11152109.html
總結
以上是生活随笔為你收集整理的中文自然语言处理(NLP)(三)运用python jieba模块计算知识点当中关键词的词频的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: step1.day11 C语言基础练习之
- 下一篇: LeetCode 1004.最长连续1的