
使用這些基本 REST API 最佳實踐構建出色的 API
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import yfinance as yf
# Download time series data using yfinance
data = yf.download('AAPL', start='2018-01-01', end='2023-06-30')
在深入研究異常檢測技術之前,先簡單介紹時間序列數據的特征。時間序列數據通常具有以下屬性:
讓我們可視化下載的時間序列數據
# Plot the time series data
plt.figure(figsize=(12, 6))
plt.plot(data['Close'])
plt.xlabel('Date')
plt.ylabel('Closing Price')
plt.title('AAPL Stock Price')
plt.xticks(rotation=45)
plt.grid(True)
plt.show()
從圖中可以觀察到股票價格隨時間增長的趨勢。也有周期性波動,表明季節性的存在。連續收盤價之間似乎存在一些自相關性。
在應用異常檢測技術之前,對時間序列數據進行預處理是至關重要的。預處理包括處理缺失值、平滑數據和去除異常值。
缺失值
由于各種原因,如數據收集錯誤或數據中的空白,時間序列數據中可能出現缺失值。適當地處理缺失值以避免分析中的偏差是必要的。
# Check for missing values
missing_values = data.isnull().sum()
print(missing_values)
我們使用的股票數據數據不包含任何缺失值。如果存在缺失值,可以通過輸入缺失值或刪除相應的時間點來處理它們。
對時間序列數據進行平滑處理有助于減少噪聲并突出顯示潛在的模式。平滑時間序列數據的一種常用技術是移動平均線。
# Smooth the time series data using a moving average
window_size = 7
data['Smoothed'] = data['Close'].rolling(window_size).mean()
# Plot the smoothed data
plt.figure(figsize=(12, 6))
plt.plot(data['Close'], label='Original')
plt.plot(data['Smoothed'], label='Smoothed')
plt.xlabel('Date')
plt.ylabel('Closing Price')
plt.title('AAPL Stock Price (Smoothed)')
plt.xticks(rotation=45)
plt.legend()
plt.grid(True)
plt.show()
該圖顯示了原始收盤價和使用移動平均線獲得的平滑版本。平滑有助于整體趨勢的可視化和減少短期波動的影響。
異常異常值會顯著影響異常檢測算法的性能。在應用異常檢測技術之前,識別和去除異常值是至關重要的。
# Calculate z-scores for each data point
z_scores = (data['Close'] - data['Close'].mean()) / data['Close'].std()
# Define a threshold for outlier detection
threshold = 3
# Identify outliers
outliers = data[np.abs(z_scores) > threshold]
# Remove outliers from the data
data = data.drop(outliers.index)
# Plot the data without outliers
plt.figure(figsize=(12, 6))
plt.plot(data['Close'])
plt.xlabel('Date')
plt.ylabel('Closing Price')
plt.title('AAPL Stock Price (Without Outliers)')
plt.xticks(rotation=45)
plt.grid(True)
plt.show()
上圖顯示了去除識別的異常值后的時間序列數據。通過減少極值的影響,去除異常值有助于提高異常檢測算法的準確性。
有人會說了,我們不就是要檢測異常值嗎,為什么要將它刪除呢?這是因為,我們這里刪除的異常值是非常明顯的值,也就是說這個預處理是初篩,或者叫粗篩。把非常明顯的值刪除,這樣模型可以更好的判斷哪些難判斷的值。
統計方法為時間序列數據的異常檢測提供了基礎。我們將探討兩種常用的統計技術:z-score和移動平均。
z-score
z-score衡量的是觀察值離均值的標準差數。通過計算每個數據點的z分數,我們可以識別明顯偏離預期行為的觀測值。
# Calculate z-scores for each data point
z_scores = (data['Close'] - data['Close'].mean()) / data['Close'].std()
# Plot the z-scores
plt.figure(figsize=(12, 6))
plt.plot(z_scores)
plt.xlabel('Date')
plt.ylabel('Z-Score')
plt.title('Z-Scores for AAPL Stock Price')
plt.xticks(rotation=45)
plt.axhline(y=threshold, color='r', linestyle='--', label='Threshold')
plt.axhline(y=-threshold, color='r', linestyle='--')
plt.legend()
plt.grid(True)
plt.show()
該圖顯示了每個數據點的計算z-score。z-score高于閾值(紅色虛線)的觀測值可視為異常。
另一種異常檢測的統計方法是基于移動平均線。通過計算移動平均線并將其與原始數據進行比較,我們可以識別與預期行為的偏差。
# Calculate the moving average
window_size = 7
moving_average = data['Close'].rolling(window_size).mean()
# Calculate the deviation from the moving average
deviation = data['Close'] - moving_average
# Plot the deviation
plt.figure(figsize=(12, 6))
plt.plot(deviation)
plt.xlabel('Date')
plt.ylabel('Deviation')
plt.title('Deviation from Moving Average')
plt.xticks(rotation=45)
plt.axhline(y=0, color='r', linestyle='--', label='Threshold')
plt.legend()
plt.grid(True)
plt.show()
該圖顯示了每個數據點與移動平均線的偏差。正偏差表示值高于預期行為,而負偏差表示值低于預期行為。
機器學習方法為時間序列數據的異常檢測提供了更先進的技術。我們將探討兩種流行的機器學習算法:孤立森林和LSTM Autoencoder。
孤立森林
孤立森林是一種無監督機器學習算法,通過將數據隨機劃分為子集來隔離異常。它測量隔離觀察所需的平均分區數,而異常情況預計需要更少的分區。
from sklearn.ensemble import IsolationForest
# Prepare the data for Isolation Forest
X = data['Close'].values.reshape(-1, 1)
# Train the Isolation Forest model
model = IsolationForest(contamination=0.05)
model.fit(X)
# Predict the anomalies
anomalies = model.predict(X)
# Plot the anomalies
plt.figure(figsize=(12, 6))
plt.plot(data['Close'])
plt.scatter(data.index, data['Close'], c=anomalies, cmap='cool', label='Anomaly')
plt.xlabel('Date')
plt.ylabel('Closing Price')
plt.title('AAPL Stock Price with Anomalies (Isolation Forest)')
plt.xticks(rotation=45)
plt.legend()
plt.grid(True)
plt.show()
該圖顯示了由孤立森林算法識別的異常時間序列數據。異常用不同的顏色突出顯示,表明它們偏離預期行為。
LSTM Autoencoder
LSTM (Long – Short-Term Memory)自編碼器是一種深度學習模型,能夠學習時間序列數據中的模式并重構輸入序列。通過將重建誤差與預定義的閾值進行比較,可以檢測異常。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
# Prepare the data for LSTM Autoencoder
X = data['Close'].values.reshape(-1, 1)
# Normalize the data
X_normalized = (X - X.min()) / (X.max() - X.min())
# Train the LSTM Autoencoder model
model = Sequential([
LSTM(64, activation='relu', input_shape=(1, 1)),
Dense(1)
])
model.compile(optimizer='adam', loss='mse')
model.fit(X_normalized, X_normalized, epochs=10, batch_size=32)
# Reconstruct the input sequence
X_reconstructed = model.predict(X_normalized)
# Calculate the reconstruction error
reconstruction_error = np.mean(np.abs(X_normalized - X_reconstructed), axis=1)
# Plot the reconstruction error
plt.figure(figsize=(12, 6))
plt.plot(reconstruction_error)
plt.xlabel('Date')
plt.ylabel('Reconstruction Error')
plt.title('Reconstruction Error (LSTM Autoencoder)')
plt.xticks(rotation=45)
plt.axhline(y=threshold, color='r', linestyle='--', label='Threshold')
plt.legend()
plt.grid(True)
plt.show()
該圖顯示了每個數據點的重建誤差。重建誤差高于閾值(紅色虛線)的觀測值可視為異常。
為了準確地評估異常檢測模型的性能,需要有包含有關異常存在或不存在的信息的標記數據。但是在現實場景中,獲取帶有已知異常的標記數據幾乎不可能,所以可以采用替代技術來評估這些模型的有效性。
最常用的一種技術是交叉驗證,它涉及將可用的標記數據分成多個子集或折疊。模型在數據的一部分上進行訓練,然后在剩余的部分上進行評估。這個過程重復幾次,并對評估結果進行平均,以獲得對模型性能更可靠的估計。
當標記數據不容易獲得時,也可以使用無監督評估度量。這些指標基于數據本身固有的特征(如聚類或密度估計)來評估異常檢測模型的性能。無監督評價指標的例子包括輪廓系數silhouette score、鄧恩指數Dunn index或平均最近鄰距離。
本文探索了使用機器學習進行時間序列異常檢測的各種技術。首先對其進行預處理,以處理缺失值,平滑數據并去除異常值。然后討論了異常檢測的統計方法,如z-score和移動平均。最后探討了包括孤立森林和LSTM自編碼器在內的機器學習方法。
異常檢測是一項具有挑戰性的任務,需要對時間序列數據有深入的了解,并使用適當的技術來發現異常模式和異常值。記住要嘗試不同的算法,微調參數并評估模型的性能,以獲得最佳結果。
本文章轉載微信公眾號@算法進階