2016年12月30日 星期五

R學習筆記 - 資料工程篇(二) XML

#註: 本篇筆記諸多內容直接紀錄課程原文,而本文也僅整理資訊之用途
課程連結 : R語言翻轉教室

RDataEngineer-02-XML
XML的全名是:eXtensible Markup Language,是一種讓電腦可以快速理解資訊的標記語言。XML的透過標記來讓電腦理解資訊的內容,並且把標籤與內容清楚的切割開。

XML的文件中,標籤是可以有結構關係的。在慣例中,我們會說tr是th的父標籤(parent),而th與td兩者都是tr的子標籤(children)| 每個標籤最多只有一個父標籤。這是因為th和td兩個標籤,寫在<tr>和</tr>之間。


在HTML網頁中,幾乎所有的標籤都有父標籤,除了html這個標籤以外。所以我們在處理HTML文件時,會稱呼這個標籤為整個文件的根(root)。


更多瞭解可以輸入wiki_html()wiki_xml()了解更仔細的背景知識。


主要使用R套件 : xml2 

xml2套件要處理XML或HTML文件之前,必須要先作解析,將文件建立成一種特殊的R 物件後,才能讓我們挖掘資訊。

#挖掘網頁資訊的三步驟:
1. 找到標籤 2. 查詢屬性 3.檢查內容

1.read_xml   :  讀取xml檔,
`read_xml`函數有`x`、`encoding`和其他參數可以使用。 `x`則可以是一個檔案路徑(filepath)、一個網址(url),或是一個XML文本的字串向量(literal xml)。

目前xml2中的物件,大致上可以分成三種:xml_document、xml_node和xml_nodeset。 xml_document就代表整個XML文件。xml_node則對應到上述介紹的XML標籤,在經過`read_xml`後每個標籤會被轉化為一個xml_node。xml_nodeset則是一群標籤的集合。


2.xml_find_all
共有兩個參數:`x`與`xpath`。`x`可以是xml_document、 xml_node或xml_nodeset。而`xpath`(XML Path Language)則是一種特別的格式,讓我們可以和電腦溝通我們要搜尋的標籤。

#範例:xml_find_all(doc1, "/a/b")
 =>  a: 父標籤  b:子標籤

若沒有提供父標籤,無法搜尋出欲搜尋之子標籤

3.xml_text( ) 
取出標籤內的內容

4.xml_parent() 
查詢標籤的父標籤

5.xml_contents() :
同樣為取出標籤內容,但當含有子標籤時, 它和`xml_text`的行為會不太一致


6.xml_children(a) :
來取得所有以a 為父標籤的標籤們


7.xml_attrs() :
取得XML標籤的屬性(帶有名字的字串向量
)
在使用XPath尋找標籤時,屬性是可以派上用場的。

#範例
`
xml_find_all(doc1,
"/a/c[@class]")`,意即是搜尋時增加:「標籤必須要帶有 名稱為"class"的屬性」。


