精华内容
下载资源
问答
  • 前言 由于LeetCode上的算法题很多涉及到一些基础的数据结构,为了更好的理解后续更新...快速排序是由东尼·霍尔所发展的种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2)...

    前言

    由于LeetCode上的算法题很多涉及到一些基础的数据结构,为了更好的理解后续更新的一些复杂题目的动画,推出一个新系列 -----《图解数据结构》,主要使用动画来描述常见的数据结构和算法。本系列包括十大排序、堆、队列、树、并查集、图等等大概几十篇。

    快速排序

    快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

    快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

    快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。

    算法步骤

    1. 从数列中挑出一个元素,称为 “基准”(pivot);

    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

    递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

    来源:github.com/hustcc/JS-S…

    算法演示

    排序动画过程解释

    1. 首先,操作数列中的所有数字

    2. 在所有数字中选择一个数字作为排序的基准(pivot), pivot 通常是随机选择的,在这里为了演示方便,我们选择最右边的数字作为 pivot

    3. 选取好 pivot 后,在操作数列中选择最左边的数字标记为 左标记 ,最右边的数字标记为 右标记

    4. 将左边的标记向右移动

    5. 当 左标记 达到超过 pivot 的数字时,停止移动

    6. 在这里,8 > 6 ,所以停止移动

    7. 然后将右边的标记向左移动

    8. 当 右标记 达到小于 pivot 的数字时,停止移动

    9. 在这里,4 > 6 ,所以停止移动

    10. 当左右标记停止时,更改标记的数字

    11. 因此,左标记 的作用是找到一个大于 pivot 的数字,右标记 的作用是找到一个小于 pivot 的数字

    12. 通过交换数字,可以在数列的左边收集小于 pivot 的数字集合,右边收集大于 pivot 的数字集合

    13. 交换之后,继续移动 左标记

    14. 在这里,9 > 6 ,所以停止移动

    15. 然后将右边的标记向左移动

    16. 当 右标记 碰撞到 左标记 时也停止移动

    17. 如果左右侧的标记停止时,并且都在同一个位置,将这个数字和 pivot 的数字交换

    18. 这就完成了第一次操作

    19. 小于 6 的都在 6 的左侧,大于 6 的都在 6 的右侧

    20. 然后递归对这分成的两部分都执行同样的操作

    21. 完成 快速排序

    代码实现

    为了更好的让读者用自己熟悉的编程语言来理解动画,笔者将贴出多种编程语言的参考代码,代码全部来源于网上。

    C++代码实现

    Java代码实现

    Python代码实现

    JavaScript代码实现

    如果你是iOS开发者,可以在GitHub上 github.com/MisterBooo/… 获取更直观可调试运行的源码。

    你可以关注公众号 五分钟学算法 获取更多排序内容。

    欢迎关注:

    展开全文
  • 点击上方,选择星标或置顶,每天给你送干货!阅读大概需要8分钟跟随小博主,每天进步丢丢每日英文There is a wholeness about the person who has ...

    点击上方,选择星标置顶,每天给你送干货

    阅读大概需要8分钟

    跟随小博主,每天进步一丢丢

    每日英文

    There is a wholeness about the person who has come to terms with his limitations.

    人生的完整在于一个人知道如何面对他的缺陷。

    Recommender:云不见

    作者:刘子仪

    编辑:王萌 (深度学习自然语言处理公众号)

    EM算法是机器学习中比较重要的用于对于带有隐变量的联合概率模型参数进行极大似然估计的方法。因为这篇文章单独把EM算法抽出来讲,对于没有统计学习基础的同学来说,理解这个算法是如何引出的可能会有些困难,会需要关于ELBO,KL散度等相关知识储备。所以本文将从以下几个方面来讲解,让入门的同学可以快速对EM算法有一个大体的认知:

    • EM算法要解决什么问题

    • EM算法的E-step和M-step以及证明其收敛性

    • EM算法的应用

    一.EM算法要解决什么问题

    EM(期望最大化)算法于1976年提出,这篇论文的名字是“Maximum Likelihood for Incomplete Data via the EM Algorithm”。其实论文题目已经非常清楚地说明了EM算法作用——从incomplete data中进行极大似然求解。

    什么是incomplete data呢,作者给出的定义是如果有两个样本空间Z和X以及关于Z->X的映射。x∈X是可以观察到的数据,而z∈Z是不能直接观察到,只能通过x间接观察到的数据,这样的数据就是incomplete data,我们称z为隐变量,EM算法的目的就是通过E-step和M-step迭代的方式进行极大似然估计,对含有隐变量的概率模型进行参数估计。

    二.EM算法的公式以及证明其收敛性

    假设输入的数据是观测数据X,隐变量数据Z,联合分布为P(x,z|θ),条件分布P(z|x,θ),要求解的是模型参数θ。

    MLE(极大似然估计)问题的其实就是求解,为了方便求解一般会加上log,后面这个式子也称为log likelihood。EM算法就是通过迭代的方式求出这个式子的解析解。

    首先选择参数初值, 开始迭代。假设是第t次迭代参数的估计值,在第t+1次迭代时,EM算法的公式是 

    这个式子后半部分的积分其实就是求期望,对应的E步我们称这个函数为Q函数,在证明收敛性时会用到,前面的加上argmax函数就是最大化,对应M步。式中是联合概率,是后验概率。

    需要注意的是,虽然参数的初值可以任意选择,但是EM算法对于初值是敏感的,随意取初值很有可能得不到好的结果,所以还是要慎重取值。

    了解了公式之后,接下来我们来证明EM算法的收敛性。即证明

     首先,两边同时取对数得 

    由上文可知 

    令 

    则 (解释说明:对于来说,和求期望没有关系,可以提取出来,而后面的等于1,所以等于同理。

    对于上式分别取θ并相减,有

    为了证明,只需证明上式右端为非负的。由于在EM算法里,在M步会对Q函数求极大,则 

    对于第二项

       

    这里的不等式由Jenson不等式得到。其实如果了解KL散度可以发现  又因为KL散度大于等于0,所以可得最后结果小于等于0。

    三.EM算法的应用

    之前有一次面试,面试官问我机器学习算法都会哪些,我说到了EM算法,然后她问EM算法有什么应用吗,她觉着EM算法没有什么应用场景。其实EM算法应用还是比较广泛的,尤其是在高斯混合模型做参数估计的时候。EM算法不像感知机,支持向量机应用普遍,它很少作为分类算法被使用,EM算法作为一种参数估计的方法,更多是和概率模型结合使用,例如用于马尔可夫模型参数求解。同时EM算法还有一些推广:GEM算法,变分EM等等。

    说个正事哈

    由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:

    (1)点击页面最上方深度学习自然语言处理”,进入公众号主页。

    (2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。

    感谢支持,比心

    投稿或交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

    方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等

    记得备注呦

    推荐两个专辑给大家:

    专辑 | 李宏毅人类语言处理2020笔记

    专辑 | NLP论文解读

    
    整理不易,还望给个在看!
    
    展开全文
  • 快速排序是种高效的排序算法,也是面试常考的算法,大多数人畏惧和逃避算法,不是因为算法有多难,而是没有找到合适的老师,简单说就是没有通俗易懂的文章,导致学习者越看越懵,看完即忘的现象。今天我想尝试...

    快速排序是一种高效的排序算法,也是面试常考的一种算法,大多数人畏惧和逃避算法,不是因为算法有多难,而是没有找到合适的老师,简单说就是没有通俗易懂的文章,导致学习者越看越懵,看完即忘的现象。今天我想尝试做一个“好老师”,用通俗易懂的方式讲解一下什么是快速排序。

    图解思想

    很多文章,上来就用某种语言,开始啪啦啪啦写代码,不熟悉该种语言的学者,一脸蒙蔽,又是一篇水文。或者跟着代码看了一下,感觉会了,关掉网页,脑子:what???我刚才看了啥?

    算法与编程语言无关,它是一种思想,理解了思想,编程语言只是一种实现方式。

    OK,来看看快速排序的思想

    假设现在有一个乱序的数组:

    5 3 6 1 4 8 2 7
    

    快速排序核心思想:

    随意找一个目标值,放在数组的某个下标,使得该下标的左侧数值都小于目标值,右侧数值都大于目标值

    随意选一个目标值,假如就数组的第一个数值 5,现在需要将 5 移动到数组的某个下标 K 上,并且以 K 为临界点,左边的数小于 5 ,右边的数大于 5 ,该怎么操作?

    使用一种二分交换的思想,以什么分?以下标 K 分。需要解决2个问题,如何交换数值,如何确定下标 K

    如何交换?

    模拟两个人,从数组 5 3 6 1 4 8 2 7 两边开始探测,先从右往左开始找一个小于5的数,再从左往右找一个大于5的数,然后交换数据,交换完成继续探测,直到两个人相遇

    模拟的两个人暂且称它们为:“探子j”"探子i"

    开始时,“探子j” 站在 右边“探子i” 站在 左边
    在这里插入图片描述由于我们选了最左边的数为 基准数,所以要从右边的 “探子j” 先出发,这个很重要(原因等你看完整个思路,自己模拟从左边开始试试就知道哪里出错了)
    "探子j" 一步步向左移动(j- -)寻找小于 5 的数字,找到 2 满足,停下来。再出动 “探子i” 一步步向右移动(i++)寻找大于5的数字,找到 6 满足,停下来。此时 “探子i” 停在6上,“探子j” 停在2上,然后交换 i 和 j 的数值
    在这里插入图片描述
    到这里完成了第一次交换,数组变化:

    5 3 6 1 4 8 2 7 => 5 3 2 1 4 8 6 7

    在现有的位置上继续探测,还是从 “探子j” 开始(强调,每次都是从探子j开始),继续向左移动(j- -),找到 4 满足,停下来;然后 “探子i” 开始继续往右寻找,走到 4 没有找到大于 5 的数字两个人就相遇了。(如果相遇之前能找到满足的数值,则依旧交换这两个值)在这里插入图片描述

    如何确定下标 K

    当两个探子相遇的下标位置,就是下标 K,此时将下标 K 数值与之前选择的 基准数 相互交换,实现 K 的左边都小于基准数,右边大于基准数在这里插入图片描述
    到这一步,我们确定了临界点 K,并且实现 K 左边的数小于 基准数 ,右边的数大于 基准数。得到数组:

    4 3 2 1 5 8 6 7

    以 K (5) 做分界点,将数组分为两个部分,然后将左右两边的子数组在执行上述操作,最终将整个数组完成排序

    OK,以上就是快速排序的基本思想,应该可以理解吧。

    撸码实现算法

    理解了思想,就按照这算法的思想一步步写代码就行了,本人熟悉java,就用java作为编程语言撸一遍

     	/**
         * 快速排序
         *
         * @param array 目标数组
         * @param left  数组最左下标值
         * @param right 数组最右下标值
         */
        public static void quickSort(int[] array, int left, int right) {
    
            //防止数组越界(这一步最后再回来理解)
            if (left >= right) return;
    
            int base = array[left];//基准数
            int i = left, j = right;//左探子i,右探子j
            int temp;//用于交换的临时变量
    
            while (i != j) {//两个探子相遇前
    
                //找出小于 基准数 的下标,当大于等于 基准数 的时候,探子j 向左移动即可(j--)
                while (array[j] >= base && i < j) {
                    j--;
                }
    
                //找出大于 基准数 的下标,当小于等于 基准数 的时候,探子i 向右移动即可(i++)
                while (array[i] <= base && i < j) {
                    i++;
                }
    
                //经过上面两个循环之后,探子j,探子i 都会停在符合条件的值的下标上面,然后就可以进行交换值啦
                if (i < j) {
                    temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
    
            //经过上面的循环之后会触发 i=j 的条件(即两个探子相遇),此时将基准值的数与i或者j(随便哪个都一样)下标的值交换,完成一次交换探测
            array[left] = array[i];//基准值的位置
            array[i] = base;//基准值
    
            //完成交换之后再对左右两边的子数组进行递归调用走上面的方法,完成整个数组的排序
            quickSort(array, left, i - 1);//左边
            quickSort(array, i + 1, right); //右边
        }
    

    读注释!读注释!读注释!然后就是,使用快排算法排序数组

            int[] array = new int[]{5, 3, 6, 1, 4, 8, 2, 7};
            quickSort(array, 0, array.length - 1);//快速排序
            for (int i = 0; i < array.length; i++) {
                System.out.print(array[i] + " ");//打印排序后的数组
            }
    

    结果输出

    1 2 3 4 5 6 7 8 
    
    展开全文
  • . 反向传播算法 1. BP算法自然语言描述   概念:梯度下降是利用损失函数的梯度,来决定最终的下降方向。反向传播算法是计算复杂梯度的方式。数学原理就是链式法则。   梯度向量中每项,不光告诉我们每个...

    一. 反向传播算法

    1. BP算法自然语言描述

      概念:梯度下降是利用损失函数的梯度,来决定最终的下降方向。反向传播算法是计算复杂梯度的方式。数学原理就是链式法则。
      梯度向量中每一项,不光告诉我们每个参数增加还是缩小。并且指出了每个参数的“性价比


    在这里插入图片描述

      我们从单样本训练进行观察。


    在这里插入图片描述

      输入的特征为784个,两层隐藏层,输出层为类别,10个节点。输出的目标为识别为2,我们看到输出层的激活值因为网络还没有训练好,值非常的随机。我们都是希望正确分类的激活值应该最大,其他的接近于0.。而激活值是由输入值权重来决定的。第一次训练的时候权重偏置都是随机设置的,那如何进行更改?
      我们最简单的方式去考虑,激活值变动,应该和当前的目标值之间的误差成正比。目前2的激活值为0.2,距离输出值1差距很大,而8的激活值为0.2,距离输出值0差距很小。所以增加2的激活值要比8更大一些。
      输出分类为2的激活函数如下图所示


    在这里插入图片描述

      根据式子我们可以看出,增大权重、增大偏置、调整上一层的激活值。可以增加当前的激活值。
      1) 如何调整权重和偏置?
      (1) 因为偏置没有输入,只作用与当前的神经元,所以可以正比当前值和目标值之间的差来进行调整。
      (2) 权重作用于上一层神经元和下一层神经元之间的连线,反应了连接的强弱,所以上层的激活值越大,那权重对当前的神经元激活值的影响就是巨大的。所以应该正比于关联的上层激活值调整参数。
      2) 如何改变上层的激活值?
      (1) 因为权重带有正负,而激活函数如果是sigmoid和ReLU函数,那么激活值一定是大于等于0的,所以想要增加当前的激活值,应该使正权连接的上层激活值增加,负权连接的上层函数激活值减少。
      (2) 上层激活值的大小也是有上层的权重和偏置还有激活值决定。
    2. 反向传播
      1) 通过上面我们理解到,改变输出神经元的激活值,需要改变上层的神经元激活值已经权重和偏置,但是在单样本训练的过程中,出了增加正确的神经元激活值,还要降低错误的神经元激活值,其他输出神经元也会改变上层的参数值,因此,要将这些神经元的期待全部求和,作为最终的改变上层神经元参数的指示。


    在这里插入图片描述

      2) 综合来说,反向传播的理解就是这样,将所有的期待改变相加,得到对上层改动的变化量,重复这个过程直到第一层。
      3) 实际训练中,是需要同时考虑每个样本对权重与偏置的修改,然后对他们的期望进行平均,作为每个参数的变化量。最终得到的向量就是梯度下降中的负梯度。η 表示倍数。


    在这里插入图片描述

    3. BP算法总结
      1) 反向传播算法计算的是单个训练样本对所有权重和偏置的调整,包括每个参数的正负变化和变化的比例。可以最快的降低损失。
      2) 梯度下降需要对训练集中的每个样本都要进行反省传播,计算说有的平均变化值,然后进行更新。这样做的缺点是会使算法的复杂度和训练样本的数量相关。
      3) 所以最终我们实践时,会使用随机梯度下降。
        (1) 首先是将训练样本打乱
        (2) 然后将所有样本分发到mini-batch中,mini-batch的大小自己决定
        (3) 计算每个mini-batch的梯度,调整参数
        (4) 直到达到某个阈值,或者loss值不再改变
        神经网络最终将会收敛到某个局部最小值上

    PS:下一篇将讲解BP算法数学原理

    参考:https://github.com/imhuay/Algorithm_Interview_Notes-Chinese/blob/master/A-深度学习/A-深度学习基础.md

    展开全文
  • 情景:讲个故事 从前有座山山里有座庙,庙里有个老和尚再给小和尚讲故事,讲的是 从前有座山山里有座庙,庙里有个老和尚再给小和尚讲故事,讲的是 从前有座山山里有座庙,庙里有个老和尚再给小和尚讲故事,讲的是...
  • //快速排速算法,使用迭代 array待排序的数组, s是数组的首索引,t是最后个元素索引 void QuickSort(int[] array, int s, int t) { //定义变量保存被排序的数组索引 int i = s, j = t; //个元素就没有必要...
  • 首先要知道数组从大到小排列的充分必要条件:对于数组中任个数,比它小的数在它左侧,比它大的数在右侧。那么我们只需将数组进行如下操作:1.分解 以a[p]为基准,将比它小的移在a[p]后面 ,比它大的都放在a[p]的...
  • 作者 | 爱笑的眼睛 来源 | 恋习Python(ID:sldata2017)最近在某网站上看到个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感。▼6分钟...
  • 5分钟包你学会快速排序 快速排序(Quicksort)由C. A. R. Hoare在1960年提出。 它的基本思想是:通过趟排序将要排序的数据分割成独立的两部分,其中部分的所有数据都比另外部分的所有数据都要小,然后再按此...
  • 点击上方蓝字设为星标下面开始今天的学习~ 作者 |梁唐 来源 |TechFlow链表是很多数据结构的基础,它的最大特点是支持快速的删除和插入,因此在很多数据频繁变动的场景下使...
  • 前不久,和大学朋友闲聊,得知了一些面试套路,现在基本上大公司,如百度,360,华为,京东,美团等的面试环节,第面都喜欢考数据结构的算法,要求在10分钟内写完程序,第二面喜欢考机器学习的一些概念,问的比较...
  • 该程序创建个神经网络模拟两个输入和个输出的异或功能。import numpy as np #注意:视频中的这行有个错字以下是sigmoid函数的函数定义,它是为这个神经网络选择的非线性类型。它不是唯一可以选择的非线性...
  • 欢迎交流与转载,文章会同步发布在公众号:机器学习算法全栈工程师(Jeemy110)作者:李中梁 @ZL LIKeras框架介绍在用了段时间的Keras后感觉真的很爽,所以特意祭出此文与我们公众号的粉丝分享。Keras是个非常方便...
  • 作者 | 爱笑的眼睛 来源 | 恋习Python(sldata2017)最近在某网站上看到个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感。▼6分钟演示1...
  • 点击上方"brucepk",选择"置顶公众号"第时间关注 Python 技术干货!阅读文本大概需要 3.5 分钟。上次文章分析了 Python 算法中的...
  • ▼6分钟演示15种排序算法https://v.qq.com/x/page/t0396emm8oy.html不知道作者是怎么做的,但是突然很想自己实现遍,而且用python实现特别快,花了天的时间,完成了这个项目。主要包括希尔排序(Shell Sort)、...
  • (给Python开发者加星标,提升Python技能)作者: 恋习Python/ 丁彦军 (本文来自作者投稿)最近在某网站上看到个视频,是关于排序算法的可视化的,看着挺有...
  • 个人学习总结用:数据结构与算法线性表的操作 、线性表的插入 //第i个位置要插入元素 Status ListInsert(SqList *L, int i, ElemType e) { int k;//(下标) if(L->length == MAXSIZE)//是否还有空间 return...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 488
精华内容 195
关键字:

一分钟快速算法