(1)互信息

交互信息可作为是一个随机变量中寓的关于其他一个随机变量的信息量,或者说是一个随机变量由于都掌握外一个随机变量而减少的不确定性。互信息本来是信息论中之一个概念,用于表示信息中的涉,
个别独随机变量统计相关性的推论

那么Face ID是啊?Face ID有啊用?

(3)mRMR的spark实现源码

mRMR算法包含几单步骤:

  • 拿数据开展处理转换的长河(注:为了计算两只特征的联手分布与边缘分布,需要将数据归一化到[0,255]中,并且用各国一样维特征使用合理之数据结构进行仓储)
  • 测算特征之间、特征及应变量之间的分布和互动信息
  • 本着特色进行mrmr得分,并开展排序
private[feature] def run(
    data: RDD[LabeledPoint],
    nToSelect: Int,
    numPartitions: Int) = {

  val nPart = if(numPartitions == 0) data.context.getConf.getInt(
      "spark.default.parallelism", 500) else numPartitions

  val requireByteValues = (l: Double, v: Vector) => {       
    val values = v match {
      case SparseVector(size, indices, values) =>
        values
      case DenseVector(values) =>
        values
    }
    val condition = (value: Double) => value <= 255 &&
      value >= 0
    if (!values.forall(condition(_)) || !condition(l)) {
      throw new SparkException(s"Info-Theoretic Framework requires positive values in range [0, 255]")
    }          
  }

  val nAllFeatures = data.first.features.size + 1
  // 将数据排列成栏状,其实是为每个数据都编上号
  val columnarData: RDD[(Long, Short)] = data.zipWithIndex().flatMap ({
    case (LabeledPoint(label, values: SparseVector), r) =>
      requireByteValues(label, values)
      // Not implemented yet!
      throw new NotImplementedError()          
    case (LabeledPoint(label, values: DenseVector), r) =>
      requireByteValues(label, values)
      val rindex = r * nAllFeatures
      val inputs = for(i <- 0 until values.size) yield (rindex + i, values(i).toShort)
      val output = Array((rindex + values.size, label.toShort))
      inputs ++ output   
  }).sortByKey(numPartitions = nPart) // put numPartitions parameter       
  columnarData.persist(StorageLevel.MEMORY_AND_DISK_SER) 

  require(nToSelect < nAllFeatures)
  // 计算mrmr过程及对特征进行排序
  val selected = selectFeatures(columnarData, nToSelect, nAllFeatures)

  columnarData.unpersist()

  // Print best features according to the mRMR measure
  val out = selected.map{case F(feat, rel) => (feat + 1) + "\t" + "%.4f".format(rel)}.mkString("\n")
  println("\n*** mRMR features ***\nFeature\tScore\n" + out)
  // Features must be sorted
  new SelectorModel(selected.map{case F(feat, rel) => feat}.sorted.toArray)
}

下面是因相互信息以及mrmr的特色选择过程:

/**
 * Perform a info-theory selection process.
 *
 * @param data Columnar data (last element is the class attribute).
 * @param nToSelect Number of features to select.
 * @param nFeatures Number of total features in the dataset.
 * @return A list with the most relevant features and its scores.
 *
 */
