美文网首页
数据表示和特征表示

数据表示和特征表示

作者: dreampai | 来源:发表于2019-01-17 15:20 被阅读0次

一、分类变量

1、One-Hot 编码(虚拟变量)

  • value_counts:使用 pandas Series 的 value_counts 函数,显示唯一值及出现次数。
  • get_dummies:自动变换所有具有对象类型(比如字符串)的列或所有分类的列
  • values:将 data_dummies 数据框转换为 Numpy 数组。

需要同时对包含训练数据和测试数据的数据框调用 get_dummies ,可以确保训练集和测试集中分类变量的表示方式相同。

import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

data=pd.read_csv('data/adult.data',header=None,index_col=False,names=['age', 'workclass', 'fnlwgt', 'education',  'education-num',
                    'marital-status', 'occupation', 'relationship', 'race', 'gender',
                    'capital-gain', 'capital-loss', 'hours-per-week', 'native-country',
                    'income'])

data=data[['age', 'workclass', 'education', 'gender', 'hours-per-week', 'occupation', 'income']]

# print(data.head())
print(data.gender.value_counts())
print('Original features:\n',list(data.columns),'\n')
data_dummies=pd.get_dummies(data)
print('Features after get_dummies:\n',list(data_dummies.columns))
print(data_dummies.head())

features=data_dummies.ix[:,'age':'occupation_ Transport-moving']
X=features.values
y=data_dummies['income_ >50K'].values
print('X.shape:{} y.shape:{}'.format(X.shape,y.shape))

X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0)
logreg=LogisticRegression()
logreg.fit(X_train,y_train)
print('Test score:{:.2f}'.format(logreg.score(X_test,y_test)))

2、数字可以编码分类变量

使用 scikit-learn 的 OnehotEncoder,指定哪些变量是连续的,哪些变量是离散的。也可以将数据框中的数值列转换为字符串。

import pandas as pd

demo_df=pd.DataFrame({'Integer Feature':[0,1,2,1],
                      'Categorical Feature':['socks','fox','socks','box']})
print(demo_df)
demo_dummies=pd.get_dummies(demo_df)
# print(demo_dummies)

demo_df['Integer Feature']=demo_df['Integer Feature'].astype(str)
demo_dummies=pd.get_dummies(demo_df)
print(demo_dummies)

二、分箱、离散化、线性模型与树

特征分箱将其划分为多个特征,可以让线性模型在连续的数据上更强大。

  • np.digitize(X,bins=bins),分箱
  • 线性模型变得更加灵活了,因为现在它对每个箱子具有不同的取值
  • 决策树模型的灵活性降低了,分箱特征对基于树的模型通常不会产生更好的效果,因为这种模型可以学习在任何位置划分数据。
    决策树可以学习如何分箱对预测这些数据最为有用,决策树可以同时查看多个特征,而分箱通常针对的是单个特征。
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.preprocessing import OneHotEncoder
import matplotlib.pyplot as plt
import numpy as np
import mglearn

X,y=mglearn.datasets.make_wave(n_samples=100)
line=np.linspace(-3,3,1000,endpoint=False).reshape(-1,1)

# 分箱
bins=np.linspace(-3,3,11)
print('bins:{}'.format(bins))
which_bin=np.digitize(X,bins=bins)
print('\nData points:\n',X[:5])
print('\nBin membership for data points:\n',which_bin[:5])

encoder=OneHotEncoder(sparse=False)
encoder.fit(which_bin)
X_binned=encoder.transform(which_bin)
print(X_binned[:5])
print('X_binned.shape:{}'.format(X_binned.shape))

line_binned=encoder.transform(np.digitize(line,bins=bins))
reg=LinearRegression().fit(X_binned,y)
plt.plot(line,reg.predict(line_binned),label='linear regression binned')

reg=DecisionTreeRegressor(min_samples_split=3).fit(X_binned,y)
plt.plot(line,reg.predict(line_binned),label='decision tree binned')
plt.plot(X[:,0],y,'o',c='k')
plt.vlines(bins,-3,3,linewidth=1,alpha=.2)
plt.legend(loc='best')
plt.ylabel('Regression output')
plt.xlabel('Input feature')
plt.show()

对于特定的数据集,如果有充分的理由使用线性模型——比如数据集很大,维度很高,但有些特征与输出关系是非线性的——那么分箱是提高建模能力的好方法。

