我負責的主要部分是文本的分類,運用最基礎的樸素貝葉斯分類算法進行處理數據。python
1、數據源算法
採用22673篇文檔的數據集,其中的0.7做爲訓練集,其中的0.3當作測試集來計算roc,測試集一共有6802篇文章的題目和摘要。app
2、數據預處理dom
原始數據是一個TXT中有不少篇文章,包括他的各類屬性,咱們只把須要的題目和摘要提取出來。ide
一、分文檔:函數
把一個TXT的多篇文章,每一篇分到一個TXT裏面,讓每篇文章的惟一標識號做爲文章的名稱。測試
import os def open_text(): #遍歷存放原始文件的目錄,獲取文件內容 for dirname in os.listdir(r'C:\Users\wxx\Desktop\train_split2\train_split2'): for text_name in os.listdir(r'C:\Users\wxx\Desktop\train_split2\train_split2\{}'.format(dirname)): with open(r'C:\Users\wxx\Desktop\train_split2\train_split2\{}\{}'.format(dirname,text_name),'r') as f: clean_text(f.readlines(),dirname,text_name) def clean_text(contents,dirname,text_name): #處理文件內容 if not os.path.exists(r'C:\Users\wxx\Desktop\clean_text\{}'.format(dirname)): #建立新的目錄來存放處理好的文件 os.mkdir(r'C:\Users\wxx\Desktop\clean_text\{}'.format(dirname)) try: with open(r'C:\Users\wxx\Desktop\clean_text\{}\{}'.format(dirname,text_name),'w') as f : i = 0#內容list下標 while i < len(contents): if i == len(contents)-1: #若是是最後一行 f.write(contents[i]) i += 1 continue if not contents[i].startswith(' ') and not contents[i+1].startswith(' '): #當前行和下一行不是一類內容 f.write(contents[i]) i += 1 continue if not contents[i].startswith(' ') and contents[i+1].startswith(' ') : #當前行和下一行是一類內容 i += 1 str = [] str.append(contents[i-1].rstrip('\n')) while i < len(contents) and contents[i].startswith(' '): #合併到一行 str.append(contents[i].rstrip('\n')) i += 1 str.append('\n') f.write(''.join(str)) print('{} write successfully'.format(text_name)) except Exception : print('{} has wrong'.format(text_name)) with open(r'C:\Users\wxx\Desktop\clean_text\error.txt','a') as fe: #記錄下出錯的文件 fe.write('{} has wrong'.format(text_name)) open_text()
二、提取題目和摘要:字體
# -*- coding: UTF-8 -*- from os import path import os import re d = path.dirname(__file__) p = r"C:\Users\tyy1\Desktop\gongzuo\clean_text\Carbon Based" #文件夾目錄 files= os.listdir(p) #獲得文件夾下的全部文件名稱 fd = open('./title and abstract1.txt','a') for file in files: #遍歷文件夾 if not os.path.isdir(file): #判斷是不是文件夾,不是文件夾纔打開 f = open(p+"/"+file); #打開文件 iter_f = iter(f); #建立迭代器 str = "" for line in iter_f: #遍歷文件,一行行遍歷,讀取文本 index = line.find("AB - ") index1 = line.find("TI - ") if 'TI - ' in line: index = index + len("TI - ") s2 = line[index:index+200] fd.write(s2) fd.flush() if 'AB - ' in line: index = index + len("AB - ") s1 = line[index:index+2000] fd.write(s1+'\n') fd.write(" "+'\n') fd.flush()
3、數據處理設計
一、tf-idf算法提取關鍵詞3d
第一步,計算詞頻:
考慮到文章有長短之分,爲了便於不一樣文章的比較,進行"詞頻"標準化。
第二步,計算逆文檔頻率:
第三步,計算TF-IDF:
結果:
import nltk import os from nltk.stem import SnowballStemmer stemmer = SnowballStemmer("english") # nltk.download() from sklearn import feature_extraction from sklearn.feature_extraction.text import TfidfTransformer from sklearn.feature_extraction.text import CountVectorizer # stopwords = nltk.corpus.stopwords.words('english') with open(r'C:\Users\wxx\Desktop\全文\stopwords.txt','r') as f: stopwords = f.readlines() clean_stopwords = [] for stopword in stopwords: clean_stopwords.append(stopword.strip()) # print(clean_stopwords) # tags = ['FW','NN','NNS','NNP','NNPS'] def open_text(): corpus = [] for text_name in os.listdir(r'C:\Users\wxx\Desktop\全文\全文\num'): with open(r'C:\Users\wxx\Desktop\全文\全文\num\{}'.format(text_name),'r') as f: words_first = [] sens = nltk.sent_tokenize(f.read()) for sen in sens: for word in nltk.word_tokenize(sen): words_first.append(stemmer.stem(word.strip())) words_second = [stemmer.stem(w) for w in words_first if w not in clean_stopwords] # words_third = [] # for word_tag in nltk.pos_tag(words_second): # if word_tagwords_second[1] in tags: # words_third.append(stemmer.stem(word_tag[0])) # test = dict(nltk.FreqDist(words_third)) clean_content = ' '.join(words_second) corpus.append(clean_content) return corpus def tfidf(corpus): vectorizer = CountVectorizer() transformer = TfidfTransformer() tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus)) word = vectorizer.get_feature_names() weight = tfidf.toarray() for i in range(len(weight)): wordlist = [] valuelist = [] for j in range(len(word)): wordlist.append(word[j]) valuelist.append(weight[i][j]) wordandvalue = dict(zip(wordlist, valuelist)) dd = sorted(wordandvalue.items(), key=lambda d: d[1], reverse=True) for i in range(5): # 顯示前五個 print(dd[i]) print('--------------------') tfidf(open_text())
二、樸素貝葉斯算法進行分類
第一階段:訓練數據生成訓練樣本集:TF-IDF
第二階段;對每一個類別計算 P(yi)(先驗機率)
第三階段:對每一個特徵屬性計算全部劃分的條件機率P(x/yi)
第四階段:對每一個類別計算P(x/yi)P(yi)
第五階段:以 P(x/yi)P(yi)最大項做爲 的所屬類別
#encoding:utf-8 import pandas as pd import numpy as np import os def read_data( path ,classes): with open(path,'r') as file: lines = file.readlines() finallines = [] pertxt = "" i = 0 for line in lines: if line == '\n': i += 1 else: i = 0 pertxt += line if i >= 2: finallines.append(pertxt) pertxt = "" i = 0 txts = pd.DataFrame({"content": finallines}) txts['classes'] = classes txts = txts.dropna() return txts def cleanFormat_test(data): txts = data stop_txt = pd.read_table(r'C:\Users\PC\Desktop\title and abstract\stopwords.txt', sep='\n', names=['words']) stop_txt = stop_txt.dropna() english_stopwords =stop_txt.words.values.tolist() english_punctuations = [',', '.', ':', ';', '?', '(', ')', '<', '>', '{', '}','[', ']', '!', '@', '#', '%', '$', '*', '/','0','1','2','3','4','5','6','7','8','9',"\n"] finallines = [] for pertxt in txts: no_punctual="" for w in pertxt: if w not in english_punctuations: no_punctual += w else: no_punctual += " " words=no_punctual.replace(" "," ").split() clean_pertxt = "" for word in words: if word not in english_stopwords: if(len(word)>4): clean_pertxt += word+ " " finallines.append(clean_pertxt) return finallines tr1=read_data(r'C:\Users\PC\Desktop\title and abstract\Test Set\Carbon Based.txt','Carbon Based') tr2=read_data(r'C:\Users\PC\Desktop\title and abstract\Test Set\metallic.txt','metallic') tr3=read_data(r'C:\Users\PC\Desktop\title and abstract\Test Set\nano ceramic.txt','nano ceramic') tr4=read_data(r'C:\Users\PC\Desktop\title and abstract\Test Set\Organic Inorganic.txt','Organic Inorganic') tr5=read_data(r'C:\Users\PC\Desktop\title and abstract\Test Set\Polymer.txt','Polymer') tr6=read_data(r'C:\Users\PC\Desktop\title and abstract\Test Set\Semi-Metallic.txt','Semi-Metallic') df_data = pd.concat([tr1,tr2,tr3,tr4,tr5,tr6]) from sklearn.model_selection import train_test_split train_x,test_x,train_y,test_y = train_test_split(df_data['content'].values,df_data['classes'].values,test_size=0.3,random_state=10) words=df_data.content.values.tolist() classes=df_data.classes.values.tolist() orign_content_list = test_x words=cleanFormat_test(words) train_x=cleanFormat_test(train_x) test_x=cleanFormat_test(test_x) from sklearn.feature_extraction.text import CountVectorizer vec = CountVectorizer(analyzer='word', lowercase = False) vec.fit(train_x) #訓練集數據用來擬合分類器 from sklearn.naive_bayes import MultinomialNB classifier = MultinomialNB() classifier.fit(vec.transform(train_x),train_y) print("貝葉斯分類器精度:") print(classifier.score(vec.transform(words), classes))
4、數據可視化
詞雲製做:調用python中 matplotlib WordCloud。
# _*_ coding:utf-8 _*_ #!/usr/bin/python # -*- coding: <encoding name> -*- import sys reload(sys) sys.setdefaultencoding('gbk') from os import path import os from scipy.misc import imread import matplotlib.pyplot as plt from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator # 獲取當前文件路徑 # __file__ 爲當前文件, 在ide中運行此行會報錯,可改成 # d = path.dirname('.') d = path.dirname(__file__) p = r"C:\Users\tyy1\Desktop\gongzuo\wx00-17\wx2016" #文件夾目錄 files= os.listdir(p) #獲得文件夾下的全部文件名稱 s = [] for file in files: #遍歷文件夾 if not os.path.isdir(file): #判斷是不是文件夾,不是文件夾纔打開 f = open(p+"/"+file); #打開文件 iter_f = iter(f); #建立迭代器 str = " " for line in iter_f: #遍歷文件,一行行遍歷,讀取文本 str = str + line s.append(str) #每一個文件的文本存到list中 # 設置背景圖片,也就是掩膜圖像,在非白色部分咱們的統計好的詞頻會顯示在這裏 alice_coloring = imread(path.join(d, "16.jpg")) stopwords = set(STOPWORDS) stopwords.add("Journal") stopwords.add("Article") stopwords.add("using") stopwords.add("used") stopwords.add("based") stopwords.add("also") stopwords.add("However") wc = WordCloud(background_color="black", # 背景顏色<br>#max_words=2000,# 詞雲顯示的最大詞數 mask=alice_coloring, # 設置背景圖片 stopwords=stopwords, max_font_size=300, # 字體最大值 random_state=50) # 上述函數設計了詞雲格式 # 生成詞雲, 能夠用generate輸入所有文本(中文很差分詞),也能夠咱們計算好詞頻後使用generate_from_frequencies函數 wc.generate(' '.join(s)) # 文本詞頻統計函數,本函數自動統計詞的個數,以字典形式內部存儲,在顯示的時候詞頻大的,字體也大 # 從背景圖片生成顏色值 image_colors = ImageColorGenerator(alice_coloring) # 如下代碼顯示圖片 plt.figure() # recolor wordcloud and show # we could also give color_func=image_colors directly in the constructor plt.imshow(wc.recolor(color_func=image_colors)) plt.axis("off") plt.show()
5、分類結果評估
(1)數據集:
採用2萬多篇文檔的數據集中的0.3測試集來計算roc,一共有6802篇文章的題目和摘要。
去標點符號:english_punctuations = [',', '.', ':', ';', '?', '(', ')', '<', '>', '{', '}','[', ']', '!', '@', '#', '%', '$', '*', '/',"\n"]
去停用詞:附件有個stopwords.txt 沒有轉換大小寫。
(2)精確度、召回率、F值:
混淆矩陣(Confusion Matrix):
真正例(True Positive;TP):將一個正例正確判斷成一個正例
僞正例(False Positive;FP):將一個反例錯誤判斷爲一個正例
真反例(True Negtive;TN):將一個反例正確判斷爲一個反例
僞反例(False Negtive;FN):將一個正例錯誤判斷爲一個反例
Ⅰ.精確率(Precision)
預測爲正例的樣本中,真正爲正例的比率.
精確率本質來講是對於預測結果來講的.表示對於結果來講,我對了多少。
Ⅱ.召回率(Recall)
預測爲正例的真實正例(TP)佔全部真實正例的比例.
召回率是對於原來的樣本而言的.表示在原來的樣本中,我預測中了其中的多少。
Ⅳ.F值
表示精確率和召回率的調和均值
微精確度爲多個混淆矩陣的精確率的平均
微精確度:0.758751607
微召回率爲多個混淆矩陣的召回率的平均
微召回率:0.763060747
微F1: 0.76090008
(3)AUC和ROC曲線
Ⅰ.FPR僞正類率(False Positive Rate,FPR)------橫座標
Ⅱ.TPR真正類率(Ture Positive Rate,TPR)-------縱座標
預測爲正且實際爲正的樣本佔全部正樣本的比例.你會發現,這個不就是召回率
ROC就是對於一個分類器,給定一些閾值,每個閾值均可以獲得一組(FPR,TPR),以FPR做爲橫座標,TPR做爲縱座標
AUC:爲ROC曲線下面積
第一列是每一篇文獻屬於這一類的機率
第二列是真實的類別 若是屬於這類就爲1,不屬於就爲0
放入Excel中,而後再使用R語言計算AUC,能夠直接畫出ROC曲線。
第一步:首先加載這個選中的程序包
第二步,導入文件:
第三步:畫圖,FALSE和TURE是作升序仍是降序
第四步:前百分之多少的AUC
(其中top=0.01能夠不設置)
第五步:算AUC
獲得的結果:
第一類:
第二類:
第三類:
第四類:
第五類:
第六類: