簡潔的序列預測算法


 


計算機和人的最大區別在於,人具備徹底的學習和強大的聯想能力,而計算機則不同,只能在程序員給定的框架內進行簡單的學習(與其說是學習,不如說是參數微調)。
人類可以很容易的發現特有的模式,比如看下面幾個例子:

image

然而,如此簡單的模式,計算機卻無法發現,但如果能讓計算機學習這種模式,那無疑是非常有價值的。
我們的目標,是給定一串序列:

image

找出其中的規律,並能夠推斷之后的序列sn,直到無窮,或是序列結束。本文是筆者獨立思考得到的,沒有參考其他學術論文,如果有更好的方法,歡迎批評指正。


如果不限制模式的長度,那么這個問題可能是無解的,即使出現一長串的A,我們也不能就只認定這就是A的重復序列,很有可能后面會出現B。因此,必須給問題增加限制條件。

模式是遞歸定義的,對ID=2的例子,是ABC的重復,內部又是一個遞增數組。ID=1的例子,則外部是遞增數組,內部是重復。若是ABCCBAABCCBA, 則是重復,重復結構是ABCCBA。 如果要求更高,可以發現內部是一個回環。

重復

重復是最基本,最常見的模式,例如AAAAA,ABCABCABC。處理起來也非常容易:

從起始長度n=1為起點,判斷之后的結構是否滿足重復條件,如果滿足,則算法終止,否則n++,直到n=min(MAXREPEATLEN,len(S)),此時序列不存在重復模式。

我們通常需要對重復段的長度增加限制,比如不超過10。

發現重復后,其表達就是數組[Mode]+ ,Mode為子序列,此時即可推導之后的元素。

值遞增遞減

考慮這樣的序列:

ABCDEF...
ABCCDEEFG...
ABCEFGIJK...

它們沒有重復模式,但存在子結構,子結構之間有遞增和遞減關系。我們的思路,是盡可能地將這種模式退化為重復模式,即可使用重復的方法。
聰明的讀者可能已經想到,既然是遞增遞減,則可使用差分。
對第一個序列,后一個元素減去前面的元素,可得:

11111111....


第二個序列:

110110110....


第三個序列:

112112112...


之后,即可調用重復模式的分析思路,解決問題。


我們似乎還沒有討論這樣的序列:

AA AB AC AD....


差分求解后,得到的是0,0,1,-1,2,-2,3,-3....這並不是一個重復的序列。
但如果按照相隔一個元素求差分,則頓時開朗:

0101010101...


因此,我們可總結值遞增遞減的模式分析方法:

從起始差分步進長度n=1為起點,判斷之后的結構是否滿足值遞增遞減條件,如果滿足,則算法轉換為處理重復模式,否則n++,直到n=min(MAXLEN,len(S)),此時序列不存在遞增遞減模式。

長度遞增遞減

這種模式,分析起來更為復雜,看下面的例子:

A AB ABC ABCD...
B EF IJK NOPQ...
1 12 112 1112 11112...


(中間的空格,是手工加上便於看清規律的)
這種規律很明顯,但並不是重復,也不是值遞增遞減,它的子結構發生了長度上的變化。
按照上一節的思路,從左到右依次差分計算:

0,1,-1,1,1,-2,1,1,1,-3,1,1,1,1,-4....
2,1,2,1,1,2,1,1,1,1...
0,1,-1,0,0,1,-1,0,0,0,1,-1....


我想盡辦法,試圖能通過某種變換,獲得像剛才那樣簡單有效的轉換,發現無果。換一個思路,通過類似概率的手段來分析。仔細觀察會發現,出現最多的數字是步進值,第一行和第二行都是1,第三行是0。之后按照步進值分割,就成了下面的增減/重復序列:

0,-1,-2,-3....
1,-1,1,-1,1,-1...


而且,步進值出現的次數,也是一個遞增,遞減序列:

1 | 1,1 | 1,1,1 | 1,1,1,1| ....
0 | 0,0 | 0,0,0....


又可以按照增減,重復序列的方式處理。

總結一下這種方式的偽代碼:
原始序列S1從左到右依次差分,得到的序列S2,求取出現次數最多的數字,以此為特征分隔符,即可將序列S2分割為兩個序列:

image

其中SA和SB分別為增減/重復序列。

其他更復雜的序列

大家看了以上的處理思路,是不是希望讓計算機去求解公務員考試題目?不好意思,復雜的序列非常多,比如下面的序列:

image

image

這個問題靠計算機搜索,幾乎是不可解的。如果硬要處理,最終會變成一個離散的多項式擬合問題,到了那個時候就一點都不酷了。

好在,現實世界的流程和結構一般沒有那么復雜,比如網頁的結構,消息出現的樣式,重復占據了絕大多數情況。可能最多出現遞增遞減和重復嵌套的情況。如果是復雜的序列,上面的檢測方法最少能告訴我們,這個序列不是重復/遞增遞減序列,可能需要用更復雜的方式來處理。對於一般的情形,這樣的思路基本夠用了。
另外要注意的問題是相等性。我們簡化了問題的描述,將序列簡化為有明確標示和序號的串。看下面的例子:

<name>zhao</name>
<job>coding</job>
<name>wang<name>
<job>eating</job>
...

這是個name,job不斷重復的xml文檔,在解決模式推斷之前,你需要一些手段告訴計算機,第一行和第三行,在一定程度上是相等的。如果不相等,這事沒戲了。

額外的有益討論

從剛才那個例子,可以看出文法推斷在自動解析上的好處:

  • 如果能夠發現序列的規律,就能自動將其結構化
  • 能在一定程度上預測下一條數據是什么類型,從而提升命中效率
  • 能夠發現隱含在數據結構中的規律

文法推斷是一項相當復雜的命題,即使序列有特定的規律,即使能找到問題的解,解的數量可能也是非常龐大的。通常使用奧卡姆剃刀原理,即認為正確的文法總是最簡單的那個。本文描述的,也只是文法推斷中一個最為簡單的命題,即序列的模式發現。
更多的真實情況,是序列有規律,但卻是符合概率的。下面的例子:

AAC AAC AAD AAC AAC AAC AAD...


多數情況出現的是AAC,但有較低的可能性出現AAD,如果能從其中找出規律並推算概率,那么也能解決相當多的問題。不過,就需要大量的數學知識和技巧了,筆者望洋興嘆,只能感慨於造物主對人類大腦的恩賜。

一方面,在表面上看起來毫無意義的噪聲,經過某種特定的數學變換,卻能從中發現穩定的規律。
只要願意,任何一串序列都能轉換為一個特定的整數,而整數處理起來比序列更為簡單和純粹。序列的分解,可以對應為整數的分解。質數為什么如此重要?因為質數提供了乘法計算中不可分解的“元”。

有任何問題,歡迎各位隨時討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM