1. 程式人生 > >特徵工程——特徵轉換

特徵工程——特徵轉換

這裡寫圖片描述

一、連續型變數

1.1 連續變數無量綱化
無量綱化: 使不同規格尺度的資料轉化統一規格尺度(將資料單位統一)
無量綱化方法:標準化, 區間所方法 
標準化: 將連續性變數轉變為 均值0 標準差1 的變數
x=xx¯σx¯σ
程式碼:                                 #對 Amount欄位--均值為0,方差為1標準化
from sklearn import preprocessing
std = preprocessing.StandardScaler()  #StandardScaler
Amount = RFM['Amount'].values.reshape(-1,1) std.fit(Amount) RFM['Amount_std'] = std.transform(Amount) RFM.head(5)

區間縮放法:把原始的連續型變數轉換為範圍在[a,b]或者 [0,1] 之間的變數

x=xmin(x)max(x)min(x)
程式碼:                                       #對 Amount欄位--[0,1]區間歸一化 
from sklearn import preprocessing
Min
Maxscaler = preprocessing.MinMaxscaler() #MinMaxscaler Amount = RFM['Amount'].values.reshape(-1,1) MinMaxscaler.fit(Amount) #擬合(訓練) RFM['Amount_range'] = MinMaxscaler.transform(Amount) RFM.head(5)
1.2 連續變數資料變換
資料變換:通過函式變換改變原始資料的分佈
目   的: 資料從無關係 -> 有關係
         呈偏態分佈-->變換後差異拉開
         讓資料符合模型理論所需要的假設,然後對其分析,例如:變換後資料呈正態分佈
資料變化方法:
logX,Ine 等 對數函式變換 x=ln(x)
box-cox 變換 :自動尋找最佳正態分佈變換函式的方法

這裡寫圖片描述

程式碼1#對 Amount欄位--log 變換
import numpy as np
RFM['Amount_log'] = np.log(RFM['Amount'])
RFM,head(5)

程式碼2#對 Amount欄位--sqrt (平方根) 變換
import numpy as np
RFM['Amount_sqrt'] = np.sqrt(RFM['Amount'])
RFM,head(5)
1.3 連續變數離散化
目的:方便探索資料相關性
      減少異常資料對模型的干擾
      為模型引入非線性,提升模型預測能力
      離散後,可進行特徵交叉組合,又M+N 變成 M*N
資料離散化方法:
    非監督離散方法:
        自定義規則,
        等寬方法,
        等頻/等深方法 
非監督離散方法:
 #對 Amount欄位--自定義區間 離散化
        cut_points = [0,200,500,800,1000]
        RFM['Amount_bin'] = pd.cut(RFM['Amount'],bin = cut_points)
        RFM,head(5)
 #對 Amount欄位--等寬 離散化
        RFM['Amount_width_bin'] = pd.cut(RFM.Amount,20) #分成20等分
        RFM,head(5)
        grouped = RFM.groupby('Amount_width_bin')
        grouped['CardID'].count()
 #對 Amount欄位--等深 離散化
        RFM['Amount_depth_bin'] = pd.qcut(RFM.Amount,5) #分成5人的等分約20%
        RFM,head(5)
        grouped = RFM.groupby('Amount_depth_bin')
        grouped['CardID'].count()
有監督離散方法:決策樹
離散化後的目標分類純度最高(對目標有很好的區分能力)
一種特殊的離散化方法:
    二值化:           把連續型變數分割為0/1(是/否) 例如:是否大於18歲(是/否)
    Rounding(取整): 本質上時一種類似‘等距方法’的離散

二、類別變數編碼

