zoukankan      html  css  js  c++  java
  • 机器学习评估指标的前世今生

    • 很多同学在入门机器学习的时候都会好奇,这么多的机器学习指标,到底要用哪个?这些指标的含义和优缺点是什么?他们之间有没有联系?像AUC这种常用的指标到底是什么意思,它的核心idea又是什么?它是怎样计算出来的?
    • 下面,我会用通俗易懂的语言,介绍不同的机器学习评估指标的具体含义,优缺点,以及它们之间的联系,将常用的机器学习评估指标串成一条线。然后重点介绍了AUC的来历,核心的idea以及计算过程。并简要介绍了评估指标和代价函数之间的关系和区别。里面有一些自己的观点和体会,如有不当,请大家指正。废话少说,上正文哈!!!
    • 我们先来看一下sklearn中支持哪些机器学习的评估指标:
     
    1
    2
    from sklearn.metrics import SCORERS
    SCORERS

    {‘accuracy’: make_scorer(accuracy_score),
    ‘adjusted_rand_score’: make_scorer(adjusted_rand_score),
    ‘average_precision’: make_scorer(average_precision_score, needs_threshold=True),
    ‘f1’: make_scorer(f1_score),
    ‘f1_macro’: make_scorer(f1_score, average=macro, pos_label=None),
    ‘f1_micro’: make_scorer(f1_score, average=micro, pos_label=None),
    ‘f1_samples’: make_scorer(f1_score, average=samples, pos_label=None),
    ‘f1_weighted’: make_scorer(f1_score, average=weighted, pos_label=None),
    ‘log_loss’: make_scorer(log_loss, greater_is_better=False, needs_proba=True),
    ‘mean_absolute_error’: make_scorer(mean_absolute_error, greater_is_better=False),
    ‘mean_squared_error’: make_scorer(mean_squared_error, greater_is_better=False),
    ‘median_absolute_error’: make_scorer(median_absolute_error, greater_is_better=False),
    ‘neg_log_loss’: make_scorer(log_loss, greater_is_better=False, needs_proba=True),
    ‘neg_mean_absolute_error’: make_scorer(mean_absolute_error, greater_is_better=False),
    ‘neg_mean_squared_error’: make_scorer(mean_squared_error, greater_is_better=False),
    ‘neg_median_absolute_error’: make_scorer(median_absolute_error, greater_is_better=False),
    ‘precision’: make_scorer(precision_score),
    ‘precision_macro’: make_scorer(precision_score, average=macro, pos_label=None),
    ‘precision_micro’: make_scorer(precision_score, average=micro, pos_label=None),
    ‘precision_samples’: make_scorer(precision_score, average=samples, pos_label=None),
    ‘precision_weighted’: make_scorer(precision_score, average=weighted, pos_label=None),
    ‘r2’: make_scorer(r2_score),
    ‘recall’: make_scorer(recall_score),
    ‘recall_macro’: make_scorer(recall_score, average=macro, pos_label=None),
    ‘recall_micro’: make_scorer(recall_score, average=micro, pos_label=None),
    ‘recall_samples’: make_scorer(recall_score, average=samples, pos_label=None),
    ‘recall_weighted’: make_scorer(recall_score, average=weighted, pos_label=None),
    ‘roc_auc’: make_scorer(roc_auc_score, needs_threshold=True)}

    哇,好多,这么多指标,我们都要会用吗?实际上不是这样的,我们平时工作中只会使用一些比较常见的指标,并且根据这些常见的指标(注意不是一个指标!)综合评价我们的模型。下面我们就一一揭晓这些常见评估方法的神秘面纱!

    回归(Regression)算法指标大揭秘

    • Mean Absolute Error 平均绝对误差
    • Mean Squared Error 均方误差
    • Root Mean Squared Error:均方根误差

    • Coefficient of determination 决定系数

    以下为一元变量和二元变量的线性回归示意图:

    怎样来衡量回归模型的好坏呢?

    我们第一眼自然而然会想到采用残差(实际值与预测值差值)的均值来衡量,即:

    问题 1:用残差的均值合理吗?

    当实际值分布在拟合曲线两侧时,对于不同样本而言$y_i-hat{y}_i$ 有正有负,相互抵消,因此我们想到采用预测值和真实值之间的距离来衡量。

    平均绝对误差 MAE

    平均绝对误差MAE(Mean Absolute Error)又被称为 $l1$ 范数损失($l1-norm loss$),

    问题 2:MAE有哪些不足?

    MAE虽能较好衡量回归模型的好坏,但是绝对值的存在导致函数不光滑,在某些点上不能求导,可以考虑将绝对值改为残差的平方,这就是均方误差。

    均方误差 MSE

    均方误差MSE(Mean Squared Error)又被称为 $l2$ 范数损失($l2-norm loss$)。

    问题 3: 还有没有比MSE更合理一些的指标?

    由于MSE与我们的目标变量的量纲不一致,为了保证量纲一致性,我们需要对MSE进行开方。

    均方根误差 RMSE

    问题 4: RMSE有没有不足的地方?有没有规范化(无量纲化的指标)?

    上面的几种衡量标准的取值大小与具体的应用场景有关系,很难定义统一的规则来衡量模型的好坏。比如说利用机器学习算法预测上海的房价RMSE在2000元,我们是可以接受的,但是当四五线城市的房价RMSE为2000元,我们还可以接受吗?下面介绍的决定系数就是一个无量纲化的指标。

    决定系数 $R^2$

    变量之所以有价值,就是因为变量是变化的。什么意思呢?比如说一组因变量为[0, 0, 0, 0, 0],显然该因变量的结果是一个常数0,我们也没有必要建模对该因变量进行预测。假如一组的因变量为[1, 3, 7, 10, 12],该因变量是变化的,也就是有变异,因此需要通过建立回归模型进行预测。这里的变异可以理解为一组数据的方差不为0。

    决定系数又称为 $R^2$ score,反应因变量的全部变异能通过回归关系被自变量解释的比例。

    $ ext{SST} = sum limits_i^m(y_i - ar y)^2 qquad ext{SST = total sum of squares}$

    $ ext{SSR} = sum limits_i^m(hat y_i - ar y)^2 qquad ext{SSR = sum of due to regression}$

    $ ext{SSE} = sum limits_i^m(hat y_i - y_i)^2 qquad ext{SSE = sum of due to erros}$

    $ ext{SST = SSR + SSE}$

    如果结果是0,就说明模型预测不能预测因变量。
    如果结果是1。就说明是函数关系。
    如果结果是0-1之间的数,就是我们模型的好坏程度。

    化简上面的公式 ,分子就变成了我们的均方误差MSE,下面分母就变成了方差:

    问题 5: 以上评估指标有没有缺陷,如果有,该怎样改进?

    以上的评估指标是基于误差的均值对进行评估的,均值对异常点(outliers)较敏感,如果样本中有一些异常值出现,会对以上指标的值有较大影响,即均值是非鲁棒的。

    解决评估指标鲁棒性问题

    我们通常用一下两种方法解决评估指标的鲁棒性问题:

    • 剔除异常值

    设定一个相对误差 $frac{|y_i-hat{y_i}|}{y_i}$,当该值超过一定的阈值时,则认为其是一个异常点,剔除这个异常点,将异常点剔除之后。再计算平均误差来对模型进行评价。

    • 使用误差的分位数来代替,

    如利用中位数来代替平均数。例如 MAPE:

    MAPE是一个相对误差的中位数,当然也可以使用别的分位数。

    分类(Classification)算法指标大揭秘

    • 精度 Accuracy
    • 混淆矩阵 Confusion Matrix
    • 准确率(查准率) Precision
    • 召回率(查全率)Recall
    • $F_eta$ Score
    • AUC Area Under Curve

    • KS Kolmogorov-Smirnov

    精度 Acc

    预测正确的样本的占总样本的比例,取值范围为[0,1],取值越大,模型预测能力越好。

    其中

    精度评价指标对平等对待每个类别,即每一个样本判对 (0) 和判错 (1) 的代价都是一样的

    问题 6: 精度有什么缺陷?什么时候精度指标会失效?

    • 对于有倾向性的问题,往往不能用精度指标来衡量。比如,判断空中的飞行物是导弹还是其他飞行物,很显然为了减少损失,我们更倾向于相信是导弹而采用相应的防护措施。此时判断为导弹实际上是其他飞行物与判断为其他飞行物实际上是导弹这两种情况的重要性是不一样的;
    • 对于样本类别数量严重不均衡的情况,也不能用精度指标来衡量。比如银行客户样本中好客户990个,坏客户10个。如果一个模型直接把所有客户都判断为好客户,得到精度为99%,但这显然是没有意义的。

    对于以上两种情况,单纯根据Accuracy来衡量算法的优劣已经失效。这个时候就需要对目标变量的真实值和预测值做更深入的分析。

    混淆矩阵 Confusion Matrix

    混淆矩阵,在无监督学习中被称为匹配矩阵(matching matrix),之所以叫混淆矩阵,是因为我们能够很 easy 从图表中看到分类器有没有将样本的类别给混淆了。矩阵每一列表示分类器预测值,每一行表示样本真实值。

    混淆矩阵如下图所示:

    mark

     

    这里牵扯到三个方面:真实值,预测值,预测值和真实值之间的关系,其中任意两个方面都可以确定第三个。

    通常取预测值和真实值之间的关系、预测值对矩阵进行划分:

    • True positive (TP)

      真实值为Positive,预测正确(预测值为Positive)

    • True negative (TN)

      真实值为Negative,预测正确(预测值为Negative)

    • False positive (FP)

      真实值为Negative,预测错误(预测值为Positive),第一类错误, Type I error。

    • False negative (FN)

      真实值为Positive,预测错误(预测值为 Negative),第二类错误, Type II error。

    混淆矩阵的衍生指标:

    mark

     

    mark

     

    mark

     

    准确率 (查准率) Precision

    Precision 是分类器预测的正样本中预测正确的比例,取值范围为[0,1],取值越大,模型预测能力越好。

    召回率 (查全率) Recall

    Recall 是分类器所预测正确的正样本占所有正样本的比例,取值范围为[0,1],取值越大,模型预测能力越好。

    应用场景:

    1. 地震的预测
      对于地震的预测,我们希望的是Recall非常高,也就是说每次地震我们都希望预测出来。这个时候我们可以牺牲Precision。情愿发出1000次警报,把10次地震都预测正确了;也不要预测100次对了8次漏了两次。
    2. 嫌疑人定罪
      基于不错怪一个好人的原则,对于嫌疑人的定罪我们希望是非常准确的。即使有时候放过了一些罪犯,但也是值得的。因此我们希望有较高的Precision值,可以合理地牺牲Recall。

    问题 7: 某一家互联网金融公司风控部门的主要工作是利用机器模型抓取坏客户。互联网金融公司要扩大业务量,尽量多的吸引好客户,此时风控部门该怎样调整Recall和Precision?如果公司坏账扩大,公司缩紧业务,尽可能抓住更多的坏客户,此时风控部门该怎样调整Recall和Precision?

    如果互联网公司要扩大业务量,为了减少好客户的误抓率,保证吸引更多的好客户,风控部门就会提高阈值,从而提高模型的查准率Precision,同时,也会放进一部分坏客户,导致查全率Recall下降。如果公司要缩紧业务,尽可能抓住更多的坏客户,风控部门就会降低阈值,从而提高模型的查全率Recall,但是这样会导致一部分好客户误抓,从而降低模型的查准率 Precision。

    根据以上几个案,我们知道随着阈值的变化Recall和Precision往往会向着反方向变化,这种规律很难满足我们的期望,即Recall和Precision同时增大。

    问题 8: 有没有什么方法权衡Recall和Precision 的矛盾?

    我们可以用一个指标来统一Recall和Precision的矛盾,即利用Recall和Precision的加权调和平均值作为衡量标准。

    $F_eta$ Score

    Precision和Recall 是互相影响的,理想情况下肯定是做到两者都高,但是一般情况下Precision高、Recall 就低,Recall 高、Precision就低。为了均衡两个指标,我们可以采用Precision和Recall的加权调和平均(weighted harmonic mean)来衡量,即$F_eta$ Score,公式如下:

    $eta$ 表示权重,

    $egin{equation}egin{split} F_{eta}& = frac{(1+eta^2) imes ext{P} imes ext{R}}{eta^2 imes ext{P}+ ext{R}} & = frac {1}{frac{eta^2}{(1+eta^2) imes R}+frac{1}{(1+eta^2) imes P}} & = frac {1}{frac{1}{(1+frac{1}{eta^2}) imes R}+frac{1}{(1+eta^2) imes P}} end{split}end{equation}$

    当$eta ightarrow 0 : F_{eta} approx P$ ;当$eta ightarrow infty: F_{eta} approx R$。

    通俗的语言就是:$eta$ 越大,Recall的权重越大,$eta$越小,Precision的权重越大。

    随着如 $eta=1$ 为$F_1$,此时Precision和Recall的权重相等,公式如下:

    由于$F_eta$ Score 无法直观反映数据的情况,同时业务含义相对较弱,实际工作用到的不多。

    问题 9: 根据以下混淆矩阵计算Recall, Precision,TPR,FPR?

    问题 10: 有没有办法观察模型好坏随阈值的变化趋势呢(提示:利用TPR, FPR两个指标)?

    有,ROC(Receiver Operating Characteristic)曲线

    问题 11: lr模型输出的是概率,需要设置阈值才能得到好坏客户,从而得到混淆矩阵,有没有一种指标不依赖于阈值?

    有,AUC

    ROC 和 AUC

    AUC是一种模型分类指标,且仅仅是二分类模型的评价指标。AUC是Area Under Curve的简称,那么Curve就是ROC(Receiver Operating Characteristic),翻译为”接受者操作特性曲线”。也就是说ROC是一条曲线,AUC是一个面积值。

    ROC

    ROC曲线为 FPR 与 TPR 之间的关系曲线,这个组合以 FPR 对 TPR,即是以代价 (costs) 对收益 (benefits),显然收益越高,代价越低,模型的性能就越好。

    • x 轴为假阳性率(FPR):在所有的负样本中,分类器预测错误的比例

    • y 轴为真阳性率(TPR):在所有的正样本中,分类器预测正确的比例(等于Recall)

    为了更好地理解ROC曲线,我们使用具体的实例来说明:

    如在医学诊断的主要任务是尽量把生病的人群都找出来,也就是TPR越高越好。而尽量降低没病误诊为有病的人数,也就是FPR越低越好。

    不难发现,这两个指标之间是相互制约的。如果某个医生对于有病的症状比较敏感,稍微的小症状都判断为有病,那么他的TPR应该会很高,但是FPR也就相应地变高。最极端的情况下,他把所有的样本都看做有病,那么TPR达到1,FPR也为1。

    我们以FPR为横轴,TPR为纵轴,得到如下ROC空间。

    我们可以看出,左上角的点(TPR=1,FPR=0),为完美分类,也就是这个医生医术高明,诊断全对。点A(TPR>FPR),医生A的判断大体是正确的。中线上的点B(TPR=FPR),也就是医生B全都是蒙的,蒙对一半,蒙错一半;下半平面的点C(TPR<FPR),这个医生说你有病,那么你很可能没有病,医生C的话我们要反着听,为真庸医。上图中一个阈值,得到一个点。现在我们需要一个独立于阈值的评价指标来衡量这个医生的医术如何,也就是遍历所有的阈值,得到 ROC 曲线。

    假设下图是某医生的诊断统计图,为未得病人群(上图)和得病人群(下图)的模型输出概率分布图(横坐标表示模型输出概率,纵坐标表示概率对应的人群的数量),显然未得病人群的概率值普遍低于得病人群的输出概率值(即正常人诊断出疾病的概率小于得病人群诊断出疾病的概率)。

    竖线代表阈值。显然,图中给出了某个阈值对应的混淆矩阵,通过改变不同的阈值$1.0 ightarrow 0$,得到一系列的混淆矩阵,进而得到一系列的TPR和FPR,绘制出ROC曲线。

    阈值为1时,不管你什么症状,医生均未诊断出疾病(预测值都为N),此时绿色和红色区域的面积为 0,因此 $FPR=TPR=0$,位于左下。随着阈值的减小,红色和绿色区域增大,紫色和蓝色区域减小。阈值为 0 时,不管你什么症状,医生都诊断结果都是得病(预测值都为P),此时绿色和红色区域均占整个区域,即紫色和蓝色区域的面积为 0,此时 $FPR=TPR=1$,位于右上。

    mark

     

    问题 12:如下,是三个模型对于 ROC 曲线,请按照模型性能好坏对齐进行排序

    由ROC曲线距离左上角越近分类器效果越好,我们可以知道分类器 4 效果最好, 分类器 1 效果最差。那么怎样判断分类器 2 和分类器 3 呢?我们引入了下面要讲的 AUC。

    AUC

    AUC定义:

    AUC 值为 ROC 曲线所覆盖的区域面积,显然,AUC越大,分类器分类效果越好。

    AUC = 1,是完美分类器。

    0.5 < AUC < 1,优于随机猜测。有预测价值。

    AUC = 0.5,跟随机猜测一样(例:丢铜板),没有预测价值。

    AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。

    注:对于AUC小于 0.5 的模型,我们可以考虑取反(模型预测为positive,那我们就取negtive),这样就可以保证模型的性能不可能比随机猜测差。

    以下为ROC曲线和AUC值的实例:

    AUC的物理意义

    AUC的物理意义正样本的预测结果大于负样本的预测结果的概率。所以AUC反应的是分类器对样本的排序能力。

    另外值得注意的是,AUC对样本类别是否均衡并不敏感,这也是不均衡样本通常用AUC评价分类器性能的一个原因。

    下面从一个小例子解释AUC的含义:小明一家四口,小明5岁,姐姐10岁,爸爸35岁,妈妈33岁建立一个逻辑回归分类器,来预测小明家人为成年人概率,假设分类器已经对小明的家人做过预测,得到每个人为成人的概率。

    1. AUC更多的是关注对计算概率的排序,关注的是概率值的相对大小,与阈值和概率值的绝对大小没有关系

    例子中并不关注小明是不是成人,而关注的是,预测为成人的概率的排序。

    问题 13:以下为三种模型的输出结果,求三种模型的 AUC。

     小明姐姐妈妈爸爸
    a 0.12 0.35 0.76 0.85
    b 0.12 0.35 0.44 0.49
    c 0.52 0.65 0.76 0.85

    AUC只与概率的相对大小(概率排序)有关,和绝对大小没关系。由于三个模型概率排序的前两位都是未成年人(小明,姐姐),后两位都是成年人(妈妈,爸爸),因此三个模型的AUC都等于1。

    1. AUC只关注正负样本之间的排序,并不关心正样本内部,或者负样本内部的排序。这也体现了AUC的本质:任意个正样本的概率都大于负样本的概率的能力

      例子中AUC只需要保证(小明和姐姐)(爸爸和妈妈),小明和姐姐在前2个排序,爸爸和妈妈在后2个排序,而不会考虑小明和姐姐谁在前,或者爸爸和妈妈谁在前。

    问题 14:以下已经对分类器输出概率从小到大进行了排列,哪些情况的AUC等于1, 情况的AUC为0(其中背景色表示True value,红色表示成年人,蓝色表示未成年人)。

    D 模型, E模型和F模型的AUC值为1,C 模型的AUC值为0(爸妈为成年人的概率小于小明和姐姐,显然这个模型预测反了)。

    AUC的计算:

    • 法1:AUC 为 ROC 曲线下的面积,那我们直接计算面积可得。面积为一个个小的梯形面积(曲线)之和。计算的精度与阈值的精度有关。
    • 法2:根据 AUC 的物理意义,我们计算正样本预测结果大于负样本预测结果的概率。取 $n_1n_0$($n_1$ 为正样本数,$n_0$ 为负样本数)个二元组,比较 score(预测结果),最后得到 AUC。时间复杂度为 O(NM)。
    • 首先把所有样本按照 score 排序,依次用 rank 表示他们,如最大 score 的样本,$rank=n$ ( $n=n_0+n_1$,其中 $n_0$ 为负样本个数,$n_1$ 为正样本个数),其次为 $n-1$。对于正样本中 rank 最大的样本 $rank_max$,有 $n_1-1$ 个其他正样本比它小。有 $rank_max-n_1$ 个负样本比它小。其次为$rank_second-(n_1-1)$。最后我们得到正样本大于负样本的概率为:

    计算复杂度为O(N+M)。

    下面有一个简单的例子:

    • 真实标签为 (1, 0, 0, 1, 0)
    • 预测结果1:(0.9, 0.3, 0.2, 0.7, 0.5)
    • 预测结果2:(0.9, 0.3, 0.2, 0.7, 0.8))
    • 分别对两个预测结果进行排序,并提取他们的序号:
      • 结果1: (5, 2, 1, 4, 3)
      • 结果2: (5, 2, 1, 3, 4)
    • 对正分类序号累加 :
      • 结果1: $sum_{正样本}{RANK(score)}=5+4=9$
      • 结果2: $sum_{正样本}{RANK(score)}=5+3=8$
    • 计算两个结果的 AUC:
      • 结果1:
      • 结果2:

    问题 15:为什么说 ROC 和AUC都能应用于非均衡的分类问题?

    ROC曲线只与横坐标 (FPR) 和 纵坐标 (TPR) 有关系,我们知道:

    以及混淆矩阵:

    我们可以发现TPR只是正样本中(第一行)预测正确的概率,在正样本内部进行,并没有牵扯到负样本。而FPR只是负样本中(第二行)预测错误的概率,在负样本内部进行,并没有牵扯到正样本。TPR和FPR的计算并没有涉及正负样本的互动(也就是没有跨行)。和正负样本的比例没有关系。因此 ROC 的值与实际的正负样本比例无关,因此既可以用于均衡问题,也可以用于非均衡问题。而 AUC 的几何意义为ROC曲线下的面积,因此也和实际的正负样本比例无关。

    KS Kolmogorov-Smirnov

    KS值是在模型中用于区分预测正负样本分隔程度的评价指标,一般应用于金融风控领域。与ROC曲线相似,ROC是以FPR作为横坐标,TPR作为纵坐标,通过改变不同阈值,从而得到ROC曲线。而在KS曲线中,则是以阈值作为横坐标,以FPR和TPR作为纵坐标,ks曲线则为TPR-FPR,ks曲线的最大值通常为ks值。

    为什么这样求KS值呢?我们知道,当阈值减小时,TPR和FPR会同时减小,当阈值增大时,TPR和FPR会同时增大。而在实际工程中,我们希望TPR更大一些,FPR更小一些,即TPR-FPR越大越好,即ks值越大越好。

    KS值的取值范围是[0,1]。通常来说,值越大,模型区分正负样本的能力越强(一般0.3以上,说明模型的效果比较好)。

    以下为KS曲线的实例 :

    评估指标和代价函数是一家人吗?

    代价函数:$f( heta, y)$,又称Cost function,loss function objective function。一般用在训练过程中,用来定义预测值和真实值之间的距离(也就是衡量模型在训练集上的性能),作为模型调整参数的反馈。代价函数越小,模型性能越好。

    评判指标:$f(hat y, y)$,一般用于训练和测试过程中,用于评估模型好坏。评判指标越大(或越小),模型越好。

    本质上代价函数和评判指标都是一家人,只他们的应用场景不同,分工不同。代价函数是用来优化模型参数的,评价指标是用来评判模型好坏的。

    作为评判指标所具备的条件:

    1. 直观,可以理解

    ……

    作为代价函数所具备的条件:

    1. 函数光滑且可导:可用梯度下降求解极值
    2. 函数为凸函数:可用梯度下降求解最优解

    ……

    例如我们经常使用的分类器评判指标 AUC 就不能直接被优化,因此我们常采用交叉熵来代替 AUC 进行优化。 一般情况下,交叉熵越小,AUC 就会越大。

    补充小知识点:micro还是macro?

    假如我们有n个二分类混淆矩阵,怎样综合评价我们的模型呢?我们通常有两种方式一种叫macro,一种叫micro。

    macro方法

    1. 计算出各混淆矩阵的Recall,Precision,记为$(P_1, R_1),(P_2,R_2),cdots,(P_n,R_n)$:

    2. 对各个混淆矩阵的Recall,Precision求平均,然后再根据求得的Recall,Precision计算F1。

    micro方法

    1. 将各混淆矩阵对应的元素进行平均,得到平均混淆矩阵:

    2. 再基于平均混淆矩阵计算Recall,Precision,然后再根据求得的Recall,Precision计算F1:

    参考文献:

    ROC 和 AUC 介绍以及如何计算AUC http://alexkong.net/2013/06/introduction-to-auc-and-roc/

    混淆矩阵 维基百科 https://en.wikipedia.org/wiki/Confusion_matrix

    ROC曲线与AUC https://blog.csdn.net/ice110956/article/details/20288239

     

     

  • 相关阅读:
    一步步学习微软InfoPath2010和SP2010--第七章节--从SP列表和业务数据连接接收数据(6)--关键点
    一步步学习微软InfoPath2010和SP2010--第七章节--从SP列表和业务数据连接接收数据(5)--添加筛选器到业务连接服务外部内容类型
    一步步学习微软InfoPath2010和SP2010--第七章节--从SP列表和业务数据连接接收数据(4)--外部项目选取器和业务数据连接
    cmake增加编译宏
    cmake 添加头文件目录,链接动态、静态库
    【学习cmake】cmake如何使用链接库 (link_directories, LINK_LIBRARIES, target_link_libraries,FIND_PACKAGE)实践篇2
    心得体悟帖---201111(moderate)
    matplotlib画箭头
    matplotlib画图xticks设置为字母
    matplotlib画图的颜色及线条详解
  • 原文地址:https://www.cnblogs.com/nxld/p/9741716.html
Copyright © 2011-2022 走看看