机器学习基础|数据的降维及实战

数据的降维

数据的降维是数据预处理中至关重要的一部分。当拥有非常高纬度的数据集时,给数据降低纬度对于分析来说是非常重要的。

数据降维的概念

维度指的是特征的维度。数据的降维指的是要最大程度降低数据特征(剔除无用特征)的同时,尽可能多的保留原数据中包含的信息。简单的说降维指的是特征的数量减少

数据降维的意义

当我们拿到多特征的数据时,有一些字段的数据对于结果是没有意义,或者意义极小,但是在做机器学习的过程中也会参与计算,对我们最终分析结果造成不利影响,我们要根据实际情况,把数据进行降维,使得计算过程更轻便。

数据降维的方法

常用的数据降维方法有两种:

  • 特征选择
  • 主成分分析

特征选择

特征选择的概念

特征选择指的是在所有特征中选择部分特征作为训练集特征,选择后特征的值不改变,但是选择后的特征维数会降低。

特征选择的目的

当数据的特征较多时,特征量达到成百上千时,会极大的消耗计算性能。并且,有许多无用的特征,也会给计算带来一定的麻烦。
例如,给出一系列猫的数据,我们需要根据特征对猫进行分类,其中有‘是否有爪子’,‘爪子的长度’,‘眼睛的颜色’,‘毛的长度’四个特征。
在这里插入图片描述
但是很明显特征1和特征4是无用特征。因为所有的猫都有爪子,并且毛的长度相差不多,这时候就需要把这些无用特征剔除。

特征选择的方法

  • Filter(过滤式): VarianceThreshold
  • Embedde(嵌入式):正则化,决策树
  • Wrapper(包裹式)
  • 神经网络
Filter(过滤式): VarianceThreshold

Variance为方差,Threshold为阈值。顾名思义,过滤式特征选择是利用设定方差阈值的方式对特征进行提取。在设定的阈值方差范围内的(即认为无用的特征)特征被剔除,范围外的特征保留。举个例子:
下表中存在特征1和特征2。特征1中每个值都一样,也就说明该特征对最后的判断不会起到任何作用,因为都一样,就不算特征了,并且该列特征的方差为0。所以设定方差阈值为0则可将其筛掉。特征二中只有两个值和其他值不一样,也可认为特征用处不大(当然也有可能这两个特征值对判断结果起到决定性作用,那就不可剔除了),设定方法阈值将其剔除。
在这里插入图片描述
所以过滤式特征选择的核心就是:根据设定方差的大小剔除无用的特征,剩余的特征数据不改变。

Sklearn库特征选择API
sklearn.feature_selection.VarianceThreshold(threshold=0.0)#threshold为设定的方差阈值

举个例子,对以下四个特征进行特征选择
在这里插入图片描述
1、调库

from sklearn.feature_selection import VarianceThreshold 

2、特征选择函数

def var():
    var = VarianceThreshold(threshold=0.0) #这里设置的方差阈值为0
    data = var.fit_transform([[1,2,3,4],[1,3,4,4],[1,4,5,4]])
    print(data)
    return None

3、运行结果

if __name__=="__main__":
   var()

在这里插入图片描述
从上面的结果可以看出,因为设置的阈值方差为0,所以把特征1和特征4删除了。当然,可以继续加大方差阈值,那么可能就只剩下一个特征。在实际的处理过程中方差阈值在0-10之间一般都可以取,那到底有没有最好的值呢?没有,这需要根据实际情况来确定。

主成分分析(PCA)

PCA的概念

PCA是一种分析、简化数据集的技术,其核心在于数据维度压缩,尽可能降低原数据的维度,损失少量信息。 通过PCA可以实现削减回归分析或者聚类分析中特征的数量。
举个例子,用一个相机给三维物体拍照,拍成的照片就是二维的,即给物体进行了降维。但是降维有个要求,要求最大限度地能够体现出原物体的特征,例如下面四个图,都是三维物体的降维结果,但是图4更能反映出原物体的信息。故图4就是我们想要的降维结果。所以说用一个低维度表示高维度物体的时候,会发生一些信息丢失,而我们的目的就是在减少特征数量的同时尽可能减少信息的丢失。
在这里插入图片描述

