算法02

析过去 把握现在 预测未来

在茫茫的数据大海海底下有一望无际的信息沙漠,金灿灿的有价值的信息深埋其中等待人们去发现和挖掘

对数据敏感就是对有价值信息的敏感    培养数据敏感性的过程就是树立真正的审美观

元数据(Metadata checkpointing)管理数据的数据

getOrCreate 有就获取激活状态的option没有就创建

机器学习在大数据项目中的位置    位于数据分析和BI报表之间层

大数据时代改变的是思维方式
数据重要性:数据资源--------->数据资产(数据的增值)
   买卖数据的公司
方法论:基于知识的理论完美主义(∵因为,∴所以)--------->基于数据的历史经验主义(基于历史事物)
   推荐系统(获取用户最近点击 浏览 收藏 加购 分享等)
   翻译:
     基于知识的方面(过去)
       你好吗?
         语言学家
           你:you  your
           好:good better well
           吗:do does did
           Are you ok? Are you good? How are you?
           How are you?
     基于数据的方面(基于数据)
       抽样调查:
         Are you ok? Are you good? How are you?(choose)
数据分析:统计学(抽样)--------->数据科学(学术界的叫法-(工业界)大数据)--------->数据科学家
   数据科学与大数据专业
   数据科学家--------->大数据的架构技能+机器学习算法的技能+多年业务经验
     boss搜索该职位
计算智能:
   复杂的算法(遗传算法)--------->简单的算法(MR)
     简单的算法+数据[也可以如同复杂算法一样解决]=>业务问题
业务层面:
   业务的数据化--------->数据的业务化
     通过数据决策业务
决策方面
   基于目标决策--------->基于数据的决策
     依靠数据决策
产业竞合方面
   基于战略为中心--------->基于数据为中心
     数据重要性

 图像识别---识别猫or狗
 无人驾驶---百度无人车
 智能翻译----中英文转换
 语音识别---提取语音特征
 医疗智能诊断-------结合传统的医生的方法+医疗数据分析
   没病----有病
   有病----没病
 数据挖掘 对信息进行价值化的提取 机器学习是一种方法 解决数据挖掘这件事情
   尿布---啤酒

什么不是机器学习
数值计算问题
确定性问题

1956  Artificial Intelligence提出
1956年夏季,以麦卡赛 明斯基 罗切斯特和申农等为首的一批有远见卓识的年轻科学家在一起聚会,共同研究和探讨用机器模拟智能的一系列有关问题,并首次提出了"人工智能"这一术语,它标志着"人工智能"这门新兴学科的正式诞生.IBM公司"深蓝"电脑击败了人类的世界国际象棋冠军更是人工智能技术的一个完美表现.人工智能的目的就是让计算机这台机器能够像人一样思考.
1950-1970
符号主义流派:专家系统占主导地位
1950:图灵设计国际象棋程序
1962:IBM Arthur Samuel的跳棋程序战胜人类高手(人工智能第一次浪潮) 跳棋 专家系统
1980-2000
统计主义流派
主要用统计模型解决问题
Vapnik 1993
1997:IBM 深蓝战胜卡斯帕罗夫(人工智能第二次浪潮) 国际象棋 统计模型 暴力穷举
2010-至今
神经网络 深度学习 大数据流派
Hinton 2006
2016:Google AlphaGO 战胜李世石(人工智能第三次浪潮) AlphaGo 大数据与深度学习

用机器学习的方法来进行数据挖掘.机器学习是一种方法;
数据挖掘是一件事情;还有一个相似的概念就是模式识别,这也是一件事情
数据挖掘是指从大量的数据中通过算法搜索隐藏于其中信息的过程.
数据挖掘通常与计算机科学有关,并通过统计 在线分析处理 情报检索 机器学习 专家系统(依靠过去的经验法则)和模式识别等诸多方法来实现上述目标
深度学习技术只是机器学习的一种
人工智能是研究如何让机器具有类人智能的学科,目标是让机器具有人类的智能.
机器学习专门研究计算机怎样模拟或实现人类的学习行为,使之不断改善自身性能
机器学习模型=数据+机器学习算法
机器学习学习的是模型 机器学习的是模型中的参数
 对于不是机器学习问题:
   1-确定的问题
   2-统计的问题
 对于机器学习来讲,通过历史数据结合算法,给出预测模型或规律进行预测分析
   1-推荐场景
   2-Facebook人物标记
   3-预测2022年世界杯冠军名称
   4-预测2022年人民币汇率张or下跌的问题?
机器学习,是达到人工智能目标的手段之一;模式识别也是达到人工智能的手段之一;
如上图所示,对数据挖掘而言,数据库提供数据管理技术,机器学习和统计学提供数据分析技术
人工智能范围比较大,机器学习相对来说属于人工智能的范畴.数据挖掘则是将机器学习作为工具,利用机器学习的算法用来完成数据挖掘
没有机器学习之前,如何对邮件进行分类?
基于规则学习

缺点:
1-规律可能会变换------人会变化
2-能否避免因为人为的因素的影响带来的影响
基于模型学习

X:自变量------>定义域----->特征features
Y:因变量------->值域------->标签列label
F:函数---------->映射------->模型model
X F Y 从X和Y中学习到最佳的F 即找到最佳的k和b
y=kx+b----------->x是邮件的特征,y就是邮件分类
机器学习学习的是什么?
机器学习学习的是模型,更进一步将机器学习学习的是模型中的参数


行向量 列向量
特征空间 由特征张成的N维空间
 

能否将所有的数据都用于训练模型
一般情况下将数据集切分为训练集和测试集 比例为 82 73 64
X+y trainingdata+机器学习算法alg algorithms = 机器学习模型Model
鸢尾花Iris Dataset数据集是机器学习领域经典数据集,该数据集可以从加州大学欧文分校(UCI)的机器学习库中得到.鸢尾花数据集包含了150条鸢尾花信息,每50条取自三个鸢尾花中之一:Setosa Versicolour和Virginica,每个花的特征用下面5种属性描述.
萼片长度(厘米)
萼片宽度(厘米)
花瓣长度(厘米)
花瓣宽度(厘米)
类(Setosa Versicolour Virginica)
花的萼片是花的外部结构,保护花的更脆弱的部分(如花瓣).在许多花中,萼片是绿的,只有花瓣是鲜艳多彩的,然而对与鸢尾花,萼片也是鲜艳多彩的.下图中的Virginica鸢尾花的图片,鸢尾花的萼片比花瓣大并且下垂,而花瓣向上

数据集dataset
每一行的数据叫样本数据
(3)除最后一列标签列外,每一列的数据叫特征或属性
(4)最后一列叫标签列,样本所属类别.
(5)属性(特征)空间∶ 这里由4个特征组成的属性空间
(6)特征向量∶构成特征空间的每一行的特征数据
(7)训练数据∶由输入X(特征)和输出Y(标签)构成.
(8)训练(过程)∶从数据中学得模型的过程叫做"学习"或"训练".训练过程中使用的数据叫做训练数据
(9)测试样本∶被预测的样本数据,由测试数据和类标签构成.
(10)测试数据∶仅有输入的x构成,根据模型得到预测Label信息.
(11)预测∶学习完模型之后,由测试数据代入模型进行预测,得到预测值
(12)预测值和真实值的差距的评判标准∶
错误率∶错误样本数占总体样本的比例
准确率∶ 1-错误率
误差∶模型的实际输出和真实值的差距
训练误差∶ 学习器在训练样本上的误差
泛化误差∶ 学习器在新的样本上的误差

在鸢尾花中花数据集中,包含150个样本和4个特征,因此将其记作150x4维的矩阵,,其中R表示向量空间,这里表示150行4维的向量,记作:

我们一般使用上标(i)来指代第i个训练样本,使用小标(j)来指代训练数据集中第j维特征.一般小写字母代表向量,大写字母代表矩阵.
表示第150个花样本的第2个特征萼片宽度.在上述X的特征矩阵中,每一行表代表一个花朵的样本,可以记为一个四维行向量
数据中的每一列代表样本的一种特征,可以用一个150维度的列向量表示

类似地,可以用一个150维度的列向量存储目标变量(类标)

 
 数据集:西瓜数据集
   样本samples:8
   特征features:3
   类别标签列(class label):1列  0或1
 特征或属性====>特征或属性空间(3)===>特征向量或属性向量====>特征或属性值
 对于非数值型的数据进行处理分析
   labelencoder 标签编码
     0-1-2
   onehotencoder独热编码
     001
     010
     100
 需要进行数据集的划分
   训练集:测试集=8:2,7:3
   训练集是训练模型  
   通过测试集测试模型
 误差
   绝对误差
   平方误差
   训练误差:模型在训练集上的误差
   测试误差:模型在测试集的上误差
   泛化误差:模型对于新数据或测试数据的适应能力 新事物的适应能力
   准确率
   错误率
[基础概念1]将这组记录的集合称为一个"数据集"(data set),其中每条记录是关于一个事件或对象(这里说的是西瓜)的描述,也称为一个"样本"(sample).
[基础概念2]而我们所说的西瓜的色泽,这种可以反应事件或对象在某方面的表现或性质的事项,称为"特征"(feature)或"属性"(attribute)"
属性上的取值,如色泽青绿等,这个取值称为属性值(attribute value).
[基础概念3]属性构成的空间称为"属性空间"或样本空间(sample space)或输入空间.比如将西瓜的颜色,敲声作为两个坐标轴,则它们可以张成一个用于描述西瓜的二维空间,每个西瓜都可以在这个空间中找到自己的坐标位置.由于空间中的每个点都对应一个坐标向量,因此我们也把一个样本称作一个"特征向量"(feature vector).
假设是西瓜数据集的第i个样本,其中是在第j个属性上的取值,如第3个西瓜在第1个属性(颜色)上取值为"乌黑".d称为样本的"维度数或维数"(dimensionality).数据集D中的表示第i个样本或示例.
[基础概念4]从数据中学得模型得过程称为"学习"(learning)或训练(training),这个过程是通过执行某个学习算法来完成的.训练过程中使用的数据称为"训练数据"(training set).
训练数据:由输入X与输出Y对组成.训练集在数学上表示为:

[基础概念5]模型有时也称为"学习器"(learner),可以看作是学习算法在给定数据和参数空间上的实例化.
[基础概念6]如果希望学得一个能帮助我们判断西瓜是不是"好瓜"的模型,仅仅有前面的样本数据是不够的,要建立这样的关于"预测(prediction)"的模型,我们需要获得训练样本的"结果"信息,如:{(颜色=青绿,敲声=浊响),好瓜}.这里的结果信息,称为样本的"标记(label)";拥有了标记信息的样本,则称为"样例(example)".用表示第i个样例,yi是样本x的标识,一般把标记的集合称为标记空间(label space)或输出空间.
学习完模型后,就需要进行预测,预测的过程称为"测试"(testing),被预测的样本称为"测试样本"(testing sample).
测试数据:也是由输入X与输出Y组成,是用于测试训练好的模型对于新数据的预测能力.例如在中学阶段的函数可表示为y=f(x),这里的f指的是通过学习得到的模型,对于测试x,可得到其预测标记y=f(x).
首先,通过电商购买数据集了解机器学习数据集的构成:其中每一个用户都由age年龄 income收入 student是否为学生 credit_rating信用级别和buy_computer是否购买电脑组成.

如果通过机器识别用户是否购买电脑,需要将数据集中各字段进行数字化:

数据集的描述:

机器学习
监督学习(supervised learning)从训练数据(training data)集合中学习模型,对测试数据(test data)进行预测.
通俗易懂地讲:监督学习指的是人们给机器一大堆标记好的数据,比如一大堆照片,标记住那些是猫的照片,那些是狗的照片,然后让机器自己学习归纳出算法或模型,然后所使用该算法或模型判断出其他照片是否是猫或狗.代表的算法或模型有Linear regression Logistic regression 支持向量机(Support Vector Machine, SVM) Neural network等.

有监督学习 带有标签列的学习方式
根据labels标签列是否为连续值的预测
如果是连续值的预测====房价预测
   称之为"回归问题"----regression
regress,re表示back,gress等于go,数值go back to mean value,也就是I'll be back的意思
在数理统计中,回归是确定多种变量相互依赖的定量关系的方法
通俗理解 越来越接近期望值的过程,回归于事物的本质

如果是离散值的预测问题====西瓜的分类
   称之为"分类问题"----classification

分类的目标是预测离散的类别 分类是将数据映射到预先定义好的不同类别,判定其属于有限个类别(如上面提到的投资级别)
回归的目标是预测连续变量 如预测房价.

分类是监督学习的一个核心问题.在监督学习中,当输出变量Y取有限个离散值时,预测问题便成了分类问题.监督学习从数据中学习一个分类模型或分类决策函数,称为分类器(classifer),分类器对新的输入进行输出的预测(prediction),称为分类(classification).
分类的类别是多个时,称为多类分类问题.
分类问题包括学习和分类的两个过程.在学习过程中,根据已知的训练数据集利用有效的学习方法学习一个分类器;在分类的过程中,利用学习的分类器对新的输入实例进行分类.
如上述的垃圾邮件就是一个2分类问题,使用相应的机器学习算法判定邮件属于垃圾邮件还是非垃圾邮件.如下图给出了30个训练样本集实例:15个样本被标记为负类别(negative class)(图中圆圈表示);15个样本被标记为正类别(positive class)(图中用加号表示).由于我们的数据集是二维的,这意味着每个样本都有两个与其相关的值:,现在我们可以通过有监督学习算法获得一条规则,并将其表示为图中的一条黑色的虚线将两类样本分开,并且可以根据值将新样本划分到某个类别中(看位于直线的那一侧).

分类的任务就是将具有类别的 无序类标分配给各个新样本.
总结:
输出变量为有限个离散值的情况称为分类问题(classification)
如果类别为正类或负类的时候,这个是一个二分类问题
如果类别是一个多类别的时候,这就是一个多分类问题.
分类问题包括了学习和分类两个过程:
学习:根据已知的训练数据集利用有效的学习方法学习一个分类器.
分类:利用学习到的算法判定新输入的实例对其进行分类.

(2)利用回归预测连续输出值
另一类监督学习方法针对连续型输出变量进行预测,也就是所谓的回归分析(regression analysis).回归分析中,数据中会给出大量的自变量和相应的连续因变量(对应输出结果),通过尝试寻找自变量和因变量的关系,就能够预测输出变量.
如下图中,给定了一个自变量x和因变量y,拟合一条直线使得样例数据点与拟合直线之间的距离最短,最常采用的是平均平方距离来计算.如此,我们可以通过样本数据的训练来拟合直线的截距和斜率,从而对新的输入变量值所对应的输出变量进行预测.
比如生活中常见的房价问题,横轴代表房屋面积,纵轴代表房屋的售价,我们可以画出图示中的数据点,再根据使得各点到直线的距离的平均平方距离的最小,从而绘制出下图的拟合直线.根据生活常识随着房屋面积的增加,房价也会增长.
回归问题的分类有:根据输入变量的个数分为一元回归和多元回归;按照输入变量和输出变量之间的关系分为线性回归和非线性回归(模型的分类).


(3)标注问题 例如有一堆词语 标注什么是名词什么是动词
标注问题是分类问题的一种推荐,输入是一个观测序列,输出是一个标记序列或状态序列.标注问题的目标在于学习一个模型,使它能够对观测序列给出标记序列作为预测.
标注问题常用的方法有:隐马尔科夫模型 条件随机场.
自然语言处理中的词性标注就是一个标注问题:给定一个由单词组成的句子,对这个句子中的每一个单词进行词性标注,即对一个单词序列预测起对应的词性标注序列.

无监督学习 无标签学习

没有y
通俗地讲:非监督学习(unsupervised learning)指的是人们给机器一大堆没有分类标记的数据,让机器可以对数据分类 检测异常等.

无监督学习
 1-聚类:物以类聚 人以群分
 考虑:如果只是根据特征如何进行分类?
   能否根据样本的特征之间的相似度进行分类
     1-首先计算各个样本之间的相似度,比如使用欧氏距离(两点之间距离公式)
     2-将相似度的比较高的样本进行聚集在一个组或一个簇中,组内的相似度是极高的,组间的相异性极高的
     3-将样本数据划分为几个组或几个簇,组内的或簇内的相似度极高的

(1)通过聚类发现数据的子群
聚类是一种探索性数据分析技术,在没有任何相关先验信息的情况下(相当于不清楚数据的信息),它可以帮助我们将数据划分为有意义的小的组别(也叫簇cluster).其中每个簇内部成员之间有一定的相似度,簇之间有较大的不同.这也正是聚类作为无监督学习的原因.
下图中通过聚类方法根据数据的两个特征值之间的相似性将无类标的数据划分到三个不同的组中.
[例子]我们可以用下图表示西瓜的色泽和敲声两个特征,分别为,我们可以将训练集中的西瓜分成若干组,每一组称为一个"簇",这些自动形成的簇可能对应一些潜在的概念划分,如"浅色瓜" "深色瓜" "本地瓜"或"外地瓜".通过这样的学习我们可以了解到数据的内在规律,能为更深入地分析数据建立基础.
需要注意的是我们事先并不知道西瓜是本地瓜 浅色瓜,而且在学习过程中使用的训练样本通常不拥有标记(label)信息.


(2)数据压缩中的降维
数据降维(dimensionality reduction)是无监督学习的另一个子领域.通常,面对的数据都是高维的,这就对有限的数据存储空间以及机器学习算法性能提出了挑战.无监督降维是数据特征预处理时常用的技术,用于清除数据中的噪声,能够在最大程度保留相关信息的情况下将数据压缩到额维度较小的子空间,但是同时也可能会降低某些算法准确性方面的性能.
如下图一个三维空间的数据映射到二维空间的实例.

特征降维不是特征选择
原本特征降维后依然可见 
特征降维    通过算法降维 将高维度数据转化为低维度数据
降维的思录是PCA主成分分析法的降维方式
半监督学习
 一部分数据有标签,一部分数据没有标签

 缺点:引入了专家知识,需要规避因为专家带来的影响
 基于聚类的假设:
   首先数据集是一部分有标签一部分是没有标签,通过将有标签的数据结合没有标签的数据进行聚类.将相似度高的样本聚集在同一个组中,相异性较高的样本分在不同的组里面
   对于聚类之后的结果,在同一个组里面既有没有标记的样本也有具有标记的样本,就可以获取已经有标记的样本数据,通过样本的类别值少数服从多数的原则进行选举,比如有标记的红8黑2那就选红,将选举的类别值给没有标记的样本加上样本的标记,通过该方法就可以让没有标记的样本全部加上标记,从而实现转化为监督学习.

半监督学习的现实需求也非常强烈,因为在现实生活中往往能容易地收集到大量未"标记"的样本,而获取有标记的样本却需要耗费人力 物力.在互联网应用的最为明显,例如在进行网页推荐时需要请用户标记出感兴趣的网页,但是很少的用户愿意花很多时间来提供标记,因此,有标记的网页样本少,但互联网上存在无数网页可作为未标记样本使用.
半监督学习就是提供了一条利用"廉价"的未标记样本的途径.
通常在处理未标记的数据时,常常采用"主动学习"的方式,也就是首先利用已经标记的数据(也就是带有类标签)的数据训练出一个模型,再利用该模型去套用未标记的数据,通过询问领域专家分类结果与模型分类结果做对比,从而对模型做进一步改善和提高,这种方式可以大幅度降低标记成本,但是"主动学习"需要引入额外的专家知识,通过与外界的交互来将部分未标记样本转化有标记的样本.但是如果不与专家进行互动,没有额外的信息,还能利用未标记的样本提高模型的泛化性能吗?
答案是肯定的,因为未标记样本虽然未直接包含标记信息,但它们与有标记样本有一些共同点,我们可以利用无监督学习的聚类方法将数据特征相似的聚在一个簇里面,从而给未标记的数据带上标记.这也是在半监督学习中常用的"聚类假设",本质上就是"利用相似的样本拥有相似的输出"这个基本假设.
半监督学习进一步划分为了纯半监督学习和直推学习(transductive learning),前者假定训练数据中的未标记样本并不是待测数据,而直推学习假设学习过程中所考虑的未标记样本恰恰是待预测样本.无论是哪一种,我们学习的目的都是在这些未标记的样本上获得最优的泛化性能(泛化简单的指的是模型无论对训练集表现效果好,对测试集效果也很不错,在模型选择中我们会详细讲解).

一部分没有标签 一部分有标签 能否将由标签的数据进行逻辑删除标签列 利用聚类将所有的数据通过样本的相似性划分为不同的组或者簇 被划分在同一个组中的样本数据应该归为一类 将划分再痛一个组中的数据是既有有被逻辑删除标签列的样本也有没有标记的样本 对有标记的样本数据根据样本的标记少数服从多数原则选择出现次数较多的样本 给没有标记的数据加上标记 这样就都有了标记可以直接利用监督学习分类或回归算法进行分类或回归

强化学习 连续决策问题
   alphaGo下棋
   无人驾驶    深度学习->图像识别->红绿灯检测
强化学习->连续决策

[基础概念]强化学习(Reinforcement Learning)是机器学习的一个重要分支,主要用来解决连续决策的问题.比如围棋可以归纳为一个强化学习问题,我们需要学习在各种局势下如何走出最好的招法.还有我们要种西瓜的过程中需要多次种瓜,在种瓜过程中不断摸索,然后才能总结出好的种瓜策略,将例子中的过程抽象出来就是"强化学习".
强化学习不像无监督学习那样完全没有学习目标,又不像监督学习那样有非常明确的目标(即label),强化学习的目标一般是变化的 不明确的,甚至可能不存在绝对正确的标签.最近火热的无人驾驶技术是一个非常复杂 非常困难的强化学习任务,在深度学习出现之前,几乎不可能实现,无人驾驶汽车通过摄像头 雷达 激光测距仪 传感器等对环境进行观测,获取到丰富的环境信息,然后通过深度强化学习模型中的CNN RNN等对环境信息进行处理 抽象和转化,在结合强化学习算法框架预测出最应该执行的动作(是加速 减速 转向等),来实现自动驾驶.当然,无人驾驶汽车每次执行的动作,都会让它到目的地的路程更短,即每次行动都会有相应奖励.
深度强化学习最具有代表性的一个里程碑是AlphaGo,围棋是棋类游戏中最复杂的游戏,19*19的棋盘给它带来了3361种状态,这个数量级别已经超过了宇宙中原子数目的状态数.因此,计算机是无法通过像IBM深蓝那样暴力搜索来战胜人类,就必须给计算机抽象思维的能力,而AlphaGo做到了这一点.
如下图所示,强化学习目标是构建一个系统Agent,在于环境Environment交互过程中提高系统的性能.环境的当前状态信息中通常包含一个反馈(Reward)信号和行为State.Agent通过与环境Environment交互,Agent可以通过强化学习来得到一系列行为,通过探索性的试错或借助精心设计的激励系统使得正向反馈最大化.
Agent可以根据棋盘上的当前局势(环境)决定落子的位置,而游戏结束时胜负的判定可以作为激励信号.如下图:
根据正负反馈修正model(agent智能体) 
迁移学习
 
 解决模型的适应性问题
 迁移学习是为了解决模型适应性问题
 1-在具有相似或相关联业务的场景下,一个场景下数据量大,一个场景下数据量比较小,可以先使用数据量大的场景先进行建模,在将模型迁移到数据量小的业务场景中
 2-通用的用户使用手机习惯的模型迁移到个性化的数据上面. 
深度学习
人脸识别图像识别
解决特征提取的问题
     提取图像中的数据 提取语音信号的中的数据
强化迁移深度学习
   强化学习-----解决连续决策问题
   迁移学习-----解决模型适应性问题
   深度学习---解决特征提取问题
总结
除了上述学习方式,还有深度学习 迁移学习等学习方式,一般深度学提取特征 强化学习解决连续决策,迁移学习解决模型适应性问题.

下面对迁移学习能解决那些问题? 

小数据的问题.比方说新开一个网店,卖一种新的糕点,没有任何的数据,就无法建立模型对用 户进行推荐.但用户买一个东西会反映到用户可能还会买另外一个东西,所以如果知道用户在另 外一个领域,比方说卖饮料,已经有了很多很多的数据,利用这些数据建一个模型,结合用户买 饮料的习惯和买糕点的习惯的关联,就可以把饮料的推荐模型给成功地迁移到糕点的领域,这样, 在数据不多的情况下可以成功推荐一些用户可能喜欢的糕点.这个例子就说明,有两个领域,一 个领域已经有很多的数据,能成功地建一个模型,有一个领域数据不多,但是和前面那个领域是 关联的,就可以把那个模型给迁移过来. 


个性化的问题.比如每个人都希望自己的手机能够记住一些习惯,这样不用每次都去设定它,怎么才能让手机记住这一点呢?其实可以通过迁移学习把一个通用的用户使用手机的模型迁移到个性化的数据上面. 

最后总结机器学习分类:

利用HIve或SparkSQL利用SQL完成样本和特征数据的抽取
->准备数据ETL->特征工程->准备算法->训练模型->模型校验->模型保存->模型在新数据预测
训练模型 算法结合数据训练模型
机器学习三要素 模型 算法 策略
统计学习=模型+策略+算法
模型:规律y=ax+b
策略:什么样的模型是好的模型?损失函数
算法:如何高效找到最优参数,模型中的参数a和b

way1:数据+算法+策略
way2:模型+算法+策略
    模型
        预测函数
            仅仅给出预测的值
        条件概率分布函数
            除了给出预测值
            给出预测值的概率
    算法
        解析解
            传统的解法
        最优解
            梯度下降法
    策略
        损失函数-目标函数-误差函数
            01损失
            绝对值损失
            平方损失
如何构建机器学习系统
    1-准备数据
    2-特征工程
        对数据的处理
            对样本(行)数据进行处理
        对特征的处理
            特征选择
            特征降维
            特征采样
    3-准备算法
        1-根据业务选择算法 联合各部门进行交流整合 从问题角度触发 主动 
业务驱动数据 两方面兼顾
            监督学习
                分类问题
                    准备数据:特征X+标签y
                回归问题
                    准备数据:特征X+标签y
            非监督学习
                聚类
                    准备数据:特征X
        2-根据数据选择算法
            数据中是否具备标签列
                监督学习
                    连续值或离散值的预测
                        分类
                        回归
                无监督学习
                    聚类
                    降维
    4-准备好超参数
        在模型训练之前需要事先指定的参数
            如迭代次数alpha
    5-训练模型
        求解模型中的参数
            如y=kx+b中的k和b
模型预测分析
泛化能力:模型对于新数据或测试数据的适应能力
    体现1:欠拟合
        现象
            训练集和测试集效果都很差
        时机
            训练初期
        原因
            模型太过于简单
        解决
            增加多项式的项
            增加多项式的项的次数
            减少正则罚项
    体现2:过拟合
        现象
            训练集效果很好,但是在测试集效果很差
        时机
            训练中后期
        原因
            模型太过于复杂
            训练数据量太少
            数据不纯
        解决
            增加正则罚项
            重新采样数据
            重新清洗数据
            dropout
    奥卡姆剃刀原则
        在具备相同或相似泛化能力的基础上,优先选择较为简单的模型
        防止模型过拟合的
正则化
    L1
    L2
经验风险和结构风险
    经验风险
        在损失函数的期望的联合概率函数不容易求解的情况下,使用平均损失替代损失函数的期望的最小化
            原因:概率大数定律
        核心:平均损失
    结构风险
        在经验风险的基础上增加了正则罚项
    最佳的模型
        一定是结构风险最小化的点
模型
机器学习中,首先要考虑学习什么样的模型,在监督学习中,如模型y=kx+b就是所要学习的内容.
模型通常分为决策函数或条件概率分布
由决策函数表示的模型为非概率模型,由条件概率分布表示的模型为概率模型.

 决策函数:仅仅给出属于一个类别的值----决策树
 条件概率分布函数:不仅仅给出类别的值,还需要给出概率---LR算法


y given X
算法====>考虑使用哪种方法解决算法的最优解的求解方式
解析解=精确解,没有误差,由等式变形得到
   传统的求解方法,称之为解析解
   求解二次函数的最小值y=ax**2+bx+c(a>0)
     求导
     令导数为0
     求解驻点
     将区间划分为几个区间,根据区间的增减性判断
     二阶导数大于0极小值,二阶导数小于0极大值
     最大值:对比极大值和端点处的值
最优解
(最优化的数值解    数值解=有误差的解,通常由简化的操作,简化的步骤,对过程做近视处理得到)
   计算机中求解方法是借用----二分法
   梯度下降法解决
人与计算机解方程区别

机器学习中利用牛顿法和梯度下降法求解最优解(泰勒展开式)


机器学习的算法就是求解最优化问题的算法.如果最优化问题有显示的解析解,这个最优化问题就比较简单,但通常这个解析解不存在,所以就需要利用数值计算的方法来求解.机器学习可以利用已有的最优化算法,也可以开发独自的最优化算法.
策略
 损失函数---误差函数---目标函数
 绝对值损失---回归 分类
 平方损失----回归
 01损失 分类问题 预测对1 预测错0

评价模型的好坏,使用损失函数进行度量,模型给出的值与实际真实值存在的差别.
损失函数度量模型一次预测的好坏,常用的损失函数有:

统计学习=模型+策略+算法
模型:规律y=ax+b
策略:什么样的模型是好的模型?损失函数
算法:如何高效找到最优参数,模型中的参数a和b
构建机器学习模型
我们使用机器学习预测模型的工作流程讲解机器学习系统整套处理过程.

特征工程 处理出算法能够使用的特征
数据来源 数仓 数据湖
算法五大特性:
1.有穷性,在执行有限的步骤之后,自动结束不会出现无限循环并且每一个步骤在可接受的时间内完成
2.确定性,算法的每一个步骤都具有确定的含义,不会出现二义性
3.可行性,算法的每一步都必须是可行的,每一步都能够通过执行有限的次数完成
4.输入,在算法中可以有零个或者多个输入
5.输出,在算法中至少有一个或者多个输出

模型的泛化能力 模型对新数据的准确率高 
如何构建机器学习系统?
 1-准备数据
 2-特征工程 X
   1-对数据进行处理
     样本数据抽样---row
   2-对特征进行处理
     特征选择
     特征降维
     特征抽样
 3-训练模型
   数据+机器学习算法
   参数:机器学习学习的就是模型,实质上学习的是  模型中对应的参数
   超参数:在机器学习模型训练之前事先指定的参数,称之为超参数,如迭代次数alpha
   y=kx+b  指定迭代次数alpha=20  k=5,b=3  y=5x+3  y=4x+6
 4-选择最佳模型
   模型不仅对于训练集效果好,对于测试效果很好==>模型泛化性能好
 5-对新数据进行预测
   模型已经训练好了,能够达到要求

整个过程包括了数据预处理 模型学习 模型验证及模型预测.其中数据预处理包含了对数据的基本处理,包括特征抽取及缩放 特征选择 特征降维和特征抽样;我们将带有类标的原始数据划按照82原则分为训练数据集和测试集.使用训练数据集用于模型学习算法中学习出适合数据集的模型,再用测试数据集用于验证最终得到的模型,将模型得到的类标签和原始数据的类标签进行对比,得到分类的错误率或正确率.
当有新数据来的时候,我们可以代入模型进行预测分类.
注:特征缩放 降维等步骤中所需的参数,只可以从训练数据中获取,并能够应用于测试数据集及新的样本,但仅仅在测试集上对模型进行性能评估或许无法监测模型是否被过度优化(后面模型选择中会提到这个概念).

数据预处理(特征工程)
数据预处理是机器学习应用的必不可少的重要步骤之一,以提到的Iris Dataset为例,将花朵的图像看做原始数据,从中提取有用的特征,其中根据常识我们可以知道这些特征可以是花的颜色 饱和度 色彩 花朵整体长度以及花冠的长度和宽度等.首先了解一下几个数据预处理方法:
(数据归一化与标准化,缺失值处理)大部分机器学习算法为达到性能最优的目的,将属性映射到[0,1]区间,或者使其满足方差为1 均值为0的标准正态分布,从而提取出的特征具有相同的度量标准.
(数据降维)当源数据的某些属性间可能存在较高的关联,存在一定的数据冗余.此时,我们使用机器学习算法中的降维技术将数据压缩到相对低维度的子空间中是非常有用的.数据降维算法不仅可以能够使得所需的存储空间更小,而且还能够使得学习算法运行的更快.
(数据集切分)为了保证算法不仅在训练集上有效,同时还能很好地应用于新数据,我们通常会随机地将数据集划分为训练数据集和测试数据集,使用训练数据集来训练及优化我们的机器学习模型,完成后使用测试数据集对最终模型进行评估.
数据预处理也称作特征工程,所谓的特征工程就是为机器学习算法选择更为合适的特征.当然,数据预处理不仅仅还有上述的三种.
选择预测模型进行模型训练
任何分类算法都有其内在的局限性,如果不对分类任务预先做一些设定,没有任何一个分类模型会比其他模型更有优势.因此在实际的工作处理问题过程中,必不可少的一个环节就是选择不同的几种算法来训练模型,并比较它们的性能,从中选择最优的一个.
(1)如何选择最优的模型呢?我们可以借助一些指标,如分类准确率(测量值和真实值之间的接近程度) 错误率等指标衡量算法性能.
(2)疑问:选择训练模型的时候没有使用测试数据集,却将这些数据应用于最终的模型评估,那么判断究竟哪一个模型会在测试数据集有更好的表现?
针对该问题,我们采用了交叉验证技术,如10折交叉验证,将训练数据集进一步分为了训练子集和测试子集,从而对模型的泛化能力进行评估.
(3)不同机器学习算法的默认参数对于特定类型的任务来说,一般都不是最优的,所以我们在模型训练的过程中会涉及到参数和超参数的调整.
什么是超参数呢?超参数是在模型训练之前已经设定的参数,一般是由人工设定的.
什么是参数呢?参数一般是在模型训练过程中训练得出的参数.
1.9.3模型验证与使用未知数据进行预测
使用训练数据集构建一个模型之后可以采用测试数据集对模型进行测试,预测该模型在未知数据上的表现并对模型的泛化误差进行评估.如果对模型的评估结果表示满意,就可以使用此模型对以后新的未知数据进行预测.(模型评估部分会专门在下节讲解~)
但什么是泛化误差呢?我们带着这个问题分别对模型验证这块涉及到的基础概念做一个深入理解:
[基础概念]通常我们把分类错误的样本数占样本总数的比例称为"错误率(error rate)",如果在m个样本中有a个样本分类错误,则错误率为E=a/m;从另一个角度,1-a/m则称为"分类精度(accurary)",也就是"精度+错误率=1".
我们将模型(或学习器)的实际输出与样本的真实值之间的差异称为"误差(error)",学习器在训练集上的误差称为"训练误差(training error)"或经验误差(empirical error),在新的样本上的误差称为"泛化误差(generalization error)".
我们在模型验证的时候期望得到泛化误差小的学习器.
模型验证与使用未知数据进行预测
使用训练数据集构建一个模型之后可以采用测试数据集对模型进行测试,预测该模型在未知数据上的表现并对模型的泛化误差进行评估.如果对模型的评估结果表示满意,就可以使用此模型对以后新的未知数据进行预测.(模型评估部分会专门在下节讲解~)
但什么是泛化误差呢?我们带着这个问题分别对模型验证这块涉及到的基础概念做一个深入理解:
[基础概念]通常我们把分类错误的样本数占样本总数的比例称为"错误率(error rate)",如果在m个样本中有a个样本分类错误,则错误率为E=a/m;从另一个角度,1-a/m则称为"分类精度(accurary)",也就是"精度+错误率=1".
我们将模型(或学习器)的实际输出与样本的真实值之间的差异称为"误差(error)",学习器在训练集上的误差称为"训练误差(training error)"或经验误差(empirical error),在新的样本上的误差称为"泛化误差(generalization error)".
我们在模型验证的时候期望得到泛化误差小的学习器.

准确率和召回率 F1分数
预测误差(error,ERR)和准确率(accurary,ACC)都提供了误分类样本数量的相关信息.误差可以理解为预测错误样本与所有被预测样本数量量的比值,而准确率计算方法则是正确预测样本的数量与所有被预测样本数量的比值.

对类别数量不均衡的分类问题来说,真正率TPR与假正率FPR是更重要的指标:
,
比如在肿瘤诊断中,我们更为关注是正确检测出的恶性肿瘤,使得病人得到治疗.然而降低良性肿瘤(假负FN)错误被划分为恶性肿瘤,但对患者影响并不大.与FPR相反,真正率提供了有关正确识别出来的恶性肿瘤样本(或相关样本)的有用信息.
由此提出了准确率(persoon,PRE)和召回率(recall,REC),是与真正率 真负率相关的性能评价指标,召回率实际上与真正率含义相同,定义如下:
(真正率是看矩阵的行,即实际情况)

准确率(模型的预测情况,看矩阵的列)定义:

实际中,常采用准确率与召回率的组合,称为F1-Score

Khold评估模型性能
验证模型准确率是非常重要的内容,我们可以将数据手工切分成两份,一份做训练,一份做测试,这种方法也叫"留一法"交叉验证.这种方法很有局限,因为只对数据进行一次测试,并不一定能代表模型的真实准确率.因为模型的准确率和数据的切分是有关系的,在数据量不大的情况下,影响比较大.因此我们提出了K折交叉验证,K-Fold交叉验证.
K-Fold交叉验证,将数据随机且均匀地分成k分,常用的k为10,数据预先分好并保持不动.假设每份数据的标号为0-9,第一次使用标号为0-8的共9份数据来做训练,而使用标号为9的这一份数据来进行测试,得到一个准确率.第二次使用标记为1-9的共9份数据进行训练,而使用标号为0的这份数据进行测试,得到第二个准确率,以此类推,每次使用9份数据作为训练,而使用剩下的一份数据进行测试,这样共进行10次,最后模型的准确率为10次准确率的平均值.这样就避免了数据划分而造成的评估不准确的问题.
模型选择
一个模型可能有很多种情况出现,那么我们如何选择最优的模型呢?
那条曲线拟合效果是最好的?


欠拟合
过拟合 

  欠拟合的现象
     模型在训练数据集和测试数据集的效果都很差
   欠拟合的发生的时间:
     模型训练的初期
   欠拟合发生的原因?
     模型太过于简单
       y=t 或 y=-2x+3
   如何解决欠拟合的问题?
     增加多项式的特征
       预测房价---面积,增加位置+房屋数量等
       y=k1x1+b===》y=k1xk2x2+b1
     增加多项式的项的次数
       y=k1x1+b===》y=k1*x1**2+k2*x+b
     减少正则罚项===>模型太过于简单

   过拟合的现象
     模型在训练集上的效果很好,但是对于新数据或测试数据效果很差
   过拟合的发生时期:
     模型训练的中后期
   过拟合的发生的原因:
     模型太过于复杂+训练数据量太少+数据不纯
   过拟合的解决办法:
     1-增加正则罚项===>模型太过于复杂
     2-重新采样训练数据
     3-重新清洗数据
     4-dropout方法--随机丢弃一些样本数据

观察上述图示:
利用已知的样本点在图示的坐标轴上画出了绿色的曲线,表示源数据的大致分布状况.假设我们使用后面要学习的线性回归去解决样本点拟合问题, 比如用多项式表示线性回归模型:,当n=0时,y=k,就是图一的平行于x轴的直线,此时该直线不能很好的拟合样本数据;当n=1时,y=kx+B,得到图2的一次直线,我们可以注意到无论怎么调整该直线都不能很好的拟合样本数据;上述n=0或1时是模型的欠拟合情况.当n=3时,,得到图3的三次函数拟合曲线,这种情况是能够很好的拟合样本数据;但是,当n=9时,得到图4的拟合曲线.当n取值越高的时候,当前样本的数据能够很好的拟合,但是在新的数据上效果却很差,这时出现了过拟合情况.
通过上述图大家应该能看到,即便我们确定了使用线性回归模型去处理,我们在选择参数的时候也是有很多种情况.如,可以调整不同的k1 k2和k3的值,同时也对应了不同的拟合直线,我们希望可以从这些参数中找到拟合较好的直线,但不能过分的好,因为我们要考虑当新数据来了模型的分类情况.
由此我们引入了模型的"泛化"能力的概念.
泛化
机器学习的目标是使学得的模型能很好地适用于"新样本",而不是仅仅在训练样本上工作的很好;即便对聚类这样的无监督学习任务,我们也希望学得的簇划分能适用于没在训练集中出现的样本.学得模型适用于新样本的能力,称为"泛化"(generalization)能力.具有强泛化能力的模型能很好地适用于整个样本空间.(现实任务中的样本空间的规模通常很大,如20 个属性,每个属性有10个可能取值,则样本空间的规模是1020).
还有一个泛化的概念:
[基础概念]模型具有好的泛化能力指的是:模型不但在训练数据集上表现的效果很好,对于新数据的适应能力也有很好的效果.
当我们讨论一个机器学习模型学习能力和泛化能力的好坏时,我们通常使用过拟合和欠拟合的概念,过拟合和欠拟合也是机器学习算法表现差的两大原因.
[基础概念]过拟合overfitting:模型在训练数据上表现良好,在未知数据或者测试集上表现差.
[基础概念]欠拟合underfitting:在训练数据和未知数据上表现都很差.
1.10.3欠拟合

图1和图2都是模型欠拟合的情况:即模型在训练集上表现的效果差,没有充分利用数据,预测准确率很低,拟合结果严重不符合预期.
产生的原因:模型过于简单
出现的场景:欠拟合一般出现在机器学习模型刚刚训练的时候,也就是说一开始我们的模型往往是欠拟合也正是因为如此才有了优化的空间,我们通过不断优化调整算法来使得模型的表达能力更强.
解决办法:(1)添加其他特征项:因为特征项不够而导致欠拟合,可以添加其他特征项来很好的解决.
添加多项式特征,如图(3)我们可以在线性模型中通过添加二次或三次项使得模型的泛化能力更强.
减少正则化参数,正则化的目的是用来防止过拟合的,但是现在模型出现了欠拟合,需要减少正则化参数.
过拟合

上图是模型过拟合的情况:即模型在训练集上表现的很好,但是在测试集上效果却很差.也就是说,在已知的数据集合中非常好,再添加一些新数据进来效果就会差很多.
产生的原因:可能是模型太过于复杂 数据不纯 训练数据太少等造成.
出现的场景:当模型优化到一定程度,就会出现过拟合的情况.
解决办法:(1)重新清洗数据:导致过拟合一个原因可能是数据不纯导致的,
增大训练的数据量:导致过拟合的另一个原因是训练数据量太小,训练数据占总数据比例太低.
采用正则化方法对参数施加惩罚:导致过拟合的原因可能是模型太过于复杂,我们可以对比较重要的特征增加其权重,而不重要的特征降低其权重的方法.常用的有L1正则和L2正则,我们稍后会提到.
采用dropout方法,即采用随机采样的方法训练模型,常用于神经网络算法中.
注意:模型的过拟合是无法彻底避免的,我们能做的只是缓解,或者说减小其风险,因为机器学习面临的是NP难问题(这列问题不存在有效精确解,必须寻求这类问题的有效近似算法求解),但是有效算法必然是在多项式时间内运行完成的,因此过拟合是不可避免的.在实际的任务中往往通过多种算法的选择,甚至对同一个算法,当使用不同参数配置时,也会产生不同的模型.那么,我们也就面临究竟选择哪一种算法,使用哪一种参数配置?这就是我们在机器学习中的"模型选择(model select)"问题,理想的解决方案当然是对候选模型的泛化误差进行评估,然后选择泛化误差最小的那个模型.我们更详细的模型选择会有专门的专题讲到,如具体的评估方法(交叉验证) 性能度量准则 偏差和方差折中等.
补充:NP难问题
NP是指非确定性多项式(non-deterministic polynomial,缩写NP).所谓的非确定性是指,可用一定数量的运算去解决多项式时间内可解决的问题.
例如,著名的推销员旅行问题(Travel Saleman Problem or TSP):假设一个推销员需要从香港出发,经过广州,北京,上海,…,等 n 个城市, 最后返回香港.任意两个城市之间都有飞机直达,但票价不等.假设公司只给报销 C 元钱,问是否存在一个行程安排,使得他能遍历所有城市,而且总的路费小于 C?
推销员旅行问题显然是 NP 的.因为如果你任意给出一个行程安排,可以很容易算出旅行总开销.但是,要想知道一条总路费小于 C 的行程是否存在,在最坏情况下,必须检查所有可能的旅行安排! 这将是个天文数字.
迄今为止,这类问题中没有一个找到有效算法.倾向于接受NP完全问题(NP-Complet或NPC)和NP难题(NP-Hard或NPH)不存在有效算法这一猜想,认为这类问题的大型实例不能用精确算法求解,必须寻求这类问题的有效的近似算法.
1.10.5奥卡姆剃刀原则
两个模型泛化率差不多(准确率和误差率) 一个模型简单 一个模型复杂 选择简单的模型 因为简单的模型可以防止过拟合
奥卡姆剃刀原则是模型选择的基本而且重要的原则.
模型是越复杂,出现过拟合的几率就越高,因此,我们更喜欢采用较为简单的模型.这种策略与应用就是一直说的奥卡姆剃刀(Occam’s razor)或节俭原则(principe of parsimony)一致.
奥卡姆剃刀:给定两个具有相同泛化误差的模型,较简单的模型比较复杂的模型更可取.

遵循的原则分配
 奥卡姆剃刀原则
   在具备相同或相似泛化能力的基础上,优先选择较为简单的模型
   本质含义:防止模型过拟合
 防火防盗防过拟合

欠拟合很容易就会发现 但是过拟合比较难发现 因为在训练集上表现得很好

 训练集30%     测试集25%-----欠拟合的解决办法
 训练集80%    测试集78%------轻微的过拟合
 训练集80%    测试集60%------明显(严重)的过拟合
经验风险与结构风险
策略部分:


模型的经验风险和结构风险

 评价一个模型?
   模型泛化能力好 
 模型的损失函数(目标函数-误差函数)越小越好
   求解平方损失或绝对值损失的误差和
   一个样本有预测值和真实值y-y_pred
   总的损失sum(yi-y_predi)
   平均损失{sum(yi-y_predi)}/N,其中N为样本的数量
 1-求解损失函数越小越好===>损失函数的期望===>利用连续型随机变量的期望求解===>
 E(L(Y,f(X))),f(X)表示的是预测值,Y是真实值 L Loss损失,损失的期望E( Loss),该期望通过 连续的二重积分实现:
损失函数期望越小越好
P(x,y)是联合概率分布,在求解的时候是不容易求解的,希望能找到近似求解方法求解损失函数的期望和期望最小化 
经验风险 就是平均损失 就是为了解决联合概率P(x,y)不好求解的时候,利用经验风险去解决损失的问题
模型f(x)关于训练数据集的平均损失称之为经验风险(emprical risk)或经验损失(empirical loss),记作R(emp)
Loss的和/N就是平均损失

平均损失替代求解

期望风险R(emp)是模型关于联合分布的期望损失,经验风险R(emp)是模型关于训练样本集的平均损失.根据大数定律,当样本容量N趋于无穷时,经验风险R(emp)趋于期望风险R(exp),所以一个很自然的想法就是利用经验风险估计期望风险.但是,由于现实中训练样本数目有限甚至很小,所以用经验风险估计期望风险常常不理想,要对经验风险进行一定的矫正,这就是关系到监督学习的两个基本策略:经验风险最小化和结构风险最小化.
经验风险最小化
在损失函数以及训练数据集确定的情况下,经验风险函数式就可以确定,经验风险最小化(emprical risk minimization,EMR)的策略认为,经验风险最小的模型是最优模型.


当样本容量足够大的时候,经验风险最小化能保证有很好的学习效果,在现实中被广泛应用,比如,极大似然估计(maximum likelihood estimation)就是经验风险最小化的一个例子,当模型是条件概率分布,损失函数是对数损失函数时,经验风险最小化就等价于极大似然估计.
结构风险
经验风险求解的方法及其容易产生过拟合的现象,在经验风险的基础上增加正则罚项
但是,当样本容量很小时,经验风险最小化的学习的效果就未必很好,会产生"过拟合"现象.
结构风险最小化(structural risk minimization,SMR)是为了防止过拟合而提出来的策略.结构风险在经验风险基础上加上表示模型复杂度的正则化项(regularizer)或罚项(penalty term).在假设空间,损失函数以及训练数据集确定的情况下,结构风险的定义是:

其中J(f)为模型的复杂度,是定义在假设空间F上的泛函,模型f越复杂.
结构风险最小化
复杂度J(f)就越大;反之,模型f就越简单,复杂度J(f)就越小,也就是说,复杂度表示对复杂模型的惩罚,lambda>=0是系数,是用以权衡经验风险和模型复杂度,结构风险小需要经验风险与模型复杂度同时小,结构风险小的模型往往对训练数据以及未知的测试数据都有较好的预测.
 

模型评估和模型选择
当损失函数给定时,基于损失函数的模型的训练误差和模型的测试误差就自然成为了学习方法评估的标准.

 
模型风险就是过拟合风险
正则化
模型选择的典型方法是正则化,正则化一般形式如下:

f(xi;w)=w0x0+w1x1+w2x2
通过置w1=0,稀疏化x1特征
使模型变得简单
经验风险较小的模型可能较复杂,这时正则化项的值会较大,正则化的作用是选择经验风险与模型复杂度同时较小的模型.
正则化项符合奥卡姆剃刀原理,在所有的可能的模型中,能够很好的解析已知数据并且十分简单的模型才是最好的模型,从贝叶斯估计的角度来看,正则化项对应于模型的先验概率,可以假设复杂的模型有较小的先验概率,简单的模型有较大的先验概率.
交叉验证
 处理数据集的划分方法
 1-简单交叉验证
   将数据集划分为训练集和测试集
   训练集:测试集=8:2
   一般在模型训练阶段使用训练集和测试集划分方法,K则切分比较麻烦
 2-K则交叉验证
   K=10或5
   好处:每一份数据都有机会成为训练集和测试集,避免在训练模型的时候因为数据带来的影响
   用途:在选择超参数(提前设置的参数)的时候
3-留一验证[用的不多]
 特殊的K则交叉验证
 K=1的时候,就是留一验证,每次只拿一个样本进行预测,其余的样本进行训练
训练时间太久 用的不多

在机器学习中常用的精度测试方法,叫做交叉验证.它的目的是得到可靠稳定的模型,具体的做法是拿出大部分数据进行建模,留小部分样本用刚刚建立的模型进行预测,并求出这小部分样本预测的误差,交叉验证在克服过拟合问题上非常有效.接下来分别阐述:
简单交叉验证 训练模型
简单交叉验证的方法是这样的,随机从最初的样本中选择部分,形成验证数据,而剩下的当作训练数据.一般来说,少于三分之一的数据被选作验证 数据. 
K则交叉验证 超参数选择
10折交叉验证是把样本数据分成10份,轮流将其中9份做训练数据, 
将剩下的1份当测试数据,10次结果的均值作为对算法精度的估计,通常情况下为了提高精度,还需要做多次10折交叉验证. 
更进一步,还有K折交叉验证,10折交叉验证是它的特殊情况.K 折交叉验证就是把样本分为K份,其中K-1份用来做训练建立模型,留剩下的一份来验证,交叉验证重复K次,每个子样本验证一次. 

10则交叉验证
E是model 数据的依赖性降低
留一验证
留一验证只使用样本数据中的一项当作验证数据,而剩下的全作为训练数据,一直重复,直到所有的样本都作验证数据一次.可以看出留 一验证实际上就是K折交叉验证,只不过这里的K有点特殊,K为样本数 据个数. 


为什么现在是进入机器学习领域最佳时机?
现如今有很多的成熟的算法库
   如Python的Sklearn Tensorflow Pytorch
   以下为Sklearn
cala的SparkMLlib

Go Golearn
R SparkR
矩阵的每一行是行向量 列是列向量
  如Java的dl4j
   如R语言sparkR
 不同于传统的方式
   自己实现算法+自己处理数据
 现如今
   使用已经现有的算法库,而将更多的经历放在对数据的认知 处理 整合上面
机器学习库基础
借助于近些年发展起来诸多强大的开源库,我们现在是进入机器学习领域的最佳时机.不用像前些年那样需要自己使用编程语言一步一步实现机器学习算法,而是使用成熟的机器学习库帮我完成做好的算法,我们只需要了解清楚各个模型的参数如何调整就能够将模型应用于实际的业务场景.
基于Python的Sklearn库
简单高效的数据挖掘和数据分析工具
可供大家使用,可在各种环境中重复使用
建立在NumPy,SciPy和matplotlib上
开源,可商业使用-获取BSD许可证

基于Scala的SparkMLLIB


R与SparkR

鸢尾花(Iris)
大数据笔记\image\机器学习\图解Iris-机器学习基础概念.png
 掌握机器学习和大数据的区别和联系
   大数据做的是数据存储和数据统计分析
   而如果从大量的数据中发现或挖掘出有价值的数据,需要结合机器学习算法,构建模型,通过模型实现预测而分析
 大数据的项目中机器学习的位置或架构
   机器学习位于大数据处理之后,Web展示之前做的事情
 掌握机器学习 深度学习 人工智能概念的区别和联系
   机器学习是人工智能的一个分支
   而深度学习是机器学习的一种实现方法,是为了解决在图像识别或语音识别方面的不足而提出的
 机器学习的数据集的构成(重点)
   数据集的名称
   数据集的行列的表示
   数据集的数据切分
   训练集训练模型
   测试集测试模型
   非数值型数据的数据化处理 
   模型的校验===损失函数 目标函数 误差函数
 机器学习的分类问题
   根据是否具备类别标签列
     监督学习
       根据是否具备连续预测的标签
         回归问题-----房价预测
         分类问题-----邮件分类
     非监督学习
       聚类------西瓜数据集的聚类
       降维----区别于特征选择
     半监督学习
       根据聚类的假设
     强化学习
       解决的是连续决策问题
     迁移学习
       解决模型的适应性问题
     深度学习
       解决图像或语音等方面特征提取的问题
 机器学习的三要素
   数据+算法+策略
   模型+算法+策略
     模型
       预测函数====直接输出值
       类条件分布函数=----输出概率+输出值
     算法
       解析解
       最优解
         梯度下降法
     策略
       损失函数目标函数误差函数
       01损失
       绝对值损失
       平方损失
 如何构建机器学习的系统?
   准备数据
   特征工程
   训练模型
   模型预测分析
   模型校验分析
 如何评价机器学习系统的性能?
   模型的泛化能力好:
     欠拟合:
       模型在训练数据和测试数据都很差
     过拟合
       模型在训练数据很好,但是在测试数据上效果很差
   奥卡姆剃刀原则
     在具有相同泛化误差的情况下,优先选择较为简单的模型
 成熟的机器学习库?
   基于scala的SparkMlib
     矩阵
   Python的sklearn

 SparkMllib是大规模机器学习库
  
 特性1:易用
   Numpy-----基于Python的矩阵运算库-----基于Python和sparkmllib进行交互
   R libaray-----基于R语言连接Spark-----SparkR
 特征2:那些算法
   分类 聚类 降维 推荐 关联规则 主题模型(NLP)
   SparkMllib五大特性:

 1-ML算法,包含-机器学习分类 回归 聚类 属性降维算法(pca) 协同过滤算法
 2-特征化:没有好的特征就没有好的model 工作重点
特征抽取(主要针对非结构化数据(文本,视频,图片)将特征量化进行结构化数据的抽取,比如美女图片量化成美的量纲) 
SparkMLLib中仅仅提供抽取文本 
特征转换 特征组合即是特征向量
类别型特征 数值化
labelencoder    Spark中StringIndexer实现 String转index指标 原始数据有顺序 IndexToString反转
onehotencoder Spark中OneHotEncoder实现 原始数据没有顺序 例如男女 男女平等
数值型特征 
归一化 01 -11 不同量纲很难让model达标 KMeans,KNN算法 降低因为量纲对模型的影响
MinMaxScaler (当前的值-最小值)/(最大值-最小值)        将数据归一化到[0,1]
MaxAbsScaler (当前的值)/max(abs(这一列元素取值))        将数据归一化到[-1,1]
标准化 某些算法需要数据呈现标准正态分布 加快收敛速度
StandScaler (当前的值-均值)/标准差  适合正太分布转化为标准正太分布的数据 均值为0方差为1
连续值特征 离散化  因为连续型数据不符合某些算法要求 例如决策树
Binarizer 二值化
Bucketizer 分桶 按照指定规则分割
特征选择 
df.select() 
算法 针对 向量 矩阵
卡方验证选择和标签列最相关的特征 减少一些价值小贡献小的特征 求证思想 假设检验 用label验feature
独立性检验 特征对标签的独立性很高则可以被淘汰
numTopFeatures 数量抽取 重点
percentile 比例
fpr 显著性水平界限 低的被淘汰
特征组合
val assembler:VectorAssembler 
= new VectorAssembler().setInputCols(frame7.columns.filter(!_.equals("category1")).filter(!_.equals("before"))).setOutputCol("next3")
val frame8:DataFrame 
= assembler.transform(frame7)
因为只有向量和矩阵才能使用机器学习算法 
特征降维 PCA 主成分分析法 利用特征值和特征向量选择具有较高特征值对应的特征向量进行降维
3-管道Pipeline:将流程按照管道串联
管道Pipline的五大属性
DataFrame 数据集上才能实现管道
Estimate 需要先fit形成model再transform的方法
Transformer 需要通过transformm转换
Pipline管道 将数据各个流程串联起来
Param 超参数
 4-持久化Persistence:保存读取model,管道
   如何理解保存模型?
     原因就是不可能每次都去训练模型,
     而将已经训练好的模型进行保存,保存在本地或hdfs中,在本地或hdfs中加载已经训练好点模型,直接可以做预测分析
 5-工具:包括线性代数 统计学 数据处理科学


决策树算法 KMeans聚类算法
改进算法 随机森林算法 层次KMeans算法

