python数据分析新手入门课程学习——(五)特征工程概述(数据预处理)(来源:慕课网)
機器學習:計算機根據經驗(數據)自動化做出決策的過程最終機器學習達到一種狀態,是當我們輸入數據后,他能根據我們之前的訓練或我們定義的目標輸出我們想要的結果,這個過程其實就像一個函數一樣。我們數據或者需求就是機器學習主體的輸入,而這個主體的輸出就是我們想要的結果。我們把學習機器主體叫做數據模型。數據模型是個函數,也是機器學習學習狀態的體現。數據模型并不是由人搭建起來的系統,它來源于數據,由數據構造。
數據模型的作用:根據我們上面講到的輸入得到一組我們狀語從句:期待的輸入側相關的映射我們通過一些模型框架,也就是算法,如決策樹,SVM等把數據組織起來就可以形成數據模型。即便使用同樣的模型框架算法,在不同的數據集的參與下,也會形成各種不同的模型。同樣的道理,同樣的數據,在不同的框架算法下,也有著不同的表現。因此數據模型的英文數據框架算法狀語從句:數據共同。作用英文的查詢查詢結果經驗表明,數據集的質和量的大小于數據模型的復雜度是呈負相關關系的數據集越大,數據集越好,數據模型的復雜度就越低。反之亦然。有時候數據集質和量差到一定程度,根本無法建立起真正反應真實數據關系的模型的。
如:有一張128×128的圖,我們要構建個數據模型來判斷圖片里到底是貓還是狗,或者什么都不是最簡單的模型就是把全世界所有情況貓和狗的128×128可能出現的影像全部都做個映射,一旦一張圖片出現了,我們立刻就知道,哪個是貓,哪個是狗,這是因為它已經提前映射好了。那如果我們只給出了寥寥幾張圖,這個時候要構建模型就會非常復雜。如果這個時候新來了張圖,是一張之前提供的,沒有的顏色,的貓,那模型的辨識程度就很難讓人滿意,而且一個模型最終的形態是什么樣子的,起決定作用的就是數據。數據質量的好壞直接影響著模型的好壞和功能。數據的數量和質量要比算法重要的多。
因為有了各種不同的模型算法,對數據就有了不同的要求,我們可以直接使用數據,也可以提取這些數據的特征進行使用。特征怎么提取,怎么使用,這是個非常浩大的工程例如:一個三位數,我們能提取出哪些特征呢?其中這里面有非常多的特征。這個三位數的個,十,百位,是不是等差數列,是不是等比數列,三位數是不是都一樣,是不是這個數字可以和哪個節日相重合。甚至有幾個1,有幾個2都是它的特征。哪些特征有用,哪些沒用,往往和我們建模的目的是有關系的。有種說法,說是在中國的股市上,股票代碼里,4這個數字特別多的股票一般都是被低估的股票;而6和8多的股票都是被高估的股票還有像車牌號,手機號,有錢人喜歡用連號等,通過這些特征我們也能大概判斷出這些人的經濟水平。剛才說到的這些特征都蘊含在數據里,也極其 明顯的。要提取這些特征需要我們有著比較豐富的社會經驗,也需要我們善于觀察,總結和歸納。一個三位數字就已經有非常多的特征了,更別說圖片,文字之類的數據了。所以,面對數據我們需要一條一條地多看的情況下,尤其要結合探索性數據的分析方法,宏觀地分析每個情況。總結歸納相關的特征,極端些,可以羅列出所有我們想不到的,想得到的,可能有用的,甚至我們看起來沒用的所有特征,有用就用,沒用就放著;更極端些,我們可以把每條數據當作一個特征,最終建立起一對一的映射關系,除了必要的特征,我們有時還需要對這些特征進行相應的轉化,才能在特定的數據模型算法得到最佳的效果。上面我們說到的所有關于特征的含義,提取,處理等內容,都是特征工程的內容(如下)。
?一,特征使用:確定數據源
?二,特征獲取:確定與存儲數據的過程
三,特征處理(重點)
特征預處理,目的是指數據屬性和特征能盡可能大的發揮作用,體現差別。
1.數據清洗
(1)數據樣本抽樣:
?
1)樣本要具有代表性:樣本各個特征的比例應該與整體的比例保持一致;
2)比如:研究人們日常飲食習慣,但所有被研究人員男女比例失調,達到了極其失真的比例7:1,樣本比例較人類這個整體不是很平衡,我們就需要通過一定的手段使樣本平衡。我們可以在充分考慮代表性的前提下,少取些男性樣本的數量,使男女樣本接近于1,這樣的抽樣雖然相較于被研究的整體有失代表性,但相對于人群的總體,更具有代表性;
3)只有在量大維度廣的數據中我們才能獲得最為準確的結論。當然利用手頭工具可能不能處理全量數據,但如果我們的目的是為了得到更準確的結論,建立更準確的模型,那就非常有必要考慮使用更合適的工具,如Hadoop的等大數據工具。
(2)異常值(空值)處理:
?
(1)空值,重復值,超出1.5倍上下四分位間距的值,實際情況下不允許出現的值。這些值可用函數處理,也可以自己添加規則進行識別。
(2)異常值較多,可以考慮用新值代替異常值;或用判斷這個屬性是否是異常值的判斷結果代替異常值;還可以考慮用集中值(除異常值之外的均值,中位數,眾數等)進行指代;
(3)連續數據中,用四分位間距確定的上下邊界來確定超過上下邊界的數,連續性的數還可以用插值的方法來填充異常值。
2.特征預處理
? ?(1)特征選擇:剔除與標注不相關或冗余的特征,減少特征的個數。
(帶來的效果是減少了模型訓練的時間。尤其是當數據特征比較多的時候(成千上萬個),有時還會有效地減少過擬合,甚至提升模型的準確度。我們前面講過PCA,奇異值變換等通過變換的方式降維的方法,這些對特征降維的處理方式,我們叫做特征提取。既然叫特征提取,那就少不了變換。)
而特征選擇則依靠研究技術調查技術方法,或者數據模型,機器學習模型本身的特征進行與標注影響大小的排序后,剔除排序靠后的特征,實現降維。特征選擇可以放在對特征處理之前進行,也可以在“ 特征變換”后進行。總之,還是要結合屬性本身的特征和任務的需求進行選擇。特征選擇需要重復迭代,不嫌麻煩多次驗證。有時可能我們自己認為特征選擇已經做的足夠好了,但實際模型中訓練并不太好,所以每次特征選擇都要使用模型去驗證,最終的目的是獲取能訓練出更好模型的數據。
數據科學中,有個比較常見的概念 - 數據歸約。特征選擇就是數據規約的一種處理方式(另一種是抽樣)。
# 引入線性回歸器 from sklearn.svm import SVR # 引入決策樹回歸器 from sklearn.tree import DecisionTreeRegressor# 確定特征X和標注Y # 獲取某列數據最直接的方式是df.[列標簽],但是當列標簽未知時可以通過loc獲取列數據。 X=df.loc[:,["A","B","C"]] Y=df.loc[:,"D"] # 引入幾個特征選擇思路的主要方法(SelectKBest——過濾,RFE——包裹,SelectFromModel——嵌入) from sklearn.feature_selection import SelectKBest,RFE,SelectFromModel?
數據選擇有三個切入思路。
1)過濾思想:。直接評價某個特征與標注相關性的特征如果相關性小,就去掉表中我們的標注無疑會落入連續值或者離散值的范疇,而把特征進行比較粗的分類,也可以分為離散值或連續值,于是我們就可以在這張表中找到標注對應的類型與特征對應的類型關聯性對應的評價方法進行評價。當然這里的閾值設置可能比較靈活。大伙可以在特征比較多的時候,閾值設得高些;特征少時,閾值低些;或直接根據任務需求,經驗進行設置。
?
skb =SelectKBest(k=2) # 擬合 # (function f_classif:離散值和連續值用的function可能不一樣, # 所以處理時一張表可能通過不同的方法進行篩選) skb.fit(X,Y) # C列相關性不高,被去掉了 skb.transform(X)2)包裹思想:包裹即包裝,包括的意思假設所有特征是個集合X,最佳的特征是它的一個子集,我們的任務就是找到這個子集我們需要先確定個評價指標,比如正確率于是我們可以遍歷特征子集,找到正確率評價下最佳的子集;也可以一步步進行迭代,比如我們先拆分成幾個大點兒的子集,如果這個時候確定了最優的特征子集,就針對這個特征子集進行接下來的拆分,直到我們的評價指標下降過快或低于閾值時,整個過程結束。
?這個思想下有個比較常用的方法:RFE算法
? # RFE需要指定estimator:這里我們用線性回歸器(復雜度不高)# step:表示每迭代一步去掉幾個特征 rfe =RFE(estimator=SVR(kernel="linear"),n_features_to_select=2,step=1) # sklearn中這些類型實體,尤其是數據轉化的類型實體,他們的操作是有共通性的(都有fit、fit_transform) # 擬合過后再進行變換 rfe.fit_transform(X,Y) # 這個輸出結果是"A"和"C",與上個結果不一致??
?3 )嵌入思想:嵌入的主體是特征,被嵌入的實體是個簡單的模型。也就是說根據個簡單的模型分析特征的重要性。最常見的方式,是用正則化的方式來做特征選擇。
如:我們這里有?個特征,通過個回歸模型對標注進行回歸,回歸可以是線性回歸,也可以是邏輯回歸等最后得到一些瓦特系數,然后對這些瓦特系數,進行正則化或正規化(正則化方式之后講,這里可認為把它轉化成個0-1之間的數)。此時,這些系數就反應了這些特征的分量和重要程度,如果有的系數比較小(像W_2),我們就可以把這個特征去掉。
嵌入思想實際上是有風險的,如有時模型選擇不當,會導致重要屬性被丟棄,所以,這里在嵌入思想選擇的模型最好是和最終做預測的模型有比較強的關聯如:都用線性模型或都用同樣分布形式的(也就是函數圖像一致的)非線性函數。
?
# threshold表示它重要性因子的那個數,低于多少得去掉。 # threshold設置得太高,去掉的屬性也越多 # threshold設置得太低,屬性則都被保留# 為什么不直接用estimator呢,為什么還要進行特征選擇呢? # 因為數據量可能會非常大,而進行特征選擇我們要快速地選出有用的特征。 # 所以我們可以對一部分樣本進行簡單的評測,簡單地用SelectFromModel,或其他的評測方法, # 而評測通過的話,我們就可以用estimator中指定的方法進行建模了。 #特征選擇中我們可能用的是一些樣本,而在正式建模中我們用的是全量數據 sfm =SelectFromModel(estimator=DecisionTreeRegressor(),threshold=0.001) sfm.fit_transform(X,Y)?
我們想預測接下來幾個小時會不會下雨,我們可以拿到歷史數據包括以下屬性,這些屬性中和我們目的直接相關的只有一個(“下雨?不下雨?”),它就是標簽,機器學習的建模是為了建立其他屬性與我們目的之間的關系。
標注:反應目的的屬性(我們關注的,又不容易獲得的,但可以存在些屬性和它有關系,并且這些有關系的屬性是容易獲取到的)其他屬性就是我們接下來要研究的特征。?
拿HR表來說,它也需要個標簽,它的目的是預測員工是否會離職,故此標簽為離職率。
?(2)特征變換:根據特征的特性進行一定方式的轉換,使特征能發揮出它的特點。
接下來我們看幾個比較常用的特征變換的方法:
(1)對指化:就是對數據進行對數化和指數化的過程我們分別看下對數化和指數化的過程。
指數化:就是將一個數進行指數變化的過程指數的底數一般情況下取自然底數?指數化的é是什么呢從圖上看,自然指數的底數函數中,在大于0的部分,橫軸表示自變量有很小一段變化,在縱軸上會有比橫軸尺度更大的變化。也就是說,原來的大于0的范圍內,數據與數據間的差異很小,而經過指數變換,數據與數據間的差距變大了如:我們計算出某特征數據屬于Y1,Y2,Y3的概率,進行指數化(他們的差距從0.1變成0.14),再進行歸一化(差距變小了0.1變成了0.04)。這個過程叫SOFTMAX(在監督學習神經網絡中有非常廣泛的應用)。
對數化:底數可以取2,10,例如如果一個數遠大于1,橫軸變化很大的時候,縱軸的變化也不會很大這樣可以將一個非常大的數縮放到一個容易與方便計算的范圍內如:收入數據。
(2)離散化:將連續數據變成離散數據的離散化操作。
數據需要被離散化的原因如下:
第一,連續數據的信息很多,但其中也有可能存在些我們意想不到的噪聲如:我們想通過收入分析國企,私企和外企哪個待遇好如果我們可以獲得員工的收入流水,基本可以確定和比較收入情況了。但如果有員工會通過接私活的方式賺取外快,或工資的一部分被公司扣去用作其他用途,那流水就有噪聲,不能直接反應收入情況。如果有合適的方法將數據離散化,直接對比離散值的分布屬性就有可能得出更令人信服的結論;第二,某些算法要求數據必須是離散的,如:樸素貝葉斯。第三,數據的非線數據映射的需求;如:拿某些數據的分布來看,分布可能會有明顯的拐點或拐角點連續數值在不同的區間內可能代表著不同的含義。
離散化的方法:
自因變量優化:就是根據自變量,因變量的有序分布,找到拐點,特殊變化點進行離散化(詳見探索性數據分析);等頻分箱又叫等深分箱(如下圖);等距分箱又叫等寬分箱(67-6 = 61,平均分成3分,分成3個區間)。接下來我們著重分析分箱技術:數據在分箱前一定要進行排序。既然是個箱子,就有它的深度和寬度。
import numpy as np import pandas as pd lst= [6,8,10,15,16,24,25,40,67] # 等深分箱 pd.qcut(lst,q=3,labels=["low","medium","high"]) # 等寬分箱 pd.cut(lst,bins=3,labels=["low","medium","high"])(3)歸一化:最小化,最大化的一種特殊形式,將數據所觸及的范圍縮放到指定大小范圍內所謂歸一化,是將數據轉換到0-1范圍的內這樣處理起來會更方便些一方面,可以觀察單個數據相對于數據整體情況的比例;另一方面,如果遇到不同樣綱的數據特征,可以方便地建立起這些數據特征之間進行合適地距離度量方法。(如:特征甲:0-10,特征B:0-100,將他們都進行歸一化,他們的范圍都是0-1,這樣對比數據就比較科學)
?
import numpy as np import pandas as pd # 導入歸一化和標準化需要用的包 from sklearn.preprocessing import MinMaxScaler,StandardScaler # 歸一化 # reshape(-1,1)表示不指定有多少行,但一定要有1列 MinMaxScaler().fit_transform(np.array([1,4,10,15,21]).reshape(-1,1))(4)標準化:將數據轉換成一個標準的形式歸一化也可以說是種標準化這里的標準化是指將數據縮放到均值為0,標注差為1的尺度上。
標準化的意義:體現一個數據與該特征下其他數據相對大小的差距關系(如:你180,其他同學都是160,你就會覺得你很高;但是全班一半人都是180,其他都是160,你就不會覺得自己有多高了。)? ?
# 標準化 # 先fit再transform也是可以的 StandardScaler().fit_transform(np.array([1,1,1,1,0,0,0,0]).reshape(-1,1)) StandardScaler().fit_transform(np.array([1,0,0,0,0,0,0,0]).reshape(-1,1))?
?(5)數值化:把非數值數據(處理起來不方便)轉化為數值數據的過程。
import numpy as np import pandas as pd from sklearn.preprocessing import LabelEncoder,OneHotEncoder我們回顧下數據的四種類型:前三類數據在使用時,要根據是否進行相關的運算進行轉換。
定序數據的數值化,可以考慮使用標簽化的處理方式。(用0,1,2等值代替原來的數據屬性。各個值之間相差多大并不重要。有時,定序數據都不需要特殊化的處理,都可以交給參數去做)。也可以使用獨熱方法進行編碼(當沒有相對大小關系的時候)。??
?
# 標簽化 LabelEncoder().fit_transform(np.array(["Down","Up","Up","Down"]).reshape(-1,1)) LabelEncoder().fit_transform(np.array(["Low","Medium","High","Medium","Low"]).reshape(-1,1))定位數據(沒有相對大小關系的)的處理(麻煩些):直接進行標簽化,會有額外的擾動這些信息有可能會影響之后建立模型的準確性定位數據中每種不同的數值,相互差別應該是一致的。將數據特征進行擴維,原來的?維屬性由?維向量來表示。這個向量只有一位是1,其他都是0。
# 在one-hot之前必須先把它label_encoding lb_encoder =LabelEncoder() # 傳入一個數組 lb_tran_f = lb_encoder.fit_transform(np.array(["Red","Yellow","Blue","Green"])) # label_encoding的結果傳入 oht_encoder = OneHotEncoder().fit(lb_tran_f.reshape(-1, 1)) oht_encoder.transform(lb_encoder.transform(np.array(["Yellow","Blue","Green","Green","Red"])).reshape(-1,1)).toarray()?
??(6)正規化:本質是將一個向量的長度正規到單位1。
import numpy as np import pandas as pd from sklearn.preprocessing import Normalizer如果距離的尺度用L1距離,那就是L1正規化。分子保持向量的分量不變,分母為各個分量絕對值的和。
如果使用L2距離(歐式距離),那就是L2正則化。分母是向量的歐式長度。
例如:
?數據處理中正規化的用法:第一個用的少;第二個可以體現出一個對象特征影響的相對關系特點;第三個,可用到線性回歸,邏輯回歸等,可用L2正則化可以表示每個特征對于標注的影響占比比較大,哪個比較小。?
# 注意:默認是對行進行正則化 Normalizer(norm="l1").fit_transform(np.array([[1,1,3,-1,2]])) Normalizer(norm="l2").fit_transform(np.array([[1,1,3,-1,2]]))?
?
?(3)特征降維?
PCA,奇異值分解都沒有考慮到標注,而是讓特征與特征之間的相關性強弱來決定降維后的分布形態,是一種無監督的降維方法。
使用到標注的降維方法:?
LDA處理過程:一個特征矩陣,特征有X_0-X_m共米個特征,Y是它的標注我們以二分類為例,這里的?取0/1同時這個特征矩陣有?行,對應于?個對象。
特征抽出來形成個特征矩陣:
我們把這個矩陣根據行進行切分,可以分成兩個子矩陣,一個矩陣的標注都是0,另一個都是1:
針對這兩個子矩陣做線性變換(標注y并不參與計算):
?LDA的核心是標注間距離盡可能大,同一標注內距離盡可能小。所以我們分成兩部分進行衡量。
針對兩個矩陣可能出現的行列數據不匹配的情況,我們可以最大化一個函數如下:
用數學的方法整理下整個過程:我們先計算每個標注下,每個特征的均值(是為了運算方便);然后最大化一個函數,這個函數要求的變量就是參數W,其他值都是根據數據指定的,是已知的函數的分子是兩個標注的子矩陣減均值后再用參數做變換,然后取平方,再取范數將其標量化;而分母是兩個新的子矩陣的平方和,然后取范數,可等效(減少運算量,并解決兩個子矩陣尺寸大小不一致的情況【即行不一致,樣本數量不一致,但特征數量一致,就保證了中間兩個矩陣是可以相乘的】)如下形式。
?分子也等效得:
簡化后如下,最終結果就是求它取最大時,W的值求出.W,就確定了新的空間下分離程度最大的方向。
例如:右圖為最佳的轉化,W確定了中間這條分離線的方向,我們可以對Wˉˉ進行正規化處理,把正規化后比較小的W ^表示的分量去掉,保留最大的,最能代表原來信息的一個或一些分量,這樣就可以達到降維的目的。
import numpy as np import pandas as pd from sklearn.discriminant_analysis import LinearDiscriminantAnalysis # X是二維數組 X=np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]]) # Y是標注 Y=np.array([1,1,1,2,2,2]) # n_components=1降成1維 LinearDiscriminantAnalysis(n_components=1).fit_transform(X,Y)# 其實LDA降維以后我們也可以把它當個判別器(fisher_classifer判別器)來用 # 賦值到一個分類器上 clf=LinearDiscriminantAnalysis(n_components=1).fit(X,Y) # 輸入的數據也一定是二維的 clf.predict([[0.8,1]]) # 我們得到個分類?
(4)特征衍生:現有特征進行某些組合,生成新的具有含義的特征。
我們通常采集到的數據的特征維度不會很大,而且直接采集到的特征并不一定能完全體現數據的全部信息,需要通過已有的數據組合發現新的含義。
常用方法:第一,可以求時間差等;第三,經常會進入常識性特征因素。
例如:某電商網站用戶購買產品的列表
?通過衍生可以建立起用戶與商品的一些關系,這個思路也是推薦系統中擴維的一種主要方法。
?
四,特征監控
如果我們建立的模型需要長期使用,隨著時間的流逝,可用的數據集會越來越多,同時在更多未知情況下,模型的效果可能會有變化,參數也可能需要重新矯正,這就需要我們對模型,對特征的契合程度進行不斷地監控。
(1)現有特征:是不是依然對我們的數據任務有積極的作用。?
(2)新特征:探索新特征是不是有助于對提高效果或者更能代表我們的數據任務目標。
總結:不同的模型需要不同的處理方式。同樣,數據分布、數據特點不同,不同的處理方式,表現出的效果不同。要多次嘗試,根據經驗,使用些針對某些領域比較常用的模型和算法。
?
總結
以上是生活随笔為你收集整理的python数据分析新手入门课程学习——(五)特征工程概述(数据预处理)(来源:慕课网)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 职场纵横:IT职位全面解析(计算机类要找
- 下一篇: 计算机论文中期考核报告,计算机与人工智能