private[feature] def selectFeatures(
    data: RDD[(Long, Short)],
    nToSelect: Int,
    nFeatures: Int) = {

  // 特征的下标
  val label = nFeatures - 1
  // 因为data是(编号,每个特征),所以这是数据数量
  val nInstances = data.count() / nFeatures
  // 将同一类特征放在一起,根据同一key进行分组,然后取出最大值加1(用于后续构建分布直方图的参数)
  val counterByKey = data.map({ case (k, v) => (k % nFeatures).toInt -> v})
        .distinct().groupByKey().mapValues(_.max + 1).collectAsMap().toMap

  // calculate relevance
  val MiAndCmi = IT.computeMI(
      data, 0 until label, label, nInstances, nFeatures, counterByKey)
  // 互信息池,用于mrmr判定,pool是(feat, Mrmr)
  var pool = MiAndCmi.map{case (x, mi) => (x, new MrmrCriterion(mi))}
    .collectAsMap() 
  // Print most relevant features
  // Print most relevant features
  val strRels = MiAndCmi.collect().sortBy(-_._2)
    .take(nToSelect)
    .map({case (f, mi) => (f + 1) + "\t" + "%.4f" format mi})
    .mkString("\n")
  println("\n*** MaxRel features ***\nFeature\tScore\n" + strRels) 
  // get maximum and select it
  // 得到了分数最高的那个特征及其mrmr
  val firstMax = pool.maxBy(_._2.score)
  var selected = Seq(F(firstMax._1, firstMax._2.score))
  // 将firstMax对应的key从pool这个map中去掉
  pool = pool - firstMax._1

  while (selected.size < nToSelect) {
    // update pool
    val newMiAndCmi = IT.computeMI(data, pool.keys.toSeq,
        selected.head.feat, nInstances, nFeatures, counterByKey)
        .map({ case (x, crit) => (x, crit) })
        .collectAsMap()

    pool.foreach({ case (k, crit) =>
      // 从pool里拿出第k个特征,然后从newMiAndCmi中得到对应的mi
      newMiAndCmi.get(k) match {
        case Some(_) => crit.update(_)
        case None =>
      }
    })

    // get maximum and save it
    val max = pool.maxBy(_._2.score)
    // select the best feature and remove from the whole set of features
    selected = F(max._1, max._2.score) +: selected
    pool = pool - max._1
  }   
  selected.reverse
}

现实测算互信息的代码如下:

/**
 * Method that calculates mutual information (MI) and conditional mutual information (CMI)
 * simultaneously for several variables. Indexes must be disjoint.
 *
 * @param rawData RDD of data (first element is the class attribute)
 * @param varX Indexes of primary variables (must be disjoint with Y and Z)
 * @param varY Indexes of secondary variable (must be disjoint with X and Z)
 * @param nInstances    Number of instances
 * @param nFeatures Number of features (including output ones)
 * @return  RDD of (primary var, (MI, CMI))
 *
 */
def computeMI(
    rawData: RDD[(Long, Short)],
    varX: Seq[Int],
    varY: Int,
    nInstances: Long,     
    nFeatures: Int,
    counter: Map[Int, Int]) = {

  // Pre-requisites
  require(varX.size > 0)

  // Broadcast variables
  val sc = rawData.context
  val label = nFeatures - 1
  // A boolean vector that indicates the variables involved on this computation
  // 对应每个数据不同维度的特征的一个boolean数组
  val fselected = Array.ofDim[Boolean](nFeatures)
  fselected(varY) = true // output feature
  varX.map(fselected(_) = true) // 将fselected置为true
  val bFeatSelected = sc.broadcast(fselected)
  val getFeat = (k: Long) => (k % nFeatures).toInt
  // Filter data by these variables
  // 根据bFeatSelected来过滤rawData
  val data = rawData.filter({ case (k, _) => bFeatSelected.value(getFeat(k))})

  // Broadcast Y vector
  val yCol: Array[Short] = if(varY == label){
   // classCol corresponds with output attribute, which is re-used in the iteration
    classCol = data.filter({ case (k, _) => getFeat(k) == varY}).values.collect()
    classCol
  }  else {
    data.filter({ case (k, _) => getFeat(k) == varY}).values.collect()
  }   

  // data是所有选择维度的特征,(varY, yCol)是y所在的列和y值数组
  // 生成特征与y的对应关系的直方图
  val histograms = computeHistograms(data, (varY, yCol), nFeatures, counter)
  // 这里只是对数据规约成占比的特征和目标变量的联合分布
  val jointTable = histograms.mapValues(_.map(_.toFloat / nInstances))
  // sum(h(*, ::))计算每一行数据之和
  val marginalTable = jointTable.mapValues(h => sum(h(*, ::)).toDenseVector)

  // If y corresponds with output feature, we save for CMI computation
  if(varY == label) {
    marginalProb = marginalTable.cache()
    jointProb = jointTable.cache()
  }

  val yProb = marginalTable.lookup(varY)(0)
  // Remove output feature from the computations
  val fdata = histograms.filter{case (k, _) => k != label}
  // fdata是特征与y的联合分布,yProb是一个值
  computeMutualInfo(fdata, yProb, nInstances)
}

