云中的数据科学

IPython 和 pandas 进行投资分析

数据科学日益专业化,可能涉及到以下许多主题:云计算、大数据、数学、业务理论和计算机科学理论。Python 之类的脚本语言往往是典型原型周期的最佳选择,可确保用数学知识来解决问题,然后将成果 “产品化” 到一个分布式云计算环境中。本文将介绍一些使用 IPython 和 pandas 进行投资分析和统计分析的实际示例。

Noah Gift, 创始人, GiftCS, LLC

Photo of Noah Gift Noah Gift 是 O'Reilly 出版的 Python For Unix and Linux System Administration 一书的合著者,并且现在还在为 Manning 编著 Google App Engine In Action 一书。他是一名作家、演说家、顾问和社区负责人,并为 IBM developerWorks、Red Hat MagazineO'Reilly 和 MacTech 撰稿。他的咨询公司的网站是 http://www.giftcs.com,他的个人网站是 http://noahgift.com。 Noah 拥有加州洛杉矶的 CIS 的硕士学位,加州 Poly San Luis Obispo 的营养科学学士学位,他还是通过 Apple 和 LPI 认证的系统管理员,他曾经在许多公司工作过,如加利福尼亚理工学院、Disney Feature Animation、Sony Imageworks 和 Turner Studios。他目前在新西兰的 Weta Digital 工作。在空闲的时候,他喜欢和妻子 Leah 以及他们的儿子 Liam 一起度过,谱写钢琴曲、参加马拉松比赛以及积极地参与体育活动。


developerWorks 投稿作者

2013 年 6 月 17 日

简介

让我们进行一个常见的分析,您可能自己就可以完成这个分析。假设您想分析股票绩效,那么您可以:

  1. 在 Yahoo 金融专区找一支股票。。
  2. 下载历史数据,保存为 CSV 文件格式。
  3. 将 CSV 文件导入 Excel。
  4. 进行数学分析:回归、描述性统计或使用 Excel Solver 工具进行线性优化。

很好,但本文为您展示一种更简单、更直观、功能更强大的方法,使用 IPython 和 pandas 进行同种分析。

IPython 库是使用 Python 的数据科学家的重要工具之一。该工具与 Excel 的最大不同在于,您可以使用它以交互方式探索来自某个交互式提示符的数据和分析。本文中的示例主要使用 IPython 作为机制来运行它们。

Python Data Analysis Library (pandas) 是一个拥有 BSD 许可证的开源库,为 Python 编程语言提供了高性能的、易于使用的数据结构和数据分析工具。

入门

在开始使用 IPython 和 pandas 时,需要设置您的 Linux 或 Unix 操作系统,如 Ubuntu 或 OS X。

  1. 安装 pip,pip 是一个用于安装和管理 Python 数据包的工具。您可能以前用过 easy_install,但 pip 现在已经取代了 easy_install。要安装 pip,请进入 Python 网站的 pip index 页面,按照说明进行操作。
  2. 在安装了 pip 之后,使用以下命令安装 IPython:
    sudo pip install IPython
  3. 使用 pip 安装 pandas:
    sudo pip install pandas
  4. 还有一个安装工具 — matplotlib,这是一个用于 Python 程序语言及其 NumPy 数值数学扩展的绘图库。请使用以下命令:
    sudo pip install matplotlib

现在已经执行了所需的所有步骤,让我们开始使用 IPython 和 pandas 吧!


Pandas 简介

将您的投资组合数据输入到 pandas 中,请使用以下代码:

清单 1. Pandas 组合数据的导入
    In [1]: import pandas.io.data as web
    
    In [2]: from pandas import DataFrame
    
    In [3]: data_feed = {}

    In [4]: symbols=['AAPL','FB', 'GOOG', 'SPLK', 'YELP', 'GG','BP','SCPJ','JNJ', 'OMG']
    
    In [5]: for ticker in symbols:
    ...:         data_feed[ticker] = web.get_data_yahoo(ticker, '05/21/2012', '11/1/2012')
    ...:
    
    In [6]: price = DataFrame({tic: data['Adj Close']
    ...:     for tic, data in data_feed.iteritems()})
    
    In [7]: volume = DataFrame({tic: data['Volume']
    ...:     for tic, data in data_feed.iteritems()})
    
    In [8]: returns = price.pct_change()

要确定年收益率百分比并进行分析,可以调用 return DataFrame 方法和 plot 方法。这可以通过调用 sum 对 DataFrame 中的各列求和来实现,该函数执行了大量工作来创建图 1 中所示的图表。

清单 2. 年收益率
    In [9]: import matplotlib.pyplot as plt
    In [10]: returns.sum().plot(kind='bar',title="% return For Year")
    Out[10]: <matplotlib.axes.AxesSubplot at 0x10c1b0350>
    In [11]: plt.show()

