(已修改)機器學習之文本分類(附帶訓練集+數據集+所有代碼)

本博客是我對之前博客進行的一些優化,對文件的處理,以及添加更多的註釋讓大家在NLP,文本分類等領域能夠更快的讓代碼跑起來。

原文鏈接:https://blog.csdn.net/qq_28626909/article/details/80382029

關於TF-IDF,樸素貝葉斯,分詞,停用詞等前面的博客(原文鏈接開頭以貼出)已經講得非常詳細了,這裏就不囉嗦了,本博客是講如何將代碼跑起來,因爲之前的代碼是我還是個菜鳥時候寫的,所以很多東西大家看不清楚,這裏我貼上當時大家問的主要問題以及在本博客中提出的解決方案

1.dat文件不能查看       解決方案:生成詳細的txt文件,大家可以直接查看

2.不清楚生成的文件內容      解決方案:生成詳細的txt文件,大家可以直接查看

3.文件路徑的修改(我之前沒有註釋) 解決方案:全部替換絕對路徑爲相對路徑,並且添加註釋,讓大家下載下來之後可以直接跑

4.有的同學有環境問題    解決方案:博客最後會放出大多數同學出現的問題以及解決方案

文件(文件夾名稱爲CSDN,進入之後的截圖如下):

大多數同學用的編譯器是pycharm,所以這裏我將演示pycharm的運行代碼

請大家將文件夾移動至pycharm中,

這一個python文件我寫的都是相對路徑,所以大家應該不用改任何路徑即可運行(只要放在一起就行)

    datapath = "./data/"  #原始數據路徑
    stopWord_path = "./stop/stopword.txt"#停用詞路徑
    test_path = "./test/"            #測試集路徑
    '''
    以上三個文件路徑是已存在的文件路徑,下面的文件是運行代碼之後生成的文件路徑
    dat文件是爲了讀取方便做的,txt文件是爲了給大家展示做的,所以想查看分詞,詞頻矩陣
    詞向量的詳細信息請查看txt文件,dat文件是通過正常方式打不開的
    '''
    test_split_dat_path =  "./test_set.dat" #測試集分詞bat文件路徑
    testspace_dat_path ="./testspace.dat"   #測試集輸出空間矩陣dat文件
    train_dat_path = "./train_set.dat"  # 讀取分詞數據之後的詞向量並保存爲二進制文件
    tfidfspace_dat_path = "./tfidfspace.dat"  #tf-idf詞頻空間向量的dat文件
    '''
    以上四個爲dat文件路徑,是爲了存儲信息做的,不要打開
    '''
    test_split_path = './split/test_split/'   #測試集分詞路徑
    split_datapath = "./split/split_data/"  # 對原始數據分詞之後的數據路徑
    '''
    以上兩個路徑是分詞之後的文件路徑,大家可以生成之後自行打開查閱學習
    '''
    tfidfspace_path = "./tfidfspace.txt"  # 將TF-IDF詞向量保存爲txt,方便查看
    tfidfspace_arr_path = "./tfidfspace_arr.txt"  # 將TF-IDF詞頻矩陣保存爲txt,方便查看
    tfidfspace_vocabulary_path = "./tfidfspace_vocabulary.txt"  # 將分詞的詞彙統計信息保存爲txt,方便查看
    testSpace_path = "./testSpace.txt"  #測試集分詞信息
    testSpace_arr_path = "./testSpace_arr.txt"  #測試集詞頻矩陣信息
    trainbunch_vocabulary_path = "./trainbunch_vocabulary.txt" #所有分詞詞頻信息
    tfidfspace_out_arr_path = "./tfidfspace_out_arr.txt"   #tfidf輸出矩陣信息
    tfidfspace_out_word_path = "./tfidfspace_out_word.txt" #單詞形式的txt
    testspace_out_arr_path = "./testspace_out_arr.txt"     #測試集輸出矩陣信息
    testspace_out_word_apth ="./testspace_out_word.txt"    #測試界單詞信息
    '''
    以上10個文件是dat文件轉化爲txt文件,大家可以查詢信息,這是NLP(自然語言處理)非常珍貴的資源
    '''