三、交互特征和多项式特征

1、交互特征

加入原始特征:只有一个 x 特征,所以只有一个斜率。因为斜率在所有箱子中是相同的,所以它似乎不是很有用

image.png
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import OneHotEncoder
import matplotlib.pyplot as plt
import numpy as np
import mglearn

X,y=mglearn.datasets.make_wave(n_samples=100)
line=np.linspace(-3,3,1000,endpoint=False).reshape(-1,1)

# 分箱
bins=np.linspace(-3,3,11)
which_bin=np.digitize(X,bins=bins)

encoder=OneHotEncoder(sparse=False)
encoder.fit(which_bin)
X_binned=encoder.transform(which_bin)
line_binned=encoder.transform(np.digitize(line,bins=bins))

X_combined=np.hstack([X,X_binned])
line_combined=np.hstack([line,line_binned])

reg=LinearRegression().fit(X_combined,y)
plt.plot(line,reg.predict(line_combined),label='linear regression combined')

for bin in bins:
    plt.plot([bin,bin],[-3,3],':',c='k')

plt.legend(loc='best')
plt.ylabel('Regression output')
plt.xlabel('Input feature')
plt.plot(X[:,0],y,'o',c='k')
plt.show()

添加交互特征或乘积特征,用来表示数据点所在箱子以及数据点在 x 轴上的位置。这个特征是箱子指示符与原始特征的乘积。


image.png
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import OneHotEncoder
import matplotlib.pyplot as plt
import numpy as np
import mglearn

X,y=mglearn.datasets.make_wave(n_samples=100)
line=np.linspace(-3,3,1000,endpoint=False).reshape(-1,1)

# 分箱
bins=np.linspace(-3,3,11)
which_bin=np.digitize(X,bins=bins)

encoder=OneHotEncoder(sparse=False)
encoder.fit(which_bin)
X_binned=encoder.transform(which_bin)
line_binned=encoder.transform(np.digitize(line,bins=bins))

X_product=np.hstack([X,X*X_binned])
line_product=np.hstack([line,line*line_binned])

reg=LinearRegression().fit(X_product,y)
plt.plot(line,reg.predict(line_product),label='linear regression combined')

for bin in bins:
    plt.plot([bin,bin],[-3,3],':',c='k')

plt.legend(loc='best')
plt.ylabel('Regression output')
plt.xlabel('Input feature')
plt.plot(X[:,0],y,'o',c='k')
plt.show()

2、多项式

image.png
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
import numpy as np
import mglearn

X,y=mglearn.datasets.make_wave(n_samples=100)
line=np.linspace(-3,3,1000,endpoint=False).reshape(-1,1)

poly=PolynomialFeatures(degree=10,include_bias=False)
poly.fit(X)
X_poly=poly.transform(X)
print('X_poly.shape:{}'.format(X_poly.shape))
print('Polynomial feature names:\n{}'.format(poly.get_feature_names()))

reg=LinearRegression().fit(X_poly,y)
line_poly=poly.transform(line)
plt.plot(line,reg.predict(line_poly),label='polynomial linear regression')
plt.legend(loc='best')
plt.ylabel('Regression output')
plt.xlabel('Input feature')
plt.plot(X[:,0],y,'o',c='k')
plt.show()

波士顿房价数据集

  • 缩放数据
  • 提取多项式和交互特征
  • Ridge 和 随机森林对比
    在使用 Ridge 时,交互特征和多项式对性能有很大的提升。但使用更加复杂的模型,情况会稍有不同
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import Ridge

boston=load_boston()
X_train,X_test,y_train,y_test=train_test_split(boston.data,boston.target,random_state=0)

# 缩放数据
scaler=MinMaxScaler()
X_train_scaled=scaler.fit_transform(X_train)
X_test_scaled=scaler.transform(X_test)

poly=PolynomialFeatures(degree=2).fit(X_train_scaled)
X_train_poly=poly.transform(X_train_scaled)
X_test_poly=poly.transform(X_test_scaled)
print('Polynomial feature names:\n{}'.format(poly.get_feature_names()))

# 岭回归对比
ridge=Ridge()
ridge.fit(X_train_scaled,y_train)
print('Score without interactions:{:.3f}'.format(ridge.score(X_test_scaled,y_test)))
ridge=Ridge()
ridge.fit(X_train_poly,y_train)
print('Score with interactions:{:.3f}'.format(ridge.score(X_test_poly,y_test)))