Spark各种数据抽象
   SparkCore数据抽象-----RDD
   SparkSQL数据抽象-----DataFrame和DataSet
   SparkStreaming批处理框架-----DStream
   StructedStreming实时流处理-----DataFrame和Dataset
   SparkMllib
     DataFrame的结构 
       spark.ml
     RDD的结构 
       spark.mllib
     版本的改进:
       1-spark2.3之后基于rdd的api可能不会在使用
       2-spark3.0基本基于rdd的api会removed
     为什么需要从rdd转变成dataframe?
       1-Dataframe的Api是比较友好的,提供udf udaf udtf,dsl,sql查询 基于统一的数据源 Tungsten 和catalyst的sql优化
       2-DataFrame提供多种语言的统一的API接口
       3-DataFrame使用Pipeline完成特征feature转换的操作
 依赖项:
   Breeze----基于netlib-java的矩阵的运算库-----基于python的Numpy或R的library

为什么选择DF的API
SparkSQL提供多种数据源 SQL查询 优化器等优势
SparkSQL提供多语言统一的API
SparkSQL可以使用ML管道操作
SparkMLlib架构
基于Netlib-java上的Breeze库实现的Vector的向量接口
基于向量接口实现的矩阵接口
基于矩阵接口完成机器学习算法以及算法指标的分析

linalg=linear(线性)+algebra(代数)
import org.apache.spark.mllib.linalg.{Matrix,Vectors}
matrix 矩阵
vectors 向量
0维 标量 7
1维 向量 (1,2,3)
2维 矩阵 [[1,2],[3,4]] 2*2矩阵 黑白图像
3维 多维数组 彩色图像rgb三原色

梯度下降法 算法最优解 


Spark1.3引入DataFrame
spark 1.6又引入了DataSet

Functional
Programming
Type-safe

Relational Object/DataSet Relational Mapping(对象/数据集关系映射)
Catalyst query optimization(优化)
Tungsten direct/packed RAM
JIT code generation(生成)
Sorting/shuffling without
Deserializing
执行时JIT会把翻译过的机器码保存起来,已备下次使用

Distribute collection of JVM objects
Functional Operators(map, filter,etc)
分发JVM对象的集合
功能性操作员

Distribute collection of Row objects
Expression-based operations and UDFs
Logical plans and optimizer 
Fast/efficient internal 
分发Row对象的集合
基于表达式的操作和UDF
逻辑计划和优化器
内部快速/高效

Internally rows,externally JVM objects
Almost the "Best of both worlds"
type safe+ fast
But slower 
内部行,外部JVM对象
几乎是“两全其美”;
类型安全快速
但比DF慢
rdd的优点:
1.强大,内置很多函数操作,group,map,filter等,方便处理结构化或非结构化数据
2.面向对象编程,直接存储的java对象,类型转化也安全
rdd的缺点:
1.由于它基本和hadoop一样万能的,因此没有针对特殊场景的优化,比如对于结构化数据处理相对于sql来比非常麻烦
2.默认采用的是java序列号方式,序列化结果比较大,而且数据存储在java堆内存中,导致gc比较频繁
dataframe的优点:
1.结构化数据处理非常方便,支持Avro, CSV, elastic search, and Cassandra等kv数据,也支持HIVE tables, MySQL等传统数据表
2.有针对性的优化,由于数据结构元信息spark已经保存,序列化时不需要带上元信息,大大的减少了序列化大小,而且数据保存在堆外内存中,减少了gc次数.
3.hive兼容,支持hql,udf等
dataframe的缺点:
1.编译时不能类型转化安全检查,运行时才能确定是否有问题
2.对于对象支持不友好,rdd内部数据直接以java对象存储,dataframe内存存储的是row对象而不能是自定义对象
dataset的优点:
1.dataset整合了rdd和dataframe的优点,支持结构化和非结构化数据
2.和rdd一样,支持自定义对象存储
3.和dataframe一样,支持结构化数据的sql查询
4.采用堆外内存存储,gc友好
5.类型转化安全,代码友好
6.官方建议使用dataset


RDD[Person]
以 Person 为类型参数,但不了解其内部结构.
DataFrame
提供了详细的结构信息 schema列的名称和类型.这样看起来就像一张表了 
DataSet[Person] 
不光有 schema 信息,还有类型信息

SparkMllib的数据类型 
linalg=linear(线性)+algebra(代数)
向量or 矩阵 虽然基于DataFrame和RDD但是最核心的数据结构是向量和矩阵
 feature 特征
1-本地向量local vector
(1)稀疏型数据集sparse
(2)密集型数据集dense
 一组向量数据(1,2,3,0,0,0,1)
 dense 稠密性向量 :(1,2,3,0,0,0,1)
 sparse 稀疏性向量 (7一共有几个数,Array(0,1,2,6)非0值的下标,Array(1,2,3,1)非0值的元素)
大数据笔记\code\MLlib_dense_and_sparse.scala
package MLLIB.C04

import org.apache.spark.mllib.linalg.{Vector, Vectors}

object LocalVector {
  def main(args:Array[String]) {
    val vd:Vector = Vectors.dense(2, 0, 6) //建立密集向量
    println(vd(2)) //打印稀疏向量第3个值
    val vs:Vector = Vectors.sparse(4, Array(0, 1, 2, 3), Array(9, 5, 2, 7)) //建立稀疏向量
    //第一个参数4代表输入数据的大小,一般要求大于等于输入的数据值,第二个参数是数据下标,第三个参数是数据值
    println(vs(2)) //打印稀疏向量第3个值
    //通过指定其非零条目来创建稀疏向量(1.0,0.0,3.0)
    val sv2:Vector = Vectors.sparse(3, Seq((0, 1.0), (2, 3.0)))
    println(sv2(0))
  }
}


labeledpoint 标签向量
LaebledPoint是建立向量标签的静态类,主要有两个方法
   (1)Features用于显示打印标记点所代表的数据内容
   (2)而label用于显示标记数
大数据笔记\code\MLlib_Labeled_Point.scala
import org.apache.spark.mllib.linalg.{Vector, Vectors}
import org.apache.spark.mllib.regression.LabeledPoint

object testLabeledPoint {
  def main(args:Array[String]) {
    val vd:Vector =  Vectors.dense(2, 0, 6)                 //建立密集向量
    val pos = LabeledPoint(1, vd)                         //对密集向量建立标记点
    println(pos.features)                               //打印标记点内容数据
    println(pos.label)                                  //打印既定标记
val vs:Vector = Vectors.sparse(4, Array(0,1,2,3), Array(9,5,2,7))      //建立稀疏向量
    val neg = LabeledPoint(2, vs)                           //对密集向量建立标记点
    println(neg.features)                                //打印标记点内容数据
    println(neg.label)                                  //打印既定标记
  }
}

libsvm数据格式
 台湾大学老师发明的数据格式,最早用于svm模型中,用于稀疏矩阵的存储
 label,index1:features index:features2
 标签,特征列的索引 特征数值,特征列的索引2 特征数值
  2 1:5 2:8 3:9(索引从1开始,从0开始会报错)
  1 1:7 2:6 3:7
  1 1:3 2:2 3:1
大数据笔记\code\LibSvmFileRead.scala
package MLLIB.C04
import org.apache.spark._
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.rdd.RDD

object LabeledPoint2Test {
  def main(args:Array[String]) {
    val conf = new SparkConf().setMaster("local").setAppName("testLabeledPoint2") //建立本地环境变量
    val sc = new SparkContext(conf) //建立Spark处理
    val mu:RDD[LabeledPoint] = MLUtils.loadLibSVMFile(sc, "D://a.txt") //读取文件
    mu.foreach(println) //打印内容(1.0,(3,[0,1,2],[2.0,3.0,5.0]))
  }
}
通过SaprkSql方式读取libsvm数据
大数据笔记\code\LibSvmFileSQLLoader.scala


local matrix本地矩阵
 按照列式的方式存储
 更多的场景下使用向量构建矩阵
大数据笔记\code\SparkMllibLocalmatrix.scala

/**
  * Created by zhao-chj on 2017/8/3.
  * 局部矩阵具有整数类型的行和列索引和双类型值,存储在单个机器上.
  * MLlib支持密集矩阵,其入口值以列主序列存储在单个双阵列中,稀疏矩阵的
  * 非零入口值以列主要顺序存储在压缩稀疏列(CSC)格式中. 例如,以下密集矩阵
  *
  * 局部矩阵的基类是Matrix,
  * 我们提供了两个实现 DenseMatrix和SparseMatrix. 我们建议使用Matrices中实现的工厂方法来创建本地矩阵.
  * 记住,MLlib中的局部矩阵以列主要顺序存储.
  */
object LocalMatrix {
  def main(args:Array[String]) {
    import org.apache.spark.mllib.linalg.{Matrix, Matrices}

    // Create a dense matrix ((1.0, 2.0), (3.0, 4.0), (5.0, 6.0))
    val dm:Matrix = Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))
    println(dm(2,0))
    // Create a sparse matrix ((9.0, 0.0), (0.0, 8.0), (0.0, 6.0))
    val sm:Matrix = Matrices.sparse(3, 2, Array(0, 1, 3), Array(0, 2, 1), Array(9, 6, 8))
    println(dm(2,1))
  }
}


分布式矩阵就是在原来本地矩阵的基础上增加了分布式特性
行矩阵(RowMatrix)
   在原来的矩阵的基础上增加了分布式特性
大数据笔记\code\SparkMllibRowMatrix.scala
package MLLIB.C04

import org.apache.spark._
import org.apache.spark.mllib.linalg.{Vector, Vectors}
import org.apache.spark.mllib.linalg.distributed.RowMatrix
//行矩阵是一个面向行的分布式矩阵,行索引是没有具体含义的.比如一系列特征向量的一个集合,通过一个RDD来代表所有的行,
//每一个行就是一个本地向量.
object RowMatrixTest {
  def main(args:Array[String]) {
    val conf = new SparkConf()                //创建环境变量
    .setMaster("local")                       //设置本地化处理
    .setAppName("testRowMatrix")            //设定名称
    val sc = new SparkContext(conf)            //创建环境变量实例
    val rdd = sc.textFile("D:RowMatrix.txt")                                     //创建RDD文件路径
      .map(_.split(' ')                             //按“ ”分割
      .map(_.toDouble))                         //转成Double类型
      .map(line => Vectors.dense(line))            //转成Vector格式
    val rm = new RowMatrix(rdd)                  //读入行矩阵
    //RowMatrix是一个transform操作,得到的并不是最终的运行结果.
    println(rm.numRows())                    //打印列数
    println(rm.numCols())                     //打印行数
  }
}

行索引矩阵(IndexedRowMatrix)
   在行矩阵的基础上行增加了行的index属性
package MLLIB.C04

import org.apache.spark._
import org.apache.spark.mllib.linalg.distributed.{IndexedRow, RowMatrix, IndexedRowMatrix}
import org.apache.spark.mllib.linalg.{Vector, Vectors}
//行索引矩阵 本质上是含有索引信息的行数据集合,每一行由长整型索引和一个本地向量组成
//行索引矩阵可从一个RDD[indexRow]实例创建,这里的IndexedRow是(Long,Vector)的封装类
//剔除了行索引信息就是一个行矩阵
object IndexedRowMatrixTest {
  def main(args:Array[String]) {
val conf = new SparkConf()                                       //创建环境变量
.setMaster("local")                                               //设置本地化处理
  .setAppName("testIndexedRowMatrix")         //设定名称
       val sc = new SparkContext(conf)                           //创建环境变量实例
    val rdd = sc.textFile( "D://BigData//Workspace//IDEAScala//SparkDemo//src//MLLIB//C04//RowMatrix.txt")                          
//创建RDD文件路径
      .map(_.split(' ')                                             //按“ ”分割
      .map(_.toDouble))                                         //转成Double类型
      .map(line => Vectors.dense(line))                            //转化成向量存储
      .map((vd) => new IndexedRow(vd.size,vd))                      //转化格式
    val irm = new IndexedRowMatrix(rdd)                        //建立索引行矩阵实例
    println(irm.getClass)                                            //打印类型
    println(irm.rows.foreach(println))                                 //打印内容数据
  }
}

  
三元组矩阵(CoordinateMatrix)
在原来的矩阵的基础上增加了行和列的索引
package MLLIB.C04
//三元组矩阵(coordinateMatrix) 是一个分布式矩阵,其实体集合是一个RDD,每一个实体是一个(i:Long,j:Ling,value:Double)三元组
//其中i代表行索引,j代表列索引,value代表实体值
//三元组矩阵常用于表示稀疏性比较高的计算中,是由RDD[MatrixEntry]来构建的.
//MatrixEntry是一个Tuple类型的元素,包含行 列和元素的值
import org.apache.spark._
import org.apache.spark.mllib.linalg.{Vector, Vectors}
import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry}

