1. 程式人生 > >機器學習-2.特徵工程和文字特徵提取

機器學習-2.特徵工程和文字特徵提取

1. 資料集的組成

  • 前面講了,機器學習是從歷史資料當中獲得規律,那這些歷史資料的組成是個什麼格式?大都儲存在哪裡?
    – 在機器學習裡大多數資料不會存在資料庫中,大都存在檔案中(比如csv檔案)
    – 不存在資料庫原因:1. 讀取速度導致存在效能瓶頸。2. 儲存的格式不太符合機器學習要求的資料格式。3. 由於我們有pandas,讀取檔案資料及處理速度非常快。
    – pandas為什麼快?1. 基於numpy,numpy非常快,因為numpy釋放了GIL鎖,它是真正的多執行緒。
  • 可用的資料集
    在這裡插入圖片描述
    – kaggle網址:https://www.kaggle.com/datasets

    – UCI資料集網址:http://archive.ics.uci.edu/ml/
    – scikit-learn網址:https://scikit-learn.org/stable/datasets/index.html#datasets
  • 常用資料集資料的結構組成
    – 結構:特徵值+目標值
    – 舉例:pandas裡的dataFrame由行列索引,其中列索引一般作為特徵值資料,依據這些資料進行分析判斷得出目標值。比如:根據人的身高,體重,膚色,頭髮長度等分析這個人的性別。其中性別作為目標值。

2. 特徵工程定義

在這裡插入圖片描述

  • 定義:特徵工程是將原始資料轉換為更好地代表預測模型的潛在問題的特徵的過程,從而提高對未知資料預測的準確性。
  • 意義:它會直接影響預測的結果。
  • Scikit-learn工具介紹
    – python語言的機器學習工具
    – 包含很多機器學習演算法的實現,文件完善,容易上手,豐富的API,在學術界頗受歡迎。
    – 安裝:pip install Scikit-learn,需要提前安裝Numpy和pandas庫。
    – 匯入:import sklearn

3. 特徵抽取

  • 特徵抽取就是對文字等資料進行特徵值化,特徵值化是為了計算機更好的去理解資料。
  • sklearn特徵抽取api:sklearn.feature_extraction

(1). 字典特徵抽取

  • 字典特徵抽取:對字典資料進行特徵值化,api:sklearn.feature_extraction.DictVectorizer
  • 抽取示例:
from sklearn.feature_extraction import DictVectorizer


def dictvec():
    """
    字典特徵抽取示例
    1. 準備資料
    2. 例項化sklearn字典特徵抽取類
    3. 呼叫fit_transform方法進行轉換
    4. 輸出特徵名稱
    5. 輸出轉換後的資料檢視效果
    :return: None
    """

    datalist = [{'city':'北京','temperature':20}, {'city':'上海','temperature':30}, {'city':'深圳','temperature':40}]  # 準備資料
    dictvec = DictVectorizer(sparse=False)  # 例項化, 預設輸出sparse矩陣格式,加上sparse=False後輸出正常矩陣格式。
    data = dictvec.fit_transform(datalist)  # 轉化資料,字典特徵抽取
    print(dictvec.get_feature_names())
    print(data)
 	# print(dictvec.inverse_transform(data)) # 將轉化的資料反轉成原來的狀態,即datalist
    return None


if __name__ == '__main__':
    dictvec()

– sparse矩陣格式:
在這裡插入圖片描述
– 加入sparse=False引數後輸出矩陣格式(numpy中的ndarray 二維陣列):
在這裡插入圖片描述

  • 由以上示例看出,數值型的資料並沒有被轉換,因為數值型本身適合進行處理。
  • 那麼輸出的轉換資料[[0. 1. 0. 20.][1. 0. 0. 30.][0. 0. 1. 40.]],如何得來,這裡涉及到one-hot編碼。
  • one-hot編碼分析:
    – 假設要提取特徵,把city分類,加入北京為1,上海為2,深圳為3,那麼123之間會不會存在優先順序之說,起碼在含義上是有歧義的,容易誤解,為了更加公平所以發明了one-hot編碼。看下圖:
    在這裡插入圖片描述
    上圖可以看到,有7個樣本,假設第一個樣本屬於人型別,則human這一列標記為1,其餘為0,依次類推即為一個熱編碼。

(2). 文字特徵抽取

第一種方式-CountVectorizer

  • 文字特徵抽取就是對文字資料進行特徵值化
  • api:sklearn.feature_extraction.text.CountVectorizer
  • 示例:
from sklearn.feature_extraction.text import CountVectorizer

def countvec():
    '''
    文字特徵值抽取示例
    1. 準備資料
    2. 例項化sklearn文字特徵抽取類
    3. 呼叫fit_transform方法轉換
    4. 輸出特徵名稱
    5. 輸出轉換後的資料
    :return: None
    '''
    textlist = ["life is short,i like python", "life is too long,i dislike python"]
    cv = CountVectorizer()
    data = cv.fit_transform(textlist)
    print(cv.get_feature_names())
    print(data.toarray())  # 和字典特徵抽取不同,沒有sparse矩陣設定的引數,因此需要手動toarray()轉換為正常陣列形式
    return None


if __name__ == '__main__':
    countvec()

– 輸出如下圖:
在這裡插入圖片描述
由輸出結果可以看出:

  1. 統計了所有文章當中所有的詞,重複的只做一次
  2. 對每篇文章,在詞的列表裡面進行統計每個詞出現的次數
  3. 單個字母不統計。
  • 對中文的處理
  • 預設sklearn不支援對中文分詞處理。需要引入jieba,pip install jieba,然後import jieba,之後jieba.cut(“我是一個程式設計師”)會返回詞語生成器。
  • 示例:
from sklearn.feature_extraction.text import CountVectorizer
import jieba

def cutword():
    '''
    jieba對中文段落進行分詞
    :return: c1,c2
    '''
    con1 = jieba.cut("生活苦短,我喜歡python")
    con2 = jieba.cut("人生漫長,我不用python")

    # 轉換成列表
    content1 = list(con1)
    content2 = list(con2)

    # 把列表轉換為字串
    c1 = ' '.join(content1)
    c2 = ' '.join(content2)

    return c1,c2

def countvec():
    '''
    文字特徵值抽取示例
    1. 獲取jieba分詞後的字串
    2. 例項化sklearn文字特徵抽取類
    3. 呼叫fit_transform方法轉換
    4. 輸出特徵名稱
    5. 輸出轉換後的資料
    :return: None
    '''
    c1,c2 = cutword()
    cv = CountVectorizer()
    data = cv.fit_transform([c1,c2])
    print(cv.get_feature_names())
    print(data.toarray())  # 和字典特徵抽取不同,沒有sparse矩陣設定的引數,因此需要手動toarray()轉換為正常陣列形式
    return None


if __name__ == '__main__':
    countvec()

– 輸出如下圖:
在這裡插入圖片描述

第二種方式-TF-IDF(term frequency–inverse document frequency)

  • TF意思是詞頻(Term Frequency),IDF意思是逆文字頻率指數(Inverse Document Frequency)。
  • 主要思想:如果某個詞或短語在一篇文章中出現的概率高,並且在其他文章中很少出現,則認為該詞或者短語具有很好的類別區分能力,適合用來分類。
  • 作用:用以評估一個詞對於一個檔案集或一個語料庫中的其中一份檔案的重要性。
  • IDF公式:log(總文件數量/該詞出現的文件數量)
  • TF*IDF即為 重要性指標
  • API:sklearn.feature_extraction.text.TfidfVectorizer
  • 示例:
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba

def cutword():
    '''
    jieba對中文段落進行分詞
    :return: c1,c2
    '''
    con1 = jieba.cut("生活苦短,我喜歡python")
    con2 = jieba.cut("人生漫長,我不用python")

    # 轉換成列表
    content1 = list(con1)
    content2 = list(con2)

    # 把列表轉換為字串
    c1 = ' '.join(content1)
    c2 = ' '.join(content2)

    return c1,c2

def tfidfvec():
    '''
    文字特徵值抽取示例
    1. 獲取jieba分詞後的字串
    2. 例項化sklearn文字特徵抽取類
    3. 呼叫fit_transform方法轉換
    4. 輸出特徵名稱
    5. 輸出轉換後的資料
    :return: None
    '''
    c1,c2 = cutword()
    tf = TfidfVectorizer()
    data = tf.fit_transform([c1,c2])
    print(tf.get_feature_names())
    print(data.toarray())  # 和字典特徵抽取不同,沒有sparse矩陣設定的引數,因此需要手動toarray()轉換為正常陣列形式
    return None

if __name__ == '__main__':
    tfidfvec()
  • 輸出如下圖:
    在這裡插入圖片描述
    根據上圖中輸出數字的大小找到重要詞彙,並根據這些詞彙可對文章進行分類,輸出的數字是tf*idf得來的。
  • 針對文字的特徵提取就是以上內容,目前記錄的仍是相對過時的技術,但還是需要理解,為後邊打下基礎。