甚至還可以指定屬性的值,例如:`xml_find_all(doc1, "/a/c[@class='g']")


一種XPath中常常使用的定位方式 :  "//"


這裡的"//"代表的就是任意位置。

當我們在處理複雜的網頁資料時,如果每次都要從根部尋找正確的路徑,是非常不方便的。此時,透過"//a",我們就可以找到在所有位置都出現的a標籤。# "//"的用法是可以搭配屬性的過濾使用的。

#HW:

1. browseURL() : 輸入URL網址即可使用預設瀏覽器,瀏覽網頁

2. read_html() : 載入網頁內容
3. encoding() : 告訴電腦,應採用哪種編碼讀取該物件
範例:  Encoding(ths_text) <- "UTF-8"

#備註:
最後再次推薦R語言翻轉教室,做作業時遇到瓶頸,可直接在線上討論區直接發問,不至於自己一個人想破頭,卻無法得到解答。

2016年12月29日 星期四

R學習筆記 - 資料工程篇(一)Parsing 字串處理

#註: 本篇筆記諸多內容直接紀錄課程原文,而本文也僅整理資訊之用途)
課程連結 : R語言翻轉教室

RDataEngineer-01-Parsing

在實務上,數據來源常常都是隱含某些規則的文字檔案。例如:伺服器依據工程師擬定的規則所產生的資料。這個規則可能是工程師自己訂的,也可能是符合眾人智慧所訂定的規範。但是不管是工程師自己的想法,或是眾人的智慧,R 都能從文字中萃取出資訊。一般而言,這樣的技術就稱作Parsing。


[複習上一篇的內容]
如何正確輸入中文資料檔?

1.先用`readBin`來看檢查這個檔案的BOM

readBin(目標檔案,what = "raw", n=3)

2.根據常用BOM連結查詢可能的編碼


3.當BOM不能判斷的時候,採用試誤法,使用各種Encoding讀個前3行試試看。


readLines(file(hospital_path, encoding = "各種編碼"), n = 3)

4.搭配`read.table`和`file`兩個函數的組合,並適當的設定`sep`、`header`和`encoding`等參數。


read.table(目標位址,fileEncoding = "編碼",header = TRUE,seq=",")


1..擷取內容

1.substringR 的`substring`函數會把`text`參數所代表的字串,依照字符的位置,擷取出中間的段落。
2.strsplit: 利用定位點將字串分割成兩部分。

根據說明文件,`strsplit`會利用`split`參數來切割`x`這個字串,並且回傳一個`list`。這是因為`x`的長度可能超過1,而`strsplit`會用`split`去切割每一個`x`的元素。而切割出來的結果,第一個元素可能切出兩段,但是第二個元素可能只切出一段。所以R 用`list`這個結構來處理。但是`strsplit`並不接受factor參數,只接受字串向量。
範例

2.處理輸出資料
為了處理輸出後的list結構資料,重複性的工作可使用lapply函數增加效率

R 的`lapply`的第一個參數`X`,通常是一個vector。第二個參數`FUN`,則是代表一種「動作」。而`lapply`會對每一個`X`的元素進行`FUN`所定義的動作,並且把結果彙整回R 。最後一個`...`的參數是什麼意思呢?這是因為`lapply`並不清楚`FUN`需要什麼參數,所以使用者可以在指定`X`和`FUN`之後,放入任意的參數,而這些參數並不是由`lapply`所使用,而是由`FUN`所使用。

#範例 :
lapply(tmp,"[",1) => tmp:目標檔案、"[" 為[]函數之呼叫方式、1則代表輸出方式


接著,若輸出資料為list結構,可使用unlist(),取得字串向量類似的函數如sapply,功能相同,差別只在於輸出為array。

2016年12月27日 星期二

R學習基礎筆記(二)Arrays-Matrices、List-DataFrame、Loading-Dataset

(註: 本篇筆記諸多內容直接紀錄課程原文,而本文也僅整理資訊之用途)
課程連結 : R翻轉課程連結

RBasic-05-Arrays-Matrices

這門課程是要介紹R 的線性代數運算系統。線性代數在許多現代的統計方法、Data Mining方法上都很重要。所以理解R 的線性代數系統,對於撰寫自己的演算法,以及了解Open Source的演算法,是非常重要的。

[矩陣介紹]
數學上來說,一個矩陣除了值之外,需要的就是維度的定義。而`matrix`這個函數,`data`的參數代表矩陣的值, `nrow`的部份代表這個矩陣有多少列,而`ncol`的部份代表這個矩陣有多少行。所以`matrix(1:18,6, 3)`會產生一個 6 列3 行(簡稱6 乘3 )的矩陣。

dim() : 可以存取矩陣維度的函數。可透過dim來更改矩陣維度。
在R 中,矩陣的資料順序是:`c(x[1,1], x[2,1], x[3,1],...)`。也就是說,如果我們下指令:`matrix(1:18, 3, 6)`, 則x[1,1]會是1, x[2,1]會是2, x[3,1]是3, x[1,2]是4, 以此類推。高維度的矩陣也是類似。我們也可以利用中括號`[]`搭配邏輯向量取出矩陣或陣列中的值。
R會根據邏輯向量在`[]`中的位置,選擇該維度,只挑出該邏輯向量為TRUE 的座標。

[如何修改矩陣和陣列的元素]
1.要修改矩陣的值,搭配`[]`和`<-`

[矩陣運算]
1.矩陣的向量式運算。它和向量的運算也非常類似,也是會自動比對位置,並且在相同運算的位置上做運算
2.而當維度不相同的時候,R會自動重複比較短的那邊。
3.所有的矩陣和陣列,就是一般的向量加上 dim 這個屬性
4.除去dim屬性 : dim(x) <- NULL ,矩陣即變成向量
5.R在陣列和向量的向量式運算,也可以回到兩個向量的運算。差別只是在它們多了維度的屬性,所以當維度差異太大的時候,R會認為向量式運算無效。所以一般來說,我們只會拿單值或向量去和陣列做運算,或是維度相同的矩陣或陣列做運算。
6.在R 中,使用`cbind`和`rbind`則可以合併兩個矩陣。

[線性代數相關]
1.在R 中兩個矩陣要作矩陣乘法,就是使用`%*%`這個運算符號。
2.當兩個向量使用`%*%`做運算,會得到他們的內積。
3.轉置矩陣 : t()
4.用`diag`快速建構對角化的矩陣
5.如果已知` A %*% x = b `,給定`A` 和`b` 我們可以用`solve` 解出 x
6.反矩陣:solve(矩陣)
7.特徵值(eigenvalues)和特徵向量(eigenvectors) : eigen(矩陣)

*註:
R 上的線性代數運算的底層是透過BLAS等函式庫做運算的,所以效能遠勝過我們自己用C寫的線性代數運算。 另外R預設是使用比較被廣泛驗證過正確性的BLAS庫,而不是效能比較快,但是還比較年輕的BLAS函式庫,例如OpenBLAS。這是因為,R coreTeam認為正確性比較重要,所以目前是採用比較舊,但是也比較可靠的BLAS庫。

*HW:

求最小平方法之估計beta : solve(t(X)%*%X)%*%t(X)%*%y

RBasic-06-List-DataFrame

LIST

list的本質,就是一個「R物件的向量」,強調「向量」的概念,因為list 是有順序性的。
1.取list的方法
1.1 使用[[]]
1.2 list$,使用`$`來透過名字取出list的值

在windows上,如果名字是中文時,使用`$`的語法可能會出錯。一個比較保險的方式是:x$`中文名稱` 。這裡的 ` 符號的按鍵,在美式鍵盤中位於1的左方,這個符號唸作:Grave accent,是R 在console中的跳脫字元。以特殊符號 為名稱的變數,可以透過兩邊包覆Grave accent來在console中存取。