object CoordinateRowMatrixTest {
  def main(args:Array[String]) {
val conf = new SparkConf()                                       //创建环境变量
.setMaster("local")                                               //设置本地化处理
.setAppName("testCoordinateRowMatrix")        //设定名称
    val sc = new SparkContext(conf)                                  //创建环境变量实例
    val rdd = sc.textFile( "D://BigData//Workspace//IDEAScala//SparkDemo//src//MLLIB//C04//RowMatrix.txt")                          
//创建RDD文件路径
      .map(_.split(' ')                                                //按“ ”分割
      .map(_.toDouble))                                     //转成Double类型
      .map(vue => (vue(0).toLong,vue(1).toLong,vue(2)))           //转化成坐标格式
      .map(vue2 => new MatrixEntry(vue2 _1,vue2 _2,vue2 _3))     //转化成坐标矩阵格式
    val crm = new CoordinateMatrix(rdd)                        //实例化坐标矩阵

    println(crm.entries.foreach(println))                       //打印数据
    println(crm.numRows())//打印行数据
    println(crm.numCols())//打印列数据
  }
}


分块矩阵(BlockMatrix)
分布式的包装

//分块矩阵 BlockMatrix是支持矩阵分块RDD的分布式矩阵,其中矩阵分块由((int,int),matrix)元祖所构成
//(int,int)是该部分矩阵所处的矩阵的索引位置,Matrix表示该索引位置上的子矩阵
//分块矩阵支持矩阵加法和乘法,并设有辅助函数验证用于检查矩阵是否设置正确.
import org.apache.spark._
import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry,BlockMatrix}
import org.apache.spark.storage.StorageLevel

object BlockMatrixTest {
  def main(args:Array[String]) {
val conf = new SparkConf()                                       //创建环境变量
.setMaster("local")                                               //设置本地化处理
.setAppName("testCoordinateRowMatrix")        //设定名称
    val sc = new SparkContext(conf)                         //创建环境变量实例
    val rdd = sc.textFile( "D://BigData//Workspace//IDEAScala//SparkDemo//src//MLLIB//C04//RowMatrix.txt")                          
//创建RDD文件路径
      .map(_.split(' ')                                           //按“ ”分割
      .map(_.toDouble))                                       //转成Double类型
      .map(vue => (vue(0).toLong,vue(1).toLong,vue(2)))           //转化成坐标格式
      .map(vue2 => new MatrixEntry(vue2 _1,vue2 _2,vue2 _3))
    //转化成坐标矩阵格式
    val crm = new CoordinateMatrix(rdd)                      //实例化坐标矩阵
    //使用toBlockMatrix把三元组矩阵转化为分块矩阵
    val matA:BlockMatrix =crm.toBlockMatrix().cache()
    // 对该分块矩阵进行检验,确认该分块是否正确,如果不正确则抛出异常
    //验证BlockMatrix是否正确设置. 当无效时抛出异常.
    // Nothing happens if it is valid.
    matA.validate()
    // Calculate A^T A.
    val ata = matA.transpose.multiply(matA)
   // print(ata.persist(StorageLevel.DISK_ONLY))//因为transpose是trnsform操作不会直接得到结果,调用action算子会得到结果
  }
}

colStats:以列为基础计算统计量的基本数据(summary 总结)

方差是衡量源数据和期望值相差的度量值
方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量
概率论中 方差用来度量随机变量和其数学期望(即均值)之间的偏离程度
统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数
在许多实际问题中,研究方差即偏离程度有着重要意义

中文名        方差    
外文名        variance/deviation Var
类    型    D(X) 数学(统计学)
研究者罗    纳德·费雪(Ronald Fisher)
定    义    数据与平均数之差平方和的平均数
种    类    离散型方差,连续型方差
总体方差计算公式 
a^ = ∑(B-c)^ / D
a^为总体方差,B为变量,c为总体均值,D为总体例数

标准差和方差都是衡量一组数据离散程度的统计量,在实际运算中,
标准差和方差越小,表示离散程度更小,也就是更稳定
标准差和方差越大,表示离散程度更高,也就更有潜力

SparkMllib统计特性

 统计特征 

   均值,方差,非0值的个数....
package sparkmllib_features_day02

import org.apache.spark.mllib.linalg.{Vector, Vectors}
import org.apache.spark.mllib.stat.{MultivariateStatisticalSummary, Statistics}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

/
   DESC:
   Complete data processing and modeling process steps:
  
  /
object testMlSummary {
  def main(args:Array[String]):Unit = {
    val conf = new SparkConf() //创建环境变量
      .setMaster("local") //设置本地化处理
      .setAppName("testSummary")
    //设定名称
    val sc = new SparkContext(conf)
    //创建环境变量实例
    val path = "\BigData\\Workspace\\SparkMachineLearningTest\\SparkMllib_BigDataSH16\\src\\main\\resources\\testSummary.txt"
    val data:RDD[Vector] = sc.textFile(path).map(_.split("").map(_.toDouble)).map(x => Vectors.dense(x))
    data.foreach(println(_))
    val summary:MultivariateStatisticalSummary = Statistics.colStats(data)
    println("non zeros:", summary.numNonzeros)
    println("min value:", summary.min)
    println("max value:", summary.max)
    println("mean value:", summary.mean)
    print("varience value:", summary.variance)
    //    (non zeros:,[5.0])
    //    (min value:,[1.0])
    //    (max value:,[5.0])
    //    (mean value:,[3.0])
    //    (varience value:,[2.5])


    val data1:RDD[Vector] = sc.parallelize(Seq(
      Vectors.dense(1.0, 10.0, 100.0),
      Vectors.dense(2.0, 20.0, 200.0),
      Vectors.dense(3.0, 30.0, 300.0)
    ))
    val summary1:MultivariateStatisticalSummary = Statistics.colStats(data1)
    println("non zeros:", summary1.numNonzeros)
    println("min value:", summary1.min)
    println("max value:", summary1.max)
    println("mean value:", summary1.mean)
    print("varience value:", summary1.variance)
    //    (non zeros:,[3.0,3.0,3.0])
    //    (min value:,[1.0,10.0,100.0])
    //    (max value:,[3.0,30.0,300.0])
    //    (mean value:,[2.0,20.0,200.0])
    //    (varience value:,[1.0,100.0,10000.0])
  }
}
pearson相关系数
pearson相关系数是在cos余弦距离基础上实现的标准化的操作

import org.apache.spark.mllib.linalg.{Matrix, Vector, Vectors}
import org.apache.spark.mllib.stat.{MultivariateStatisticalSummary, Statistics}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

/**
  * DESC:
  * Complete data processing and modeling process steps:
  *
  */
object testMlSummary {
  def main(args:Array[String]):Unit = {
    val conf = new SparkConf() //创建环境变量
      .setMaster("local") //设置本地化处理
      .setAppName("testSummary")
    //设定名称
    val sc = new SparkContext(conf)
    //创建环境变量实例
    val path = "\BigData\\Workspace\\SparkMachineLearningTest\\SparkMllib_BigDataSH16\\src\\main\\resources\\testSummary.txt"
    val data:RDD[Vector] = sc.textFile(path).map(_.split("").map(_.toDouble)).map(x => Vectors.dense(x))
    data.foreach(println(_))
    val summary:MultivariateStatisticalSummary = Statistics.colStats(data)
    println("non zeros:", summary.numNonzeros)
    println("min value:", summary.min)
    println("max value:", summary.max)
    println("mean value:", summary.mean)
    print("varience value:", summary.variance)
    //    (non zeros:,[5.0])
    //    (min value:,[1.0])
    //    (max value:,[5.0])
    //    (mean value:,[3.0])
    //    (varience value:,[2.5])


    val data1:RDD[Vector] = sc.parallelize(Seq(
      Vectors.dense(1.0, 10.0, 100.0),
      Vectors.dense(2.0, 22.0, 204.0),
      Vectors.dense(3.0, 30.0, 300.0)
    ))
    val summary1:MultivariateStatisticalSummary = Statistics.colStats(data1)
    println("non zeros:", summary1.numNonzeros)
    println("min value:", summary1.min)
    println("max value:", summary1.max)
    println("mean value:", summary1.mean)
    print("varience value:", summary1.variance)
    //    (non zeros:,[3.0,3.0,3.0])
    //    (min value:,[1.0,10.0,100.0])
    //    (max value:,[3.0,30.0,300.0])
    //    (mean value:,[2.0,20.0,200.0])
    //    (varience value:,[1.0,100.0,10000.0])
    val seriesX:RDD[Double] = sc.parallelize(Array(1, 2, 3, 3, 5))
    // a series// must have the same number of partitions and cardinality as seriesX
    val seriesY:RDD[Double] = sc.parallelize(Array(11, 22, 33, 33, 555))
    val corr:Double = Statistics.corr(seriesX, seriesY)
    println("corr relatuonship")
    print(corr) //pearson 0.850028
    println("corr matrix")
    val corr1Matrix:Matrix = Statistics.corr(data1) // Pearson correlation matrix comparing columns in X.
    println(corr1Matrix)
    //    1.0  1.0  1.0
    //    1.0  1.0  1.0
    //    1.0  1.0  1.0
  }
}


如果改用Dataframe的结构

import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.ml.stat.Correlation
import org.apache.spark.sql.{DataFrame, SparkSession}

/**
  * DESC:
  * Complete data processing and modeling process steps:
  *
  */
object testMlSummary2 {
  def main(args:Array[String]):Unit = {
    //1-准备环境
    val spark:SparkSession = SparkSession.builder().master("local[*]").appName("testMlSummary2").getOrCreate()
    spark.sparkContext.setLogLevel("WARN")
    import spark.implicits._
    //2-导入数据
    val data = Seq(
      Vectors.sparse(4, Seq((0, 1.0), (3, -2.0))),
      Vectors.dense(4.0, 5.0, 0.0, 3.0),
      Vectors.dense(6.0, 7.0, 0.0, 8.0),
      Vectors.sparse(4, Seq((0, 9.0), (3, 1.0))))
    val df = data.map(Tuple1.apply).toDF("features")
    df.printSchema()
    df.show(false)
    println("ml package corr result is:")
    val df1:DataFrame = Correlation.corr(df, "features", "pearson")
    df1.show(false)
    //    +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    //    |pearson(features)                                                                                                                                                                                                                                                                      |
    //      +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    //    |1.0                   0.055641488407465814  NaN  0.4004714203168137
    //    0.055641488407465814  1.0                   NaN  0.9135958615342522
    //    NaN                   NaN                   1.0  NaN
    //    0.4004714203168137    0.9135958615342522    NaN  1.0

  }
}

import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.ml.stat.Correlation
import org.apache.spark.sql.{DataFrame, SparkSession}
import org.apache.spark.{SparkConf, SparkContext}

/**
 * DESC:这里就是描述如何通过DataFrame完成相关系数统计
 */
object _08SparkMlStatisticSummary {
  def main(args:Array[String]):Unit = {
    val conf:SparkConf = new SparkConf().setMaster("local[*]").setAppName("_08SparkMlStatisticSummary")
    val spark:SparkSession = SparkSession.builder().config(conf).getOrCreate()
    spark.sparkContext.setLogLevel("WARN")
    import spark.implicits._
    val data = Seq(
      Vectors.sparse(4, Seq((0, 1.0), (3, -2.0))),
      Vectors.dense(4.0, 5.0, 0.0, 3.0),
      Vectors.dense(6.0, 7.0, 0.0, 8.0),
      Vectors.sparse(4, Seq((0, 9.0), (3, 1.0)))
    )
    val df = data.map(Tuple1.apply).toDF("features")
    val dfDF:DataFrame = Correlation.corr(df, "features")
    dfDF.show(truncate = false)

    spark.stop()
  }
}

DataSet编译时检查类型
DataFrame运行时检查类型

什么时候用随机数?
1-随机数可以用于随机生成制定分布方式的数据
2-随机数可以用于训练集合测试集的拆分

数据科学领域中,随机数的作用是当没有数据的时候,可以用随机数产生数据,产生符合某种分布方式的随机数,比如获取上海2019年高考成绩,高考成绩符合正太分布,能造一组符合正态分布的随机数

随机数可以用于在机器学习中数据集切分为训练集和测试集


mport org.apache.spark.mllib.linalg
import org.apache.spark.mllib.linalg.{Matrix, Vectors}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.stat.{MultivariateStatisticalSummary, Statistics}
import org.apache.spark.mllib.random.RandomRDDs._

/**
 * DESC:描述本地向量构建思路
 */
object _07SparkMllibVectorSummary extends Serializable {
  def main(args:Array[String]):Unit = {

    val conf:SparkConf = new SparkConf().setMaster("local[*]").setAppName("hero")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")

    val data:RDD[String] = sc.textFile("\demohome\\scalahome\\gswscalademo01\\src\\main\\resources\\test.txt")
    val vectorData:RDD[linalg.Vector] = data.map(_.toDouble).map(x => Vectors.dense(x))
    val summary:MultivariateStatisticalSummary = Statistics.colStats(vectorData)

    println("min value is:", summary.min)
    println("max value is:", summary.max)
    println("variance value is:", summary.variance)
    println("numNonZeors is:", summary.numNonzeros)
    println("mean value is:", summary.mean)
    println("count value is:", summary.count)

    //定义一组DOuble类型的RDD-----1-sc.textfile 2-sc.makerdd paralleise 3-rdd的转换
    val data1:RDD[Double] = sc.parallelize(Seq(1.0, 2.0, 3.0, 4.0), 1)
    val data2:RDD[Double] = sc.parallelize(Seq(2.0, 4.0, 6.0, 8.0), 1)

    val corr1:Double = Statistics.corr(data1, data2, "pearson")
    println(corr1)

    //在工作更多的是构建相关系数矩阵
    val fatData:RDD[String] = sc.textFile("\demohome\\scalahome\\gswscalademo01\\src\\main\\resources\\test.txt")
    val fatRDD:RDD[linalg.Vector] = fatData.map(_.split(" ").map(_.toDouble)).map(x => (Vectors.dense(x)))
    val matrix:Matrix = Statistics.corr(fatRDD, method = "pearson")
    println("matrix value is:\n", matrix)
    /*   sc:SparkContext,
       size:Long,
       numPartitions:Int = 0,
       seed:Long*/
    //seed随机数种子,保证随机选择数据的可重复性
    val rddData:RDD[Double] = normalRDD(sc, 7L, 1, 2223L)
    rddData.foreach(println(_))
    //数据的随机拆分
    val array:Array[RDD[linalg.Vector]] = vectorData.randomSplit(Array(0.8, 0.2), seed = 1L)
    val trainingSet:RDD[linalg.Vector] = array(0)
    val testSet:RDD[linalg.Vector] = array(1)
    trainingSet.foreach(println(_))
    println("=" * 100)
    testSet.foreach(println(_))
  }
}

import org.apache.spark.mllib.random.RandomRDDs
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

/**
  * DESC:
  * Complete data processing and modeling process steps:
  *
  */
object randomNumberTest {
  def main(args:Array[String]):Unit = {
    //1-准备环境
    val conf = new SparkConf()
      .setMaster("local")
      .setAppName("RandomRDDTest")
    val sc = new SparkContext(conf)
    sc.setLogLevel("WARN")
    //随机数
    //from the standard normal distribution.
    val double:RDD[Double] = RandomRDDs.normalRDD(sc,10)
    double.foreach(println(_))
    //samples
    val dataSamples:RDD[Int] = sc.parallelize(1 to 10)
    //是否进行又放回的抽样------是否保证整体的数据是一致的
    //抽样的比例,抽样20%
    //抽样的时候保证每次抽取的结果的可重复性seed=3----随机数种子
    //同一个seed随机数抽样的结果是一致的
    val sample:RDD[Int] = dataSamples.sample(false,0.2) // 1 3 5  [seed=9 1 2 3]
    val sample1:Array[Int] = dataSamples.takeSample(false,2,40)
    val split:Array[RDD[Int]] = dataSamples.randomSplit(Array(0.6, 0.4), seed = 123L)
    val test01 = split(0)
    val test02 = split(1)
    test01.foreach(println)
    println("*"*100)
    test02.foreach(println)
    println("*"*100)
    sample.foreach(println)
    println("*"*100)
    for (a <- sample1)println(a)

  }
}


特征工程分类
 提取 从“原始”数据中提取特征
   特别是对文章数据 从图像中抽取特征(深度学习)

 转换 缩放,转换或修改特征
   性别(男,女,其他)====>sex(0,1,-1)
   转换

 选择 从更大的特征集中选择特征子集
   featuresA+featuresB
   df.select("featuresB")
   df.select($"featuresB")
   df.select(col("featuresB"))
   df.select($"featuresB,col("featuresB"))
 卡方验证

 TFIDF
   含义 计算词频逆文档频率(注意,在sparkmllib中使用的是hashingtf)
   目的 计算出一个文章中出现的重要的词
   能用在哪些地方 
     提取文章的关键词汇
 CountVector
   含义 计算单词出现的次数
   目的 找出出现次数较多的单词或词语
   用途 在文章中找出出现次数最多的词
 
sin^2(α)+cos^2(α)=1 

两个互补角 sin值相同cos值相反

正弦定理
a / sinA = b / sinB = c / sinC = 2R R即外接圆半径

锐角三角形

sinB = h/c 
sinC = h/b
h = c * sinB = b * sinC
c / sinC = b / sinB
a / sinA = b / sinB = c / sinC

直角三角形
sinA = a / c
sinB = b / c
c = b / sinB = a / sinA 
C = 90DU = π/2
sinC = 1
所以 c/sinC = c = b / sinB = a / sinA
钝角三角形

sina = sinb
  
sinC = h / b   h = b * sinC
sinB = sin(PI - B) = h / c   h = c * sinB
c / sinC = b / sinB 

2a + 2b = PI - 2c
故c不变的情况下 a + b定值

sinC = sinC` = c / 2r
c / sinC = 2r

余弦定理
cosC = a*a +b*b -c*c / 2ab

锐角三角形

cosC = DC / b
h^ = b^ - DC^
h^ = c^ - (a - DC)^
b^ -DC^ = c^ - a^ -DC^ + 2aDC
DC = a^ + b^ -c^ / 2a

cosC = a^ + b^ -c^ / 2ab

直角三角形

a^ + b^ = c^
a^ + b^ - c^ = 0
cosC = 0  = a^ + b^ -c^ / 2ab

钝角三角形

h^ = b^ - x^
h^ = c^ - (a + x)^ = c^ - a^ - x^ -2ax
2ax = c^ - b^ - a^
x = c^ - b^ - a^ / 2a
又因为 cosC = -x / b
故cosC = a^ + b^ - c^ / 2ab

a向量的模 = a1^ + a2^
a模b模cosA =a向量*b向量 
cosA = a向量*b向量 / a模b模
余弦相似度 -1 ~ 1 
1完全相似 
-1 ~ 0完全不相似


数据建模
大数据项目架构

机器学习系统构建


强化学习

迁移学习

经验风险和结构风险

机器学习库
    Python的Sklearn
    Go的GoLearn
    Scala的SparkMllib
为什么有SparkMLlib

SparkMLlib五大特性

SparkMLlib架构与数据类型

为什么数据结构由RDD换成DtaFrame

SparkMLlib特征工程
类别型数据    数值化转换
数值型数据    年龄,身高,体重 单位or量纲 归一化和标准化
连续值属性离散化 年龄0-100 青年 中年 老年 决策树算法需要对连续值属性离散化 分桶

SparkMLlib特征工程案例


逻辑回归(LR,Logistic Regression)是传统机器学习中的一种分类模型,由于LR算法具有简单 高效 易于并行且在线学习(动态扩展)的特点,在工业界具有非常广泛的应用.
在线学习算法 LR属于一种在线学习算法,可以利用新的数据对各个特征的权重进行更新,而不需要重新利用历史数据训练
   LogisticRegression
   LR建模
   setMaxIter设置最大迭代次数(默认100),具体迭代次数可能在不足最大迭代次数停止
   setTol设置容错(默认1e-6),每次迭代会计算一个误差,误差值随着迭代次数增加而减小,当误差小于设置容错,则停止迭代
   setRegParam设置正则化项系数(默认0),正则化主要用于防止过拟合现象,如果数据集较小,特征维数又多,易出现过拟合,考虑增大正则化系数
   setElasticNetParam正则化范式比(默认0),正则化有两种方式:L1(Lasso)和L2(Ridge),L1用于特征的稀疏化,L2用于防止过拟合
   setLabelCol设置标签列
   setFeaturesCol设置特征列
   setPredictionCol设置预测列
   setThreshold设置二分类阈值
  
   ParamMap 
   在Spark中,Cross Validation(交叉验证)和ParamMap(“参数组合”的Map)结合使用.具体做法是,针对某有特定的Param组合,
   CrossValidator计算K (K 则交叉验证)个评估分数的平均值.然后和其它“参数组合”CrossValidator计算结果比较,
   完成所有的比较后,将最优的“参数组合”挑选出来,这“最优的一组参数”将用在整个训练数据集上重新训练(re-fit),得到最终的Model.

KNN近朱者赤 旁边元素比判断本元素
abs absolute 绝对值
L1曼哈顿距离    L2欧氏距离
colX为该cell
infer 内部的

性别(x)    考试成绩(y)
男    优
女    优
男    差
女    优
男    优

X的信息熵计算为 
    p(男) = 3/5 = 0.6
    p(女) = 2/5 = 0.4
根据上面的计算公式可得 
    列X的信息熵 为  H(x)= - ( 0.6 * log2(0.6) + 0.4 * log2(0.4)) =  0.97.......
Y的信息熵计算为 
    p(优) = 4/5 = 0.8
    p(差) = 1/5 = 0.2
列X的信息熵 为  H(x)= - ( 0.8 * log2(0.8) + 0.2 * log2(0.2)) =  0.72.......

条件熵

H(y | x = 男)= -(2/3 * log2(2/3) + 1/3 * log2(1/3)) = 0.9182733333
H(y | x = 女)= - 1 * log2(1) =  0.0...
H(y | x)= 3/5 * H(y | x = 男)+ 2/5 * H(y | x = 女) = 0.55... +  0.0... = 0.55

H(Y|X=长相) = p(X =帅)*H(Y|X=帅)+p(X =不帅)*H(Y|X=不帅)


 

猜你喜欢

转载自blog.csdn.net/qq_34387470/article/details/114585631
今日推荐