# 随机森林对比
rf=RandomForestRegressor(n_estimators=100)
rf.fit(X_train_scaled,y_train)
print('Score without interactions:{:.3f}'.format(rf.score(X_test_scaled,y_test)))
rf=RandomForestRegressor(n_estimators=100)
rf.fit(X_train_poly,y_train)
print('Score with interactions:{:.3f}'.format(rf.score(X_test_poly,y_test)))

四、单变量非线性变换

  • 如果特征和目标之间存在非线性关系,那么建模就变得非常困难,特别是回归问题。
  • log 和 exp 函数可以帮助调节数据的相对比列,从而改进线性模型或神经网络的学习效果。
  • 在处理周期性模式的数据时,sin 和 cos 函数非常有用。

大部分模型都在每个特征大致遵循高斯分布时表现最好,也就是说,每个特征的直方图应该具有类似于熟悉的“钟形曲线”的形状。

处理整数计数数据时,计数数据指类似“用户 A 多长时间登陆一次”,计数不可能取负值,并且遵循特定的统计模式。


许多较小的值和一些非常大的值.png

数据分布的不对称性变小,也不再有非常大的异常值


image.png
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split

rnd=np.random.RandomState(0)
X_org=rnd.normal(size=(1000,3))
w=rnd.normal(size=3)

X=rnd.poisson(10*np.exp(X_org))
y=np.dot(X_org,w)
print('Number of feature appearances:\n{}'.format(np.bincount(X[:,0])))
# 许多较小的值和一些非常大的值
bins=np.bincount(X[:,0])
plt.bar(range(len(bins)),bins,color='r')
plt.ylabel('Number of appearances')
plt.xlabel('Value')
plt.show()

X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0)
score=Ridge().fit(X_train,y_train).score(X_test,y_test)
print('Test score:{:.3f}'.format(score))
# 由于数据取值中包含0 对数取0没有意义,所以+1
X_train_log=np.log(X_train+1)
X_test_log=np.log(X_test+1)
#数据分布的不对称性变小,也不再有非常大的异常值
plt.hist(X_train_log[:,0],bins=25,color='gray')
plt.xlabel('Value')
plt.ylabel('Number of appearances')
plt.show()

score=Ridge().fit(X_train_log,y_train).score(X_test_log,y_test)
print('Test score:{:.3f}'.format(score))

五、自动化特征选择

如何判断每个特征的作用有多大:

  • 单变量统计
  • 基于模型的选则
  • 迭代选择

1、单变量统计

计算每个特征和目标值之间的关系是否存在统计显著性,然后选择具有最高置信度的特征。
对分类问题通常是 f_classif (默认值),对回归问题通常是 f_regressioni,然后基于测试中确定的 p 值来选择一种舍弃特征的方法。


image.png
from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import SelectPercentile
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt

import numpy as np

cancer=load_breast_cancer()
# 添加噪声数据
rng=np.random.RandomState(42)
noise=rng.normal(size=(len(cancer.data),50))
X_w_noise=np.hstack([cancer.data,noise])

X_train,X_test,y_train,y_test=train_test_split(X_w_noise,cancer.target,random_state=0,test_size=.5)

# 选择前50%特征
select=SelectPercentile(percentile=50)
select.fit(X_train,y_train)
X_train_selected=select.transform(X_train)


print('X_train.shape:{}'.format(X_train.shape))
print('X_train_selected.shape:{}'.format(X_train_selected.shape))
# 可视化
mask=select.get_support()
print(mask)
plt.matshow(mask.reshape(1,-1),cmap='gray_r')
plt.xlabel('Sample index')
plt.show()

X_test_selected=select.transform(X_test)
lr=LogisticRegression()
lr.fit(X_train,y_train)
print('Score with all features:{:.3f}'.format(lr.score(X_test,y_test)))
lr.fit(X_train_selected,y_train)
print('Score with only selected features:{:.3f}'.format(lr.score(X_test_selected,y_test)))

2、基于模型的选择

用于特征选择的监督模型不需要与用于最终监督建模的模型相同,特征选择模型需要为每个特征提供某种重要性度量,以便用这个度量对特征进行排序。
决策树和基于决策树的模型提供了 feature_importances_ 属性,可以直接编码每个特征的重要性。线性模型系数的绝对值也可以用于表示特征重要性。