DataFrame

傳統的matrix和array由於有同質性的限制(所有的元素都要同樣的型態),所以在資料分析上並不方便。因為我們分析的資料,通常都不會全部都用相同的型態。在結構化的資料中,通常資料是以表格的形式,而各欄位會有自己的型態,例如是:數值型態、類別型態等等。

1.data.frame是一種list。因為表格的各欄是型態不一的向量,所以我們需要用list來裝不同型態的向量。
2.因為表格的資料是結構化的,所以data.frame的值不能存放太奇怪的物件。具體來說,data.frame的各個元素必須是以下幾種類型之一:數值(numeric)、字串(character)、布林(logical)、類別(factor)、數值矩陣(numeric matrix)、 list或data.frame
3.data.frame代表的是二維表格,所以每一個值的長度都要一致(矩陣或data.frame的話,則是列(row)的個數)。
4.在data.frame上,通常會先對欄位做選擇,取得欄位中的向量以後,才能使用中括號。
5.其實`[]`中括號這個函數,有一個參數叫做:`drop`,而且預設為`TRUE`。當我們使用`[]`取得結果的時候,如果有一個方向可以縮減維度(例如只有一個欄位的表格),R就會自動把表格的結構破壞,回傳一個向量。

*HW:
1.可以利用`model.matrix`來建立一個矩陣,類別變數若僅有兩種變化,可自動用1,0表示。
2.跑迴歸分析,可以簡單用`lm`這個函數
3.summary(g)則會顯示各個參數的t 檢定,以及整個模型的R-squared

