日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

机器学习的练功心法(三)——特征工程

發(fā)布時間:2023/12/9 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 机器学习的练功心法(三)——特征工程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 致謝
  • 3 特征工程
    • 3.1 Sklearn工具及數(shù)據(jù)集
    • 3.2 數(shù)據(jù)集
    • 3.3 數(shù)據(jù)集的劃分
    • 3.4 特征工程介紹
      • 3.4.1 為什么需要特征工程
      • 3.4.2 什么是特征工程
      • 3.4.3 特征提取
        • 3.4.3.1 字典特征提取
        • 3.4.3.2 文本特征提取
        • 3.4.3.3 中文文本特征提取
        • 3.4.3.4 TF-IDF算法
    • 3.5 特征預處理
      • 3.5.1 特征預處理主要內容
      • 3.5.2 大局看待
      • 3.5.3 歸一化
      • 3.5.4 標準化
    • 3.6 降維
      • 3.6.1 特征選擇
      • 3.6.2 過濾式
        • 3.6.2.1 低方差特征過濾
        • 3.6.2.2 相關系數(shù)法
      • 3.6.3 主成分分析

致謝

本文參照了下列文章的些許知識:

TF-IDF算法介紹及實現(xiàn)_Asia-Lee-CSDN博客_tf-idf

Python入門:jieba庫的使用_點滴記錄-CSDN博客_jieba

Python jieba庫的基本使用_Test_Box-CSDN博客_python的jieba庫怎么使用

數(shù)據(jù)歸一化(標準化)的兩種方法簡介_嗶哩嗶哩_bilibili

歸一化 (Normalization)、標準化 (Standardization)和中心化/零均值化 (Zero-centered) - 簡書 (jianshu.com)

標準化和歸一化,請勿混為一談,透徹理解數(shù)據(jù)變換_夏洛克江戶川-CSDN博客_歸一化和標準化

3 特征工程

我們需要的不僅僅是只會靠個嘴說這些理論,更重要的是能夠用代碼實現(xiàn)上述的知識。但是實現(xiàn)這些算法和模型,我們需要有數(shù)據(jù)集使用,數(shù)據(jù)集如果沒有可用的我們可以人工捏造,而如果想要實戰(zhàn)我們可以前往一些網(wǎng)址去尋找人們整理好的數(shù)據(jù)集。下面推薦一些常用的數(shù)據(jù)集來源:

Kaggle網(wǎng)址:Find Open Datasets and Machine Learning Projects | Kaggle

UCI數(shù)據(jù)集網(wǎng)址:UCI Machine Learning Repository

Sklearn網(wǎng)址:scikit-learn: Machine Learning in Python — scikit-learn 1.0.2 文檔

3.1 Sklearn工具及數(shù)據(jù)集

Sklearn全名為Scikit-learn,它是python語言的機器學習工具,其包內具有許多知名的機器學習算法的實現(xiàn),而且官方文檔完善,容易上手,具有豐富的API。

如果你是使用Anaconda3的玩家,那你不需要再去官網(wǎng)安裝這個包了,使用下列指令看看你所有包里面有沒有它吧!

pip list

3.2 數(shù)據(jù)集

讓我們使用這個包加載一些數(shù)據(jù)集如何?

datasets.load_*() #獲取小規(guī)模數(shù)據(jù)集,數(shù)據(jù)包含在datasets中 datasets.fetch_*() #獲取大規(guī)模數(shù)據(jù)集,需要從網(wǎng)上下載,函數(shù)的第一個參數(shù)時data_home,表示數(shù)據(jù)集下載的目錄里,默認是~/scikit_learn_data/

當然,我們首先使用小規(guī)模數(shù)據(jù)集,其使用方法如下:

sklearn.datasets.load_boston() #其中l(wèi)oad_后面跟的名字即為數(shù)據(jù)集的名字

如果我們想要導入大數(shù)據(jù)集的話,我們可以這么寫:

sklearn.datasets.fetch_名字(data_home = None, subset = 'train')

不過奇怪的是,我使用的是下列的方式導入數(shù)據(jù)集無效

