資料分析特徵工程方法

等待的豬發表於2021-01-21

《準備》一書中講到解決問題一個方法(STP法則)亦適合於資料分析或者資料探勘領域,即:瞭解背景情況(S)、明確最終目標(T)、準備提案(P)。首先必須得明白資料分析的背景,針對背景做些相對全面的瞭解,在逐步明確最終目標(不得不說這是一個不斷追問的過程),準備分析的大概流程,將資料分析的方法嵌入其中,應該說資料分析工具是多種多樣的,我們甚至可以不需要知道具體的工具怎麼使用,因為網路上有極多的工具介紹,但我們需要了解的是分析的思路,藉著思路去找工具。我們介紹了資料分析資料特徵提取的一些思路以及一些工具供大家參考。
相關例子的資料來源於 https://www.kaggle.com/dgomonov/new-york-city-airbnb-open-data 紐約市Airbnb開放資料美國紐約市的Airbnb列表和指標(2019)
利用的庫有pandas、sklearn。

  • 資料特徵提取腦圖
    在這裡插入圖片描述

  • 資料描述
    資料描述的目的是檢視資料集的基本情況,包括資料量、資料缺失情況等。

#讀取資料集
df = pd.read_csv('AB_NYC_2019.csv')
#資料描述
df.describe()
#資料集情況
df.info()

##資料集描述結果
在這裡插入圖片描述
##各列資料情況
在這裡插入圖片描述

  • 異常值處理
    異常值的處理一般有這麼幾個方法:刪除、重新計算替代(包括:均值、填0、中位數、眾數、模型預測值替代等)。
#刪除空值
df.dropna(inplace=True)
#刪除某列為0的值
df[~df.price.isin([0])]
  • 歸一化
    1)min~max方法:
    在這裡插入圖片描述
df['price_min_max'] = df['price'].apply(lambda x:(x-df['price'].min())/(df['price'].max()-df['price'].min()))

2)Z評分歸一化:通過中心化和標準化處理,得到均值為0,標準差為1的服從標準正態分佈的資料。

df['price_std'] = df['price'].map(lambda x:(x-df['price'].mean())/df['price'].std())

3)取對數

import math
df['price_log'] = df['price'].apply(lambda x:math.log((x/2.0),2))
sns.distplot(df.price_log)
plt.title('價格取對數結果')

在這裡插入圖片描述

  • 時間處理方法
    時間作為一個重要的特徵,需要將其數值化才能放入各種模型中,數值化亦可方便統計分析。時間特徵處理一般需要將str型別的日期轉換為時間戳。根據時間戳可以把時間特徵劃分為周度、日度、月度、年度、十年等週期,對於類似於餐飲、旅遊等行業還可以劃分工作日/休息日、節假日(是/否)等。
#將時間由字元轉換成時間戳
df['last_review_time']=pd.to_datetime(df.last_review)
#月份提取
df['last_review_time_month']=df['last_review_time'].apply(lambda x :x.month)
#周度提取
df['last_review_time_week']=df['last_review_time'].apply(lambda x :x.week)
#季度提取
df['last_review_time_quarter'] = df['last_review_time'].apply(lambda x :x.quarter)
#是否工作日
def is_busday(date):
    if bool(len(pd.bdate_range(date, date))):
        date_bus = 1
    else:
        date_bus = 0
    return date_bus

df['last_review_time_is_bus'] = df['last_review_time'].apply(lambda x:is_busday(x))
#是否節假日
#1)美國節假日
from pandas.tseries.holiday import USFederalHolidayCalendar as calendar

car = calendar()
holidays = car.holidays(df['last_review_time'].min(),df['last_review_time'].max())
df['last_review_time_is_holiday'] = df['last_review_time'].isin(holidays).astype(int)
#2)中國節假日
import calendar
import chinese_calendar as cn_cal
df['last_review_time_is_CN_holiday'] = df['last_review_time'].apply(lambda x:cn_cal.is_holiday(x)).astype(int)
  • 類別資料編碼
    類別特徵指類似與地區、國度、型別ID等非數值化特徵。將此類特徵數值化可以使用one_hot編碼、也可以編碼為0、1、2、3等連續值。
#地區one_hot編碼
df2=pd.get_dummies(df['neighbourhood_group'])
df = df.join(df2)