算数据分布直方图的主意:

private def computeHistograms(
    data: RDD[(Long, Short)],
    yCol: (Int, Array[Short]),
    nFeatures: Long,
    counter: Map[Int, Int]) = {

  val maxSize = 256
  val byCol = data.context.broadcast(yCol._2)   
  val bCounter = data.context.broadcast(counter)
  // 得到y的最大值
  val ys = counter.getOrElse(yCol._1, maxSize).toInt

  // mapPartitions是对rdd每个分区进行操作,it为分区迭代器
  // map得到的是(feature, matrix)的Map
  data.mapPartitions({ it =>
    var result = Map.empty[Int, BDM[Long]]
    for((k, x) <- it) {
      val feat = (k % nFeatures).toInt; val inst = (k / nFeatures).toInt
      // 取得具体特征的最大值
      val xs = bCounter.value.getOrElse(feat, maxSize).toInt
      val m = result.getOrElse(feat, BDM.zeros[Long](xs, ys)) // 创建(xMax,yMax)的矩阵
      m(x, byCol.value(inst)) += 1
      result += feat -> m
    }
    result.toIterator
  }).reduceByKey(_ + _)
}

测算互信息之公式:

private def computeMutualInfo(
    data: RDD[(Int, BDM[Long])],
    yProb: BDV[Float],
    n: Long) = {   

  val byProb = data.context.broadcast(yProb)
  data.mapValues({ m =>
    var mi = 0.0d
    // Aggregate by row (x)
    val xProb = sum(m(*, ::)).map(_.toFloat / n)
    for(i <- 0 until m.rows){
      for(j <- 0 until m.cols){
        val pxy = m(i, j).toFloat / n
        val py = byProb.value(j); val px = xProb(i)
        if(pxy != 0 && px != 0 && py != 0) // To avoid NaNs
          // I(x,y) = sum[p(x,y)log(p(x,y)/(p(x)p(y)))]
          mi += pxy * (math.log(pxy / (px * py)) / math.log(2))
      }
    }
    mi       
  }) 
}

Face ID,是iPhone X用于代替Touch
ID而生产的刷脸认证方法,搭载环境光传感器、距离感应器,还并了红外镜头、泛光感应元件(flood
camera)和点阵投影器,多种布置并搭建用户3D 脸部模型。

(3)mllib中合拢学习算法计算特征重要性的源码

当spark
2.0后,mllib的仲裁树算法都引入了算特征重要性的计featureImportances,而任意森林算法(RandomForestRegressionModel和RandomForestClassificationModel类)和gbdt算法(GBTClassificationModel和GBTRegressionModel类)均以决策树算法中计算特征未纯度和特性重要性的法子来得到所采取模型的特征重要性。
若是这些合并方法的落实类似都围拢成了TreeEnsembleModel[M <:
DecisionTreeModel]是特质(trait),即featureImportances是当拖欠特质中实现之。
featureImportances方法的为主计算思路是:

  • 对各一样株决策树而言,特征j的基本点指标为具备通过特征j进行分的树结点的增益的和
  • 用同样蔸树的风味重要性归一化到1
  • 将合并模型的性状重要性向量归一化到1

以下是源码分析:

def featureImportances[M <: DecisionTreeModel](trees: Array[M], numFeatures: Int): Vector = {
  val totalImportances = new OpenHashMap[Int, Double]()
  // 针对每一棵决策树模型进行遍历
  trees.foreach { tree =>
    // Aggregate feature importance vector for this tree
    val importances = new OpenHashMap[Int, Double]()
    // 从根节点开始,遍历整棵树的中间节点,将同一特征的特征重要性累加起来
    computeFeatureImportance(tree.rootNode, importances)
    // Normalize importance vector for this tree, and add it to total.
    // TODO: In the future, also support normalizing by tree.rootNode.impurityStats.count?
    // 将一棵树的特征重要性进行归一化
    val treeNorm = importances.map(_._2).sum
    if (treeNorm != 0) {
      importances.foreach { case (idx, impt) =>
        val normImpt = impt / treeNorm
        totalImportances.changeValue(idx, normImpt, _ + normImpt)
      }
    }
  }
  // Normalize importances
  // 归一化总体的特征重要性
  normalizeMapValues(totalImportances)
  // Construct vector
  // 构建最终输出的特征重要性向量
  val d = if (numFeatures != -1) {
    numFeatures
  } else {
    // Find max feature index used in trees
    val maxFeatureIndex = trees.map(_.maxSplitFeatureIndex()).max
    maxFeatureIndex + 1
  }
  if (d == 0) {
    assert(totalImportances.size == 0, s"Unknown error in computing feature" +
      s" importance: No splits found, but some non-zero importances.")
  }
  val (indices, values) = totalImportances.iterator.toSeq.sortBy(_._1).unzip
  Vectors.sparse(d, indices.toArray, values.toArray)
}

其中computeFeatureImportance方法为:

// 这是计算一棵决策树特征重要性的递归方法
def computeFeatureImportance(
    node: Node,
    importances: OpenHashMap[Int, Double]): Unit = {
  node match {
    // 如果是中间节点,即进行特征划分的节点
    case n: InternalNode =>
      // 得到特征标记
      val feature = n.split.featureIndex
      // 计算得到比例化的特征增益值,信息增益乘上该节点使用的训练数据数量
      val scaledGain = n.gain * n.impurityStats.count
      importances.changeValue(feature, scaledGain, _ + scaledGain)
      // 前序遍历二叉决策树
      computeFeatureImportance(n.leftChild, importances)
      computeFeatureImportance(n.rightChild, importances)
    case n: LeafNode =>
    // do nothing
  }
}

原先深感摄像头会通过炫耀并分析30,000差不多个不可见的触发来捕获准确的脸数据,进而创造而面部的吃水图;另外它还见面捕获您面部的红外图像。

(2)mRMR

故而出现mRMR算法来展开特色选择,主要是为了解决由此最大化特征和对象变量的系涉嫌度量得到的极度好之m个特征,并不一定会获得最好的前瞻精度之题材。
面前介绍的评论特征的法门基本都是依据是否跟对象变量具有高相关性的特性,但是这些特征里还可能含有冗余特征(比如目标变量是立方体体积,特征呢底面的长度、底面的增长率、底面的面积,其实底面的面积可以由长与富有得,所以只是吃认为是一律种植冗余信息),mRMR算法就是因此来在保管最好要命相关性的又,又失去除了冗余特征的道,相当给博了同等组“最单纯”的特点子集(特征之间区别大十分,而同目标变量的相关性也十分要命)。
当一个特例,变量之间的相关性(correlation)可以就此统计学的依赖关系(dependency)来替,而彼此信息(mutual
information)是如出一辙种植评价该依赖关系的心气方法。
mRMR可看是最大化特征子集的联手分布和对象变量之间因关系之一律种类似
mRMR本身或属于filter型特征选择方式。

可以经过max(V-W)或max(V/W)来统筹考虑相关性和冗余性,作为特色评价的标准。

解锁
安全性对具有人的话还主要,Face
ID能确保设施及之音讯安全无虑,和针对性TouchID采取的保护措施一样。
Face ID利用原本深感摄像头及机器上技术,提供了平等种安全的认证解决方案。
当开锁时用户仅待看在手机,Face ID就能够实现刷脸解锁。

(2)通过gini不纯度计算特征重要性

管是scikit-learn还是mllib,其中的自由森林与gbdt算法都是依据决策树算法,一般的,都是采取了cart树算法,通过gini指数来算特征的重要性的。
比如scikit-learn的sklearn.feature_selection.SelectFromModel可以兑现冲特征重要性分支进行特色的变换。

>>> from sklearn.ensemble import ExtraTreesClassifier
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X.shape
(150, 4)
>>> clf = ExtraTreesClassifier()
>>> clf = clf.fit(X, y)
>>> clf.feature_importances_ 
array([ 0.04...,  0.05...,  0.4...,  0.4...])
>>> model = SelectFromModel(clf, prefit=True)
>>> X_new = model.transform(X)
>>> X_new.shape              
(150, 2)

