精华内容
下载资源
问答
  • 案例1主题: 主成分分析及学生成绩神秘联系分析 案例2主题: 因子分析及学生成绩神秘联系分析 案例一:目的与内容 学生的考试是评估学生的学习程度及能力,当我们只想知道学生的学习程度如何时,可借由一份良好的...

    案例1主题: 主成分分析及学生成绩神秘联系分析

    案例2主题: 因子分析及学生成绩神秘联系分析

    案例一:目的与内容
    学生的考试是评估学生的学习程度及能力,当我们只想知道学生的学习程度如何时,可借由一份良好的试卷来测验出学生的学习程度分布状况。可是怎样才是一份良好的试卷呢?当然是学习程度好的学生所考的成绩较高,而学习程度差的学生成绩较低,亦即试卷能真正反映出学生学习程度差异的真实分布情况。想作一个总体性学习状况比较时,便可以用主成分分析来找出主成分,本文中的学生神秘成绩联系主成分分析是由六科成绩线性组合而成的新变量,可以帮助我们看出学生的六科科学习成绩状况的综合指标,老师可以根据这来发现学生成绩的变化,及时有效发现学习的问题,帮助学生提高成绩,促进教学相长。老师是人类的灵魂工程师。少年强则国强,所以这内容是极具意义的。

    案例二:目的与内容
    因子分析是主成分分析的推广,也是一种把多个变量化为少数几个综合变量的多变量分析方法,其目的是用有限个不可观测的变量来解释原始变量之间的相关性关系。
    因子分析的主要用途在于:1 减少分析变量个数;2 通过对变量间相关关系的探测,将原始变量进行分类。即将相关性高的变量分为一组,用共性因子代替该组变量。在本文中,将用因子分析来帮助学生成绩这几门科目的相关性是否真的有可能由文科和理科来刻画。
    三、主成分分析上机步骤与上机结果
    数据准备
    在这里插入图片描述
    数据包含52名学生6个学科的成绩

    案例一主成分分析

    样本主成分分析实现过程

    (1)将原始数据标准化,以消除变量间在数量级和量纲的不同。
    (2)求标准化数据的相关矩阵。(ps:存放数据test_score文件的路径各有不同,所以要先用setwd(“文件路径”)设置好路径)
    在这里插入图片描述在这里插入图片描述(3)求相关矩阵的特征值和特征向量
    在这里插入图片描述 (4)计算方差贡献率和累积方差贡献率
    在这里插入图片描述Standard deviation:方差 comp.1到comp.6对应的方差就是它们的信息量 即是我们 所说的特征值,对应的标准差就是方差开平方

    Proportion of Variance: 方差的占比

    Cumulative Proportion 累积方差贡献率

    (5)确定主成分
    如上图,用两个主成分,累积的方差贡献率就变成了82.87左右,我们认为已经是一个比较高的数值
    所以我们这就采用前两个主成分就可以了
    在综合指标只要选取前两个这里插入图片描述综合指标只要选取前两个

    (6)用原指标的线性组合来计算各成分得分
    在这里插入图片描述(Ps:数据中的六科Y1、Y2、Y3、Y4、Y5、Y6分别是数学、物理、化学、语文、历史、英语)在这里插入图片描述 z1可以理解为文科的平均情况减去理科的平均情况,数值越大说明文科的成绩越好,数值越小,反之理科越好,z1刻画的是一个偏科的情况
    z2是一种相对均衡的情况,类似我们通用所使用的平均分,称为均衡表现

    四、讨论分析
    进一步探索一些典型学生的样本主成分取值/得分
    在这里插入图片描述下面行依次是6、7、45、30、49、26、33、8号同学成绩的情况
    在这里插入图片描述红色框:可以看到是一个挺大的数据,上面可以说是文科减理科的情况,越大说明是文科越好,越小说明理科越好,所以6,7,45号学生应该是;理科成绩比文科好,看一下原始数据,确实是这样
    原始数据蓝色框:同样如此,应该是文科比理科好很多,原始数据如下
    在这里插入图片描述
    绿色框:从第二个主成分指标看,是一个负数,因为第二个主成分前面都是负号,所以它越小越负,说明本身成绩应该是挺高的,均衡成绩应该是挺高的,看一下原始数据
    在这里插入图片描述
    黄色框:可以看到是一个很大的整数,那么他的总成绩本身真的不高在这里插入图片描述
    碎石图

    在这里插入图片描述
    另外一种方法选取多少个主成分比较合适
    主成分总结

    数据降维
    通常我们会用少于原始变量数的主成分来描述尽可能多的数据差异,特别是当原始变量维度很高时,可以达到将维目的。

    构建综合指标
    主成分分析主要用于构建综合指标来区分目标群体,例如构建顾客各种消费行为的综合指标进行客户分级

    四、因子分析上机步骤与上机结果
    查看相关系数矩阵
    在这里插入图片描述
    猜想:大体上前面三个好像更相关一点,后三个更相关一点。所以暂时将因子模型定位下面这个样子
    在这里插入图片描述
    用极大似然法来估计载荷矩阵:
    在这里插入图片描述
    factanal是Factor analysis的意思,factors保留两个公共因子,如下图可以看到累积的方差贡献率是0.745
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200526093910459.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pjamlj,size_16,color_FFFFFF,t_70

    通过自定义程序包尝试主成分法:
    在这里插入图片描述
    可以看到累积方差达到了82.87,是比用极大似然法估计来得好的,也许极大似然法是基于分布的,分布并不是那么得正态,所以后续倾向于主成分法来讨论分析。主成分法如果没有经过旋转,它的载荷矩阵是这个样子(如下图)。
    在这里插入图片描述
    可以看出解释并不是那么明显,不知道每个因子到底是什么意思,所以使用旋转因子的方法
    计算旋转因子载荷:
    在这里插入图片描述

    可以看到经过旋转,累积方差贡献率没什么变化,但是两个因子它的载荷变了很多,可以看到第一个公共因子它基本主要决定Y4,Y5,Y6,第二个公共因子主要在决定前三个,剩下的值都很少,我们可以忽略掉,这个就告诉我们一种比较简便的方法
    解释第一个和第二个因子,第一个找后三个变量的共同点,分别是语文,英语,历史的,是文科,第二个分别是数理化,理科。
    在这里插入图片描述

    旋转过后的因子空间里面,两个坐标轴都经过很多的点,都是靠近坐标轴。
    因子旋转的作用
    经过旋转以后,因子的意义更加清晰
    在这里插入图片描述
    所以我们基本上是可以通过我们的相关性和因子分析,把我们的变量分成两类,一类是语文,历史,英语,是文科(一定程度上),一类是数学,物理和化学,是理科。通过这个案例可以得出这样将科目分为文科,理科是合理的,通过它的相关性,通过学生在这些科目当中的表现。

    计算样本因子得分
    在这里插入图片描述
    可以看出有些同学文科好,有些理科好,有的都挺好,有的都挺差
    画图展示
    在这里插入图片描述

    第一个横轴就是文科,对应的是第一个公共因子,第二轴是y轴,是理科因子
    如上图,我们可以分析出一些学霸,学渣的结论,偏科情况
    五、主成分分析与因子分析综合对比讨论分析

    在这里插入图片描述

    展开全文
  • 分析YOLOv3目标检测

    千次阅读 2020-11-18 07:26:30
    YOLOv3最大的变化包括两点:使用残差模型采用FPN架构。YOLO2曾采用passthrough结构来检测细粒度特征,在YOLO3更进一步采用了3个不同尺度的特征图来进行对象检测。 YOLOv3 的先验检测(Prior detection)系统将...

    前言

    YOLOv3模型比之前的模型复杂了,但是精度也提高了。YOLOv3最大的变化包括两点:使用残差模型和采用FPN架构。YOLO2曾采用passthrough结构来检测细粒度特征,在YOLO3更进一步采用了3个不同尺度的特征图来进行对象检测。

    YOLOv3 的先验检测(Prior detection)系统将分类器或定位器重新用于执行检测任务;将模型应用于图像的多个位置和尺度。

    论文标题: YOLOv3: An Incremental Improvement

    论文作者: Joseph Redmon Ali Farhadi

    论文地址:https://arxiv.org/abs/1804.02767

     

     

    改进之处

    • 多尺度预测 

    • 更好的基础分类网络(类ResNet)和分类器 DarkNet-53

    • 分类器-类别预测

    关键点:3个尺度的特征图、能检测不同尺度的输入图像、快速高效的检测方式。

     

    目录

    网络结构

    特点:

    网络结构剖析:

    特征图

    先验框

    置信度和类别解码

    训练策略

    损失函数

    实验结果

    优点

    总结


    网络结构

    YOLOv3的特征提取器是一个残差模型,因为包含53个卷积层,所以称为Darknet-53,从网络结构上看,相比Darknet-19网络使用了残差单元,在一些层之间设置了快捷链路(shortcut connections),所以可以构建得更深。另外一个点是采用FPN架构(Feature Pyramid Networks for Object Detection)来实现多尺度检测。

    DarkNet-53:

    特点:

    • 只有卷积层:通过调节卷积步长控制输出特征图的尺寸。所以对于输入图片尺寸没有特别限制。
    • 金字塔特征图:小尺寸特征图用于检测大尺寸物体,而大尺寸特征图检测小尺寸物体。
    • 借鉴 ResNet:将输入的特征图,与输出特征图对应维度进行相加。
    • 借鉴 DenseNet:将特征图按照通道维度直接进行拼接。

     

    网络结构剖析:

    YOLOv3采用了3个尺度的特征图(当输入为416 x 416时):(13 x 13), (26 x 26),(52 x 52) ,VOC数据集上的YOLOv3网络结构下图所示,其中红色部分为各个尺度特征图的检测结果。YOLOv3每个位置使用3个先验框,所以使用k-means得到9个先验框,并将其划分到3个尺度特征图上,尺度更大的特征图使用更小的先验框,和SSD类似

    YOLOv3使用的聚类方法还是K-Means,它能用来确定边界框的先验。选择了9个聚类和3个尺寸,然后在不同尺寸的边界框上均匀分割维度聚类。在COCO数据集上,这9个聚类分别是:(10×13)、(16×30)、(33×23)、(30×61)、(62×45)、(59×119)、(116 × 90)、(156 × 198)、(373 × 326)。

     

    Darknet-53处理速度每秒78张图,比 Darknet-19慢不少,但是比同精度的ResNet快很多。 Yolo3依然保持了高性能。

    精度和速度中做取舍,选择了精度不错的。

     

    特征图

    • 根据不同的输入尺寸,会得到不同大小的输出特征图。
    • 每个特征图的每个格子中,都配置3个不同的先验框,所以最后三个特征图,这里暂且 reshape为8×8x3×85、16×16×3。
    • 检测框位置(4维)、检测置信度(1维)、类别(80维)都在其中,加起来正好是85维。

     

    先验框

    Yolo v3沿用了 Yolo2中关于先验框的技巧,并且使用k- means对数据集中的标签框进行聚类,得到类别中心点的9个框,作为先验框。

    有了先验框与输出特征图,就可以解码检测框 x , y, w , h 

     

    带有维度先验和定位预测的边界框。我们边界框的宽和高以作为离聚类中心的位移,并使用 Sigmoid 函数预测边界框相对于滤波器应用位置的中心坐标。

    仍采用之前的logis,其中cx,cy是网格的坐标偏移量,pw,ph是预设的anchor box的边长.最终得到的边框坐标值是b*,而网络学习目标是t*,用sigmod函数、指数转换。

     

    置信度和类别解码

    置信度在输出85维中占固定一位,由 sigmoid函数解码即可,解码之后数值区间在【0,1】

    COCO数据集有80个类别,所以类别数在85维输出中占了80维,每一维独立代表一个类别的置信度。使用 sigmoid激活函数替代了YOLOv2中的 softmax,取消了类别之间的互斥,可以使网络更加灵活。

    sigmoid输出的值之和不必等于1 ; softmax输出的值之和等于1(有互斥)

    YOLOv3不使用Softmax对每个框进行分类,主要考虑因素有两个:

    1. Softmax使得每个框分配一个类别(score最大的一个),而对于Open Images这种数据集,目标可能有重叠的类别标签,因此Softmax不适用于多标签分类。

    2. Softmax可被独立的多个logistic分类器替代,且准确率不会下降。

    分类损失采用binary cross-entropy loss。

     

    三个特征图一共可以解码出8×8×3+16×16×3+32×32×3=4032个box以及相应的类别、置信度。这4032个box,在训练和推理时,使用方法不一样:
       训练时4032个box全部送入打标签函数,进行后一步的标签以及损失函数的计算。
       推理时,选取一个置信度阈值,过滤掉低阈值boⅹ,再经过nms(非极大值抑制),就可以输出整个网络的预测结果了。

     

    训练策略

    预测框:正例( positive)、负例( negative)、忽略样例( Ignore)

      正例:取一个 ground truth,与4032个框全部计算IoU,最大的为正例。正例产生置信度loss、检测框loss、类别loss. ground truth box为对应的预测框的标签

      负例:与全部 ground truth的IoU都小于阈值(0.5),则为负例。负例只有置信度产生loss,置信度标签为0。

      忽略样例:正例除外,与任意一个 ground truth的IOU大于阈值(论文中使用0.5),则为忽略样例。忽略样例不产生任何loss。

     

     

    损失函数

    x、y、w、h 使用MSE作为损失函数。

     

    实验结果

    在性能相当的情况下,YOLOv3的运行速度明显快于其他(RetinaNet-50、RetinaNet-101)检测方法。

     

    YOLOv3比SSD模型要好得多,在AP50指标上可以与最先进的模型相媲美:

     

    YOLOv3目标检测效果:

     

    优点

    • 快速,pipline简单.

    • 背景误检率低。

    • 通用性强。YOLO对于艺术类作品中的物体检测同样适用。它对非自然图像物体的检测率远远高于DPM和RCNN系列检测方法。

     

    总结

    YOLOv3是一个好的检测器,在当时它速度快,精度又高。虽然基于.3和.95的新指标,它在COCO上的成绩不如人意,但对于旧的检测指标.5 IOU,它还是非常不错的。

     

    • 考虑到检测物体的重叠情况,用多标签的方式替代了之前softmax单标签方式
    • 骨干架构使用了更为有效的残差网络,网络深度也更深;
    • 多尺度特征使用的是FPN的思想;
    • 锚点聚类成了9类

     

    9种尺度的先验框 https://blog.csdn.net/dexterod/article/details/104582362

    参考1:YOLO官网  https://pjreddie.com/darknet/yolo/

    参考2:https://www.cnblogs.com/cecilia-2019/p/11570943.html

     

    YOLO物体/目标检测  https://blog.csdn.net/qq_41204464/category_10425913.html?spm=1001.2101.3001.4235

     

     

     

     

    展开全文
  • 基于Spark的学生成绩分析系统

    千次阅读 2018-07-02 17:33:00
    本文是本人硕士期间云计算课程的一次大...但是也正因为此,本文一些基础概念描述的也挺详细,包括但不限于Spark简介、Spark与Hadoop对比、Spark架构介绍、Pearson相关系数简介、Spark中的combineByKey函数简介等。

    本文首发于我的个人博客QIMING.INFO,转载请带上链接及署名。

    本文是本人硕士期间云计算课程的一次大作业,所以可能部分内容有充字数的嫌疑,还望各位看官无视。。。但是也正因为此,本文对一些基础概念描述的也挺详细,包括但不限于Spark简介、Spark与Hadoop对比、Spark架构介绍、Pearson相关系数简介、Spark中的combineByKey函数简介、Spark中提交并运行作业的方法等。

    问题说明

    提出问题及目标

    学生成绩是评价学生学习效果和老师教学效果的重要指标,如何充分利用已有的学生成绩数据,发现其中的规律,提高教学质量是广大教育工作者普遍关注的问题。

    一般而言,学生各科成绩之间或多或少都存在联系,例如一个学习好的学生各科成绩普遍都比较高。研究者们对此进行了大量的数据采集、统计工作,从他们的研究结果来看,学生各科成绩之间的确存在一定的相关性,只是不同课程之间相关性的强弱不同而已。

    通过对学生成绩进行统计分析,可以发现学生成绩中隐藏的课程关联规则和模式,这些知识可以帮助老师更加合理地安排教学内容,从而对教学起到促进作用。

    现有西工大某学院2006级至2015级学生的全部成绩,我们想利用这些数据统计出:①各学科的整体情况;②各课程之间的相关性

    目标细化及难点

    经过讨论,我们决定用每个年级的各科平均成绩来反映该学科的整体情况,并分年级计算各个课程之间的Pearson相关系数以反映各课程间的相关性。并最后将分析的结果保存在HDFS上。

    要做到这些工作,我们需要解决以下难点:
    ① 2006至2015学生人数众多,且课程种类多,为分析带来了极大困难
    ② 用单机运行处理大量数据需要大量的时间
    所以我们便考虑使用分布式计算引擎Spark来克服这些难点。

    背景

    Spark简介

    Spark是专为大规模数据处理而设计的快速通用的计算引擎,最初在2009年由加州大学伯克利分校的AMP实验室用Scala语言开发,并于2010年成为Apache的开源项目。

    Spark是基于MapReduce算法实现的分布式计算,拥有Hadoop MapReduce所具有的优点;但不同于MapReduce的是中间过程的输出和结果可以保存在内存中,从而不再需要读写HDFS,大大提高了速度。

    Spark和Hadoop的关系图如下:

    官方资料介绍,和Hadoop相比,Spark可以让你的程序在内存中运行时速度提升100倍,就算在硬盘上,运行速度也能提升10倍。

    Spark架构

    Spark的架构示意图如下:

    如图可见,Spark主要有以下模块:
    ① Spark Core:包含Spark的基本功能;尤其是定义RDD的API、操作以及这两者上的动作。其他Spark的库都是构建在RDD和Spark Core之上的。
    ② Spark SQL:提供通过Apache Hive的SQL变体Hive查询语言(HiveQL)与Spark进行交互的API。每个数据库表被当做一个RDD,Spark SQL查询被转换为Spark操作。
    ③ Spark Streaming:对实时数据流进行处理和控制。Spark Streaming允许程序能够像普通RDD一样处理实时数据
    ④ MLlib:一个常用机器学习算法库,算法被实现为对RDD的Spark操作。这个库包含可扩展的学习算法,比如分类、回归等需要对大量数据集进行迭代的操作。
    ⑤ GraphX:控制图、并行图操作和计算的一组算法和工具的集合。GraphX扩展了RDD API,包含控制图、创建子图、访问路径上所有顶点的操作。

    Spark RDD简介

    RDD(Resilient Distributed Dataset)即弹性分布式数据集。

    RDD是Spark的核心,在Spark中,对数据的所有操作不外乎创建RDD、转化已有RDD以及调用RDD操作进行求值。每个RDD都被分为多个分区,这些分区运行在集群中的不同节点上。RDD可以包含Python、Java、Scala中任意类型的对象,甚至可以包含用户自定义的对象。

    RDD是Spark中的抽象数据结构类型,任何数据在Spark中都被表示为RDD。从编程的角度来看,RDD可以简单看成是一个数组。和普通数组的区别是,RDD中的数据是分区存储的,这样不同分区的数据就可以分布在不同的机器上,同时可以被并行处理。因此,Spark应用程序所做的无非是把需要处理的数据转换为RDD,然后对RDD进行一系列的变换和操作从而得到结果。

    更多内容可参考本站的这篇文章Spark RDD的简单使用

    Pearson相关系数简介

    Pearson相关系数 (Pearson Correlation Coefficient)是用来衡量两个数据集合是否在一条线上面,它用来衡量定距变量间的线性关系。Pearson是一个介于-1和1之间的值,用来描述两组线性的数据一同变化移动的趋势。

    Pearson系数的计算公式如下:

    注:Cov(X,Y)表示X和Y的协方差,E(X ) 表示X的平均值。

    Pearson 相关系数大小的含义如下表所示:

    相关性 负相关 正相关
    -0.09 至 0.0 0.0 至 0.09
    -0.3 至 -0.1 0.1 至 0.3
    -0.5 至 -0.3 0.3 至 0.5
    -1.0 至 -0.5 0.5 至 1.0

    实现步骤

    源数据是在MySQL数据库中存储的,所以在进行统计分析工作前要先将数据从MySQL数据库中读取出来。

    平均成绩分析

    取数据

    根据课程id取出每个年级的各个学生此门课程的成绩,SQL语句如下:

    def sqlStr(courseId: Int): String = {
      s"""SELECT c.gradeId,sc.score FROM tb_student st
          LEFT JOIN tb_score sc ON st.studentId = sc.studentId
          LEFT JOIN tb_class c  ON st.classId = c.classId
          WHERE sc.courseId = $courseId
          ORDER BY sc.studentId"""
    }

    转化数据

    从MySQL中取得的数据在Spark中是DataFrame类型的,为了方便计算,我们需要将其转化为一个键值对RDD,键为“科目+年级”,值为每个学生成绩,如( C语言2006级,89.0),代码如下:

    val scoreRdd = scoreDataFrame.map(x => (courseStr(courseId) + gradeStr(x.getLong(0).toInt), x.getDecimal(1).doubleValue)).rdd

    计算平均成绩

    调用RDD的combineByKey()方法来计算平均数,此方法先将相同键的值加起来,之后除以这个键的个数,得到这个键对应的平均成绩,代码如下:

    val averageScoreRdd = scoreRdd.combineByKey(
      createCombiner = (v: Double) => (v: Double, 1),
      mergeValue = (c: (Double, Int), v: Double) => (c._1 + v, c._2 + 1),
      mergeCombiners = (c1: (Double, Int), c2: (Double, Int)) => (c1._1 + c2._1, c1._2 + c2._2),
      numPartitions = 3
    ).map { case (k, v) => (k, v._1 / v._2) }

    代码说明:

    • createCombiner即当遇到一个新键时,创建一个此键对应的累加器,如第一次遇到(C语言2006级,89.0)时,创建(C语言2006级,(89.0,1));
    • mergeValue即当遇到之前已遇到过的键时,将该键的累加器与当前值合并,如再遇到(C语言2006级,90.5)时,合并为(C语言2006级,(179.5,2));
    • mergeCombiners即将各个分区的结果进行合并,得到每门课程对应不同年级的总成绩和总人数,如(C语言2006级,(19173.7,241));
    • numPartitions即表示Spark分了3个分区来并行处理数据;

    代码最后一行的map即为将每个键的累加器的总成绩除以总人数,得到一个值为平均成绩的RDD,如(C语言2006级,79.559)。

    保存结果

    调用saveAsTextFile()方法将计算出的平均成绩存储在HDFS中,每个科目的平均成绩保存在用该科目名命名的文件夹中,代码如下:

    averageScoreRdd.sortByKey().saveAsTextFile("hdfs://localhost:9000/user/hadoop/output/score-avg/" + courseStr(courseId))

    相关性分析

    取数据

    根据年级id取出当前年级每个学生所有科目的成绩,SQL语句如下:

    def allScoreSqlStr(gradeId: Int): String = {
      s"""SELECT
            MAX(case cou.courseId when '1' THEN IFNULL(sc.score, 0) END) '高等数学',
            MAX(case cou.courseId when '2' THEN IFNULL(sc.score, 0) END) '外语',
            MAX(case cou.courseId when '3' THEN IFNULL(sc.score, 0) END) '离散数学',
            MAX(case cou.courseId when '4' THEN IFNULL(sc.score, 0) END) 'C语言' ,
            MAX(case cou.courseId when '5' THEN IFNULL(sc.score, 0) END) '数据结构',
            MAX(case cou.courseId when '6' THEN IFNULL(sc.score, 0) END) '组成原理',
            MAX(case cou.courseId when '7' THEN IFNULL(sc.score, 0) END) '操作系统'
          FROM  tb_student st
          LEFT JOIN tb_score sc on st.studentId = sc.studentId
          LEFT JOIN tb_course cou on cou.courseId = sc.courseId
          LEFT JOIN tb_class cla ON  st.classId = cla.classId
          WHERE cla.gradeId = $gradeId
          GROUP BY st.studentId
          ORDER BY st.studentId"""
    }

    转化数据

    先将此DataFrame类型的数据转化成数值类型的RDD:

    val data = scoreDataFrame.map(x => x.toString).rdd.
      map(x => x.substring(1, x.length - 1).split(",")).
      map(x => x.map(x => x.toDouble))

    计算Pearson相关系数可以调用Spark MLlib库中的方法,但是该方法要求RDD为向量类型的RDD,所以继续转化:

    val data1 = data.map(x => Vectors.dense(x))

    计算Pearson相关系数

    直接调用Spark MLlib库中的Statistics.corr方法进行计算:

    val corr = Statistics.corr(data1, "pearson")

    保存结果

    经过上述计算,得到的corr是一个矩阵,我们想将结果保存成CSV以便于查看,所以应先将corr转化成一个数值类型的RDD,再将RDD转化成DataFrame以便于保存为CSV文件,最后将结果保存到HDFS上,每个年级的各科相关系数保存在以该年级命名的文件夹中,代码如下:

    val tmpRdd = sc.parallelize(corr.rowIter.toArray.map(x => x.toArray)).map(x => (x(0), x(1), x(2), x(3), x(4), x(5), x(6)))
    val tmpDF = tmpRdd.toDF("高等数学", "外语", "离散数学", "C语言", "数据结构", "组成原理", "操作系统")
    tmpDF.write.format("csv").save("hdfs://localhost:9000/user/hadoop/output/score-pearson/" + gradeStr(gradeId))

    提交运行

    代码编写完成后,我们需要将代码打包成jar文件(打包过程略),然后提交到spark集群上运行,有以下三步:

    启动master

    进入spark的安装目录,输入:

    ./sbin/start-master.sh

    启动worker

    ./bin/spark-class org.apache.spark.deploy.worker.Worker spark://localhost:7077  

    这里的地址为:启动master后,在浏览器输入localhost:8080,查看到的master地址:

    启动成功后,用jps查看进程:

    因本实验中还用到了HDFS,所以也必须启动它(使用start-dfs.sh),启动后再用jps查看一下进程:

    提交作业

    ./bin/spark-submit --master spark://localhost:7077 --class ScoreAnalysis /home/hadoop/scoreanalysis.jar

    注:这里将打包好的jar包放在了/home/hadoop/目录下

    可以在4040端口查看作业进度:

    结果展示

    上文说过,我们将结果保存在了HDFS中,所以当程序运行完成后,要查看结果,必须用Hadoop HDFS提供的命令或者进入namenode管理页面进行查看。

    在控制台上输入以下命令:

    $ hadoop fs –ls /user/hadoop/output/

    结果如下图:

    为了便于查看,我们也可以进入namenode管理页面。

    查看平均成绩

    进入score-avg文件夹,可以看到每个科目创建了一个文件夹。

    进入外语文件夹,可以看到有四个文件,_SUCCESS表示文件存储成功,其他三个文件即Spark保存时有三个分区,分别进行了保存。

    为了方便查看,我们使用cat命令,将所有文件内容整合到一个本地文件中,如下图所示:

    查看Pearson相关系数

    进入score-pearson文件夹,可以看到,我们将不同课程的相关性按年级分成了不同的文件夹。

    以2006级为例说明,进入2006级文件夹,看到5个文件,_SUCCSESS说明保存成功,其余四个文件即Spark保存时有四个分区,分别进行了保存。

    同样,我们用cat命令将其合并到一个文件中,即在控制台中输入:

    hadoop fs -cat /user/hadoop/output/score-pearson/2006级/part-* >  //home/hadoop/score-pearson/2006级.csv

    之后打开2006级.csv,便能清晰的看到2006级学生成绩各科的pearson相关系数了:

    从图中可以看出,组成原理和操作系统的Pearson相关系数最高,达到了0.62,说明组成原理和操作系统的相关性较强。

    总结

    在本次实验中,我们小组共同合作,完成了用Spark进行对西工大某学院学生2006级至2015级各课程的成绩统计与分析。

    在这个过程中,我们学习到了Hadoop、Spark环境的搭建,Spark RDD的使用,Scala语言的用法,以及分布式开发的思想,并成功得出了各课程的平均成绩与相关性。

    这次实践我们收获到了很多,但由于能力与时间有限,本实验还有很多可以改进的地方。以后还有很多值得学习与研究的地方,我们会再接再厉,努力做得更好。

    附完整代码

    import java.util.Properties
    
    import org.apache.spark.mllib.linalg.Vectors
    import org.apache.spark.mllib.stat.Statistics
    import org.apache.spark.sql.SparkSession
    
    /**
      * xu qi ming
      * 2018.06.15
      */
    object ScoreAnalysis {
    
      /**
        * 根据课程id查找每个学生的成绩和所在年级的SQL语句
        *
        */
      def sqlStr(courseId: Int): String = {
        s"""SELECT c.gradeId,sc.score FROM tb_student st
              LEFT JOIN tb_score sc ON st.studentId = sc.studentId
              LEFT JOIN tb_class c ON  st.classId = c.classId
              WHERE sc.courseId = $courseId
              ORDER BY sc.studentId"""
      }
    
      /**
        * 查找当前年级每个学生所有科目的成绩的SQL语句
        *
        */
      def allScoreSqlStr(gradeId: Int): String = {
        s"""SELECT
              MAX(case cou.courseId when '1' THEN IFNULL(sc.score, 0) END) '高等数学',
              MAX(case cou.courseId when '2' THEN IFNULL(sc.score, 0) END) '外语',
              MAX(case cou.courseId when '3' THEN IFNULL(sc.score, 0) END) '离散数学',
              MAX(case cou.courseId when '4' THEN IFNULL(sc.score, 0) END) 'C语言' ,
              MAX(case cou.courseId when '5' THEN IFNULL(sc.score, 0) END) '数据结构',
              MAX(case cou.courseId when '6' THEN IFNULL(sc.score, 0) END) '组成原理',
              MAX(case cou.courseId when '7' THEN IFNULL(sc.score, 0) END) '操作系统'
            FROM  tb_student st
            LEFT JOIN tb_score sc on st.studentId = sc.studentId
            LEFT JOIN tb_course cou on cou.courseId = sc.courseId
            LEFT JOIN tb_class cla ON  st.classId = cla.classId
            WHERE cla.gradeId = $gradeId
            GROUP BY st.studentId
            ORDER BY st.studentId"""
      }
    
    
      /**
        * 将年级id转换成字符串
        *
        */
      def gradeStr(gradeId: Int): String = {
        gradeId match {
          case 1 => "2006级"
          case 2 => "2007级"
          case 3 => "2008级"
          case 4 => "2009级"
          case 5 => "2010级"
          case 6 => "2011级"
          case 7 => "2012级"
          case 8 => "2013级"
          case 9 => "2014级"
          case 10 => "2015级"
        }
      }
    
      /**
        * 将课程id转换成相应课程名字符串
        *
        */
      def courseStr(corseId: Int): String = {
        corseId match {
          case 1 => "高等数学"
          case 2 => "外语"
          case 3 => "离散数学"
          case 4 => "C语言"
          case 5 => "数据结构"
          case 6 => "组成原理"
          case 7 => "操作系统"
        }
      }
    
      def main(args: Array[String]): Unit = {
    
        // 生成SparkSession对象
        val spark = new SparkSession.Builder().appName("ScoreAnalysis").getOrCreate()
        //生成SparkContext对象
        val sc = spark.sparkContext
    
        //建立与mysql数据库的连接
        val connProperties = new Properties()
        connProperties.put("driver", "com.mysql.jdbc.Driver")
        connProperties.put("user", "root")
        connProperties.put("password", "Root_1234")
        connProperties.put("fetchsize", "100")
    
        import spark.implicits._
    
        /**
          * 计算指定课程的每个年级的平均成绩
          *
          */
        def averageScore(courseId: Int): Unit = {
    
          //连接数据库,将取得的成绩保存成DataFrame
          val scoreDataFrame = spark.read.jdbc(
            "jdbc:mysql://localhost:3306/db_score",
            s"(${sqlStr(courseId)}) as table01",
            connProperties)
    
          //将DataFrame转化成一个键值对RDD,键是科目+年级,值是每个学生的成绩
          val scoreRdd = scoreDataFrame.map(x => (courseStr(courseId) + gradeStr(x.getLong(0).toInt), x.getDecimal(1).doubleValue)).rdd
    
          //计算每个年级的平均成绩
          val averageScoreRdd = scoreRdd.combineByKey(
            createCombiner = (v: Double) => (v: Double, 1),
            mergeValue = (c: (Double, Int), v: Double) => (c._1 + v, c._2 + 1),
            mergeCombiners = (c1: (Double, Int), c2: (Double, Int)) => (c1._1 + c2._1, c1._2 + c2._2),
            numPartitions = 3
          ).map { case (k, v) => (k, v._1 / v._2) }
    
          //保存到HDFS中
          averageScoreRdd.sortByKey().saveAsTextFile("hdfs://localhost:9000/user/hadoop/output/score-avg/" + courseStr(courseId))
        }
    
        //循环这7门课,求每个课程每个年级的平均成绩
        for (i <- 1 to 7) {
          averageScore(i)
        }
    
        /**
          * 计算指定年级的所有科目的pearson相关系数
          *
          */
        def pearsonCorr(gradeId: Int): Unit = {
    
          //连接数据库,将取得的成绩保存成DataFrame
          val scoreDataFrame = spark.read.jdbc(
            "jdbc:mysql://localhost:3306/db_score",
            s"(${allScoreSqlStr(gradeId)}) as table01",
            connProperties)
    
          //将DataFrame转成数值类型的RDD
          val data = scoreDataFrame.map(x => x.toString).rdd.
            map(x => x.substring(1, x.length - 1).split(",")).
            map(x => x.map(x => x.toDouble))
    
          //将数值RDD转为Vector类型的RDD
          val data1 = data.map(x => Vectors.dense(x))
    
          //调用机器学习库的统计学习中的算法计算pearson相关系数
          //将结果返回成一个矩阵
          val corr = Statistics.corr(data1, "pearson")
    
          //保存计算的结果到HDFS
          val tmpRdd = sc.parallelize(corr.rowIter.toArray.map(x => x.toArray)).map(x => (x(0), x(1), x(2), x(3), x(4), x(5), x(6)))
          val tmpDF = tmpRdd.toDF("高等数学", "外语", "离散数学", "C语言", "数据结构", "组成原理", "操作系统")
          tmpDF.write.format("csv").save("hdfs://localhost:9000/user/hadoop/output/score-pearson/" + gradeStr(gradeId))
        }
    
        //循环这10个年级,求每个年级的各科相关系数情况
        for (i <- 1 to 10) {
          pearsonCorr(i)
        }
      }
    
    }
    展开全文
  • 在编写“学生成绩管理系统”软件之前,同类型产品的市场进行了前期调查,与多位软件设计者使用者进行了探讨和分析之后由软件项目小组向系统分析人员与软件设计人员提出了这份需求规格说明书。该需求说明书...
  • 本次用 MapReduce 查找(输入一个学生的姓名,输出该生姓名以及其参加考试的课程和成绩)是我们《大数据基础》课程的期末大作业的功能需求之一。临近期末,在这里记录一下自己的学习收获,希望大家在浏览的过程中...

    本次用 MapReduce 查找(输入一个学生的姓名,输出该生姓名以及其参加考试的课程和成绩)是我们《大数据基础》课程的期末大作业【 基于MapReduce的成绩分析系统 】 的功能需求之一。

    临近期末,在这里记录一下自己的学习收获,希望大家在浏览的过程中有所收获。

    由于能力有限,博客中难免会存在一些不足,有纰漏之处恳请大佬指正,不胜感激… …💚

    本次该大作业完整的代码我已上传,需要的可以下载:
    基于MapReduce的成绩分析系统实现编程源代码

    博客主页:爱跑步的mango 🌱

    一、数据及字段说明

    这个数据与另一篇博客的输入数据是一样的,点击下方即可查看:
    👉 【基于MapReduce的成绩分析系统】——计算每门课程的平均成绩、最高成绩、最低成绩 👈

    二、过程分析及解题思路

    • 需求: 查找(输入一个学生的姓名,输出该生姓名以及其参加考试的课程和成绩)
      返回结果格式举例:olive:english,48;PE,78;music,48;chinese,42;(这里的olive是我们指定的要查找的学生姓名,后面其参加考试的课程和对应的成绩,可以指定查找其他学生。)
    • 解题思路: 查找(输入一个学生的姓名,输出该生姓名以及其参加考试的课程和成绩),在main方法中传递变量属性,将要查询的学生姓名通过参数设置,在map阶段取出,主要考虑找到聚合的key,然后reduce方法去拉取数据的时候会进行归并排序,这里用自定义Student类实现WritableComparable接口的compareTo方法定义的逻辑来比较是否是相同的数据,也就是学生姓名。这样相同的key数据就会在同一个reduce方法中执行,这时候我们在reduce方法中进行相关的过滤,就可以找到目标数据了。
    • 关键: mapper阶段和reducer阶段的输入和输出是什么?
    • 对于mapper阶段,map方法输出的key-value分别是
      key:Student
      value: NullWritable
    • 对于reducer阶段,reduce方法输出的key-value分别是
      key:Student
      values: NullWritable

    三、具体代码实现

    • 自定义数据类型:Student 的代码
    package Mapreduce.mark6;
    
    import org.apache.hadoop.io.WritableComparable;
    
    
    
    import java.io.DataInput;
    
    import java.io.DataOutput;
    
    import java.io.IOException;
    
    
    
    public class Student implements WritableComparable<Student> {
    
        private StringBuilder courseName;//课程名
    
        private String studentName;//学生姓名
    
        private Integer score;
    
    
    
        public Student() {
    
        }
    
    
    
        public Student(StringBuilder courseName, String studentName, Integer score) {
    
            this.courseName = courseName;
    
            this.studentName = studentName;
    
            this.score = score;
    
        }
    
    
    
        public StringBuilder getCourseName() {
    
            return courseName;
    
        }
    
    
    
        public void setCourseName(StringBuilder courseName) {
    
            this.courseName = courseName;
    
        }
    
    
    
        public String getStudentName() {
    
            return studentName;
    
        }
    
    
    
        public void setStudentName(String studentName) {
    
            this.studentName = studentName;
    
        }
    
    
    
        public Integer getScore() {
    
            return score;
    
        }
    
    
    
        public void setScore(Integer score) {
    
            this.score = score;
    
        }
    
      //比较规则
    
        @Override
    
        public int compareTo(Student o) {
    
            return this.studentName.compareTo(o.studentName);
    
        }
    
    // 序列化
    
        @Override
    
        public void write(DataOutput out) throws IOException {
    
            out.writeUTF(courseName.toString());
    
            out.writeUTF(studentName);
    
            out.writeInt(score);
    
        }
    
        //反序列化
    
        @Override
    
        public void readFields(DataInput in) throws IOException {
    
            this.courseName = new StringBuilder(in.readUTF());
    
            this.studentName = in.readUTF();
    
            this.score = in.readInt();
    
        }
    
        //通过toString方法自定义输出类型
    
        @Override
    
        public String toString() {
    
            return studentName + ':' + courseName;
        }
    }
    
    • MapReduce的代码
    package Mapreduce.mark6;
    
    
    
    import org.apache.hadoop.conf.Configuration;
    
    import org.apache.hadoop.fs.FileSystem;
    
    import org.apache.hadoop.fs.Path;
    
    import org.apache.hadoop.io.LongWritable;
    
    import org.apache.hadoop.io.NullWritable;
    
    import org.apache.hadoop.io.Text;
    
    import org.apache.hadoop.mapreduce.Job;
    
    import org.apache.hadoop.mapreduce.Mapper;
    
    import org.apache.hadoop.mapreduce.Reducer;
    
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    
    
    
    import java.io.IOException;
    
    //hadoop jar hadoop.jar Mapreduce.mark6.FindCoursesMR  hdfs://localhost:9000/user/hadoop/markinput  hdfs://localhost:9000/user/hadoop/findoutout6  olive
    
    public class FindCoursesMR {
    
        public static void main(String[] args) throws Exception {
    
        	if (args.length<3) {
    
                System.out.printf("Usage:%s <input> <output>\n");
    
            }
    
            Configuration conf = new Configuration();
    
            conf.set("studentName",args[2]);//args[2]是传入的第3个参数
    
            Job job = Job.getInstance(conf);
    
            //设置jar包所在路径
    
            job.setJarByClass(FindCoursesMR.class);
    
            job.setMapperClass(FCMapper.class);
    
            job.setReducerClass(FCReducer.class);
    
            //设置我们的业务逻辑Mapper 类的输出 key 和 value  的数据类型
    
            job.setMapOutputKeyClass(Student.class);
    
            job.setMapOutputValueClass(NullWritable.class);
    
            //这两个方法对map和reduce阶段的输出都能起到作用
    
            job.setOutputKeyClass(Student.class);
    
            job.setOutputValueClass(NullWritable.class);
    
    
    
            Path inputPath = new Path(args[0]);
    
            Path outPutPath = new Path(args[1]);
    
            FileSystem fs = FileSystem.get(conf);
    
            if (fs.exists(outPutPath)) fs.delete(outPutPath,true);
    
            FileInputFormat.setInputPaths(job,inputPath);
    
            FileOutputFormat.setOutputPath(job,outPutPath);
    
            
    
           //boolean waitForCompletion = job.waitForCompletion(true);
    
           // System.out.println("job is finished!");
    
            //System.exit(job.waitForCompletion(true)?0:1);
    
            System.out.println(job.waitForCompletion(true)?1:0);
    
        }
    
    
        static class FCMapper extends Mapper<LongWritable,Text, Student, NullWritable> {
    
        	 //map  方法的生命周期:  框架每传一行数据就被调用一次
    
    	    //key :  这一行的起始点在文件中的偏移量
    
    	    //value : 这一行的内容
    
            @Override
    
            protected void map(LongWritable key, Text line, Context context) throws IOException, InterruptedException {
    
                String[] fields = line.toString().split(",");
    
                if (fields.length==3){
    
                    context.write(new Student(new StringBuilder(fields[0]),fields[1],Integer.parseInt(fields[2])),NullWritable.get());
    
                }
    
            }
    
        }
    
    
    
        static class FCReducer extends Reducer<Student,NullWritable,Student,NullWritable> {
    
            private static String studentName = "";
    
            private static StringBuilder stringBuilder = null;
    
            private static Student stu = null;
    
    
    
            @Override
    
            protected void setup(Context context) throws IOException, InterruptedException {
    
            	//setup是在map执行前加载的方法,读取数据
    
                studentName = context.getConfiguration().get("studentName");
    
                stringBuilder = new StringBuilder();
    
                stu = new Student();
    
                stu.setStudentName(studentName);
    
            }
    
    
    
            @Override
    
            protected void reduce(Student key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
    
                if (studentName.equals(key.getStudentName())){
    
                    for (NullWritable value : values) {
    
                        stringBuilder.append(key.getCourseName() + ","+key.getScore()+";");
    
                    }
                    stu.setCourseName(stringBuilder);
                    context.write(stu,NullWritable.get());
                }
            }
        }
    }
    

    四、程序运行结果

    • 程序处理完成之后的结果所保存的位置:hdfs://localhost:9000/user/hadoop/findoutout6(这是自己定义的位置)。
    • 程序的执行结果
      在这里插入图片描述
      (可见,得到了我们要查找的学生olive考试的课程和对应的成绩。)

    本次的分享就到这里就结束了,这里要感谢老师和某个大佬,才让我可以完成,同时也教会了我很多东西。以上有任何错误,希望可以得到大佬们的指正,互相学习!✨

    💜 基于MapReduce的成绩分析系统如果想看更多功能实现的学习体验,欢迎访问:

    【基于MapReduce的成绩分析系统】——菜单主界面实现

    【基于MapReduce的成绩分析系统】——计算每门课程的平均成绩、最高成绩、最低成绩

    【基于MapReduce的成绩分析系统】——计算每门课程学生的平均成绩,并将平均成绩从高到低输出

    【基于MapReduce的成绩分析系统】——查找(输入一个学生的姓名,输出该生姓名以及其参加考试的课程和成绩)

    【基于MapReduce的成绩分析系统】——求该成绩表每门课程当中出现了相同分数的分数,出现的姓名以及该相同分数的人数


    展开全文
  • 目标检测主流算法的分析与论述

    千次阅读 2021-01-08 10:30:58
    经过多年的发展,在R-CNN、YOLO、SSD等经典算法的基础上,目标检测算法演化出了数量众多的算法理论,本文通过目前较为成熟的几种目标检测算法进行分析和论述,不同算法的优点不足做出讨论,将为不同的应用场景...
  • title: 高考成绩分析 categories: Person date: 2020-07-28 12:56:41 timestamp: 2020-07-28 12:56:41 tags: [blog, gaokao,dataproc] 开始 突发奇想, 想看下高考成绩的分布, 如果把每个省市的成绩划线成0-100 ...
  • 2 使用NumPySciPy进行数值分析2.1 基本概念1 from numpy importarray2 from numpy.random importnormal, randint3 #使用List来创造一组数据4 data = [1, 2, 3]5 #使用ndarray来创造一组数据6 data = array([1, 2, ...
  • 如何制定人生目标和实现目标

    千次阅读 2017-01-11 22:54:56
    如何制定人生目标和实现目标 第一步:分析你的需求。你也许会问:这一步怎么做呢?不妨试试以下方法。开动脑筋,写下来10条未来5年你认为自己应做的事情,要确切,但不要有限制和顾虑那些是自己做不到的,给自己...
  • 浅谈数据分析和数据建模

    千次阅读 2019-11-26 15:43:02
    过去企业都是通过线下渠道接触客户,客户数据不全,只能利用财务数据进行业务运营分析,缺少围绕客户的个人数据,数据分析应用的领域集中在企业内部经营财务分析。 数字时代到来之后,企业经营的各个阶段都可以被...
  • K12在线教育行业产品分析报告

    千次阅读 2017-08-30 14:02:20
    本篇文章分为两大部分:第一部分为行业分析,简单介绍了K12在线教育行业的整体情况,有助于了解K12在线教育的背景(包括:K12行业背景、K12在线教育概况、目标人群场景分析);第二部分为产品分析,包括答疑类、...
  • 马拉松成绩和体重的关系

    千次阅读 2015-08-13 09:56:00
    阿飞近来也体重PB的关系很感兴趣,于是跟大家分享下文。 作文(1)体重与成绩的假说公式 1.1 假说1:1kg=3分钟 关于体重马拉松成绩的关系,在日本大家一般都知道福冈大学田中教授的那个假说。“1kg=...
  • 目标检测简介

    千次阅读 2019-07-06 09:33:32
    文章目录目标检测简介1 引言2 目标检测分类2.1 传统的目标检测算法2.2 基于深度学习的目标检测算法2.2.1 基于two stage的目标检测2.2.2 基于one stage的目标检测3 Faster RCNN目标检测算法及其实现3.1 Faster RCNN...
  • 个人目标设定 每一个同学,都要思考自己的职业规划,暑假做什么实习、以后做什么工作。如有疑惑,欢迎大家交流。 我们每个人,都需要不断学习与成长,你们需要,老师也需要。老师计划于2014年6月26-27日参加在北京...
  • Python成绩管理系统

    千次阅读 2020-06-11 09:44:22
    本系统是基于Python语言,通过对成绩管理工作的日常分析,确定了具体的研究目标以及业务功能。采用了结构化的设计方法设计了一个简单的框架,通过编程实现了对成绩信息的添加、修改、删除、查询,并且使用csv文件...
  • 我做过近两年的电商运营,其中感触很深的一个点就是从数据的维度对目标做拆分。天猫的双11刚刚过去,马云又创造了新的成绩,912亿。从去年的571亿到今年的912亿,马云怎么就敢说今年可以做900亿呢?在设定这个目标...
  • 学生成绩管理系统主要用于各类大学院校在教学这一部分的管理,是针对于教务处课程、学生、学生成绩进行合理地安排以及统筹计划,以便让教务处以最短的工作时间内把学生的成绩核算出来,提高教务处的办事效率。...
  • 没有目标就失去一切  刚毕业那会儿,幼稚得可笑,老跟同学打电话,明面上聊聊近况,暗地里比较。你要比我工资多一百块,心里特不平衡,凭什么呀,在学校那会儿公认的我比你强。你要带个头衔,而我啥也不是,普通...
  • 是企业为了实现生产经营目的,运用特定的标准指标,采取科学的方法,承担生产经营过 程及结果的各级管理人员完成指定任务的工作实绩由此带来的诸多效果做出价值判断的过 程。 本案例以作者的亲历感受着重...
  • 回顾目标——评估结果——分析原因——总结经验 回顾目标:当初的目的期望是什么; 评估结果:对照原来的目的找出过程中的亮点不足; 分析原因:事情做成功的关键原因失败的根本原因,包括主观客观两方面...
  • 潜在语义分析对认知科学的启示

    千次阅读 2009-11-03 21:09:00
    潜在语义分析技术认知科学以及虚拟现实系统的设计也具有启示: 首先,由于LSA可以用数学方法实现文本的理解,所以可采用LSA分析文本的理解。 认知领域中,文本理解研究的主要目标是发现影响读者由文本材料...
  • 数据建模讲解案例分析

    万次阅读 多人点赞 2017-04-18 13:34:09
    维基百科数据分析的定义如下: Analysis of data is a process of inspecting, cleaning, transforming, and modeling data with the goal of discovering useful information, suggesting conclu...
  • 考试成绩随想

    2009-02-22 10:25:00
    报了软件设计师、北大软件工程硕士还有系统分析员的考试,第一门考试的成绩在去年7月份的时候就出来了,很顺利地通过了,第二门考试经过了几道关卡之后也以比较好的成绩通过了,系统分析员考试成绩是最后出来的。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,478
精华内容 16,191
关键字:

对成绩分析和以后的目标