import sklearn sklearn.datasets.load_boston() #其中l(wèi)oad_后面跟的名字即為數(shù)據(jù)集的名字

而用下面的方式導入?yún)s成功了

from sklearn.datasets import load_iris

subset屬性可以指定加載哪一部分的數(shù)據(jù)集,可以是訓練集train,可以是測試集test,也可以是所有all。

說了這么多不如動手實現(xiàn)一下,下面跟著我敲一下下面的代碼吧!

from sklearn.datasets import load_irisdef datasets_demo():"""sklearn數(shù)據(jù)集的使用"""#獲取數(shù)據(jù)集iris = load_iris()print("鳶尾花數(shù)據(jù)集:\n",iris)print("查看數(shù)據(jù)集描述:\n",iris["DESCR"])print("查看特征值的名字:\n",iris.feature_names)print("查看特征值:\n",iris.data,iris.data.shape)return Nonedatasets_demo()

通過上面的操作我們可以發(fā)現(xiàn)load和fetch返回的數(shù)據(jù)集一般是字典格式,其中包含有幾個屬性,如下所示:

  • data:特征數(shù)據(jù)數(shù)組,是[n_samples*n_features]的二維numpy.ndarray數(shù)組
  • target:標簽數(shù)組,是n_samples的一維numpy.ndarray數(shù)組
  • descr:數(shù)據(jù)描述
  • feature_names:特征名
  • feature_names:標簽名

sklearn自帶的數(shù)據(jù)集有以下幾種:

自帶的小的數(shù)據(jù)集為:sklearn.datasets.load_name

自帶的大的數(shù)據(jù)集為:sklearn.datasets.fetch_name

需要注意的是,在導入大數(shù)據(jù)集時,一般需要下載,運行程序的速度可能會較慢。

3.3 數(shù)據(jù)集的劃分

通過對之前的學習,我們知道數(shù)據(jù)集分為訓練集和測試集。所以對于我們從sklearn導入的數(shù)據(jù)集中,我們不應該全部用于訓練,而應該留一部分用于測試。

對于訓練集和測試集的劃分比例比較經(jīng)典的就是73劃分,即訓練集百分之七十,而測試集為百分之三十。

那我們怎么劃分?我們自己寫算法來劃分嗎?其實不然,sklearn早就知道你會有此一步,所以你只需要調用其API即可。sklearn中用于分割數(shù)據(jù)集的函數(shù)如下:

sklearn.model_selection.train_test_split(arrays,*options)

x:數(shù)據(jù)集的特征值

y:數(shù)據(jù)集的特征值

test_size:測試集的大小,一般為float

random_state:隨機數(shù)種子,不同的種子會造成不同的隨機采樣結果。相同的種子采樣結果相同。

return:訓練集特征值,測試集特征值,訓練集目標值,測試集目標值。

讓我們看看代碼怎么寫:

#記得調用函數(shù)! from sklearn.model_selection import train_test_split#定義分割打印函數(shù) def DataSplit():'''數(shù)據(jù)集劃分'''#用四個變量來接收分割函數(shù)返回的值x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.3,random_state=22)#打印看看!print("訓練集的特征值:\n",x_train,x_train.shape)return None#調用 DataSplit()

3.4 特征工程介紹

3.4.1 為什么需要特征工程

運用不同的機器學習模型,所分類或預測的結果大相徑庭,這是因為有時候在特征工程階段不同的操作導致結果的不同。機器學習領域的大神吳恩達曾經(jīng)說過:業(yè)界廣泛流傳:數(shù)據(jù)和特征決定了機器學習的上限,而模型和算法知識逼近這個上限罷了。

3.4.2 什么是特征工程

特征工程師使用專業(yè)背景知識和技巧處理數(shù)據(jù),使得特征能在機器學習算法上發(fā)揮更好的作用的過程,其意義會直接影響機器學習的效果。

對于特征工程來說,其使用的工具有別于數(shù)據(jù)分析中我們用的pandas,而是采用了sklearn中對于特征處理更為強大的接口。特征工程包含的步驟有:

  • 特征提取
  • 特征預處理
  • 特征降維

3.4.3 特征提取

特征提取就是將非結構化數(shù)據(jù)轉為結構化數(shù)據(jù)的過程,或者說,將任意數(shù)據(jù)(如文本或圖像)轉換為可用于機器學習的數(shù)字特征。特征值化是為了計算機更好的去理解數(shù)據(jù)。不同的原始數(shù)據(jù)有不同的轉換方法,如下所示:

  • 字典特征提取(特征離散化)
  • 文本特征提取
  • 圖像特征提取(深度學習領域)

在機器學習中,我們可以使用sklearn.feature_extraction這個API來滿足我們的需求。

3.4.3.1 字典特征提取

字典特征提取會將鍵值對中的鍵轉換為獨熱編碼。假如我們要對字典數(shù)據(jù)進行特征值化,我們可以采用以下的函數(shù):

sklearn.feature_extraction.DicVectorizer(sparse = True…)

DicVectorizer.fit_transform(X):其中X是字典或者包含字典的迭代器返回值,其返回sparse(稀疏)矩陣

DicVectorizer.inverse_tranform(X):其中X是array數(shù)組或者sparse(稀疏)矩陣,其返回值是轉換之前的數(shù)據(jù)格式

DicVectorizer.get_feature_names():返回類別名稱

我們來嘗試對下列數(shù)據(jù)進行提取:

from sklearn.feature_extraction import DictVectorizer #導包def load_dic():data = [{'city':'北京','temperature':100},{'city':'上海','temperature':60}]#實例化一個轉換器類transfer = DictVectorizer(sparse=False)#調用其方法data_new = transfer.fit_transform(data)#打印特征提取后的新數(shù)據(jù)print("new data:\n",data_new)print("feature name:\n",transfer.get_feature_names())load_dic()

這里需要科普兩個知識:

獨熱編碼(one-hot編碼)

如果只是二分分類,這種分類我們大可只用0或者1來表示。

假設每次輸入是一個2×2的灰度圖像。我們可以用一個標量表示每個像素值,每個圖像對應四個特征x1,x2,x3,x4x_1,x_2,x_3,x_4x1?,x2?,x3?,x4?,此外,假設每個圖像屬于類別"貓",“雞”,"狗"中的一個。

接下來,我們要選擇如何表示標簽,如同我們前面所說,我們肯定不可能說P = “貓”,我們有兩個明顯地選擇:最直接的想法是選擇y∈{1,2,3},其中正數(shù)分別代表{“狗”,“貓”,“雞”}。

但是統(tǒng)計學家很早之前就發(fā)明了一種表示分類數(shù)據(jù)的簡單方法:獨熱編碼。獨熱編碼是一個向量,它的分量和類別一樣多。類別對應的分量設置為1,其他所有分量設置為0。比如說應用到我們這個例子上的話,我們就可以用獨熱編碼來表示我們的標簽y,其中貓對應(1,0,0),雞對應(0,1,0),狗對應(0,0,1)。

稀疏矩陣

在矩陣中,若數(shù)值為0的元素數(shù)目遠遠多于非0元素的數(shù)目,并且非0元素分布沒有規(guī)律時,則稱該矩陣為稀疏矩陣;與之相反,若非0元素數(shù)目占大多數(shù)時,則稱該矩陣為稠密矩陣。定義非零元素的總數(shù)比上矩陣所有元素的總數(shù)為矩陣的稠密度。

當我們采用獨熱編碼時,如果類別過多,就會導致向量中含有大量的0,而采用稀疏矩陣來表示可以將非零值按位置表示出來,這么做可以省去大量的0,提高計算速度。

學完了字典特征提取,我們拿到數(shù)據(jù)集怎么判斷該不該用這個方法呢?我們可以從兩點來判斷:

  • 本身就是字典或字典迭代器
  • 類別特征較多,那么可以將數(shù)據(jù)集的特征轉換為字典類型,再進行字典提取

3.4.3.2 文本特征提取

文本特征提取可以將文本數(shù)據(jù)進行特征值化。這里所說的文本包括句子、短語、單詞、字母,但是我們一般是把單詞來作為特征。假如我們要采用文本特征提取,我們可以采用以下的函數(shù):

sklearn.feature_extraction.text.CountVectorizer(stop_words = [])

其返回的是一個詞頻矩陣

CountVectorizer.fit_transform(X):其中X是文本或者文本字符串的可迭代對象,返回一個sparse矩陣。

CountVectorizer.inverse_transform(X):其中X是數(shù)組或者sparse矩陣,返回值為轉換之前的數(shù)據(jù)格。

CountVectorizer.get_feature_names():其返回值是一個單詞列表。

我們來嘗試對下列數(shù)據(jù)進行提取:

from sklearn.feature_extraction.text import CountVectorizerdef load_string():"""文本特征抽取"""data = ["lift is short,i lke python","life is too long , i disllike python"]#實例化一個轉換器類transfer = CountVectorizer()#調用其方法data_new = transfer.fit_transform(data).toarray()#打印print("new data:\n",data_new)print("feature name:\n",transfer.get_feature_names())load_string()

如果傳入的數(shù)據(jù)是中文,在單詞沒有空格分隔符的情況下,其按句子分。

def load_chinese_string():"""中文文本特征提取"""data = ["我愛北京,我很喜歡北京","我很愿意去北京居住"]#實例化一個轉換器類transfer = CountVectorizer()#調用其方法data_new = transfer.fit_transform(data).toarray()#打印print("new data:\n",data_new)print("feature name:\n",transfer.get_feature_names())load_chinese_string()

如果不想對一些語氣詞做統(tǒng)計,可以在實例化CountVectorizer類的時候以列表的形式將停用詞傳給該類。

3.4.3.3 中文文本特征提取

我們在前面說過,對于中文的文本特征提取無法像英文一般提取單詞,只能提取句子,因為其沒有如英文一般一句話好幾個單詞用空格分割的特性,如果在中文中一句話幾個單詞之間要手動加空格,顯然是不現(xiàn)實的。我們可以利用一些庫來幫我們分割中文單詞,以便做特文本特征提取。

我們這里使用jieba庫,該庫是一款優(yōu)秀的python第三方中文分詞庫,jieba支持三種分詞模式:精確模式、全模式和搜索引擎模式。

  • 精確模式,試圖將句子最精確地切開,適合文本分析;
  • 全模式,把句子中所有的可以成詞的詞語都掃描出來, 速度非常快,但是不能解決歧義;
  • 搜索引擎模式,在精確模式的基礎上,對長詞再次切分,提高召回率,適合用于搜索引擎分詞。
  • paddle模式,利用PaddlePaddle深度學習框架,訓練序列標注(雙向GRU)網(wǎng)絡模型實現(xiàn)分詞。同時支持詞性標注。paddle模式使用需安裝paddlepaddle-tiny,pip install paddlepaddle-tiny==1.6.1。目前paddle模式支持jieba v0.40及以上版本。jieba v0.40以下版本,請升級jieba,pip install jieba --upgrade 。PaddlePaddle官網(wǎng)

很多同學可能是使用anaconda3來進行機器學習的學習的,所以其沒有自帶jieba庫,我們打開shell窗口,然后輸入以下指令來安裝jieba庫。

pip install jieba

jieba庫三種模式簡單使用方法如下:

import jiebaseg_str = "好好學習,天天向上。"print("/".join(jieba.lcut(seg_str))) # 精簡模式,返回一個列表類型的結果 print("/".join(jieba.lcut(seg_str, cut_all=True))) # 全模式,使用 'cut_all=True' 指定 print("/".join(jieba.lcut_for_search(seg_str))) # 搜索引擎模式

需要注意的是,通過jieba的cut方法返回的是一個迭代器對象,你可以用list包裝它或者用其他的方式也可以。在新版本的jieba中,調用lcut方法可以使得效果和cut+list的效果一樣。

學會了上面的操作,讓我們來按照下面的代碼敲一次再熟悉一下:

from sklearn.feature_extraction.text import CountVectorizer import jiebadef cut_word(text):"""進行中文分詞"""return " ".join(list(jieba.cut(text)))def count_chinese_demo():data = ["每個男人的心中都有兩朵玫瑰,娶了紅玫瑰,久而久之,紅的變成了墻上的一抹蚊子血,白的還是“床前明月光”;娶了白玫瑰,白的便是衣服上的一粒飯粘子,紅的卻是心口上的一顆朱砂痣。"]data_new = []for sent in data:data_new.append(cut_word(sent))#print(data_new)#實例化一個轉換器類transfer = CountVectorizer()#調用其方法data_final = transfer.fit_transform(data_new).toarray()#打印print("new data:\n",data_final)print("feature name:\n",transfer.get_feature_names())count_chinese_demo()

3.4.3.4 TF-IDF算法

上面的特征提取顯然是有問題的,為何?因為我們通常如果有做中文文本特征提取,一般都是用于情感分析,即自然語言處理。我們做自然語言處理NLP的步驟是根據(jù)一些情感詞來判斷其句子中包含的情感,而如果你將一個句子事無巨細的全部提取,顯然沒有必要。

我們對句子關鍵詞的提取采用的是API中TfidfVectorizer,人們更喜歡叫他TF-IDF。

通過關鍵詞的提取,我們更加容易地可以掌握句子的意思和文章的感情或大概。

TF-IDF的主要思想是:如果某一個詞或者短語在一篇文章中出現(xiàn)的概率高,并且在其他文章中很少出現(xiàn),則認為此詞或者短語具有很好的類別區(qū)分能力,適合用來分類。而TF-IDF的作用就是用來評估詞或短語在一份文件中的重要程度。

TFIDF是根據(jù)下面兩項指標來判斷關鍵詞或關鍵短語的:

  • 詞頻(term frequency,TF)是指給定的詞語在該文件中出現(xiàn)的頻率
  • 逆向文檔頻率(inverse document frequency , IDF)是一個詞語普遍重要性的度量。某一特定詞語的idf,可以由總文件數(shù)目除以包含該詞語文件的數(shù)目,再將得出的商取以10為底的對數(shù)得到

當我們想要看某個詞的關鍵程度,只需將該詞對應的TF和IDF相乘即可。

講完理論,接下來讓我們看一下sklearn庫中有哪些API供我們完成這項工作。

sklearn.feature_extraction.text.TfidfVectorizer(stop_words = None…)

  • TfidfVectorizer.fit_transform(X):其中X表示文本或者文本字符串的可迭代對象,返回值為sparse矩陣
  • TfidfVectorizer.inverse_transform(X):其中X代表array數(shù)組或者sparse矩陣,返回值為轉換之前的數(shù)據(jù)格式
  • TfidfVectorizer.get_feature_names():其返回值為一個單詞列表

了解了上面的原理后,讓我們敲一下下面的代碼體會一下吧。

from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfVectorizer import jiebadef tfidf_demo():"""用tdidf的方法進行文本特征抽取"""data = ["每個男人的心中都有兩朵玫瑰,娶了紅玫瑰,久而久之,紅的變成了墻上的一抹蚊子血,白的還是“床前明月光”;娶了白玫瑰,白的便是衣服上的一粒飯粘子,紅的卻是心口上的一顆朱砂痣。"]data_new = []for sent in data:data_new.append(cut_word(sent))#print(data_new)#實例化一個轉換器類transfer = TfidfVectorizer()#調用其方法data_final = transfer.fit_transform(data_new)#打印print("new data:\n",data_final)print("feature name:\n",transfer.get_feature_names())tfidf_demo()

綜上所述,實際上TF-IDF算法是分類機器學習算法進行文章分類中前期數(shù)據(jù)處理的一種方式。

3.5 特征預處理

特征預處理是通過一些轉換函數(shù)將特征數(shù)據(jù)轉換成更加適合算法模型的特征數(shù)據(jù)過程。

3.5.1 特征預處理主要內容

特征預處理主要包括兩種,即數(shù)值型數(shù)據(jù)的歸一化和標準化。在sklearn中,我們可以通過:

sklearn.preprocessing

這個API來達到我們想要的結果。

3.5.2 大局看待

那么歸一化和標準化又是什么呢?我們?yōu)槭裁匆盟鼈兡?#xff1f;這就要涉及到數(shù)據(jù)的維度了。在有些數(shù)據(jù)中具有多個特征,各個特征之間的數(shù)量級差別很大,比如男生的學生號和男生吃過的米飯數(shù),一個是以接近無窮的數(shù)量,一個僅僅是六位數(shù)或三位數(shù)。相差如此巨大的數(shù)量級會讓我們的機器誤以為某些特征不重要,而且計算會變慢。

讓我們再看一個例子:

這個條形圖中橫坐標是國家,縱坐標是人口數(shù)量,由于中國人口基數(shù)過大,導致其他國家的人口看起來幾乎為0,難以看出數(shù)據(jù)間的具體差異。而且條形圖后半部分的國家人口增長速度過快,從澳大利亞開始人口基數(shù)逐漸明顯,這影響條形圖的美觀。

如何解決上述的問題呢?

這時候就要引入我們的0-1歸一化了。歸一化能把數(shù)據(jù)通過某種函數(shù)映射到(0,1)或者(1,1)之間的小數(shù),這樣做事為了數(shù)據(jù)處理方便,在轉換的過程中,不同單位或量級的指標在函數(shù)的作用下會加權,導致數(shù)據(jù)間的差異變化不要那么巨大,即讓數(shù)值差異過大的幾組數(shù)據(jù)縮小在同一數(shù)量級中。這么做的好處不僅僅體現(xiàn)在后續(xù)處理方便,更重要的是在參數(shù)估計時使用梯度下降求解最優(yōu)化問題時,歸一化/標準化可以加快梯度下降的求解速度。

通過歸一化對上述的問題映射到0-1上后,我們可以看到效果如下:

雖然壓縮為同一個數(shù)量級了,但是還是沒有達到解決差異過大導致前幾個國家數(shù)據(jù)不明顯的問題,這個時候我們就要引入我們第二個方法:零均值規(guī)范化(Z-score標準化)。通過標準化后的數(shù)據(jù)如下:

3.5.3 歸一化

歸一化前面說過,其可以通過函數(shù)將原始數(shù)據(jù)進行變換映射到(默認)[0,1]之間。其公式如下所示:
X=x?minmax?min其中max指的是統(tǒng)一特征下不同數(shù)據(jù)的最大特征反之則為minX = \frac{x-min}{max-min}\\ 其中max指的是統(tǒng)一特征下不同數(shù)據(jù)的最大特征\\ 反之則為min X=max?minx?min?max統(tǒng)數(shù)據(jù)min
讓我們來計算一下吧!

假設我要對特征1上的90這個數(shù)據(jù)做歸一化,只需X=90?6090?60=1X = \frac{90-60}{90-60} = 1X=90?6090?60?=1。

如果你不想投到[0,1]區(qū)間,而想投到其他區(qū)間,可以將上述的X代入下面這個公式:
X′=X?(mx?mi)+mi其中mx為指定區(qū)間的右端點,mi為指定區(qū)間的左端點X' = X*(mx - mi)+mi \\其中mx為指定區(qū)間的右端點,mi為指定區(qū)間的左端點 X=X?(mx?mi)+mimx區(qū)mi區(qū)
如我們要投到[-1,1],只需X′=1?(1+1)?1=1X' = 1*(1+1)-1 = 1X=1?(1+1)?1=1。

以上就是歸一化的計算過程,下面讓我們看看如何用API來實現(xiàn)吧!

歸一化使用的API方法如下所示:

sklearn.preprocessing.MinMaxScaler(feature_range = (0,1)…)

MinMaxScalar.fit_transform(X):其中X是numpy中array格式的數(shù)據(jù),返回值為于轉化前形狀相同的array。

下面跟著我敲一下下面的代碼:

from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split import jieba from sklearn.preprocessing import MinMaxScalerdef minmax_demo():"""歸一化"""# 實例化轉換器類transfer = MinMaxScaler()# 調用其方法# 獲取數(shù)據(jù)集iris = load_iris()x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target)iris_new = transfer.fit_transform(x_train)print(iris_new)minmax_demo()