2.Face ID发出什么用

附录

逻辑回归模型与离散特征
将连特征离散化(像是独热编码之类的技术)交给逻辑回归模型,这样做的优势来以下几点:

  1. 疏散为量内积乘法运算速度快,计算结果好存储,容易扩展。
  2. 离散化后的特性对大数据来不行强的鲁棒性:比如一个特色是年纪>30凡1,否则0。如果特征没有离散化,一个百般数据“年龄300年份”会于范造成十分充分的干扰。
  3. 逻辑回归属于广义线性模型,表达能力受限;单变量离散化为N个后,每个变量有单独的权重,相当给为模型引入了非线性,能够提升型表达能力,加大拟合。
  4. 离散化后好开展特色交叉,由M+N个变量变为M*N个变量,进一步引入非线性,提升表达能力。
  5. 特色离散化后,模型会另行安定,比如使对用户年龄去散化,20-30作为一个区间,不会见因为一个用户年龄增长了同岁即变成一个毕两样之总人口。当然处于区间相邻处的样本会刚好相反,所以怎么划分区间是家学问。
    李沐少帅指出,模型是以离散特征还是连续特征,其实是一个“海量离散特征+简单模型”

    “少量连接特征+复杂模型”的权衡。既好离散化用线性模型,也可据此连特征加深度上。

贯彻动画表情
而尽体系除去能够用来Face
ID人脸验证,也堪扩大自拍功能,实现动画表情。
Animoji动话表情下到了Face
ID中的人数脸定位、三维建模、图像处理等技术,同时为使至了AR增强现实的有关技术,可以说凡是一个虽看起简单,但事实上很考验技术实力而且使用上深有趣之应用环境。

一如既往、 特征选择的几个泛问题

  • 为什么?
    (1)降低维度,选择要的风味,避免维度灾难,降低计算成本
    (2)去除不相干的冗余特征(噪声)来下滑学习之难度,去除噪声的烦扰,留下关键因素,提高预测精度
    (3)获得重新多来物理意义之,有价之特点

  • 差模型有例外之特色适用型?
    (1)lr模型适用于拟合离散特征(见附录)
    (2)gbdt模型适用于拟合连续数值特征
    (3)一般说来,特征有比充分的方差说明蕴含较多信息,也是较起价的特点

  • 特色子集的搜索:
    (1)子集搜索问题。
    比如逐步丰富相关特征(前望forward搜索)或逐步失去丢无关特征(后往backward搜索),还有双向搜索。
    缺陷是,该政策也贪欲算法,本轮最完美并不一定是全局最美妙,若不能够穷举搜索,则无法避免欠问题。
    该子集搜索策略属于最为深连锁(maximum-relevance)的精选策略。
    (2)特征子集评价和胸襟。
    信增益,交叉熵,相关性,余弦相似度等评级准则。

  • 一流的表征选择方式

鉴别精度
Face ID识别的精确度则是iPhone
X安全性的重点,以往因二维平面的面识别技术于即时点强烈无法和基于三维成像的Face
ID相提并论,而跟跟为生物识别技术之Touch
ID指纹识别相比,从苹果宣布的多寡来拘禁是应有是优化的,我以为识别精准性大家要么得以放心的。

(4)mllib中决定树算法计算特征未纯度的源码

InternalNode类使用ImpurityCalculator类的私家实例impurityStats来记录不纯度的信息与状态,具体运用啊一样栽划分方式经过getCalculator方法来拓展分选:

def getCalculator(impurity: String, stats: Array[Double]): ImpurityCalculator = {
  impurity match {
    case "gini" => new GiniCalculator(stats)
    case "entropy" => new EntropyCalculator(stats)
    case "variance" => new VarianceCalculator(stats)
    case _ =>
      throw new IllegalArgumentException(
        s"ImpurityCalculator builder did not recognize impurity type: $impurity")
  }
}

因gini指数为条例,其消息计算的代码如下:

@Since("1.1.0")
@DeveloperApi
override def calculate(counts: Array[Double], totalCount: Double): Double = {
  if (totalCount == 0) {
    return 0
  }
  val numClasses = counts.length
  var impurity = 1.0
  var classIndex = 0
  while (classIndex < numClasses) {
    val freq = counts(classIndex) / totalCount
    impurity -= freq * freq
    classIndex += 1
  }
  impurity
}

上述源码解读即是起并方法来测算特征重要性及决策树算法具体算节点特征未纯度方法的历程。

iPhone
X的音信或者都理解了,它正面几乎均是屏幕,也便意味着唯一的按键Home键以及Touch
ID的收敛,而初的位置证明方法就是是Face ID。

其三、最老连锁最小冗余(mRMR)算法

9月13如泣如诉凌晨底苹果发布会上,苹果发布了崭新的十周年纪念版全面屏iPhone
X,并且带来了新的Face ID技术。

参考资料

  • 机械上,周志华
  • 交互信息的明亮
    http://www.fuzihao.org/blog/2015/01/17/%E4%BA%92%E4%BF%A1%E6%81%AF%E7%9A%84%E7%90%86%E8%A7%A3/
  • Feature Selection Based on Mutual Information: Criteria of
    Max-Dependency, Max-Relevance, and Min-Redundancy
  • An improved implementation of the classical feature selection
    method: minimum Redundancy and Maximum Relevance (mRMR).
    https://github.com/sramirez/fast-mRMR

转载请注明作者Jason Ding及其出处
jasonding.top
Github博客主页(http://blog.jasonding.top/)
CSDN博客(http://blog.csdn.net/jasonding1354)
简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest\_articles)
Google搜索jasonding1354跻身我之博客主页

Animoji动画表情

(1)决策树划分属性的依据

Face ID的贯彻依靠的是iPhone
X顶部一如既往稍片没让屏幕覆盖的区域。这无异粗片区域并了差不多上八单零件,除了麦克风(Microphone)、扬声器(Speaker)、前置摄像头(Front
camera)、环境光传感器(Ambient light sensor)、距离感应器(Proximity
sensor)等我们熟悉的组成部分,还并了红外镜头(Infrared
camera)、泛光感应元件(Flood illuminator)、点阵投影器(Dot projector)。

仲、从决策树模型的特征重要性说打

决策树好当作是前方望寻找以及信熵相结合的算法,树节点的分开属性所成的会师就是择下的特征子集。

iPhone X

苹果统计还是也之开了一个神经引擎(Neural Engine),可就经常处理人脸识别。
A11仿生芯片的神经网络引擎起一部分安康存放于SecureEnclave中,它会用深度图跟红外图像转换为数学表示形式,然后还将此象征形式和注册之颜面数据进行比。
苹果高级副总裁Phil
Schiller于发布会及说明称,“我们因而神经网络处理图像和点阵模式,来起人口脸数学模型。”

Face ID比Touch ID更为安全,Touch ID被破解的票房价值是1/50,000,而Face
ID概率大概也1/1,000,000。
用作一如既往件附加的保护措施,Face
ID只同意匹配尝试失败五涂鸦,之后便欲输入密码。
当时同统计概率值对于有人群有所不同,其中包双胞胎、和汝长得好像的兄弟姐妹,以及无满13周岁底小家伙,因为他们或许还无全形成明确的面特征。

刷脸支付
Face ID同时支持Apple
Pay和老三正值采取,人脸识别与刷脸支付已经于外界熟知,马云为早已在支付宝上进行现身说法。
这次苹果之Face
ID在二维底图像上叠加了相同交汇深度信息,可以保证人脸识别更安全。
对此人脸识别中用照片蒙骗系统的问题,由于来了3D信息,也自免顶意向。

鉴别速度
就是分辨速度而言,Face ID要拍卖的数比较由Touch
ID实际上只要重多,不过得益于性能更强悍A11电脑和那构成的Neural生物引擎,还有基于神经网络的算法,从当下来拘禁Face
ID识别速度比较由Touch ID应该出高效的升级换代,响应速度也愈发灵活。

3.总结
对此Face
ID或者说面部识别术以来,影响该经验的面除了两个,一个凡是可辨速度,另一个虽是识别的精准性。

本来深感摄像头(TrueDepth Camera System)

1.Face ID是什么