PCA降维+SVR+数据可视化 实战记录

基于SVR算法对四姑娘山景区2019年下半年客流量进行预测

1.整理用机器学习进行回归分析的过程和原理(入门)10

回归分析过程

(1)选定训练模型,即为程序选定一个求解框架,如线性回归模型(Linear Regression)等。

(2)导入训练集,即给模型提供大量可供学习参考的正确数据。

(3)选择合适的学习算法,通过训练集中大量输入输出结果让程序不断优化输入数据与输出数据间的关联性,从而提升模型的预测准确度。

(4)在训练结束后即让模型预测结果,为程序提供一组新的输入数据,模型根据训练集的学习成果来预测这组输入对应的输出值。

回归分析原理

2.谈谈你眼里的机器学习是什么,怎样使用机器学习算法解决实际问题,可以结合例子。20

机器学习定义

  • 机器学习是一门将诸多理工科知识融合在一起,通过一定手段让机器模仿人类的学习行为,,最终达到机器能够分析问题,解决问题以及不断改善自身的性能的多领域交叉学科,作为对机器学习一无所知的小白,个人感觉机器学习包罗万象且学习门槛较高。

解决实际问题:

  • 垃圾邮件检测:根据邮箱中的邮件,识别哪些是垃圾邮件,哪些不是。

  • 信用卡欺诈检测:根据用户一个月内的信用卡交易,识别哪些交易是该用户操作的,哪些不是。帮助程序退还那些欺诈交易。

  • 数字识别:根据信封上手写的邮编,识别出每一个手写字符所代表的数字。

  • 语音识别:从一个用户的话语,确定用户提出的具体要求。帮助程序能够并尝试自动填充用户需求。

  • 人脸识别:根据相册中的众多数码照片,识别出那些包含某一个人的照片。

  • 产品推荐:根据一个用户的购物记录和冗长的收藏清单,识别出这其中哪些是该用户真正感兴趣,并且愿意购买的产品。

  • 医学分析:根据病人的症状和一个匿名的病人资料数据库,预测该病人可能患了什么病。

  • 股票交易:根据一支股票现有的和以往的价格波动,判断这支股票是该建仓、持仓还是减仓。

  • 客户细分:根据用户在试用期的的行为模式和所有用户过去的行为,识别出哪些用户会转变成该产品的付款用户,哪些不会。

  • 形状鉴定:根据用户在触摸屏幕上的手绘和一个已知的形状资料库,判断用户想描绘的形状。

3.整理SVR(支持向量机回归)的作用,基本思想和基本原理简单介绍。30

SVR的作用

支持向量回归模型(Support Vector Regression, SVR)是使用SVM来拟合曲线,做回归分析。支持向量机(SVM)本身是针对二分类问题提出的,而SVR(支持向量回归)是SVM(支持向量机)中的一个重要的应用分支。SVR回归与SVM分类的区别在于,SVR的样本点最终只有一类,它所寻求的最优超平面不是SVM那样使两类或多类样本点分的“最开”,而是使所有的样本点离着超平面的总偏差最小。

​ SVM是要使到超平面最近的样本点的“距离”最大;

​ SVR则是要使到超平面最远的样本点的“距离”最小。

SVM资料补充&&SVR思想及原理

补充:SVM

SVM是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,其学习策略便是间隔最大化,最终可转化为一个凸二次规划问题的求解。

对于下面一个数据集,有两类分别使用×和○来表示。那么想要找到一条曲线来区分这两类。可想而知,这样的曲线存在无数条,如何找到那一条最优的曲线呢?那就是要找到间隔(Gap)最大的那一条曲线,然后就可以根据这条曲线来分类了。而这条曲线称为超平面。图中加粗的×与○,则称这些向量为支持向量。

img

而实际上,很少会遇到上面的情况,能直接使用一条直线将数据分类,更多的时候,数据无法通过直线来分类。比如下面这种情况:

img

既然在二维上该数据无法使用线性分类,那么就将数据映射到更高维上,在高维上构造超平面,从而完成分类。

img

这就是为什么将上面的直线称为超平面。

所以对于非线性的模型,我们需要:

  1. 使用非线性映射将数据投影至特征空间;
  2. 在特征空间使用线性分类器;

看似很简单,但是在映射时,就会发现当变量增多时,映射到高维空间的维度是呈指数增长的,计算起来十分困难,这时候就需要核函数(kernel function)了。核函数也是将特征从低维到高维进行转换,但是它是先在低维上进行计算,实际的分类效果表现在高维上。这样就避免了在高维上复杂的计算,仍得到相同的结果。

一些常用的核函数:

  • 多项式核
  • 高斯核
  • 线性核

SVR是一种“宽容的回归模型,严格的线性回归是在向量空间里用线性函数去拟合样本。该模型以所有样本实际位置到该线性函数的综合距离为损失,通过最小化损失来求取线性函数的参数。对于线性回归而言,一个样本只要不算正好落在作为模型的线性函数上,就要被计算损失。而SVR在线性函数两侧制造了一个“间隔带”,对于所有落入到间隔带内的样本,都不计算损失;只有间隔带之外的,才计入损失函数。之后再通过最小化间隔带的宽度与总损失来最优化模型。

4.配置tensorflow环境,通过截图证明(pip)。 10

在这里插入图片描述

5.总结机器学习评估指标,包括简单介绍,计算公式(可以截图),使用场景等。10

1.准确率(accuracy)

  • 定义:正确分类的测试实例个数占测试实例总数的比例,用于衡量模型正确的预测新的或先前未见过的数据的类标号的能力。

  • 计算公式
    A c c u r a c y = ( T P + T N ) / ( T P + T N + F P + F N ) Accuracy = (TP+TN)/(TP+TN+FP+FN) Accuracy=(TP+TN)/(TP+TN+FP+FN)

2.误分率

  • 定义:错误分类的测试实例个数占测试实例总数的比例,表示分类器做出错误分类的概率有多大。

  • 计算公式
    E r r o r r a t e = 1 − A c c u r a c y = ( F N + F P ) / ( T P + T N + F P + F N ) Errorrate=1-Accuracy = (FN+FP)/(TP+TN+FP+FN) Errorrate=1Accuracy=(FN+FP)/(TP+TN+FP+FN)

3.精确率(precision)

  • 定义:正确分类的正例个数占分类为正例的实例个数的比例,也称查准率

  • 计算公式
    T P / ( T P + F P ) TP/(TP+FP) TP/(TP+FP)

4.召回率(recall)

  • 定义:正确分类的正例个数占实际正例个数的比例 也称查全率

  • 计算公式
    T P / ( T P + F N ) TP/(TP+FN) TP/(TP+FN)

5.F-值(F-Measure)

  • 定义:F-Measure是查全率与查准率加权调和平均,又称为F-Score

  • 计算公式

  • ( 1 ) F 1 = 2 P R / ( P + R ) = 2 T P / ( 2 T P + F P + F N ) ( 2 ) F − = ( α 2 + 1 ) P R / ( α 2 ) P + R ) (1)F1 = 2PR/(P+R)=2TP/(2TP+FP+FN) (2)F- = (α^2+1)PR/(α^2)P + R) 1F1=2PR/(P+R)=2TP/(2TP+FP+FN)2F=(α2+1)PR/(α2)P+R)

6.ROC曲线(Receiver Operating Characteristic)

  • 比如在逻辑回归里面,我们会设一个阈值,大于这个值的为正类,小于这个值为负类。如果我们减小这个阀值,那么更多的样本会被识别为正类。这会提高正类的识别率,但同时也会使得更多的负类被错误识别为正类。为了形象化这一变化,在此引入 ROC ,ROC 曲线可以用于评价一个分类器好坏。

  • ROC曲线是一个二维图形,横轴为FPR,纵轴为TPR,直观的展示FPR与TPR之间的对应关系。

    • (FPR=0,TPR=0)意味着将每一个实例都预测为负例

    • (FPR=1,TPR=1)意味着将每一个实例都预测为正例

    • (FPR=0,TPR=1)为最优分类器点

7.其他评估指标

  • 计算复杂度:决定着算法执行的速度和占用的资源,它依赖于具体的实现细节和软硬件环境。由于数据挖掘的操作对象是海量的数据库,因而空间和时间的复杂度将是非常重要的问题。
  • 速度:这涉及产生和使用模型的时间花费。
  • 可解释性:分类结果只有可解释性好,容易理解,才能更好地用于决策支持。
  • 可伸缩性:一个模型的可伸缩性,使之在给定内存和磁盘空间等可用的系统资源的前提下,算法的运行时间应当随数据库大小线性增加。
  • 稳定性:一个模型是稳定的,是指它没有随着它所针对数据的变换而过于剧烈变化。
  • 成本:这涉及预测错误代价所产生的计算花费。

6. 加分项:使用PCA对百度搜索指数进行降维,降低到三维并降维后的数据存到excel中。40

​ 为了提高统计模式识别的正确识别率,人们通常需要采集数量巨大的数据特征,使得原始空间或输入空间的维数可能高达几千维或万维。如果直接在输入空间上进行分类器训练,就可能带来两个棘手的问题:(1)很多在低维空间具有良好性能的分类算法在计算上变得不可行;(2)在训练样本容量一定的前提下,特征维数的增加将使得样本统计特性的估计变得更加困难,从而降低分类器的推广能力或泛化能力,呈现所谓的“过学习”或“过训练”的现象。要避免出现“过学习”的情况,用于统计分类器训练的训练样本个数必须随着维数的增长而呈指数增长,从而造成人们所说的“维数灾难”。这一问题可以通过降维来解决。因为高维数据中包含了大量的冗余并隐藏了重要关系的相关性,降维的目的就是消除冗余,减少被处理数据的数量,同时还能保持数据的特征完整性。PCA将数据投射到一个低维子空间实现降维。

#源代码
import pandas as pd
import numpy as np
import openpyxl
import xlwt

#读取表格数据,填充到矩阵作为数据集
def read_data(X):
    cnt=0
    worksheet = openpyxl.load_workbook('./第一次考核/原百度搜索指数.xlsx')
    sheet = worksheet.get_sheet_by_name('Sheet1')
    rows = sheet.max_row # 获取行数
    cols = sheet.max_column # 获取列数
    all_content = []
    #取表格中数据
    for i in range(2,rows+1) :
        for j in range (2,cols):
            X[i-2][j-2] = sheet.cell(row=i,column=j).value
            #print(X[i-2][j-2],end=' ')
            cnt=cnt+1
    #print(cnt)
    return X
    

