Matlab是做科研是比較常用的建模工具,研一做專案遇到了一個比較基礎的問題,所以我打算記錄下來並分享出來!
處理問題步驟:
1. 丟擲問題
2. 思考解決方法
3. 程式碼驗證看結果
-
丟擲問題
在專案中有一批原始資料,在資料中有佔很少比例的異樣點,我們已經知道這些異樣點是會影響結果精度的,需要剔除。
為了去除這些震盪點,我們自定義一些資料來進行模擬,用以找出去除方法,模擬的優勢就在於能更快解決問題。
帶有震盪點的模擬資料點圖如下:
-
思考解決方法
在這個模擬資料點圖中可以看出所有的異樣點都在曲線的上部,異樣點在曲線的一側(全在上部或者在下部)還算好辦,
若是有上有下則要複雜的多(以後的文章中應該還會討論)。現在我們要想出一種好的演算法來去除這些點,認真想想其實
還真不是太容易搞···。經過思考之後,明確了問題的關鍵所在:(1). 如何找出這些點: 方法:將每個點進行標號(0 1 2·· n),從第一個點開始,依次用後一個點的y值減去前一個點的y值並賦給自定義的變數diff1, 例:diff1 = y(i+1) - y(i) 若diff1 < 0 ,則繼續,若diff1 > 0,則記錄i+1這個點,並把i點作為新的起始點,用後面的點與i點做差, 例:diff1 = y(i+m) - y(i), m > 1, 直到遇到使diff1 < 0 的點,那這個點就是正常點,i點到此點之間的就都是異樣點。 (2). 正常點之後還有異樣點怎麼解決? 方法:很簡單,用迭代方法就可以解決,迭代之後就都可以解決 (3). 然後呢? 找出異樣點之後,將這些點刪除,用新的資料陣列代替原有資料陣列,問題就解決了
放個圖可能更好理解:
-
程式碼驗證看結果
具體的程式碼如下:arry = [];%存放異常點下標 i=1; while(i<length(A(:,1))-1) diff1 = A(i+1,2) - A(i,2);%後一點y值到前一點y值之差 if diff1 > 0 n = i;%記住異常值前一點的下標 m=1; arry=[arry;n+m];%記住異常值下標 diff1 = A(i+m+1,2) - A(i,2); while diff1 > 0 arry = [arry;n+m+1]; m = m+1; diff1 = A(n+1+m,2) - A(n,2); end i=i+m; end i=i+1; end %遍歷陣列 ARRY 刪掉A中第arry(i)的元素 bb = A(:,2); bb(arry) = []; xi2 = [1:length(A(:,1))]; xi1 = xi2; xi1(arry) = []; result = interp1(xi1,bb,xi2)'; A_new = [A(:,1),result]; plot(A_new(:,1),A_new(:,2))。
程式碼比較簡單,註釋就不方那麼多了,思路理解了,寫程式碼就很清晰了
資料我就不展示了,看一下結果吧:
我們解決問題的時候,首先要解決自己思想上的問題,思路清晰之後才好動手操作,這就是為什麼演算法工程師要比程式設計師的工資高,努力做個優秀的打工人!