• 机器学习


    定义

    机器学习(Machine Learning, ML)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。
    它是人工智能的核心,是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域。目前,世界上共有几百种不同的机器学习算法。

    机器学习算法类别

    分类与聚类

    Classification (分类)
    给定一堆样本数据以及这些数据所属的类别标签,通过算法来预测新数据的类别,有先验知识。

    对于一个 classifier ,通常需要你告诉它“这个东西被分为某某类”这样一些例子,理想情况下,一个 classifier 会从它得到的训练集中进行“学习”,从而具备对未知数据进行分类的能力,这种提供训练数据的过程通常叫做 supervised learning (监督学习)

    Clustering(聚类)
    事先并不知道一堆数据可以被划分到哪些类,通过算法来发现数据之间的相似性,从而将相似的数据划入相应的类,简单地说就是把相似的东西分到一组,没有先验知识。

    聚类的时候,我们并不关心某一类是什么,我们需要实现的目标只是把相似的东西聚到一起,因此,一个聚类算法通常只需要知道如何计算相似度就可以开始工作了,因此 clustering 通常并不需要使用训练数据进行学习,这在 Machine Learning 中被称作 unsupervised learning (无监督学习).

    常见的分类与聚类算法

    常用的分类算法:k-最近邻法(k-nearest neighbor,kNN),决策树分类法,朴素贝叶斯分类算法(native Bayesian classifier)、支持向量机(SVM)的分类器,神经网络法,模糊分类法等等。

    常见聚类算法: K均值(K-means clustering)聚类算法、K-MEDOIDS算法、CLARANS算法;BIRCH算法、CURE算法、CHAMELEON算法等;基于密度的方法:DBSCAN算法、OPTICS算法、DENCLUE算法等;基于网格的方法:STING算法、CLIQUE算法、WAVE-CLUSTER算法;

    监督学习与无监督学习

    机器学习按照训练数据是否有“先验知识”,一般划分为三类:
    1) 监督学习(supervised learning)
    2) 无监督学习(unsupervised learning)
    3) 半监督学习(semi-supervised learning)

    监督式学习技术需要关于结果的先验知识
    例如,如果我们正在研究一个市场活动的历史数据,我们可以根据市场是否产生预期的反应来对数据进行分类,或决定下一步要花多少钱。监督式学习技术为预测和分类提供了强大的工具。

    无监督学习技术不需要先验知识
    例如,在某些欺诈的案例中,只有当事情发生很久以后,我们才可能知道某次交易是不是欺诈。在这种情况下,与其试图预测哪些交易是欺诈,我们不如使用机器学习来识别那些可疑的交易,并做出标记,以备后续观察。我们对某种特定的结果缺乏先验知识、但仍希望从数据中汲取有用的洞察时,就要用到无监督式学习。

    Kmeans算法

    是一个简单的聚类算法,目的是把n个对象根据他们的属性分为k个分类,k<n。

    优点:算法速度很快
    缺点:分组的数目k是一个输入参数,不合适的k可能返回较差的结果。

     spark kmeans算法demo

    object KMeansDemo {
    
    def main(args: Array[String]) {
    
    val conf = new SparkConf()
    conf.setAppName("ML")
    conf.setMaster("local[*]")
    
    val sc = new SparkContext(conf)
    sc.setLogLevel("ERROR")
    
    // Load and parse the data
    val data = sc.textFile("D:/mllib/kmeans_data.txt")
    // 数据转换成向量,每一行三个数据,因此是三维的
    val parsedData = data.map(s => Vectors.dense(s.split(' ').map(_.toDouble))).cache()
    
    // Cluster the data into two classes using KMeans
    val numClusters = 2
    // 最大迭代次数
    val numIterations = 20
    // 训练KMeansModel数据模型
    val clusters = KMeans.train(parsedData, numClusters, numIterations)
    
    // 打印聚类中心点
    println(" cluster center ")
    for (c <- clusters.clusterCenters) {
    println(" " + c.toString)
    }
    
    // 打印每个点属于哪个分类
    for (data <- parsedData) {
    println(data + " " + clusters.predict(data))
    }
    
    // 预测数据属于哪个类别
    println("Vectors 0.2 0.2 0.2 is belongs to clusters:" + clusters.predict(Vectors.dense("0.2 0.2 0.2".split(' ').map(_.toDouble))))
    println("Vectors 8 8 8 is belongs to clusters:" + clusters.predict(Vectors.dense("8 8 8".split(' ').map(_.toDouble))))
    
    // Evaluate clustering by computing Within Set Sum of Squared Errors
    val WSSSE = clusters.computeCost(parsedData)
    println("Within Set Sum of Squared Errors = " + WSSSE)
    
    // Save and load model
    // clusters.save(sc, "D:/mllib/save/kmeans/")
    // val sameModel = KMeansModel.load(sc, "D:/mllib/save/kmeans/")
    
    sc.stop()
    }
    
    }

    D:/mllib/kmeans_data.txt数据

    0.0 0.0 0.0
    0.1 0.1 0.1
    0.2 0.2 0.2
    9.0 9.0 9.0
    9.1 9.1 9.1
    9.2 9.2 9.2

    朴素贝叶斯算法(Naive Bayes)

    朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。算法的基础是概率问题,分类原理是通过某对象的先验概率,利用贝叶斯公式计算出其后验概率,即该对象属于某一类的概率,选择具有最大后验概率的类作为该对象所属的类。朴素贝叶斯假设是约束性很强的假设,假设特征条件独立,但朴素贝叶斯算法简单,快速,具有较小的出错率。 在朴素贝叶斯的应用中,主要研究了电子邮件过滤以及文本分类研究。

      spark Naive Bayes算法demo

    def main(args: Array[String]) {
    
        val conf = new SparkConf()
        conf.setAppName("ML")
        conf.setMaster("local[*]")
    
        val sc = new SparkContext(conf)
        sc.setLogLevel("ERROR")
    
        // 加载数据
        val data = sc.textFile("D:/mllib/sample_naive_bayes_data.txt")
        // 0,1 0 0 数据格式,第一个0是label,后面的1 0 0是特征
        val parsedData = data.map { line =>
          val parts = line.split(',')
          // 转换数据为LabeledPoint
          LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(' ').map(_.toDouble)))
        }
    
        // 数据分为training(60%)和测试数据(40%).
        val splits = parsedData.randomSplit(Array(0.6, 0.4), seed = 11L)
        val training = splits(0)
        val test = splits(1)
    
        // 开始训练模型  modelType指定方法类型,multinomial或者bernoulli
        val model = NaiveBayes.train(training, lambda = 1.0, modelType = "multinomial")
    
    
        val testData = LabeledPoint(0, Vectors.dense("1 0 0".split(' ').map(_.toDouble)))
    
        // 根据特征预测label
        println("label:" + model.predict(testData.features))
    
    
        // model.predict(p.features) 预测值   p.label 实际值
        val predictionAndLabel = test.map(p => (model.predict(p.features), p.label))
    
        // 计算准确率
        val accuracy = 1.0 * predictionAndLabel.filter(x => x._1 == x._2).count() / test.count()
    
        sc.stop()
      }
    

    数据

    0,1 0 0
    0,2 0 0
    0,3 0 0
    0,4 0 0
    1,0 1 0
    1,0 2 0
    1,0 3 0
    1,0 4 0
    2,0 0 1
    2,0 0 2
    2,0 0 3
    2,0 0 4
    

    K最近邻分类算法(KNN)

    分类算法,分类思想比较简单,从训练样本中找出K个与其最相近的样本,然后看这k个样本中哪个类别的样本多,则待判定的值(或说抽样)就属于这个类别。近朱者赤,近墨者黑。

    SVM

    分类算法,SVM可分为三类:线性可分(linear SVM in linearly separable case)的线性SVM、线性不可分的线性SVM、非线性(nonlinear)SVM

    spark demo

    def main(args: Array[String]) {
    
        val conf = new SparkConf()
        conf.setAppName("ML")
        conf.setMaster("local[*]")
    
        val sc = new SparkContext(conf)
        sc.setLogLevel("ERROR")
    
        // 加载数据,把数据转换成特征向量
        val data = MLUtils.loadLibSVMFile(sc, "D:/mllib/sample_libsvm_data.txt")
    
        // 数据分为training (60%)和test (40%).
        val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L)
        val training = splits(0).cache()
        val test = splits(1)
    
        // 迭代次数
        val numIterations = 200
        val model = SVMWithSGD.train(training, numIterations)
    
        // Clear the default threshold.
        model.clearThreshold()
    
        // 计算预测数据
        val scoreAndLabels = test.map { point =>
          val score = model.predict(point.features)
          // 打印预测值与实际值
          println(score + " : " + point.label)
          (score, point.label)
        }
    
        // 对数据进行评估
        val metrics = new BinaryClassificationMetrics(scoreAndLabels)
        val auROC = metrics.areaUnderROC()
    
        println("Area under ROC = " + auROC)
    
        // 计算正确率
        val trainErr = scoreAndLabels.filter(r => r._1 != r._2).count.toDouble / test.count
    
        println("train error = " + trainErr)
    
        sc.stop()
      }
    

    数据在spark目录spark-2.1.0-bin-hadoop2.7datamllibsample_libsvm_data.txt

    Logistic regression

    分类算法,主要在流行病学中应用较多,比较常用的情形是探索某疾病的危险因素,根据危险因素预测某疾病发生的概率

    def main(args: Array[String]) {
    
        val conf = new SparkConf()
        conf.setAppName("ML")
        conf.setMaster("local[*]")
    
        val sc = new SparkContext(conf)
        sc.setLogLevel("ERROR")
    
        // 加载数据,把数据转换成特征向量
        val data = MLUtils.loadLibSVMFile(sc, "D:/mllib/sample_libsvm_data.txt")
    
        // 数据分为training (60%)和test (40%).
        val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L)
        val training = splits(0).cache()
        val test = splits(1)
    
        // 逻辑回归
        val model =  new LogisticRegressionWithLBFGS().setNumClasses(10)
          .run(training)
    
        // 计算预测数据
        val predictionAndLabels = test.map { point =>
          val score = model.predict(point.features)
          // 打印预测值与实际值
          println(score + " : " + point.label)
          (score, point.label)
        }
    
        // 对数据进行评估
        val metrics = new MulticlassMetrics(predictionAndLabels)
        val precision = metrics.precision
        println("Precision = " + precision)
    
        // 计算正确率
        val trainErr = predictionAndLabels.filter(r => r._1 != r._2).count.toDouble / test.count
    
        println("train error = " + trainErr)
    
        sc.stop()
      }
    

    协同过滤

    协同过滤常常被用于分辨某位特定顾客可能感兴趣的东西,这些结论来自于对其他相似顾客对哪些产品感兴趣的分析。协同过滤以其出色的速度和健壮性,在全球互联网领域炙手可热

    def main(args: Array[String]) {
    
        val conf = new SparkConf()
        conf.setAppName("ML")
        conf.setMaster("local[*]")
    
        val sc = new SparkContext(conf)
        sc.setLogLevel("ERROR")
    
        // 加载数据,把数据转换成特征向量
        val data = sc.textFile("D:/mllib/als/test.data")
        val ratings = data.map(_.split(',') match { case Array(user, item, rate) =>
          // 用户  产品  评分
          Rating(user.toInt, item.toInt, rate.toDouble)
        })
    
        // 构建推荐模型
        val rank = 10
        // 迭代次数
        val numIterations = 10
        // rank使用的特征的数量
        val model = ALS.train(ratings, rank, numIterations, 0.01)
    
        // 数据转换成(user, product)
        val usersProducts = ratings.map { case Rating(user, product, rate) =>
          (user, product)
        }
        val predictions =
          model.predict(usersProducts).map { case Rating(user, product, rate) =>
            println(rate)
            ((user, product), rate)
          }
    
        // 基于用户推荐产品
        val recommends = model.recommendProducts(4, 1)
        for (r <- recommends) {
          println(r)
        }
    
        // 基于产品推荐用户
        // model.recommendUsers()
    
        // 实际值和预测值进行join
        val ratesAndPreds = ratings.map { case Rating(user, product, rate) =>
          println(rate)
          ((user, product), rate)
        }.join(predictions)
    
        val MSE = ratesAndPreds.map { case ((user, product), (r1, r2)) =>
          val err = (r1 - r2)
          // 平方
          err * err
        }.mean() // 均值
    
        // 均方误差
        println("Mean Squared Error = " + MSE)
    
        sc.stop()
      }
    

    决策树

    决策树(Decision Tree)是一种简单但是广泛使用的分类器。通过训练数据构建决策树,可以高效的对未知的数据进行分类。决策数有两大优点:1)决策树模型可以读性好,具有描述性,有助于人工分析;2)效率高,决策树只需要一次构建,反复使用,每一次预测的最大计算次数不超过决策树的深度。

    def main(args: Array[String]) {
    
        val conf = new SparkConf()
        conf.setAppName("ML")
        conf.setMaster("local[*]")
    
        val sc = new SparkContext(conf)
        sc.setLogLevel("ERROR")
    
        // 加载数据,把数据转换成特征向量
        val data = MLUtils.loadLibSVMFile(sc, "D:/mllib/sample_libsvm_data.txt")
        // 数据70%training 30% test
        val splits = data.randomSplit(Array(0.7, 0.3))
        val (trainingData, testData) = (splits(0), splits(1))
    
        val numClasses = 2
        val categoricalFeaturesInfo = Map[Int, Int]()
        val impurity = "gini"
        val maxDepth = 5
        val maxBins = 32
    
        // 构建决策树模型 numClasses分几类
        // impurity "gini" (recommended) or "entropy"
        // maxDepth 树的最大深度
        // maxBins 建议 32
        val model = DecisionTree.trainClassifier(trainingData, numClasses, categoricalFeaturesInfo,
          impurity, maxDepth, maxBins)
    
        // 通过模型预测测试数据
        val labelAndPreds = testData.map { point =>
          val prediction = model.predict(point.features)
          (point.label, prediction)
        }
    
        // 计算错误率
        val testErr = labelAndPreds.filter(r => r._1 != r._2).count().toDouble / testData.count()
        println("Test Error = " + testErr)
        // println("Learned classification tree model:
    " + model.toDebugString)
    
        sc.stop()
      }
    

      

  • 相关阅读:
    Code Forces 650 C Table Compression(并查集)
    Code Forces 645B Mischievous Mess Makers
    POJ 3735 Training little cats(矩阵快速幂)
    POJ 3233 Matrix Power Series(矩阵快速幂)
    PAT 1026 Table Tennis (30)
    ZOJ 3609 Modular Inverse
    Java实现 LeetCode 746 使用最小花费爬楼梯(递推)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
    Java实现 LeetCode 745 前缀和后缀搜索(使用Hash代替字典树)
  • 原文地址:https://www.cnblogs.com/heml/p/6806907.html
Copyright © 2020-2023  润新知