類別變數編碼:
類別型變數—-編碼成—> 數值型變數
目的:
機器學習演算法 無法處理類別型變數,必須轉換為數值型變數
一定程度起到了擴充特徵的作用(構造了新的特徵)
one-hot encoding 獨熱編碼
dummy encoding 啞變數編碼
label-encoding 標籤編碼
count-Encoding 頻數編碼 (可以去量綱化,秩序,歸一化)
Target encoding 二分類 用目標變數中的某一類的比例來編碼
程式碼:
import pandas as pd                    #匯入的資料來源於 特徵構造
trade = pd.read_csv('./data/transaction.txt')
trade['Date'] = pd.to_datetime(trade['Date'])
RFM = trade.groupby('CardID').egg({'Date':'max','CardID':'count','Amount':'sum'})
RFM.head()

--------------Onehot 編碼(獨熱編碼)使用pandas------------------
onehot = pd.get_dummies(RFM['CardID']),drop_first = False,prefix = 'Freq'

onehot.head()
    from sklearn import preprocessing      #使用sklearn 匯入OneHotEncoder
    onehot = preprocessing.OneHotEncoder() #OneHotEncoder
    Freq = RFM['CardID'].values.reshape(-1,1)
onehot.fit(Freq)
    Freq_onehot = onehot.transform(Freq).toarray()
    Freq_onehot
    df = pd.DataFrame(Freq_onehot)         #將array 轉為pandas 的dataframe
    df.head()

三、時間型、日期型變數轉換

程式碼:
import pandas as pd
data = pd.DataFrame({'data_time':pd.date_range('1/1/2017 00:00:00',period = 12,freq = 'H'),'data':pd.date_range('2017-1-1',period = 12,freq = 'M')
})

■ data:提取日期型和時間型的特徵變數
data['year']= data['data_time'].dt.year
data['month'] = data['data_time'].dt.month
data['day'] = data['data_time'].dt.day
data['hour'] = data['data_time'].dt.hour
data['minute'] = data['data_time'].dt.minute
data['second'] = data['data_time'].dt.second
data['quarter'] = data['data_time'].dt.quarter
data['week'] = data['data_time'].dt.week
data['yearmonth'] = data['data_time'].dt.strftime('%Y-%m')
data['halfyear'] = data['data_time'].mapa(lambda d:'H' if d.month <= 6 else 'H2')data:轉換為相對時間特徵
import datetime
data['deltaDayToToday'] = (datetime.date.today()-data['date'].dt.date).dt.days  #距離今天的間隔(天數)
data['deltaMonthToToday'] = datetime.date.today().month - data['date'].dt.month #距離今天的間隔(月數)
data['daysOfyear'] = data['date'].map(lambda d:366 if d.is_leap_year els 365)   #一年過去的進度
data['rateOfyear'] = data['date'].dt.dayofyear/data['daysOfyear']
data.head()

四、 缺失值處理

刪除缺失值記錄
缺失值替換:
用0替換
平均數替換
眾數替換
預測模型替換
構造NaN encoding編碼
構造一個新的欄位來標識是否有缺失(1/0) 任何時候都可使用
import pandas as pd
titanic = pd.read_csv('./data/titanic.csv')
titanic.info()

age_mean = round(titanic['Age'].mean())        #對缺失值進行填充
titanic['Age'].fillna(age_mean,inplace = True) #填充平均年齡
titanic.info()

titanic = pd.read_csv('./data/titanic.csv')    #構造缺失值的標誌變數(0/1)
titanic.info()
titanic['Age_ismissing'] = 0
titanic.loc[titanic['Age'].isnull(),'Age_ismissing'] = 1
titanic['Age_ismissing'].value_counts()

五、 特徵組合

目的:
構造更多更好的特徵,提升模型精度(例如:地球儀的經緯密度)
方法:
多個連續變數: 加減乘除運算
多個類別型變數: 所有值交叉組合
import pandas as pd 
titanic = pd.read_csv('./data/titanic.csv')
titanic.head()

# 組合特徵
titanic['Sex_pclass_combo'] = titanic['Sex']+'_pclass_'+titanic['Pclass'].astype(str)
titanic.Sex_pclass_combo.value_counts()

# onehot編碼
Sex_pclass_combo = pd.get_dummies['Sex_pclass_combo'],drop_first = False,prefix = 'onehot'
Sex_pclass_combo.head()