V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
princelai
V2EX  ›  问与答

关于 random.uniform 和 random.randn 出现极端情况导致随机漫步不正常

  •  
  •   princelai · 2016-06-03 16:26:58 +08:00 · 3799 次点击
    这是一个创建于 3098 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在用 python 模拟股价随机游走的时候使用过两种随机方法,在测试的时候都能生成[-10%,10%]之间的数,但是在绘图时就发现 uniform 方法有很大问题,直接看代码。

    方法 1-uniform

    def random_stock(N=4,size=1000):
        arr = []
        for j in range(N):
            np.random.seed()
            init = np.random.randint(5,100)#初始化价格
            l = [init]
            for i in range(size):
                np.random.seed()
                l.append(l[-1]*(1+np.random.uniform(-0.1,0.1)))#核心代码
            arr.extend(l)
        return np.array(arr).reshape(N,-1).T
    
    df = random_stock(4,1000)
    data = pd.DataFrame(df,index=pd.date_range(start='2012-1-1',periods=df.shape[0],freq='B'),columns=[s for s in 'ABCDEFGHIJ'[:df.shape[1]]])
    

    方法 2-randn

    def random_stock(N=4,size=1000):
        arr = []
        for j in range(N):
            np.random.seed()
            init = np.random.randint(5,100)#初始化价格
            l = [init]
            for i in range(size):
                np.random.seed()
                l.append(l[-1]*(1+np.random.randn()*0.027))#核心代码
            arr.extend(l)
        return np.array(arr).reshape(N,-1).T
    

    第二种方法绘图出来是没问题的,但是第一种方法绘图出来见贴图,这个图比较极端,四张图都出现这种情况,但是每次运行 100%会有一张图出现暴涨或暴跌后一蹶不振的情况(暴涨的话会从几十块一路涨到 800 块啊!), 60%概率出现 2 张图出现这种状况,亲吻出现这种状况是什么原因?

    12 条回复    2016-06-03 17:48:30 +08:00
    princelai
        1
    princelai  
    OP
       2016-06-03 16:27:34 +08:00
    skydiver
        2
    skydiver  
       2016-06-03 16:36:14 +08:00
    第二种方法绘图出来是什么样子的?
    princelai
        3
    princelai  
    OP
       2016-06-03 16:38:32 +08:00
    @skydiver
    就是这种很随机的波动,不是单边涨或跌
    skydiver
        4
    skydiver  
       2016-06-03 16:39:10 +08:00
    本来均匀分布和正态分布结果就不一样。也可以理解吧。

    而且看文档里

    Samples are uniformly distributed over the half-open interval [low, high) (includes low, but excludes high)

    所以均匀分布的时候实际上是不平衡的,所以更倾向于下跌
    princelai
        5
    princelai  
    OP
       2016-06-03 16:47:52 +08:00
    @skydiver
    ```
    tmp = np.random.uniform(-0.1,0.1,1000)

    In [80]: tmp.max()
    Out[80]: 0.099213124782427387

    In [81]: tmp.min()
    Out[81]: -0.099187629003319552

    In [84]: tmp.std()
    Out[84]: 0.057371789966341694

    In [85]: tmp.var()
    Out[85]: 0.0032915222839420251

    In [87]: tmp.sort()

    In [88]: tmp[499]
    Out[88]: -0.001321330606845611
    ```
    平均分布相比正态分布应该更多的涨停跌停,但事实上,只有跌停没有涨停啊
    Mutoo
        6
    Mutoo  
       2016-06-03 16:53:42 +08:00
    把 random.seed() 放在 for 里面本来就不是很好的作法。
    princelai
        7
    princelai  
    OP
       2016-06-03 16:55:21 +08:00
    @Mutoo 原来都不用 seed 的,我这是第一次,不知道该怎么用,我删除掉试试
    princelai
        8
    princelai  
    OP
       2016-06-03 17:23:51 +08:00
    @Mutoo 删除 seed 还是一样,运行了 3 次,一共 12 张图,还有 5 张出现一样情况,另一次出现暴涨,从不到 100 块涨到 1200 块了。。。。。
    skydiver
        9
    skydiver  
       2016-06-03 17:34:12 +08:00
    @princelai 我上面贴了的,是左闭右开区间……当然有跌停没涨停……
    princelai
        10
    princelai  
    OP
       2016-06-03 17:37:04 +08:00 via Android
    @skydiver 好吧也不纠结了,没想到一个开一个闭影响这么大,还是用正态分布了,也符合股市的分布
    Mutoo
        11
    Mutoo  
       2016-06-03 17:38:28 +08:00
    随机的范围是 1+(-0.1, 0.1) => 0.9 ~ 1.1
    若考虑只有 0.9 和 1.1 这两个离散的情况,且等概率出现,实验 2n 次,则必然有

    1 * (0.9^n) * (1.1^n) < 1

    也就是你亏掉 10%,下一次想要回本,必须要赚 11.1%,而不是 10%,因为你本金已经没那么多了。
    Mutoo
        12
    Mutoo  
       2016-06-03 17:48:30 +08:00
    这里随机的分布是正常的,问题在于你用的是乘法而不是加法。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5939 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 06:25 · PVG 14:25 · LAX 22:25 · JFK 01:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.