PCA的原理

如果需要深入的了解PCA原理,需要了解一些向量积变换、方差和协方差矩阵等数学知识,感兴趣的可以去百度。这里通过一个简单事例进行说明。给出5个点,如下:

横坐标纵坐标
-1-2
-10
00
21
01

在坐标轴上的分布为:
在这里插入图片描述
要求:将二维的数据简化为一维。即将平面降维为一条直线。
那么降维的结果会有很多,例如将其降维到x轴上
在这里插入图片描述
降维之后原来的5个点就变成了3个点,从5个点变为3个点的过程中就出现了信息的丢失。同样的,如果降维后的结果在y轴上,依然会存在较大的信息丢失。而PCA需要的做的就是将丢失信息减到最小,例如下面的降维结果,就要比之前的降维效果要好。
在这里插入图片描述
说到底,PCA就是要找到上面那样的一条最优的红色线。PCA处理的过程中特征数量会减少,数据也会改变,会将丢失的信息降到最低。

PCA的适用场合

当特征数量较少时是不推荐使用PCA的,比如当特征数量只有十几个二十几个,那就没必要了。只有当特征数量达到上百上千时,才考虑对数据进行简化。图片的特征数量通常上千,此时就适合做主成分分析,再比如分析巨量数据时,如医学领域,金融市场领域。

PCA解决的主要问题

高维度的数据中,特征常常是相关的。
例如下表的特征1和特征2。在这里插入图片描述
我们可以发现特征1乘以2倍就是特征2,其变化趋势是相同的,那么我们就可以把两个特征当作一个特征来处理。在实际处理过程中,当数据中存在成百上千个特征时,必然会出现上面的情况,这时我们就可以用PCA进行降维。

Sklearn主成分分析API

sklearn.decomposition.PCA(n_components=None……) 

需要注意的是n_components有两种形式,可以是小数,也可以是整数。

  • 当n_components是小数时,为(0,1]之间的数,表示的是信息保留量,即降维后要保存多少数据。一般设置为90%-100%,保存原始数据的90%-100%。
  • 当n_components是整数时,表示减少到的特征数量。
  • 在PCA降维过程中,我们常设置n_components为小数,而不是设置为整数。
    举个例子
    对下列特征进行降维
    在这里插入图片描述

1、调库

from sklearn.decomposition import PCA

2、PCA函数

def pca():
    pca = PCA(n_components=0.95)#设置为保留原数据的95%
    data = pca.fit_transform([[2,5,1,7],[5,1,7,8],[9,4,2,1]])
    print(data)
    return None

3、结果

if __name__=="__main__":
   pca()

在这里插入图片描述
保存原数据95%的信息后,降成了2维。

Instacart Market Basket Analysis实战

问题背景

数据集源于kaggle中的一道竞赛题,我们利用其中的四个表格进行降维处理

  • products.csv:商品信息
    在这里插入图片描述

  • order_products_prior.csv:订单与商品信息
    在这里插入图片描述

  • orders.csv:用户的订单信息
    在这里插入图片描述

  • aisles.csv:商品所属具体物品类别
    在这里插入图片描述

要求:根据用户购买的物品类别,把用户进行分类。

问题分析

要求的终极目标是把user_id与aisle合在一起。但是
user_id和aisle是在两张不同的表上面的,所以我们首先要根据键值利用pandas将表进行合并。user_id在表orders.csv中,aisle在aisles.csv中,两个表没有共同的键值,故需要通过其他的表来进行合并。
通过分析我们发现order_products_prior.csv和products.csv有共同键值product_id,故先将其合并,合并后的表和orders.csv有共同键值order_id。三个表合并后的表和aisles.csv有共同键值aisle_id。由此,便将user_id和aisle放在了一张表上。

