精华内容
下载资源
问答
  • 现在,在你提出《Journal of Obvious Results》上发表的结论之前,让我们继续问为什么为什么人们会帮助别人,即使自己会付出代价?至少部分原因是他们想这样;这让他们对自己和世界感觉良好。 为什么善良...

    十二、合作进化

    原文:Chapter 12 Evolution of cooperation

    译者:飞龙

    协议:CC BY-NC-SA 4.0

    自豪地采用谷歌翻译

    在最后一章中,我们提出两个问题,一个来自生物学,一个来自哲学:

    • 在生物学中,“利他主义问题”是自然选择与利他主义之间的明显冲突,自然选择表明动物生存在不断竞争的状态中来生存和繁殖,利他主义是许多动物帮助其他动物的倾向,甚至是显然对他们不利。见 https://en.wikipedia.org/wiki/Altruism_(biology)
    • 在道德哲学中,人性问题是,人类是否从根本上是善良的,或者邪恶的,或者是由环境塑造的空白状态。见 https://en.wikipedia.org/wiki/Human_nature

    我们将用来解决这些问题的工具,(同样)是基于智能体的模拟和博弈论,博弈论是一组抽象模型,旨在描述智能体交互的各种方式。具体来说,我们会考虑囚徒困境。

    本章的代码位于chap12.ipynb中,该书是本书仓库中的Jupyter笔记本。使用此代码的更多信息,请参见第?节。

    12.1 囚徒困境

    囚徒困境是博弈论中的一个话题,但它不是一种有趣的博弈。相反,这种博弈揭示了人类的动机和行为。以下是来自维基百科的它的介绍(https://en.wikipedia.org/wiki/Prisoner's_dilemma):

    两名犯罪团伙成员被逮捕并囚禁。每个囚犯都被单独监禁,无法与另一方交流。检察官缺乏足够的证据,来证明这两个人的主要指控。他们希望以较轻的指控被判处两年徒刑。同时,检察官为每个囚犯提供商量的余地。每个囚犯都有机会:(1)通过证明对方犯罪出卖对方,或(2)通过保持沉默与另一方合作。出价是:

    • 如果 A 和 B 各自背叛对方,每个人都服刑 2 年。
    • 如果 A 背叛 B 但 B 保持沉默,A 将被释放,B 将被监禁 3 年(反之亦然)。
    • 如果 A 和 B 都保持沉默,他们两人只会服刑 1 年(较轻的质控)。

    很显然,这种情况是假想的,但它用于代表各种不同的互动,其中智能体必须选择是相互“合作”还是“背叛”,以及每个智能体的奖励(或惩罚)取决于他人的选择。

    有了这套奖惩,我们很有可能说智能体应该合作,也就是说,双方都应该保持沉默。 但两个智能体不知道对方会做什么,所以每个人都必须考虑两种可能的结果。 首先,从 A 的角度来看它:

    • 如果 B 保持沉默,A 最好是背叛;他会无罪而不是服刑 1 年。
    • 如果 B 背叛,A 最好也是背叛;他只会服刑 2 年而不是 3 年。

    不管 B 做什么,A 最好都是背叛。 而且因为博弈是对称的,所以从 B 的角度来看这个分析是一样的:不管 A 做什么,B 最好也是背叛。

    在这个博弈的最简单版本中,我们假设 A 和 B 没有考虑其他因素。 他们不能互相沟通,所以他们不能协商,作出承诺或相互威胁。 他们只考虑直接目标,最小化他们的判决;他们不考虑任何其他因素。

    在这些假设下,两个智能体的理性选择都是背叛。 这可能是一件好事,至少在刑事司法方面是这样。 但对囚犯来说,这令人沮丧,因为显然,他们无法获得他们双方都想要的结果。 而且这种模式适用于现实生活中的其他场合,其中合作有更大的好处以及对于玩家来说都会更好。

    研究这些场景以及摆脱困境的方法,博弈论研究者关注的焦点,但这不是本章的重点。 我们正朝着不同的方向前进。

    12.2 善良的问题

    自 20 世纪 50 年代,囚徒困境被首次讨论以来,它一直是社会心理学研究的热门话题。根据前一节的分析,我们可以说一个理想的智能体应该做什么; 很难预测真正的人究竟做了些什么。 幸运的是,实验已经完成了 [1]。

    [1] 这里有一个最近的报告,提到以前的实验:Barreda-Tarrazona, Jaramillo-Gutiérrez, Pavan, and Sabater-Grande, “Individual Characteristics vs. Experience: An Experimental Study on Cooperation in Prisoner’s Dilemma”, Frontiers in Psychology, 2017; 8: 596. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5397528/

    如果我们假设人们足够聪明地进行分析(或者在解释时理解它),并且他们通常为了自己的利益而行事,那么我们预计他们几乎总是背叛。 但他们没有。 在大多数实验中,受试者的合作远远超过理性的智能体模型的预测 [2]。

    [2] 有个不错的视频归纳了我们目前讨论的内容:https://www.youtube.com/watch?v=t9Lo2fgxWHw

    这个结果最明显的解释是,人们不是理性的智能体,这对任何人都不应该感到惊讶。 但为什么不是呢? 是因为他们不够聪明,无法理解这种情况,还是因为他们故意违背自己的利益行事?

    根据实验结果,似乎至少有一部分解释是纯粹的利他主义:许多人愿意为了让别人受益而承担成本。现在,在你提出《Journal of Obvious Results》上发表的结论之前,让我们继续问为什么:

    • 为什么人们会帮助别人,即使自己会付出代价?至少部分原因是他们想这样;这让他们对自己和世界感觉良好。
    • 为什么善良让人感觉良好?诱人的说法是,有人跟他们提出这是正确的,或者更普遍来说,他们被社会训练为想要做好事。但毫无疑问 [3],至少有一大部分利他主义是天生的;在不同程度上,利他主义的倾向是正常大脑发育的结果。
    • 那么,为什么呢?大脑发育的内在部分,以及随后的个体特征,是基因的结果。当然,基因与利他主义的关系是复杂的,可能有许多基因与环境因素相互作用,导致人们在不同情况下或多或少是无私的。尽管如此,几乎可以肯定的是基因导致人们变得无私。
    • 最后,为什么呢?如果在自然选择下,动物为了生存和繁殖而彼此不断竞争,似乎显然利他主义会适得其反。在一个种群中,有些人帮助别人,甚至是为别人伤害自己,其他人纯粹是自私的,似乎自私者会受益,利他者会受到影响,并且利他主义的基因将被驱逐而灭绝。

    [3] 我希望你能原谅我在这里用“毫无疑问”代替实验的参考资料,我想在本章中介绍一些理由,而不会陷入太深。

    这个明显的矛盾是“利他主义问题”:为什么利他主义的基因没有消失?

    在生物学家中,有很多可能的解释,包括互惠利他主义,性选择,亲属选择和群体选择。而在非科学家中,还有更多的解释。我把它交给你去探索别的假说;现在我想专注于一种解释,可以说是最简单的一种解释:也许利他主义是适应性的。换句话说,利他主义的基因可能使人们更容易生存和繁殖。

    事实证明,引发利他主义问题的囚徒困境,也可能有助于解决问题。

    12.3 囚徒困境比赛

    在 20 世纪 70 年代后期,密歇根大学的政治学家罗伯特阿克塞尔罗德(Robert Axelrod)组织了一场比赛来比较囚徒困境(PD)的策略。

    他邀请参与者以计算机程序的形式提交策略,然后相互对抗并保持得分。具体来说,他们玩的是 PD 的迭代版本,其中智能体针对同一对手进行多轮比赛,因此他们的决定可以基于历史。

    在 Axelrod 的比赛中,一个简单的策略出人意料地好,称为“针锋相对”,即 TFT,TFT 在第一轮迭代比赛中总是合作;之后,它会复制上一轮对手所做的任何事情。对手继续合作,TFT 保持合作,如果对手任何时候都背叛,下一轮 TFT 背叛,但如果对手变回合作,TFT 也会合作。

    这些比赛的更多信息,以及 TFT 为何如此出色的解释,请参阅以下视频:https://www.youtube.com/watch?v=BOvAbjfJ0x0

    看看这些比赛中表现出色的策略,Alexrod 发现了他们倾向于分享的特点:

    • 善良:表现好的策略在第一轮比赛中合作,并且通常会在随后的几轮中合作。
    • 报复:始终合作的策略,并不如如果对手背叛就报复的策略好。
    • 宽恕:但是过于斗气的策略往往会惩罚自己以及对手。
    • 不嫉妒:一些最成功的策略很少超过对手;他们成功了,因为他们对各种各样的对手都做得足够好。

    TFT 具有所有这些属性。

    Axelrod 的比赛为利他主义问题提供了部分可能的答案:也许利他主义的基因是普遍存在的,因为它们是适应性的。 许多社会互动可以建模为囚徒困境的变种,就这种程度而言,如果将一个大脑设定为善良,平衡报复和宽恕,就会在各种各样的情况下表现良好。

    但是 Axelrod 比赛中的策略是由人们设计的;他们并不进化。 我们需要考虑,善良、报复和宽恕的基因是否可以通过突变出现,成功侵入其他策略的种群,并抵制后续突变的侵入。

    12.4 合作进化的模拟

    合作进化是第一本书的标题,Axelrod 展示了来自囚徒困境比赛的结果,并讨论了利他主义问题的影响。 从那以后,他和其他研究人员已经探索了 PD 比赛的进化动态性,也就是说,PD 选手的总体中,策略的分布随时间如何变化。 在本章的其余部分中,我运行这些实验的一个版本并展示结果。

    首先,我们需要一种将 PD 策略编码为基因型的方法。 在这个实验中,我考虑了一些策略,其中智能体每一轮的选择仅取决于前两轮中对手的选择。 我用字典来表示策略,它将对手的前两个选择映射为智能体的下一个选择。

    以下是这些智能体的类定义:

    class Agent:
    
        keys = [(None, None),
                (None, 'C'),
                (None, 'D'),
                ('C', 'C'),
                ('C', 'D'),
                ('D', 'C'),
                ('D', 'D')]
    
        def __init__(self, values, fitness=np.nan):
            self.values = values
            self.responses = dict(zip(self.keys, values))
            self.fitness = fitness

    keys是每个智能体的词典中的键序列,其中元组('C', 'C')表示对手在前两轮合作;(None, 'C')意味着只有一轮比赛并且对手合作;(None, None)表示还没有回合。

    __init__方法中,values是对应于键的一系列选项,'C''D'。 所以如果值的第一个元素是'C',那就意味着这个智能体将在第一轮合作。 如果值的最后一个元素是'D',那么如果对手在前两轮中背叛,该智能体将会背叛。

    在这个实现中,总是背叛的智能体的基因型是'DDDDDDD'; 总是合作的智能体的基因型是'CCCCCCC',而 TFT 的基因型是'CCDCDCD'

    Agent类提供copy,它使其它智能体具有相同的基因型,但具有一定的变异概率:

    
    prob_mutate = 0.05
    
    def copy(self):
        if np.random.random() > self.prob_mutate:
            values = self.values
        else:
            values = self.mutate()
        return Agent(values, self.fitness)

    突变的原理是,在基因型中选择一个随机值并从'C'翻转到'D',或者相反:

    
    def mutate(self):
        values = list(self.values)
        index = np.random.choice(len(values))
        values[index] = 'C' if values[index] == 'D' else 'D'
        return values

    既然我们有了智能体,我们还需要比赛。

    12.5 Tournament

    Tournament类封装了 PD 比赛的细节:

    payoffs = {('C', 'C'): (3, 3),
               ('C', 'D'): (0, 5),
               ('D', 'C'): (5, 0),
               ('D', 'D'): (1, 1)}
    
    num_rounds = 6
    
    def play(self, agent1, agent2):
        agent1.reset()
        agent2.reset()
    
        for i in range(self.num_rounds):
            resp1 = agent1.respond(agent2)
            resp2 = agent2.respond(agent1)
    
            pay1, pay2 = self.payoffs[resp1, resp2]
    
            agent1.append(resp1, pay1)
            agent2.append(resp2, pay2)
    
        return agent1.score, agent2.score

    payoffs是一个字典,将从智能体的选择映射为奖励。例如,如果两个智能体合作,他们每个得到 3 分。如果一个背叛而另一个合作,背叛者得到 5 分,而合作者得到 0 分。如果他们都背叛,每个都会得到 1 分。这些是 Axelrod 在他的比赛中使用的收益。

    play运行几轮 PD 游戏。它使用Agent类中的以下方法:

    • reset:在第一轮之前初始化智能体,重置他们的分数和他们的回应的历史记录。
    • respond:考虑到对手之前的回应,向每个智能体询问回应。
    • append:通过存储选项,并将连续轮次的分数相加,来更新每个智能体。

    在给定的回合数之后,play将返回每个智能体的总分数。我选择了num_rounds = 6,以便每个基因型的元素都以大致相同的频率访问。第一个元素仅在第一轮访问,或在六分之一的时间内访问。接下来的两个元素只能在第二轮中访问,或者每个十二分之一。最后四个元素在六分之一时间内访问,平均每次访问六次,或者平均每个六分之一。

    Tournament提供了第二种方法,即melee,确定哪些智能体互相竞争:

    
    def melee(self, agents, randomize=True):
        if randomize:
            agents = np.random.permutation(agents)
    
        n = len(agents)
        i_row = np.arange(n)
        j_row = (i_row + 1) % n
    
        totals = np.zeros(n)
    
        for i, j in zip(i_row, j_row):
            agent1, agent2 = agents[i], agents[j]
            score1, score2 = self.play(agent1, agent2)
            totals[i] += score1
            totals[j] += score2
    
        for i in i_row:
            agents[i].fitness = totals[i] / self.num_rounds / 2

    melee接受一个智能体列表和一个布尔值randomize,它决定了每个智能体每次是否与同一邻居竞争,或者匹配是否随机化。

    i_rowj_row包含匹配的索引。 totals包含每个智能体的总分数。

    在循环内部,我们选择两个智能体,调用play和更新totals。 最后,我们计算每个智能体获得的,每轮和每个对手的平均点数,并将结果存储在每个智能体的fitness属性中。

    12.6 Simulation

    本章的Simulation类基于第?章的中的那个;唯一的区别是__init__step

    这是__init__方法:

    class PDSimulation(Simulation):
    
        def __init__(self, tournament, agents):
            self.tournament = tournament
            self.agents = np.asarray(agents)
            self.instruments = []

    Simulation对象包含一个Tournament对象,一系列的智能体和一系列的Instrument对象(就像第?章中一样)。

    以下是step方法:

    
    def step(self):
        self.tournament.melee(self.agents)
        Simulation.step(self)

    此版本的step使用Tournament.melee,它为每个智能体设置fitness属性;然后它调用父类的step方法,父类来自第?章:

    
    # class Simulation
    
        def step(self):
            n = len(self.agents)
            fits = self.get_fitnesses()
    
            # see who dies
            index_dead = self.choose_dead(fits)
            num_dead = len(index_dead)
    
            # replace the dead with copies of the living
            replacements = self.choose_replacements(num_dead, fits)
            self.agents[index_dead] = replacements
    
            # update any instruments
            self.update_instruments()

    Simulation.step将智能体的适应性收集到一个数组中; 然后它会调用choose_dead来决定哪些智能体死掉,并用choose_replacements来决定哪些智能体繁殖。

    我的模拟包含生存差异,就像第?章那样,但不包括繁殖差异。 你可以在本章的笔记本上看到细节。 作为练习之一,你将有机会探索繁殖差异的效果。

    12.7 结果

    假设我们从三个智能体开始:一个总是合作,一个总是背叛,另一个执行 TFT 策略。 如果我们在这个种群中运行Tournament.melee,合作者每轮获得 1.5 分,TFT 智能体获得 1.9 分,而背叛者获得 3.33 分。 这个结果表明,“总是背叛”应该很快成为主导策略。

    但是“总是缺陷”包含着自我破坏的种子,如果更好的策略被驱使而灭绝,那么背叛者就没有人可以利用,他们的适应性下降,并且容易受到合作者的入侵。

    根据这一分析,预测系统的行为不容易:它会找到一个稳定的平衡点,还是在基因型景观的各个位置之间振荡? 让我们运行模拟来发现它!

    我以 100 个始终背叛的相同智能体开始,并运行 5000 个步骤的模拟:

    tour = Tournament()
    agents = make_identical_agents(100, list('DDDDDDD'))
    sim = PDSimulation(tour, agents)

    图 12.1:平均适应性(囚徒困境的每个回合的所得点数)

    图?展示了随时间变化的平均适应性(使用第?章的MeanFitness仪器)。最初平均适应性是 1,因为当背叛者面对对方时,他们每轮只能得到 1 分。

    经过大约 500 个时间步,平均适应性增加到近 3,这是合作者面对彼此时得到的。但是,正如我们所怀疑的那样,这种情况不稳定。在接下来的 500 个步骤中,平均适应性下降到 2 以下,回到 3,并继续振荡。

    模拟的其余部分变化很大,但除了一次大的下降之外,平均适应性通常在 2 到 3 之间,长期平均值接近 2.5。

    而且这还不错!它不是一个合作的乌托邦,每轮平均得 3 分,但距离始终背叛的乌托邦还很远。这比我们所期待的,自利智能体的自然选择要好得多。

    为了深入了解这种适应性水平,我们来看看更多的仪器。Niceness在每个时间步骤之后测量智能体的基因型的合作比例:

    
    class Niceness(Instrument):
    
        def update(self, sim):
            responses = np.array([agent.values
                                  for agent in sim.agents])
            metric = np.mean(responses == 'C')
            self.metrics.append(metric)

    图 12.2:种群中所有基因组的平均友善度(左)和第一轮合作的种群比例(右)

    图?(左图)展示结果:平均友善度从 0 迅速上升到 0.75,然后在 0.4 到 0.85 之间波动,长期平均值接近 0.65。 同样,这相当好!

    具体看开始的移动,我们可以追踪第一轮合作的智能体的比例。 这是这个仪器:

    
    class Retaliating(Instrument):
    
        def update(self, sim):
            after_d = np.array([agent.values[2::2]
                                for agent in sim.agents])
            after_c = np.array([agent.values[1::2]
                                for agent in sim.agents])
            metric = np.mean(after_d=='D') - np.mean(after_c=='D')
            self.metrics.append(metric)

    报复行为将所有基因组中的元素数量,其中对手背叛后智能体也背叛(元素 2, 4 和 6),与其中的元素数量,其中对手合作后智能体背叛相比较。正如你现在的预期,结果差异很大(你可以在笔记本中看到图形)。平均而言,这些分数之间的差异小于 0.1,所以如果智能体在对手合作后,30% 的时间中背叛,他们可能会在背叛后的 40% 时间中背叛。

    这个结果为这个断言提供了较弱的支持,即成功的策略会报复。也许所有智能体甚至很多智能体都没有必要进行报复;如果整个种群中至少存在一定的报复倾向,那么这可能足以阻止高度报复策略的普及。

    为了衡量宽恕,我再次定义了一个工具,来查看在前两轮之后,智能体是否更有可能在 D-C 之后进行合作,与 C-D 相比。在我的模拟中,没有证据表明这种特殊的宽恕。另一方面,这些模拟中的策略在某种意义上是必然的宽容,因为它们只考虑前两轮的历史。

    12.8 总结

    Axelrod 的比赛提出了解决利他主义问题的一个可能的解决办法:或许善良,但不是太善良,是适应性的。但是原始比如中的策略是由人们,而不是进化论设计的,并且策略的分布在比赛过程中没有改变。

    所以这就提出了一个问题:像 TFT 这样的策略可能会在固定的人为设计策略中表现良好,但它们是否会进化?换句话说,他们是否可以通过变异出现在种群中,与祖先竞争成功,并抵抗他们的后代的入侵?

    本章中的模拟表明:

    • 背叛者种群容易受到更善良的策略的入侵。
    • 过于善良的种群容易受到背叛者的入侵。
    • 所以,善良的平均程度有所波动,但善良的平均数量普遍较高,而平均适应程度一般更接近合作乌托邦而不是偏差异议程度。
    • 在 Alexrod 的比赛中,TFT 是一项成功的战略,但对于不断发展的种群来说,这似乎不是一个最佳策略。事实上,可能没有稳定的最佳策略。
    • 某种程度的报复可能是适应性的,但对所有智能体来说,可能没有必要进行报复。 如果在整个种群中有足够的报复行为,这可能足以防止背叛者入侵 [4]。

    [4] 这就引入了博弈论中一个全新的话题 - 搭便车问题(见 https://en.wikipedia.org/wiki/Free-rider_problem)。

    很明显,这些模拟中的智能体很简单,而囚徒困境是一种有限范围的社交互动的高度抽象模型。 尽管如此,本章的结果对人性提供了一些见解。 也许我们对合作,报复和宽恕的倾向是天生的,至少部分是。 这些特征是我们的大脑的工作机制的结果,至少部分是由我们的基因控制的。 也许我们的基因这样来构建我们的大脑,因为在人类进化史上,自私的大脑的基因不太可能传播。

    所以也许这就是为什么自私基因会建立无私的大脑。

    12.9 练习

    本章的代码位于本书仓库的 Jupyter 笔记本chap12.ipynb中。打开笔记本,阅读代码并运行单元个。你可以使用这个笔记本来练习本章的练习。我的解决方案在chap12soln.ipynb中。

    练习 1

    本章中的模拟取决于我任意选择的条件和参数。作为练习,我鼓励你去探索其他条件,看看他们对结果有什么影响。这里有一些建议:

    1. 改变初始条件:不要从所有背叛者开始,看看如果从所有合作者,所有 TFT 或随机智能体开始会发生什么。
    2. Tournament.melee中,我在每个时间步骤开始时洗牌,所以每个玩家对抗两个随机选择的玩家。如果你不洗牌会怎么样?在这种情况下,每个智能体都会反复与相同的邻居进行比赛。这可能会让少数人的战略,更容易通过利用局部性入侵大多数。
    3. 由于每个智能体只与另外两个智能体进行比赛,因此每轮比赛的结果都是非常不同的:在任何一轮比赛中,胜过大部​​分智能体的智能体可能会运气不好,或者相反。如果增加每个智能体在每轮中的对手数量会发生什么?或者如果在每一步结束时,智能体的适应性是上一轮结束时其当前得分和适应性的平均值,会怎么样?
    4. 我为prob_survival函数选择的值从 0.7 到 0.9 不等,所以适应性最差的智能体p = 0.7,生存了 3.33 个时间步骤,适应性最强的智能体生存了 10 个。如果你使prob_survival更加或更加不“激进”,会发生什么情况。
    5. 我选择了num_rounds = 6,以便基因组的每个元素对比赛的结果具有大致相同的影响。 但这比 Alexrod 在他的比赛中使用的值要小得多。 如果增加num_rounds会发生什么? 注意:如果你研究这个参数的效果,你可能想修改Niceness来衡量基因组中最后4个元素的友善度,随着num_rounds的增加,它会受到更多的选择性压力。
    6. 我的实现拥有生存差异和随机繁殖。 如果添加繁殖差异会发生什么?

    练习 2

    在我的模拟中,种群从未收敛到一个状态,其中多数人共享相同的,据推测是最佳的基因型。对于这个结果有两种可能的解释:一是没有最佳策略,因为无论何时种群被大多数基因型控制,这种状况为少数人入侵提供了机会;另一种可能性是,突变率高到足以维持多种基因型,即使多数是非最佳的。为了辨别这些解释,请尝试降低突变率来查看发生了什么。或者,从随机种群开始,并且不带突变来运行,直到只有一个基因型存活。或者带突变来运行,直到系统达到稳定状态;然后关闭突变并运行,直到只有一个幸存的基因型。这些情况下基因型的特征是什么?

    练习 3

    我的实验中的智能体是“反应型”的,因为他们在每轮中的选择只取决于对手在前几轮中的做法。考虑探索一些策略,它们也考虑到智能体过去的选择。这样的策略将能够区分报复性对手,和没有挑衅而背叛的对手。

    展开全文
  •  本文着重分析了在室内、地下、机井、矿井等特殊环境下,人员的快速统计、识别及高精度定位的目前行业状况,并对相关案例进行了剖析研究,从而项目有效实施得出可行的解决方法。 0、引言 全球卫星定位系统...

    复杂环境下关于人员

    快速统计、识别及定位的研究

    摘要:

           本文着重分析了在室内、地下、机井、矿井等特殊环境下,人员的快速统计、识别及高精度定位的目前行业状况,并对相关案例进行了剖析研究,从而为项目有效性实施得出可行的解决方法。

    0、引言

    全球卫星定位系统(GPS)的成功使人们对定位服务的需求日益增多,然而在室内等复杂环境下,由于卫星信号接收受到严重干扰,GPS 无法满足定位精度的要求。射频识别技术(RFID)具有非接触、非视距、成本低且定位精度高的优点,开始得到越来越多的关注,成为优选的室内定位技术。

    1、项目背景及要求

    1.1、项目要求:

    1、实现人员统计  AAAAA

    2、实现人员识别  AAA

    3、实现人员定位  A

    1.2、项目背景

    目前GPS无法在室内、室外、地下、矿井等复杂环境下的进行人员识别及快速精准定位。因此需要一种能够快速人员统计、识别及精准定位的技术方案。

    1.3、专业词汇

    1.3.1、人数统计

    人数统计是一种运用视频图像分析技术进行人流量统计的视频智能化应用系统。通过内置算法对视频中人数和人群流动方向等信息进行有效统计并生成报表。用户可以在掌握监控区域实时动态信息的同时,及时得到现场准确的人数和人群流量数据,有利于管理单位更高效的组织工作,它可与第三方软件系统进行集成,为科学决策提供数据支持。

    1.3.2、无线射频识别(RFID)

    依赖电子标签

    可以广泛应用于监狱、矿井、地下作业、室内等环境。

    RFID技术的基本工作原理:标签进入磁场后,接收解读器发出的射频信号,凭借感应电流所获得的能量发送出存储在芯片中的产品信息(Passive Tag,无源标签或被动标签),或者由标签主动发送某一频率的信号(Active Tag,有源标签或主动标签),解读器读取信息并解码后,送至中央信息系统进行有关数据处理。

    一套完整的RFID系统, 是由阅读器(Reader)与电子标签(TAG)也就是所谓的应答器(Transponder)及应用软件系统三个部份所组成,其工作原理是Reader发射一特定频率的无线电波能量给Transponder,用以驱动Transponder电路将内部的数据送出,此时Reader便依序接收解读数据, 送给应用程序做相应的处理。

     

    1.3.3、辅助GPS技术(A-GPS)     

    依赖:带有GPS和网络的移动终端设备

    A-GPS技术是一种结合了网络基站信息和GPS信息对移动台进行定位的技术,可以在GSM/GPRS、WCDMA、CDMA2000和TD-SCDMA网络中使用。该技术需要在手机内增加GPS接收机模块,并改造手机天线,同时要在移动网络上加建位置服务器、差分GPS基准站等设备。如果要提高该方案在室内等GPS信号屏蔽地区的定位有效性,该方案还提出需要增添类似于EOTD方案中的位测量单元(LMU)。

    A-GPS基本思想是通过在卫星信号接收效果较好的位置上设置若干参考GPS接收机,并利用AGPS服务器通过与终端的交互获得终端的粗位置,然后通过移动网络将该终端需要的星历和时钟等辅助数据发送给终端,由终端进行GPS定位测量。测量结束后,终端可自行计算位置结果或者将测量结果发回到AGPS服务器,服务器进行计算并将结果发回给终端。同时后台SP可获取位置信息为其它服务应用。

     

    1.3.4、Zigbee无线组网通讯技术

           Zigbee是基于IEEE802.15.4标准的低功耗个域网协议。根据这个协议规定的技术是一种短距离、低功耗的无线通信技术。其特点是近距离、低复杂度、自组织、低功耗、低数据速率、低成本。主要适合用于自动控制和远程控制领域,可以嵌入各种设备。简而言之,ZigBee就是一种便宜的,低功耗的近距离无线组网通讯技术。

     

    1.3.5、RADAR室内定位系统

    Microsoft公司开发的RAD从室内定位系统利用指纹识别技术进行定位,解决WLAN中定位移动计算设备的问题"该方法是通过对特定环境下的RF信号衰落特征值进行处理实现的。

    RADAR系统是基于IEEE802.llWLAN的室内无线射频定位系统,属于采用经验测试和信号传播模型相结合的场景法定位系统"RADAR系统把信号强度作为估算射频发射器与接收器间距的依据,建立射频信号的传输信道模型,确定信号衰减与发射器!接收器间墙壁数量的关系,从而得到给定位置接收器最优的距离估算参数"该系统事先在建筑物内部固定有三个位置已知的基站,待定位置的移动点通过两个步骤获取位置"首先是一个离线的数据收集的过程,由各移动节点发送广播报文,基站的接收器根据信号强度确定移动节点的位置,并将此位置存入一个场景一位置的表结构中"第二个步骤是在线数据处理过程,移动节点定期发送广播报文,基站节点查表,根据接收信号的强度找出最为接近的位置作为节点当前的位置"

     

    1.3.6、ActiveBadge 室内定位系统

    2、目前行业相关案例分析

    2.1、基于图像识别技术

    2.1.1、人员统计

    视频人数统计技术是一种基于智能视频分析技术发展而来的应用功能,人数统计技术采用先进的智能视频分析算法,通过视频画面分析检测活体(人体头部和肩部)的形状,并在设定区域内分析进和出的不同个体数量,实现相关人数数据的统计和记录。

    人数统计系统是利用计算机视觉技术,对画面进行分析、处理、应用的过程,完整的行人数量统计系统,主要包括以下几个步骤:

     

    系统技术原理如下图所示:

    案例一、天威电子科技

    http://www.skycount.com.cn/Products.aspx

    摄像枪通过数据传输线路(超五类双绞线或视频线)把采集回来的客流图像数据传输至已安装天威客流统计系统的电脑进行处理分析,从而得出精确的客流量数据。

    案例二、飞瑞斯:人形检测分析仪

    http://www.firscom.cn/products_27_274.html

    人形检测分析仪是飞瑞斯科技利用视频分析连续、客观地监控目标区域,根据图像中人的形体特征检测,进而完整的检测出人数来,人形检测产品,可采集某区域、街道、路口的人流量和过往人流的数据,在公共场所广场可利用此软件进行拥挤安全预警分流措施。

    飞瑞斯:客流统计一体机

    http://www.firscom.cn/case_43_51.html     

     

    案例三、平安视讯

     http://www.safevision.cn/about.asp?nid=2&id=3      平安视讯

    案例四、精点科技

     http://www.wisecount.com/product_498_271.html    精点科技

    2.1.3、人员识别

    案例一、成都网视通成科技有限公司

    http://www.soci.com.cn/company/shop/cpxs_230021_110814.html

    智能视频人脸识别系统

     

           案例二、永盛

    http://www.keliutongji.com/Products/264.html 

    “壹脸通”人脸识别监控系统/VIP识别系统

     


    2.2、基于传感器技术

    2.2.1、人员定位

    案例一、北京中矿华沃科技

    采用技术:ZigBee技术

    高精度人员定位系统

    http://www.zkhw.cn/fenlei_mores.aspx?id=99

    北京中矿华沃科技股份有限公司

     

    案例二、深圳市万全智能技术有限公司

    采用技术:RFID技术

    深圳市万全智能技术有限公司。

    超高频RFID阅读器、UHF RFID天线、UHF RFID标签

    http://www.vanch.cn/pro/show/100.html 

    2.3、基于指纹识别技术

    2.3.1、人员统计、人员识别

    案例一、汉王

    汉王人脸通门禁考勤机 E392A

    http://www.hanwangshop.com/product_ebook.aspx?id=189

     

    案例二、中控考勤机

    人脸

    http://www.kqj123.com/main.asp?pid=184&id=5

    指纹

    http://www.kqj123.com/main.asp?pid=209&id=5

    射频卡、指纹、密码

     im2500 8寸TFT高清晰图形界面,可显示个性图形界面及逼真的人员彩色照片。内置Intel32位处理器,采用中控科技最新Biokey VX8.0版高速混合引擎指纹识别算法,全面提高识别质量,及其机器运行效率。满足用户个性需求:射频卡、指纹、密码、摄像拍照,可任意组合识别。内置Webserver,可以高效的浏览。支持手机远程查询、TCP/IP协议、100M高速网络,可实现跨网段数据传送。支持考勤数据实时传送,利用稳定的网络平台,大大提高了考勤数据的可靠性。

     


    3、解决方案

    3.1、A方案:人员统计

    3.1.1、采用技术:图像分析处理

    方案流程:

    视频监控-->获取图像-->分析图像-->计算人数-->反馈用户

    设备:

    视频监控设备、监控平台

           可用产品:

     

    相关论文:

    基于DM642视频监控人数统计的设计和实现_谢锐.caj

    基于视频图像处理的人数自动统计技术研究_顾德军.caj

    基于图像的公共汽车人数自动统计技术研究_李志刚.caj

    智能视频监控中的行人流量自动统计技术的研究_吕沛.caj

     

     

    3.1.2、采用技术:红外线

    方案流程:

    红外设备布控-->触发电路-->分析计算-->计算人数-->反馈用户

    设备:

    红外设备、单片机等

           可用产品:

     

    相关论文:

    公共娱乐场所人数统计系统研究_赵炯.caj

    基于红外传感器的楼宇人数统计系统的设计_李娟.caj

    采用红外织网的室内定位技术_宁静.caj

    3.2、B方案:人员统计、人员识别

    采用技术:图像分析处理

    方案流程:

    视频监控-->获取图像-->分析图像-->人员识别、计算人数-->反馈用户

    设备:

    视频监控设备、监控平台

           可用产品:

    相关论文:

    基于统计学习的自动人脸识别算法研究_王先基.caj

    基于监控视频的人脸识别与运动目标分割_吴松.caj
    基于人脸识别的会所智能监控系统的研究_阮琳琳.caj

    基于视频监控图像的人脸识别技术的研究_徐辉.caj

    视频定位技术在城市公共安全视频监控系统中的应用_许昳.caj

    3.3、C方案:人员统计、人员识别、人员定位

    采用技术:电子标签

    方案流程:

    传感器-->发送数据-->服务器计算数据-->识别人员、计算人数、地理位置等

    设备:

    附着电子标签的终端设备、传感器数据读取平台

           可用产品:

     

    相关论文:

    基于RFID标签的定位原理和技术_韩晶.caj

    基于RFID的室内定位技术研究_李魏峰.caj

    基于RFID监狱犯人活动定位系统的设计与实现_姚敏.caj

    基于ZigBee技术的室内定位系统研究与实现_李同松.caj

    3.3、D方案:人员统计、人员识别

    采用技术:指纹识别+头像识别

    门禁一般分为:

    刷卡门禁{带/不带考勤数据}

    指纹门禁{带考勤数据}

    人脸识别门禁{带考勤数据}

    http://www.kqj123.com/main.asp?pid=127&id=5

    方案流程:

    人员主动刷卡-->打卡机识别-->分析计算

    专用红外夜视摄象头

    验证方式面部识别、刷卡+面部识别、指纹+面部识别、指纹++面部识别

    三维人脸识别率: 
    ·
    姿态变化 100% 
    · 面部头发遮挡 87% 
    · 头部遮挡试验戴帽子和头盔对有效识别的影响95%
    ·
    弱光线 100%

     

    相关论文:

    自动指纹识别系统关键技术研究_王玮.caj

    自动指纹识别技术的发展与应用_尹义龙.caj

    自动指纹识别方法研究_王崇文.caj

    指纹识别系统的研究与设计_甘露.caj

     

    关键词:

    人员 统计定位 人脸 识别 视频 指纹

     

    展开全文
  • 复杂性应对之道 - 领域建模

    万次阅读 多人点赞 2018-03-19 17:39:07
    为什么要领域建模 软件的世界里没有银弹,是用事务脚本还是领域模型没有对错之分,关键看是否合适。就像自营和平台哪个模式更好?答案是都很好,所以亚马逊可以有三方入住,阿里也可以有自建仓嘛。实际上,CQRS就是...

    为什么要领域建模

    维护过企业级业务系统的同学,基本上没有一个不抱怨业务代码烂的,过程式的面条代码充斥着屏幕,程序员的心力和体力都经受着极大的考验,怎么破?

    DDD革命

    DDD革命性在于,领域模型准确反映了业务语言,而传统J2EE或Spring+Hibernate等事务性编程模型只关心数据,这些数据对象除了简单setter/getter方法外,没有任何业务方法,被比喻成贫血模式

    以银行账号Account为案例,Account有“存款”,“计算利息”和“取款”等业务行为,但是传统经典的方式是将“存款”,“计算利息”和“取款”行为放在账号的服务AccountService中,而不是放在Account对象本身之中。我们不能因为用了计算机,用了数据库,用了框架,业务模型反而被技术框架给绑架了,就像人虽然是由母亲生的,但是人的吃喝拉撒母亲不能替代,更不能以母爱名义剥夺人的正常职责行为,如果是这样,这个人就是被母爱绑架了。

    DDD不是银弹

    软件的世界里没有银弹,是用事务脚本还是领域模型没有对错之分,关键看是否合适。就像自营和平台哪个模式更好?答案是都很好,所以亚马逊可以有三方入住,阿里也可以有自建仓嘛。

    实际上,CQRS就是对事务脚本和领域模型两种模式的综合,因为对于Query和报表的场景,使用领域模型往往会把简单的事情弄复杂,此时完全可以用奥卡姆剃刀把领域层剃掉,直接访问Infrastructure。

    我个人也是坚决反对过度设计的,因此对于简单业务场景,我强力建议还是使用事务脚本,其优点是简单、直观、易上手。但对于复杂的业务场景,你再这么玩就不行了,因为一旦业务变得复杂,事务脚本就很难应对,容易造成代码的“一锅粥”,系统的腐化速度和复杂性呈指数级上升。目前比较有效的治理办法就是领域建模,因为领域模型是面向对象的,在封装业务逻辑的同时,提升了对象的内聚性和重用性,因为使用了通用语言(Ubiquitous Language),使得隐藏的业务逻辑得到显性化表达,使得复杂性治理成为可能。

    接下来,让我们看一个银行转账的实例,对比下事务脚本和领域模型两者编程模型的不同。

    DDD初体验

    银行转账事务脚本实现

    在事务脚本的实现中,关于在两个账号之间转账的领域业务逻辑都被写在了MoneyTransferService的实现里面了,而Account仅仅是getters和setters的数据结构,也就是我们说的贫血模型:

    public class MoneyTransferServiceTransactionScriptImpl
          implements MoneyTransferService {
      private AccountDao accountDao;
      private BankingTransactionRepository bankingTransactionRepository;
      . . .
      @Override
      public BankingTransaction transfer(
          String fromAccountId, String toAccountId, double amount) {
        Account fromAccount = accountDao.findById(fromAccountId);
        Account toAccount = accountDao.findById(toAccountId);
        . . .
        double newBalance = fromAccount.getBalance() - amount;
        switch (fromAccount.getOverdraftPolicy()) {
        case NEVER:
          if (newBalance < 0) {
            throw new DebitException("Insufficient funds");
          }
          break;
        case ALLOWED:
          if (newBalance < -limit) {
            throw new DebitException(
                "Overdraft limit (of " + limit + ") exceeded: " + newBalance);
          }
          break;
        }
        fromAccount.setBalance(newBalance);
        toAccount.setBalance(toAccount.getBalance() + amount);
        BankingTransaction moneyTransferTransaction =
            new MoneyTranferTransaction(fromAccountId, toAccountId, amount);
        bankingTransactionRepository.addTransaction(moneyTransferTransaction);
        return moneyTransferTransaction;
      }
    }

    上面的代码大家看起来应该比较眼熟,因为目前大部分系统都是这么写的。需求评审完,工程师画几张UML图完成设计,就开始向上面这样怼业务代码了,这样写基本不用太费脑,完全是面向过程的代码风格。有些同学可能会说,我这样写也可以实现系统功能啊,还是那句话“just because you can, doesn’t mean you should”。说句不好听的,正是有这么多“没有追求”、“不求上进”的码农才造成了应用系统的混乱、败坏了应用开发的名声。这也是为什么很多应用开发工程师觉得工作没意思,技术含量低,觉得整天就是写if-else的业务逻辑代码,系统又烂,工作繁琐、无聊、没有成长、没有成就感,所以转向去做中间件啊,去写JDK啊,觉得那个NB。实际上,应用开发一点都不简单也不无聊,业务的变化比底层Infrastructure的变化要多得多,解决的难度也丝毫不比写底层代码容易,只是很多人选择了用无聊的方式去做。其实我们是有办法做的更优雅的,这种优雅的方式就是领域建模,唯有掌握了这种优雅你才能实现从工程师向应用架构的转型。同样的业务逻辑,接下来就让我们看一下用DDD是怎么做的。

    银行转账领域模型实现

    如果用DDD的方式实现,Account实体除了账号属性之外,还包含了行为和业务逻辑,比如debit( )credit( )方法。

    // @Entity
    public class Account {
      // @Id
      private String id;
      private double balance;
      private OverdraftPolicy overdraftPolicy;
      . . .
      public double balance() { return balance; }
      public void debit(double amount) {
        this.overdraftPolicy.preDebit(this, amount);
        this.balance = this.balance - amount;
        this.overdraftPolicy.postDebit(this, amount);
      }
      public void credit(double amount) {
        this.balance = this.balance + amount;
      }
    }

    而且透支策略OverdraftPolicy也不仅仅是一个Enum了,而是被抽象成包含了业务规则并采用了策略模式的对象。

    public interface OverdraftPolicy {
      void preDebit(Account account, double amount);
      void postDebit(Account account, double amount);
    }
    public class NoOverdraftAllowed implements OverdraftPolicy {
      public void preDebit(Account account, double amount) {
        double newBalance = account.balance() - amount;
        if (newBalance < 0) {
          throw new DebitException("Insufficient funds");
        }
      }
      public void postDebit(Account account, double amount) {
      }
    }
    public class LimitedOverdraft implements OverdraftPolicy {
      private double limit;
      . . .
      public void preDebit(Account account, double amount) {
        double newBalance = account.balance() - amount;
        if (newBalance < -limit) {
          throw new DebitException(
              "Overdraft limit (of " + limit + ") exceeded: " + newBalance);
        }
      }
      public void postDebit(Account account, double amount) {
      }
    }

    而Domain Service只需要调用Domain Entity对象完成业务逻辑即可。

    public class MoneyTransferServiceDomainModelImpl
          implements MoneyTransferService {
      private AccountRepository accountRepository;
      private BankingTransactionRepository bankingTransactionRepository;
      . . .
      @Override
      public BankingTransaction transfer(
          String fromAccountId, String toAccountId, double amount) {
        Account fromAccount = accountRepository.findById(fromAccountId);
        Account toAccount = accountRepository.findById(toAccountId);
        . . .
        fromAccount.debit(amount);
        toAccount.credit(amount);
        BankingTransaction moneyTransferTransaction =
            new MoneyTranferTransaction(fromAccountId, toAccountId, amount);
        bankingTransactionRepository.addTransaction(moneyTransferTransaction);
        return moneyTransferTransaction;
      }
    }

    通过上面的DDD重构后,原来在事务脚本中的逻辑,被分散到Domain Service,Domain Entity和OverdraftPolicy三个满足SOLID的对象中,在继续阅读之前,我建议可以自己先体会一下DDD的好处。

    领域建模的好处

    DDD最大的好处是:接触到需求第一步就是考虑领域模型,而不是将其切割成数据和行为,然后数据用数据库实现,行为使用服务实现,最后造成需求的首肢分离。DDD让你首先考虑的是业务语言,而不是数据。DDD强调业务抽象和面向对象编程,而不是过程式业务逻辑实现。重点不同导致编程世界观不同

    面向对象

    • 封装:Account的相关操作都封装在Account Entity上,提高了内聚性和可重用性。
    • 多态:采用策略模式的OverdraftPolicy(多态的典型应用)提高了代码的可扩展性。

    业务语义显性化

    • 通用语言:“一个团队,一种语言”,将模型作为语言的支柱。确保团队在内部的所有交流中,代码中,画图,写东西,特别是讲话的时候都要使用这种语言。例如账号,转账,透支策略,这些都是非常重要的领域概念,如果这些命名都和我们日常讨论以及PRD中的描述保持一致,将会极大提升代码的可读性,减少认知成本。说到这,稍微吐槽一下我们有些工程师的英语水平,有些神翻译让一些核心领域概念变得面目全非。
    • 显性化:就是将隐式的业务逻辑从一推if-else里面抽取出来,用通用语言去命名、去写代码、去扩展,让其变成显示概念,比如“透支策略”这个重要的业务概念,按照事务脚本的写法,其含义完全淹没在代码逻辑中没有突显出来,看代码的人自然也是一脸懵逼,而领域模型里面将其用策略模式抽象出来,不仅提高了代码的可读性,可扩展性也好了很多。

    如何进行领域建模

    初步建模

    好的模型应该是建立在对业务深入理解的基础上。就我自己的经验而言,建模是一个不断迭代的过程,一开始可以简单点来。

    首先抓住一些核心概念,这些业务知识和核心概念可以通过和业务专家沟通,也可以通过头脑风暴的形式从User Story或者Event Storming去扣。

    然后假设一些业务场景走查一下,再写一些伪代码验证一下run一下,看看顺不顺,如果很顺滑,说明没毛病,否则就要看看是不是需要调整一下模型,随着项目的进行和对业务理解的不断深入,这种迭代将持续进行。

    举个栗子,比如让你设计一个中介系统,一个典型的User Story可能是“小明去找工作,中介说你留个电话,有工作机会我会通知你”,这里面的关键名词很可能就是我们需要的领域对象:
    - 小明是求职者。
    - 电话是求职者的属性。
    - 中介包含了中介公司,中介员工两个关键对象。
    - 工作机会肯定也是关键领域对象;
    - 通知这个动词暗示我们这里用观察者模式会比较合适。

    然后再梳理一下领域对象之间的关系,一个求职者可以应聘多个工作机会,一个工作机会也可以被多个求职者应聘,M2M的关系,中介公司可以包含多个员工,O2M的关系。对于这样简单的场景,这个建模就差不多了。

    当然我们的业务场景往往比这个要复杂,而且不是所有的名词都是领域对象也可能是属性,也不是所有的动词都是方法也可能是领域对象,再者,看的见实体好找,看不见的、隐藏的,需要深入理解业务,需要“无中生有”才能得到的抽象就没那么容易发现了,所以要具体问题具体对待,这个进化的过程需要我们有很好的业务理解力,抽象能力以及建模的经验(知道为什么公司的job model里那么强调技术人员的业务理解力和抽象能力了吧

    比如通常情况下,价格和库存只是订单和商品的一个属性,但是在阿里系电商业务场景下,价格计算和库存扣减的复杂程度可以让你怀疑人生,因此作为电商中台,把价格和库存单独当成一个域(Domain)去对待是很必要的。

    当然这个只是最初级的模型,接下来我会通过DDD中的一些核心概念的介绍,让大家更清楚的了解建模的过程。

    领域事件(Domain Event)

    An event is something that has happened in the past. A domain event is, logically, something that happened in a particular domain, and something you want other parts of the same domain (in-process) or domain in aonther bounded context to be aware of and potentially react to.

    Domain Event是由一个特定领域触因为一个用户Command触发的发生在过去的行为产生的事件,而这个事件是系统中其它部分感兴趣的。

    为什么Domain Event如此重要? 因为在现在的分布式环境下,没有一个业务系统是割裂的,而Messaging绝对是系统之间耦合度最低,最健壮,最容易扩展的一种通信机制。因此理论上它是分布式系统的必选项。

    但是目前大部分系统的Event都设计的很随性,没有统一的指导和规范,导致Event滥用和无用的情况时有发生,而Domain Event给我们一个很好的方向,指引我们该如何设计我们系统的Event。

    Event命名

    Your Domain Event type names should be a statement of a past occurrence, that is, a verb in the past tense.

    因为表示的是过去事件,所以推荐命名为Domain Name + 动词的过去式 + Event。这样比较可以确切的表达业务语义。

    下面是几个举例:
    1. CustomerCreatedEvent,表示客户创建后发出的领域事件。
    2. OpportunityTransferedEvent,表示机会转移后发出的领域事件。
    3. LeadsCreatedEvent,表示线索创建后发出的领域事件。

    Event内容

    Event的内容有两种形式:

    1. Enrichment:也就是在Event的payload中尽量多多放data,这样consumer就可以自恰(Autonomy)的处理消息了。
    2. Query-Back:这种是在Event中通过回调拿到更多的data,这种形式会加重系统的负载,performance也会差一些。

    所以如果要在Enrichment和Query-Back之间做选择的话,首先推荐使用Enrichment。

    Event Sourcing

    Event Sourcing是在Domain Event上面的一个扩展,是一个可选项。也就是要有一个Event Store保存所有的Events,其实如果你是用MetaQ作为Event机制的话,这些Events都是存储在MetaQ当中的,只是MetaQ并没有提供很好的Event查询和回溯,所以如果决定使用Event Sourcing的话,最好还是自己单独建立一个Event Store。

    使用Event Sourcing主要有以下好处,如果用不到的话,完全可以不用,但是Domain Event还是强烈建议要使用。

    1. Event Sourcing存储了所有发生在Core Domain上面的事件。
    2. 基于这些事件,我们可以做系统回放,系统Debug,以及做用户行为的分析(类似于打点)

    Event Storming

    事件风暴是《DDD Distilled》书中提出的一个业务分析的方法论,其主要作用是从Domian事件出发,来分析用户Command,来找到Ubiquitous Languange,来抽象Domain Entity以及Bounded Context。

    可以和User Story的方法论结合起来使用,其最大的优点是,这种分析方式即使是non-tech的人,比如产品,业务专家等也能听得懂,也能参与进来。相比较一上来就使用UML画领域模型图而言。

    聚合根(Aggreagte)

    聚合根(Aggregate Root)是DDD中的一个概念,是一种更大范围的封装,把一组有相同生命周期、在业务上不可分隔的实体和值对象放在一起考虑,只有根实体可以对外暴露引用,也是一种内聚性的表现。

    确定聚合边界要满足固定规则(Invariant),是指在数据变化时必须保持的一致性规则,具体规则如下
    - 根实体具有全局标识,最终负责检查规定规则
    - 聚合内的实体具有本地标识,这些标识在Aggregate内部才是唯一的
    - 外部对象不能引用除根Entity之外的任何内部对象
    - 只有Aggregate的根Entity才能直接通过数据库查询获取,其他对象必须通过遍历关联来发现
    - Aggegate内部的对象可以保持对其他Aggregate根的引用
    - Aggregate边界内的任何对象修改时,整个Aggregate的所有固定规则都必须满足

    还是看银行的例子,Account(账号)是CustomerInfo(客户信息)Entity和Address(值对象)的聚合根,Tansaction(交易)是流水(Journal)的聚合根,因为流水是因为交易才产生的,具有相同的生命周期。
    image.png

    最后提醒一下,聚合根是一个逻辑概念,主观性很强,所以在建模过程中很容易产生分歧,因此在日常工作中千万不要教条,把握住一条主要原则,我们的最终目的是为了业务语义显现化,如果因为聚合根把模型弄的晦涩难懂那就得不偿失了

    领域服务(Domain Service)

    什么是领域服务

    有些领域中的动作,它们是一些动词,看上去却不属于任何对象。它们代表了领域中的一个重要的行为,所以不能忽略它们或者简单地把它们合并到某个实体或者值对象中。当这样的行为从领域中被识别出来时,最佳实践是将它声明成一个服务。这样的对象不再拥有内置的状态。它的作用仅仅是为领域提供相应的功能。Service往往是以一个活动来命名,而不是Entity来命名。例如开篇转账的例子,转账(transfer)这个行为是一个非常重要的领域概念,但是它是发生在两个账号之间的,归属于账号Entity并不合适,因为一个账号Entity没有必要去关联他需要转账的账号Entity,这种情况下,使用MoneyTransferDomainService就比较合适了。
    识别领域服务,主要看它是否满足以下三个特征:
    1. 服务执行的操作代表了一个领域概念,这个领域概念无法自然地隶属于一个实体或者值对象。
    2. 被执行的操作涉及到领域中的其他的对象。
    3. 操作是无状态的。

    领域服务陷阱

    在使用领域服务时要特别当心,一个比较常见的错误是没有努力为行为找到一个适当的对象,就直接抽象成领域服务,这会使我们的代码逐渐转化为过程式的编程,一个极端的例子是把所有的行为都放到领域服务中,而领域模型退化成只有属性的贫血DO,那DDD就没有任何意义了。所以一定要深入思考,既不能勉强将行为放到不符合对象定义的对象中,破坏对象的内聚性,使其语义变得模糊。也不能不加思考的都放到领域服务中,从而退化成面向过程的编程。

    应用服务和领域服务如何划分

    在领域建模中,我们一般将系统划分三个大的层次,即应用层(Application Layer),领域层(Domain Layer)和基础实施层(Infrastructure Layer),关于这三个层次的详细内容可以参考我的另一篇SOFA框架的分层设计。可以看到在App层和Domain层都有服务(Service),这两个Service如何划分呢,什么样的功能应该放在应用层,什么样的功能应该放在领域层呢?
    决定一个服务(Service)应该归属于哪一层是很困难的。如果所执行的操作概念上属于应用层,那么服务就应该放到这个层。如果操作是关于领域对象的,而且确实是与领域有关的、为领域的需要服务,那么它就应该属于领域层。总的来说,涉及到重要领域概念的行为应该放在Domain层,而其它非领域逻辑的技术代码放在App层,例如参数的解析,上下文的组装,调用领域服务,消息发送等。还是银行转账的case为例,下图给出了划分的建议:
    image.png

    边界上下文(Bounded Context)

    领域实体是有边界上下文的,比如Apple这个实体不同的上下文,表达的含义就完全不一样,在水果店它就是水果,在苹果专卖店它就是手机。

    所以边界上下文(Bounded Context)在DDD里面是一个非常重要的概念,Bounded Context明确地限定了模型的应用范围,在Context中,要保证模型在逻辑上统一,而不用考虑它是不是适用于边界之外的情况。在其他Context中,会使用其他模型,这些模型具有不同的术语、概念、规则和Ubiquitous Language的行话。

    上下文映射(Context Mapping)

    那么不同Context下的业务要互相通信怎么办呢?这就涉及跨边界的Context Mapping(上下文映射),首先不同上下文之间的通信可以是同步的,也可以是异步的,同步的话一般是RPC或者RESTFul,异步的话会推荐上文提到的Domain Event.

    Mapping的方式有很多种,有Shared Kernal(共享内核),Conformist(追随者),以及Anti-Corruption(防腐层)等等。

    我个人比较推崇Domain Event + AC,这样可以将系统之间的耦合降到最低。

    以我们真实的业务场景举个例子,比如会员这个概念在ICBU网站是指网站上的Buyer,但是在CRM领域是指Customer,虽然很多的属性都是一样的,但是二者在不同的Context下其语义和概念是有差别的,我们需要用AC做一下转换:
    image.png

    边界上下文和微服务

    先来说一下微服务,抛开以Docker为代表的底层容器化技术不看,微服务和我们之前的SOA么有本质区别。

    这不是我一个人的观点,关于这个想法我还专门求证了业界大牛Randy Shoup,问他微服务和SOA的区别,下面是他给我的回答
    image.png

    那么如何划分系统,才能得到一个比较合适的粒度,不会太粗,也不会太细呢。此时我们可以考虑DDD的战略设计,即从战略角度整体描述业务领域全貌,然后通过边界上下文将不同的实体归类到相对应的域里面。

    比如在CRM领域,我们按照下面的战略设计图,我会自然的把CRM系统划分成销售服务,组织权限服务,营销服务,售卖服务。
    image.png

    模型重构

    最后我想强调的是,建模不是一次性的工作,也不可能是一次性的工作,业务在演化,随之而来的模型也需要演化和重构,当模型和业务部匹配的时候,你还是要霸王硬上弓的往里面塞,其结果可想而知。

    模型统一

    建模的过程很像盲人摸象,不同背景人用不同的视角看同一个东西,其理解也是不一样的。比如两个盲人都摸到大象鼻子,一个人认为是像蛇(活的能动),而另一个人认为像消防水管(可以喷水),那么他们将很难集成。双方都无法接受对方的模型,因为那不符合自己的体验。事实上,他们需要一个新的抽象,这个抽象需要把蛇的“活着的特性”与消防水管的“喷水功能”合并到一起,而这个抽象还应该排除先前两个模型中一些不确切的含义和属性,比如毒牙,或者卷起来放到消防车上去的行为,这就是模型的统一。统一完的模型也许还不叫大象鼻子,但是已经很接近大象鼻子的属性和功能了,随着我们对模型对象、对业务理解的越来越深入、越来越透彻,我们会不断的调整演化我们的模型,所以建模不是一个one-time off的工作,而是一个持续不断演化重构的过程。

    模型演化

    世界上唯一不变的就是变化,模型和代码一样也需要不断的重构和精化,每一次的精化之后,开发人员应该对领域知识有了更加清晰的认识。这使得理解上的突破成为可能,之后,一系列快速的改变得到了更符合用户需要并更加切合实际的模型。其功能性及说明性急速增强,而复杂性却随之消失。这种突破需要我们对业务有更加深刻的领悟和思考,然后再加上重构的勇气和能力,勇气是项目工期很紧你敢不敢重构,能力是你有没有完备的CI保证你的重构不破坏现有的业务逻辑。

    实体在演变
    以开篇的银行账号为例,假如一开始账号都有withdraw(取钱)的行为,此时只需要在Account上加上withdraw方法就好了。
    - 演变一:
    随着业务的发展,我们需要支持ATM账号和Online账号,而Online账号是不能withdraw的,此时最差的做法是保持模型不变,而是在withdraw方法中判断如果是OnlineAccount则抛出异常。这种简单的代码堆砌可以满足业务功能,但是其业务语义完全被掩盖。更好的重构方法应该是将withdraw抽成一个接口IWithdrawable。
    - 演变二:
    好的,没有什么可以阻挡业务对变化的向往。现在公司出于安全性的考虑,为新开通的ATMAccount设置了取款上线,超过则不能支取。简单做法是在IWithdrawable中再加入一个setLimit行为,可是我们并不想改动影响到老的账号业务,所以更好的重构应该是重新写一个ILimitedWithdrawable接口,让其继承老接口,这样老的代码就可以保持不变了。
    image.png
    通过上面的例子,我们可以看到领域模型和面向对象是一对孪生兄弟,我们会用到大量的OO原则,比如上面的重构就用到了SOLID的SRP(单一职责)和OCP(开闭原则)。在实际工作中,我的确也有这样的体会,自从践行DDD以后,我们采用OOA和OOD的时候比以前明显多了很多,OO的能力也在不断的提升。

    引入新抽象
    还是以开篇的转账来举个例子,假如转账业务开始变的复杂,要支持现金,信用卡,支付宝,比特币等多种通道,且没种通道的约束不一样,还要支持一对多的转账。那么你还是用一个transfer(fromAccount, toAccount)就不合适了,可能需要抽象出一个专门的领域对象Transaction,这样才能更好的表达业务,其演化过程如下:
    image.png

    业务可视化和可配置化

    好的领域建模可以降低应用的复杂性,而可视化和可配置化主要是帮助大家(主要是非技术人员,比如产品,业务和客户)直观地了解系统和配置系统,提供了一种“code free”的解决方案,也是SaaS软件的主要卖点。要注意的是可视化和可配置化难免会给系统增加额外的复杂度,必须慎之又慎,最好是能使可视化和配置化的逻辑与业务逻辑尽量少的耦合,否则破坏了原有的架构,把事情搞的更复杂就得不偿失了。

    可扩展设计中,我已经介绍了我们SOFA架构是如何通过扩展点的设计来支撑不同业务差异化的需求的,那么可否更进一步,我们将领域的行为(也叫能力)和扩展点用可视化的方式呈现出来,并对于一些不需要编码实现的扩展点用配置的方式去完成呢。当然是可以的,比如还是开篇转账的例子,对于透支策略OverdraftPolicy这个业务扩展点,新来一个业务说透支额度不能超过1000,我们可以完全结合规则引擎进行配置化完成,而不需要编码。

    所以我能想到的一种还比较优雅的方式,是通过Annotation注解的方式对领域能力和扩展点进行标注,然后在系统bootstrap阶段,通过代码扫描的方式,将这些能力点和扩展点收集起来上传到中心服务器,然后再通过GUI的方式呈现出来,从而做到业务的可视化和可配置化。大概的示意图如下:
    image.png

    有同学可能会问流程要不要可视化,这里要分清楚两个概念,业务逻辑流和工作流,很多同学混淆了这两个概念。业务逻辑流是响应一次用户请求的业务处理过程,其本身就是业务逻辑,对其编排和可视化的意义并不是很大,无外乎只是把代码逻辑可视化了,在我们的SOFA框架中,是通过扩展点和策略模式来处理业务的分支情况,而我看到我们阿里很多的内部系统将这种响应一次用户请求的业务逻辑用很重的工作流引擎来做,美其名曰流程可编排,实质上往往是把简单的事情复杂化了。而工作流是指完成一项任务所需要不同节点的连接,节点主要分为自动节点和人工节点,其中每个人工节点都需要用户的参与,也就是响应一次用户的请求,比如审批流程中的经理审批节点,CRM销售过程的业务员的处理节点等等。此时可以考虑使用工作流引擎,特别是当你的系统需要让用户自定义流程的时候,那就不得不使用可视化和可配置的工作流引擎了,除此之外,最好不要自找麻烦。我曾在银行工作过,亲眼看见过IBM是怎么忽悠银行使用它们的BPM系统,然后把系统弄的巨复杂无比,所以我对工作流引擎的印象并不好,当然也不排除有用的特别合适的案例,只是我还没看见,如果有看见的同学麻烦告诉我一声,学习一下。因为我们现在还没有让用户自定义流程的诉求,所以使用工作流引擎并不在我们现阶段的考虑范围之内。

    展开全文
  • 方差分析与假设检验相关知识点总结方差分析基本原理单因素方差分析双因素方差分析假设检验参数检验非参数检验 方差分析 基本原理 单因素方差分析 双因素方差分析 假设检验 参数检验 非参数检验 ...

    参数说明

    1. p-value:p值,即某件事情发生的概率
    2. α:显著性水平
    3. β:本文中一般指假设检验的第二类错误的概率
    4. Pr(M):置信区间
    5. σ2:本文中一般指总体方差
    6. s2:本文中一般指样本方差
    7. μ:本文中一般指总体平均值
    8. X:本文中一般指样本平均值
    9. H0:原假设,H0值等
    10. H1:备择假设
    11. t:t检验、T分布、t值等
    12. F:F检验、F分布、F值等
    13. z:z检验、z分布、z值等
    14. 2:卡方检验、卡方分布、卡方值等
    15. n:样本长度

    显著性水平

    显著性水平(通常用α表示)是在进行假设检验时事先确定一个可允许的概率作为判断界限的小概率标准。检验中,依据显著性水平大小把概率划分为二个区间,小于给定标准的概率区间称为拒绝区间,大于这个标准则为接受区间。事件属于接受区间,原假设成立而无显著性差异;事件属于拒绝区间,拒绝原假设而认为有显著性差异。

    通俗来讲,显著水平表示的是一个标准,即表示判断界限的小概率标准,往往显著性水平存在一定的人为因素,通常作为标准的小概率有0.1、0.05、0.01。有时人们也会使用显著性水平来检验假设是否成立,而用到的便是小概率事件。我们一般认为p-value≤0.05就可以认为假设是不成立的。0.05这个标准就是显著水平,当然选择多少作为显著水平也是主观的。

    对显著水平的理解必须把握以下二点:

    1. 显著性水平不是一个固定不变的数值,依据拒绝区间所可能承担的风险来决定。
    2. 统计上所讲的显著性与实际生活工作中的显著性是不一样的。

    显著性水平检验

    显著性水平检验属于假设检验的一种,应用的原理便是上面所说的显著性水平的原理,首先确定一个标准(即判断界限的小概率标准),一般取0.05(与后续的95%置信区间相对应)。当某个事件的发生概率小于这个概率时,事件属于拒绝区间,该事件具有显著性差异,拒绝原假设,即假设不成立。

    置信区间

    • 置信区间是指由样本统计量所构造的总体参数的估计区间。在统计学中,一个概率样本的置信区间是对这个样本的某个总体参数的区间估计。置信区间展现的是这个参数的真实值有一定概率落在测量结果的周围的程度,其给出的是被测量参数的测量值的可信程度,即前面所要求的“一个概率”。就拿捕鱼来说,一网下去,我知道里面有多少比例的鱼是我想要的鱼。
    • 点估计与区间估计:
    1. 点估计:点估计是用样本统计量来估计总体参数,因为样本统计量为数轴上某一点值,估计的结果也以一个点的数值表示,所以称为点估计。比如买彩票,你买了5号,那么就意味着你猜测5号一定会中奖。
    2. 区间估计:区间估计是在点估计的基础上,给出总体参数估计的一个区间范围,该区间通常由样本统计量加减估计误差得到。与点估计不同,进行区间估计时,根据样本统计量的抽样分布可以对样本统计量与总体参数的接近程度给出一个概率度量。仍然是上面的买彩票,你觉得中奖号在5号左右,然后你买了1号到10号10张彩票,那么就意味着你猜测着1号到10张中的某一张会中奖,使用的是点估计加减估计误差,很显然区间估计比点估计更准确。
    • 计算公式:Pr(c1<=μ<=c2)=1-α,其中α为显著性水平。
    • 95%置信区间:通常使用的较多的是95%置信区间,对应的α为0.05。一个样本服从X~N(μ,σ2)分布,其中μ为样本均值,σ2为样本方差;其95%置信区间可以按照如下方式计算(公式中1.96就是α=0.05时对应的标准值):
      在这里插入图片描述

    假设检验

    • 假设检验:指事先对总体参数或分布形式作出某种假设,然后利用样本信息来判断原假设是否成立,通常具有①采用逻辑上的反证法,②依据统计上的小概率原理等特点。
    • 假设检验的分类:
    1. 参数检验:参数检验指当总体分布已知的情况下,根据样本数据对总体分布的统计参数(如均值、方差等)进行推断,常用的参数检验有t检验、f检验、Z检验等;
    2. 非参数检验:非参数检验指当总体分布未知的情况下,根据样本数据对总体的分布形式或特征进行推断,常用的非参数检验有卡方检验、秩和检验等。
    • 两类错误:
    1. 第Ⅰ类错误(弃真错误):原假设为真时拒绝原假设,第一类错误的概率为α(α即显著性水平);
    2. 第Ⅱ类错误 (取伪错误):原假设为假时接受原假设,第二类错误的概率为β。
    H0是真实的H0是不真实的
    拒绝H0第Ⅰ类错误(α)正确
    接受H0正确第Ⅱ类错误( β)
    1. 两类错误的关系:α越大β越小,α越小β越大,因此无法同时减少两类错误,通常我们都是力求控制α的情况下减小β。
    • 假设检验的基本步骤:
    1. 提出原假设和备择假设
    2. 确定适当的检验统计量
    3. 规定显著性水平α
    4. 计算检验统计量的值
    5. 作出统计决策
    • 原假设与备择假设
    1. 原假设:待检验的假设,又称“0假设”,表示为H0,通常在假设中包含等号如=,≤,≥等;
    2. 备择假设:与原假设的对立的假设,表示为H1,通常在假设中包含不等号如≠,<,>等;
    • 双侧检验与单侧检验
    1. 双侧检验(双尾检验):只强调差异不强调方向性(比如大小,多少)的检验叫双尾检验。如检验样本和总体均值有无差异, 或样本数之间有没有差异,采取双侧检验。双侧检验的相关信息表示如下:
      在这里插入图片描述
    2. 单侧检验(单尾检验):强调某一方向的检验叫单尾检验。如当要检验的是样本所取的总体参数值大于或小于某个特定值时,采用单侧检验。单侧检验的相关信息表示如下:
      在这里插入图片描述
    3. 区别对比:
      ①双侧检验只关心两个总体参数之间是否有差异,而不关心谁大谁小;单侧检验则强调差异的方向性,即关心研究对象是高于还是低于某一总体水平。
      ②如果不清楚后测数据是否高于前测数据,研究目的是想判断前后测的均值是否不同,就需要用双尾检验;如果后测数据不可能低于前测数据,研究目的是仅仅想知道后测数据是不是高于前测数据,则可以采用单尾检验。
      ③双侧检验的研究假设是检验两参数之间是否有差异,零假设 H0: u1= u0,备择假设:H1:u1≠ u0;单侧检验的研究假设中有一参数和另一参数方向性的比较,比如"大于"(或“小于”)等。
    • 简单举例:
      在某次乒乓球赛中,对手提议通过抛硬币来决定谁先发球,“花”面朝上则对手先发球,反之则我。此时我认为这枚硬币是不公平的,而对手却说这枚硬币是公平的。这时我们可通过假设检验来验证这枚硬币是否公平。

      假设 :这枚硬币是公平的
      检验 :抛十次硬币,看是否符合假设。

      反复抛硬币符合二项分布X∼B(n,μ),其中n代表扔硬币的次数,μ代表“花”朝上的概率。在硬币是公平的前提下,扔10次硬币应该符合以下分布:X∼B(10,0.5)。
      总共扔了两次,都是“花”朝上,虽然几率是0.5x0.5 = 0.25,但是也正常,继续扔;总共扔了四次,也都是“花”朝上,几率是0.54=0.0625,感觉有点不正常,但是万一是运气呢?继续扔;总共扔了十次,也都是“花”朝上,那我就认为很可能你这枚硬币不是公平的。
      那么当我们抛10次硬币,当出现多少次“花”面朝上就可以认为该硬币是不公平的,这是一个客观的判断,我们可结合显著性水平检验来判断。例如,我们可以计算抛10次硬币出现9次“花”面朝上的概率来检验我们的假设是否成立,这一事件的概率为P(9≤X≤10)=0.01≤0.05,表示出来如下图所示:
      在这里插入图片描述
      该事件属于显著性检验的拒绝区间,有显著性差异,拒绝原假设,即该硬币不公平。如果扔10次出现出现8次正面:P(8≤X≤10)=0.05,这个和我们的显著水平是一样的,我们也可以拒绝假设,只是没有那么“显著”了。综上所述,当需要检验一枚硬币是否公平时,可以连续抛十次,当出现八次以上的“花”面朝上就可以认为该硬币是不公平的。

    参数检验

    参数检验的定义前面已介绍了,这里主要看一下几种常用的参数检验,包括t检验、f检验和z检验。

    F检验

    • F检验(也称方差比率检验、方差齐性检验)是一种在零假设之下,统计值服从F-分布的检验。其通常是用来分析用了超过一个参数的统计模型,以判断该模型中的全部或一部分参数是否适合用来估计母体。F检验可以用于三组或者多组之间的均值比较,但是F检验对于数据的正态性非常敏感,如果被检验的数据无法满足均是正态分布的条件时,该数据的稳健型会大打折扣,特别是当显著性水平比较低时。但是,如果数据符合正态分布,而且α至少为0.05,该检验的稳健型还是相当可靠的。
    • F检验的主要用途有①方差齐性检验,②方差分析,③线性回归方程整体的显著性检验。这里主要说一下第一点。方差齐性是方差分析和一些均数比较t检验的重要前提,利用[公式]检验进行方差齐性检验是最原始的,但对数据要求比较高,它要求样本来自两个独立的、服从正态分布的总体。方差齐性检验的 F 值计算方法如下:
      在这里插入图片描述
      在这里插入图片描述
      一般约定取较大的方差作为分子,较小的方差作为分母,计算出的F值与理论F值进行比较并得出结论。

    t检验

    • 主要用于样本含量较小(通常n < 30),总体标准差σ未知的正态分布,那么此时一切可能的样本平均数与总体平均数的离差统计量呈t分布。t检验是用t分布理论来推论差异发生的概率,从而比较两个平均数的差异是否显著。
    • t检验有以下三种方法(选取哪种t检验方法是由数据特点和结果要求来决定的):
    1. 单一样本T检验(One-Sample T Test):用来比较一组数据的平均值和一个数值有无差异。例如,你选取了5个人,测定了他们的身高,要看这五个人的身高平均值是否高于、低于还是等于1.70m,就需要用这个检验方法。
    2. 独立样本T检验(Independent-Sample T Test):用来看两组数据的平均值有无差异。比如,你选取了5男5女,想看男女之间身高有无差异,这样,男的一组,女的一组,这两个组之间的身高平均值的大小比较可用这种方法。
    3. 配对样本T检验(Paired-Sample T Test):用来看一组样本在处理前后的平均值有无差异。比如,你选取了5个人,分别在饭前和饭后测量了他们的体重,想检测吃饭对他们的体重有无影响,就需要用这个t检验。注意,配对样本t检验要求严格配对,也就是说,每一个人的饭前体重和饭后体重构成一对。
    • t检验分为单总体t检验和双总体t检验:
    1. 单总体t检验:检验一个样本平均数与一已知的总体平均数的差异是否显著。当总体分布是正态分布,如总体标准差σ未知且样本容量n<30,那么样本平均数与总体平均数的离差统计量呈t分布。检验统计量为:
      在这里插入图片描述
      如果样本属于大样本(n>30)也可以写成:
      在这里插入图片描述
      其中,t为样本平均数与总体平均数的离差统计量;X为样本平均数;μ为总体平均数;σx为样本标准差;n为样本容量。
    2. 双总体t检验 :检验两个样本平均数与其各自所代表的总体的差异是否显著。双总体t检验又分为两种情况,一是相关样本平均数差异的显著性检验,用于检验匹配而成的两组被试获得的数据或同组被试在不同条件下所获得的数据的差异性,这两种情况组成的样本即为相关样本。二是独立样本平均数的显著性检验。各实验处理组之间毫无相关存在,即为独立样本。该检验用于检验两组非相关样本被试所获得的数据的差异性。相关样本的t检验公式为:
      在这里插入图片描述
      其中,X1,X2分别为两样本平均数;σx12,σx22分别为两样本方差;y为相关样本的相关系数。

    Z检验

    • Z检验(在国内一般叫U检验)就是用服从正态分布N(0,1)的统计量Z来进行显著性检验。使用这种检验方法,必须先知道总体的方差σ2;Z检验一般用于大样本(即大于30)平均值差异性检验的方法,它是用标准的理论来推断差异发生的概率,从而比较两个的差异是否显著;当已知标准差时,验证一组数的均值是否与某个值相等时,用Z检验。
    • 原理:Z检验是通过计算两个平均数之间差的Z分数来与规定的理论Z值相比较,看是否大于规定的理论Z值,从而判定两平均数的差异是否显著的一种差异显著性检验方法。
    • 一般步骤:
    1. 建立虚无假设H012,即先假定两个平均数之间没有显著差异;
    2. 计算Z值,对于不同类型的问题选用不同的计算方式:
      ① 检验一个样本平均数(x)与一个已知的总体平均数(μ0)的差异是否显着。其Z值计算公式为:在这里插入图片描述
      在这里插入图片描述
      ② 检验两组样本平均数的差异性,从而判断它们各自代表的总体的差异是否显着。Z值计算公式为:
      在这里插入图片描述
      在这里插入图片描述
    3. 比较计算所得Z值与理论Z值,推断发生的概率,依据Z值与差异显着性关系表作出判断。
    Z值p值差异程度
    ≥2.58≤0.01非常显著
    ≥1.96≤0.05显著
    ≤1.96≥0.05不显著

    非参数检验

    卡方检验(✘2检验)

    • 卡方检验是一种用途很广的计数资料的假设检验方法,主要是比较两个及两个以上样本率(构成比)以及两个分类变量的关联性分析。根本思想在于比较理论频数和实际频数的吻合程度或者拟合优度问题,应用主要有①两个率或两个构成比比较的卡方检验;②多个率或多个构成比比较的卡方检验以及分类资料的相关分析。
    • 卡方检验计算原理:
      在这里插入图片描述
      其中:A是实际值,T为理论值,x2表示理论值与实际值的差异程度。
      然后查询卡方分布的临界值,将计算的值与临界值比较,如果x2 <临界值,则假设成立。
      查询临界值就需要知道自由度:V =(行数-1)*(列数-1),根据算出的V查询卡方分布表。
    • 举例:例如想知道喝牛奶对感冒发病率有没有影响(下表中括号内的为理论人数)。
    感冒人数未感冒人数合计感冒率
    喝牛奶组43(39.3231)96(99.6769)13930.94%
    不喝牛奶组28(31.6848)84(80.3152)11225.00%
    合计7118025128.29%

    喝牛奶组和不喝牛奶组的感冒率为30.94%和25.00%,两者的差别可能是抽样误差导致,也可能是 牛奶对感冒率真的有影响。

    下面进行假设:假设喝牛奶对感冒发病率没有影响,即喝牛奶与感冒无关,所以感冒的发病率实际是(43+28)/(43+28+96+84)=28.29%。

    根据上面的公式计算出x2=1.077,对于该问题V=1,查询可得临界值为3.84,x2=1.077<3.84,假设成立,即喝牛奶与感冒无关。

    秩和检验

    • 秩和检验又称顺序和检验,它不依赖于总体分布的具体形式,应用时可以不考虑被研究对象为何种分布以及分布是否以知,因而实用性较强,这种方法主要用于比较两个独立样本(两个样本可以不等长)的差异。
    • 秩和检验的优缺点:
    1. 优点:不受总体分布限制,适用面广;适用于等级资料及两端无确定值的资料;易于理解,易于计算。
    2. 秩和检验的缺点:符合参数检验的资料,用秩和检验,则不能充分利用信息,检验功效低。
    • 适用范围:两个样本来自两个独立的但非正态获形态不清的两总体,要检验两样本之间的差异是否显著,不应运用参数检验中的t+检验,而需采用秩和检验。
    • 两样本的容量长度均小于10的检验步骤:
    1. 将两个样本数据混合并由小到大进行等级排列(最小的数据秩次编为1,最大的数据秩次编为n1+n2);
    2. 把容量较小的样本中各数据的等级相加,即秩和,用T表示。
    3. 把T值与秩和检验表中 α 显著性水平下的临界值相比较,如果 T1 < T < T2,则两样本差异不显著;如果 T ≤ T1或 T ≥ T2,则表明两样本差异显著(T1 、 T2分别为两个样本长度对应的秩和检验表中 α 显著性水平下的值)。
    • 【例】某年级随机抽取6名男生和8名女生的英语考试成绩如下表所示。问该年级男女生的英语成绩是否存在显著差异?
      在这里插入图片描述
      ①建立假设:
      H0:男女生的英语成绩不存在显著差异;
      H1:男女生的英语成绩存在显著差异。
      ②编排秩序,求秩和T:T= 62.5;
      ③推断与结论:根据 n1 = 6, n2 = 8,α = 0.05查秩和表等检验的上下限位T1 = 29,T2 = 61;有T>T2,所以拒绝原假设,即男女生的英语成绩存在显著差异。
    • 两样本的容量长度均大于10的检验步骤:
      当两个样本容量都大于10时,秩和 T 的分布接近于正态分布,因此可以用Z检验,其基本公式为:
      在这里插入图片描述
      【例】还是前面的例子,不过这一次检验的是12个男生和14个女生,成绩如下表所示:
      在这里插入图片描述
      ①建立假设:
      H0:男女生的英语成绩不存在显著差异;
      H1:男女生的英语成绩存在显著差异。
      ②编排秩序,求秩和: n1 = 12, n2 = 14,T= 144.5,将 T 带入公式算 Z 值得Z = -0.9;
      ③推断与结论:α = 0.05,查表得 Zα = 1.96,|Z| < Zα,所以保留原假设,拒绝备择假设,即男女生的英语成绩不存在显著差异。

    常用的假设检验种类及使用的检验方法

    • 单总体均值的假设检验
    1. 总体方差σ2已知:z检验,检验统计量为:
      在这里插入图片描述
    2. 总体方差σ2未知:t检验,检验统计量为:
      在这里插入图片描述
    • 双总体均值差的假设检验
    1. 两总体均是正态分布,两总体方差已知:z检验(n可以小于30),检验统计量为:
      在这里插入图片描述
    2. 两总体均是正态分布,两总体方差未知但相等:t检验,检验统计量为:
      在这里插入图片描述
    3. 两总体分布未知:z检验(两个样本容量n都需要大于30),检验统计量为: 在这里插入图片描述
    • 单正态总体方差的假设检验:✘2检验,检验统计量为:
      在这里插入图片描述
    • 双正态总体方差之比的假设检验:F检验,检验统计量为:
      在这里插入图片描述
    • 汇总:在这里插入图片描述

    方差分析

    对于一到两组数据之间的总体均值的假设检验,使用T检验和Z检验就可实现,而对于两组以上的总体均值的假设检验则需要使用方差分析。当然对于三组及以上之间的总体均值的假设检验也可通过两两组合多次使用T检验和Z检验来实现,只不过比较麻烦,使用方差分析可以大大减少工作量,并且增强假设检验的稳定性。

    原理和相关术语

    【例】某公司采用四种方式推销其产品。为检验不同方式推销产品的效果,随机抽样得下表,不同的销售方式对销售量有影响吗?
    在这里插入图片描述

    • 方差分析的相关术语:
    1. 因素(Factor):因素是指所要研究的变量,它可能对因变量产生影响。在【例】中,要分析不同销售方式对销售量是否有影响,所以,销售量是因变量,而销售方式是可能影响销售量的因素。如果方差分析只针对一个因素进行,称为单因素方差分析。如果同时针对多个因素进行,称为多因素方差分析。本章后面也会介绍单因素方差分析和双因素方差分析,它们是方差分析中最常用的。
    2. 水平(Level):水平指因素的具体表现,如销售的四种方式就是因素的不同取值等级。有时水平是人为划分的,比如质量被评定为好、中、差。
    3. 单元(Cell):单元指因素水平之间的组合。【例】中销售方式一下的五种不同的销售业绩就构成一个单元。方差分析要求的方差齐性就是指的各个单元间的方差齐性。
    4. 元素(Element):元素指用于测量因变量的最小单位。一个单元里可以只有一个元素,也可以有多个元素。【例】中各单元中有 5 个元素。
    5. 均衡(Balance):如果一个试验设计中任一因素各水平在所有单元格中出现的次数相同,且每个单元格内的元素数相同,则称该试验是为均衡,否则,就被称为不均衡。不均衡试验中获得的数据在分析时较为复杂。【例】是均衡的。
    6. 交互作用(Interaction):如果一个因素的效应大小在另一个因素不同水平下明显不同,则称为两因素间存在交互作用。当存在交互作用时,单纯研究某个因素的作用是没有意义的,必须在另一个因素的不同水平下研究该因素的作用大小。如果所有单元格内都至多只有一个元素,则交互作用无法测出。
    • 方差分析的基本原理:将数据总的偏差平方和按照产生的原因分解成:(总的偏差平方和)=(由因素水平引起的偏差平方和)+(试验误差平方和);上式右边两个平方和的相对大小可以说明因素的不同水平是否使得各型号的平均维修时间产生显著性差异,为此需要进行适当的统计假设检验。上例中要看不同推销方式的效果,其实就归结为一个检验问题,设μi为第 i 种推销方式 i(i=1,2,3,4)的平均销售量,即检验原假设μ1234是否为真。

      从上【例】的表可以观察到,四个均值都不相等,方式二的销售量明显较大。然而,我们并不能简单地根据这种第一印象来否定原假设,而应该分析μ1、μ2、μ3、μ4之间差异的原因。20 个数据各不相同,这种差异可能由两方面的原因引起的:一是推销方式的影响,不同的方式会使人们产生不同消费冲动和购买欲望,从而产生不同的购买行动,这种由不同水平造成的差异,我们称为系统性差异;另一是随机因素的影响,同一种推销方式在不同的工作日销量也会不同,因为来商店的人群数量不一,经济收入不一,当班服务员态度不一,这种由随机因素造成的差异,我们称为随机性差异。

    • 两个方面产生的差异用两个方差来计量:

    1. 组内方差,即水平内部的方差,仅包含随机性差异;
    2. 组间方差,即μ1、μ2、μ3、μ4之间的总体差异,它既包含系统性差异,也包含随机性差异。
    • 进行方差分析,样本通常要符合以下假定:首先是各样本的独立性,即各组观察数据,是从相互独立的总体中抽取的,只有是独立的随机样本,才能保证方差的可加性;其次要求所有观察值都是从正态总体中抽取,且方差相等。

    单因素方差分析

    • 单因素方差分析的数据结构
      单因素方差分析的数据结构一般如下图所示:在这里插入图片描述
      在单因素方差分析中,若因素 A 共有 r 个水平,对均衡试验而言,每个水平的样本容量为 k,则共有 kr 个观察值,如上表所示。对不均衡试验,各水平中的样本容量可以是不同的,设第i个样本的容量是ni,则观测值的总个数为:
      在这里插入图片描述

    • 单因素方差分析的步骤

    1. 建立假设
      原假设和备择假设为:
      H0:μ123=……=μr
      H1:μ1、μ2、μ3、……、μr不全等。
    2. 构造检验F统计量
      方差分析表:在这里插入图片描述
      水平的均值:令xi为第 i 水平的样本均值,则
      在这里插入图片描述
      全部观察值的总均值:令x为全部观察值的总均值,则
      在这里插入图片描述
      总离差平方和(SST):反映全部观察值的离散状况,是全部观察值与总平均值的离差平方和计算公式为:
      在这里插入图片描述
      误差项离差平方和(SSE):又称为组内离差平方和,它反映了水平内部观察值的离散情况,即随机因素产生的影响计,算公式为:
      在这里插入图片描述
      水平项离差平方和(SSA):又称组间离差平方和,是各组平均值与总平均值的离差平方和。它既包括随机误差,也包括系统误差,计算公式为:
      在这里插入图片描述
      由于各样本的独立性,使得变差具有可分解性,即总离差平方和等于误差项离差平方和加上水平项离差平方和,用公式表达为:SST = SSE + SSA。
      根据方差统计表:F=组间方差 / 组内方差= MSA / MSE=[SSA /(r-1)] / [SSE /(n-r)]
    3. 判断与结论
      在假设条件成立时,F统计量服从第一自由度df1为 r-1、第二自由度df2为 n-r 的 F 分布。将统计量 F 与给定的显著性水平α的临界值Fα(r-1,n-r) 比较,可以作出决策,决策图如下:
      在这里插入图片描述
      若 F≥Fα,则拒绝原假设H0,表明均值之间的差异显著,因素 A 对观察值有显著影响;
      若 F<Fα,则不能拒绝原假设H0,表明均值之间的差异不显著,因素 A 对观察值没有显著影响。
      决策方式:一是用 F 与 F crit 比较,F>F crit,则拒绝原假设;二是用 P-value 与α比较,如果 P-value<α,则拒绝原假设。
    • 【例】对以下数据做方差分析,要求判断四种不同的推销方式对销量是否有影响。
      在这里插入图片描述
      当α=0.05时,分析结果如下(每个数值得含义可参考方差分析表):
      在这里插入图片描述
      决策:F>F crit,拒绝原假设,即μ1、μ2、μ3、μ4不全等,四种推销方式对销售量有显著影响。

    双因素方差分析

    • 双因素方差分析有两种类型:
      一种是无交互作用的双因素方差分析,它假定因素 A 和因素 B 的效应之间是相互独立的,不存在相互关系;另一种是有交互作用的方差分析,它假定 A、B 两个因素不是独立的,而是相互起作用的,两个因素同时起作用的结果不是两个因素分别作用的简单相加,两者的结合会产生一个新的效应。
    • 无交互作用的双因素方差分析
      方差分析表:
      在这里插入图片描述
      (一)数据结构
      设两个因素分别是 A 和 B。因素 A 共有 r 个水平,因素 B 共有 s 个水平,无交互作用的双因素方差分析的数据结构如下表所示:
      在这里插入图片描述
      (二)分析步骤
    1. 分析模型与建立假设
      在水平组合(Ai , Bj) 下的试验结果Xij服从 N ( μij , σ2 ),i = 1,2……,r;j = 1,2,……,s,假设这些试验结果相互独立。与单因素方差分析模型相类似, 令 μ 称为一般水平或平均水平,αi = μi - μ 称为因素A在第i个水平下的效应,βj = μj - μ 称为因素 B 在第 j 个水平下的效应。若μij = μ + αi + βj,则称这种方差分析模型为无交互作用的双方差分析模型,此时只需对(Ai , Bj) 的每种组合各做一次试验,观测值记为xij。把原参数μij变换成新参数 αi 和 βj后,无交互作用的双因素方差分析模型为:
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      两个影响因素的原假设与备择假设如下:
      对于因素A,H0A:μ123=……=μr;H1A:μ1、μ2、μ3、……、μr不全等。
      对于因素B,H0B:μ123=……=μs;H1B:μ1、μ2、μ3、……、μs不全等。
      我们检验因素 A 是否起作用实际上就是检验各个 αi 是否均为 0,如都为 0,则因素 A 所对应的各组总体均数都相等,即因素 A 的作用不显著;对因素 B,也是这样。因此上述假设等价于:
      对于因素A,H0A:α123=……=αr = 0;H1A:μ1、μ2、μ3、……、μr不全为0。
      对于因素B,H0B:β123=……=βs = 0;H1B:β1、β2、β3、……、βs不全为0。
    2. 构造检验统计量
      水平的均值:
      在这里插入图片描述
      总均值:
      在这里插入图片描述
      离差平方和的分解:双因素方差分析同样要对总离差平方和 SST 进行分解,SST 分解为三部分:SSA 、SSB和 SSE,以分别反映因素 A 的组间差异、因素 B 的组间差异和随机误差(即组内差异)的离散状况。它们的计算公式分别为:
      在这里插入图片描述
      为检验因素 A 的影响是否显著,采用下面的统计量(相关参数可查看方差分析表):
      在这里插入图片描述
      为检验因素 B 的影响是否显著,采用下面的统计量(相关参数可查看方差分析表):
      在这里插入图片描述
    3. 判断与结论
      根据给定的显著性水平α在 F 分布表中查找相应的临界值Fα,将统计量 F 与Fα进行比较,作出拒绝或不能拒绝原假设H0的决策。决策方式如下:
      在这里插入图片描述
      当然也可比较P-value与α的大小,原理同上。
      【例】某公司想知道产品销售量与销售方式及销售地点是否有关,随机抽样得下表数据,以 α = 0.05 的显著性水平进行检验。
      在这里插入图片描述
      首先针对问题,提出原假设和备择假设:
      对于因素A,H0A:μ1234;H1A:μ1、μ2、μ3、μ4不全等。
      对于因素B,H0B:μ12345;H1B:μ1、μ2、μ3、μ4、μ5不全等。
      根据以上步骤得出方差分析结果如下:
      在这里插入图片描述
      结论:
      FA ≥ Fα,拒绝原假设H0A,即销售方式对销售量有影响;
      FB < Fα,不能拒绝原假设H0B,即销售地点对销售量的影响不显著。
    • 有交互作用的双因素方差分析
      方差分析表:
      在这里插入图片描述
      (一)数据结构
      设两个因素分别是 A 和 B,因素 A 共有 r 个水平,因素 B 共有 s 个水平,在水平组合(Ai , Bj) 下的试验结果Xij服从 N ( μij , σ2 ),i = 1,2……,r;j = 1,2,……,s,假设这些试验结果相互独立。为对两个因素的交互作用进行分析,每个水平组合下至少要进行两次试验,不妨假设在每个水平组合( Ai, Bj) 下重复 t 次试验,每次试验的观测值用χijk表示,k=1,2,……,t ,那么有交互作用的双因素方差分析的数据结构如下表所示:
      在这里插入图片描述
      (二)分析步骤
    1. 分析模型与建立假设:
      与无交互作用双因素方差分析模型一样, 令 μ 称为一般水平或平均水平,αi = μi - μ 称为因素A在第i个水平下的效应,βj = μj - μ 称为因素 B 在第 j 个水平下的效应。若μij ≠ μ + αi + βj,则称这种方差分析模型为有交互作用的双方差分析模型,此时再令γij = μij - μ - αi - βj称为因素 A 的第 i 水平与因素 B 的第 j 水平的交互效应,且满足:
      在这里插入图片描述
      把原参数 μj 变换成新参数 αi、 βj 和 γij 后,有交互作用的双因素方差分析模型为:
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      这里i = 1,2……,r;j = 1,2,……,s;k=1,2,……,t ;,随机误差 εijk 相互独立,都服从N(0,σ2)的分布。与前面的分析思路相同,我们检验因素 A、因素 B 以及两者的交互效应是否起作用实际上就是检验各个 αi、 βj 和 γ~ij 是否都为 0,故对此模型要检验的假设有有三个:
      对于因素A,H0A:α123=……=αr = 0;H1A:μ1、μ2、μ3、……、μr不全为0。
      对于因素B,H0B:β123=……=βs = 0;H1B:β1、β2、β3、……、βs不全为0。
      对因素 A 和 B 的交互效应:H0C:对一切 i , j 有 γij = 0;H1C:对一切 i , j 有 γij 不全为零。
    2. 构建检验统计量
      水平的均值:
      在这里插入图片描述
      总均值:
      在这里插入图片描述
      离差平方和的分解:与无交互作用的双因素方差分析不同,总离差平方和 SST 将被分解为四个部分:SSA、SSB、SSAB 和 SSE,以分别反映因素 A 的组间差异、因素 B 的组间差异、因素 AB 的交互效应和随机误差的离散状况。它们的计算公式分别表示如下:
      在这里插入图片描述
      构造检验统计量:
      ①为检验因素 A 的影响是否显著,采用下面的统计量:
      在这里插入图片描述
      ②为检验因素 B 的影响是否显著,采用下面的统计量:
      在这里插入图片描述
      ③为检验因素 A、B 交互效应的影响是否显著,采用下面的统计量:
      在这里插入图片描述
      (三)判断与结论
      根据给定的显著性水平 α 在 F 分布表中查找相应的临界值 Fα,将统计量 F 与 Fα 进行比较,作出拒绝或不能拒绝原假设H0的决策。
      若 FA ≥ Fα(r -1,rs(t-1)),则拒绝原假设H0A,表明因素 A 对观察值有显著影响,否则,不能拒绝原假设H0A
      若 FB ≥ F α(s-1,rs(t-1)),则拒绝原假设H0B,表明因素 B 对观察值有显著影响,否则,不能拒绝原假设H0B
      若 FAB ≥ F α ((r-1)(s-1), rs(t-1)),则拒绝原假设H0C,表明因素 A、B 的交互效应对观察值有显著影响,否则,不能拒绝原假设H0C
      当然也可比较P-value与α的大小,原理同上。
      【例】电池的板极材料与使用的环境温度对电池的输出电压均有影响。今材料类型与环境温度都取了三个水平,测得输出电压数据如下表所示,问不同材料、不同温度及它们的交互作用对输出电压有无显著影响(α=0.05)。
      在这里插入图片描述
      首先针对问题,提出原假设和备择假设:
      对因素 A: H0A : αi = 0;H1A : αi 不全为零(i, j = 1,2,3);
      对因素 B: H0B : βj = 0;H1B : βj 不全为零(i, j = 1,2,3);
      对因素 A 和 B 的交互效应:H0C : γij = 0;H1C : γij不全为零(i, j = 1,2,3) 。
      根据以上分析步骤得出分析结果如下:
      在这里插入图片描述
    展开全文
  • 为什么编译原理被称为龙书?

    千次阅读 多人点赞 2020-07-17 08:32:21
    为什么这本书叫做 龙书(Dragon book)? 这本书很有意思,它的书名是 《Compilers: Principles, Techniques, and Tools》,也就是编译器的原则、技术和工具。但它却画出了一个恐龙和骑士,恐龙身上写的是 Complexity...
  • 创业公司做数据分析(四)ELK日志系统

    万次阅读 多人点赞 2017-01-07 00:54:07
      在上面的部署方案中,我们将Logstash分为Shipper和Indexer两种角色来完成不同的工作,中间通过Redis做数据管道,为什么要这样做?为什么不是直接在每台机器上使用Logstash提取数据、处理、存入Elasticsearch? ...
  • 数据挖掘与数据分析

    万次阅读 多人点赞 2018-05-28 13:58:14
    一、数据挖掘和数据分析概述 数据挖掘和数据分析都是从数据中提取一些有价值的信息,二者有很多联系,但是二者的侧重点和实现手法有所区分。 数据挖掘和数据分析的不同之处: 1、在应用工具上,数据挖掘一般要通过...
  • 网站数据分析指标体系

    千次阅读 2017-08-27 12:26:17
    标签: 郑来轶 数据分析 分析报告 数据报表 网站分析 分类: 03.数据分析 【编者注】网站流量统计,是指对网站访问的相关指标进行统计。本文整理自网友分享的一份 Word 文档,主要介绍了网站分析的 KPI 指标、...
  • 数据分析运营---A/B测试中20个必须知道的问题

    万次阅读 多人点赞 2017-04-29 23:49:08
    通过随机化和适当的实验设计,实验构建了科学的因果关系,这就是为什么对照实验(A/B测试)是药物测试的最高标准。 正是考虑到后验方法的局限,西医(现代医学科学)首先引入了 A/B 测试的方法来验证新药的疗效。...
  • 谢组学研究产生大量的数据,这些数据具有高维、小样本、高噪声等复杂特征。如何从复杂的代谢组学数据中提取出有价值的信息,筛选出潜在的生物标志物成为近年来代谢组学研究的热点和难点。据此,本文针对目前代谢组学...
  • 信息系统分析与设计课程心得

    万次阅读 多人点赞 2017-02-28 13:41:39
    信息系统分析与设计课程心得此博客信息系统分析与设计课程的学习心得记录。一、绪论1概念1.1信息要了解信息系统,首先要了解信息的概念。信息是我们理解世界的重要概念,我对它的定义是:信息是对客观事物及其相互...
  • 谷歌企业文化建设分析

    千次阅读 2017-12-05 17:09:35
    简要分析谷歌作为一家科技巨头的企业文化。
  • 科学研究设计六:有效威胁

    万次阅读 2017-11-18 08:46:51
    内部有效和外部有效
  • 应用程序设计语言的复杂性 应用程序设计语言的复杂性 文 / 周爱民 无论如何,工程师最终都要通过一个产品实现过程来满足用户的如下需求。 非功能性需求。 非当前需求。 这些是应用系统复杂性的主要构成。通常,...
  • 第06章 长尾的复杂性

    2020-03-18 15:43:47
    第06章 长尾的复杂性 6.1 多样性、差异性和渠道力量 《长尾理论》一书将形成长尾效应的原因概括多样性、差异性和渠道力量三个方面,但更根本的原因是深深隐藏于上述三个方面背后的知识和信息机制。更为完善的...
  • 3 从复杂到错综复杂 4 建立有效组织 第二部分:化繁简 5 建立互信和目标共享的团队 6 突破“深井”,建立关系 第三部分:信息共享 7 打造体系思维 8 共享意识 10 击败“囚徒...
  • 竞品分析 | 百词斩竞品分析报告

    千次阅读 2019-09-07 16:15:25
    在线英语的热度持续不下,很多新晋互联网新秀也纷纷涉足在线教育,据悉,字节跳动正在内测一款名“汤圆英语”的英语学习APP,旨在在线英语教学。字节跳动也想分得在线英语的一杯羹,更有大批量的老牌app也在不断...
  • HAWQ取代传统数仓实践(一)——为什么选择HAWQ

    万次阅读 多人点赞 2017-05-10 16:24:57
     TPC-DS针对具有各种操作要求和复杂性的查询定义了99个模板,例如点对点、报告、迭代、OLAP、数据挖掘等。成熟的基于Hadoop的SQL系统需要支持和正确执行多数此类查询,以解决各种不同分析工作场景和使用案例中的...
  • 机器学习模型可解释的详尽介绍

    千次阅读 2019-11-20 17:30:00
    机器之心平台来源:腾讯技术工程模型可解释方面的研究,在近两年的科研会议上成为关注热点,因为大家不仅仅满足于模型的效果,更对模型效果的原因产生更多的思考,这样的思考有助于...
  • 数据分析思路

    万次阅读 多人点赞 2018-09-14 16:08:06
    而大部分我们所购买的书基本都是某一类工具如何使用去进行数据分析,但是看完过后还是不太懂什么是数据分析,应用到实际工作场景中照样很迷茫不知道该如何下手,这是什么原因呢?有的小伙伴会说:我想分析的根本没有...
  • 【本章导读语】 模型可以澄清相互间的关系,识别出关键元素,有意识地减少可能 引起的混淆。 ________凯文.... SaaS系统包括SaaS平台及应用系统,SaaS系统的开发是个全面...现在的社会是个以市场导向的社会,市场决定
  • 商业分析报告编写

    千次阅读 2019-09-05 09:15:39
    1.1描述性分析 1.2数据透视 1.3可视化图表 2.数据挖掘分析:Python,SPSS,SAS,R 2.1协同过滤 2.2分类分析 2.3关联分析 2.4聚类分析等 3.大数据分析:Hadoop,Spark 3.1Hadoop大数据平台 3.2数据整理 3.3建模、分析...
  • 软件的可维护问题知识与分析

    万次阅读 2014-08-22 16:28:48
    这种经历往往并不像看起来那么简单——有时看懂,进而修改别人的少许代码,都会觉得老虎天——无从下手,究其原因主要是代码晦涩,关系复杂,难以隔离影响等。  而这时我们或者抱怨前人代码写的愚蠢,垃圾;或者又...
  • arcpy环境搭建

    千次阅读 2017-06-01 11:40:21
    目的是以实用高效的方式通过Python 执行地理数据分析、数据转换、数据管理和地图自动化创建基础。 该包提供了丰富纯正的 Python 体验,具有代码自动完成功能(输入关键字和点即可获得该关键字所支持的属性和方法的...
  • 软件工程需求分析方法

    千次阅读 2019-11-28 17:12:02
    详细介绍软件工程需求分析方法,转载自别处,
  • 数据分析常用的100个指标和术语

    千次阅读 多人点赞 2019-09-05 18:31:47
    3、数据分析名词解释 一、互联网常用名词解释 1、PV(Page View)页面浏览量 指某段时间内访问网站或某一页面的用户的总数量。通常用来衡量一篇文章或一次活动带来的流量效果,也是评价网站日常流量数据的重要...
  • 第二个,为什么要fork一个子进程来实现,直接while循环不可以吗?  解答:  (1)我们之所以使用execvp(),是因为函数的原型是 i nt execvp(const char *file ,char * const argv []); 第一个参数是命令...
  • 1. SWOT分析模型 「SWOT分析模型简介」 「SWOT模型含义介绍」 「SWOT分析步骤」 2. PEST分析模型 PEST分析的内容 3. 波特五力模型 [定义] [五力模型] 1. SWOT分析模型 「SWOT分析模型简介」 (也称TOWS...
  • 高中英语复杂语句分析

    千次阅读 2009-10-03 10:34:00
    高中英语阅读英语长难句分析方法内容: 阅读理解中有些难句子和长句子看不懂,请老师写一些难句子长句子并教我分析一下 答:在阅读中,我们经常会遇到一些长而难的句子。长难句通常含有较多、较长的修饰成分、并列...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 152,940
精华内容 61,176
关键字:

为什么内部环境分析具有复杂性