歸一化公式是由最大值和最小值計算得到的,因此當數(shù)據(jù)中有異常值的情況下會影響歸一化效果,所以這種方法魯棒性比較差,只適用傳統(tǒng)精確小數(shù)據(jù)場景。

3.5.4 標準化

標準化的公式如下:
X=x?meanσX = \frac {x - mean}{\sigma} X=σx?mean?
讓我們來看看其使用的API:

sklearn.preprocessing.StandardScaler()

StandardScaler.fit_transform(X):其中X為numpy中array格式的數(shù)據(jù),返回值為轉換前形狀相同的array。

讓我們跟著下面的代碼來試一下:

from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScalerdef stand_demo():"""標準化"""# 實例化轉換器類transfer = StandardScaler()# 獲取數(shù)據(jù)集iris = load_iris()x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target)iris_train = transfer.fit_transform(x_train)print(iris_train)stand_demo()

標準化適用于在已有樣本足夠多的情況下使其比較穩(wěn)定,適合現(xiàn)代嘈雜大數(shù)據(jù)場景。

3.6 降維

要提到降維,我們首先就要知道維度是什么。在數(shù)學中,0維度一般指標量,1維一般指向量,2維一般指矩陣,3維及以上一般指多個矩陣嵌套。

降維是指在某些限定條件下,降低隨機變量特征的個數(shù),得到一組“不相關”主變量的過程。用通俗的話來講就是,特征太多了,后來很難輸入到算法之中,我們需要舍棄一些維度,或者將一些維度合二為一來達到降維的效果。

通常在進行降維后,特征和特征之間能夠達到一種不相關的效果。如果沒有達到這種效果,就說明你的降維工作做的不夠好,因為在訓練模型的時候,我們都是使用特征和標簽來訓練模型,如果特征本身之間存在問題或者特征之間相關性較強,算法學習預測效果會大打折扣。

降維的方式有兩種:即特征選擇和主成分分析。在下一小節(jié)中,我們會細講它們。

3.6.1 特征選擇

特征選擇是指在數(shù)據(jù)中包含冗余或相關變量中尋找出主要特征。

特征選擇包含有四種方法,為了入門,我們只講其中兩種:過濾式和嵌入式。詳見:特征選擇(Feature Selection)_hren_ron的博客-CSDN博客_特征選擇。

  • Filter(過濾式):主要探究特征本身特點、特征與特征和目標值之間關聯(lián)。其主要的方法有方差選擇法和相關系數(shù)法。
  • Embedded(嵌入式):算法自動選擇特征(特征和目標值之間的關聯(lián))。其主要方法有決策樹、正則化、深度學習卷積等。

對于特征選擇的使用,我們可以使用sklearn給我們提供的模塊:

sklearn.feature_selection

3.6.2 過濾式

3.6.2.1 低方差特征過濾

對于一些地方差的特征,其穩(wěn)定性良好導致所有的特征基本處于同一堆位置。而在聚類和密度聚類算法中(無監(jiān)督學習),其就是要根據(jù)數(shù)據(jù)的分布特點來劃分類別的,如果你的數(shù)據(jù)全部湊在一起沒有分布特點還劃分啥?所以低方差特征過濾就是刪除所有低方差的特征。我們可以使用sklearn中的API來達到我們需要的效果。

sklearn.feature_selection.VarianceThreshold(threshold = 0.0)

其API中提供了Variance.fit_transform(X)函數(shù):其中X代表numpy型數(shù)組[n_sample,n_feature],返回的數(shù)組中會被刪除原來數(shù)組中低方差的特征。

讓我們來用這個方法來對鳶尾花數(shù)據(jù)集進行特征選擇吧!

# 導包 from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.feature_selection import VarianceThresholddef datademo():# 加載鳶尾花數(shù)據(jù)集iris = datasets.load_iris()x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target)# 實例化轉換器類transfer = VarianceThreshold(threshold=0)iris_new = transfer.fit_transform(x_train)print(iris_new)datademo()

