降维
在建模过程中,如果特征矩阵的维度过大,计算量也相应会很大,这有可能导致训练时间过长,降维的目的就是在尽量不影响模型效果的前提下,压缩特征的维度,从而解决模型训练时间过长的问题。
目前主要的降维算法是主成分分析(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(bx0−ay0)−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 直线上的投影,就可以得到该部电影的综合评价。