结果是:

图 1. 年收益率
年收益

图 1 所示,Facebook 进行了 IPO,并且年初至今它的损失接近 IPO 值的 40%。相比之下,Yelp(在同一个行业中)获利几乎为 40%。事后看来,卖空 Facebook 而买进 Yelp 几乎可以让原始投资翻倍。sum() 命令的文本输出在该代码中展示了年收益的实际原始值:

清单 3. 原始输出总和
    In [12]: returns.sum()
    Out[12]:
    AAPL    0.077139
    BP      0.155668
    FB     -0.376935
    GG      0.285309
    GOOG    0.124510
    JNJ     0.140735
    OMG     0.145005
    SCPJ    0.189855
    SPLK    0.021382
    YELP    0.357202

考虑数据的另一个方法是创建全年日收益率率变化的柱状图,了解这是否反映了数据的底层洞察。幸运的是,这非常简单,如下列代码所示:

清单 4. 创建一幅日收益率柱状图
    In [13]: returns.diff().hist()
    Out[13]:
    array([[Axes(0.125,0.677778;0.158163x0.222222),
    Axes(0.330612,0.677778;0.158163x0.222222),
    Axes(0.536224,0.677778;0.158163x0.222222),
    Axes(0.741837,0.677778;0.158163x0.222222)],
    [Axes(0.125,0.388889;0.158163x0.222222),
    Axes(0.330612,0.388889;0.158163x0.222222),
    Axes(0.536224,0.388889;0.158163x0.222222),
    Axes(0.741837,0.388889;0.158163x0.222222)],
    [Axes(0.125,0.1;0.158163x0.222222),
    Axes(0.330612,0.1;0.158163x0.222222),
    Axes(0.536224,0.1;0.158163x0.222222),
    Axes(0.741837,0.1;0.158163x0.222222)]], dtype=object)
    
    In [14]: plt.show()

清单 4 中的代码给出该图表:

图 2. 日收益率柱状图
日收益率柱状图

另一个查看数据的方法是记下日收益率并绘制年度线性图。下面的代码样例展示了如何操作:

清单 5. Pandas 投资组合相关性的年度线性图
    In [15]: returns.plot(title="% Daily Change For Year")
    Out[15]: <matplotlib.axes.AxesSubplot at 0x10b56e850>
    
    In [16]: plt.show()

结果如下:

图 3. 柱状图日收益率作为线性图表
柱状图日收益率作为线性图表

这种简单图表存在的问题是不太容易理解图中的信息。处理时间系列数据的方法是使用 cumsum 函数,将数据绘成图表。

清单 6. 累计和
In [17]: ts = returns.cumsum()

In [18]: plt.figure(); ts.plot(); plt.legend(loc='upper left')
Out[18]: <matplotlib.legend.Legend at 0x10c69cb50>
    
In [19]: plt.show()

图 4 所示的结果告诉了我们关于您的投资组合的更多信息。通过进行时间系列分析并绘制结果图标,Facebook 显然面临着比原来想象的更加困难的时刻,年收益下降了 40%,九月份甚至一度下降了 60%。有关股票走势的其他数据表明,Facebook 的标准偏差相当高。因为标准偏差是风险的大致表现,所以,在制订该组合并确定权重时,应重点关注这个地方。

图 4. 投资组合累积和
投资组合累积和

确定十种股票间百分比变化的相关性与调用 DataFrame 收益 corr 的方法一样简单。

清单 7. Pandas 组合相关性的百分比变化
    In [9]: returns.corr()
    Out[9]:
            AAPL        BP        FB        GG      GOOG       JNJ       
                      OMG      SCPJ      SPLK      YELP
    AAPL  1.000000  0.169053  0.094286  0.134131  0.376466  
                      0.163904  0.411568  0.117152  0.368266  0.124856
    BP    0.169053  1.000000  0.011832  0.294994  0.291391  
                      0.437816  0.436781 -0.009499  0.224151  0.084014
    FB    0.094286  0.011832  1.000000 -0.065156  0.081912  
                      0.020755  0.130815  0.039980  0.038010  0.343646
    GG    0.134131  0.294994 -0.065156  1.000000  0.302844  
                      0.138329  0.206255 -0.066144  0.148690 -0.006135
    GOOG  0.376466  0.291391  0.081912  0.302844  1.000000  
                      0.144882  0.305486 -0.001538  0.226364  0.154207
    JNJ   0.163904  0.437816  0.020755  0.138329  0.144882  
                      1.000000  0.268308  0.021108  0.190023 -0.009803
    OMG   0.411568  0.436781  0.130815  0.206255  
                      0.305486  0.268308  1.000000  0.117257  0.279653  0.146944
    SCPJ  0.117152 -0.009499  0.039980 -0.066144 -
                      0.001538  0.021108  0.117257  1.000000 -0.017114  0.058541
    SPLK  0.368266  0.224151  0.038010  0.148690  0.226364  
                      0.190023  0.279653 -0.017114  1.000000  0.215260
    YELP  0.124856  0.084014  0.343646 -0.006135  0.154207 
                    -0.009803  0.146944  0.058541  0.215260  1.000000
    In [58]: plt.show()

