降维中的主成分分析(PCA)

降维

在建模过程中,如果特征矩阵的维度过大,计算量也相应会很大,这有可能导致训练时间过长,降维的目的就是在尽量不影响模型效果的前提下,压缩特征的维度,从而解决模型训练时间过长的问题。

目前主要的降维算法是主成分分析(PCA)和因子分析(FA)

主成分分析

世上的大多数事物都有非常多的特征,我们在评价某种事物的时候,仅依据某一特征进行评价,难免有失偏颇,主成分分析,就是一种从所有样本中选出综合实力最强样本的分析方法。

示例数据:
在这里插入图片描述
如何判断哪部电影是最优的呢?使用哪个指标呢?无论使用哪个,都有失偏颇,这时就可以使用主成分分析。

先画出散点图:

import pandas as pd 
import matplotlib.pyplot as plt
from pylab import mpl
data = pd.read_csv('D:\example_csv\movie.csv',encoding = 'gbk')
#确定坐标轴
plt.rcParams['font.sans-serif']=['SimHei'] #防止中文乱码
mpl.rcParams['axes.unicode_minus'] = False #防止负号乱码
fig = plt.figure()
plt.xlabel('累计票房')
plt.ylabel('豆瓣评分')
plt.xlim([0,data['累计票房'].max()*1.5])
plt.ylim([0,data['豆瓣评分'].max()*1.5])
#画散点图
plt.scatter(
    data['累计票房'],data['豆瓣评分'],s = 50,marker = 'o',
    color = 'blue',linewidth = 5)

data.apply(
    lambda row:plt.text(
        row.累计票房,row.豆瓣评分,
        row.电影名称,fontsize = 15),axis = 1
)

执行代码:
在这里插入图片描述
从散点图可以看出,《回到远古时代》虽然票房少,但是评分非常高,《无敌小金刚》虽然票房高,但是评分不高。

对所有特征进行Z-Score标准化:

from sklearn.preprocessing import scale
data['标准化累计票房'] = scale(data['累计票房'])
data['标准化豆瓣评分'] = scale(data['豆瓣评分'])

执行代码,标准化数据如下:
在这里插入图片描述
画出标准化后的散点图:

fig = plt.figure()
plt.xlabel('标准化累计票房')
plt.ylabel('标准化豆瓣评分')
plt.xlim([data['标准化累计票房'].min()*1.3,data['标准化累计票房'].max()*1.5])
plt.ylim([data['标准化豆瓣评分'].min()*1.3,data['标准化豆瓣评分'].max()*1.5])
plt.scatter(
    data['标准化累计票房'],data['标准化豆瓣评分'],s = 50,
    marker = 'o',color = 'blue',linewidth = 5)

data.apply(
    lambda row:plt.text(
        row.标准化累计票房,row.标准化豆瓣评分,
        row.电影名称,fontsize = 15),axis = 1
)

执行代码:
在这里插入图片描述

画出x = y的直线:

plt.plot(np.arange(-5,5),
         np.arange(-5,5),
         color = 'red',linewidth = 5)

执行代码:
在这里插入图片描述

求解每个点在 x = y 这条直线的投影:
根据点到直线的投影公式:
x = b ( b x 0 − a y 0 ) − a c a 2 + b 2 x =\frac{b(bx_0 - ay_0) - ac}{a^2 +b^2} x=a2+b2b(bx0ay0)ac
y = a ( − b x 0 + a y 0 ) − b c a 2 + b 2 y =\frac{a(-bx_0 + ay_0) - bc}{a^2 +b^2} y=a2+b2a(bx0+ay0)bc

可以知道,每个点到y = x 这条直线的投影坐标为: ( x + y 2 , x + y 2 ) (\frac{x + y}{2},\frac{x + y}{2}) (2x+y,2x+y)

绘图代码如下:

def verticalpoints(x,y):
    x0 = (x+y)/2
    y0 = (x+y)/2
    plt.scatter(
        x0,y0,alpha = 0.5,
        s= 200,marker = 'o')
    plt.plot([x,x0],[y,y0])
data.apply(
        lambda row:verticalpoints(
        row.标准化累计票房,row.标准化豆瓣评分),axis = 1
)

执行代码,即可得到每个点到直线的投影:
在这里插入图片描述

最后,我们根据每部电影在y = x 直线上的投影,就可以得到该部电影的综合评价。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值