机器学习是一个神秘的术语

机器学习”是一个神秘的术语。大多数开发者在日常工作中根本不需要它,我们所知道的关于它的唯一细节来自于5年前的某个大学课程(已经被遗忘)。我不是机器学习专家,但我碰巧在一家做这方面工作的公司工作,所以我开始学习基础知识。我从来没有编写过实际的机器学习任务,但有一个很好的概述。

但是什么是机器学习呢?它指导计算机理解大量的数据(# big data hashtag–check)。在哪些方面?

  • 将新条目分类到现有类别中——这是垃圾邮件吗,这是关于体育或政治的新闻文章吗,这个符号是字母“a”,还是“b”,还是“c”,自动驾驶汽车前面的这个物体是行人还是路标。
  • 预测一个新条目的价值(回归问题)——我的车值多少钱,明天的股价是多少。
  • 将条目

怎么会?与许多不的是,计算机科学家和开发人员已经编写了这些代码,可以重用它们(当然,要有相当的理解)。

但是如果算法已经写好了,那么用机器学习一定很容易吧?不。讽刺的是,机器学习最难的部分是人类告诉机器关于数据什么是重要的部分。这个过程被那些以某种方式描述数据的特征是什么,计算机可以用它来识别有意义的模式。我不是机器学习专家,但在我看来,这一步是大多数机器学习工程师(或数据科学家)每天都在做的事情。他们没有发明新的算法;他们试图找出给定数据的哪些特征组合能给出最佳结果。这是一个有许多我没有经验的“启发”的过程。(当然,这是一种过度简化,因为我的同事们确实在做研究并提出改进算法,但这是事情的科学方面)

最容易用于分为两组的分类,但也有方法将其应用于多类或多标签分类)。如果您必须将一封电子邮件分类为垃圾邮件或非垃圾邮件,您的精确度是所有标记为垃圾邮件的电子邮件中正确标记为垃圾邮件的百分比。召回率是被正确标记为垃圾邮件的电子邮件占被标记为垃圾邮件的电子邮件总数的百分比。因此,如果您有200封电子邮件,其中100封是垃圾邮件,您的程序将其中80封正确标记为垃圾邮件,20封错误标记为垃圾邮件,那么您的准确率为80%(80/80+20),召回率为80%(80/100实际垃圾邮件)。当你在这两个指标上得分较高时,就会取得好的结果。也就是说,如果您的垃圾邮件过滤器能够正确检测大多数垃圾邮件,并且不会将非垃圾邮件标记为垃圾邮件,那么它就是好的。

https://book.douban.com/review/14390293/

将数据输入算法的过程很简单。您通常有两组数据——训练集和评估集。通常从一组开始,然后分成两组(训练组应该是较大的一组)。这些集合包含您为相关数据确定的所有特性的值。您首先使用训练集“训练”您的分类器统计模型(如果您想知道训练是如何发生的,请阅读各种算法),然后运行评估集以查看有多少项被正确分类(评估集中有正确的答案,因此您可以将其与分类器产生的输出进行比较)。

让我用我的第一个真正的机器学习代码来说明这一点(有一个很大的免责声明,这个任务可能不太它们组合成问题集,并在每年的活动中分配它们。但是我们仍然不擅长评估一个问题对高中生来说有多难。即使我们中的许多人曾经是这样的奥运会的竞争者,我们现在知道的“太多”以至于无法评估难度。所以我决定把机器学习应用到这个问题上。

如上所述,我必须从选择正确的特性开始。经过几次迭代后,我最终使用了:问题中示例的数量、示例的平均长度、作业的数量、作为解决方案的一部分要发现的语言组件的数量,以及问题数据是否被打乱。复杂度(容易、中等、困难)来自于奥林匹克竞赛中参赛者的实际分数(平均分数:0-8分=困难,8-12分–中等,> 12分容易)。我不确定这些特性是否与问题的复杂性有关,因此我尝试添加和删除一些。我将特征数据放性=特征):

https://weibo.com/ttarticle/p/show?id=2309404767623912227527

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