RBasic-07-Loading-Dataset

[內建資料]
R 內建有許多知名的資料集。這些內建的資料集,目前都在`datasets`這個套件之中。
1.呼叫內建資料: data( 資料名, package = "datasets")
2.查詢內建資料詳細內容 :help(資料名)

[外部資料]
讀取中文資料的幾種方式,
此處僅介紹csv。

1.csv 檔的格式是以行(Line)為單位。每一行(Line)就是一筆紀錄(Record)。而每一筆紀錄中,是以一個分隔符號來讓使用者或程式分辨欄位。常見的分隔符號有: tab (\t)或逗號(,) 。

2.載入中文資料常見的編碼問題,參考以下連結
影片教學 :  什麼是編碼?

3.測試檔案編碼
3.1 檢查檔案有沒有BOM:
BOM是一種利用檔案最前面的2 個或 3 個位元組來標示檔案編碼的方式,在windows底下建立的中文檔案, 有很高的機會會帶BOM 。
readBin(lvr_land.path, what= "raw", n = 3)
 R 中的`readBin` 是一個很可以直接讀取檔案中的位元組的指令 ,所以可以正確的處理BOM。第一個參數是檔案的路徑。第二個名稱為 what的參數,是告訴R要如何處理讀入的資料。`what = "raw"`代表讀入的資料用位元處理,而不是文字。第三個名稱為n 的參數,代表要輸 入的長度。這裡選`n =3` 是因為通常BOM 最多就是3 個位元組。
接著查詢 常用的BOM,觀看是否出現常用編碼。

3.2使用`file`搭配`readLines`
如果讀出來的中文可以正常顯示,通常我們就猜中編碼了。如果讀出亂碼,或是讀取發生錯誤,那可能就猜錯了,就換個編碼猜猜看。
e.g. readLines(file(lvr_land.path, encoding = "BIG5"), n = 1)
n = 讀取行數

3.3使用file()搭配read.table()
read.table(file(目標位址, encoding = "BIG5"), sep = ",", header =TRUE)

#註:`file`函數會建立一個代表檔案的物件,在R 之中叫做`connection`。 R會不定時的關閉不使用的connection,並且在console 顯示警告訊息。
所以之後同學會不定時的看到:`closing unused connection`。

4. 使用readBin +  stringi 讀取外部資料
4.1
R 是型態為raw 的向量來處理位元的物件。只要能知道檔案的大小, readBin就可以把所有的檔案資料以raw 的形式輸入到R 中。
可以使用`file.info`來查詢檔案的大小 。
lvr_land.info =  file.info(檔案路徑)
lvr_land.bin = readBin(lvr_land.path ,what = "raw", n= lvr_land.info$size)
lvr_land.info$size = 該檔案大小

4.2
透過stringi套件的`stri_encode`,我們可以把一個位元組的向量(在 R中,這類向量的型態是raw )從一個編碼轉換為另一個編碼。
lvr_land.txt <- stri_encode(lvr_land.bin, "BIG-5", "UTF-8")

5.read.table  讀取CSV 格式檔案最泛用的指令
read.table( 路徑, fileEncoding = "BIG-5")
 fileEncoding 這個參數雖然可以解碼,但只能用在file參數為字串的case。