這段代碼是對各個文件的註釋,裏面的內容應該算是比較詳細了。下面貼出完整代碼:

#!D:/workplace/python
# -*- coding: utf-8 -*-
# @File  : TFIDF_naive_bayes_wy.py
# @Author: WangYe
# @Date  : 2019/5/29
# @Software: PyCharm
# 機器學習之文本分類(附帶訓練集+數據集+所有代碼)
# 博客鏈接:https://blog.csdn.net/qq_28626909/article/details/80382029
import jieba
from numpy import *
import pickle  # 持久化
import os
from sklearn.feature_extraction.text import TfidfTransformer  # TF-IDF向量轉換類
from sklearn.feature_extraction.text import TfidfVectorizer  # TF_IDF向量生成類
from sklearn.datasets.base import Bunch
from sklearn.naive_bayes import MultinomialNB  # 多項式貝葉斯算法


def readFile(path):
    with open(path, 'r', errors='ignore') as file:  # 文檔中編碼有些問題,所有用errors過濾錯誤
        content = file.read()
        file.close()
        return content


def saveFile(path, result):
    with open(path, 'w', errors='ignore') as file:
        file.write(result)
        file.close()


def segText(inputPath, resultPath):
    fatherLists = os.listdir(inputPath)  # 主目錄
    for eachDir in fatherLists:  # 遍歷主目錄中各個文件夾
        eachPath = inputPath + eachDir + "/"  # 保存主目錄中每個文件夾目錄,便於遍歷二級文件
        each_resultPath = resultPath + eachDir + "/"  # 分詞結果文件存入的目錄
        if not os.path.exists(each_resultPath):
            os.makedirs(each_resultPath)
        childLists = os.listdir(eachPath)  # 獲取每個文件夾中的各個文件
        for eachFile in childLists:  # 遍歷每個文件夾中的子文件
            eachPathFile = eachPath + eachFile  # 獲得每個文件路徑
            #  print(eachFile)
            content = readFile(eachPathFile)  # 調用上面函數讀取內容
            # content = str(content)
            result = (str(content)).replace("\r\n", "").strip()  # 刪除多餘空行與空格
            # result = content.replace("\r\n","").strip()

            cutResult = jieba.cut(result)  # 默認方式分詞,分詞結果用空格隔開
            saveFile(each_resultPath + eachFile, " ".join(cutResult))  # 調用上面函數保存文件


def bunchSave(inputFile, outputFile):
    catelist = os.listdir(inputFile)
    bunch = Bunch(target_name=[], label=[], filenames=[], contents=[])
    bunch.target_name.extend(catelist)  # 將類別保存到Bunch對象中
    for eachDir in catelist:
        eachPath = inputFile + eachDir + "/"
        fileList = os.listdir(eachPath)
        for eachFile in fileList:  # 二級目錄中的每個子文件
            fullName = eachPath + eachFile  # 二級目錄子文件全路徑
            bunch.label.append(eachDir)  # 當前分類標籤
            bunch.filenames.append(fullName)  # 保存當前文件的路徑
            bunch.contents.append(readFile(fullName).strip())  # 保存文件詞向量
    with open(outputFile, 'wb') as file_obj:  # 持久化必須用二進制訪問模式打開
        pickle.dump(bunch, file_obj)
        # pickle.dump(obj, file, [,protocol])函數的功能:將obj對象序列化存入已經打開的file中。
        # obj:想要序列化的obj對象。
        # file:文件名稱。
        # protocol:序列化使用的協議。如果該項省略,則默認爲0。如果爲負值或HIGHEST_PROTOCOL,則使用最高的協議版本


