《准备》一书中讲到解决问题一个方法(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', '*lyn', '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])
关于数据特征提取就先结束在此,需要说明的是还有文本特征分析、图片特征分析,未完待续。。。。。