在這裡插入圖片描述

#房型room_type one_hot編碼
df3=pd.get_dummies(df['room_type'])
df = df.join(df3)

在這裡插入圖片描述

  • 連續性資料離散化
    連續性資料特徵離散化是針對連續性資料分佈不成正態分佈或者離散程度太大的情況,對連續性資料進行分段或者數值變換的操作。
    1)首先檢視資料的分佈情況:
sns.boxplot(df.price)
sns.lineplot(range(len(df.price)),df.price)

在這裡插入圖片描述
從price的分佈情況可以看到,資料跨度極大,離散程度大,資料主要集中分佈在3000以下。通過seaborn.distplot()逐步檢視資料分佈情況,以確定合適的區間臨界值。

#<500
price_500 = df[df.price.apply(lambda x :x<500)]
sns.distplot(price_500.price)
plt.title('0~500')
#500~3000
price_3000 = df[df.price.apply(lambda x :x<3000 and x>500)]
sns.distplot(price_3000.price)
plt.title('500~3000')
#3000~10000
price_10000 = df[df.price.apply(lambda x :x>3000)]
sns.distplot(price_10000.price)
plt.title('3000~10000')

在這裡插入圖片描述
從資料的分佈情況來看,將區間設定為[0,50,100,150,200,250,300,400,500,600,700,800,900,1000,1500,2000,2500,3000,4000,6000,8000,10000]

#分段
price_list =[0,50,100,150,200,250,300,400,500,600,700,800,900,1000,1500,2000,2500,3000,4000,6000,8000,10000]
df['price_bins']=pd.cut(df.price,price_list)
#區間編碼:one_hot
pd.get_dummies(df.price_bins)

在這裡插入圖片描述

  • 連續性資料特徵多維化
    連續性特徵多維化的目的是建立特徵之間的關聯性,由此構建新特徵。常見的有特徵間的對數計算、線性計算等。sklearn庫整合了線性計算的方法,即 PolynomialFeatures。
#多特徵構建高維特徵
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2)
price_poly=poly.fit_transform(df7[['price_min_max','price_std']])
pd.DataFrame(price_poly)

在這裡插入圖片描述
polynnomialFeatures特徵描述
0:a0*b0 1:a1*b0 2:a0*b1 3:a2*b1 4:a1*b1 5:a0*b2

  • 資料特徵降維及展示
    我們構建了多維化的特徵群,那些特徵適合,或者說需要將單獨的特徵降維為若干特徵,能加速後續機器學習的訓練,得到更優的模型。常用的降維方法有PCA\T-SNE\LLE等。
#PCA降維
from sklearn.decomposition import PCA
features = df7[['number_of_reviews', 'reviews_per_month', 'price_min_max', 'price_std', 'Bronx', 'Brooklyn', 'Manhattan', 'Queens', 'Staten Island', 'price_log']]#特徵
fe_model = PCA(n_components=2)
new_fetures=fe_model.fit_transform(features)
plt.scatter(new_fetures[:,0],new_fetures[:,1])
plt.title('PCA降維結果展示')

在這裡插入圖片描述

#T-SNE降維
from sklearn.manifold import TSNE
new_fetures_tsne = TSNE(n_components=2).fit_transform(features)
plt.scatter(new_fetures_tsne[:,0],new_fetures_tsne[:,1])
plt.title('TSNE降維結果展示')

在這裡插入圖片描述

#LLE特徵降維
from sklearn.manifold import locally_linear_embedding as LLE
new_fetures_tsne = LLE(new_fetures,n_neighbors=12,n_components=2)
plt.scatter(new_fetures_tsne[0][:,0],new_fetures_tsne[0][:,1])
plt.title('LLE降維結果展示')

在這裡插入圖片描述

#T-SNE特徵降維:3個特徵
from mpl_toolkits.mplot3d import Axes3D
new_fetures_tsne = TSNE(n_components=3).fit_transform(features)
ax = plt.subplot(projection='3d')
ax.scatter(new_fetures_tsne[:,0],new_fetures_tsne[:,1],new_fetures_tsne[:,2])

在這裡插入圖片描述
關於資料特徵提取就先結束在此,需要說明的是還有文字特徵分析、圖片特徵分析,未完待續。。。。。

相關文章