投资组合理论

到目前为止,分析已变得十分简单。投资分析通常包含确定一个可以 “击败市场” 的最佳组合。市场通常是指标准普尔 500 指数。没有确定的证据表明互惠基金可以通过技术(而不是运气)击败市场。您可以通过指数基金的消极投资击败大部分互惠基金,这对您是十分有利的,因为绝大多数的共同基金无法年复一年地击败市场投资组合。

尽管事实证明,由一批数学博士、火箭科学家及拥有数十亿美元国会成员组成的经过培训的专业人员也无法击败市场,让我们在空闲时试用 pandas 来处理这个问题。第一步是了解您的组合如何与市场投资组合(标准普尔 500 指数)进行较量。

清单 8. SPY 的累积时间图
        In [116]: market_data_feed = {}
        
        In [117]: market_symbols=['SPY']
        
        In [118]: for ticker in market_symbols:
        .....:         market_data_feed[ticker] = web.get_data_yahoo
                      (ticker, '05/21/2012', '11/1/2012')
        .....:
        
        In [119]: market_price = DataFrame({tic: data['Adj Close']
        .....:     for tic, data in market_data_feed.iteritems()})
        
        In [120]:
        
        In [120]: market_volume = DataFrame({tic: data['Volume']
        .....:     for tic, data in market_data_feed.iteritems()})
        
        In [121]: 
        
        In [121]: market_returns = market_price.pct_change()
        
        In [122]: market_returns.cumsum()
        In [123]: mts = market_returns.cumsum()
        
        In [124]: plt.figure(); mts.plot(); plt.legend(loc='upper left')
        Out[124]: <matplotlib.legend.Legend at 0x10b8f4650>
        
        In [125]: plt.show()

该示例中,创建了另一个 DataFrame,在同一时间周期内,它可以充当您的 “市场投资组合”。图 5 中的图表展示了 SPY 生成的收益率,SPY 是标准普尔 500 指数的代理。

图 5. SPY 生成的收益率
SPY 生成的收益率的图表

在完成两个时间系列的图表后,下一步分析是查看与市场投资组合相对的产品投资组合。两种临时应急的方法是 (a) 查看您的组合与市场投资组合的平均收益率,(b) 查看标准偏差 (stdev),这是一种关于您的投资组合与市场投资组合的大致风险代理。

清单 9. 战胜股市
In [126]: sum_returns = returns.sum()
In [127]: sum_returns.mean()
Out[127]: 0.11198689337482581
In [128]: market_returns.sum().mean()
Out[128]: 0.093679854637400028
In [239]: market_returns.std()
Out[239]:
minor
SPY      0.008511        
In [240]: returns.std().mean()
Out[240]: 0.025706773344634132

结束语

清单 9 的最后交互示例中,您可以通过 11% 的投资组合收益率与 9% 的市场投资组合收益率来战胜股市。在启动对冲基金之前,您可能需了解为什么市场投资组合获得 8% 的标准偏差,而您的投资组合只获得了 2% 的标准偏差。快速回答是,您冒了较大风险,而且只是幸运罢了。进一步的分析涉及到确定 alpha、beta、预期收益,以及进行 Fama-French 和有效边界优化之类的高级分析。

本文中,Python 用于执行临时应急的投资组合分析。Python 逐渐变成用于真实数据分析的首选语言。Pyomo、pandas、Numpy 和 IPython 之类的库使得在 Python 中应用高级数学知识变得更加轻松。如果您想了解更多关于投资组合分析的信息,请参阅 参考资料 中的阅读建议。


下载

描述名字大小
CSV 文件和源代码src.zip6.30KB

参考资料

学习

获得产品和技术

  • 下载 pip 并用于安装 IPython。
  • 以最适合您的方式 评估 IBM 产品:下载产品试用版,在线试用产品,在云环境下试用产品,或者在 SOA 沙盒 中花费几个小时来学习如何高效地实现面向服务的架构。

讨论

  • 加入 developerWorks 中文社区。探索由开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户进行交流。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Cloud computing, Open source
ArticleID=934165
ArticleTitle=云中的数据科学
publish-date=06172013