class PCA(object):
    def __init__(self, X, K):

        self.X = X       #样本矩阵X
        self.K = K       #K阶降维矩阵的K值
        self.centrX = [] #矩阵X的中心化
        self.C = []      #样本集的协方差矩阵C
        self.U = []      #样本矩阵X的降维转换矩阵
        self.Z = []      #样本矩阵X的降维矩阵Z

        self.centrX = self._centralized()
        self.C = self._cov()
        self.U = self._U()
        self.Z = self._Z()   #Z=XU求得

    # 1.矩阵X的中心化
    def _centralized(self):
        '''矩阵X的中心化'''
        print('样本矩阵X:\n', self.X)
        centrX = []
        mean = np.array([np.mean(attr) for attr in self.X.T]) #样本集的特征均值
        #mean[np.isnan(mean)] = 1407.894806
        print('样本集的特征均值:\n',mean)
        centrX = self.X - mean ##样本集的中心化
        print('样本矩阵X的中心化centrX:\n', centrX)
        return centrX

    #2.求样本矩阵X的协方差矩阵C
    def _cov(self):
        #样本集的样例总数
        ns = np.shape(self.centrX)[0]
        #样本矩阵的协方差矩阵C
        C = np.matmul(self.centrX.T,self.centrX)/(ns-1)
        #C = C[np.logical_not(np.isnan(C))]
        print('样本矩阵X的协方差矩阵C:\n', C)
        return C
    
    #3.求协方差矩阵C的特征值、特征向量
    def _U(self):
        #先求X的协方差矩阵C的特征值和特征向量
        a,b = np.linalg.eig(self.C) #特征值赋值给a,对应特征向量赋值给b 
        print('样本集的协方差矩阵C的特征值:\n', a)
        print('样本集的协方差矩阵C的特征向量:\n', b)

        #给出特征值降序的topK的索引序列
        ind = np.argsort(-1*a)

        #4.构建K阶降维的降维转换矩阵U
        UT = [b[:,ind[i]] for i in range(self.K)]   #获取最大的k个值的
        U = np.transpose(UT)    #构成一维转换矩阵
        print('%d阶降维转换矩阵U:\n'%self.K, U)
        return U
    
    #5.通过低阶转换矩阵,把原矩阵转换成低维矩阵
    def _Z(self):
        Z = np.dot(self.X, self.U)    #计算X和转换矩阵的乘积,得到降维后的矩阵
        print('样本矩阵X的降维矩阵Z:\n', Z)
        print('原矩阵的维度:', np.shape(X))
        print('降维后的维度:', np.shape(Z))
        np.savetxt('./第一次考核/PCA_百度搜索指数.csv', Z, delimiter = ',')
        return Z



if __name__=='__main__':
    #读取xlsx的数据
    X=np.zeros([1523,13])     #创建一个1523*13的0矩阵
    dataset=read_data(X)   #读取表格中的数据,放到矩阵中 

    # #降维
    K = 3   #降维,k为得到结果的维度
    pca = PCA(X,K)     #调用PCA主函数
   

原表格是152415,第一行和第一列均不提取,所以是1523 * 14 的矩阵,压缩到三维后是15233,下面是运行截图,原表格和降维后表格的部分截图

运行截图:

在这里插入图片描述

原表格:

在这里插入图片描述

降维后表格:
在这里插入图片描述

7~11 SVR实战环节

利用train_test_split方法,将X,y随机划分问,训练集(X_train),训练集标签(X_test),测试卷(y_train),测试集标签(y_test),安训练集:测试集=7:3的概率划分,到此步骤,可以直接对数据进行处理,最终,用PCA降维后数据集进行训练得到结果如图:
在这里插入图片描述

用原数据集训练得到结果如图:

在这里插入图片描述

由图知:经过主成分分析后,拟合优度远远达不到要求,所以采用原数据集进行训练,且得出模型评分:高斯> 多项式>线性>sigmoid

所以,核函数选择高斯核函数

绘出并保存图像:

SVR预测值与真实值对比:

在这里插入图片描述

源码实现:

# 导入库
from sklearn.datasets import load_boston
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error,mean_squared_error,explained_variance_score,r2_score
from sklearn.svm import LinearSVR
from sklearn import metrics
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVR
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

#读取.CSV文件成矩阵的形式
my_matrix = np.loadtxt(open("./第一次考核/原百度搜索指数.csv"),delimiter=",",skiprows=0)
#对于矩阵而言,将矩阵倒数第一列之前的数值给了XPCA_(输入数据),将矩阵大最后一列的数值给了y(标签)
X, y = my_matrix[:,:-1],my_matrix[:,-1]
#利用train_test_split方法,将X,y随机划分问,训练集(X_train),训练集标签(X_test),测试卷(y_train),
#测试集标签(y_test),安训练集:测试集=7:3的
#概率划分,到此步骤,可以直接对数据进行处理
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=0.4)

#np.column_stack将两个矩阵进行组合连接
train= np.column_stack((X_train,y_train))
test = np.column_stack((X_test, y_test))

#数据预处理
Stand_X = StandardScaler()  # 特征进行标准化
Stand_Y = StandardScaler()  # 标签也是数值,也需要进行标准化
X_train = Stand_X.fit_transform(X_train)
X_test = Stand_X.transform(X_test)
y_train = Stand_Y.fit_transform(y_train.reshape(-1,1)) # reshape(-1,1)指将它转化为1列,行自动确定
y_test = Stand_Y.transform(y_test.reshape(-1,1)) 
 