3.6.2.2 相關系數(shù)法

皮爾遜相關系數(shù)是相關系數(shù)法的其中一種,其反映了變量之間相關關系密切程度的統(tǒng)計指標。

我不是很建議你去了解這個相關系數(shù)的公式,因為我們不是在學概率論。如果你想了解這個公式,你可以先去學學概率論。
r=n∑xy?∑x∑yn∑x2?(∑x)2n∑y2?(∑y)2r = \frac{n \sum xy- \sum x \sum y}{\sqrt {n \sum x^2 - (\sum x)^2} \sqrt{n \sum y^2 - (\sum y)^2}} r=nx2?(x)2?ny2?(y)2?nxy?xy?
當計算出r之后,如果其值介于-1到+1之間,那么其性質如下:

當r >0時,表示兩變量正相關,r<0時,兩變量為負相關。

當| r | = 1時,表示兩變量為完全相關,r = 0時,表示兩變量間無相關關系。

當0< | r |<1時,表示兩變量存在一定程度的相關,且| r |越解決1,兩變量間線性關系越密切,| r |越接近于0,表示兩變量的線性相關越弱。

一般可按三級劃分:| r |<0.4為低度相關,0.4<= | r |<0.7為顯著性相關,0.7<= | r |<1為高度線性相關。

我們可以使用scipy庫中的pearsonr來達到我們的目的。

from scipy.stats import pearsonr

x:(N,)array _like

y:(N, )array_like Returns:(Pearson’s correlation coefficient, p -value)

由于這里沒有合適的數(shù)據(jù)集,這里我就不演示了。

需要注意的是,兩個特征相關性很高的話,我們選取其中一個即可。或者我們可以使用主成分分析。

3.6.3 主成分分析

主成分分析是指高維數(shù)據(jù)轉化為低維數(shù)據(jù)的過程,在此過程中可能會舍棄原有數(shù)據(jù)、創(chuàng)造新的變量。其作用是將數(shù)據(jù)維數(shù)壓縮,盡可能降低原數(shù)據(jù)的維數(shù),損失少量信息。

主成分分析一般用于回歸分析或者聚類分析中。

如何更好地講述主成分分析呢?我們可以這么理解。

在現(xiàn)實生活中任何物體都是三維的,當結果素描將圖像印于紙上時,三維就轉換為了二維,這就是PCA。

我們首先將二維降到一維。在平面直角坐標系中我們有一些點,降維的方式就是畫一條直線,然后將所有點投影到這條線上,如圖所示:

以上的圖實際上是有5個點的,但是由于選出直線的不合理,導致點和線重合了,高維信息的損失了一部分。而在降維的過程中,我們應該保持高維度盡可能多的信息。

而如果采用下面的方式降維,這時候就非常不錯了。

我們要將一個三維的特征向量降至一個二維的特征向量。過程是與上面類似的,我們將三維向量投射到一個二維的平面上,強迫使得所有的數(shù)據(jù)都在同一個平面上,降至二維的特征向量。同通俗的話來講就是,拿一張白紙擺在空間中,然后讓所有的點投影到紙上。需要注意的是,與上面相同,我們不希望降維的過程中高維度信息受到損失。

弄清楚上面的原理后,讓我們開始看看sklearn中有哪些API供我們調用吧!

sklearn.decomposition.PCA(n_components = None)

其中n_components可以是小數(shù)也可以是整數(shù),小數(shù)表示保留百分之多少的信息,整數(shù)為減少到多少特征。

方法PCA.fit_transform(X):其中X只能傳入numpy array格式的數(shù)據(jù)[n_samples,n_features],其返回的是轉換后指定維度的array。

讓我們來試試!

from sklearn.decomposition import PCAdef pca_demo():"""PCA降維"""data = [[2,8,4,5],[6,3,0,8],[5,4,9,1]]#實例化一個轉換器類transfer = PCA(n_components=0.95)#調用轉換方法data_new = transfer.fit_transform(data)print(data_new)pca_demo()

總結

以上是生活随笔為你收集整理的机器学习的练功心法(三)——特征工程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。