image.png
from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import SelectFromModel
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt

import numpy as np

cancer=load_breast_cancer()

rng=np.random.RandomState(42)
noise=rng.normal(size=(len(cancer.data),50))
X_w_noise=np.hstack([cancer.data,noise])

X_train,X_test,y_train,y_test=train_test_split(X_w_noise,cancer.target,random_state=0,test_size=.5)

select=SelectFromModel(
    RandomForestClassifier(n_estimators=100,random_state=42),
    threshold='median'
)
select.fit(X_train,y_train)
X_train_l1=select.transform(X_train)
print('X_train.shape:{}'.format(X_train.shape))
print('X_train_l1.shape:{}'.format(X_train_l1.shape))

mask=select.get_support()
plt.matshow(mask.reshape(1,-1),cmap='gray_r')
plt.xlabel('Sample index')
plt.show()

X_test_l1=select.transform(X_test)
score=LogisticRegression().fit(X_train_l1,y_train).score(X_test_l1,y_test)
print('Test score:{:.3f}'.format(score))

3、迭代特征选择

在迭代特征选择中,将会构建一系列模型,每个模型都使用不同数量的特征。

  • 开始时没有特征,然后逐个添加特征,直到满足某个终止条件
  • 从所有特征开始,然后逐个删除特征,直到满足某个终止条件。

递归特征消除(RFE):从所有特征开始构建模型,并根据模型舍弃最不重要的特征,然后使用除舍弃特征之外的所有特征来构建一个新模型,如此继续,指导剩下预设数量的特征。

from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import RFE
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt
import numpy as np

cancer=load_breast_cancer()

rng=np.random.RandomState(42)
noise=rng.normal(size=(len(cancer.data),50))
X_w_noise=np.hstack([cancer.data,noise])

X_train,X_test,y_train,y_test=train_test_split(X_w_noise,cancer.target,random_state=0,test_size=.5)

select=RFE(
    RandomForestClassifier(n_estimators=100,random_state=42),
    n_features_to_select=40
)
select.fit(X_train,y_train)
mask=select.get_support()
plt.matshow(mask.reshape(1,-1),cmap='gray_r')
plt.xlabel('Sample index')
plt.show()

X_train_rfe=select.transform(X_train)
X_test_rfe=select.transform(X_test)
score=LogisticRegression().fit(X_train_rfe,y_train).score(X_test_rfe,y_test)
print('Test score:{:.3f}'.format(score))
print('Test score:{:.3f}'.format(select.score(X_test,y_test)))

六、利用专家知识

1、使用 POSIX 时间特征和随机森林组合,效果不佳,其原因是测试集 POSIX 时间特征的值超出了训练集特征取值的范围。树以及随机森林无法外推到训练集之外的特征范围。
2、使用一天内的时间和一周的星期几
3、使用线性模型预测,我们用整数编码一周的星期几和一天内的时间,被解释为连续变量。因此需要使用 OneHotEncoder 编码,解释为分类变量,使用 PolynomialFeatures 进行特征组合,让模型为星期几和时刻的每一种组合学到一个系数。

对于选定的 Citi Bike 站点,自行车出租数量随时间的变化.png
随机森林仅使用 POSIX 时间做出的预测.png
随机森林使用每天的时刻做出的预测.png
随机森林使用一周的星期几和每天的时刻两个特征做出的预测.png
线性模型使用一周的星期几和每天的时刻两个特征做出的预测.png
线性模型使用 one-hot 编码过的一周的星期几和每天时刻两个特征做出的预测.png
线性模型使用星期几和时刻两个特征的乘积做出的预测.png
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import mglearn

citibike=mglearn.datasets.load_citibike()
print('Citi Bike data:\n{}'.format(citibike.head()))

# 可视化
plt.figure(figsize=(10,3))
xticks=pd.date_range(start=citibike.index.min(),end=citibike.index.max(),freq='D')
plt.xticks(xticks,xticks.strftime('%a %m-%d'),rotation=90,ha='left')
plt.plot(citibike,linewidth=1)
plt.xlabel('Date')
plt.ylabel('Rentals')
plt.show()

