精华内容
下载资源
问答
  • 2021-11-20 18:29:36

    一、概述

      对于由Python训练的机器学习模型,通常有pickle和pmml两种部署方式,pickle方式用于在python环境中的部署,pmml方式用于跨平台(如Java环境)的部署,本文叙述的是pmml的跨平台部署方式。

      PMML(Predictive Model Markup Language,预测模型标记语言)是一种基于XML描述来存储机器学习模型的标准语言。如,对在Python环境中由sklearn训练得到的模型,通过sklearn2pmml模块可将它完整地保存为一个pmml格式的文件,再在其他平台(如java)中加载该文件进行使用,从而实现模型的跨平台部署。

    在这里插入图片描述


    二、实现步骤

     1.训练环境中安装生成pmml文件的工具。
      如在Python环境中安装sklearn2pmml模块(pip install sklearn2pmml)。
     2.训练模型。
     3.将模型保存为pmml文件。
     4.部署环境中导入依赖的工具包。
      如在Java环境中导入pmml-evaluator、pmml-evaluator-extension(特殊情况下另加)、jaxb-core、jaxb-api、jaxb-impl等jar包。
     5.开发应用,加载、使用模型。

    :对sklearn2pmml生成的pmml模型文件,在java中加载使用时,需将文件中的命名空间属性xmlns="…/PMML-4_4"改为xmlns="…/PMML-4_3",以适应低版本的jar包对它的解析。


    三、示例

      在python中使用sklearn训练一个线性回归模型,并在java环境中部署使用。

    工具:PyCharm-2017、Python-39、sklearn2pmml-0.76.1;IntelliJ IDEA-2018、jdk-14.0.2。

    1.训练数据集training_data.csv

    xy
    1506450
    2007450
    2508450
    3009450
    35011450
    40015450
    60018450

    2.训练、保存模型

    import sklearn2pmml as pmml
    from sklearn2pmml import PMMLPipeline
    from sklearn import linear_model as lm
    import os
    import pandas as pd
    
    def save_model(data, model_path):
        pipeline = PMMLPipeline([("regression", lm.LinearRegression())]) #定义模型,放入pipeline管道
        pipeline.fit(data[["x"]], data["y"]) #训练模型,由数据中第一行的名称确定自变量和因变量
        pmml.sklearn2pmml(pipeline, model_path, with_repr=True) #保存模型
    
    if __name__ == "__main__":
        data = pd.read_csv("training_data.csv")
        model_path = model_path = os.path.dirname(os.path.abspath(__file__)) + "/my_example_model.pmml"
        save_model(data, model_path)
        print("模型保存完成。")
    

    3.将pmml文件的xmlns属性修改为PMML-4_3

    在这里插入图片描述


    4.java程序中加载、使用模型
    (1)创建maven项目,将pmml模型文件拷贝至项目根目录下。
    (2)加入依赖包

    <dependencies>
            <dependency>
                <groupId>org.jpmml</groupId>
                <artifactId>pmml-evaluator</artifactId>
                <version>1.4.15</version>
            </dependency>
            <dependency>
                <groupId>com.sun.xml.bind</groupId>
                <artifactId>jaxb-core</artifactId>
                <version>2.2.11</version>
            </dependency>
            <dependency>
                <groupId>javax.xml</groupId>
                <artifactId>jaxb-api</artifactId>
                <version>2.1</version>
            </dependency>
            <dependency>
                <groupId>com.sun.xml.bind</groupId>
                <artifactId>jaxb-impl</artifactId>
                <version>2.2.11</version>
            </dependency>
        </dependencies>
    

    (3)java程序加载模型完成预测

    public class MLPmmlDeploy {
        public static void main(String[] args) {
    
            String model_path = "./my_example_model.pmml"; //模型路径
            int x = 700; //测试的自变量值
    
            Evaluator model = loadModel(model_path); //加载模型
            Object r = predict(model, x); //预测
    
            Double result = Double.parseDouble(r.toString());
            System.out.println("预测的结果为:" + result);
        }
    
        private static Evaluator loadModel(String model_path){
            PMML pmml = new PMML(); //定义PMML对象
            InputStream inputStream; //定义输入流
            try {
                inputStream = new FileInputStream(model_path); //输入流接到磁盘上的模型文件
                pmml = PMMLUtil.unmarshal(inputStream); //将输入流解析为PMML对象
            }catch (Exception e){
                e.printStackTrace();
            }
    
            ModelEvaluatorFactory modelEvaluatorFactory = ModelEvaluatorFactory.newInstance(); //实例化一个模型构造工厂
            Evaluator evaluator = modelEvaluatorFactory.newModelEvaluator(pmml); //将PMML对象构造为Evaluator模型对象
    
            return evaluator;
        }
    
        private static Object predict(Evaluator evaluator, int x){
            Map<String, Integer> data = new HashMap<String, Integer>(); //定义测试数据Map,存入各元自变量
            data.put("x", x); //键"x"为自变量的名称,应与训练数据中的自变量名称一致
            List<InputField> inputFieldList = evaluator.getInputFields(); //得到模型各元自变量的属性列表
    
            Map<FieldName, FieldValue> arguments = new LinkedHashMap<FieldName, FieldValue>();
            for (InputField inputField : inputFieldList) { //遍历各元自变量的属性列表
                FieldName inputFieldName = inputField.getName();
                Object rawValue = data.get(inputFieldName.getValue()); //取出该元变量的值
                FieldValue inputFieldValue = inputField.prepare(rawValue); //将值加入该元自变量属性中
                arguments.put(inputFieldName, inputFieldValue); //变量名和变量值的对加入LinkedHashMap
            }
    
            Map<FieldName, ?> results = evaluator.evaluate(arguments); //进行预测
            List<TargetField> targetFieldList = evaluator.getTargetFields(); //得到模型各元因变量的属性列表
            FieldName targetFieldName = targetFieldList.get(0).getName(); //第一元因变量名称
            Object targetFieldValue = results.get(targetFieldName); //由因变量名称得到值
    
            return targetFieldValue;
        }
    
    }
    

    在这里插入图片描述

    示例下载:
    https://download.csdn.net/download/Albert201605/45645889

    End.


    参考

    1. https://www.freesion.com/article/4628411548/
    2. https://www.cnblogs.com/pinard/p/9220199.html
    3. https://www.cnblogs.com/moonlightpoet/p/5533313.html
    更多相关内容
  • SHAP模型:可解释机器学习模型

    千次阅读 2021-08-24 10:47:29
    首先个人理解SHAP模型是对机器学习模型进行解释的一个模型 上面这个图就是一个比较直观的解释 机器学习模型一般都是一个黑盒。比如某个模型要进行一些预测任务,首先对模型输入一些已知条件(Age=65,Sex=F,BP=...

     小白进阶选手,如果写的内容有什么问题大家一起讨论学习呀 :)

    模型介绍

    首先个人理解SHAP模型是对机器学习模型进行解释的一个模型

     上面这个图就是一个比较直观的解释

    机器学习模型一般都是一个黑盒。比如某个模型要进行一些预测任务,首先对模型输入一些已知条件(Age=65,Sex=F,BP=180,BMI=40),然后模型根据输入进行训练,最终训练完的模型可以对该条件输出预测结果(Output=0.4)

    所以这样模型只能得到最终的结果,至于模型内部是怎么计算的,输入的已知条件(Age=65,Sex=F,BP=180,BMI=40)是怎么对预测结果(Output=0.4)影响的,我们都没法知道

    而SHAP模型就可以让我们知道这些已知条件到底对最终预测结果起到哪些影响(是对结果起到正向影响还是对结果起到了负向影响),除了SHAP模型,其实也有其他方法可以进行特征重要性的计算,比如下面这个表格里提到的,我们可以根据各种方法的优点选择适合的进行特征重要性计算

    而本文主要介绍的SHAP 属于模型事后解释的方法,它的核心思想是计算特征对模型输出的边际贡献,再从全局和局部两个层面对“黑盒模型”进行解释。SHAP构建一个加性的解释模型,所有的特征都视为“贡献者”

    SHAP的全称是SHapley Additive exPlanation,SHAP是由Shapley value启发的可加性解释模型。而Shapley value起源于合作博弈论,那什么是合作博弈呢。比如说甲乙丙丁四个工人一起打工,甲和乙完成了价值100元的工件,甲、乙、丙完成了价值120元的工件,乙、丙、丁完成了价值150元的工件,甲、丁完成了价值90元的工件,那么该如何公平、合理地分配这四个人的工钱呢?Shapley提出了一个合理的计算方法,我们称每个参与者分配到的数额为Shapley value

    结合文章一开始提到的预测任务,我认为就是已知条件(Age=65,Sex=F,BP=180,BMI=40)一起完成了预测结果(Output=0.4),那么该如何公平、合理地分配这四个已知条件对预测结果的贡献呢?此时SHAP模型就会给这四个已知条件都分配一个Shapley value值,根据这个值我们就可以很好的进行理解

    SHAP可以具体解决的任务

    • 调试模型用
    • 指导工程师做特征工程
    • 指导数据采集的方向
    • 指导人们做决策
    • 建立模型和人之间的信任

    这一部分在https://yyqing.me/post/2018/2018-09-25-kaggle-model-insights这个网站里讲的很详细

    SHAP库可用的explainers

    在SHAP中进行模型解释需要先创建一个explainer,SHAP支持很多类型的explainer

    • deep:用于计算深度学习模型,基于DeepLIFT算法,支持TensorFlow / Keras。
    • gradient:用于深度学习模型,综合了SHAP、集成梯度、和SmoothGrad等思想,形成单一期望值方程,但速度比DeepExplainer慢,并且做出了不同的假设。 此方法基于Integrated Gradient归因方法,并支持TensorFlow / Keras / PyTorch。
    • kernel:模型无关,适用于任何模型
    • linear:适用于特征独立不相关的线性模型
    • tree:适用于树模型和基于树模型的集成算法,如XGBoost,LightGBM或CatBoost

    实验

    在网上找了几个相关的实验跑一下加深印象,SHAP模型输出的可视化图真的是挺美观的

     

    感觉要把SHAP运用理解透,首先对于机器学习的一些模型需要运用的比较熟练

    网上找的的几个代码都是回归类的问题,所以了解的也比较浅显,以后遇到其他问题也可以尝试用SHAP对模型进行解释看看(网上对SHAP解释深度学习模型的例子不算很多,比如有看到一个CV方向的例子,通过SHAP来解释深度学习模型每一层网络对最终检查结果的影响情况,以后可以尝试一下这个方面),然后不断补充这里的实验部分

    问题1:

    足球运动员身价估计

    每个足球运动员在转会市场都有各自的价码,这个问题的目的是根据球员的各项信息和能力值来预测该球员的市场价值。

    问题2:

    波士顿房价估计

    通过数据挖掘对影响波士顿房价的因素进行分析

    具体代码:

    https://colab.research.google.com/drive/1V6XUWCbR7cPKXfdCJXKC1LjNHlg0GpFE?usp=sharing

    SHAP导出各种格式的图

    注意画图前需要加:

    shap.initjs()

    不加就会报错:

    Visualization omitted, Javascript library not loaded!
    Have you run `initjs()` in this notebook? If this notebook was from another user you must also trust this notebook (File -> Trust notebook). If you are viewing this notebook on github the Javascript has been stripped for security. If you are using JupyterLab this error is because a JupyterLab extension has not yet been written.

    如果想要在论文中添加SHAP模型输出的图,只是在代码最后加上plt.savefig,保存下来的图像为空白图。python的shap库,底层仍然使用matplotlib,根据源码可以发现在调用shap.xxx_plot时可以选择传递一个参数就可以正常使用plt.savefig了,几种不同的shap.xxx_plot需要传递的参数可能是不一样的,下面就举几个例子,一般情况下加上matplotlib=True,show = False这两个参数的比较多

    除了下面几个例子,瀑布图直接调用plt.savefig即可,shap.decision_plot则需要传入参数return_objects=True

    shap.force_plot(explainer.expected_value, shap_values[j], data[cols].iloc[j],matplotlib=True,show = False)
    plt.savefig('./result_300dpi.jpg', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.jpg', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.png', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.png', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.tiff', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.tiff', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.svg', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.svg', bbox_inches='tight', dpi=150)
    shap.summary_plot(shap_values, data[cols],show = False)
    plt.savefig('./result_300dpi.jpg', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.jpg', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.png', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.png', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.tiff', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.tiff', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.svg', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.svg', bbox_inches='tight', dpi=150)
    shap.dependence_plot('age', shap_values, data[cols], interaction_index=None, show=False)
    plt.savefig('./result_300dpi.jpg', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.jpg', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.png', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.png', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.tiff', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.tiff', bbox_inches='tight', dpi=150)
    plt.savefig('./result_300dpi.svg', bbox_inches='tight', dpi=300)
    plt.savefig('./result_150dpi.svg', bbox_inches='tight', dpi=150)

    References 

    https://www.jianshu.com/p/324a7c982034

    https://zhuanlan.zhihu.com/p/64799119

    https://zhuanlan.zhihu.com/p/83412330

    展开全文
  • 提高机器学习模型性能的五个关键方法

    万次阅读 多人点赞 2018-09-08 11:52:10
    如何提高机器学习模型性能, 可从五个关键方面入手。 1. 数据预处理 2. 特征工程 3. 机器学习算法 4. 模型集成与融合 5. 数据增强 以下是各个方面的具体分析和方法: [ 说明:1、这里主要是各个关键方法的...

    如何提高机器学习模型性能, 可从五个关键方面入手。

    1. 数据预处理

    2. 特征工程

    3. 机器学习算法

    4. 模型集成与融合

    5. 数据增强

    以下是各个方面的具体分析和方法:

    [ 说明:1、这里主要是各个关键方法的知识汇总梳理,便于集中学习,具体的实际应用内容后续单独写。 2、参考整理了很多大拿的文章和资料,但忘了记录来处,如有不适当转载的,请留言,我看到后第一时间删除。 ]

    第一部分:数据预处理

             机器学习里有一句名言:数据和特征决定了机器学习的上限,而模型和算法的应用只是让我们逼近这个上限。这个说法形象且深刻的提出前期数据处理和特征分析的重要性。这一点从我们往往用整个数据挖掘全流程60%以上的时间和精力去做建模前期的数据处理和特征分析也能看出。那么疑问来了,这超过60%时间和精力我们都用在哪了?本文基于以往的知识储备以及实际的项目经验,我做一个总结。 主要包括三点,一是获取数据、数据抽样,二是数据探索,三是数据预处理与清洗

    一、 获取数据,数据抽样:如何保证取样数据的质量?是否在足够范围内有代表性?数据样本取多少合适?如何分类(训练集、测试集、验证集)等等。当要处理或者要分析的数据量比较大,而我们的计算机或者平台不支持开展全量数据分析时,利用抽样技术进行样本分析往往是一个好的主意,其中抽样技术有:

    1.简单随机抽样(simple random sampling):将所有调查总体编号,再用抽签法或随机数字表随机抽取部分观察数据组成样本。

    优点:操作简单,均数、率及相应的标准误计算简单。

    缺点:总体较大时,难以一一编号。

    2.系统抽样(systematic sampling):又称机械抽样、等距抽样,即先将总体的观察单位按某一顺序号分成n个部分,再从第一部分随机抽取第k号观察单位,依次用相等间距从每一部分各抽取一个观察单位组成样本。

    优点:易于理解、简便易行。

    缺点:总体有周期或增减趋势时,易产生偏性。

    3.整群抽样(cluster sampling):先将总体依照一种或几种特征分为几个子总体(类.群),每一个子总体称为一层,然后从每一层中随机抽取一个子样本,将它们合在一起,即为总体的样本,称为分层样本

    优点:便于组织、节省经费。

    缺点:抽样误差大于单纯随机抽样。

    4.分层抽样(stratified sampling):将总体样本按其属性特征分成若干类型或层,然后在类型或层中随机抽取样本单位,合起来组成样本。有按比例分配和最优分配(过度抽样是否就是最优分配方法?)两种方案。

    优点:样本代表性好,抽样误差减少。

    缺点:由于通过划类分层,增大了各类型中单位间的共同性,容易抽出具有代表性的调查样本。该方法适用于总体情况复杂,各类别之间差异较大(比如金融客户风险/非风险样本的差异),类别较多的情况。

    其中我们经常用到的是分层抽样和简单随机抽样,有两种抽取模式,有放回和无放回,以及两种抽取方式,按照比例抽样和按照规模抽样,其中:

    有放回抽样:每次抽取的样品在下次抽样前要放回总体,也就是说,每次都是从总体中抽取数据,每次抽到各个样本的概率是相等的;

    无放回抽样:每次抽取后样本总体都会减少一,所以每次抽取后,下一次抽取样本的时候,抽样概率就会改变;

    按照比例抽样:按照总体的百分比多少抽取样本数据;

    按照规模抽样:即按照个数抽取,抽取的样本规模是多少,规模不大于总体规模

    二、 数据探索(数据质量稽核和特征分析):根据观测、调查收集到初步的样本数据集后,接下来要考虑的问题是:样本数据集的数量和质量是否满足模型构建的要求?有没有出现从未设想过的数据状态?其中有没有什么明显的规律和趋势?各因素之间有什么样的关联性?数据探索就是通过检验数据集的数据质量、绘制图表、计算某些特征量等手段,对样本数据集的结构和规律进行分析的过程。

    数据探索可以从数据质量分析和数据特征分析等两个角度进行展开:

    1  数据质量分析:是数据挖掘中数据准备过程中的重要一环,是数据预处理的前提,也是数据挖掘分析结论有效性和准确性的基础。数据质量分析的主要任务是检查原始数据中是否存在脏数据,脏数据一般是指不符合要求,以及不能直接进行相应分析的数据。在数据挖掘中,脏数据包括:

    1) 缺失值

    2)异常值

    3)不一致的值

    4)重复数据及含有特殊符号的数据

    1.1     缺失值分析:数据的缺失主要包括记录的缺失和记录中某个字段信息的缺失,两者都会造成分析结果的不准确。通过使用简单的统计分析,可以得到含有缺失值的属性的个数,以及每个属性的未缺失数、缺失数与缺失率等。

    1.1.1缺失值产生的原因:

    1)有些信息是被遗漏的。可能是因为输入时认为不重要、忘记填写或对数据理解错误等一些人为因素而遗漏的

    2)属性值不存在。

    3)有些信息暂时无法获取,或者获取的代价比较大。

    1.1.2缺失值的影响:

    1)数据挖掘建模将丢失大量的有用信息

    2)数据挖掘模型所表现出的不确定性更加显著,模型中蕴含的规律更难把握

    3)包含空值的数据会使建模过程陷入混乱,导致不可靠的输出

    1.2   异常值分析:异常值分析是检验数据是否有录入错误以及含有不合常理的数据。忽视异常值的存在是十分危险的,不加剔除地把异常值包括进数据的计算分析过程中,会给结果带来不良影响。异常值是指样本中的个别值,其数据明显偏离其余的观测值。异常值也称为离群点,异常值的分析也称为离群点分析。异常值分析可以通过以下3种方法来探索。

    1)简单统计量分析:可以先对变量做一个描述性统计,进而查看哪些数据是不合理的。最常用的统计量是最大值和最小值。

    2)3原则:如果数据服从于正态分布,在3原则下,异常值被定义为一组测定值与平均值的偏差值超过3倍标准差的值,即|x-u| >3。如果数据不服从正态分布,也可以用远离平均值的多少倍标准差来描述。

    3)箱型图分析:箱型图提供了识别异常值的一个标准:异常值通常被定义为小于QL -1.5IQR或大于QU +1.5IQR的值。

    1.3   一致性分析:数据不一致性是指数据的矛盾性、不相容性。直接对不一致性的数据进行挖掘,可能会产生与实际相违背的挖掘结果。在数据挖掘过程中,不一致数据的产生主要发生在数据集成的过程中,可能是由于被挖掘数据来自于不同的数据源、对于重复存放的数据未能进行一致性更新造成的。

    2  数据特征分析:对数据进行质量分析以后,可以通过绘制图表、计算某些特征量等手段进行数据的特征分析。主要通过分布分析、对比分析、统计量分析、周期性分析、贡献度分析、相关性分析等角度进行展开。

    2.1  分布分析:分布分析能揭示数据的分布特征和分布类型。对于定性数据,可用饼形图和条形图直观的现实分布情况。

    2.2  对比分析:对比分析是指把两个相互联系的指标进行比较,从数据量上展开和说明研究对象规模的大小,水平的高低,速度的快慢。在对比分析中,选择合适的对比标准是十分关键的步骤。

    2.3  统计量分析:用统计指标对定量数据进行统计描述,常从集中趋势和离中趋势两个方面进行分析。

    2.4  周期性分析:周期性分析是探索某个变量是否随着时间变化而呈现出某种周期变化趋势。时间尺度相对较长的周期性趋势有年度周期性趋势、季节性周期性趋势,相对较短的有月度周期性趋势、周度周期性趋势,甚至更短的天、小时周期性趋势。

    2.5  贡献度分析:贡献度分析又称帕累托分析,它的原理是帕累托法则又称2/8定律。

    2.6  相关性分析:分析连续变量之间线性相关程度的强弱,并用适当的统计指标表示出来的过程称为相关分析,

    1) 判断两个变量是否具有线性相关关系的最直观的方法是直接绘制散点图;

    2)需要同时考察多个变量间的相关关系时,可利用散点图矩阵同时绘制各变量间的散点图,从而快速发现多个变量间的主要相关性;

    计算相关系数:为了更加准确的描述变量之间的线性相关程度,可以通过计算相关系数来进行相关分析。在二元变量的相关分析过程中比较常用的有Pearson相关系数、Spearman秩相关系数和判定系数。

    1)Pearson相关系数:一般用于分析两个连续性变量之间的关系;

    2)Spearman秩相关系数:一般用来处理不服从正态分布的变量、分类或等级变量之间的关联性,也称等级相关系数。

    3)判定系数:判定系数是相关系数的平方,用r^2表示:用来衡量回归方程对y的解释程度。

    三、 数据预处理和清洗(data preprocessing):是指在主要的处理以前对数据进行的一些处理,现实世界中数据大体上都是不完整,不一致的脏数据,无法直接进行数据挖掘,或挖掘结果差强人意。为了提高数据挖掘的质量产生了数据预处理技术。数据预处理有多种方法:数据清理,数据集成,数据变换,数据归约等。这些数据处理技术在数据挖掘之前使用,大大提高了数据挖掘模式的质量,降低实际挖掘所需要的时间。

    1、 数据清理:通过填写缺失的值、光滑噪声数据、识别或删除离群点并解决不一致性来“清理”数据。主要是达到如下目标:格式标准化,异常数据清除,错误纠正,重复数据的清除。

    1)处理缺失值方法:

    a.忽略元祖,挖掘任务涉及分类任务中如果缺少类标号时通常这样做

    b.人工填写缺失值,量大时行不通

    c.使用一个全局常量填充缺失值,简单但不可靠

    d.使用属性的均值填充缺失值

    e.使用与给定元组属同一类的所有样本的属性均值

    f.使用最有可能的值填充缺失值,可以用回归,使用贝叶斯形式化的基于推理的工具或决策树归纳确定,是流行的做法。

    2)数据光滑技术:噪声是被测量的变量的随机误差或方差

    a.分箱,分箱方法通过考察数据的“近邻”(即周围的值)来光滑有序数据的值,有序值分布到一些“桶”或箱中。由于分箱方法考察近邻的值,因此进行局部光滑。几种分箱技术:用箱均值光滑、用箱边界光滑、用箱中位数光滑。

    b.回归:可以用一个函数(如回归函数)拟合数据来光滑数据。线性回归涉及找出拟合两个属性(或变量)的“最佳”线,是的一个属性可以用来预测另一个。多元线性回归是线性回归的扩展,其中涉及的属性多于两个,并且数据拟合到一个多维曲面。

    c.聚类:通过聚类检测离群点

    2、 数据集成:将多个数据源中的数据结合起来并统一存储,建立数据仓库的过程实际上就是数据集成,具体来讲就是将分散在不同来源的数据有机地整合到一起的一步,例如宽表整合。明确哪些数据源可用?哪些数据与当前挖掘目标相关?。其中要考虑三个问题:实体识别、数据冗余和数据值冲突检测与处理。

    数据分析任务多半涉及数据集成。数据集成合并多个数据源中的数据,存放在一个一致的数据存储(如数据仓库)中。这些数据源可能包括多个数据库、数据立方体或一般文件。数据集成有三个主要问题:

    a.模式集成和对象匹配,实体识别问题:来自多个信息源的现实世界的等价实体如何才能匹配?元数据可以帮助避免模式集成的错误。

    b.冗余:有些冗余可以被相关分析检测到。通过计算属性A,B的相关系数(皮尔逊积矩系数)来判断是否冗余;对于离散数据,可通过卡方检验来判断两个属性A和B之间的相关联系。

    c.数据值冲突的检测与处理

    3、 数据变换:通过平滑聚集,数据概化,规范化等方式将数据转换成适用于数据挖掘的形式。其中平滑可以用分箱、聚类和回归来实现。数据泛化过程即概念分层,将低层次的数据提炼到更高一级的概念层次中。规范化又有最大最小规范化、0-值规范化和小数定标规范化。此外还可以构造新的属性来使数据集成。

    a.光滑:去掉数据的噪声,包括分箱,回归和聚类

    b.聚集:对数据进行汇总或聚集。这一步通常用来为多粒度数据分析构造数据立方体

    c.数据泛化:使用概念分层,用高层概念替换底层或“原始”数据。

    d.规范化:又称为归一化,feature scaling特征缩放。将属性数据按比例缩放,使之落入一个小的特定区间。规范化方法:

    1.最小-最大规范化:v'=[(v-min)/(max-min)]*(new_max-new_min)+new_min

    2.z-score规范化(或零均值规范化):v'=(v-属性A的均值E)/属性A的标准差∽

    3.小数定标规范化:v'=v/10的j次方,j是使Max(|v'|)<1的最小整数

    e.属性构造(或特征构造):可以构造新的属性并添加到属性集中,以帮助挖掘过程。

    4、 数据归约:数据挖掘时往往数据量非常大,在少量数据上进行挖掘分析需要很长的时间,数据归约技术可以用来得到数据集的归约表示,它小得多,但仍然接近于保持原数据的完整性,并结果与归约前结果相同或几乎相同。此类技术主要有如下几类:

    a、 数据方聚集、

    b、 维规约(检测并删除不相关、弱相关或冗余的属性或维)

    c、 数据压缩(小波或傅立叶变换以及主成份分析)

    d、 数值规约(用替代的、较小的数据表示替换或估计数据):主要有回归、直方图、聚类、选样等操作

    e、 还有概念分层。

    第二部分:特征工程

    特征是数据中抽取出来的对结果预测有用的信息,可以是文本或者数据。特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。过程包含了特征提取、特征构建、特征选择等模块

    这里写图片描述

    一、特征构造:就是从原始的数据中构造特征集,原始数据可能是时间戳、文本、图片、音频等。我们需要从这些数据中构建特征集。下面介绍主要的特征构建方法。

    1,对数值型数据: 
    (1)无量纲化:在对于非tree base 的模型,对数据的规格要求其实是很高的,这就需要无量纲化各个维度的数据。常用方法:归一化(StandardScaler类,本文所用到方法全是sklearn中的)、最大最小区间缩放(MinMaxScaler类)、正则归一化(Normalizer类) 
    (2)统计值:包括max, min, mean, std等。对数据计算的统计值也可以作为特征,只要与问题有关。 
    (3)离散化: 也就是分箱/分区操作,把连续值转成非线性数据,比如成绩可以分为A、B、C三等,也可以理解为把数据分成类别。常用对定量特征二值化(Binarizer类)。

    2,对类别型数据: 对于类别型数据不能用数值表示。(比如颜色{红、绿、蓝},数字1、2、3可以表示,但是颜色本身没有数学关系,这会误导我们的数学模型)。常用的方法是热编码-(one-hot方法)(OneHotEncoder类)

    3,对时间戳数据: 很多任务与时间维度有关系,比如用电量等,此时要将时间戳数据转换为时间特征。常见的转换有: 
    (1)day of weak(一周的星期几)、day of month、day of year、week of year、month of year、hour of day、minute of day 、哪个季度。 
    (2)t_m24(前一天的数值)、t_m48(前两天的数值)等。 
    (3)tdif(与亲一天的数值的差值)等。

    4,对文本数据: 
    (1)词袋:本数据预处理后,去掉停用词,剩下的词组成的list,在词库中的映射稀疏向量。Python中用CountVectorizer处理词袋。 也就是考虑某个词在当前训练样本中出现的频率。 
    (2)使用TF-IDF特征:TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF(t) = (词t在当前文中出现次数) / (t在全部文档中出现次数),IDF(t) = ln(总文档数/ 含t的文档数),TF-IDF权重 = TF(t) * IDF(t)。自然语言处理中经常会用到。(考虑到了这个词语是不是在大部分文件都出现了,即包含这个词语的文本条数的倒数,这种词语一般没有什么作用,排除掉常用词语的干扰)

    5,计算统计特征: 很多时候统计特征对问题很有帮助,统计的内容包括加减平均、分位线、次序型、比例类等。

    6,组合特征: 
    (1)拼接型:简单的组合特征。就是把多个特征组合成一个(男人喜欢打篮球:就是把男人,喜欢打篮球和在一起了) 
      - user_id&&category: 10001&&女裙 10002&&男士牛仔 
      - user_id&&style: 10001&&蕾丝 10002&&全棉   
    (2) 模型特征组合: 
      - 用GBDT产出特征组合路径 
      - 组合特征和原始特征一起放进LR训练

    7,缺失特征处理: 对于缺失特征可以修改成新的特征,也可以删除,常用有: 
    (1)删除:最简单的方法是删除,删除属性或者删除样本。如果大部分样本该属性都缺失,这个属性能提供的信息有限,可以选择放弃使用该维属性;如果一个样本大部分属性缺失,可以选择放弃该样本。虽然这种方法简单,但只适用于数据集中缺失较少的情况。 
    (2) 统计填充:对于缺失值的属性,尤其是数值类型的属性,根据所有样本关于这维属性的统计值对其进行填充,如使用平均数、中位数、众数、最大值、最小值等,具体选择哪种统计值需要具体问题具体分析。另外,如果有可用类别信息,还可以进行类内统计,比如身高,男性和女性的统计填充应该是不同的。 
    (3) 统一填充:对于含缺失值的属性,把所有缺失值统一填充为自定义值,如何选择自定义值也需要具体问题具体分析。当然,如果有可用类别信息,也可以为不同类别分别进行统一填充。常用的统一填充值有:“空”、“0”、“正无穷”、“负无穷”等。 
    (4) 预测填充:我们可以通过预测模型利用不存在缺失值的属性来预测缺失值,也就是先用预测模型把数据填充后再做进一步的工作,如统计、学习等。虽然这种方法比较复杂,但是最后得到的结果比较好。

    8,特征转换: 对已有的特征做变换,产生新的特征。常见的数据变换有基于多项式的、基于指数函数的、基于对数函数的。4个特征,度为2的多项式转换公式如下: 
    这里写图片描述

    二、特征选择: 
    当数据预处理完成后,我们需要选择有意义的特征输入机器学习的算法和模型进行训练。原始的特征可能有冗余(两个特征说的是一个问题,相关性太强)、噪声(会影响问题的效果)。通常来说,从两个方面考虑来选择特征:

    特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。 
    特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优选选择。除方差法外,本文介绍的其他方法均从相关性考虑。

    1,filter(过滤法)方法:评估单个特征和结果值之间的相关程度, 排序留下Top相关的特征部分。 评价方式: Pearson相关系数, 互信息, 距离相关度。 缺点:只评估了单个特征对结果的影响,没有考虑到特征之间的关联作用, 可能把有用的关联特征误踢掉。因此工业界使用比较少。

    (1)方差选择:计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。使用feature_selection库的VarianceThreshold类。 
    (2)相关系数法:计算各个特征对目标值的相关系数以及相关系数的P值。用feature_selection库的SelectKBest类结合相关系数来选择。 
    (卡方检验是检验定性自变量对定性因变量的相关性,互信息是评价定性自变量对定性因变量的相关性,可以用这两个值和SelectKBest类来选择)

    2,wrapper(包裹法): 方法:把特征选择看做一个特征子集搜索问题, 筛选各种特 征子集, 用模型评估子集特征的效果。 典型算法:“递归特征删除算法”,应用在逻辑回归的过程: 
    a.用全量特征跑一个模型; 
    b.根据线性模型的系数(体现相关性),删掉5-10%的弱特征,观察准确率/auc的变化; 
    c.逐步进行, 直至准确率/auc出现大的下滑停止。 
    (python中是RFE类)

    3,嵌入法: 方法:根据模型来分析特征的重要性,最常见的方式为用正则化方式来做特征选择。(这种方式在工业界很常用) 
    (1)基于惩罚项的方法:就是用L1,L2正则化来做特征选择。L1正则有截断效应:不重要的特征的参数权重为0,L1正则方法具有稀疏解的特性,因此天然具备特征选择的特性,但是要注意,L1没有选到的特征不代表不重要,原因是两个具有高相关性的特征可能只保留了一个,如果要确定哪个特征重要应再通过L2正则方法交叉检验;;L2正则有缩放效应:拿到手的特征都比较小。SelectFromModel类来解决。

    (2)基于树模型的特征选择法:树模型中GBDT也可用来作为基模型进行特征选择,使用feature_selection库的SelectFromModel类结合GBDT模型。

    三、特征降维: 当特征选择完成后,可以直接训练模型了,但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。常见的降维方法除了以上提到的基于L1惩罚项的模型以外,另外还有主成分分析法(PCA)和线性判别分析(LDA),线性判别分析本身也是一个分类模型。PCA和LDA有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样: PCA是为了让映射后的样本具有最大的发散性;而LDA是为了让映射后的样本有最好的分类性能。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。(这在python都有相应的方法) 
    (降维是进行特征的变换和映射产生了不同的维度更小的特征,二特征选择是在原始的特征中选择有意义的特征,并没有产生新的特征)

    备注: 
    1,特征处理完后,就应该进行模型训练和模型选择,模型的训练可以用sklearn或者很多其他机器学习的包做,模型的选择可以参考: 
    sklearn超参数选择: 
    http://blog.csdn.net/u014248127/article/details/78938561 
    sklearn中的交叉验证与参数选择: 
    http://blog.csdn.net/u014248127/article/details/78899195

    2,本篇文章中的代码实现可以参考:使用sklearn做单机特征工程 
    http://www.cnblogs.com/jasonfreak/p/5448385.html

    第三部分:机器学习算法

      从广义上来说,机器学习是一种能够赋予机器学习的能力以此让它完成直接编程无法完成的功能的方法。但从实践的意义上来说,机器学习是一种通过利用数据,训练出模型,然后使用模型预测的一种方法。

      机器学习无疑是当前数据分析领域的一个热点内容。很多人在平时的工作中都或多或少会用到机器学习的算法。从范围上来说,机器学习跟模式识别,统计学习,数据挖掘是类似的,同时,机器学习与其他领域的处理技术的结合,形成了计算机视觉、语音识别、自然语言处理等交叉学科。因此,一般说数据挖掘时,可以等同于说机器学习。同时,我们平常所说的机器学习应用,应该是通用的,不仅仅局限在结构化数据,还有图像,音频等应用。

      机器学习的算法很多。很多时候困惑人们都是,很多算法是一类算法,而有些算法又是从其他算法中延伸出来的。这里,我们从两个方面来给大家介绍,第一个方面是学习的方式,第二个方面是算法的类似性。

    一、机器学习方式

      根据数据类型的不同,对一个问题的建模有不同的方式。在机器学习或者人工智能领域,人们首先会考虑算法的学习方式。在机器学习领域,有几种主要的学习方式。将算法按照学习方式分类是一个不错的想法,这样可以让人们在建模和算法选择的时候考虑能根据输入数据来选择最合适的算法来获得最好的结果。

    1.1 监督学习

    这里写图片描述

      在监督式学习下,输入数据被称为“训练数据”,每组训练数据有一个明确的标识或结果,如对防垃圾邮件系统中“垃圾邮件”“非垃圾邮件”,对手写数字识别中的“1“,”2“,”3“,”4“等。在建立预测模型的时候,监督式学习建立一个学习过程,将预测结果与“训练数据”的实际结果进行比较,不断的调整预测模型,直到模型的预测结果达到一个预期的准确率。监督式学习的常见应用场景如分类问题和回归问题。常见算法有逻辑回归(Logistic Regression)和反向传递神经网络(Back Propagation Neural Network)

    1.2 无监督学习

    这里写图片描述

      在非监督式学习中,数据并不被特别标识,学习模型是为了推断出数据的一些内在结构。常见的应用场景包括关联规则的学习以及聚类等。常见算法包括Apriori算法以及k-Means算法。

    1.3 半监督学习

    这里写图片描述

      在此学习方式下,输入数据部分被标识,部分没有被标识,这种学习模型可以用来进行预测,但是模型首先需要学习数据的内在结构以便合理的组织数据来进行预测。应用场景包括分类和回归,算法包括一些对常用监督式学习算法的延伸,这些算法首先试图对未标识数据进行建模,在此基础上再对标识的数据进行预测。如图论推理算法(Graph Inference)或者拉普拉斯支持向量机(Laplacian SVM.)等。

    1.4 强化学习

    这里写图片描述

      在这种学习模式下,输入数据作为对模型的反馈,不像监督模型那样,输入数据仅仅是作为一个检查模型对错的方式,在强化学习下,输入数据直接反馈到模型,模型必须对此立刻作出调整。常见的应用场景包括动态系统以及机器人控制等。常见算法包括Q-Learning以及时间差学习(Temporal difference learning)

    二、机器学习常用算法

      根据算法的功能和形式的类似性,我们可以把算法分类,比如说基于树的算法,基于神经网络的算法等等。当然,机器学习的范围非常庞大,有些算法很难明确归类到某一类。而对于有些分类来说,同一分类的算法可以针对不同类型的问题。这里,我们尽量把常用的算法按照最容易理解的方式进行分类。

    2.1 回归算法(有监督学习)

    这里写图片描述

      在大部分机器学习课程中,回归算法都是介绍的第一个算法。原因有两个:一.回归算法比较简单,介绍它可以让人平滑地从统计学迁移到机器学习中。二.回归算法是后面若干强大算法的基石,如果不理解回归算法,无法学习那些强大的算法。回归算法有两个重要的子类:即线性回归和逻辑回归。

      回归算法是试图采用对误差的衡量来探索变量之间的关系的一类算法。回归算法是统计机器学习的利器。在机器学习领域,人们说起回归,有时候是指一类问题,有时候是指一类算法,这一点常常会使初学者有所困惑。常见的回归算法包括:最小二乘法(Ordinary Least Square),逻辑回归(Logistic Regression),逐步式回归(Stepwise Regression),多元自适应回归样条(Multivariate Adaptive Regression Splines)以及本地散点平滑估计(Locally Estimated Scatterplot Smoothing)

    • 线性回归就是如何拟合出一条直线最佳匹配我所有的数据?一般使用“最小二乘法”来求解。“最小二乘法”的思想是这样的,假设我们拟合出的直线代表数据的真实值,而观测到的数据代表拥有误差的值。为了尽可能减小误差的影响,需要求解一条直线使所有误差的平方和最小。最小二乘法将最优问题转化为求函数极值问题。函数极值在数学上我们一般会采用求导数为0的方法。但这种做法并不适合计算机,可能求解不出来,也可能计算量太大。

    • 逻辑回归是一种与线性回归非常类似的算法,但是,从本质上讲,线型回归处理的问题类型与逻辑回归不一致。线性回归处理的是数值问题,也就是最后预测出的结果是数字,例如房价。而逻辑回归属于分类算法,也就是说,逻辑回归预测结果是离散的分类,例如判断这封邮件是否是垃圾邮件,以及用户是否会点击此广告等等。

      实现方面的话,逻辑回归只是对对线性回归的计算结果加上了一个Sigmoid函数,将数值结果转化为了0到1之间的概率(Sigmoid函数的图像一般来说并不直观,你只需要理解对数值越大,函数越逼近1,数值越小,函数越逼近0),接着我们根据这个概率可以做预测,例如概率大于0.5,则这封邮件就是垃圾邮件,或者肿瘤是否是恶性的等等。从直观上来说,逻辑回归是画出了一条分类线,逻辑回归算法划出的分类线基本都是线性的(也有划出非线性分类线的逻辑回归,不过那样的模型在处理数据量较大的时候效率会很低)。

    2.2 正则化方法

    这里写图片描述

      正则化方法是其他算法(通常是回归算法)的延伸,根据算法的复杂度对算法进行调整。正则化方法通常对简单模型予以奖励而对复杂算法予以惩罚。常见的算法包括:Ridge Regression, Least Absolute Shrinkage and Selection Operator(LASSO),以及弹性网络(Elastic Net)。

    2.3 基于实例的算法

    这里写图片描述

      基于实例的算法常常用来对决策问题建立模型,这样的模型常常先选取一批样本数据,然后根据某些近似性把新数据与样本数据进行比较。通过这种方式来寻找最佳的匹配。因此,基于实例的算法常常也被称为“赢家通吃”学习或者“基于记忆的学习”。常见的算法包括 k-Nearest Neighbor(KNN), 学习矢量量化(Learning Vector Quantization, LVQ),以及自组织映射算法(Self-Organizing Map , SOM)

    2.4 决策树算法

      决策树算法根据数据的属性采用树状结构建立决策模型, 决策树模型常常用来解决分类和回归问题。常见的算法包括:分类及回归树(Classification And Regression Tree, CART), ID3 (Iterative Dichotomiser 3), C4.5, Chi-squared Automatic Interaction Detection(CHAID), Decision Stump, 随机森林(Random Forest), 多元自适应回归样条(MARS)以及梯度推进机(Gradient Boosting Machine, GBM)

      一般的机器学习模型至少考虑两个量:一个是因变量,也就是我们希望预测的结果,在这个例子里就是小Y迟到与否的判断。另一个是自变量,也就是用来预测小Y是否迟到的量。假设我把时间作为自变量,譬如我发现小Y所有迟到的日子基本都是星期五,而在非星期五情况下他基本不迟到。于是我可以建立一个模型,来模拟小Y迟到与否跟日子是否是星期五的概率。就是一个最简单的机器学习模型,称之为决策树。

      当我们考虑的自变量只有一个时,情况较为简单。如果把我们的自变量再增加一个。例如小Y迟到的部分情况时是在他开车过来的时候(你可以理解为他开车水平较臭,或者路较堵)。于是我可以关联考虑这些信息。建立一个更复杂的模型,这个模型包含两个自变量与一个因变量。再更复杂一点,小Y的迟到跟天气也有一定的原因,例如下雨的时候,这时候我需要考虑三个自变量。

      如果我希望能够预测小Y迟到的具体时间,我可以把他每次迟到的时间跟雨量的大小以及前面考虑的自变量统一建立一个模型。于是我的模型可以预测值,例如他大概会迟到几分钟。这样可以帮助我更好的规划我出门的时间。在这样的情况下,决策树就无法很好地支撑了,因为决策树只能预测离散值。我们可以用线型回归方法建立这个模型。

      如果我把这些建立模型的过程交给电脑。比如把所有的自变量和因变量输入,然后让计算机帮我生成一个模型,同时让计算机根据我当前的情况,给出我是否需要迟出门,需要迟几分钟的建议。那么计算机执行这些辅助决策的过程就是机器学习的过程。

    2.5 贝叶斯方法

    这里写图片描述

      贝叶斯方法算法是基于贝叶斯定理的一类算法,主要用来解决分类和回归问题。常见算法包括:朴素贝叶斯算法,平均单依赖估计(Averaged One-Dependence Estimators, AODE),以及Bayesian Belief Network(BBN)。

    2.6 基于核的算法(有监督学习)

    这里写图片描述

      基于核的算法中最著名的莫过于支持向量机(SVM)了。 基于核的算法把输入数据映射到一个高阶的向量空间, 在这些高阶向量空间里, 有些分类或者回归问题能够更容易的解决。 常见的基于核的算法包括:支持向量机(Support Vector Machine, SVM), 径向基函数(Radial Basis Function ,RBF), 以及线性判别分析(Linear Discriminate Analysis ,LDA)等。接下来将重点介绍一下SVM

    · 支持向量机 SVM

      支持向量机算法是诞生于统计学习界,同时在机器学习界大放光彩的经典算法。

      支持向量机算法从某种意义上来说是逻辑回归算法的强化:通过给予逻辑回归算法更严格的优化条件,支持向量机算法可以获得比逻辑回归更好的分类界线。但是如果没有某类函数技术,则支持向量机算法最多算是一种更好的线性分类技术。

      但是,通过跟高斯“核”的结合,支持向量机可以表达出非常复杂的分类界线,从而达成很好的的分类效果。“核”事实上就是一种特殊的函数,最典型的特征就是可以将低维的空间映射到高维的空间。

      SVM方法是通过一个非线性映射p,把样本空间映射到一个高维乃至无穷维的特征空间中(Hilber空间),使得在原来的样本空间中非线性可分的问题转化为在特征空间中的线性可分的问题。升维,就是把样本向高维空间做映射,一般情况下这会增加计算的复杂性,甚至会引起“维数灾难”,因而人们很少问津。但是作为分类、回归等问题来说,很可能在低维样本空间无法线性处理的样本集,在高维特征空间中却可以通过一个线性超平面实现线性划分(或回归)。一般的升维都会带来计算的复杂化,SVM方法巧妙地解决了这个难题:应用核函数的展开定理,就不需要知道非线性映射的显式表达式;由于是在高维特征 空间中建立线性学习机,所以与线性模型相比,不但几乎不增加计算的复杂性,而且在某种程度上避免了“维数灾难”.这一切要归功于核函数的展开和计算理论。

      选择不同的核函数,可以生成不同的SVM,常用的核函数有以下4种: 
      - 性核函数K(x,y)=x·y 
      - 多项式核函数K(x,y)=[(x·y)+1]d 
      - 向基函数K(x,y)=exp(-|x-y|^2/d^2) 
      - 层神经网络核函数K(x,y)=tanh(a(x·y)+b)

      如下图所示,我们如何在二维平面划分出一个圆形的分类界线?在二维平面可能会很困难,但是通过“核”可以将二维空间映射到三维空间,然后使用一个线性平面就可以达成类似效果。也就是说,二维平面划分出的非线性分类界线可以等价于三维平面的线性分类界线。于是,我们可以通过在三维空间中进行简单的线性划分就可以达到在二维平面中的非线性划分效果。

    待分类数据

    已分类数据

      支持向量机是一种数学成分很浓的机器学习算法(相对的,神经网络则有生物科学成分)。在算法的核心步骤中,有一步证明,即将数据从低维映射到高维不会带来最后计算复杂性的提升。于是,通过支持向量机算法,既可以保持计算效率,又可以获得非常好的分类效果。因此支持向量机在90年代后期一直占据着机器学习中最核心的地位,基本取代了神经网络算法。直到现在神经网络借着深度学习重新兴起,两者之间才又发生了微妙的平衡转变。

    2.7 聚类算法(无监督学习)

    这里写图片描述

      聚类,就像回归一样,有时候人们描述的是一类问题,有时候描述的是一类算法。聚类算法通常按照中心点或者分层的方式对输入数据进行归并。简单来说,聚类算法就是计算种群中的距离,根据距离的远近将数据划分为多个族群,所以的聚类算法都试图找到数据的内在结构,以便按照最大的共同点将数据进行归类。常见的聚类算法包括 k-Means算法以及期望最大化算法(Expectation Maximization, EM)。

    2.8 关联规则学习

    这里写图片描述

      关联规则学习通过寻找最能够解释数据变量之间关系的规则,来找出大量多元数据集中有用的关联规则。常见算法包括 Apriori算法和Eclat算法等。

    2.9 人工神经网络 ANN(有监督学习)

      神经网络(也称之为人工神经网络,ANN)算法是80年代机器学习界非常流行的算法,不过在90年代中途衰落。现在,携着“深度学习”之势,神经网络重装归来,重新成为最强大的机器学习算法之一。

      神经网络的诞生起源于对大脑工作机理的研究。早期生物界学者们使用神经网络来模拟大脑。机器学习的学者们使用神经网络进行机器学习的实验,发现在视觉与语音的识别上效果都相当好。在BP算法(加速神经网络训练过程的数值算法)诞生以后,神经网络的发展进入了一个热潮。BP算法的发明人之一是前面介绍的机器学习大牛Geoffrey Hinton。

      人工神经网络是机器学习的一个庞大的分支,有几百种不同的算法,通常用于解决分类和回归问题。(其中深度学习就是其中的一类算法,我们会单独讨论),重要的人工神经网络算法包括:感知器神经网络(Perceptron Neural Network), 反向传递(Back Propagation),Hopfield网络,自组织映射(Self-Organizing Map, SOM)。学习矢量量化(Learning Vector Quantization, LVQ)

      具体说来,神经网络的学习机理是什么?简单来说,就是分解与整合。在著名的Hubel-Wiesel试验中,学者们研究猫的视觉分析机理是这样的。

    这里写图片描述

      比方说,一个正方形,分解为四个折线进入视觉处理的下一层中。四个神经元分别处理一个折线。每个折线再继续被分解为两条直线,每条直线再被分解为黑白两个面。于是,一个复杂的图像变成了大量的细节进入神经元,神经元处理以后再进行整合,最后得出了看到的是正方形的结论。这就是大脑视觉识别的机理,也是神经网络工作的机理。

      让我们看一个简单的神经网络的逻辑架构。在这个网络中,分成输入层,隐藏层,和输出层。输入层负责接收信号,隐藏层负责对数据的分解与处理,最后的结果被整合到输出层。每层中的一个圆代表一个处理单元,可以认为是模拟了一个神经元,若干个处理单元组成了一个层,若干个层再组成了一个网络,也就是”神经网络”。

    这里写图片描述

      上图描述的是一个目前研究最为成熟Shallow 结构的神经网络(只含有单层隐藏层神经元的结构)。第一层为输入层 (input layer ),第二层称为隐藏层 ( hidden layer ),最后一层为输出层( output layer )。神经元之间都是由低层出发,终止于高层神经元的一条有向边进行连接,每条边都有自己的权重。每个神经元都是一个计算单元,如在Feed-forward neural network 中,除输入层神经元外,每个神经元为一个计算单元,可以通过一个计算函数 f() 来表示,函数的具体形式可以自己定义,现在用的较多的是 感知器计算神经元,如果你对感知器有所了解的话,理解起来会容易很多。 可以计算此时神经元所具有的能量值,当该值超过一定阀值的时候神经元的状态就会发生改变,神经元只有两种状态,激活或未激活。在实际的人工神经网络中,一般是用一种概率的方式去表示神经元是否处于激活状态,可以用 h(f) 来表示,f 代表神经元的能量值,h(f) 代表该能量值使得神经元的状态发生改变的概率有多大,能量值越大,处于激活状态的概率就越高。到这部分你已经接触到了关于神经网络的几个基本术语,下面用更加规范的符号来表示,神经元的激活值(activations) f() ,表示计算神经元的能量值, 神经元的激活状态 h(f) ,h 表示激活函数。


    在神经网络中,每个处理单元事实上就是一个逻辑回归模型,逻辑回归模型接收上层的输入,把模型的预测结果作为输出传输到下一个层次。通过这样的过程,神经网络可以完成非常复杂的非线性分类。

      下图会演示神经网络在图像识别领域的一个著名应用,这个程序叫做LeNet,是一个基于多个隐层构建的神经网络。通过LeNet可以识别多种手写数字,并且达到很高的识别精度与拥有较好的鲁棒性。

    这里写图片描述

      右下方的方形中显示的是输入计算机的图像,方形上方的红色字样“answer”后面显示的是计算机的输出。左边的三条竖直的图像列显示的是神经网络中三个隐藏层的输出,可以看出,随着层次的不断深入,越深的层次处理的细节越低,例如层3基本处理的都已经是线的细节了。LeNet的发明人就是前文介绍过的机器学习的大牛Yann LeCun。

      大约二三十年前,Neural Network曾经是ML领域特别火热的一个方向,但是后来确慢慢淡出了,进入90年代,神经网络的发展进入了一个瓶颈期。其主要原因是尽管有BP算法的加速,神经网络的训练过程仍然很困难。因此90年代后期支持向量机(SVM)算法取代了神经网络的地位。 
       
      原因包括以下几个方面: 
      1. 比较容易过训练,参数比较难确定; 
      2. 训练速度比较慢,在层次比较少(小于等于3)的情况下效果并不比其它方法更优;

      所以中间有大约20多年的时间,神经网络被关注很少,这段时间基本上由SVM和Boosting算法主导。但是,Hinton坚持下来并最终(和Bengio、Yann.lecun等)提成了一个实际可行的Deep Learning框架。

    2.10 深度学习

    这里写图片描述

      虽然深度学习这四字听起来颇为高大上,但其理念却非常简单,就是传统的神经网络发展到了多隐藏层的情况。

      在上文介绍过,自从90年代以后,神经网络已经消寂了一段时间。但是BP算法的发明人Geoffrey Hinton一直没有放弃对神经网络的研究。由于神经网络在隐藏层扩大到两个以上,其训练速度就会非常慢,因此实用性一直低于支持向量机。2006年,Geoffrey Hinton在科学杂志《Science》上发表了一篇文章,论证了两个观点:

      1.多隐层的神经网络具有优异的特征学习能力,学习得到的特征对数据有更本质的刻画,从而有利于可视化或分类; 
      2.深度神经网络在训练上的难度,可以通过“逐层初始化” 来有效克服。

      通过这样的发现,不仅解决了神经网络在计算上的难度,同时也说明了深层神经网络在学习上的优异性。从此,神经网络重新成为了机器学习界中的主流强大学习技术。同时,具有多个隐藏层的神经网络被称为深度神经网络,基于深度神经网络的学习研究称之为深度学习。

      由于深度学习的重要性质,在各方面都取得极大的关注,按照时间轴排序,有以下四个标志性事件值得一说:

      1. 2012年6月,《纽约时报》披露了Google Brain项目,这个项目是由Andrew Ng和Map-Reduce发明人Jeff Dean共同主导,用16000个CPU Core的并行计算平台训练一种称为“深层神经网络”的机器学习模型,在语音识别和图像识别等领域获得了巨大的成功。Andrew Ng就是文章开始所介绍的机器学习的大牛。 
      2. 2012年11月,微软在中国天津的一次活动上公开演示了一个全自动的同声传译系统,讲演者用英文演讲,后台的计算机一气呵成自动完成语音识别、英中机器翻译,以及中文语音合成,效果非常流畅,其中支撑的关键技术是深度学习; 
      3. 2013年1月,在百度的年会上,创始人兼CEO李彦宏高调宣布要成立百度研究院,其中第一个重点方向就是深度学习,并为此而成立深度学习研究院(IDL)。 
      4. 2013年4月,《麻省理工学院技术评论》杂志将深度学习列为2013年十大突破性技术(Breakthrough Technology)之首。

      神经网络研究领域领军者Hinton在2006年提出了神经网络Deep Learning算法,使神经网络的能力大大提高,向支持向量机发出挑战。Deep Learning假设神经网络是多层的,首先用RestrictedBoltzmann Machine(非监督学习)学习网络的结构,然后再通过Back Propagation(监督学习)学习网络的权值。

      深度学习算法是对人工神经网络的发展。 在近期赢得了很多关注, 深度学习试图建立大得多也复杂得多的神经网络。很多深度学习的算法是半监督式学习算法,用来处理存在少量未标识数据的大数据集。常见的深度学习算法包括:受限波尔兹曼机(Restricted Boltzmann Machine, RBN), Deep Belief Networks(DBN),卷积网络(Convolutional Network), 堆栈式自动编码器(Stacked Auto-encoders)。

      总之,deep learning能够得到更好地表示数据的feature,同时由于模型的层次、参数很多,capacity足够,因此,模型有能力表示大规模数据,所以对于图像、语音这种特征不明显(需要手工设计且很多没有直观物理含义)的问题,能够在大规模训练数据上取得更好的效果。此外,从模式识别特征和分类器的角 度,deep learning框架将feature和分类器结合到一个框架中,用数据去学习feature,在使用中减少了手工设计feature的巨大工作量(这是目前工业界工程师付出努力最多的方面),因此,不仅仅效果可以更好,而且,使用起来也有很多方便之处。


    Deep Learning与传统的神经网络异同:

    • 相同点: Deep Learning采用了神经网络相似的分层结构,系统由包括输入层、隐层(多层)、输出层组成的多层网络,只有相邻层节点之间有连接,同一层以及跨层节点之间相互无连接,每一层可以看作是一个Logistic Regression模型;这种分层结构,是比较接近人类大脑的结构的。

    • 不同点:而为了克服神经网络训练中的问题,DL采用了与神经网络很不同的训练机制。传统神经网络中,采用的是Back Propagation的方式进行,简单来讲就是采用迭代的算法来训练整个网络,随机设定初值,计算当前网络的输出,然后根据当前输出和label之间的 差去改变前面各层的参数,直到收敛(整体是一个梯度下降法)。而DeepLearning整体上是一个Layer-Wise的训练机制。这样做的原因是因为,如果采用Back Propagation的机制,对于一个Deep Network(7层以上),残差传播到最前面的层已经变得太小,出现所谓的Gradient Diffusion。

    2.11 降低维度算法(无监督学习)

    这里写图片描述

      像聚类算法一样,降低维度算法试图分析数据的内在结构,不过降低维度算法是以非监督学习的方式试图利用较少的信息来归纳或者解释数据。这类算法可以用于高维数据的可视化或者用来简化数据以便监督式学习使用。常见的算法包括:主成份分析(Principle Component Analysis, PCA),偏最小二乘回归(Partial Least Square Regression,PLS), Sammon映射,多维尺度(Multi-Dimensional Scaling, MDS), 投影追踪(Projection Pursuit)等。

      其主要特征是将数据从高维降低到低维层次。在这里,维度其实表示的是数据的特征量的大小,例如,房价包含房子的长、宽、面积与房间数量四个特征,也就是维度为4维的数据。可以看出来,长与宽事实上与面积表示的信息重叠了,例如面积=长 × 宽。通过降维算法我们就可以去除冗余信息,将特征减少为面积与房间数量两个特征,即从4维的数据压缩到2维。于是我们将数据从高维降低到低维,不仅利于表示,同时在计算上也能带来加速。

      刚才说的降维过程中减少的维度属于肉眼可视的层次,同时压缩也不会带来信息的损失(因为信息冗余了)。如果肉眼不可视,或者没有冗余的特征,降维算法也能工作,不过这样会带来一些信息的损失。但是,降维算法可以从数学上证明,从高维压缩到的低维中最大程度地保留了数据的信息。因此,使用降维算法仍然有很多的好处。

      降维算法的主要作用是压缩数据与提升机器学习其他算法的效率。通过降维算法,可以将具有几千个特征的数据压缩至若干个特征。另外,降维算法的另一个好处是数据的可视化,例如将5维的数据压缩至2维,然后可以用二维平面来可视。降维算法的主要代表是PCA算法(即主成分分析算法)。

    2.12 集成算法

    这里写图片描述

      集成算法用一些相对较弱的学习模型独立地就同样的样本进行训练,然后把结果整合起来进行整体预测。集成算法的主要难点在于究竟集成哪些独立的较弱的学习模型以及如何把学习结果整合起来。这是一类非常强大的算法,同时也非常流行。常见的算法包括:Boosting, Bootstrapped Aggregation(Bagging), AdaBoost,堆叠泛化(Stacked Generalization, Blending),梯度推进机(Gradient Boosting Machine, GBM),随机森林(Random Forest)。

    第四部分:模型集成与融合

    在机器学习训练完模型之后我们要考虑模型的效率问题,常用的模型效率分析手段有:

    • 研究模型学习曲线,判断模型是否过拟合或者欠拟合,并做出相应的调整;
    • 对于模型权重参数进行分析,对于权重绝对值高/低的特征,可以对特征进行更细化的工作,也可以进行特征组合;
    • 进行bad-case分析,对错误的例子分析是否还有什么可以修改挖掘
    • 模型融合:模型融合就是训练多个模型,然后按照一定的方法集成过个模型,应为它容易理解、实现也简单,同时效果也很好,在工业界的很多应用,在天池、kaggle比赛中也经常拿来做模型集成。

    这篇文章主要机器学习中的模型融合,包括bagging,Boosting两种思想的方法。

    一、模型融合的认识、分析: 
    1,模型融合的概念: 下图介绍了模型融合的一般结构:先产生一组”个体学习器 ,再用某种策略将它们结合起来,加强模型效果。 
    这里写图片描述

    2,模型融合应用广发的原因: 可以通过数学证明模型,随着集成中个体分类器数目T 的增大,集成的错误率将指数级下降,最终趋向于零。具体证明在周志华和李航老师的书中都有。

    3,模型融合的条件:个体学习器准确性越高、多样性越大,则融合越好。(这里写图片描述,E代表融合后的误差加权均值,这里写图片描述代表个体学习器的误差加权均值,这里写图片描述代表模型的多样性,也就是各个模型之间的分歧值)

    Base Model 之间的相关性要尽可能的小。这就是为什么非 Tree-based Model 往往表现不是最好但还是要将它们包括在 Ensemble 里面的原因。Ensemble 的 Diversity 越大,最终 Model 的 Bias 就越低。 
    Base Model 之间的性能表现不能差距太大。这其实是一个 Trade-off,在实际中很有可能表现相近的 Model 只有寥寥几个而且它们之间相关性还不低。但是实践告诉我们即使在这种情况下 Ensemble 还是能大幅提高成绩。

    4,模型融合的分类: 按照个体学习器的关系可以分为两类:

    • 个体学习器问存在强依赖关系、必须串行生成的序列化方法,代表Boosting方法;
    • 个体学习器间不存在强依赖关系、可同时生成的并行化方法,代表是Bagging 和”随机森林” 。

    二、个体学习器依赖的融合-boosting: 
    1,boosting方法的思想: 
    Boosting算法的工作机制是首先从训练集用初始权重训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器2;如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器。 
    这里写图片描述

    2,Boosting系列算法里最著名算法主要有AdaBoost算法和提升树(boosting tree)系列算法。提升树系列算法里面应用最广泛的是梯度提升树(Gradient Boosting Tree)。

    AdaBoost算法:是加法模型、损失函数为指数函数、学习算法为前向分布算法时的二分类算法。

    提升树:是加法模型、学习算法为前向分布算法时的算法。不过它限定基本学习器为决策树。对于二分类问题,损失函数为指数函数,就是把AdaBoost算法中的基本学习器限定为二叉决策树就可以了;对于回归问题,损失函数为平方误差,此时,拟合的是当前模型的残差。

    梯度提升树:是对提升树算法的改进,提升树算法只适合误差函数为指数函数和平方误差,对于一般的损失函数,梯度提升树算法利用损失函数的负梯度在当前模型的值,作为残差的近似值。(GBDT算法有两种描述思路,一个是基于残差的版本(当损失函数是均方差损失时,因为对均方差求导后就是2(y-y_hat) 就是真实值和预测值得残差方向,一个是基于梯度gradient的版本(当损失函数是其它损失函数时,例如交叉熵损失)。说白了都是基于梯度的,只不过均方差求导后变成残差了)

    三、个体学习器不依赖依赖的融合-bagging: 
    1,bagging方法的思想: bagging算法的思想是通过对样本采样的方式,使我们的基本学习器存在较大的差异。 
    这里写图片描述

    2,bagging系类算法 常见有bagging算法和随机深林算法

    bagging算法:采用的是自助采样法(Bootstap sampling),即对于m个样本的原始训练集,我们每次先随机采集一个样本放入采样集,接着把该样本放回,也就是说下次采样时该样本仍有可能被采集到,这样采集m次,最终可以得到m个样本的采样集,由于是随机采样,这样每次的采样集是和原始训练集不同的,和其他采样集也是不同的,这样得到多个不同的弱学习器。

    随机森林: 是对bagging算法的改进。改进一:基本学习器限定为决策树,改进二:除了bagging的在样本上加上扰动,同时在属性上也加上扰动,即是在决策树学习的过程中引入了随机属性选择,对基决策树的每个结点,先从该结点的属性集合中随机选择一个包含k个属性的子集,然后再从这个子集中选择一个最优属性用于划分。

    四、模型融合的结合策略: 基本学习器学习完后,需要将各个模型进行融合,常见的策略有:

    1,平均法: 平均法有一般的评价和加权平均,这个好理解。对于平均法来说一般用于回归预测模型中,在Boosting系列融合模型中,一般采用的是加权平均融合。

    2,投票法:有绝对多数投票(得票超过一半),相对多数投票(得票最多),加权投票。这个也好理解,一般用于分类模型。在bagging模型中使用。

    3,学习法:一种更为强大的结合策略是使用”学习法”,即通过另一个学习器来进行结合,把个体学习器称为初级学习器,用于结合的学习器称为次级学习器或元学习器。常见的有Stacking和Blending两种 
    (1)Stacking方法: Stacking 先从初始数据集训练出初级学习器,然后”生成”一个新数据集用于训练次级学习器。在这个新数据集中,初级学习器的输出被当作样例输入特征,而初始样本的标记仍被当作样例标记。 
    stacking一般使用交叉验证的方式,初始训练集D 被随机划分为k 个大小相似的集合D1 , D2 , … , Dk,每次用k-1个部分训练T个模型,对另个一个部分产生T个预测值作为特征,遍历每一折后,也就得到了新的特征集合,标记还是源数据的标记,用新的特征集合训练一个集合模型。

    这里写图片描述
    (2)Blending方法: Blending与Stacking大致相同,只是Blending的主要区别在于训练集不是通过K-Fold的CV策略来获得预测值从而生成第二阶段模型的特征,而是建立一个Holdout集,例如说10%的训练数据,第二阶段的stacker模型就基于第一阶段模型对这10%训练数据的预测值进行拟合。说白了,就是把Stacking流程中的K-Fold CV 改成 HoldOut CV。

    五、多样性增强: 模型的多样性可以改善融合后的效果,增强的手段有:

    • 数据样本的扰动:bagging中提到的给定初始数据集, 可从中产生出不同的数据子集, 再利用不同的数据子集训练出不同的个体学习器。
    • 输入属性的扰动:随机深林提到的使用控制属性的子空间的不同,产生差异较大的模型。
    • 输出表示的扰动:输出表示进行操纵以增强多样性,可对训练样本的类标记稍作变动。
    • 算法参数的扰动:基学习算法一般都有参数需进行设置,例如神经网络的隐层神经元数、初始连接权值等,通过随机设置不同的参数,往往可产生差别较大的个体学习器。

    六、bagging、boosting的对比: Bagging主要在优化variance(即模型的鲁棒性),boosting主要在优化bias(即模型的精确性) 
    bagging: Bagging 是 Bootstrap Aggregating 的简称,意思就是再取样 (Bootstrap) 然后在每个样本上训练出来的模型取平均,所以是降低模型的 variance。 
    由于E[\frac{\sum X_i}{n}]=E[X_i],所以bagging后的bias和单个子模型的接近,一般来说不能显著降低bias。另一方面,若各子模型独立,则有Var(\frac{\sum X_i}{n})=\frac{Var(X_i)}{n},此时可以显著降低variance。 
    Boosting: boosting从优化角度来看,是用forward-stagewise这种贪心法去最小化损失函数(指数函数),boosting是在sequential地最小化损失函数,其bias自然逐步下降。但由于是采取这种sequential、adaptive的策略,各子模型之间是强相关的,于是子模型之和并不能显著降低variance。所以说boosting主要还是靠降低bias来提升预测精度。

    第五部分:数据增强

    为什么需要数据增强 :

    一般而言,比较成功的神经网络需要大量的参数,许许多多的神经网路的参数都是数以百万计,而使得这些参数可以正确工作则需要大量的数据进行训练,而实际情况中数据并没有我们想象中的那么多

    数据增强的作用 :

    1. 增加训练的数据量,提高模型的泛化能力
    2. 增加噪声数据,提升模型的鲁棒性

    如何获得大量的数据 :

    一种方法是获得新的数据,这种方法比较麻烦,需要大量的成本,而第二种方法则是对数据进行增强,即利用已有的数据比如翻转、平移或旋转,创造出更多的数据,来使得神经网络具有更好的泛化效果。

    数据增强的分类 :

    数据增强可以分为两类,一类是离线增强,一类是在线增强。

    1. 离线增强 : 直接对数据集进行处理,数据的数目会变成增强因子 x 原数据集的数目 ,这种方法常常用于数据集很小的时候
    2. 在线增强 : 这种增强的方法用于,获得 batch 数据之后,然后对这个 batch 的数据进行增强,如旋转、平移、翻折等相应的变化,由于有些数据集不能接受线性级别的增长,这种方法长用于大的数据集,很多机器学习框架已经支持了这种数据增强方式,并且可以使用 GPU 优化计算。

    常用的数据增强技术 :

    首先定义增强因子 : 指的是数据做离线增强之后增长的倍数。

    1. 翻转 :增强因子 2 或 3 
      数据翻转是一种常用的数据增强方法,这种方法不同于旋转 180 这种方法是做一种类似于镜面的翻折。 
      从左到右 :原图 水平翻转 垂直翻转

    2. 旋转 : 增强因子 2 到 4 
      旋转就是顺时针或者逆时针的旋转,注意在旋转的时候, 最好旋转 90 - 180 度否则会出现尺度的问题 
      这里写图片描述

    3. 缩放 :增强因子任意 
      图像可以被放大或缩小。放大时,放大后的图像尺寸会大于原始尺寸。大多数图像处理架构会按照原始尺寸对放大后的图像 进行裁切。我们将在下一章节讨论图像缩小,因为图像缩小会减小图像尺寸,这使我们不得不对图像边界之外的东西做出假设。下面是图像缩放的例子。 
      这里写图片描述

    4. 裁剪 :增强因子任意 
      这种方法更流行的叫法是随机裁剪,我们随机从图像中选择一部分,然后降这部分图像裁剪出来,然后调整为原图像的大小 
      这里写图片描述

    5. 平移 : 增强因子任意 
      平移是将图像沿着 x 或者 y 方向 (或者两个方向) 移动。我们在平移的时候需对背景进行假设,比如说假设为黑色等等,因为平移的时候有一部分图像是空的,由于图片中的物体可能出现在任意的位置,所以说平移增强方法十分有用。 
      这里写图片描述

    6. 添加噪声 :增强因子任意 看噪声的类型 
      过拟合通常发生在神经网络学习高频特征的时候 (因为低频特征神经网络很容易就可以学到,而高频特征只有在最后的时候才可以学到) 而这些特征对于神经网络所做的任务可能没有帮助,而且会对低频特征产生影响,为了消除高频特征我们随机加入噪声数据来消除这些特征。 
      这里写图片描述

    图像增强的效果 :

    图像增强非常必要,我也有过亲自的实验,特别是有些论文中,如果不进行图片增强,就无法达到论文中提到的效果,下面展现一下图片增强的效果示意图 : 
    这里写图片描述

    图中 :C10 和 C100 是没有经过图片增强的,C10+ 和 C100+ 是经过了图片增强的。

    展开全文
  • 方法的选择取决问题的类型(分类、回归、聚类)、数据的类型(图像、图形、时间系列、音频等等)以及方法本身的配置(调优)。 在本文中,我们将使用 Python 中最著名的三个模块来实现一个简单的线性回归模型。 ...

    机器学习是人工智能的一门子科学,其中计算机和机器通常学会在没有人工干预或显式编程的情况下自行执行特定任务(当然,首先要对他们进行训练)。 不同类型的机器学习技术可以划分到不同类别,如图 1 所示。方法的选择取决于问题的类型(分类、回归、聚类)、数据的类型(图像、图形、时间系列、音频等等)以及方法本身的配置(调优)。

    在本文中,我们将使用 Python 中最著名的三个模块来实现一个简单的线性回归模型。 使用 Python 的原因是它易于学习和应用。 我们将使用的三个模块是:

    1- Numpy:可以用于数组、矩阵、多维矩阵以及与它们相关的所有操作。

    2- Keras:TensorFlow 的高级接口。 它也用于支持和实现深度学习模型和浅层模型。 它是由谷歌工程师开发的。

    3- PyTorch:基于 Torch 的深度学习框架。 它是由 Facebook 开发的。

    所有这些模块都是开源的。 Keras(TF) 和 PyTorch 都支持使用 GPU 来加快执行速度。

    以下部分介绍线性回归的理论和概念。 如果您已经熟悉理论并且想要实践部分,可以跳过到下一部分。

    线性回归

    它是一种数学方法,可以将一条线与基础数据拟合。 它假设输出和输入之间存在线性关系。 输入称为特征或解释变量,输出称为目标或因变量。 输出变量必须是连续的。 例如,价格、速度、距离和温度。 以下等式在数学上表示线性回归模型:

    Y = W*X + B

    如果把这个方程写成矩阵形式。 Y 是输出矩阵,X 是输入矩阵,W 是权重矩阵,B 是偏置向量。 权重和偏置是线性回归参数。 有时权重和偏置分别称为斜率和截距。

    训练该模型的第一步是随机初始化这些参数。 然后它使用输入的数据来计算输出。 通过测量误差将计算出的输出与实际输出进行比较,并相应地更新参数。并重复上述步骤。该误差称为 L2 范数(误差平方和),由下式给出:

    计算误差的函数又被称作损失函数,它可以有不同的公式。 i 是数据样本数,y 是预测输出,t 是真实目标。 根据以下等式中给出的梯度下降规则更新参数:

    在这里,𝜂(希腊字母 eta)是学习率,它指定参数的更新步骤(更新速度)。 𝛿(希腊字母 delta)只是预测输出和真实输出之间的差异。 i 代表迭代(所谓的轮次)。 𝛻 L(W) 是损失函数相对于权重的梯度(导数)。 关于学习率的价值,有一点值得一提。 较小的值会导致训练速度变慢,而较大的值会导致围绕局部最小值或发散(无法达到损失函数的局部最小值)的振荡。 图 2 总结了以上所有内容。

    现在让我们深入了解每个模块并将上面的方法实现。

    Numpy 实现

    我们将使用 Google Colab 作为我们的 IDE(集成开发环境),因为它功能强大,提供了所有必需的模块,无需安装(部分模块除外),并且可以免费使用。

    为了简化实现,我们将考虑具有单个特征和偏置 (y = w1*x1 + b) 的线性关系。

    让我们首先导入 Numpy 模块来实现线性回归模型和 Matplotlib 进行可视化。

    # Numpy is needed to build the model
    import numpy as np
    # Import the module matplotlib for visualizing the data
    import matplotlib.pyplot as plt
    

    我们需要一些数据来处理。 数据由一个特征和一个输出组成。 对于特征生成,我们将从随机均匀分布中生成 1000 个样本。

    # We use this line to make the code reproducible (to get the same results when running)
    np.random.seed(42)
    # First, we should declare a variable containing the size of the training set we want to generate
    observations = 1000
    
    # Let us assume we have the following relationship
    # y = 13x + 2
    # y is the output and x is the input or feature
    # We generate the feature randomly, drawing from an uniform distribution. There are 3 arguments of this method (low, high, size).
    # The size of x is observations by 1. In this case: 1000 x 1.
    x = np.random.uniform(low=-10, high=10, size=(observations,1))
    
    # Let us print the shape of the feature vector
    print (x.shape)
    

    为了生成输出(目标),我们将使用以下关系:

    Y = 13 * X + 2 + 噪声

    这就是我们将尝试使用线性回归模型来估计的。 权重值为 13,偏置为 2。噪声变量用于添加一些随机性。

    np.random.seed(42)
    # We add a small noise to our function for more randomness
    noise = np.random.uniform(-1, 1, (observations,1))
    
    # Produce the targets according to the f(x) = 13x + 2 + noise definition.
    # This is a simple linear relationship with one weight and bias.
    # In this way, we are basically saying: the weight is 13 and the bias is 2.
    targets = 13*x + 2 + noise
    
    # Check the shape of the targets just in case. It should be n x m, where n is the number of samples
    # and m is the number of output variables, so 1000 x 1.
    print (targets.shape)
    

    让我们绘制生成的数据。

    # Plot x and targets
    plt.plot(x,targets)
    
    # Add labels to x axis and y axis
    plt.ylabel('Targets')
    plt.xlabel('Input')
    
    # Add title to the graph
    plt.title('Data')
    
    # Show the plot
    plt.show()
    

    图 3 显示了这种线性关系:

    对于模型训练,我们将从参数的一些初始值开始。 它们是从给定范围内的随机均匀分布生成的。 您可以看到这些值与真实值相差甚远。

    np.random.seed(42)
    # We will initialize the weights and biases randomly within a small initial range.
    # init_range is the variable that will measure that.
    init_range = 0.1
    
    # Weights are of size k x m, where k is the number of input variables and m is the number of output variables
    # In our case, the weights matrix is 1 x 1, since there is only one input (x) and one output (y)
    weights = np.random.uniform(low=-init_range, high=init_range, size=(1, 1))
    
    # Biases are of size 1 since there is only 1 output. The bias is a scalar.
    biases = np.random.uniform(low=-init_range, high=init_range, size=1)
    
    # Print the weights to get a sense of how they were initialized.
    # You can see that they are far from the actual values.
    print (weights)
    print (biases)
    
    [[-0.02509198]]
    [0.09014286]
    

    我们还为我们的训练设置了学习率。 我们选择了 0.02 的值。 这里可以通过尝试不同的值来探索性能。 我们有了数据,初始化了参数,并设置了学习率,已准备好开始训练过程。 我们通过将 epochs 设置为 100 来迭代数据。在每个 epoch 中,我们使用初始参数来计算新输出并将它们与实际输出进行比较。 损失函数用于根据前面提到的梯度下降规则更新参数。 新更新的参数用于下一次迭代。 这个过程会不断重复,直到达到 epoch 数。 可以有其他停止训练的标准,但我们今天不讨论它。

    # Set some small learning rate 
    # 0.02 is going to work quite well for our example. Once again, you can play around with it.
    # It is HIGHLY recommended that you play around with it.
    learning_rate = 0.02
    
    # We iterate over our training dataset 100 times. That works well with a learning rate of 0.02.
    # We call these iteration epochs.
    # Let us define a variable to store the loss of each epoch.
    losses = []
    for i in range (100):
        
        # This is the linear model: y = xw + b equation
        outputs = np.dot(x,weights) + biases
        # The deltas are the differences between the outputs and the targets
        # Note that deltas here is a vector 1000 x 1
        deltas = outputs - targets
            
        # We are considering the L2-norm loss as our loss function (regression problem), but divided by 2.
        # Moreover, we further divide it by the number of observations to take the mean of the L2-norm.
        loss = np.sum(deltas ** 2) / 2 / observations
        
        # We print the loss function value at each step so we can observe whether it is decreasing as desired.
        print (loss)
    
        # Add the loss to the list 
        losses.append(loss)
        
        # Another small trick is to scale the deltas the same way as the loss function
        # In this way our learning rate is independent of the number of samples (observations).
        # Again, this doesn't change anything in principle, it simply makes it easier to pick a single learning rate
        # that can remain the same if we change the number of training samples (observations).
        deltas_scaled = deltas / observations
        
        # Finally, we must apply the gradient descent update rules.
        # The weights are 1 x 1, learning rate is 1 x 1 (scalar), inputs are 1000 x 1, and deltas_scaled are 1000 x 1
        # We must transpose the inputs so that we get an allowed operation.
        weights = weights - learning_rate * np.dot(x.T,deltas_scaled)
        biases = biases - learning_rate * np.sum(deltas_scaled)
        
        # The weights are updated in a linear algebraic way (a matrix minus another matrix)
        # The biases, however, are just a single number here, so we must transform the deltas into a scalar.
        # The two lines are both consistent with the gradient descent methodology. 
    

    我们可以观察每个轮次的训练损失。

    # Plot epochs and losses
    plt.plot(range(100),losses)
    
    # Add labels to x axis and y axis
    plt.ylabel('loss')
    plt.xlabel('epoch')
    
    # Add title to the graph
    plt.title('Training')
    
    # Show the plot
    # The curve is decreasing in each epoch, which is what we need
    # After several epochs, we can see that the curve is flattened.
    # This means the algorithm has converged and hence there are no significant updates
    # or changes in the weights or biases.
    plt.show()
    

    正如我们从图 4 中看到的,损失在每个 epoch 中都在减少。 这意味着模型越来越接近参数的真实值。 几个 epoch 后,损失没有显着变化。 这意味着模型已经收敛并且参数不再更新(或者更新非常小)。

    此外,我们可以通过绘制实际输出和预测输出来验证我们的模型在找到真实关系方面的指标。

    # We print the real and predicted targets in order to see if they have a linear relationship.
    # There is almost a total match between the real targets and predicted targets.
    # This is a good signal of the success of our machine learning model.
    plt.plot(outputs,targets, 'bo')
    plt.xlabel('Predicted')
    plt.ylabel('Real')
    plt.show()
    
    # We print the weights and the biases, so we can see if they have converged to what we wanted.
    # We know that the real weight is 13 and the bias is 2
    print (weights, biases)
    

    这将生成如图 5 所示的图形。我们甚至可以打印最后一个 epoch 之后的参数值。 显然,更新后的参数与实际参数非常接近。

    [[13.09844702]] [1.73587336]
    

    Numpy 实现线性回归模型就是这样。

    Keras 实现

    我们首先导入必要的模块。 TensorFlow 是这个实现的核心。 它是构建模型所必需的。 Keras 是 TensorFlow 的抽象,以便于使用。

    # Numpy is needed to generate the data
    import numpy as np
    # Matplotlib is needed for visualization
    import matplotlib.pyplot as plt
    # TensorFlow is needed for model build
    import tensorflow as tf
    

    为了生成数据(特征和目标),我们使用了 Numpy 中生成数据的代码。 我们添加了一行来将 Numpy 数组保存在一个文件中,以防我们想将它们与其他模型一起使用(可能不需要,但添加它不会有什么坏处)。

    np.savez('TF_intro', inputs=x, targets=targets)
    

    Keras 有一个 Sequential 的类。 它用于堆叠创建模型的层。 由于我们只有一个特征和输出,因此我们将只有一个称为密集层的层。 这一层负责线性变换 (W*X +B),这是我们想要的模型。 该层有一个称为神经元的计算单元用于输出计算,因为它是一个回归模型。 对于内核(权重)和偏置初始化,我们在给定范围内应用了均匀随机分布(与 Numpy 中相同,但是在层内指定)。

    # Declare a variable where we will store the input size of our model
    # It should be equal to the number of variables you have
    input_size = 1
    # Declare the output size of the model
    # It should be equal to the number of outputs you've got (for regressions that's usually 1)
    output_size = 1
    
    # Outline the model
    # We lay out the model in 'Sequential'
    # Note that there are no calculations involved - we are just describing our network
    model = tf.keras.Sequential([
                                # Each 'layer' is listed here
                                # The method 'Dense' indicates, our mathematical operation to be (xw + b)
                                tf.keras.layers.Input(shape=(input_size , )),
                                tf.keras.layers.Dense(output_size,
                                                     # there are extra arguments you can include to customize your model
                                                     # in our case we are just trying to create a solution that is 
                                                     # as close as possible to our NumPy model
                                                     # kernel here is just another name for the weight parameter
                                                     kernel_initializer=tf.random_uniform_initializer(minval=-0.1, maxval=0.1),
                                                     bias_initializer=tf.random_uniform_initializer(minval=-0.1, maxval=0.1)
                                                     )
                                ])
    
    # Print the structure of the model
    model.summary()
    

    为了训练模型,keras提供 fit 的方法可以完成这项工作。 因此,我们首先加载数据,指定特征和标签,并设置轮次。 在训练模型之前,我们通过选择合适的优化器和损失函数来配置模型。 这就是 compile 的作用。 我们使用了学习率为 0.02(与之前相同)的随机梯度下降,损失是均方误差。

    # Load the training data from the NPZ
    training_data = np.load('TF_intro.npz')
    
    # We can also define a custom optimizer, where we can specify the learning rate
    custom_optimizer = tf.keras.optimizers.SGD(learning_rate=0.02)
    
    # 'compile' is the place where you select and indicate the optimizers and the loss
    # Our loss here is the mean square error
    model.compile(optimizer=custom_optimizer, loss='mse')
    
    # finally we fit the model, indicating the inputs and targets
    # if they are not otherwise specified the number of epochs will be 1 (a single epoch of training), 
    # so the number of epochs is 'kind of' mandatory, too
    # we can play around with verbose; we prefer verbose=2
    model.fit(training_data['inputs'], training_data['targets'], epochs=100, verbose=2)
    

    我们可以在训练期间监控每个 epoch 的损失,看看是否一切正常。 训练完成后,我们可以打印模型的参数。 显然,模型已经收敛了与实际值非常接近的参数值。

    # Extracting the weights and biases is achieved quite easily
    model.layers[0].get_weights()
    
    # We can save the weights and biases in separate variables for easier examination
    # Note that there can be hundreds or thousands of them!
    weights = model.layers[0].get_weights()[0]
    
    bias = model.layers[0].get_weights()[1]
    bias,weights
    
    (array([1.9999999], dtype=float32), array([[13.1]], dtype=float32))
    

    当您构建具有数千个参数和不同层的复杂模型时,TensorFlow 可以为您节省大量精力和代码行。 由于模型太简单,这里并没有显示keras的优势。

    PyTorch 实现

    我们导入 Torch。这是必须的,因为它将用于创建模型。

    # Numpy is needed for data generation
    import numpy as np
    # Pytorch is needed for model build
    import torch
    

    数据生成部分未显示,因为它与前面使用的代码相同。 但是Torch 只处理张量(torch.Tensor)。所以需要将特征和目标数组都转换为张量。 最后,从这两个张量创建一个张量数据集。

    # TensorDataset is needed to prepare the training data in form of tensors
    from torch.utils.data import TensorDataset
    
    # To run the model on either the CPU or GPU (if available)
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    
    # Since torch deals with tensors, we convert the numpy arrays into torch tensors
    x_tensor = torch.from_numpy(x).float()
    y_tensor = torch.from_numpy(targets).float()
    
    # Combine the feature tensor and target tensor into torch dataset
    train_data = TensorDataset(x_tensor , y_tensor)
    
    

    模型的创建很简单。 与keras类似,Sequential 类用于创建层堆栈。 我们只有一个线性层(keras叫密集层),一个输入和一个输出。 模型的参数使用定义的函数随机初始化。 为了配置模型,我们设置了学习率、损失函数和优化器。 还有其他参数需要设置,这里不做介绍。

    # Initialize the seed to make the code reproducible
    torch.manual_seed(42)
    
    # This function is for model's parameters initialization
    def init_weights(m):
        if isinstance(m, torch.nn.Linear):
            torch.nn.init.uniform_(m.weight , a = -0.1 , b = 0.1)
            torch.nn.init.uniform_(m.bias , a = -0.1 , b = 0.1)
    
    # Define the model using Sequential class
    # It contains only a single linear layer with one input and one output
    model = torch.nn.Sequential(torch.nn.Linear(1 , 1)).to(device)
    
    # Initialize the model's parameters using the defined function from above
    model.apply(init_weights)
    
    # Print the model's parameters
    print(model.state_dict())
    
    # Specify the learning rate
    lr = 0.02
    
    # The loss function is the mean squared error
    loss_fn = torch.nn.MSELoss(reduction = 'mean')
    
    # The optimizer is the stochastic gradient descent with a certain learning rate
    optimizer = torch.optim.SGD(model.parameters() , lr = lr)
    

    我们将使用小批量梯度下降训练模型。 DataLoader 负责从训练数据集创建批次。 训练类似于keras的实现,但使用不同的语法。 关于 Torch训练有几点补充:

    1- 模型和批次必须在同一设备(CPU 或 GPU)上。

    2- 模型必须设置为训练模式。

    3- 始终记住在每个 epoch 之后将梯度归零以防止累积(对 epoch 的梯度求和),这会导致错误的值。

    # DataLoader is needed for data batching
    from torch.utils.data import DataLoader
    
    # Training dataset is converted into batches of size 16 samples each.
    # Shuffling is enabled for randomizing the data
    train_loader = DataLoader(train_data , batch_size = 16 , shuffle = True)
    
    # A function for training the model
    # It is a function of a function (How fancy)
    def make_train_step(model , optimizer , loss_fn):
      def train_step(x , y):
        # Set the model to training mode
        model.train()
        # Feedforward the model with the data (features) to obtain the predictions
        yhat = model(x)
        # Calculate the loss based on the predicted and actual targets
        loss = loss_fn(y , yhat)
        # Perform the backpropagation to find the gradients
        loss.backward()
        # Update the parameters with the calculated gradients
        optimizer.step()
        # Set the gradients to zero to prevent accumulation
        optimizer.zero_grad()
        return loss.item()
      return train_step
    
    # Call the training function
    train_step = make_train_step(model , optimizer , loss_fn)
    
    # To store the loss of each epoch
    losses = []
    
    # Set the epochs to 100
    epochs = 100
    
    # Run the training function in each epoch on the batches of the data
    # This is why we have two for loops
    # Outer loop for epochs
    # Inner loop for iterating through the training data batches
    for epoch in range(epochs):
      # To accumulate the losses of all batches within a single epoch
      batch_loss = 0
      for x_batch , y_batch in train_loader:
        x_batch = x_batch.to(device)
        y_batch = y_batch.to(device)
        loss = train_step(x_batch , y_batch)
        batch_loss = batch_loss + loss
      # 63 is not a magic number. It is the number of batches in the training set
      # we have 1000 samples and the batch size is 16 (defined in the DataLoader)
      # 1000/16 = 63
      epoch_loss = batch_loss / 63
      losses.append(epoch_loss)
    
    # Print the parameters after the training is done
    print(model.state_dict())
    
    OrderedDict([('0.weight', tensor([[13.0287]], device='cuda:0')), ('0.bias', tensor([2.0096], device='cuda:0'))])
    

    作为最后一步,我们可以绘制 epoch 上的训练损失以观察模型的性能。 如图 6 所示。

    完成。 让我们总结一下到目前为止我们学到的东西。

    总结

    线性回归被认为是最容易实现和解释的机器学习模型之一。 在本文中,我们使用 Python 中的三个不同的流行模块实现了线性回归。 还有其他模块可用于创建。 例如,Scikitlearn。

    本文的代码在这里可以找到:https://github.com/Motamensalih/Simple-Linear-Regression

    作者:Motamen MohammedAhmed

    展开全文
  • 机器学习入门--神经元模型

    千次阅读 2018-05-07 22:52:44
    人工神经元模型我们高中都学习过神经大概是个什么样子。通常是由一个神经细胞都有树突、轴突、细胞核等等。树突可以接受其他神经传来的信号,然后对这些信号进行一下处理传递给下一个神经。在这里我们通过一个...
  • 谈谈机器学习模型的部署

    千次阅读 2019-02-19 10:58:58
    随着机器学习的广泛应用,如何高效的把训练好的机器学习模型部署到生产环境,正在被越来越多的工具所支持。我们今天就来看一看不同的工具是如何解决这个问题的。 上图的过程是一个数据科学项目所要经历的典型的...
  • 机器学习(一元线性回归模型

    千次阅读 2020-01-22 20:50:54
    模型:一元线性回归模型 回归分析:建立方程模拟两个或者多个变量之间是如何相互关联,被预测的变量称为因变量(结果),用来进行预测的变量称为 自变量(输入参数),当输入参数只有一个(输出1个)时,称为一元...
  • 机器学习实践:气象数据分析-10

    千次阅读 2022-01-20 14:57:11
    机器学习实践:气象数据分析 1、实验描述 本节实验主要是针对气象数据进行分析,从实验数据中分析温度、湿度、风力、风向等数据,再利用matplotlib进行绘图,直观展示分析结果,通过本节实验我们能够直观感受到...
  • Python数据分析与机器学习项目实战

    千次阅读 2020-11-08 11:32:46
    时值蚂蚁上市之际,马云在上海滩发表演讲。马云的核心逻辑其实只有一个,在全球数字经济时代,有且只有一种金融优势,...更准确的说谁能掌握机器学习数据分析能力,谁就掌握了数字货币的发行权! 来自南京大学、.
  • 精心挑选的100多种机器学习数据

    千次阅读 2021-03-07 16:42:13
    大多数数据科学和机器学习初学者做错的事情是,他们只是专注学习许多理论概念,而等待太长时间才能启动专注该概念的实际实现的机器学习/数据科学项目。毫无疑问,从理论上讲清楚您的机器学习概念总会很好,但是...
  • 机器学习实战的数据集在哪找Good machine learning research starts with an exceptional dataset. There is no need to spend your evening crafting your own set of data in MySQL or, god forbid, Excel. ...
  • 基于机器学习技术,无需对加密的恶意流量进行解密,通过分析加密流量中的未加密信息、上下文数据等特征,借助常见的机器学习算法实现对加密流量的分类检测,发现加密恶意流量中潜藏的安全威胁。
  • 前一篇文章普及了基于机器学习的恶意代码检测技术,主要参考郑师兄的视频总结,包括机器学习概述与算法举例、基于机器学习方法的恶意代码检测、机器学习算法在工业界的应用。这篇文章将分享两篇论文,介绍机器学习是...
  • 机器学习算法在训练过程中,做的就是:检查多个样本并尝试找出可最大限度地减少损失的模型;目标就是将损失(Loss)最小化 在这里插入图片描述 上图就是一般模型训练的一般过程(试错过程),其中 模型: 将一个或多...
  • 人工智能AI、机器学习模型理解

    万次阅读 多人点赞 2018-10-22 22:05:00
    模型文件”一般说的是这个算法用到的各种输入、输出数据的值。 因为机器学习往往需要大量的运算,所以有必要将中间变量也存入文件中,以便可以多次地运算。 机器学习是一类算法的通称,具体到某个算法,那模型的...
  • 1、使用了柱状图,零度矩阵,热度图,皮尔逊系数图等多种方式对数据进行可视...4、借助自动学习库,辅助完成模型的挑选 5、尝试了多种模型(XGBoost,LightGBM,Catboost,神经网络,决策树,逻辑回归,SVM)进行预测。
  • 这篇文章将介绍基于机器学习的恶意代码检测技术,主要参考郑师兄的视频总结,包括机器学习概述与算法举例、基于机器学习方法的恶意代码检测、机器学习算法在工业界的应用。同时,我再结合自己的经验进行扩充,详细...
  • Spark-机器学习模型持久化

    千次阅读 2017-08-26 12:25:29
    机器学习模型持久化(机器学习模型的保存和加载)使得以下三类机器学习场景变得容易:数据科学家开发ML模型并移交给工程师团队在生产环境中发布; 数据工程师把一个Python语言开发的机器学习模型训练工作流集成到一...
  • 机器学习基础知识点

    千次阅读 2021-10-24 14:38:12
    文章目录机器学习基础知识点监督学习回归线性回归岭回归lasso回归分类k最近邻分类朴素贝叶斯分类logistic回归支持向量机其他随机梯度下降线性判别分析决策树无监督学习聚类k均值分层次聚类谱聚类高斯混合模型降维PCA...
  • 机器学习练习题

    千次阅读 2021-11-16 10:08:00
    机器学习考试练习题单项选择题多项选择题判断题填空题简答题 单项选择题 1.在NumPy中创建一个元素均为0的数组可以使用( )函数。 [A] A.zeros( ) B.arange( ) C.linspace( ) D.logspace( ) 2.通常( )误差作为...
  • 机器学习实战——美国疫情数据

    千次阅读 2020-09-06 16:00:11
    题目要求 所谓“看花容易绣花难”,学了近一个月机器学习,实战(完全靠自己的项目)还是第一次做,尽管头有点大,但还是很有信心做好的!
  • 机器学习数据预处理方法

    千次阅读 2020-01-03 12:36:30
    熟悉数据挖掘和机器学习的小伙伴们都知道,数据处理相关的工作时间占据了整个项目的70%以上。数据的质量,直接决定了模型的预测和泛化能力的好坏。它涉及很多因素,包括:准确性、完整性、一致性、时效性、可信性和...
  • 机器学习期末考试判断题

    千次阅读 2021-11-13 21:32:36
    1.集合中的元素没有特定顺序但可以重复。 参考答案:错误 集合(set)是一个无序的不重复元素序列。 创建一个空集合必须用 set() 而不是 { },...4.机器学习算法在图像识别领域的性能表现可能会超过人类。 参考答案
  • 机器学习7个主要领域

    万次阅读 多人点赞 2019-06-13 08:24:58
    机器学习是识别隐藏在数据中的可能性并将其转化为完全成熟机会的技术。巧合的是,机会是促进业务运营并在竞争对手中脱颖而出的因素。 了解机器学习算法如何应用各个领域以获得可带来合法业务优势的结果至关重要。...
  • 数据清洗,特征转换,特征选择,降维,异常数据处理及自然语言处理详细介绍。
  • 机器学习过程

    千次阅读 2019-04-18 08:26:22
    机器学习是一个从定义数据开始,最终获得一定准确率的模型的过程。在本节中,我们将学习这个过程。 1.问题定义 机器学习的过程从定义一个商业问题开始。机器学习的需求是什么?这个任务真的需要高级的预测算法来...
  • 分类问题属于机器学习问题的类别,其中给定一组功能,任务是预测离散值。分类问题的一些常见示例是,预测肿瘤是否为癌症,或者学生是否可能通过考试。 在本文中,鉴于银行客户的某些特征,我们将预测客户在6个月后...
  • 机器学习数据预处理及特征工程总结(超详细)

    万次阅读 多人点赞 2017-11-30 11:58:11
    机器学习里有一句名言:数据和特征决定了机器学习的上限,而模型和算法的应用只是让我们逼近这个上限。这个说法形象且深刻的提出前期数据处理和特征分析的重要性。这一点从我们往往用整个数据挖掘全流程60%以上的...
  • 点击上方蓝字关注我们✎编 者 按 在线音频行业在中国仍是蓝海一片。根据 CIC 数据显示,中国在线音频行业市场规模由 2016 年的 16 亿增长至 2020年的 131 亿,...

空空如也

空空如也

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

机器学习 模型文件于元数据