時間序列表示方法
- 2020 年 1 月 27 日
- 筆記
自然界中,除了2D、3D的圖片、影片駛距以外,更多的是一些類似於序列的數據,比如語音、文字,這些數據都是有時間先後順序的
現在就有這樣一個問題,對於一個2D圖片順序,我們用一個像素點的RGB值來表示這個像素的色彩度。但是對於語音、文字該如何表示呢?
語音在某一個時間段會產生一段波形,這段波形中波峰值就可以表示此刻聲音的強度。對於一段文字中的字元也可以表示。但是在PyTorch中是沒有string類型的,我們必須要把string類型表示為另外一種數值類型。如何進行時間序列的表示(Representation),如何進行時間序列的資訊提取(Information Extraction )就成了時間序列研究的關鍵問題
Sequence Representation
- $[seq_len, feature_len]$ 假設一句話有5個單詞,那麼$seq_len=5$,而$feature_len$取決於你的應用場景,比方說每個單詞用一個1維向量來表示,那麼$feature_len=1$,如果每個單詞用一個100維向量來表示,那麼$feature_len=100$
例如下圖的歷史房價圖,所採用的表示方式就是[100,1]

How to represent a word
通常我們會使用one-hot Encoding的方式對文字進行編碼,看下面的一個例子
假設有下面的兩句話:
- have a good day
- have a great day 這兩句話共有5個辭彙,於是可以用$V$表示,其中$V={have, a, good, great, day}$。因為有5個辭彙,所以每個辭彙都用一個5維的向量進行表示,如下所示:
- have = [1, 0, 0, 0, 0]
- a = [0, 1, 0, 0, 0]
- good = [0, 0, 1, 0, 0]
- great = [0, 0, 0, 1, 0]
- day = [0, 0, 0, 0, 1]
但這麼做有以下的缺點:
- 每個word的vector都是獨立的,所以使用one-hot Encoding沒有體現單詞語單詞之間的關係
- 如果辭彙量很多,則vector的維度會很大,同時造成數據稀疏問題
Word Embedding
上面one-hot Encoding存在很多問題,那麼應該如何修改呢?我們可以用另一種方式去定義每一個單詞——word embedding。下面這句話解釋word embedding很合適
Word embeddings embed meaning of text in a vector space.(把文本的意思嵌入到向量空間中)
有一些詞的詞性是相近的,比如「love」和「like」,對於這種詞性相近的詞,我們需要他們的向量表示也能相近,如何度量和定義向量之間的相似程度呢?非常簡單,就是使用兩個向量的夾角,夾角越小,越相近。舉個例子,下面有4段話
- The cat likes playing wool.
- The kitty likes playing wool.
- The dog likes playing ball
- The boy does not like playing ball or wool.
這裡面有4個詞,分別是cat,kitty,dog和boy。下面我們使用一個二維的詞向量(a,b)來表示每一個詞,其中a和b分別代表著這個詞的一種屬性,比如a代表是否喜歡玩球,b代表是否喜歡玩毛線,數值越大表示越喜歡,那麼我們就能用數值來定義每一個單詞
對於cat,我們可以定義他的word embedding為(-1, 4),因為它不喜歡玩球,喜歡玩毛線;kitty為(-2, 5);dog為(3, -2);boy為(-2,-3)。把這四個向量在坐標系中表示出來

從上圖就能明顯看出kitty和cat的夾角比較小,所以它們比較相似,dog和boy之間的夾角很大,所以它們不相似
下面說一下具體公式。對於向量$boldsymbol{x}, boldsymbol{y} in mathbb{R}^d$,它們的餘弦相似度是它們之間夾角的餘弦值
$$ frac{boldsymbol{x}^top boldsymbol{y}}{|boldsymbol{x}| |boldsymbol{y}|} in [-1, 1]. $$
在PyTorch中Word Embedding是通過一個函數來實現的nn.Embedding
import torch import torch.nn as nn word_to_idx = {"hello": 0, "world": 1} # 給每個詞打上索引 lookup_tensor = torch.tensor([word_to_idx["hello"]], dtype=torch.long) # 取出"hello"對應的索引 embeds = nn.Embedding(2, 5) # 2 words in vocab, 5 dimensional embeddings hello_embed = embeds(lookup_tensor) # 傳入索引 print(hello_embed)
輸出
tensor([[-1.2999, 2.2142, 0.2436, -1.9585, 0.8714]], grad_fn=<EmbeddingBackward>)
稍微解釋下這幾行程式碼,首先因為每個單詞都需要用一個數字去表示,所以我們要構建一個單詞-數字之間的映射
然後是nn.Embedding(2, 5)
,2表示有2個詞,5表示5維,其實也就是個2×5的矩陣。所以如果你有1000個詞,每個詞希望是100維,你就可以這樣寫這行程式碼nn.Embedding(1000, 100)