註1:在中文版windows 上預設會使用BIG5編碼,
註2:header = TRUE`代表檔案的第一行是欄位名稱,而不是資料。`header=FALSE`代表檔案的第一行就是資料。
seq = 分隔符號

5.1 我們可以用`l10n_info()`來查詢作業系統對於各種Encoding的支援狀況

根據經驗,如果`l10n_info()`的輸出中,MBCS為TRUE且UTF-8 為FALSE,則要使用:`textConnection(lvr_land.txt)`來從`lvr_land.txt`建立一個connection。除此之外,則使用`textConnection(lvr_land.txt, encoding = "UTF-8")`

6如果要使用R 讀取XML 的資料,可以使用套件XML 。如果要讀取JSON, 可以使用rjsonlite。只要資料格式是公開格式,我們很容易找到R 的套件來 讀取該資料格式。這就是R 是Open Source 的威力!

2016年12月25日 星期日

R學習基礎筆記(一) Introduction、Vectors、Object、Factors

前言:
過去筆者使用SAS和R來跑論文的資料處理與分析時,因為沒有一個系統性的筆記來整理所學,總覺得知識相當拼湊、零碎,所查詢到的應用最後都變成一個個超連結紀錄在我的最愛。近日,偶然在網路上發現R翻轉教室的線上課程套件,是一個相當適合有點R程式基礎、卻不知道如何再進階的人。藉由紀錄所學,希望將R做個有系統的學習紀錄。
(註: 本篇筆記諸多內容直接紀錄課程原文,而本文也僅整理資訊之用途)


RBasic-01-Introduction

1.help(函數) 、 ?函數
可直接獲得一個函數的細節說明
2. expression、assignment
在R中每一段指令分為expression、assignment ( a <- 1 )兩種
使用 {} 將多個expression包裹,即變成一個大的expression。
3.source()
透過`source`指令,來載入一個撰寫R指令的文件,並且執行文件中的expressions。
4. objects()
object可以是一個變數,也可以是一連串的數字,文字,甚至是函數,以及 更複雜的東西。
使用 objects() 、ls()來列出目前存在的object
5.rm() : 刪除存在之物件

RBasic-02-Data-Structure-Vectors

1.R 的object結構是針對資料分析所設計的。所以最簡單 的object,就是一連串的數字。在R 中,大部份的運算都是向量式的。舉例來說,加法`+`在R 就是向量式。 結果的第一個值,就是輸入的兩個向量的第一個值的相加。

1.1向量式運算:
+-*/ 、log、exp、sin、cos、tan、sqrt
1.2非向量式運算 : 
max()、min()、range():回傳向量的範圍(最大到最小)
sum():加總、length():回傳個數、mean()樣本平均數、var()樣本變異數、sd()樣本標準差、sort()回傳與原向量相同長度的向量,但值由小排到大。
NaN (not a number)
NA (not available)
Inf (無限)
可以利用`is.na`來判斷一個向量裡面有沒有NA,雖然我們理解NA和NaN的不同,但是`is.na`會把兩者都看成TRUE。

2. : 運算子,可提供指定數字的序列,如產生1到10,1:10。在R中的優先處理順序高於+-*/。與seq()函數功能相同,如seq(1,10)。seq(to = 起點,from = 終點, by = 如何間隔, length.out = 產出個數)
不想要序列,僅想要重複值可使用rep(值, times = 重複次數,each = 每個重複次數)

3.邏輯值  TRUE(T)、FALSE(F) ,注意T、F非保留字,可自行更改。
類似可用於建立邏輯向量的「條件」有:大於`>`、大於等於`>=`、
小於`<`、小於等於`<=`、相等`==`和不相等`!=`。
「交集」`&`和「聯集」`|`

4.字串
有時候,我們需要處理文字類型的object。這些object常常用於指定繪圖的標題、或是處理一些類別形變數,如:國籍、行政區等等。 這樣的資料,在R之中是透過單引號`'`或雙引號`"`來建立的。 這類的資料,常常被人稱為:「字串」。
`x`而不用雙引號包覆它,R 會把這個`x`當成變數名稱,輸入一個包含雙引號的字串,可使用單引號`'`來包覆雙引號。
paste():將字串接成一個字串,是向量化的函數
paste0():將字串接成一個字串(無空格)