def readBunch(path):
    with open(path, 'rb') as file:
        bunch = pickle.load(file)
        # pickle.load(file)
        # 函數的功能:將file中的對象序列化讀出。
    return bunch


def writeBunch(path, bunchFile):
    with open(path, 'wb') as file:
        pickle.dump(bunchFile, file)


def getStopWord(inputFile):
    stopWordList = readFile(inputFile).splitlines()
    return stopWordList


def getTFIDFMat(inputPath, stopWordList, outputPath,
                tftfidfspace_path,tfidfspace_arr_path,tfidfspace_vocabulary_path):  # 求得TF-IDF向量
    bunch = readBunch(inputPath)
    tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[],
                       vocabulary={})
    '''讀取tfidfspace'''
    tfidfspace_out = str(tfidfspace)
    saveFile(tftfidfspace_path, tfidfspace_out)
    # 初始化向量空間
    vectorizer = TfidfVectorizer(stop_words=stopWordList, sublinear_tf=True, max_df=0.5)
    transformer = TfidfTransformer()  # 該類會統計每個詞語的TF-IDF權值
    # 文本轉化爲詞頻矩陣,單獨保存字典文件
    tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
    tfidfspace_arr = str(vectorizer.fit_transform(bunch.contents))
    saveFile(tfidfspace_arr_path, tfidfspace_arr)
    tfidfspace.vocabulary = vectorizer.vocabulary_  # 獲取詞彙
    tfidfspace_vocabulary = str(vectorizer.vocabulary_)
    saveFile(tfidfspace_vocabulary_path, tfidfspace_vocabulary)
    '''over'''
    writeBunch(outputPath, tfidfspace)


def getTestSpace(testSetPath, trainSpacePath, stopWordList, testSpacePath,
                 testSpace_path,testSpace_arr_path,trainbunch_vocabulary_path):
    bunch = readBunch(testSetPath)
    # 構建測試集TF-IDF向量空間
    testSpace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[],
                      vocabulary={})
    '''
       讀取testSpace
       '''
    testSpace_out = str(testSpace)
    saveFile(testSpace_path, testSpace_out)
    # 導入訓練集的詞袋
    trainbunch = readBunch(trainSpacePath)
    # 使用TfidfVectorizer初始化向量空間模型  使用訓練集詞袋向量
    vectorizer = TfidfVectorizer(stop_words=stopWordList, sublinear_tf=True, max_df=0.5,
                                 vocabulary=trainbunch.vocabulary)
    transformer = TfidfTransformer()
    testSpace.tdm = vectorizer.fit_transform(bunch.contents)
    testSpace.vocabulary = trainbunch.vocabulary
    testSpace_arr = str(testSpace.tdm)
    trainbunch_vocabulary = str(trainbunch.vocabulary)
    saveFile(testSpace_arr_path, testSpace_arr)
    saveFile(trainbunch_vocabulary_path, trainbunch_vocabulary)
    # 持久化
    writeBunch(testSpacePath, testSpace)


def bayesAlgorithm(trainPath, testPath,tfidfspace_out_arr_path,
                   tfidfspace_out_word_path,testspace_out_arr_path,
                   testspace_out_word_apth):
    trainSet = readBunch(trainPath)
    testSet = readBunch(testPath)
    clf = MultinomialNB(alpha=0.001).fit(trainSet.tdm, trainSet.label)
    # alpha:0.001 alpha 越小,迭代次數越多,精度越高
    # print(shape(trainSet.tdm))  #輸出單詞矩陣的類型
    # print(shape(testSet.tdm))
    '''處理bat文件'''
    tfidfspace_out_arr = str(trainSet.tdm)  # 處理
    tfidfspace_out_word = str(trainSet)
    saveFile(tfidfspace_out_arr_path, tfidfspace_out_arr)  # 矩陣形式的train_set.txt
    saveFile(tfidfspace_out_word_path, tfidfspace_out_word)  # 文本形式的train_set.txt

    testspace_out_arr = str(testSet)
    testspace_out_word = str(testSet.label)
    saveFile(testspace_out_arr_path, testspace_out_arr)
    saveFile(testspace_out_word_apth, testspace_out_word)

    '''處理結束'''
    predicted = clf.predict(testSet.tdm)
    total = len(predicted)
    rate = 0
    for flabel, fileName, expct_cate in zip(testSet.label, testSet.filenames, predicted):
        if flabel != expct_cate:
            rate += 1
            print(fileName, ":實際類別:", flabel, "-->預測類別:", expct_cate)
    print("erroe rate:", float(rate) * 100 / float(total), "%")



# 分詞,第一個是分詞輸入,第二個參數是結果保存的路徑

#
if __name__ == '__main__':
    datapath = "./data/"  #原始數據路徑
    stopWord_path = "./stop/stopword.txt"#停用詞路徑
    test_path = "./test/"            #測試集路徑
    '''
    以上三個文件路徑是已存在的文件路徑,下面的文件是運行代碼之後生成的文件路徑
    dat文件是爲了讀取方便做的,txt文件是爲了給大家展示做的,所以想查看分詞,詞頻矩陣
    詞向量的詳細信息請查看txt文件,dat文件是通過正常方式打不開的
    '''
    test_split_dat_path =  "./test_set.dat" #測試集分詞bat文件路徑
    testspace_dat_path ="./testspace.dat"   #測試集輸出空間矩陣dat文件
    train_dat_path = "./train_set.dat"  # 讀取分詞數據之後的詞向量並保存爲二進制文件
    tfidfspace_dat_path = "./tfidfspace.dat"  #tf-idf詞頻空間向量的dat文件
    '''
    以上四個爲dat文件路徑,是爲了存儲信息做的,不要打開
    '''
    test_split_path = './split/test_split/'   #測試集分詞路徑
    split_datapath = "./split/split_data/"  # 對原始數據分詞之後的數據路徑
    '''
    以上兩個路徑是分詞之後的文件路徑,大家可以生成之後自行打開查閱學習
    '''
    tfidfspace_path = "./tfidfspace.txt"  # 將TF-IDF詞向量保存爲txt,方便查看
    tfidfspace_arr_path = "./tfidfspace_arr.txt"  # 將TF-IDF詞頻矩陣保存爲txt,方便查看
    tfidfspace_vocabulary_path = "./tfidfspace_vocabulary.txt"  # 將分詞的詞彙統計信息保存爲txt,方便查看
    testSpace_path = "./testSpace.txt"  #測試集分詞信息
    testSpace_arr_path = "./testSpace_arr.txt"  #測試集詞頻矩陣信息
    trainbunch_vocabulary_path = "./trainbunch_vocabulary.txt" #所有分詞詞頻信息
    tfidfspace_out_arr_path = "./tfidfspace_out_arr.txt"   #tfidf輸出矩陣信息
    tfidfspace_out_word_path = "./tfidfspace_out_word.txt" #單詞形式的txt
    testspace_out_arr_path = "./testspace_out_arr.txt"     #測試集輸出矩陣信息
    testspace_out_word_apth ="./testspace_out_word.txt"    #測試界單詞信息
    '''
    以上10個文件是dat文件轉化爲txt文件,大家可以查詢信息,這是NLP(自然語言處理)非常珍貴的資源
    '''

    #輸入訓練集
    segText(datapath,#讀入數據
            split_datapath)#輸出分詞結果
    bunchSave(split_datapath,#讀入分詞結果
              train_dat_path)  # 輸出分詞向量
    stopWordList = getStopWord(stopWord_path)  # 獲取停用詞表
    getTFIDFMat(train_dat_path, #讀入分詞的詞向量
                stopWordList,    #獲取停用詞表
                tfidfspace_dat_path, #tf-idf詞頻空間向量的dat文件
                tfidfspace_path, #輸出詞頻信息txt文件
                tfidfspace_arr_path,#輸出詞頻矩陣txt文件
                tfidfspace_vocabulary_path)  #輸出單詞txt文件
    '''
    測試集的每個函數的參數信息請對照上面的各個信息,是基本相同的
    '''
    #輸入測試集
    segText(test_path,
            test_split_path)  # 對測試集讀入文件,輸出分詞結果
    bunchSave(test_split_path,
              test_split_dat_path)  #
    getTestSpace(test_split_dat_path,
                 tfidfspace_dat_path,
                 stopWordList,
                 testspace_dat_path,
                 testSpace_path,
                 testSpace_arr_path,
                 trainbunch_vocabulary_path)# 輸入分詞文件,停用詞,詞向量,輸出特徵空間(txt,dat文件都有)
    bayesAlgorithm(tfidfspace_dat_path,
                   testspace_dat_path,
                   tfidfspace_out_arr_path,
                   tfidfspace_out_word_path,
                   testspace_out_arr_path,
                   testspace_out_word_apth)

然後我們運行代碼:

代碼的輸出仍然不變,但是會生成很多文件:

split文件夾中是訓練集和測試集的文詞文件

剩下的dat文件是打不開的,但是我轉成相應的txt文件了,每個文件在上面都有註釋,大家針對自己想要的一一對應查閱,這是非常好的NLP的學習資源,我這裏隨便截取兩個

第一張圖已經是詞頻矩陣了,將tfidf的值已經計算出來了,第二個是單詞出現頻率,詳細請參考開始我放出的原博客鏈接

(如果你的打開有亂碼,請轉爲GBK,記事本自動轉換不用擔心,pycharm請手動點擊,如下圖)

最後,我想說一下,因爲很多人可能是新手或者剛入行,我這裏附上常見的一些問題,因爲我當時開始學的時候也是有個大哥在幫我。

以下爲同學們給我發的微信bug圖片:

1.

出現這種問題是缺少包,我們可以在終端輸入 

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

some-package 到時候替換爲 缺少的模塊,以上圖代碼爲例,分別替換爲    jieba,numpy ,scikit-learn

然後這裏肯定有人問,終端在哪?兩個辦法進入終端:

                  1.window下按win + r ,輸入cmd,然後複製上面的代碼(路徑無所謂)

                          linux下直接輸入即可

                   2.pycharm下點這個

然後輸入,回車就ok了

當然還有很多其他辦法,我這裏就說兩個比較適合新手的方法

2.

也有同學出現pycharm中缺少環境的,但是大家的疑問是我裝過python或者 anaconda了,怎麼缺少環境呢?

這裏我放出其他博客的鏈接,大家可以參考

https://blog.csdn.net/weixin_41923961/article/details/86584683

正常學習文件以及代碼下載鏈接(僅有輸入文件,運行後可生成輸出文件,推薦大家學習使用):

鏈接:https://pan.baidu.com/s/1IW6kMev17sjyPFdizsS13g 
提取碼:ap7m 

 

最後啊,因爲有人是給學校交作業啊什麼,比較急,什麼明天不交就掛科了什麼的。。。我這裏再放一個鏈接,這是我生成好的數據文件,大家可以直接交了。。。但是我不推薦啊,畢竟我都這麼費勁寫博客教大家怎麼運行我的代碼了

 

急着明天交作業的同學的生成文件,代碼,以及運行截圖(無水印)下載鏈接(非常不推薦,不值得學習):

鏈接:https://pan.baidu.com/s/1arv3b-poyMUFxz3dcaSm5g 
提取碼:ofa2 

 

由於提問評論人太多,這裏我留下個人微信:wy1119744330     添加好友請備註  :CSDN博客

你們的問題我都會盡量滿足,謝謝大家

最後再附上原博客鏈接:https://blog.csdn.net/qq_28626909/article/details/80382029

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章