# ① 线性核函数
clf = LinearSVR(C=2)
clf.fit(X_train,y_train)
y_pred = clf.predict(X_test)
print("线性核函数:")
print("训练集评分:", clf.score(X_train,y_train))
print("测试集评分:", clf.score(X_test,y_test))
print("测试集均方差:",metrics.mean_squared_error(y_test,y_pred.reshape(-1,1)))
print("测试集R2分:",metrics.r2_score(y_test,y_pred.reshape(-1,1)))

# ② 高斯核函数
clf = SVR(kernel='rbf',C=8,gamma=0.05)
clf.fit(X_train,y_train)
y_pred = clf.predict(X_test)
print("高斯核函数:")
print("训练集评分:", clf.score(X_train,y_train))
print("测试集评分:", clf.score(X_test,y_test))
print("测试集均方差:",metrics.mean_squared_error(y_test,y_pred.reshape(-1,1)))
print("测试集R2分:",metrics.r2_score(y_test,y_pred.reshape(-1,1)))

# ③ sigmoid核函数
clf = SVR(kernel='sigmoid',C=2)
clf.fit(X_train,y_train)
y_pred = clf.predict(X_test)
print("sigmoid核函数:")
print("训练集评分:", clf.score(X_train,y_train))
print("测试集评分:", clf.score(X_test,y_test))
print("测试集均方差:",metrics.mean_squared_error(y_test,y_pred.reshape(-1,1)))
print("测试集R2分:",metrics.r2_score(y_test,y_pred.reshape(-1,1)))

# ④ 多项式核函数
clf = SVR(kernel='poly',C=2)
clf.fit(X_train,y_train)
y_pred = clf.predict(X_test)
print("多项式核函数:")
print("训练集评分:", clf.score(X_train,y_train))
print("测试集评分:", clf.score(X_test,y_test))
print("测试集均方差:",metrics.mean_squared_error(y_test,y_pred.reshape(-1,1)))
print("测试集R2分:",metrics.r2_score(y_test,y_pred.reshape(-1,1)))


#结果可视化
plt.figure(figsize=(30, 5))

# 这两行代码使得 pyplot 画出的图形中可以显示中文与负值
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

#画曲线
plt.plot(np.arange(len(y_pred)), y_test,'-',linewidth=0.5,color='g',label='true value')
plt.plot(np.arange(len(y_pred)),y_pred,'-',linewidth=0.5,color='r',label='predict value')
plt.title('SVR预测值与真实值对比')
plt.xlabel('日期')
plt.ylabel('客流量(千人)')

# 将样例显示出来
plt.legend(loc='best')     

#保存图片,一定在show之前保存
plt.savefig('.\第一次考核\SVR.png')
plt.show()

12. 总结对于数据分析的意义重大,总结学习笔记与实验记录(无论成功与否),以备后期回顾。30分

以上为全部学习笔记,总结一下,本次实战,总体上讲还是比较成功的,学到了许多以前闻所未闻的知识,也掌握了一些分析问题的思路,最终拟合优度达到0.759,也绘制出了SVR前后的图像,基本完成了任务,实践中的两点给我的印象比较深:

​ 第一,在作PCA降维时发现不管用什么方法,样本矩阵计算后均会得到一行一列的Nan,这令我非常不解,我用了六个小时仔细排查了方方面面,最后发现是原本数据集中的两个数据本身就是缺失的,我觉得这是非常重要的经验,能够帮助我以后能够更快发现问题,解决问题。

​ 第二,在SVR预测的过程中,我发现用PCA数据集与原数据集训练得到结果的拟合优度有非常明显的差距,但是,就我目前的水平而言,我只能套着主成分分析的模板走,所以无法分析具体是那一步出现了问题,希望以后有时间,还能继续深入思考这个问题,并将之解决。

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

血月无华AUV

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值