5.指定資料位址
5.1 使用vector搜尋 x[c(1,3)]
5.2 邏輯搜尋 x[x >5]
5.3 消去法 x[-2] 除了第二個值以外的
5.4 使用names()為所有值取名,x[c("值的名字)]
HW:
`7e9`是R 的科學符號,代表`7 * 10^9`

RBasic-03-Data-Structure-Object

1.`mode`和`length`
在R 中,我們操作的所有變數,都是一種R 物件(Object)。這些向量物件有兩個很重要的屬性:`mode`和`length`。`mode`代表這個向量的值型態,總共有:`logical`、`integer`、`numeric`、`complex`、`character`和`raw`。`length`代表這個向量的值的個數。

2. list
R 也可以建立一種叫做`list`的向量,這是「R 物件」的向量。換句話說,每一個值 都是R物件,都有自己的`mode`、`length`等屬性。我們會在一些複雜的統計模型中,見到這樣的資料型態。
`g[1]`和`g[[1]]`的差異。使用`g[1]`時,R取出向量的第一個元素,並且維持list的結構,
使用`g[[1]]`時,R會打破list的結構,再取出向量的第一個元素,所以`g[[1]]`的 型態會是存放在list裡面的R物件的型態。
list向量最有用的地方,在於它可以裝不同型態的值。

3.attributes:  "names"和"class"
所有的R 物件,都有「屬性」(attributes)。我們可以用`attributes`這個函數來印出一個R物件的屬性。 請同學試試看:`attributes(g)`
在R 中,我們可以用`attr(g, "names")`來取得名字是"names"的屬性。請同學試試看。 names():查詢names屬性、class(): 查詢class屬性。


RBasic-04-Factors


Factor是一個向量物件,用途是儲存「類別」的資料,有這樣的資料格式,我們可以輕易把資料集依照類別分組。
Factor() : 轉為Factor向量,Factor向量中的levels屬性代表向量中允許出現的類別。 要取出這些類別,可使用levels()。
在Factor向量中指派沒在levels裡面的類別,會出現NA。
進一步觀察factor向量的結構。請輸入 str()。Factor向量本質上只是整數向量加上levels。這樣設計的原因是儲存整數比儲存文字更省空間。

其實「類別」的資料有兩種。分為「無順序」與「有順序」的,轉為有順序的factor向量。做法是在factor函數中,把ordered設為TRUE。
並且把levels順序以向量方式傳入,level要由小到大填入。

此章節小結
1.Factor向量用來儲存類別的資料。level屬性限制能在向量中出現的類別種類。
2.Factor本質上是整數向量,只是帶有levels。
3.Factor可以是無順序或有順序的,可用在Factor函數中使用ordered=TRUE讓Factor變成有序。

2016年10月18日 星期二

[閱讀心得]經濟指標告訴你&沒告訴你的事 (一)


經濟指標告訴你&沒告訴你的事

這本書是由知名財經作家- 愛榭克在2012年所出版的書籍。本書從四大構面出發,分別為觀念、基礎、應用、趨勢。由淺入深的介紹了許多總經面的經濟指標,並用此分析未來經濟局勢的趨勢。我們透過數據分析了解經濟強弱後,投資人可以更靈活的透過資產配置,布局於多元資產來避免損失的風險。以下筆者便順著此四大構面來重點摘要該書的精華與心得。

觀念篇
1.作者認為「學習投資應該從如何避開大空頭開始」,理由為當市場面臨多轉空的時刻,初期跌幅的損失往往需要後期更強勢的漲幅來彌補,過去投資人在長期投資下的觀點,手中資產經歷空頭與多頭市場後,往往白忙一場。
2.作者強調「長期投資的價值」應將重點放置於價值,而非長期。透過適當指標的趨勢觀察,抓住轉折點,才能獲取價值的回報。而此經濟指標就是美國實質GDP年增率

基礎篇
1.歐債危機中,媒體關注焦點的指標多為【政府債務/GDP 比率】,作者指出危機重點不在於債務,而是經濟本身陷入衰退。政府赤字導致的國家債務比重提高,並不會導致雷曼立即破產的局面。而是一個緩慢的過程。
當年歐洲財政當局與ECB就是透過財政緊縮與升息,加速經濟衰退的程度,而擴大危機本身,而另一方面,英美所採取的降息、量化寬鬆策略,就結果面而言,是較快走出歐債危機本身所帶來的經濟傷害。
2.美國仍舊牽引全球景氣動向,美元作為全球壟斷的儲備貨幣地位,短期內仍十分穩固,與其他經濟體相比,中國、德國與日本皆是出口型導向經濟,故美國內需市場是否增長便是全球經濟景氣的指標。
另外,對於新興國家來說,一旦美國經濟增長趨緩,受到熱錢回流和歐美需求減緩的影響程度,是比危機發生震央國更加明顯的。
3.作者認為,美債為最順應經濟變化的市場,絕非低回報、僅能避險的工具。適合不喜歡在短短幾年內進出的長線投資人。
而作者的美債多空分水嶺: 實質GDP年增率3%、核心通膨率2%
是透過兩方面分析美債投資人【有賺就好】的投資心理,通膨與機會成本,通膨易於理解,而機會成本則是指美債相對其他市場的獲利差距。實質GDP年增率便用於表示經濟熱絡程度,年增率高往往代表景氣熱絡,適合投資於股市。
故當同時發生實質GDP年增率3%、核心通膨率2%,是賣出美債的時機,反之,則該加碼。
因當通膨率攀升,遲早交實質經濟拉下,則應該持續加碼美債。然而若通膨位於谷底,可預期經濟增長能拉起通膨,反之該賣出美債。
因此作者得出以下結論

(1)通膨與經濟增長之間的關係,又以經濟增長較為重要
(2)兩項數據出現落差時,趨勢轉折即將出現

本文筆者便以如下實際資料驗證

  1. Real Gross Domestic Product   美國實質GDP
  2. Consumer Price Index for All Urban Consumers: All Items Less  Food and Energy  美國核心通膨
  3. BofA Merrill Lynch US High Yield Total Return Index Value美林高收益債指標
  4. BofA Merrill Lynch US Corp AAA Total Return Index Value美林美國AAA級公司債指標
  5. Russell 3000® Total Market Index  美股羅素3000


為了便於觀察,計算出股債報酬率後,統一由初始值1開始增長,而Key則是依作者所說之條件實質GDP年增率3%、核心通膨率2%,觸發則出現黃色直條標記之。
觀測期間由2000/1~2016/4,季資料。







可以發現從2000年至今,觸發條件僅八次,集中於2000年初與2004第四季至2006第一季。若在2000年賣出美債,在高收益美債可避免損失,但相對美股也無法避免下行風險。而在2004年初若跟隨訊號投入美股,一直到2006的確有不錯收益。但相對高收益債與AAA級債市亦有不錯表現。本質上而言

結論:
1.此分水嶺條件在過去17年較不易觸發,尤其GDP增長率在近年基本上難以突破3%,更較難觸發條件。
2.長期債市報酬率在過去17年報酬率持續領先股市,債市的確如作者所說,並非刻板印象中的低回報、避險資產。

另外下列附圖為美國實質GDP與核心CPI之年增率比較,可以觀察到美國GDP自2015/1已停止增長,而通膨持續穩定攀高。而於本文完成日期,S&P500指數仍位於相對高點,基本上確立股市的泡沫本質,但何時會消散,還需要更多總體指標來驗證。