中企动力 > 商学院 > 表格算法
  • ?

    选择Spark机器学习API的四大机器学习算法,你掌握了多少?

    月亭亭

    展开

    作者丨Andrew C. Oliver

    翻译 丨 雨言

    编辑注:本文简要介绍了四种经典的机器学习算法。

    本文将简要介绍Spark机器学习库(Spark MLlib’s APIs)的各种机器学习算法,主要包括:统计算法、分类算法、聚类算法和协同过滤算法,以及各种算法的应用。

    你不是一个数据科学家。“根据科技和商业媒体报道,机器学习将防止全球变暖”,显然只有中国的新闻媒体才会发布类似的虚假新闻,可能机器学习能够识别虚假新闻吧(与分类算法有关)?事实上,机器学习还真的可以呢!

    那么机器学习能做点什么呢?你又将怎样发现呢?如果你已经使用了Apache Spark进行批处理和流处理,那么现在有一东西可以帮你更好地处理。有一个你在用Spark SQL和Spark流处理的时候很可能同时用到的东西,就是Spark MLlib,Spark MLlib是一个API形式的机器学习库和统计算法。

    下面简要介绍一下四种最基本的MLlib APIs,主要包括它们的作用和应用。

    统计算法

    这些API主要是用来进行A-B检验或者A-B-C检验。通常在商业中,我们认为,如果两个东西的平均值相等,那么这两个东西就大体相当了。其实不一定。试想一下,一个汽车制造商换掉汽车座椅之后,做一个关于座椅舒适度的调查。对于个子矮小的用户来说,他们可能觉得座椅更舒服了,但是对于个子高大的用户来说,他们可能会觉得非常不舒服,以至于放弃购买汽车,而个子中等的用户刚好平衡了这个差异。通常,新座椅也许要更舒服一些,但是,如果没有身高超过6英尺的用户购买的话,我们还是失败了。根据Spark的假设测试,你可以先做一个皮尔逊卡方值检验或者一个柯尔莫可洛夫-斯米洛夫检验,先测试一下某个东西的“合适程度”,或者它的取值是否符合“正态分布”。这种方法基本适用于所有需要比较两串数据的情况。“合适程度”表明“你是否喜欢”,或者说新算法是否达到了“优于”旧算法的目的。赶紧报名参加Coursera的基础统计课程吧。

    分类算法

    你的属性是什么?如果你手头有一堆属性不同的东西,你可以让电脑对这些东西进行正确的归类。这里的技巧就是要把各个属性对应到各个“类”,而对于这个分类,并没有标准的正确答案,错误答案倒是不少。如果你认为某人在看一组表格并把它们归类,这就是分类算法。你在使用垃圾邮件过滤器时就已经接触过分类算法了,垃圾邮件过滤器就是过滤掉包含垃圾邮件中常见词语的邮件。分类算法还可以用来诊断患者病情或用来预测哪些用户有可能取消订购有线广播电视(一般是不看体育节目的人)。从本质上来说,分类学习是基于过去的数据标签,然后把这些标签应用到未来的发展预测。在Coursera的机器学习专业化中,有一门专门针对分类学习的课程,7月10开始开课,现在报名参加应该也来得及。

    聚类算法

    当你跟一个人讨论“机器学习”的时候,如果对方只能说出k-means算法,那说明他只看过“小抄”,什么都不懂。如果你手上有一组属性,你可以找到一些关键点把这些属性归为各个类中,这就是聚类算法。你能说出各个不同类之间的区别,但是也有可能有些类是比较接近的。有可能一个大的东西和一个小的东西被归为了同一类,而另一个更小的东西却被归为了大的一类。再加上其他各种复杂的属性和不同的维度,所以其实聚类算法也有很多种。聚类算法和分类算法不同,但是聚类算法经常用来对一群人分组,二者最大的区别在于,在聚类算法中,我们不知道集群前面的标签(或组)是什么,而在分类算法中,标签就很明确了。客户细分是一个常见的应用,不同的客户有不一样的喜好特点,比如可以把客户分成信用组、保留风险组或购买组(对于新鲜农产品或熟食),但是也有可能要根据已有数据进行诈骗识别的分类。Coursera上有专门讲解聚类算法的讲座系列,没错,他们确实有包括k-means算法,但有点诡异的是,有一半的教授是漂浮在黑板表面的(你去看了之后就知道我在说什么了)。

    协同过滤算法

    好吧,协同过滤算法是一种大众化的算法。我们公司就用协同过滤算法去提高搜索结果的精确度,我还做过一个相关的讲座,如果有足够多的人点击第二张猫的照片,那它一定比第一张猫的图片好。在一个社交或电子商务环境中,如果你充分运用各种用户的“喜欢”和“不喜欢”,你就可以找到出对于大部分用户或者某一特定用户群体来说“最好的”结果,这是通过个性化系统的多属性过滤来实现的,例如,当你在Google地图或Yelp上搜索餐厅(你可以根据服务质量、食物种类、内部风格、是否适合小孩、是否有情调、用户评论和消费水平等等进行过滤)时使用的就是这个原理。斯坦福大学机器学习课程有关于协同过滤算法的专题讲座,7月10日开课(现在也还可以报名)。

    上述并不是关于机器学习的所有算法,但也算是使用过程中最常见的几种算法了。以上四个大类中,每一类中都包含好几个可选算法或者衍生算法,那要选哪个呢?好吧,具体选用哪一种算法是考虑数学背景、实验过程和已知数据等各种因素的综合结果。记住,这些算法都只是你分析问题的工具而已,也有可能使用这些算法之后得到的是没有用的结果。

    如果你刚接触机器学习,那Coursera上的机器学习基础 (https://coursera.org/learn/ml-foundations) 可 以带你快速入门――请忽略那一半的诡异的漂浮的教授。

  • ?

    HR要进阶,先吃透人力资源需求预测(内附实用工具表格)

    高垣

    展开

    【C8HR大讲堂干货分享】

    相当一部分人力资源从业者,主要的工作只是招人,领导让招几个就招几个,自己无法进行人力资源需求预测,给出建设性意见。看完这篇文章,或许能帮你早点告别小白阶段。本文节选自《人才招募与评鉴》系列微课第一期,由C8首席面试官,人才甄选、评鉴实战专家 王荣娜 老师主讲。

    人力资源需求预测的方法与步骤是HR及企业管理者需要掌握的知识和技能。

    人力资源需求预测的方法与步骤,总共分为四步。

    第一步,预测现实的人力资源需求。

    首先要对目前岗位人员进行分析,确定公司目前的编制、人员配置是否合理。接着盘点现有人才的胜任情况,哪些人不适岗。然后确定部门人员是超编还是缺编。

    梳理完就有结果了,比如说某某部门现在已经超编了,要淘汰多少。某某部门已经缺编了,要增加多少人员的配置。拿这个报告,和管理者讨论,修正后就是现实的人力资源需求预测。

    第二步,预测未来的人力资源需求。

    很多人做了多年的人力资源,可能主要都是在做招聘的工作,是为了满足公司眼前的用人需求,根本没有做到为企业的发展和规划做预见性、战略性的发展建议。

    做未来人力资源需求预测,首先要跟企业的发展规划挂钩。比如说一个企业有发展规划方向后,肯定会确定各个部门的任务和指标,任务下达后,就可以预料到新增人数。

    企业的发展战略分解出各个部门的职能,各个部门的目标,最终确定到人员上,从而产生了人员的增加或者变动。

    使用这个表你可以做出未来几年的预测。管理职系、销售职系、技术职系,都是按照各个岗位不同模型做的划分。

    对很多HR朋友来说,现实的人力资源需求相对是很好预测的,但是未来的人力资源需求预测就比较难做到。这里给大家一些具体的预测方法。

    未来人力资源需求的预测方法分为两大类。

    第一类叫定性预测方法,就是运用归纳、演绎、分析,从而总结出来的预测方式。第二类叫定量预测方法,就是指运用数学语言,会有函数、算法和公式,是相对比较复杂的方式,前提是企业要有多年的基础数据。

    由于很多企业都缺乏足够的数据,所以今天重点讲如何用定性的方法预测未来的人力资源需求。

    △①、管理评价法。

    指人力资源的需求用一种主观的方法去实现。

    比如说由部门经理和人力资源部人员一起来预测和判断企业在某时间段对人力资源的需求。这种管理评价法有两种,一种自下而上,一种自上而下。

    自下而上,是基层管理人员根据自己的生产能力,员工流动情况,自己先做出一个预测,之后汇报给上级部门。

    自上而下,是指由高层管理者根据组织发展的目标和方向,及经营环境的变化来预测人力资源需求。

    我们在预测的过程中,一定要将“自上而下”和“自下而上”两种方式进行汇总,结合起来用。管理评价法是比较主观的,会受判断者的经验影响。

    △②、现状预测法。

    适用于短期预测,非常简单快捷。

    假定企业保持原有的生产和技术不变,企业的人力资源处于相对稳定的状态。这时候,只要企业目前人员配备比例和人员数量适合我们短期内人力资源需求就可以了。

    人力资源需求预测主要就是推算出规划期内哪些岗位上的人员将得到晋升、降职、退休或者调出本组织。然后再准备调动人员去弥补就可以了。

    △③、经验预测法。

    比较适合稳定型的小企业。

    利用线下情报和资料,结合以往的经验,再结合自己企业的特点来预测企业未来的人员和需求。预测的结果受经验的影响比较大。需要多查一些资料,多几个人综合去预测,以减少误差。

    △④、情景描述法。

    适用于特别的阶段,比如说环境变化或者说组织变革阶段。

    情景描述法是企业的人力资源部门对组织未来的战略目标和相关因素进行假设性描述分析,综合作出多种人力资源需求的备选方案。

    △⑤、工作研究预测法。

    适合于结构比较简单、职责清晰的企业。

    工作研究预测法是指企业根据具体岗位工作内容和职责范围,在假设岗位上的工作人员完全适岗前提下,来确定他的工作量,最后得出需要的人数。

    这种工作研究预测法的关键在于企业内部能否做好科学的工作分析,包括是否有非常准确的职位说明书,同时用人标准建立的非常清晰。

    △⑥、微观集成法。

    适用于短期预测,并且组织的生产和服务比较稳定。

    微观集成法是指组织的各个部门根据自己部门需求,预测将来某个时段各种人员的需求量。人力资源部门,把各个部门的预测综合起来,就形成了总体方案。

    这种方法一般是由上而下布置的预测工作。所以会由直接部门经理根据本部门的业务发展需求来预测出对某种人员的需求量。

    △⑦、零基预测法。

    这种分析的关键是看人力资源需求分析是否详尽。

    零基预测法是指以组织现有的员工数量为基础,来预测未来的员工需求情况。

    如果因为员工退休或者被解雇,或某种原因离开了公司,这时就需要对人力资源需求进行分析,确定是否需要补充。如果设立新的职位,也同样要进行这种分析。

    △⑧、驱动因素预测法。

    驱动因素预测的步骤总共有4个。

    第一个,先寻找驱动因素。

    比如说产量、质量、速度,包括客户方面的变化,新的资本等。

    第二个,分析驱动因素与人力资源的关系。

    第三个,预测驱动因素的变动。

    第四个,根据驱动因素的影响,来预测人力资源的需求。

    △⑨、专家讨论法。

    适用于技术型的企业。

    像有些领域,技术专家几乎在把握着整个企业发展的趋势,所以他们容易对该领域的技术人员作出预测。各个专家独立拿出人力预测方案,人力资源管理人员将这些方案进行整理汇总。

    △⑩、德尔菲法。

    适用于长期预测。

    只邀请某领域的专家或是有经验的管理人员,用问卷调研的方式,小组面谈的形式,对企业的人力资源需求进行分析、评估、预测,最终达成一致意见。在这个过程中我们要给专家提供充分的资料和信息,来确保判断的准确性。

    以上给大家讲解了针对未来人力资源需求预测的10种方法,适用于企业不同的阶段和规模。

    第三步,预测未来流失的人力资源。

    所谓的流失就是指我们预测哪些人可能要离职。这些人一离职,就会有岗位空缺,从而产生了招聘需求。

    比如,有些人要退休了,有些人要休产假了,有一些人可能会提出离职,需要HR关注和预测。

    第四步,制定出企业中短长期的整体人力资源需求预测。

    想要学习更多人才方面的课程,请在荔枝微课搜“C8HR大讲堂”。

    想要了解自己的职业性格和定位,请搜索下载C8HR进行测试。

  • ?

    哈希算法的特点以及运用

    祖万言

    展开

    什么是哈希算法

    哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。

    哈希算法的特点

    哈希表是根据设定的哈希函数H(key)和处理冲突方法将一组关键字映射到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种表称为哈希表或散列,所得存储位置称为哈希地址或散列地址。作为线性数据结构与表格和队列等相比,哈希表无疑是查找速度比较快的一种。

    通过将单向数学函数(有时称为“哈希算法”)应用到任意数量的数据所得到的固定大小的结果。如果输入数据中有变化,则哈希也会发生变化。哈希可用于许多操作,包括身份验证和数字签名。也称为“消息摘要”。

    简单解释:哈希(Hash)算法,即散列函数。它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出。哈希函数的这种单向特征和输出数据长度固定的特征使得它可以生成消息或者数据。

    哈希算法的运用

    Hash算法在信息安全方面的应用主要体现在以下的3个方面:

    1)文件校验

    我们比较熟悉的校验算法有奇偶校验和CRC校验,这2种校验并没有抗数据篡改的能力,它们一定程度上能检测并纠正数据传输中的信道误码,但却不能防止对数据的恶意破坏。

    MD5 Hash算法的”数字指纹”特性,使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法,不少Unix系统有提供计算md5 checksum的命令。

    2) 数字签名

    Hash 算法也是现代密码体系中的一个重要组成部分。由于非对称算法的运算速度较慢,所以在数字签名协议中,单向散列函数扮演了一个重要的角色。 对 Hash 值,又称”数字摘要”进行数字签名,在统计上可以认为与对文件本身进行数字签名是等效的。而且这样的协议还有其他的优点。

    3) 鉴权协议

    如下的鉴权协议又被称作挑战–认证模式:在传输信道是可被侦听,但不可被篡改的情况下,这是一种简单而安全的方法。以上就是一些关于hash以及其相关的一些基本预备知识。

    GDCA致力于网络信息安全,已通过WebTrust 的国际认证,是全球可信任的证书签发机构。GDCA专业技术团队将根据用户具体情况为其提供最优的产品选择建议,并针对不同的应用或服务器要求提供专业对应的HTTPS解决方案。GDCA一直以“构建网络信任体系,服务现代数字生活”的宗旨,致力于提供全球化的数字证书认证服务。其自主品牌——信鉴易 TrustAUTH SSL证书:包括 OVSSL、EVSSL、代码签名证书等。为涉足互联网的企业打造更安全的生态环境,建立更具公信力的企业网站形象。

    文章转载:https://trustauth/wiki/15658.html

  • ?

    一文简述多种强化学习算法,重要概念和术语一览

    Noya

    展开

    本文简要介绍了强化学习及其重要概念和术语,并着重介绍了 Q-Learning 算法、SARSA、DQN 和 DDPG 算法。

    强化学习(RL)指的是一种机器学习方法,其中智能体在下一个时间步中收到延迟的奖励(对前一步动作的评估)。这种方法主要用于雅达利(Atari)、马里奥(Mario)等游戏中,表现与人类相当,甚至超过人类。最近,随着与神经网络的结合,这种算法不断发展,已经能够解决更复杂的任务,比如钟摆问题。

    虽然已经有大量的强化学习算法,但似乎并没有什么文章对它们进行全面比较。每次需要决定将哪些算法应用于特定的任务时,都让我很纠结。本文旨在通过简要讨论强化学习的设置来解决这个问题,并简要介绍一些众所周知的算法。

    1. 强化学习入门

    通常,强化学习的设置由两部分组成,一个是智能体(agent),另一个是环境(environment)。

    强化学习图示

    环境指的是智能体执行动作时所处的场景(例如雅达利游戏中的游戏本身),而智能体则表示强化学习算法。环境首先向智能体发送一个状态,然后智能体基于其知识采取动作来响应该状态。之后,环境发送下一个状态,并把奖励返回给智能体。智能体用环境所返回的奖励来更新其知识,对上一个动作进行评估。这个循环一直持续,直到环境发送终止状态来结束这个事件。

    大多数强化学习算法遵循这一模式。下面我将简要介绍强化学习中的一些术语,以方便下一节的讨论。

    定义

    1. 动作(A):智能体可以采取的所有可能的行动。

    2. 状态(S):环境返回的当前情况。

    3. 奖励(R):环境的即时返回值,以评估智能体的上一个动作。

    4. 策略(π):智能体根据当前状态决定下一步动作的策略。

    5. 价值(V):折扣(discount)下的长期期望返回,与 R 代表的短期返回相区分。Vπ(s) 则被定义为策略 π 下当前状态**s**的期望长期返回值。

    6. Q 值或行动值 (Q):Q 值与价值相似,不同点在于它还多一个参数,也就是当前动作 a。Qπ(s, a) 指当前状态**s**在策略π下采取动作 a 的长期回报。

    无模型(Model-free)vs. 基于模型(Model-based)

    这里的模型指的是环境的动态模拟,即模型学习从当前状态 s0 和动作 a 到下一个状态 s1 的转移概率 T(s1|(s0, a))。如果成功地学习了转移概率,那么智能体将知道给定当前状态和动作时,进入特定状态的可能性。然而,当状态空间和动作空间增长(S×S×A,用于表格设置)时,基于模型的算法就变得不切实际了。

    另一方面,无模型算法依赖试错来更新知识。因此,它不需要空间来存储所有状态和动作的组合。下一节讨论的所有算法都属于这一类。

    在策略(on-policy)vs. 离策略(off-policy)

    在策略智能体基于当前动作 a 学习价值,而离策略智能体基于局部最优的贪心行为(greedy action)a* 学习价值。(我们将在 Q-Learning 和 SARSA 算法部分进一步讨论这个问题)

    2. 各种算法的说明

    2.1 Q-learning 算法

    Q-Learning 是基于贝尔曼方程(Bellman Equation)的离策略、无模型强化学习算法:

    贝尔曼方程

    其中,E 代表期望, 是折扣因子(discount factor)。我们可以将它重写成 Q 值的形式:

    Q 值形式的贝尔曼方程

    最优的 Q 值 Q*,可以表示为:

    最优 Q 值

    目标是最大化 Q 值。在深入探讨优化 Q 值的方法之前,我想讨论两个与 Q-learning 密切相关的值更新方法。

    策略迭代法

    策略迭代法交替使用策略评估和策略改进。

    策略迭代法

    策略评估会评估从上次策略改进中获得的贪心策略的价值函数 V。另一方面,策略改进通过使每个状态的 V 值最大化的动作来更新策略。更新方程以贝尔曼方程为基础。它不断迭代直到收敛。

    策略迭代的伪代码

    价值迭代

    价值迭代只包含一个部分。它基于最优贝尔曼方程来更新值函数 V。

    最优贝尔曼方程

    价值迭代的伪代码

    在迭代收敛之后,通过对所有状态应用最大值函数直接导出最优策略。

    注意,这两种方法都需要知道转移概率 p,这表明它是一个基于模型的算法。但是,正如我前面提到的,基于模型的算法存在可扩展性问题。那么 Q-learning 如何解决这个问题呢?

    Q-Learning 更新方程

    α 指学习速率(即我们接近目标的速度)。Q-learning 背后的思想高度依赖于价值迭代。然而,更新方程被上述公式所取代。因此,我们不再需要担心转移概率。

    Q-learning 的伪代码

    注意,下一个动作 a』 的选择标准是要能够最大化下一个状态的 Q 值,而不是遵循当前的策略。因此,Q-Learning 属于离策略算法。

    2.2 状态-动作-奖励-状态-动作(State-Action-Reward-State-Action,SARSA)

    SARSA 很像 Q-learning。SARSA 和 Q-learning 之间的关键区别是 SARSA 是一种在策略算法。这意味着 SARSA 根据当前策略执行的动作而不是贪心策略来学习 Q 值。

    SARSA 的更新方程

    动作 a_(t+1) 是在当前策略下的下一个状态 s_(t+1) 执行的动作。

    SARSA 的伪代码

    从上面的伪代码中,你可能会注意到执行了两个动作选择,它们始终遵循当前策略。相比之下,Q-learning 对下一个动作没有约束,只要它能最大化下一个状态的 Q 值就行了。因此,SARSA 是一种在策略算法。

    2.3 深度 Q 网络(Deep Q Network,DQN)

    Q-learning 是一种非常强大的算法,但它的主要缺点是缺乏通用性。如果你将 Q-learning 理解为在二维数组(动作空间×状态空间)中更新数字,那么它实际上类似于动态规划。这表明 Q-learning 智能体不知道要对未见过的状态采取什么动作。换句话说,Q-learning 智能体没有能力对未见过的状态进行估值。为了解决这个问题,DQN 引入神经网络来摆脱二维数组。

    DQN 利用神经网络来估计 Q 值函数。网络的输入是当前的动作,而输出是每个动作对应的 Q 值。

    用 DQN 玩雅达利游戏

    2013 年,DeepMind 将 DQN 应用于雅达利游戏,如上图所示。输入是当前游戏场景的原始图像,经过包括卷积层和全连接层的多个层,输出智能体可执行的每个动作的 Q 值。

    问题归结为:我们如何训练网络?

    答案是基于 Q-learning 更新方程来训练网络。回想一下 Q-learning 的目标 Q 值是:

    目标 Q 值

    相当于状态 s, 代表神经网络里的参数。因此,网络的损失函数可定义为目标 Q 值与网络 Q 值输出之间的平方误差。

    DQN 的伪代码

    另外两种技术对于训练 DQN 也很重要:

    1. 经验回放(Experience Replay):由于典型强化学习设置中的训练样本高度相关,且数据效率较低,这将导致网络更难收敛。解决样本分布问题的一种方法是采用经验回放。从本质上讲,样本转换会被存储,然后从「转换池」中随机选择该转换来更新知识。

    2. 分离目标网络(Separate Target Network):目标 Q 网络与用来估值的网络结构相同。根据上面的伪代码,在每个 C 步骤,目标网络都被重置为另一个。因此,波动变得不那么严重,带来了更稳定的训练。

    2.4 深度确定性策略梯度(Deep Deterministic Policy Gradient,DDPG)

    虽然 DQN 在高维问题上取得了巨大的成功,例如雅达利游戏,但动作空间仍然是离散的。然而,许多有趣的任务,特别是物理控制任务,动作空间是连续的。而如果你把动作空间分离得太细来趋近连续空间,你的动作空间就太大了。例如,假设自由随机系统的自由度为 10。对于每一个自由度,你把空间分成 4 个部分,你最终就会有有 4= 1,048,576 个动作。对于这么大的动作空间来说,收敛也是极其困难的。

    DDPG 依赖于「行动者-评论家」(actor-critic)架构。行动者用来调整策略函数的参数,即决定特定状态下的最佳动作。

    策略函数

    而评论家用于根据时间差分(temporal difference,TD)误差来评估行动者估计出来的策略函数。

    时间差分误差

    在这里,小写的 v 表示行动者已经确定的策略。看起来很熟悉对吗?看着像 Q-learning 的更新方程!TD 学习是一种学习如何根据给定状态的未来值来预测价值的方法。Q-learning 是 TD 学习的一种特殊类型,用于学习 Q 值。

    「行动者-评论家」架构

    DDPG 还从 DQN 借鉴了经验回放和分离目标网络的思想。DDPG 的另一个问题是它很少对动作进行探索。一个解决方案是在参数空间或动作空间中添加噪声。

    动作噪声(左),参数噪声(右)

    OpenAI 这篇博客认为在参数空间上添加噪声比在动作空间上添加要好得多。一个常用的噪声是 Ornstein-Uhlenbeck 随机过程。

    DDPG 的伪代码

  • ?

    算法基础:生动理解BitMap算法

    Vanna

    展开

    BitMap?

    BitMap你可能会想到位图文件,但在算法中也有个叫BitMap的数据结构,常利用在压缩、爬虫系统中url除重、解决全组合问题,经常被用在解决海量数据寻找重复数据或者判断数据是否存在该集合的问题。

    一道经常出现的面试题

    面试经常会问:给一台配置是2G内存,要处理一个包含40亿个不重复并且没有排过序的整数。那么问题在于,给出一个整数,怎么快速这个整数是否在这40亿数据中呢?

    思考:40亿int占40亿*4/1024/1024/1024大概占15G左右,2G内存肯定加载不了,但这个问题最好的方案肯定是放在内存里去判断集合是否存在该元素。

    解决思路:如何在2G内存存储15G数据,一个int在C中是占4个字节的即要32bit位,如果能够用一个bit位来标识一个int整数那么存储空间将大大减少,算一下40亿个int需要的内存空间为40亿/8/1024/1024大概为476.83 mb,这样的话我们完全可以将这40亿个int放到内存中进行处理。

    BitMap映射表

    1个int占4字节即4*8=32位,那么我们只需要申请一个int数组长度为 int tmp[1+N/32]即可存储完这些数据,其中N代表要进行查找的总数,tmp中的每个元素在内存在占32位可以对应表示十进制数0~31。

    简单来说就是一个数组的加一位索引代表进一位,byte[0] = 0~31,byte[1]=32~63,byte[2]=64~95,以此类推。其图示如下:

    转换成表格为:

    以上算法关键的点在于如果判定数字在BitMap中的位置,其实有个很简单的方法就是直接除以32得到的整数倍 - 1是BitMap的索引,然后除以32取整数部分(即取模运算)就可以得到在该索引下该数字的位置。

    Java代码

    由于Java本身带有BitMap的Api,这里就不累赘写多一次,代码如下:

    总结

    BitMap是一种很常用的数据结构,比如用在BloomFilter中,或者用于无重复整数的排序等等。由于BitMap对内存的占用极小,经常在大数据中被优化使用,在算法实现中也是比较简单、经典的算法,值得大家一试。

  • ?

    机器学习:详解基于用户协同过滤(User-CF)的推荐算法

    木棉

    展开

    User-CF的推荐实例

    在学校生活的时候,新生开学都会问同专业的师兄师姐“我要买什么书?”、“我要怎么安排作息?”等相似的问题,此时师兄师姐就会依着他们的专业和偏好做一些推荐,这就是现实中个性化推荐具体个例。这里面有一个有趣的地方,一般师弟师妹们不会去问不同专业的师兄师姐这些问题,也不会去问刚毕业的学长,这是为什么?因为对他们而言,上一届的同专业学长们的知识结构跟他们最为相近,兴趣偏好也比较相似,所以他们推荐的结果比较靠谱。

    那么,在一个个性化推荐系统中,当一个用户A需要个性化推荐时,可以先找和他有相似兴趣的其他用户,然后把那些用户喜欢的、而用户A没有听说过的物品推荐给A。这种方法成为基于用户的协同过滤算法(User-CF)。

    详细过程

    相似度计算:找到和目标用户兴趣相似的用户集合

    构建推荐矩阵:找到这个集合中用户喜欢的,且目标用户没有听说过的物品推荐给目标用户。

    1.相似度计算

    相似度计算目标是找到目标用户与其他已知偏好的用户的相似度。这里,协同过滤(CF)主要利用用户行为的相似度。给定用户u和用户v,令N(u)表示用户曾经有过正反馈的物品集合,令N(v)为用户v曾经有过正反馈的物品集合。

    这里相似度计算有几个细节,如果用户属性是用布尔值(0,1)来表示的话,例如:

    其中0表示不喜欢,1表示喜欢。那么可以通过Jaccard公式简单计算u和v的相似度,其公式定义是A与B交集的大小与A与B并集的大小的比值,范围在[0,1],值越接近1,A与B越相似。特别地,当A、B集合都为空时,J(A,B)定义为1,计算公式如下:

    上述结果代入公式计算后得:

    当然这有个缺陷,Jaccard公式无法表示u,v对每个属性的具体偏好大小。这时候可以用余弦相似度进行求解。

    改变下表格中的数值,表示具体偏好:

    代入余弦相似度公式计算得

    相似地,也有Tanimoto 系数(Tanimoto Coefficient)和欧几里德距离(Euclidean Distance),当用欧几里德距离表示相似度,一般采用以下公式进行转换,距离越小,相似度越大。

    Tanimoto 系数也称为 Jaccard 系数,是 Cosine 相似度的扩展,也多用于计算文档数据的相似度:

    2.构建推荐矩阵

    经过上述的相似度计算,现在找到和目标用户兴趣相似的用户集合,现在有个用户u,需要为他推荐水果种类,计算了用户u与其他用户的相似度,构建推荐矩阵如下:

    得到上面对于用户u的推荐矩阵后,User-CF算法会给用户推荐和他兴趣最相似的K个用户喜欢的物品。如下的公式度量了User-CF算法中用户u对物品i的感兴趣程度:

    其中, S(u, K)包含和用户u兴趣最接近的K个用户, N(i)是对物品i有过行为的用户集合, w_uv是用户u和用户v的兴趣相似度, r_vi代表用户v对物品i的兴趣度。假设K=2时,那么实际上矩阵按相似度排序如下:

    那么此时用户u对桃的兴趣度计算:

    如果对用户u只推荐一种水果,那么此时按照UserCF算法的最终计算推荐结果应为菠萝。

    适用范围

    User-CF算法的假设是一个用户和其他用户的兴趣偏好类似,那么他们喜欢的东西都应该是差不多,即人以群分的概念。

    该算法适用于用户较少、用户个性化兴趣不太显著的场合,推荐过程中用户新的行为不一定会导致推荐结果的变化,如果用户过多,那么计算用户相似矩阵的代价太大。且该算法无法解决新用户进来的冷启动问题,但新物品进来能够较快地进行推荐。

  • ?

    资料分析大讲堂(比较大小的简单算法)

    艾米

    展开

    比较大小的题型一向是大家觉得最难、最费时的一种题型。如果每个选项都只能靠计算才能进行比较,那毋庸置疑,你做一个题的时间,别人可能已经完成了四个题。那如何才能更快的做比较,有两个原则一定要掌握透彻:1.全面扫描选项,找准比较的基准。2.合理利用口算,减少动笔时间。

    基础知识:

    专项知识检测

    材料:

    1.2008-2012 年该市文化产业人均生产总值最小的是哪年?

    A.2008 B.2009 C.2011 D.2012

    【答案】B。所求值为条形图数字除以折线图数字最小,观察可知B项分子比其他项更小(与A项接近),而分母较其他项明显更大,故易得B项为最小值

    2.2008-2012 年该市文化产业人均生产总值最大的是哪年?

    A.2008 B.2010 C.2011 D.2012

    【答案】B。所求值为条形图数字除以折线图数字最大,观察可知,C、D两项分子数字相较A、B两项而言变化不算太大,都是四千多的数,而分母明显比A、B两项大了很多,故分数值不可能是最大的,排除C、D。A项与B项的大小亦可看成分子相近,而2010年的分母小得更明显,故2010年是最大的。

    或者用差分比较去判断A、B两项。

    的大小,可通过比较

    得出,差分数为

    ,选B。

    材料:2012 年末,男性人口 69395 万人,同比增加 327 万人,女性人口 66009 万人,同比增加 342 万人;城镇人口 71182 万人,同比增加 2103 万人;乡村人口 64222 万人,同比减少 1434万人。

    3.2012 年中国男性人口、女性人口、城镇人口的同比增长率按大小排序正确的是:

    A.城镇人口>男性人口>女性人口

    B.城镇人口>女性人口>男性人口

    C.女性人口>男性人口>城镇人口

    D.女性人口>城镇人口>男性人口

    【答案】B。增长率=

    。从题干易得城镇人口的增长量最多,而基期值与男性或女性相差不大,故可知城镇人口增长率是最大的。女性人口的增长量大于男性人口,且基期量小于男性人口,故易得女性人口的增长率大于男性人口。故答案为B。

    材料:表 2013年上半年部分城市软件服务业收入完成情况

    城市

    企业个数

    软件业务收入

    本期累计(亿元)

    同比增减(%)

    大连市

    1691

    581.5

    28

    厦门市

    715

    241.4

    32

    青岛市

    347

    303.3

    21

    深圳市

    2365

    1395.1

    18

    沈阳市

    1685

    565.6

    26

    4.在所给城市中,2013 年上半年软件服务业累计收入同比增加第二多的是:

    A.深圳市 B.青岛市 C.大连市 D.沈阳市

    【答案】C。观察表格易得,深圳为增长最多的。在大连与沈阳中考虑增加第二多,可直接看出大连排名第二(581.5>565.6且28%>26%)。故选C。

    5.在所给城市中,2013 年上半年软件服务业累计收入同比增加最少的是:

    B.深圳市 B.青岛市 C.大连市 D.厦门市

    【答案】B。厦门同比增长

    ,青岛同比增长

    比较可得32%约为21%的1.6倍,303约为241的5/4=1.25倍,故可明显察得厦门大于青岛,故增加最少的是青岛。

    亦可通过估算

    ,

    比较得出。

  • ?

    高效的寻路算法—A-star算法(附C++代码)

    汪雅琴

    展开

    什么是A-star算法

    A*(A-Star)算法是一种静态路网中求解最短路最有效的方法,俗称A星算法。这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法。常用于游戏中的NPC的移动计算,或线上游戏的BOT的移动计算上。公式表示为:f(n)=g(n)+h(n),其中f(n)是节点n从初始点到目标点的估价函数,g(n)是在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。

    A-star算法的原理

    先引入二个概念:

    节点(Node):每个格子都可以称为节点。

    代价(Cost):描述角色移动到某个节点时所走的距离(或难易程度)。

    三种基本的估价算法(也称估价公式),其算法示意图如下:

    对于“曼哈顿算法”,,笔直的走,然后转个弯,再笔直的继续。

    “几何算法”的最好解释就是“勾股定理”,算出起点与终点之间的直线距离,然后乘上代价因子。

    “对角算法”综合了以上二种算法,先按对角线走,一直走到与终点水平或垂直平行后,再笔直的走。

    在计算机中我们将地图表现为单元格,分可走单元格和不可走单元格。,必须要让计算机“有选择地走”。

    若以当前单元格为起点(称为父单元格,它的周围有八个方向),下一步走哪呢?

    这时就得给下一步的单元格(称为子单元格)进行“估价”。

    “估价”可用估价函数来实现。

    入门级的估价函数是这样的:

    终点到目前点的估计代价=终点至当前点的直线距离

    于是下一步的代价可以这样算

    代价=起点到当前点的实际步数(通过一个变量累加可以直接得到)+ 终点到目前点的估计代价

    然后把估价后的单元格放入“待考察表”

    从待考察表中取代价最小的单元格作为起点,对它周围8个方向的单元格进行估价,然后把它放入“已考察表”。

    若对一个单元格估价时,发现它已经在“待考察表”中则比较该单元格原先的估价和当前的估价,保留小的估价,并更新其父单元格属性。

    不断重复以上过程,直到在“待考察表”中取出的单元格是终点单元格为止,若“待考察表为空”则表示找不到路径。

    到达终点单元格后,通过其“父单元格”属性,一直找到起点,便构成一条路径。

    两个例子:

    Enter the map's filename: b.txt Rows=7Cols=13. . . . . . . . . . . . . . . . . . . x . . . . . . . . . x x x x . . . . . . . . . . . . x . . . . . . . . . x x x x . . . . . . . . . . . . x . . . . . . . . . . . . . . . . . . . Set the start point ( x , y ):5 3Set the end point ( x , y ):12 3Steps:12,311,210,19,08,07,06,05,04,03,12,23,34,35,3Rows=7Cols=13. . . . * * * * * * . . . . . . * . . x . . . * . . . . * x x x x . . . . * . . . . * * * x . . . . . * . . . x x x x . . . . . . . . . . . . x . . . . . . . . . . . . . . . . . . . =========================== Enter the map's filename: a.txt Rows=7Cols=7. . . . . . . . x x x . . . . . . x . x . . . . x . x . . . . . . x . . . . . . x . . . . . . x . Set the start point ( x , y ):0 0Set the end point ( x , y ):6 6Steps:6,66,56,46,36,25,14,03,02,01,00,0Rows=7Cols=7* * * * * . . . x x x . * . . . . x . x * . . . x . x * . . . . . x * . . . . . x * . . . . . x *

    C++代码

    1. 评价函数

    以当前状态下各将牌到目标位置的距离之和作为节点的评价标准。距离的定义为:“某将牌行下标与目标位置行下标之差的绝对值 + 列下标与目标位置列下标之差的绝对值”。距离越小,该节点的效果越好。某个状态所有将牌到目标位置的距离之和用“h值”表示。

    2. 主要函数

    2.1 countH(state & st);

    countH函数功能是计算st状态的h值。

    计算过程中将会用到rightPos数组,数组里记录的是目标状态下,0~9每个将牌在九宫格里的位置(位置 = 行下标 * 3 + 列下标)。

    2.2 f(state * p);

    f()=h()+level

    2.3 look_up_dup(vector & vec, state * p);

    在open表或close表中,是否存在指定状态p,当找到与p完全相等的节点时,退出函数。

    2.4 search(state & start);

    在open表不为空时,按f值由小到大对open表中元素进行排序。

    调用findZero()函数找到0值元素的位置。空格可以向上下左右四个方向移动,前提是移动后不能越过九宫格的边界线。确定某方向可走后,空格移动一步,生成状态p’。

    此时,检查open表中是否已有p’,若有,更新p’数据;检查close表中是否已有p’,若有,将p’从close表中删除,添加到open表中。 重复的执行这个过程,直到某状态的h值为零。

    2.5 dump_solution(state * q);

    在终端输出解路径。

    // A*算法 八数码问题

    #include "stdafx.h"

    #include

    #include

    #include

    #include

    using namespace std;

    const int GRID = 3; //Grid表示表格的行数(列数),这是3*3的九宫格

    int rightPos[9] = { 4, 0, 1, 2, 5, 8, 7, 6, 3 }; //目标状态时,若p[i][j]=OMG,那么3*i+j = rightPos[OMG]

    struct state{

    int panel[GRID][GRID]; int level; //记录深度 int h;

    state * parent;

    state(int level) :level(level){}

    bool operator == (state & q){

    //判断两个状态是否完全相等(对应位置元素相等),完全相等返回true,否则返回false

    for (int i = 0; i

    if (panel[i][j] != q.panel[i][j]) return false; } }

    return true; }

    state & operator = (state & p){ //以状态p为当前状态赋值,对应位置元素相同

    for (int i = 0; i

    return *this; } };

    void dump_panel(state * p){ //将八数码按3*3矩阵形式输出 for (int i = 0; i

    cout<< p->panel[i][j]<< " "; cout << endl; } }

    int countH(state & st){ //给定状态st,计算它的h值。

    int h = 0;

    for (int i = 0; i

    h += abs(rightPos[st.panel[i][j]] / GRID - i) +

    abs(rightPos[st.panel[i][j]] % GRID - j);

    //h=各个将牌与其目标位置的距离之和.距离定义为:行下标之差的绝对值+列下标之差的绝对值。 } }

    return h; }

    int findZero(state & st){ //找到零值元素,返回其在表中的位置

    for (int i = 0; i

    int f(state * p){ //计算并返回f()值,即h值+level return countH(*p) + p->level; }

    bool compare_state(state * p, state * q){ //比较两个状态的f值 return f(p) > f(q); }

    vector open_table; //open表 vector close_table; //close表

    vector::iterator look_up_dup(vector & vec, state * p){ vector::iterator it_r = vec.begin(); for (; it_r

    return it_r; }

    state * search(state & start){ //A*算法进行搜索

    int level = 0;

    open_table.push_back(&start); int count = 0;

    while (!open_table.empty()){

    sort(open_table.begin(), open_table.end(), compare_state); //对open表中的元素进行排序

    state * p = open_table.back(); open_table.pop_back();

    if (countH(*p) == 0)

    return p; //所有将牌到达目标位置,搜索过程结束 level = p->level + 1;

    int zeroPos = findZero(*p);

    int x = zeroPos / 3; //空格的行下标 int y = zeroPos % 3; //空格的列下标

    for (int i = 0; i<4; i++){ //上下左右四个方向 int x_offset = 0, y_offset = 0; switch (i){

    case 0:x_offset = 0, y_offset = 1; break; //右 case 1:x_offset = 0, y_offset = -1; break;//左 case 2:x_offset = 1, y_offset = 0; break;//上 case 3:x_offset = -1, y_offset = 0; break;//下 };

    if (x + x_offset<0 || x + x_offset >= GRID || y + y_offset<0 || y + y_offset >= GRID){ continue;

    //若移动一步后,将超出上/下/左/右边界,则这个方向不可走,尝试下一个方向

    }

    state * q = new state(level); //这个方向可走,扩展下一个节点

    q->parent = p; *q = *p;

    q->panel[x][y] = q->panel[x + x_offset][y + y_offset]; q->panel[x + x_offset][y + y_offset] = 0;//空格沿这个方向移一步

    bool skip = false;

    vector::iterator dup = look_up_dup(open_table, q); //若q已在open表中,则对open表中的信息进行更新

    if (dup != open_table.end()){ if (f(q) < f(*dup)){

    (*dup)->level = q->level; (*dup)->parent = q->parent; }

    skip = true; }

    dup = look_up_dup(close_table, q);

    if (dup != close_table.end()){ //若q已在close表中,且f值比原值小,

    if (f(q) < f(*dup)){ //则将q从close表清除,加入open表

    delete *dup;

    close_table.erase(dup); open_table.push_back(q); skip = true; } }

    if (!skip){

    open_table.push_back(q); } }

    close_table.push_back(p); } }

    void dump_solution(state * q) //输出解路径 {

    vector trace; while (q){

    trace.push_back(q); q = q->parent; }

    int count = 0;

    while (!trace.empty()){

    cout<< "Step " << count << " :^-^=^-^=^-^=^-^=^ ^=^-^=^-^=^-^=^-^=^-^=^@\n";

    dump_panel(trace.back());

    cout<< "h: " << countH(*trace.back()) <<"\tg:"<

    << f(trace.back()) << endl << endl; trace.pop_back(); count++; } }

    int main() {

    state p(0); state *q;

    p.panel[0][0] = 2;//设置初始状态 p.panel[0][1] = 1; p.panel[0][2] = 6; p.panel[1][0] = 4; p.panel[1][1] = 0; p.panel[1][2] = 8; p.panel[2][0] = 7; p.panel[2][1] = 5; p.panel[2][2] = 3;

    p.parent = NULL; q = search(p);

    dump_solution(q);

    system("pause"); }

  • ?

    APS基础知识系列之三

    奔赴

    展开

    写了两篇APS基础知识系列文章,主要介绍了计划开始生产时间PST和最迟计划开始生产时间LPST。今天计划介绍最早计划开始生产时间EPST(Earlist Plan Start Time)。

    在写了前两篇文章的时候,有读者反馈这两篇文章价值不大。对于APS的算法,最流行最普遍的介绍是使用MRP Grid的逻辑,如下图。

    这个MRP算法的基本逻辑是教科书里经常用到的,按照这个算法将来需要将产品按BOM展开,会形成一系列的生产工单,以及相关工单的这一系列表格。这一系列表格的计算中,是按理想状态的计算,如果按照这个时间下订单,但供应商产能瓶颈,无法按时生产,那么必然导致提前期增大,从而最终影响交货期。

    我这一系列APS的文章,将用另外一个方法,主要是通过:

    PST=MAX{EPST,LPST,当前时间}

    这个算法作为主要逻辑,在这个逻辑中融入MRP的算法,逐渐深入展开。

    所以首先需要把PST,EPST,LPST介绍清楚。

    EPST算法

    EPST主要是根据物料获得时间来计算的。当缺料的时候,生产无法开始。

    EPST的计算首选需要展BOM,获得产品的物料信息,以及需要工艺路径,来获得每一个操作的时间,通过物料以及相关的工艺路径,来获得每一个操作需要物料的时间最终确定各个环节的EPST。算法如图:

    EPST需要考虑最小排队时间和物料移动时间!

    后续将通过案例介绍PST,EPST,LPST的算法。

  • ?

    电商第一步,学会表格数据分析

    Lennon

    展开

    今天为大家分享一个数据分析的方法,大家可以打开店铺后台,看着步骤来操作。

    很多电商人都知道数据分析的重要性,但是真正做起来却发现无从下手,而且即使是看到数据之后,也不知道怎么分析,往往是看着一个连接“莫名奇妙”的爆了,又“莫名其妙”的死了。

    其实每个链接的起爆和衰落都是有原因的,只要掌握今天的数据分析方法,在以后的操作过程中才能真正看清数据,掌握数据

    首先,打开生意参谋,商品-商品效果-选择日期,在选择日期时,建议大家往前倒推15天的时间,比如今天是30号,那么,就从这个月的15号开始,选择好日期之后,点击下载。

    下载好15号的数据之后,再选择16号,继续下载,把最近15的的数据下载下来以后是这样的。

    这是我们店铺所有链接在过去15天的所有数据,而且非常详细,可以说,过去15天的店铺的起落兴衰内在原因都在这里了,接下来我们开始将这些数据重新组合整理,以便于更直观的看到所有链接的详细数据,从而进行数据对比,分析,得出结论,打开第一个表格是这样的。

    这是所有的链接在10.10日的数据,第一个链接是主打款,是主要分析目标,所以把这一排全部复制下来,放在一个新的表格里。

    然后把10.11之后的所有数据全部复制下来,放在一个表格里,把无关紧要的数据删掉,以免影响我们的专注力。

    ps:在删无关紧要的数据时要注意看数据浮动大不大,比如平均停留时长这一项,如果这一项波动特别大就不要删掉,波动不大的话就删掉,因为它只是次要数据,不是核心数据,最后留下来的核心数据,见下图:

    这个是我已经做好的表格,最后的收藏率和加购率是手动加上去的,因为官方没有提供这两个数据,但是官方提供了收藏人数和访客数,所以我们就可以手动算出来。

    在收藏率下输入公式:‘=收藏人数/访客数’然后回车,就会得到这个链接的收藏率,把这一列拖下来即可得到所有日期的收藏率,加购率也是一样操作即可

    为了方便观察数据,我们把所属终端这一行改成日期,见下图:

    这样是不是一目了然了?哈哈哈,是不是感觉所有原因都自动跳出来了!

    重点看流量暴涨的10.19号--22号这4天数据:

    访客数暴涨的同时,搜索引导的访客数也在暴涨,而且直通车并没有加大投入,所以接下来我们着重看搜索数据,我们知道,现在所有的数据,都是结果,是上一个周期的数据浮动才导致的结果。

    所以接下来我们看上一个周期发生了什么。

    发现什么秘密没有?

    每次流量大涨之前的一天,搜索支付转化率都是超过5%的!记住这个数字。

    10.17号和10.18号,连续两天都超过了5%,然后导致10.19号访客数直接翻翻!

    所以也就是说,在这个类目,这个客单价下,我们的搜索支付转化率不能低于5%,这是一个系统云计算得出的数据,只要能够稳住这个数值,理论上来说,这个链接是必爆无疑的!

    当然,除了数据之外,还有很多其他方面的权重值也很重要,比如客服回复时长,动销率,发货速度,好评率,dsr,等等,我们今天只分析数据,其他方面有空再详解。

    还有一点值得注意的是:

    有些类目权重计算核心并不是支付转化率!

    有些类目权重计算核心并不是支付转化率!

    有些类目权重计算核心并不是支付转化率!

    但是大部分类目都逃不过这个表格里的所有数据,有了这个表格基本都能够计算出来类目权重算法,目前最核心的数据有:支付转化率,uv价值,收藏率,加购率。

    只要能够找出自己类目的核心权重,然后维护好这个数据,在产品没问题的情况下,想不爆,太难了!

    客单价69左右的女裤类目的核心权重是转化率,客单价129左右的天猫女鞋核心权重是uv价值,这一点很难复制,只能用自己的店铺数据去推断,找出这个潜在规律即可。

    免责声明:本文使用图文及视频等作品部分源于网络,我们尊重著作权所有人的合法权益,如涉及版权争议,请著作权人告知我方删除

表格算法

所有视频需要登录后,才能观看

请先登录您的帐号,即可完整播放,如果您尚未注册帐号,请先点击注册。

img

在线咨询

建站在线咨询

img

微信咨询

扫一扫添加
动力姐姐微信

img
img

TOP