分類問題集錦及練習

Sklearn 與 TensorFlow 機器學習實用指南
https://hand2st.apachecn.org/#/

一. 分類問題種類

  1. 二分類
  2. 多類分類
  3. 多標籤分類
  4. 多輸出分類
  5. 層級分類

二. 評價指標

  1. 預備知識——混淆矩陣

  2. 準確率

  3. 召回率

  4. F1值

  5. ROC曲線

三.分類流程(預處理、分詞、去停用詞、取名詞、特徵提取、特徵加權tf_idf、構造分類器)

3.1.分詞(以jieba庫爲例)

1.算法:基於概率圖模型的條件隨機場
概率圖模型:是一類用圖模式來表達基於概率相關的模型的總稱。
(1)模型表示2種:貝葉斯網絡(有向、因果)、馬爾科夫隨機場(無向、相互作用)
(2)模型學習:轉化爲數學公式
(3)模型預測:
2.條件隨機場(判別式無向圖模型)
(1)基本思路:對漢字進行標註即由字構成詞(組詞),不僅考慮文字詞語出現的頻率信息,而且考慮上下文語境,具備較好的學習能力,對歧義詞和未登錄詞的識別具有良好的效果;
缺點:訓練週期長、運營時計算量大,性能不如詞典分詞
(2)具體實現:
CRF認爲一個字有四種狀態:詞頭(Begin,B)、詞中(Middle,M)、詞尾(End,E)、單字成詞(Single,S)。
分詞過程:對詞進行標註後、將B和E之間的字以及S單字構成分詞。
訓練集:已經標註好的語料庫
特徵學習過程4步走:
a)統計某個字出現的總次數;
b) 統計某個字出現爲B、M、E、S的概率(在某種狀態下出現的次數/總次數)
c)統計某個字在某個狀態下,轉移到下一個狀態的概率(狀態轉移概率的計算)疑問,怎麼計算
d)a、b、c過程與隱馬爾可夫過程相似,但是條件隨機場會學習上下文關係。如當前狀態爲B的“我”,下一個字是“們”的概率,當前狀態爲S的“我”,上一個字是“的”的概率,下一個字是“愛”的概率。
分詞:將輸入變成字符數組,如“我喜歡喫芒果”變爲【‘我’,‘喜’,‘歡’,‘喫’,‘芒’,‘果’】;
取出特徵學習過程中學習到的每個字的特徵;
爲確定每個字的狀態,可繪製一個表格;
利用維特比算法求出概率最大路徑,取出路徑中對應的狀態,完成分詞。
代碼實現:

# jieba庫的分詞算法:基於概率圖模型的條件隨機場
# git https://github.com/xgli/jieba
import jieba
seg_list = jieba.cut("我喜歡喫芒果",cut_all=True,HMM=True)
#分詞兩種模式,全模式、精確模式(默認),搜索引擎模式;是否使用HMM模型
print(",".join(seg_list)) #引號內的是分隔符
# 分詞之後將語料庫存入某一路徑
# 這裏存儲模式爲Bunch類型
from sklearn.datasets.base import Bunch  # Bunch類似字典結構
bunch = Bunch(target_name = [],label =[],filenames=[],contents =[])
# target_name:整個數據集類別集合,label:所有文本標籤的集合,filenames:所有文本文件的名稱,contents:分詞後的文本文件(一個文本文件一行)

3.分詞中存在的問題

3.2.去停用詞

停用詞表(包括標點符號、語氣助詞等)

#1.分詞以及去停用詞(針對數據集2的)
#數據集:https://github.com/cystanford/text_classification
#分詞算法 https://github.com/xgli/jieba
import os
import jieba

# 未分詞語料庫路徑
corpus_path =r'I:\代碼\tensorflow\文本分類\分類數據\text_classification\test'
# 分詞後語料庫路徑
seg_path = r'I:\代碼\tensorflow\文本分類\分類數據\text_classification\seg_test'
# 停用詞路徑
stop_list_Path = r'I:\代碼\tensorflow\文本分類\分類數據\text_classification\stop\stopword.txt'

def stopwordsList(stop_list_Path):
    f = open(stop_list_Path,'r',encoding='utf-8')
    stopwords = [line.strip() for line in f.readlines()]
    return stopwords

def readfile(filepath):
    f = open(filepath,'r',encoding='gb2312',errors='ignore')
    content = f.read()
    # read()返回的是字符串,讀全文本的內容。readline()返回一行,是字符串類型。readlines()讀取所有行,保存在列表中
    f.close()
    return content
    # 這裏返回整個文本,以便後續進行分詞
def savefile(seg_path,content):
    f = open(seg_path,'w',encoding='utf-8')
    f.write(content)
    f.close()

cate_dir = os.listdir(corpus_path) # 獲取子類別目錄
for cate in cate_dir:
    cate_complete_dir = corpus_path+'\\'+cate+"\\" # 獲取子類別的完整路徑
    seg_cate_complete_dir = seg_path + '\\' + cate + "\\"
    if not os.path.exists(seg_cate_complete_dir): # 創建分詞後的保存的路徑
        os.makedirs(seg_cate_complete_dir)
    file_dir = os.listdir(cate_complete_dir)#獲取每個類別下的文件
    for file in file_dir:
        file_complete_dir = cate_complete_dir+file # 獲取每個類別下的文件的完整路徑
        content = readfile(file_complete_dir) # 返回這個文本
        # 對文本進行處理,刪除換行以及多餘空格
        content = content.replace("\n",'').strip()
        content_seg = jieba.cut(content)
        #創建停用詞表
        stopwords = stopwordsList(stop_list_Path)
        outstr =''
        for word in content_seg:
            if word not in stopwords:
                if word !='\t':
                    outstr+=word
                    outstr+=" "
        savefile(seg_cate_complete_dir+"\\"+file,' '.join(outstr))