表的合并–pd.merge()

表的合并需要用到pd.merge

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
         left_index=False, right_index=False, sort=True,
         suffixes=('_x', '_y'), copy=True, indicator=False,
         validate=None)

  • left: 拼接的左侧DataFrame对象
  • right: 拼接的右侧DataFrame对象
  • on: 要加入的列或索引级别名称。 必须在左侧和右侧DataFrame对象中找到。 如果未传递且left_index和right_index为False,则DataFrame中的列的交集将被推断为连接键。
  • left_on:左侧DataFrame中的列或索引级别用作键。 可以是列名,索引级名称,也可以是长度等于DataFrame长度的数组。
  • right_on: 左侧DataFrame中的列或索引级别用作键。 可以是列名,索引级名称,也可以是长度等于DataFrame长度的数组。
  • left_index: 如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键。 对于具有MultiIndex(分层)的DataFrame,级别数必须与右侧DataFrame中的连接键数相匹配。
  • right_index: 与left_index功能相似。

读取四张表格

import pandas as pd
from sklearn.decomposition import PCA
prior = pd.read_csv("order_products__prior.csv")
aisles = pd.read_csv("aisles.csv")
orders = pd.read_csv("orders.csv")
products = pd.read_csv("products.csv")

合并第一张表后的结果

_mg = pd.merge(prior,products,on='product_id') #将prior表和products合在一起,键值为product_i

在这里插入图片描述
可以看到,根据product_id把两张表合并在了一起。
以此类推,可以合并第二张、第三张表,合并后的结果见下图
在这里插入图片描述
此时用户和物品就放在了一张表格上。

交叉表–pd.crosstab()

经过上面的处理,我们得到了总表,但是我们只注重用户买了哪些东西。所以我们需要得到一张用户和所买物品数目表。这就需要交叉表操作。
什么是交叉表,先举个例子。
例如下表,我们想到清晰的知道每个人所买商品的数量。即计算按姓名分组的商品频率。
在这里插入图片描述
通过交叉表处理后,便得到了下表。
在这里插入图片描述
这样,就可以清晰的展现出每个人所买的物品数目。
交叉表API为pd.crosstab() 其默认生成以行和列分类的频数表。

pd.crosstab(index,   #  分组依据
            columns,   # 列
            values=None,   # 聚合计算的值
            rownames=None,   # 列名称
            colnames=None,   # 行名称
            aggfunc=None,   # 聚合函数
            margins=False,   # 总计行/列
            dropna=True,   #  是否删除缺失值
            normalize=False    # 
           )

经过交叉表处理后,则可变为下表
在这里插入图片描述
上表中,行为用户id,列为所买商品数目。
根据所买商品数目就可以对用户进行划分,有的喜欢买食物、有的喜欢买电器等等。
上表中共有134个特征,但是我们仔细观察就会发现,有很多特征都是0,也就是我们所说的无用特征。所以接下来就进行PCA降维。

pca = PCA(n_components=0.9)
data = pca.fit_transform(cross)

降维结果:
在这里插入图片描述
查看降维后的特征

data.shape

(206209, 27)

降维结束后生于27个特征。

完整代码

import pandas as pd
from sklearn.decomposition import PCA
prior = pd.read_csv("order_products__prior.csv")
aisles = pd.read_csv("aisles.csv")
orders = pd.read_csv("orders.csv")
products = pd.read_csv("products.csv")
# 合并四张表
_mg = pd.merge(prior,products,on='product_id')
_mg1 = pd.merge(_mg,orders,on='order_id')
_mg2 = pd.merge(_mg1,aisles,on='aisle_id')
cross = pd.crosstab(_mg2['user_id'],_mg2['aisle'])
pca = PCA(n_components=0.9)
data = pca.fit_transform(cross)
  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值