y=citibike.values
# X=citibike.index.strftime('%s').astype('int64').reshape(-1,1)
X = citibike.index.astype("int64").values.reshape(-1, 1) // 10**9


n_train=184

def eval_on_features(features,target,regressor):
    # 将给定特征划分为训练集和测试集
    X_train,X_test=features[:n_train],features[n_train:]
    y_train, y_test=target[:n_train],target[n_train:]
    regressor.fit(X_train,y_train)
    print('Test-set R^2:{:.2f}'.format(regressor.score(X_test,y_test)))
    y_pred=regressor.predict(X_test)
    y_pred_train=regressor.predict(X_train)
    plt.figure(figsize=(10,3))
    plt.xticks(range(0,len(X),8),xticks.strftime('%a %m-%d'),rotation=90,ha='left')
    plt.plot(range(n_train),y_train,label='train')
    plt.plot(range(n_train,len(y_test)+n_train),y_test,'-',label='test')
    plt.plot(range(n_train),y_pred_train,'--',label='prediction train')
    plt.plot(range(n_train,len(y_test)+n_train),y_pred,'--',label='prediction test')
    plt.legend(loc=(1.01,0))
    plt.xlabel('Date')
    plt.ylabel('Rentals')
    plt.show()

# 使用POSIX时间特征
regressor=RandomForestRegressor(n_estimators=100,random_state=0)
eval_on_features(X,y,regressor)

# 使用每天的时刻
X_hour=citibike.index.hour.values.reshape(-1,1)
eval_on_features(X_hour,y,regressor)

# 使用时刻+星期
X_hour_week=np.hstack([citibike.index.dayofweek.values.reshape(-1,1),
                       citibike.index.hour.values.reshape(-1, 1)])
eval_on_features(X_hour_week,y,regressor)

# 使用线性模型 整数编码一周的星期几和一天内的时间,它们被解释为连续变量
eval_on_features(X_hour_week,y,LinearRegression())

# 分类变量
enc=OneHotEncoder()
X_hour_week_onehot=enc.fit_transform(X_hour_week).toarray()
eval_on_features(X_hour_week_onehot,y,Ridge())

# 交互特征 星期几和时刻的每一种组合学到一个系数
poly_transformer=PolynomialFeatures(degree=2,interaction_only=True,include_bias=False)
X_hour_week_onehot_poly=poly_transformer.fit_transform(X_hour_week_onehot)
eval_on_features(X_hour_week_onehot_poly,y,Ridge())

相关文章

  • 数据表示和特征表示

    一、分类变量 1、One-Hot 编码(虚拟变量) value_counts:使用 pandas Series 的...

  • 多变量线性回归

    图中是包含多个房屋特征的训练数据,我们用 表示特征个数, 表示第 个 训练样本, 表示第 个训练样本的第 ...

  • NLP - 特征表示

    # 前言 前馈神经网络中,全连接层可以看做是从四维到六维的线性变换。实现了一个向量与矩阵的乘法. h=xW, 其中...

  • 核方法

    令 表示输入数据 的数据空间, 被称为输入空间 (input space). 是一个映射, 令 表示特征空...

  • pyecharts绘制地图

    导入库和数据,绘制基本地图 用颜色图例表示数据特征,连续型表示,max_表示图例展示的最大数值,如果比数值大,那么...

  • 特征表示—动态词典

    动态词典构造 在文本分类中,在处理流程上一般都大致会包括以下步骤:文本分词(含去停用词)建立测试集词列表与类别映射...

  • 3.1.1.1特征抽取

    3.1.1特征抽取 特征抽取,就是逐条将原始数据转化为特征向量的形式,这个过程同时涉及对数据特征的量化表示;而特征...

  • 机器学习 之 回归

    1. 线性回归 模型 y表示预测结果n表示特征的个数xi表示第 i 个特征的值θj表示第 j 个参数 h表示假设函...

  • 第一周 - Model and Cost Function

    模型表示 m:表示训练样本数量x:表示输入的特征,也被称为特征量y:表示输出变量,或目标变量(x,y):表示一个训...

  • 特征工程

    1. 介绍 特征工程是对原始数据进行一系列工程处理,将其提炼为特征,作为输入。是一个表示和展示数据的过程,特征工程...

网友评论

      本文标题:数据表示和特征表示

      本文链接:https://www.haomeiwen.com/subject/iiridqtx.html