print("分詞結束")


#————————————沒看懂——————————————
# 2.將分詞後的文本信息轉換成文本向量信息並對象化,利用了Scikit-Learn庫的Bunch數據結構(類似字典,鍵值對)提供了一種key,value的對象形式
import os
import pickle  #持久化類
from sklearn.datasets.base import Bunch
#target_name 所有分類集的名稱列表
#label 每個文件的分類標籤列表
#filenames 文件路徑
#contents 分詞後文件詞向量形式
def readfile(path):
    f = open(path,'r',encoding='gb2312',errors='ignore')
    content = f.read()
    f.close()
    return content
bunch = Bunch(target_name=[],label=[],filenames=[],contents=[])

wordbag_path = r"I:\代碼\tensorflow\文本分類\分類數據\text_classification\wordbag\train_word_bag\train_set.dat"
seg_path = r'I:\代碼\tensorflow\文本分類\分類數據\text_classification\seg_train'
# 獲取類別信息
cate_dir = os.listdir(seg_path)
#將類別信息保存到Bunch對象中去
bunch.target_name.extend(cate_dir)
for cate in cate_dir:
    cate_complete_dir = seg_path+"\\"+ cate+"\\"
    file_dir = os.listdir(cate_complete_dir)# 當前類別下所有的文件名
    for file in file_dir:
        file_complete_dir = cate_complete_dir + file
        bunch.label.append(cate)#保存當前文件的分類標籤
        bunch.filenames.append(file_complete_dir)# 保存當前文件的文件路徑
        bunch.contents.append(readfile(file_complete_dir).strip())# 保存文件詞向量
# Bunch對象持久化
fi = open(wordbag_path,'wb')
pickle.dump(bunch,fi)
fi.close()
print("構建文本對象結束")

3.3取名詞

3.4 特徵提取

構建詞典
進行語料庫各文章類別特徵進行提取,對於每一類,選取各類topN個詞作爲分類特徵詞
注:文本的結構化表示目前有四種:詞向量空間(詞頻);
主體模型;
依存句法的樹表示;
RDF的圖表示

3.5 特徵加權

權重矩陣(表示第j個詞在第i個類別中的tf-idf值,二維矩陣大小n*m(n類別數,m單詞數),每一列表示一個單詞在整個類別中的取值,稱爲一個詞向量。
tf:某個詞在某個類別中出現的次數or頻率
idf:總類別數/包含這個詞的類別數,對商取對數
注意:詞表中的每一個詞不一定在每個類中出現,採取分母加1平滑的方法。

3.6構造分類器

候選:神經網絡、深度學習模型、LDA、SVM、KNN最近鄰、Adaboosting、決策樹、樸素貝葉斯、

對比算法 適用場景 精度 速度 複雜度
KNN 尚可 最快 簡單
SVM 支持線性不可分 取中
樸素貝葉斯 短文本 很高

3.7 評價分類結果

  1. sklearn 數據劃分方法 https://www.cnblogs.com/hellcat/p/7045585.html
    K-折交叉法
    留一法
    隨機劃分法
  2. 準確率(P),召回率®、F1值 、ROC曲線、閾值幾者的關係?
    增加準確率會降低召回率,反之亦然。這叫做準確率與召回率之間的折衷
    如何計算(輸入:樣本真實標籤、樣本預測標籤)
    ROC是真正例率(正例被正確分類的,召回率)比假正例率(反例被錯誤分成正例)
    PR曲線與ROC曲線如何選擇?
    正負樣本不均衡
    在實際學習中,我們可以使用ROC來判斷兩個分類器的優良,然後進行分類器的選擇,然後可以根據PRC表現出來的結果衡量一個分類器面對不平衡數據進行分類時的能力,從而進行模型的改進和優化
    一些不平衡數據學習時對應解決方法。

一、使用ROC、PRC曲線來衡量分類器的效果

二、數據採樣法

  1. 過採樣:通過增加少數樣本來提高少數類別的分類性能。

  2. 欠採樣:通過減少多數樣本來提高少數類別的分類性能。

三、使用代價敏感學習

對於分類混淆矩陣,對不同的分類效果可以賦予不同的權值。

對於AdaBoost,可以基於代價函數來調整錯誤樣本權重向量D(原先是依據上一個分類器的錯誤率)。

對於NaiveBayes,可以選擇具有最小期望代價而不是最大概率的類別作爲最後的結果。

  1. cross_val_predict 不同策略輸出對比
    無:直接輸出最終的結果(預測的類別)
    decision_function():(forest_clf,X_train,y_train_5,cv=3,method = “decision_function”) :數組——值
    predict_proba(): (forest_clf,X_train,y_train_5,cv=3,method = “predict_proba”) : 矩陣——每個樣本屬於每個類別的額概率

  2. fit(),trandform(),fit_transform()
    數據預處理
    算法

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