zoukankan      html  css  js  c++  java
  • 机器学习一般应用过程--以分类算法为例(二)餐饮销量案例

    分类模型:输入样本的属性值,输出对应的类别,将每个样本映射到对应的类别

    常用的分类算法:knn,决策树,贝叶斯分类器,支持向量机


    KNN是通过测量不同特征值之间的距离进行分类。它的的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。K通常是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

    下面通过一个简单的例子说明一下:如下图,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。

     

    由此也说明了KNN算法的结果很大程度取决于K的选择。

         在KNN中,通过计算对象间距离来作为各个对象之间的非相似性指标,避免了对象之间的匹配问题,在这里距离一般使用欧氏距离或曼哈顿距离:

                          

    同时,KNN通过依据k个对象中占优的类别进行决策,而不是单一的对象类别决策。这两点就是KNN算法的优势。


    朴素贝叶斯分类

    贝叶斯定理我们基本都是学过的 :

    其中 P(c)就是先验概率,之所以叫它先验概率,就是因为这个是根据以往的经验是预先知道的。P(x|c)就是对于类别c,x属于c的概率,也称作“似然”(likelihood)。P(x)是归一化因子。
    贝叶斯分类就是希望从上式估计出后验概率,但是这里有个问题,样本xx通常是多维的x=(x1,x2,⋯,xk),每个维度又有不同的取值ai个,那么总的可能取值有个,维度越高这个数字基本是指数增加,对于有限个的数据是很难给出有效的估计的,因为相对于所有的可能,样本点还是太少,所以我们就引出了朴素贝叶斯分类

    朴素贝叶斯分类采用了属性独立假设:对于已知类别,假设所有属性相互独立。
    那么我们的贝叶斯公式可以写成

    P(x)对所有类别都是相同的,那么我们不考虑它,可以得出贝叶斯分类器: 

    解释一下就是对于任意样本,对所有的c计算上式,然后选择其中使得上式值最大的c作为xx对应的类别。

    下面介绍一下,上面的式子该怎么计算: 
    假设我们有数据集合D,第c类样本是它的子集为Dc,那么先验概率为

    然后求对于每个属性的条件概率,对于离散情况,令Dc,xiDcDc中第i个属性为xi的样本组成的集合,那么条件概率为

    那么对于连续属性呢?我们假设条件概率服从正态分布

    那么有


    最后如果在某个类别里面某个属性的取值个数为0,那么条件概率P(xi|c)P(xi|c)就是0,由于最后计算概率是连乘,这将导致无论其他属性包含什么信息,最后的结果都是0,这是不合理的,所以我们采用一种叫拉普拉斯平滑(Laplace Smoothing)的方法修正一下。 

    其中N表示数据集中可能的类别数,NiNi表示第ii个属性可能的取值个数。

    朴素贝叶斯举例:

    基于父母节点,计算后代节点:

    以上就是朴素贝叶斯分类的原理,下面介绍scikit-learn中相关算法的使用

    scikit-learn 中的使用

    sklearn.naive_bayes模块中只有三个分类器,分别为,BernoulliNB(),GaussianNB(),MultinomialNB()

    (其中参数中的alpha是平滑的参数,为1的时候就是上面说过的拉普拉斯平滑 ;

    属性中class_log_prior_可以输出各个类的先验概率, feature_log_prob_ 可以输出条件概率)


     决策树结构

     

     贪心算法构建决策树:

     属性度量选择:

    信息增益:

    ID3算法的缺陷:

    c4.5:

     

     cart:

     

    分类树:

     

    关于树的减枝:

    决策树的优缺点:


     支持向量机 SVM

    线性判别法:

    旋转得到:


    算法比较实现

    案例使用的数据是餐饮类数---销售与天气,周末,促销的关系。

    1.什么是分类准确率?
    评价分类器性能的指标一般是分类准确率(Accuracy),其定义是:对于给定的测试数据集,分类器正确分类的样本数和总样本数之比。

    对于二分类问题常见的评价指标是精确率(precision)与召回率(recall)。
    通常以关注的类为正类,其他类为负类,分类器在测试数据集上的预测或正确或不正确,四种情况出现的总数分别记作:

    TP ——将正类预测为正类数(True Positive)
    FN ——将正类预测为负类数(False Negative)
    FP ——-将负类预测为正类
    TN ——-将负类预测为负类数
    ---------------------

    准确率
       准确率是对给定数据集,分类正确样本个数和总样本数的比值。即:


    精确度
       精确度说明判断为真的正例占所有判断为真的样例比重,即:

    召回率
       召回率又被称为查全率,用来说明分类器中判定为真的正例占总正例的比率,即:

    三者之间的联系
       一般来说,精确度和召回率之间是矛盾的,这里引入F1-Score作为综合指标,就是为了平衡准确率和召回率的影响,较为全面地评价一个分类器。F1是精确率和召回率的调和平均:

       一般来说准确率和召回率呈负相关,一个高,一个就低,如果两个都低,一定是有问题的。如下图所示:


    ---------------------

     1 # -*- coding: utf-8 -*-
     2 import numpy as np
     3 from sklearn.neighbors import KNeighborsClassifier
     4 from sklearn.metrics import precision_recall_curve
     5 from sklearn.metrics import classification_report
     6 from sklearn.naive_bayes import BernoulliNB
     7 from sklearn.feature_extraction.text import TfidfVectorizer
     8 from sklearn.cross_validation import train_test_split
     9 #import matplotlib.pyplot as plt
    10 import pandas as pd
    11   
    12 ####knn最邻近算法####
    13 inputfile = '/Volumes/win/linshi/sales_data.xls'
    14 data = pd.read_excel(inputfile, index_col = u'序号') #导入数据
    15 
    16 #数据是类别标签,要将它转换为数据
    17 #用1来表示“好”、“是”、“高”这三个属性,用-1来表示“坏”、“否”、“低”
    18 data[data == u''] = 1
    19 data[data == u''] = 1
    20 data[data == u''] = 1
    21 data[data != 1] = -1
    22 x = data.iloc[:,:3].as_matrix().astype(int)
    23 y = data.iloc[:,3].as_matrix().astype(int)
    24 
    25 
    26 #拆分训练数据与测试数据 
    27 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)
    28 
    29 
    30 #训练KNN分类器 
    31 clf = KNeighborsClassifier(algorithm='kd_tree')
    32 clf.fit(x_train, y_train)
    33 
    34 #测试结果
    35 answer = clf.predict(x_test)
    36 print(x_test)
    37 print(answer)
    38 print(y_test)
    39 print(np.mean( answer == y_test))
    40 
    41 #准确率
    42 precision, recall, thresholds = precision_recall_curve(y_train, clf.predict(x_train))
    43 print(classification_report(y_test, answer, target_names = ['', '']))

     knn分类器运行结果

    sklearn中的classification_report函数用于显示主要分类指标的文本报告.在报告中显示每个类的精确度,召回率,F1值等信息。
    主要参数:
    y_true:1维数组,或标签指示器数组/稀疏矩阵,目标值。
    y_pred:1维数组,或标签指示器数组/稀疏矩阵,分类器返回的估计值。
    labels:array,shape = [n_labels],报表中包含的标签索引的可选列表。
    target_names:字符串列表,与标签匹配的可选显示名称(相同顺序)。
    sample_weight:类似于shape = [n_samples]的数组,可选项,样本权重。
    digits:int,输出浮点值的位数.
    ---------------------

    0.571428571429
                 precision    recall  f1-score   support
    
              低       0.67      0.80      0.73         5
              高       0.00      0.00      0.00         2
    
    avg / total       0.48      0.57      0.52         7
    

    其中列表左边的一列为分类的标签名,右边support列为每个标签的出现次数.avg / total行为各列的均值(support列为总和).
    precision recall f1-score三列分别为各个类别的精确度/召回率及F1值.


    精确度和召回率都高时,F1值也会高. F1值在1时达到最佳值(完美的精确度和召回率),最差为0.在二元分类中,[Math Processing Error] F1值是测试准确度的量度。
    ---------------------


     参数解释

    str参数       即内部采用什么算法实现。有以下几种选择参数:'ball_tree':球树、'kd_tree':kd树、'brute':暴力搜索、'auto':自动根据数据的类型和结构选择合适的算法。默认情况下是‘auto’。暴力搜索就不用说了大家都知道。具体前两种树型数据结构哪种好视情况而定。KD树是对依次对K维坐标轴,以中值切分构造的树,每一个节点是一个超矩形,在维数小于20时效率最高--可以参看《统计学习方法》第二章。ball tree 是为了克服KD树高维失效而发明的,其构造过程是以质心C和半径r分割样本空间,每一个节点是一个超球体。一般低维数据用kd_tree速度快,用ball_tree相对较慢。超过20维之后的高维数据用kd_tree效果反而不佳,而ball_tree效果要好,具体构造过程及优劣势的理论大家有兴趣可以去具体学习。

      leaf_size=30               

    int参数      基于以上介绍的算法,此参数给出了kd_tree或者ball_tree叶节点规模,叶节点的不同规模会影响数的构造和搜索速度,同样会影响储树的内存的大小。具体最优规模是多少视情况而定。

      matric='minkowski'     

    str或者距离度量对象   即怎样度量距离。默认是闵氏距离,闵氏距离不是一种具体的距离度量方法,它可以说包括了其他距离度量方式,是其他距离度量的推广,具体各种距离度量只是参数p的取值不同或者是否去极限的不同情况,具体大家可以参考这里,讲的非常详细    


     贝叶斯分类器

     1 ####贝叶斯分类器####
     2 #训练贝叶斯分类器
     3 clf = BernoulliNB() 
     4 clf.fit(x_train,y_train)
     5 
     6 
     7 #测试结果
     8 answer = clf.predict(x_test)
     9 print(x_test)
    10 print(answer)
    11 print(y_test)
    12 print(np.mean( answer == y_test))
    13 print(classification_report(y_test, answer, target_names = ['', '']))
    0.714285714286
                 precision    recall  f1-score   support
    
              低       0.80      0.80      0.80         5
              高       0.50      0.50      0.50         2
    
    avg / total       0.71      0.71      0.71         7
    

      

     决策树分类器

     1 ####决策树####
     2 from sklearn.tree import DecisionTreeClassifier as DTC
     3 dtc = DTC(criterion='entropy') #建立决策树模型,基于信息熵
     4 dtc.fit(x_train, y_train) #训练模型
     5 
     6 #导入相关函数,可视化决策树。
     7 #导出的结果是一个dot文件,需要安装Graphviz才能将它转换为pdf或png等格式。
     8 from sklearn.tree import export_graphviz
     9 import graphviz
    10 import pydotplus
    11 from sklearn.externals.six import StringIO
    12 
    13 dot_data=StringIO()
    14 export_graphviz(dtc, out_file = dot_data)
    15 graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
    16 graph.write_png("tree.png")#使用pdf或png文件保存
    17 # =============================================================================
    18 #使用dot文件保存
    19 # #with open("tree.dot", 'w') as f:
    20 # #    f=export_graphviz(dtc, out_file = f)
    21 # =============================================================================
    22 #测试结果
    23 answer = dtc.predict(x_test)
    24 print(x_test)
    25 print(answer)
    26 print(y_test)
    27 print(np.mean( answer == y_test))
    28 print(classification_report(y_test, answer, target_names = ['', '']))

     决策树dot文件转换成png或这话pdf需要安装Graphviz!(如果嫌麻烦,可以按照注释代码提示直接使用dot文件保存即可)

    mac下的Graphviz安装及使用:

    1.安装homebrew 

    打开终端运行以下命令:

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    2.安装Graphviz

     如果速度慢,可以尝试更改下载镜像以及连接等待time。

    homebrew安装完毕后在终端运行命令 brew install graphviz即可

    3.测试生存图片

    在终端进入要转换的dot文件所在目录,输入以下命令生成图片
    
    dot pic.dot -T png -o pic.png
    
    输入以下命令生成PDF
    
    dot -Tpdf iris.dot -o iris.pdf

    决策树可视化图片如下:

    
    
    0.714285714286
                 precision    recall  f1-score   support
    
              低       0.71      1.00      0.83         5
              高       0.00      0.00      0.00         2
    
    avg / total       0.51      0.71      0.60         7

     svm

     1 ####SVM####
     2 from sklearn.svm import SVC
     3 clf =SVC()
     4 clf.fit(x_train, y_train)  
     5 
     6 #测试结果
     7 answer = clf.predict(x_test)
     8 print(x_test)
     9 print(answer)
    10 print(y_test)
    11 print(np.mean(answer == y_test))
    12 print(classification_report(y_test, answer, target_names = ['', '']))
    0.571428571429
                 precision    recall  f1-score   support
    
              低       0.67      0.80      0.73         5
              高       0.00      0.00      0.00         2
    
    avg / total       0.48      0.57      0.52         7

     最后,贝叶斯分类器效果较好,其他几类差不多。

     

     

  • 相关阅读:
    Controlling behavior of existing services in system
    获取站点路径方法
    如何处理DataTable.Select();执行后重新排序的问题!
    ASP.NET 2.0 编程珠玑之五调试已创建好的代码
    Meal Scheduler in C#
    DHTML+Ajax? MXML+ActionScript? XAML+C#? 是巧合,还是必然?
    C#验证输入的是否数字
    Monitoring System Usage using Windows Service
    ADO.NET 2.0中的DataSet和DataTable
    使用asp.net 2.0和SQL SERVER 2005构建多层应用
  • 原文地址:https://www.cnblogs.com/daliner/p/10088715.html
Copyright © 2011-2022 走看看