@RELATION problem-complexity

@ATTRIBUTE examples NUMERIC

@ATTRIBUTE avgExampleSize NUMERIC

@ATTRIBUTE components NUMERIC

@ATTRIBUTE assignments NUMERIC

@ATTRIBUTE scrambled {true,false}

@ATTRIBUTE complexity {easy,medium,hard}

@DATA

34,6,11,8,false,medium

12,21,7,17,false,medium

14,11,11,17,true,hard

13,16,9,14,false,hard

16,35,7,17,false,hard

20,9,7,10,false,hard

24,5,8,6,false,medium

9,14,13,4,false,easy

18,7,17,7,true,hard

18,7,12,10,false,easy

10,16,9,11,false,hard

11,3,17,13,true,easy

...

评估集看起来完全一样,但是更小(在我的例子中,只有7个条目为一个很好的工具(至少对于初学者来说),它包含了很多算法,可以简单地重用。

https://movie.douban.com/doulist/150186338/

跟我生成了下面的简单代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

public static void main(String[] args) throws Exception {

    ArffLoader loader = new ArffLoader();

    loader.setFile(new File("problem_complexity_train_3.arff"));

    Instances trainingSet = loader.getDataSet();

    // this is the complexity, here we specify what are our classes,

    // into which we want to classify the data

    int classIdx = 5;

        

    ArffLoader loader2 = new ArffLoader();

    loader2.setFile(new File("problem_complexity_test_3.arff"));

    Instances testSet = loader2.getDataSet();

        

    trainingSet.setClassIndex(classIdx);

    testSet.setClassIndex(classIdx);

        

     // using the LMT classification algorithm. Many more are available  

     Classifier classifier = new LMT();

     classifier.buildClassifier(trainingSet);

        

     Evaluation eval = new Evaluation(trainingSet);

     eval.evaluateModel(classifier, testSet); 

     System.out.println(eval.toSummaryString());

  

     // Get the confusion matrix

     double[][] confusionMatrix = eval.confusionMatrix();

     ....

}

关于算法选择的评论——由于知识不足,我只是尝试了几个,并选择了产生最佳结果的一个。

执行评估后,您可以获得eval.toConfusionMatrix),您可以使用它来查看结果的质量。当你对结果满意时,你可以着手对新条目进行分类,这是你不知道的复杂性。要做到这一点,您必须提供一个数据集,与其他两个数据集的唯一区别是,您用问号代替了class (easy、medium、hard)。例如:

1

2

3

4

...

@DATA

34,6,11,8,false,?

12,21,7,17,false,?

然后,您可以运行分类器:

1

2

3

4

5

6

7

8

9

10

11

12

ArffLoader loader = new ArffLoader();

loader.setFile(new File("unclassified.arff"));

Instances dataSet = loader.getDataSet();

DecimalFormat df = new DecimalFormat("#.##");

for (Enumeration en = dataSet.enumerateInstances(); en.hasMoreElements();) {

    double[] results = classifier.distributionForInstance(en.nextElement());

    for (double result : results) {

        System.out.print(df.format(result) + " ");

     }

     System.out.println();

};

这将打印出每个条目落入每个类别的概率。因为我们将使用这个输出仅仅作为复杂性的一个提示,而不是作为最终的决定,所以有时产生错误的结果是可以的。但在许多机器学习问题中,没有人对结果进行评估,因此获得更高的准确性是最重要的任务。

然而,这种方法如何扩展呢?我可以在大批量生产系统中重用上面的代码吗?在网络上,你通常不会实时运行机器学习任务(而是作为预定任务运行),所以答案可能是“是”。

我在这个领域还是个新手,但是完成了一个实际的任务后,我分享了我微小的经验和知识。与此同时,我正在以给你更多的细节。

作为开发人员,我们可以在工作项目中使用机器学习吗?如果我们有大量的数据——是的。开始并不难,尽管我们可能会犯愚蠢的错误,但这是一件值得探索的有趣的事情,可能会给我们正在构建的产品带来价值。

你可能感兴趣的:(c++)