# 如何開發多元多步空氣污染時間序列預測的機器學習模型
> 原文: [https://machinelearningmastery.com/how-to-develop-machine-learning-models-for-multivariate-multi-step-air-pollution-time-series-forecasting/](https://machinelearningmastery.com/how-to-develop-machine-learning-models-for-multivariate-multi-step-air-pollution-time-series-forecasting/)
實時世界時間序列預測具有挑戰性,其原因不僅限于問題特征,例如具有多個輸入變量,需要預測多個時間步驟,以及需要對多個物理站點執行相同類型的預測。
EMC Data Science Global Hackathon 數據集或簡稱“空氣質量預測”數據集描述了多個站點的天氣狀況,需要預測隨后三天的空氣質量測量結果。
機器學習算法可以應用于時間序列預測問題,并提供諸如處理具有嘈雜的復雜依賴性的多個輸入變量的能力的好處。
在本教程中,您將了解如何開發用于空氣污染數據的多步時間序列預測的機器學習模型。
完成本教程后,您將了解:
* 如何估算缺失值并轉換時間序列數據,以便可以通過監督學習算法對其進行建模。
* 如何開發和評估一套線性算法用于多步時間序列預測。
* 如何開發和評估一套非線性算法用于多步時間序列預測。
讓我們開始吧。

如何開發多變量多步空氣污染時間序列預測的機器學習模型
照片由 [Eric Sc??hmuttenmaer](https://www.flickr.com/photos/akeg/376488289/) ,保留一些權利。
## 教程概述
本教程分為九個部分;他們是:
1. 問題描述
2. 模型評估
3. 機器學習建模
4. 機器學習數據準備
5. 模型評估測試線束
6. 評估線性算法
7. 評估非線性算法
8. 調整滯后大小
## 問題描述
空氣質量預測數據集描述了多個地點的天氣狀況,需要預測隨后三天的空氣質量測量結果。
具體而言,對于多個站點,每小時提供 8 天的溫度,壓力,風速和風向等天氣觀測。目標是預測未來 3 天在多個地點的空氣質量測量。預測的提前期不是連續的;相反,必須在 72 小時預測期內預測特定提前期。他們是:
```py
+1, +2, +3, +4, +5, +10, +17, +24, +48, +72
```
此外,數據集被劃分為不相交但連續的數據塊,其中 8 天的數據隨后是需要預測的 3 天。
并非所有站點或塊都可以獲得所有觀察結果,并且并非所有站點和塊都可以使用所有輸出變量。必須解決大部分缺失數據。
該數據集被用作 2012 年 Kaggle 網站上[短期機器學習競賽](https://www.kaggle.com/c/dsg-hackathon)(或黑客馬拉松)的基礎。
根據從參與者中扣留的真實觀察結果評估競賽的提交,并使用平均絕對誤差(MAE)進行評分。提交要求在由于缺少數據而無法預測的情況下指定-1,000,000 的值。實際上,提供了一個插入缺失值的模板,并且要求所有提交都采用(模糊的是什么)。
獲勝者在滯留測試集([私人排行榜](https://www.kaggle.com/c/dsg-hackathon/leaderboard))上使用隨機森林在滯后觀察中獲得了 0.21058 的 MAE。該帖子中提供了此解決方案的說明:
* [把所有東西都扔進隨機森林:Ben Hamner 贏得空氣質量預測黑客馬拉松](http://blog.kaggle.com/2012/05/01/chucking-everything-into-a-random-forest-ben-hamner-on-winning-the-air-quality-prediction-hackathon/),2012。
在本教程中,我們將探索如何為可用作基線的問題開發樸素預測,以確定模型是否具有該問題的技能。
## 模型評估
在我們評估樸素的預測方法之前,我們必須開發一個測試工具。
這至少包括如何準備數據以及如何評估預測。
### 加載數據集
第一步是下載數據集并將其加載到內存中。
數據集可以從 Kaggle 網站免費下載。您可能必須創建一個帳戶并登錄才能下載數據集。
下載整個數據集,例如“_ 將所有 _”下載到您的工作站,并使用名為' _AirQualityPrediction_ '的文件夾解壓縮當前工作目錄中的存檔。
* [EMC 數據科學全球黑客馬拉松(空氣質量預測)數據](https://www.kaggle.com/c/dsg-hackathon/data)
我們的重點將是包含訓練數據集的' _TrainingData.csv_ '文件,特別是塊中的數據,其中每個塊是八個連續的觀察日和目標變量。
我們可以使用 Pandas [read_csv()函數](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html)將數據文件加載到內存中,并在第 0 行指定標題行。
```py
# load dataset
dataset = read_csv('AirQualityPrediction/TrainingData.csv', header=0)
```
我們可以通過'chunkID'變量(列索引 1)對數據進行分組。
首先,讓我們獲取唯一的塊標識符列表。
```py
chunk_ids = unique(values[:, 1])
```
然后,我們可以收集每個塊標識符的所有行,并將它們存儲在字典中以便于訪問。
```py
chunks = dict()
# sort rows by chunk id
for chunk_id in chunk_ids:
selection = values[:, chunk_ix] == chunk_id
chunks[chunk_id] = values[selection, :]
```
下面定義了一個名為 _to_chunks()_ 的函數,它接受加載數據的 NumPy 數組,并將 _chunk_id_ 的字典返回到塊的行。
```py
# split the dataset by 'chunkID', return a dict of id to rows
def to_chunks(values, chunk_ix=1):
chunks = dict()
# get the unique chunk ids
chunk_ids = unique(values[:, chunk_ix])
# group rows by chunk id
for chunk_id in chunk_ids:
selection = values[:, chunk_ix] == chunk_id
chunks[chunk_id] = values[selection, :]
return chunks
```
下面列出了加載數據集并將其拆分為塊的完整示例。
```py
# load data and split into chunks
from numpy import unique
from pandas import read_csv
# split the dataset by 'chunkID', return a dict of id to rows
def to_chunks(values, chunk_ix=1):
chunks = dict()
# get the unique chunk ids
chunk_ids = unique(values[:, chunk_ix])
# group rows by chunk id
for chunk_id in chunk_ids:
selection = values[:, chunk_ix] == chunk_id
chunks[chunk_id] = values[selection, :]
return chunks
# load dataset
dataset = read_csv('AirQualityPrediction/TrainingData.csv', header=0)
# group data by chunks
values = dataset.values
chunks = to_chunks(values)
print('Total Chunks: %d' % len(chunks))
```
運行該示例將打印數據集中的塊數。
```py
Total Chunks: 208
```
### 數據準備
既然我們知道如何加載數據并將其拆分成塊,我們就可以將它們分成訓練和測試數據集。
盡管每個塊內的實際觀測數量可能差異很大,但每個塊的每小時觀察間隔為 8 天。
我們可以將每個塊分成前五天的訓練觀察和最后三天的測試。
每個觀察都有一行稱為' _position_within_chunk_ ',從 1 到 192(8 天* 24 小時)不等。因此,我們可以將此列中值小于或等于 120(5 * 24)的所有行作為訓練數據,將任何大于 120 的值作為測試數據。
此外,任何在訓練或測試分割中沒有任何觀察的塊都可以被丟棄,因為不可行。
在使用樸素模型時,我們只對目標變量感興趣,而不對輸入的氣象變量感興趣。因此,我們可以刪除輸入數據,并使訓練和測試數據僅包含每個塊的 39 個目標變量,以及塊和觀察時間內的位置。
下面的 _split_train_test()_ 函數實現了這種行為;給定一個塊的字典,它將每個分成訓練和測試塊數據。
```py
# split each chunk into train/test sets
def split_train_test(chunks, row_in_chunk_ix=2):
train, test = list(), list()
# first 5 days of hourly observations for train
cut_point = 5 * 24
# enumerate chunks
for k,rows in chunks.items():
# split chunk rows by 'position_within_chunk'
train_rows = rows[rows[:,row_in_chunk_ix] <= cut_point, :]
test_rows = rows[rows[:,row_in_chunk_ix] > cut_point, :]
if len(train_rows) == 0 or len(test_rows) == 0:
print('>dropping chunk=%d: train=%s, test=%s' % (k, train_rows.shape, test_rows.shape))
continue
# store with chunk id, position in chunk, hour and all targets
indices = [1,2,5] + [x for x in range(56,train_rows.shape[1])]
train.append(train_rows[:, indices])
test.append(test_rows[:, indices])
return train, test
```
我們不需要整個測試數據集;相反,我們只需要在三天時間內的特定提前期進行觀察,特別是提前期:
```py
+1, +2, +3, +4, +5, +10, +17, +24, +48, +72
```
其中,每個提前期相對于訓練期結束。
首先,我們可以將這些提前期放入函數中以便于參考:
```py
# return a list of relative forecast lead times
def get_lead_times():
return [1, 2 ,3, 4, 5, 10, 17, 24, 48, 72]
```
接下來,我們可以將測試數據集縮減為僅在首選提前期的數據。
我們可以通過查看' _position_within_chunk_ '列并使用提前期作為距離訓練數據集末尾的偏移量來實現,例如: 120 + 1,120 +2 等
如果我們在測試集中找到匹配的行,則保存它,否則生成一行 NaN 觀測值。
下面的函數 _to_forecasts()_ 實現了這一點,并為每個塊的每個預測提前期返回一行 NumPy 數組。
```py
# convert the rows in a test chunk to forecasts
def to_forecasts(test_chunks, row_in_chunk_ix=1):
# get lead times
lead_times = get_lead_times()
# first 5 days of hourly observations for train
cut_point = 5 * 24
forecasts = list()
# enumerate each chunk
for rows in test_chunks:
chunk_id = rows[0, 0]
# enumerate each lead time
for tau in lead_times:
# determine the row in chunk we want for the lead time
offset = cut_point + tau
# retrieve data for the lead time using row number in chunk
row_for_tau = rows[rows[:,row_in_chunk_ix]==offset, :]
# check if we have data
if len(row_for_tau) == 0:
# create a mock row [chunk, position, hour] + [nan...]
row = [chunk_id, offset, nan] + [nan for _ in range(39)]
forecasts.append(row)
else:
# store the forecast row
forecasts.append(row_for_tau[0])
return array(forecasts)
```
我們可以將所有這些組合在一起并將數據集拆分為訓練集和測試集,并將結果保存到新文件中。
完整的代碼示例如下所示。
```py
# split data into train and test sets
from numpy import unique
from numpy import nan
from numpy import array
from numpy import savetxt
from pandas import read_csv
# split the dataset by 'chunkID', return a dict of id to rows
def to_chunks(values, chunk_ix=1):
chunks = dict()
# get the unique chunk ids
chunk_ids = unique(values[:, chunk_ix])
# group rows by chunk id
for chunk_id in chunk_ids:
selection = values[:, chunk_ix] == chunk_id
chunks[chunk_id] = values[selection, :]
return chunks
# split each chunk into train/test sets
def split_train_test(chunks, row_in_chunk_ix=2):
train, test = list(), list()
# first 5 days of hourly observations for train
cut_point = 5 * 24
# enumerate chunks
for k,rows in chunks.items():
# split chunk rows by 'position_within_chunk'
train_rows = rows[rows[:,row_in_chunk_ix] <= cut_point, :]
test_rows = rows[rows[:,row_in_chunk_ix] > cut_point, :]
if len(train_rows) == 0 or len(test_rows) == 0:
print('>dropping chunk=%d: train=%s, test=%s' % (k, train_rows.shape, test_rows.shape))
continue
# store with chunk id, position in chunk, hour and all targets
indices = [1,2,5] + [x for x in range(56,train_rows.shape[1])]
train.append(train_rows[:, indices])
test.append(test_rows[:, indices])
return train, test
# return a list of relative forecast lead times
def get_lead_times():
return [1, 2 ,3, 4, 5, 10, 17, 24, 48, 72]
# convert the rows in a test chunk to forecasts
def to_forecasts(test_chunks, row_in_chunk_ix=1):
# get lead times
lead_times = get_lead_times()
# first 5 days of hourly observations for train
cut_point = 5 * 24
forecasts = list()
# enumerate each chunk
for rows in test_chunks:
chunk_id = rows[0, 0]
# enumerate each lead time
for tau in lead_times:
# determine the row in chunk we want for the lead time
offset = cut_point + tau
# retrieve data for the lead time using row number in chunk
row_for_tau = rows[rows[:,row_in_chunk_ix]==offset, :]
# check if we have data
if len(row_for_tau) == 0:
# create a mock row [chunk, position, hour] + [nan...]
row = [chunk_id, offset, nan] + [nan for _ in range(39)]
forecasts.append(row)
else:
# store the forecast row
forecasts.append(row_for_tau[0])
return array(forecasts)
# load dataset
dataset = read_csv('AirQualityPrediction/TrainingData.csv', header=0)
# group data by chunks
values = dataset.values
chunks = to_chunks(values)
# split into train/test
train, test = split_train_test(chunks)
# flatten training chunks to rows
train_rows = array([row for rows in train for row in rows])
# print(train_rows.shape)
print('Train Rows: %s' % str(train_rows.shape))
# reduce train to forecast lead times only
test_rows = to_forecasts(test)
print('Test Rows: %s' % str(test_rows.shape))
# save datasets
savetxt('AirQualityPrediction/naive_train.csv', train_rows, delimiter=',')
savetxt('AirQualityPrediction/naive_test.csv', test_rows, delimiter=',')
```
運行該示例首先評論了從數據集中移除了塊 69 以獲得不足的數據。
然后我們可以看到每個訓練和測試集中有 42 列,一個用于塊 ID,塊內位置,一天中的小時和 39 個訓練變量。
我們還可以看到測試數據集的顯著縮小版本,其中行僅在預測前置時間。
新的訓練和測試數據集分別保存在' _naive_train.csv_ '和' _naive_test.csv_ '文件中。
```py
>dropping chunk=69: train=(0, 95), test=(28, 95)
Train Rows: (23514, 42)
Test Rows: (2070, 42)
```
### 預測評估
一旦做出預測,就需要對它們進行評估。
在評估預測時,使用更簡單的格式會很有幫助。例如,我們將使用 _[chunk] [變量] [時間]_ 的三維結構,其中變量是從 0 到 38 的目標變量數,time 是從 0 到 9 的提前期索引。
模型有望以這種格式進行預測。
我們還可以重新構建測試數據集以使此數據集進行比較。下面的 _prepare_test_forecasts()_ 函數實現了這一點。
```py
# convert the test dataset in chunks to [chunk][variable][time] format
def prepare_test_forecasts(test_chunks):
predictions = list()
# enumerate chunks to forecast
for rows in test_chunks:
# enumerate targets for chunk
chunk_predictions = list()
for j in range(3, rows.shape[1]):
yhat = rows[:, j]
chunk_predictions.append(yhat)
chunk_predictions = array(chunk_predictions)
predictions.append(chunk_predictions)
return array(predictions)
```
我們將使用平均絕對誤差或 MAE 來評估模型。這是在競爭中使用的度量,并且在給定目標變量的非高斯分布的情況下是合理的選擇。
如果提前期不包含測試集中的數據(例如 _NaN_ ),則不會計算該預測的錯誤。如果提前期確實在測試集中有數據但預測中沒有數據,那么觀察的全部大小將被視為錯誤。最后,如果測試集具有觀察值并進行預測,則絕對差值將被記錄為誤差。
_calculate_error()_ 函數實現這些規則并返回給定預測的錯誤。
```py
# calculate the error between an actual and predicted value
def calculate_error(actual, predicted):
# give the full actual value if predicted is nan
if isnan(predicted):
return abs(actual)
# calculate abs difference
return abs(actual - predicted)
```
錯誤在所有塊和所有提前期之間求和,然后取平均值。
將計算總體 MAE,但我們還將計算每個預測提前期的 MAE。這通常有助于模型選擇,因為某些模型在不同的提前期可能會有不同的表現。
下面的 evaluate_forecasts()函數實現了這一點,計算了 _[chunk] [variable] [time]_ 格式中提供的預測和期望值的 MAE 和每個引導時間 MAE。
```py
# evaluate a forecast in the format [chunk][variable][time]
def evaluate_forecasts(predictions, testset):
lead_times = get_lead_times()
total_mae, times_mae = 0.0, [0.0 for _ in range(len(lead_times))]
total_c, times_c = 0, [0 for _ in range(len(lead_times))]
# enumerate test chunks
for i in range(len(test_chunks)):
# convert to forecasts
actual = testset[i]
predicted = predictions[i]
# enumerate target variables
for j in range(predicted.shape[0]):
# enumerate lead times
for k in range(len(lead_times)):
# skip if actual in nan
if isnan(actual[j, k]):
continue
# calculate error
error = calculate_error(actual[j, k], predicted[j, k])
# update statistics
total_mae += error
times_mae[k] += error
total_c += 1
times_c[k] += 1
# normalize summed absolute errors
total_mae /= total_c
times_mae = [times_mae[i]/times_c[i] for i in range(len(times_mae))]
return total_mae, times_mae
```
一旦我們對模型進行評估,我們就可以呈現它。
下面的 _summarize_error()_ 函數首先打印模型表現的一行摘要,然后創建每個預測提前期的 MAE 圖。
```py
# summarize scores
def summarize_error(name, total_mae, times_mae):
# print summary
lead_times = get_lead_times()
formatted = ['+%d %.3f' % (lead_times[i], times_mae[i]) for i in range(len(lead_times))]
s_scores = ', '.join(formatted)
print('%s: [%.3f MAE] %s' % (name, total_mae, s_scores))
# plot summary
pyplot.plot([str(x) for x in lead_times], times_mae, marker='.')
pyplot.show()
```
我們現在準備開始探索樸素預測方法的表現。
機器學習建模
問題可以通過機器學習來建模。
大多數機器學習模型并不直接支持隨時間推移的觀測概念。相反,必須將滯后觀察視為輸入要素才能進行預測。
這是時間序列預測的機器學習算法的一個好處。具體來說,他們能夠支持大量的輸入功能。這些可能是一個或多個輸入時間序列的滯后觀察。
用于經典方法的時間序列預測的機器學習算法的其他一般好處包括:
* 能夠支持變量之間關系中的噪聲特征和噪聲。
* 能夠處理不相關的功能。
* 能夠支持變量之間的復雜關系。
該數據集面臨的挑戰是需要進行多步預測。機器學習方法有兩種主要方法可用于進行多步預測;他們是:
* **直接**。開發了一個單獨的模型來預測每個預測提前期。
* **遞歸**。開發單一模型以進行一步預測,并且遞歸地使用該模型,其中先前預測被用作輸入以預測隨后的提前期。
遞歸方法在預測短的連續交付時間塊時是有意義的,而直接方法在預測不連續的交付周期時可能更有意義。直接方法可能更適合空氣污染預測問題,因為我們有興趣預測三天內 10 個連續和不連續交付時間的混合。
數據集有 39 個目標變量,我們根據預測的提前期為每個目標變量開發一個模型。這意味著我們需要(39 * 10)390 個機器學習模型。
使用機器學習算法進行時間序列預測的關鍵是輸入數據的選擇。我們可以考慮三個主要的數據來源,它們可以用作輸入并映射到目標變量的每個預測提前期;他們是:
* **單變量數據**,例如來自正在預測的目標變量的滯后觀察。
* **多變量數據**,例如來自其他變量(天氣和目標)的滯后觀測。
* **元數據**,例如有關預測日期或時間的數據。
可以從所有塊中提取數據,提供豐富的數據集,用于學習從輸入到目標預測提前期的映射。
39 個目標變量實際上包含 14 個站點的 12 個變量。
由于提供數據的方式,建模的默認方法是將每個變量站點視為獨立的。可以通過變量折疊數據,并為多個站點的變量使用相同的模型。
一些變量被故意貼錯標簽(例如,不同的數據使用具有相同標識符的變量)。然而,也許這些錯誤標記的變量可以從多站點模型中識別和排除。
## 機器學習數據準備
在我們探索此數據集的機器學習模型之前,我們必須以能夠適合模型的方式準備數據。
這需要兩個數據準備步驟:
* 處理丟失的數據。
* 準備輸入輸出模式。
目前,我們將關注 39 個目標變量并忽略氣象和元數據。
### 處理丟失的數據
對于 39 個目標變量,塊由五小時或更少的小時觀察組成。
許多塊沒有全部五天的數據,并且沒有任何塊具有所有 39 個目標變量的數據。
在塊沒有目標變量數據的情況下,不需要預測。
如果一個塊確實有一些目標變量的數據,但不是所有五天的值,那么該系列中將存在空白。這些間隙可能需要幾個小時到一天的觀察時間,有時甚至更長。
處理這些差距的三種候選戰略如下:
* 忽略差距。
* 無間隙地使用數據。
* 填補空白。
我們可以忽略這些差距。這樣做的一個問題是,在將數據分成輸入和輸出時,數據不會是連續的。在訓練模型時,輸入將不一致,但可能意味著最后 n 小時的數據或數據分布在最后 _n_ 天。這種不一致將使學習從輸入到輸出的映射非常嘈雜,并且可能比模型更難以實現。
我們只能使用無間隙的數據。這是一個不錯的選擇。風險在于我們可能沒有足夠或足夠的數據來適應模型。
最后,我們可以填補空白。這稱為數據插補,有許多策略可用于填補空白。可能表現良好的三種方法包括:
* 保持最后觀察到的值向前(線性)。
* 使用塊中一天中的小時的中值。
* 使用跨塊的一小時的中值。
在本教程中,我們將使用后一種方法,并通過使用跨塊的時間的中位數來填補空白。經過一點點測試后,這種方法似乎可以產生更多的訓練樣本和更好的模型表現。
對于給定變量,可能缺少由缺失行定義的觀察值。具體地,每個觀察具有' _position_within_chunk_ '。我們期望訓練數據集中的每個塊有 120 個觀察值,其中“ _positions_within_chunk_ ”從 1 到 120 包含。
因此,我們可以為每個變量創建一個 120 _NaN_ 值的數組,使用' _positions_within_chunk_ '值標記塊中的所有觀察值,剩下的任何值都將被標記為 _NaN_ 。然后我們可以繪制每個變量并尋找差距。
下面的 _variable_to_series()_ 函數將獲取目標變量的塊和給定列索引的行,并將為變量返回一系列 120 個時間步長,所有可用數據都標記為來自塊。
```py
# layout a variable with breaks in the data for missing positions
def variable_to_series(chunk_train, col_ix, n_steps=5*24):
# lay out whole series
data = [nan for _ in range(n_steps)]
# mark all available data
for i in range(len(chunk_train)):
# get position in chunk
position = int(chunk_train[i, 1] - 1)
# store data
data[position] = chunk_train[i, col_ix]
return data
```
我們需要為每個塊計算一個小時的并行序列,我們可以使用它來為塊中的每個變量輸入小時特定數據。
給定一系列部分填充的小時,下面的 _interpolate_hours()_ 函數將填充一天中缺少的小時數。它通過找到第一個標記的小時,然后向前計數,填寫一天中的小時,然后向后執行相同的操作來完成此操作。
```py
# interpolate series of hours (in place) in 24 hour time
def interpolate_hours(hours):
# find the first hour
ix = -1
for i in range(len(hours)):
if not isnan(hours[i]):
ix = i
break
# fill-forward
hour = hours[ix]
for i in range(ix+1, len(hours)):
# increment hour
hour += 1
# check for a fill
if isnan(hours[i]):
hours[i] = hour % 24
# fill-backward
hour = hours[ix]
for i in range(ix-1, -1, -1):
# decrement hour
hour -= 1
# check for a fill
if isnan(hours[i]):
hours[i] = hour % 24
```
我們可以調用相同的 _variable_to_series()_ 函數(上面)來創建具有缺失值的系列小時(列索引 2),然后調用 _interpolate_hours()_ 來填補空白。
```py
# prepare sequence of hours for the chunk
hours = variable_to_series(rows, 2)
# interpolate hours
interpolate_hours(hours)
```
然后我們可以將時間傳遞給可以使用它的任何 impute 函數。
我們現在可以嘗試在同一系列中使用相同小時填充值中的缺失值。具體來說,我們將在系列中找到所有具有相同小時的行并計算中值。
下面的 _impute_missing()_ 獲取塊中的所有行,準備好的塊的一天中的小時數,以及具有變量的缺失值和變量的列索引的系列。
它首先檢查系列是否全部缺失數據,如果是這種情況則立即返回,因為不能執行任何插補。然后,它會在系列的時間步驟中進行枚舉,當它檢測到沒有數據的時間步長時,它會收集序列中所有行,并使用相同小時的數據并計算中值。
```py
# impute missing data
def impute_missing(train_chunks, rows, hours, series, col_ix):
# impute missing using the median value for hour in all series
imputed = list()
for i in range(len(series)):
if isnan(series[i]):
# collect all rows across all chunks for the hour
all_rows = list()
for rows in train_chunks:
[all_rows.append(row) for row in rows[rows[:,2]==hours[i]]]
# calculate the central tendency for target
all_rows = array(all_rows)
# fill with median value
value = nanmedian(all_rows[:, col_ix])
if isnan(value):
value = 0.0
imputed.append(value)
else:
imputed.append(series[i])
return imputed
```
### 監督表示
我們需要將每個目標變量的系列變換為具有輸入和輸出的行,以便我們可以適應有監督的機器學習算法。
具體來說,我們有一個系列,如:
```py
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```
當使用 2 個滯后變量預測+1 的前置時間時,我們將系列分為輸入( _X_ )和輸出( _y_ )模式,如下所示:
```py
X, y
1, 2, 3
2, 3, 4
3, 4, 5
4, 5, 6
5, 6, 7
6, 7, 8
7, 8, 9
```
這首先要求我們選擇一些滯后觀察值作為輸入。沒有正確的答案;相反,測試不同的數字并查看哪些有效是一個好主意。
然后,我們必須將系列分為 10 個預測提前期中的每一個的監督學習格式。例如,使用 2 個滯后觀察預測+24 可能如下所示:
```py
X, y
1, 2, 24
```
然后對 39 個目標變量中的每一個重復該過程。
然后,可以跨塊來聚集為每個目標變量的每個提前期準備的模式,以提供模型的訓練數據集。
我們還必須準備一個測試數據集。也就是說,為每個塊的每個目標變量輸入數據( _X_ ),以便我們可以將其用作輸入來預測測試數據集中的提前期。如果我們選擇滯后為 2,則測試數據集將包含每個塊的每個目標變量的最后兩個觀察值。非常直截了當。
我們可以從定義一個函數開始,該函數將為給定的完整(插補)系列創建輸入輸出模式。
下面的 _supervised_for_lead_time()_ 函數將采用一系列滯后觀察作為輸入,預測前置時間進行預測,然后返回從該系列中抽取的輸入/輸出行列表。
```py
# created input/output patterns from a sequence
def supervised_for_lead_time(series, n_lag, lead_time):
samples = list()
# enumerate observations and create input/output patterns
for i in range(n_lag, len(series)):
end_ix = i + (lead_time - 1)
# check if can create a pattern
if end_ix >= len(series):
break
# retrieve input and output
start_ix = i - n_lag
row = series[start_ix:i] + [series[end_ix]]
samples.append(row)
return samples
```
理解這件作品很重要。
我們可以測試此函數并探索不同數量的滯后變量并預測小型測試數據集的提前期。
下面是一個完整的示例,它生成一系列 20 個整數并創建一個具有兩個輸入滯后的系列,并預測+6 前置時間。
```py
# test supervised to input/output patterns
from numpy import array
# created input/output patterns from a sequence
def supervised_for_lead_time(series, n_lag, lead_time):
data = list()
# enumerate observations and create input/output patterns
for i in range(n_lag, len(series)):
end_ix = i + (lead_time - 1)
# check if can create a pattern
if end_ix >= len(series):
break
# retrieve input and output
start_ix = i - n_lag
row = series[start_ix:i] + [series[end_ix]]
data.append(row)
return array(data)
# define test dataset
data = [x for x in range(20)]
# convert to supervised format
result = supervised_for_lead_time(data, 2, 6)
# display result
print(result)
```
運行該示例將打印顯示滯后觀察結果及其相關預測提前期的結果模式。
嘗試使用此示例來熟悉此數據轉換,因為它是使用機器學習算法建模時間序列的關鍵。
```py
[[ 0 1 7]
[ 1 2 8]
[ 2 3 9]
[ 3 4 10]
[ 4 5 11]
[ 5 6 12]
[ 6 7 13]
[ 7 8 14]
[ 8 9 15]
[ 9 10 16]
[10 11 17]
[11 12 18]
[12 13 19]]
```
我們現在可以為給定目標變量系列的每個預測提前期調用 _supervised_for_lead_time()_。
下面的 _target_to_supervised()_ 函數實現了這個功能。首先,將目標變量轉換為系列,并使用上一節中開發的函數進行估算。然后為每個目標提前期創建訓練樣本。還創建了目標變量的測試樣本。
然后,為該目標變量返回每個預測提前期的訓練數據和測試輸入數據。
```py
# create supervised learning data for each lead time for this target
def target_to_supervised(chunks, rows, hours, col_ix, n_lag):
train_lead_times = list()
# get series
series = variable_to_series(rows, col_ix)
if not has_data(series):
return None, [nan for _ in range(n_lag)]
# impute
imputed = impute_missing(chunks, rows, hours, series, col_ix)
# prepare test sample for chunk-variable
test_sample = array(imputed[-n_lag:])
# enumerate lead times
lead_times = get_lead_times()
for lead_time in lead_times:
# make input/output data from series
train_samples = supervised_for_lead_time(imputed, n_lag, lead_time)
train_lead_times.append(train_samples)
return train_lead_times, test_sample
```
我們有件;我們現在需要定義驅動數據準備過程的函數。
此功能可構建訓練和測試數據集。
該方法是枚舉每個目標變量,并從所有塊中收集每個提前期的訓練數據。同時,我們在對測試數據集進行預測時收集所需的樣本作為輸入。
結果是具有維度 _[var] [提前期] [樣本]_ 的訓練數據集,其中最終維度是目標變量的預測提前期的訓練樣本行。該函數還返回具有維度 _[chunk] [var] [樣本]_ 的測試數據集,其中最終維度是用于對塊的目標變量進行預測的輸入數據。
下面的 _data_prep()_ 函數實現了這種行為,并將塊格式的數據和指定數量的滯后觀察值用作輸入。
```py
# prepare training [var][lead time][sample] and test [chunk][var][sample]
def data_prep(chunks, n_lag, n_vars=39):
lead_times = get_lead_times()
train_data = [[list() for _ in range(len(lead_times))] for _ in range(n_vars)]
test_data = [[list() for _ in range(n_vars)] for _ in range(len(chunks))]
# enumerate targets for chunk
for var in range(n_vars):
# convert target number into column number
col_ix = 3 + var
# enumerate chunks to forecast
for c_id in range(len(chunks)):
rows = chunks[c_id]
# prepare sequence of hours for the chunk
hours = variable_to_series(rows, 2)
# interpolate hours
interpolate_hours(hours)
# check for no data
if not has_data(rows[:, col_ix]):
continue
# convert series into training data for each lead time
train, test_sample = target_to_supervised(chunks, rows, hours, col_ix, n_lag)
# store test sample for this var-chunk
test_data[c_id][var] = test_sample
if train is not None:
# store samples per lead time
for lead_time in range(len(lead_times)):
# add all rows to the existing list of rows
train_data[var][lead_time].extend(train[lead_time])
# convert all rows for each var-lead time to a numpy array
for lead_time in range(len(lead_times)):
train_data[var][lead_time] = array(train_data[var][lead_time])
return array(train_data), array(test_data)
```
### 完整的例子
我們可以將所有內容組合在一起,并使用監督學習格式為機器學習算法準備訓練和測試數據集。
在預測每個預測提前期時,我們將使用先前 12 小時的滯后觀測作為輸入。
然后,生成的訓練和測試數據集將保存為二進制 NumPy 數組。
下面列出了完整的示例。
```py
# prepare data
from numpy import loadtxt
from numpy import nan
from numpy import isnan
from numpy import count_nonzero
from numpy import unique
from numpy import array
from numpy import nanmedian
from numpy import save
# split the dataset by 'chunkID', return a list of chunks
def to_chunks(values, chunk_ix=0):
chunks = list()
# get the unique chunk ids
chunk_ids = unique(values[:, chunk_ix])
# group rows by chunk id
for chunk_id in chunk_ids:
selection = values[:, chunk_ix] == chunk_id
chunks.append(values[selection, :])
return chunks
# return a list of relative forecast lead times
def get_lead_times():
return [1, 2, 3, 4, 5, 10, 17, 24, 48, 72]
# interpolate series of hours (in place) in 24 hour time
def interpolate_hours(hours):
# find the first hour
ix = -1
for i in range(len(hours)):
if not isnan(hours[i]):
ix = i
break
# fill-forward
hour = hours[ix]
for i in range(ix+1, len(hours)):
# increment hour
hour += 1
# check for a fill
if isnan(hours[i]):
hours[i] = hour % 24
# fill-backward
hour = hours[ix]
for i in range(ix-1, -1, -1):
# decrement hour
hour -= 1
# check for a fill
if isnan(hours[i]):
hours[i] = hour % 24
# return true if the array has any non-nan values
def has_data(data):
return count_nonzero(isnan(data)) < len(data)
# impute missing data
def impute_missing(train_chunks, rows, hours, series, col_ix):
# impute missing using the median value for hour in all series
imputed = list()
for i in range(len(series)):
if isnan(series[i]):
# collect all rows across all chunks for the hour
all_rows = list()
for rows in train_chunks:
[all_rows.append(row) for row in rows[rows[:,2]==hours[i]]]
# calculate the central tendency for target
all_rows = array(all_rows)
# fill with median value
value = nanmedian(all_rows[:, col_ix])
if isnan(value):
value = 0.0
imputed.append(value)
else:
imputed.append(series[i])
return imputed
# layout a variable with breaks in the data for missing positions
def variable_to_series(chunk_train, col_ix, n_steps=5*24):
# lay out whole series
data = [nan for _ in range(n_steps)]
# mark all available data
for i in range(len(chunk_train)):
# get position in chunk
position = int(chunk_train[i, 1] - 1)
# store data
data[position] = chunk_train[i, col_ix]
return data
# created input/output patterns from a sequence
def supervised_for_lead_time(series, n_lag, lead_time):
samples = list()
# enumerate observations and create input/output patterns
for i in range(n_lag, len(series)):
end_ix = i + (lead_time - 1)
# check if can create a pattern
if end_ix >= len(series):
break
# retrieve input and output
start_ix = i - n_lag
row = series[start_ix:i] + [series[end_ix]]
samples.append(row)
return samples
# create supervised learning data for each lead time for this target
def target_to_supervised(chunks, rows, hours, col_ix, n_lag):
train_lead_times = list()
# get series
series = variable_to_series(rows, col_ix)
if not has_data(series):
return None, [nan for _ in range(n_lag)]
# impute
imputed = impute_missing(chunks, rows, hours, series, col_ix)
# prepare test sample for chunk-variable
test_sample = array(imputed[-n_lag:])
# enumerate lead times
lead_times = get_lead_times()
for lead_time in lead_times:
# make input/output data from series
train_samples = supervised_for_lead_time(imputed, n_lag, lead_time)
train_lead_times.append(train_samples)
return train_lead_times, test_sample
# prepare training [var][lead time][sample] and test [chunk][var][sample]
def data_prep(chunks, n_lag, n_vars=39):
lead_times = get_lead_times()
train_data = [[list() for _ in range(len(lead_times))] for _ in range(n_vars)]
test_data = [[list() for _ in range(n_vars)] for _ in range(len(chunks))]
# enumerate targets for chunk
for var in range(n_vars):
# convert target number into column number
col_ix = 3 + var
# enumerate chunks to forecast
for c_id in range(len(chunks)):
rows = chunks[c_id]
# prepare sequence of hours for the chunk
hours = variable_to_series(rows, 2)
# interpolate hours
interpolate_hours(hours)
# check for no data
if not has_data(rows[:, col_ix]):
continue
# convert series into training data for each lead time
train, test_sample = target_to_supervised(chunks, rows, hours, col_ix, n_lag)
# store test sample for this var-chunk
test_data[c_id][var] = test_sample
if train is not None:
# store samples per lead time
for lead_time in range(len(lead_times)):
# add all rows to the existing list of rows
train_data[var][lead_time].extend(train[lead_time])
# convert all rows for each var-lead time to a numpy array
for lead_time in range(len(lead_times)):
train_data[var][lead_time] = array(train_data[var][lead_time])
return array(train_data), array(test_data)
# load dataset
train = loadtxt('AirQualityPrediction/naive_train.csv', delimiter=',')
test = loadtxt('AirQualityPrediction/naive_test.csv', delimiter=',')
# group data by chunks
train_chunks = to_chunks(train)
test_chunks = to_chunks(test)
# convert training data into supervised learning data
n_lag = 12
train_data, test_data = data_prep(train_chunks, n_lag)
print(train_data.shape, test_data.shape)
# save train and test sets to file
save('AirQualityPrediction/supervised_train.npy', train_data)
save('AirQualityPrediction/supervised_test.npy', test_data)
```
運行示例可能需要一分鐘。
結果是包含訓練和測試數據集的兩個二進制文件,我們可以在以下部分加載這些文件,以便訓練和評估問題的機器學習算法。
## 模型評估測試線束
在我們開始評估算法之前,我們需要更多的測試工具元素。
首先,我們需要能夠在訓練數據上使用 scikit-learn 模型。下面的 _fit_model()_ 函數將復制模型配置,并使其適合所提供的訓練數據。我們需要適應每個配置模型的許多(360)版本,因此這個函數將被調用很多。
```py
# fit a single model
def fit_model(model, X, y):
# clone the model configuration
local_model = clone(model)
# fit the model
local_model.fit(X, y)
return local_model
```
接下來,我們需要為每個變量擬合一個模型并預測提前期組合。
我們可以通過首先通過變量枚舉訓練數據集,然后通過提前期來完成此操作。然后我們可以擬合模型并將其存儲在具有相同結構的列表列表中,具體為: _[var] [time] [model]_ 。
下面的 _fit_models()_ 函數實現了這一點。
```py
# fit one model for each variable and each forecast lead time [var][time][model]
def fit_models(model, train):
# prepare structure for saving models
models = [[list() for _ in range(train.shape[1])] for _ in range(train.shape[0])]
# enumerate vars
for i in range(train.shape[0]):
# enumerate lead times
for j in range(train.shape[1]):
# get data
data = train[i, j]
X, y = data[:, :-1], data[:, -1]
# fit model
local_model = fit_model(model, X, y)
models[i][j].append(local_model)
return models
```
擬合模型是緩慢的部分,可以從并行化中受益,例如使用 Joblib 庫。這是一個擴展。
一旦模型適合,它們就可用于對測試數據集進行預測。
準備好的測試數據集首先按塊組織,然后按目標變量組織。預測很快,首先要檢查是否可以進行預測(我們有輸入數據),如果是,則使用適當的模型作為目標變量。然后,將使用每個直接模型預測變量的 10 個預測前置時間中的每一個。
下面的 _make_predictions()_ 函數實現了這一點,將模型列表列表和加載的測試數據集作為參數,并返回結構 _[chunks] [var] [time]的預測數組 _。
```py
# return forecasts as [chunks][var][time]
def make_predictions(models, test):
lead_times = get_lead_times()
predictions = list()
# enumerate chunks
for i in range(test.shape[0]):
# enumerate variables
chunk_predictions = list()
for j in range(test.shape[1]):
# get the input pattern for this chunk and target
pattern = test[i,j]
# assume a nan forecast
forecasts = array([nan for _ in range(len(lead_times))])
# check we can make a forecast
if has_data(pattern):
pattern = pattern.reshape((1, len(pattern)))
# forecast each lead time
forecasts = list()
for k in range(len(lead_times)):
yhat = models[j][k][0].predict(pattern)
forecasts.append(yhat[0])
forecasts = array(forecasts)
# save forecasts fore each lead time for this variable
chunk_predictions.append(forecasts)
# save forecasts for this chunk
chunk_predictions = array(chunk_predictions)
predictions.append(chunk_predictions)
return array(predictions)
```
我們需要一個要評估的模型列表。
我們可以定義一個通用的 _get_models()_ 函數,該函數負責定義映射到已配置的 scikit-learn 模型對象的模型名稱字典。
```py
# prepare a list of ml models
def get_models(models=dict()):
# ...
return models
```
最后,我們需要一個功能來推動模型評估過程。
給定模型字典,枚舉模型,首先在訓練數據上擬合模型矩陣,預測測試數據集,評估預測,并總結結果。
下面的 _evaluate_models()_ 函數實現了這一點。
```py
# evaluate a suite of models
def evaluate_models(models, train, test, actual):
for name, model in models.items():
# fit models
fits = fit_models(model, train)
# make predictions
predictions = make_predictions(fits, test)
# evaluate forecast
total_mae, _ = evaluate_forecasts(predictions, actual)
# summarize forecast
summarize_error(name, total_mae)
```
我們現在擁有評估機器學習模型所需的一切。
## 評估線性算法
在本節中,我們將檢查一套線性機器學習算法。
線性算法是假設輸出是輸入變量的線性函數的算法。這很像 ARIMA 等經典時間序列預測模型的假設。
現場檢查意味著評估一套模型,以便大致了解哪些有效。我們感興趣的是任何超過簡單自回歸模型 AR(2)的模型,其實現的 MAE 誤差約為 0.487。
我們將使用默認配置測試八種線性機器學習算法;特別:
* 線性回歸
* 套索線性回歸
* 嶺回歸
* 彈性網絡回歸
* 胡貝爾回歸
* Lasso Lars 線性回歸
* 被動攻擊性回歸
* 隨機梯度下降回歸
我們可以在 _get_models()_ 函數中定義這些模型。
```py
# prepare a list of ml models
def get_models(models=dict()):
# linear models
models['lr'] = LinearRegression()
models['lasso'] = Lasso()
models['ridge'] = Ridge()
models['en'] = ElasticNet()
models['huber'] = HuberRegressor()
models['llars'] = LassoLars()
models['pa'] = PassiveAggressiveRegressor(max_iter=1000, tol=1e-3)
models['sgd'] = SGDRegressor(max_iter=1000, tol=1e-3)
print('Defined %d models' % len(models))
return models
```
完整的代碼示例如下所示。
```py
# evaluate linear algorithms
from numpy import load
from numpy import loadtxt
from numpy import nan
from numpy import isnan
from numpy import count_nonzero
from numpy import unique
from numpy import array
from sklearn.base import clone
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
from sklearn.linear_model import ElasticNet
from sklearn.linear_model import HuberRegressor
from sklearn.linear_model import LassoLars
from sklearn.linear_model import PassiveAggressiveRegressor
from sklearn.linear_model import SGDRegressor
# split the dataset by 'chunkID', return a list of chunks
def to_chunks(values, chunk_ix=0):
chunks = list()
# get the unique chunk ids
chunk_ids = unique(values[:, chunk_ix])
# group rows by chunk id
for chunk_id in chunk_ids:
selection = values[:, chunk_ix] == chunk_id
chunks.append(values[selection, :])
return chunks
# return true if the array has any non-nan values
def has_data(data):
return count_nonzero(isnan(data)) < len(data)
# return a list of relative forecast lead times
def get_lead_times():
return [1, 2, 3, 4, 5, 10, 17, 24, 48, 72]
# fit a single model
def fit_model(model, X, y):
# clone the model configuration
local_model = clone(model)
# fit the model
local_model.fit(X, y)
return local_model
# fit one model for each variable and each forecast lead time [var][time][model]
def fit_models(model, train):
# prepare structure for saving models
models = [[list() for _ in range(train.shape[1])] for _ in range(train.shape[0])]
# enumerate vars
for i in range(train.shape[0]):
# enumerate lead times
for j in range(train.shape[1]):
# get data
data = train[i, j]
X, y = data[:, :-1], data[:, -1]
# fit model
local_model = fit_model(model, X, y)
models[i][j].append(local_model)
return models
# return forecasts as [chunks][var][time]
def make_predictions(models, test):
lead_times = get_lead_times()
predictions = list()
# enumerate chunks
for i in range(test.shape[0]):
# enumerate variables
chunk_predictions = list()
for j in range(test.shape[1]):
# get the input pattern for this chunk and target
pattern = test[i,j]
# assume a nan forecast
forecasts = array([nan for _ in range(len(lead_times))])
# check we can make a forecast
if has_data(pattern):
pattern = pattern.reshape((1, len(pattern)))
# forecast each lead time
forecasts = list()
for k in range(len(lead_times)):
yhat = models[j][k][0].predict(pattern)
forecasts.append(yhat[0])
forecasts = array(forecasts)
# save forecasts for each lead time for this variable
chunk_predictions.append(forecasts)
# save forecasts for this chunk
chunk_predictions = array(chunk_predictions)
predictions.append(chunk_predictions)
return array(predictions)
# convert the test dataset in chunks to [chunk][variable][time] format
def prepare_test_forecasts(test_chunks):
predictions = list()
# enumerate chunks to forecast
for rows in test_chunks:
# enumerate targets for chunk
chunk_predictions = list()
for j in range(3, rows.shape[1]):
yhat = rows[:, j]
chunk_predictions.append(yhat)
chunk_predictions = array(chunk_predictions)
predictions.append(chunk_predictions)
return array(predictions)
# calculate the error between an actual and predicted value
def calculate_error(actual, predicted):
# give the full actual value if predicted is nan
if isnan(predicted):
return abs(actual)
# calculate abs difference
return abs(actual - predicted)
# evaluate a forecast in the format [chunk][variable][time]
def evaluate_forecasts(predictions, testset):
lead_times = get_lead_times()
total_mae, times_mae = 0.0, [0.0 for _ in range(len(lead_times))]
total_c, times_c = 0, [0 for _ in range(len(lead_times))]
# enumerate test chunks
for i in range(len(test_chunks)):
# convert to forecasts
actual = testset[i]
predicted = predictions[i]
# enumerate target variables
for j in range(predicted.shape[0]):
# enumerate lead times
for k in range(len(lead_times)):
# skip if actual in nan
if isnan(actual[j, k]):
continue
# calculate error
error = calculate_error(actual[j, k], predicted[j, k])
# update statistics
total_mae += error
times_mae[k] += error
total_c += 1
times_c[k] += 1
# normalize summed absolute errors
total_mae /= total_c
times_mae = [times_mae[i]/times_c[i] for i in range(len(times_mae))]
return total_mae, times_mae
# summarize scores
def summarize_error(name, total_mae):
print('%s: %.3f MAE' % (name, total_mae))
# prepare a list of ml models
def get_models(models=dict()):
# linear models
models['lr'] = LinearRegression()
models['lasso'] = Lasso()
models['ridge'] = Ridge()
models['en'] = ElasticNet()
models['huber'] = HuberRegressor()
models['llars'] = LassoLars()
models['pa'] = PassiveAggressiveRegressor(max_iter=1000, tol=1e-3)
models['sgd'] = SGDRegressor(max_iter=1000, tol=1e-3)
print('Defined %d models' % len(models))
return models
# evaluate a suite of models
def evaluate_models(models, train, test, actual):
for name, model in models.items():
# fit models
fits = fit_models(model, train)
# make predictions
predictions = make_predictions(fits, test)
# evaluate forecast
total_mae, _ = evaluate_forecasts(predictions, actual)
# summarize forecast
summarize_error(name, total_mae)
# load supervised datasets
train = load('AirQualityPrediction/supervised_train.npy')
test = load('AirQualityPrediction/supervised_test.npy')
print(train.shape, test.shape)
# load test chunks for validation
testset = loadtxt('AirQualityPrediction/naive_test.csv', delimiter=',')
test_chunks = to_chunks(testset)
actual = prepare_test_forecasts(test_chunks)
# prepare list of models
models = get_models()
# evaluate models
evaluate_models(models, train, test, actual)
```
運行該示例為每個評估的算法打印 MAE。
我們可以看到,與簡單的 AR 模型相比,許多算法顯示出技能,實現了低于 0.487 的 MAE。
Huber 回歸似乎表現最佳(使用默認配置),實現了 0.434 的 MAE。
這很有趣,因為 [Huber 回歸](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.HuberRegressor.html)或[穩健回歸](https://en.wikipedia.org/wiki/Robust_regression)與 Huber 損失,是一種設計為對訓練數據集中的異常值具有魯棒性的方法。這可能表明其他方法可以通過更多的數據準備(例如標準化和/或異常值去除)來表現更好。
```py
lr: 0.454 MAE
lasso: 0.624 MAE
ridge: 0.454 MAE
en: 0.595 MAE
huber: 0.434 MAE
llars: 0.631 MAE
pa: 0.833 MAE
sgd: 0.457 MAE
```
## 非線性算法
我們可以使用相同的框架來評估一套非線性和集成機器學習算法的表現。
特別:
**非線性算法**
* k-最近鄰居
* 分類和回歸樹
* 額外的樹
* 支持向量回歸
**集合算法**
* Adaboost 的
* 袋裝決策樹
* 隨機森林
* 額外的樹木
* 梯度增壓機
下面的 _get_models()_ 函數定義了這九個模型。
```py
# prepare a list of ml models
def get_models(models=dict()):
# non-linear models
models['knn'] = KNeighborsRegressor(n_neighbors=7)
models['cart'] = DecisionTreeRegressor()
models['extra'] = ExtraTreeRegressor()
models['svmr'] = SVR()
# # ensemble models
n_trees = 100
models['ada'] = AdaBoostRegressor(n_estimators=n_trees)
models['bag'] = BaggingRegressor(n_estimators=n_trees)
models['rf'] = RandomForestRegressor(n_estimators=n_trees)
models['et'] = ExtraTreesRegressor(n_estimators=n_trees)
models['gbm'] = GradientBoostingRegressor(n_estimators=n_trees)
print('Defined %d models' % len(models))
return models
```
完整的代碼清單如下。
```py
# spot check nonlinear algorithms
from numpy import load
from numpy import loadtxt
from numpy import nan
from numpy import isnan
from numpy import count_nonzero
from numpy import unique
from numpy import array
from sklearn.base import clone
from sklearn.neighbors import KNeighborsRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.tree import ExtraTreeRegressor
from sklearn.svm import SVR
from sklearn.ensemble import AdaBoostRegressor
from sklearn.ensemble import BaggingRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import ExtraTreesRegressor
from sklearn.ensemble import GradientBoostingRegressor
# split the dataset by 'chunkID', return a list of chunks
def to_chunks(values, chunk_ix=0):
chunks = list()
# get the unique chunk ids
chunk_ids = unique(values[:, chunk_ix])
# group rows by chunk id
for chunk_id in chunk_ids:
selection = values[:, chunk_ix] == chunk_id
chunks.append(values[selection, :])
return chunks
# return true if the array has any non-nan values
def has_data(data):
return count_nonzero(isnan(data)) < len(data)
# return a list of relative forecast lead times
def get_lead_times():
return [1, 2, 3, 4, 5, 10, 17, 24, 48, 72]
# fit a single model
def fit_model(model, X, y):
# clone the model configuration
local_model = clone(model)
# fit the model
local_model.fit(X, y)
return local_model
# fit one model for each variable and each forecast lead time [var][time][model]
def fit_models(model, train):
# prepare structure for saving models
models = [[list() for _ in range(train.shape[1])] for _ in range(train.shape[0])]
# enumerate vars
for i in range(train.shape[0]):
# enumerate lead times
for j in range(train.shape[1]):
# get data
data = train[i, j]
X, y = data[:, :-1], data[:, -1]
# fit model
local_model = fit_model(model, X, y)
models[i][j].append(local_model)
return models
# return forecasts as [chunks][var][time]
def make_predictions(models, test):
lead_times = get_lead_times()
predictions = list()
# enumerate chunks
for i in range(test.shape[0]):
# enumerate variables
chunk_predictions = list()
for j in range(test.shape[1]):
# get the input pattern for this chunk and target
pattern = test[i,j]
# assume a nan forecast
forecasts = array([nan for _ in range(len(lead_times))])
# check we can make a forecast
if has_data(pattern):
pattern = pattern.reshape((1, len(pattern)))
# forecast each lead time
forecasts = list()
for k in range(len(lead_times)):
yhat = models[j][k][0].predict(pattern)
forecasts.append(yhat[0])
forecasts = array(forecasts)
# save forecasts for each lead time for this variable
chunk_predictions.append(forecasts)
# save forecasts for this chunk
chunk_predictions = array(chunk_predictions)
predictions.append(chunk_predictions)
return array(predictions)
# convert the test dataset in chunks to [chunk][variable][time] format
def prepare_test_forecasts(test_chunks):
predictions = list()
# enumerate chunks to forecast
for rows in test_chunks:
# enumerate targets for chunk
chunk_predictions = list()
for j in range(3, rows.shape[1]):
yhat = rows[:, j]
chunk_predictions.append(yhat)
chunk_predictions = array(chunk_predictions)
predictions.append(chunk_predictions)
return array(predictions)
# calculate the error between an actual and predicted value
def calculate_error(actual, predicted):
# give the full actual value if predicted is nan
if isnan(predicted):
return abs(actual)
# calculate abs difference
return abs(actual - predicted)
# evaluate a forecast in the format [chunk][variable][time]
def evaluate_forecasts(predictions, testset):
lead_times = get_lead_times()
total_mae, times_mae = 0.0, [0.0 for _ in range(len(lead_times))]
total_c, times_c = 0, [0 for _ in range(len(lead_times))]
# enumerate test chunks
for i in range(len(test_chunks)):
# convert to forecasts
actual = testset[i]
predicted = predictions[i]
# enumerate target variables
for j in range(predicted.shape[0]):
# enumerate lead times
for k in range(len(lead_times)):
# skip if actual in nan
if isnan(actual[j, k]):
continue
# calculate error
error = calculate_error(actual[j, k], predicted[j, k])
# update statistics
total_mae += error
times_mae[k] += error
total_c += 1
times_c[k] += 1
# normalize summed absolute errors
total_mae /= total_c
times_mae = [times_mae[i]/times_c[i] for i in range(len(times_mae))]
return total_mae, times_mae
# summarize scores
def summarize_error(name, total_mae):
print('%s: %.3f MAE' % (name, total_mae))
# prepare a list of ml models
def get_models(models=dict()):
# non-linear models
models['knn'] = KNeighborsRegressor(n_neighbors=7)
models['cart'] = DecisionTreeRegressor()
models['extra'] = ExtraTreeRegressor()
models['svmr'] = SVR()
# # ensemble models
n_trees = 100
models['ada'] = AdaBoostRegressor(n_estimators=n_trees)
models['bag'] = BaggingRegressor(n_estimators=n_trees)
models['rf'] = RandomForestRegressor(n_estimators=n_trees)
models['et'] = ExtraTreesRegressor(n_estimators=n_trees)
models['gbm'] = GradientBoostingRegressor(n_estimators=n_trees)
print('Defined %d models' % len(models))
return models
# evaluate a suite of models
def evaluate_models(models, train, test, actual):
for name, model in models.items():
# fit models
fits = fit_models(model, train)
# make predictions
predictions = make_predictions(fits, test)
# evaluate forecast
total_mae, _ = evaluate_forecasts(predictions, actual)
# summarize forecast
summarize_error(name, total_mae)
# load supervised datasets
train = load('AirQualityPrediction/supervised_train.npy')
test = load('AirQualityPrediction/supervised_test.npy')
print(train.shape, test.shape)
# load test chunks for validation
testset = loadtxt('AirQualityPrediction/naive_test.csv', delimiter=',')
test_chunks = to_chunks(testset)
actual = prepare_test_forecasts(test_chunks)
# prepare list of models
models = get_models()
# evaluate models
evaluate_models(models, train, test, actual)
```
運行該示例,我們可以看到許多算法與自回歸算法的基線相比表現良好,盡管在上一節中沒有一個表現與 Huber 回歸一樣好。
支持向量回歸和可能的梯度增強機器可能值得進一步研究分別達到 0.437 和 0.450 的 MAE。
```py
knn: 0.484 MAE
cart: 0.631 MAE
extra: 0.630 MAE
svmr: 0.437 MAE
ada: 0.717 MAE
bag: 0.471 MAE
rf: 0.470 MAE
et: 0.469 MAE
gbm: 0.450 MAE
```
## 調整滯后大小
在之前的抽查實驗中,滯后觀察的數量被任意固定為 12。
我們可以改變滯后觀察的數量并評估對 MAE 的影響。一些算法可能需要更多或更少的先前觀察,但是一般趨勢可能跨越算法。
準備具有一系列不同數量的滯后觀察的監督學習數據集并擬合并評估每個觀察數據的 HuberRegressor。
我試驗了以下數量的滯后觀察:
```py
[1, 3, 6, 12, 24, 36, 48]
```
結果如下:
```py
1: 0.451
3: 0.445
6: 0.441
12: 0.434
24: 0.423
36: 0.422
48: 0.439
```
下面提供了這些結果的圖表。

Huber 回歸的滯后觀測數與 MAE 的線圖
隨著滯后觀測數量的增加,我們可以看到整體 MAE 降低的總趨勢,至少到一個點,之后誤差再次開始上升。
結果表明,至少對于 HuberRegressor 算法,36 個滯后觀察可能是實現 MAE 為 0.422 的良好配置。
## 擴展
本節列出了一些擴展您可能希望探索的教程的想法。
* **數據準備**。探索簡單數據準備(如標準化或統計異常值刪除)是否可以提高模型表現。
* **工程特征**。探索工程特征(如預測時段的中值)是否可以提高模型表現
* **氣象變量**。探索在模型中添加滯后氣象變量是否可以提高表現。
* **跨站點模型**。探索組合相同類型的目標變量以及跨站點重用模型是否會提高表現。
* **算法調整**。探索調整一些表現更好的算法的超參數是否可以帶來表現改進。
如果你探索任何這些擴展,我很想知道。
## 進一步閱讀
如果您希望深入了解,本節將提供有關該主題的更多資源。
* [EMC 數據科學全球黑客馬拉松(空氣質量預測)](https://www.kaggle.com/c/dsg-hackathon/data)
* [將所有東西放入隨機森林:Ben Hamner 贏得空氣質量預測黑客馬拉松](http://blog.kaggle.com/2012/05/01/chucking-everything-into-a-random-forest-ben-hamner-on-winning-the-air-quality-prediction-hackathon/)
* [EMC 數據科學全球黑客馬拉松(空氣質量預測)的獲獎代碼](https://github.com/benhamner/Air-Quality-Prediction-Hackathon-Winning-Model)
* [分區模型的一般方法?](https://www.kaggle.com/c/dsg-hackathon/discussion/1821)
## 摘要
在本教程中,您了解了如何為空氣污染數據的多步時間序列預測開發機器學習模型。
具體來說,你學到了:
* 如何估算缺失值并轉換時間序列數據,以便可以通過監督學習算法對其進行建模。
* 如何開發和評估一套線性算法用于多步時間序列預測。
* 如何開發和評估一套非線性算法用于多步時間序列預測。
你有任何問題嗎?
在下面的評論中提出您的問題,我會盡力回答。
- Machine Learning Mastery 應用機器學習教程
- 5競爭機器學習的好處
- 過度擬合的簡單直覺,或者為什么測試訓練數據是一個壞主意
- 特征選擇簡介
- 應用機器學習作為一個搜索問題的溫和介紹
- 為什么應用機器學習很難
- 為什么我的結果不如我想的那么好?你可能過度擬合了
- 用ROC曲線評估和比較分類器表現
- BigML評論:發現本機學習即服務平臺的聰明功能
- BigML教程:開發您的第一個決策樹并進行預測
- 構建生產機器學習基礎設施
- 分類準確性不夠:可以使用更多表現測量
- 一種預測模型的巧妙應用
- 機器學習項目中常見的陷阱
- 數據清理:將凌亂的數據轉換為整潔的數據
- 機器學習中的數據泄漏
- 數據,學習和建模
- 數據管理至關重要以及為什么需要認真對待它
- 將預測模型部署到生產中
- 參數和超參數之間有什么區別?
- 測試和驗證數據集之間有什么區別?
- 發現特征工程,如何設計特征以及如何獲得它
- 如何開始使用Kaggle
- 超越預測
- 如何在評估機器學習算法時選擇正確的測試選項
- 如何定義機器學習問題
- 如何評估機器學習算法
- 如何獲得基線結果及其重要性
- 如何充分利用機器學習數據
- 如何識別數據中的異常值
- 如何提高機器學習效果
- 如何在競爭機器學習中踢屁股
- 如何知道您的機器學習模型是否具有良好的表現
- 如何布局和管理您的機器學習項目
- 如何為機器學習準備數據
- 如何減少最終機器學習模型中的方差
- 如何使用機器學習結果
- 如何解決像數據科學家這樣的問題
- 通過數據預處理提高模型精度
- 處理機器學習的大數據文件的7種方法
- 建立機器學習系統的經驗教訓
- 如何使用機器學習清單可靠地獲得準確的預測(即使您是初學者)
- 機器學習模型運行期間要做什么
- 機器學習表現改進備忘單
- 來自世界級從業者的機器學習技巧:Phil Brierley
- 模型預測精度與機器學習中的解釋
- 競爭機器學習的模型選擇技巧
- 機器學習需要多少訓練數據?
- 如何系統地規劃和運行機器學習實驗
- 應用機器學習過程
- 默認情況下可重現的機器學習結果
- 10個實踐應用機器學習的標準數據集
- 簡單的三步法到最佳機器學習算法
- 打擊機器學習數據集中不平衡類的8種策略
- 模型表現不匹配問題(以及如何處理)
- 黑箱機器學習的誘惑陷阱
- 如何培養最終的機器學習模型
- 使用探索性數據分析了解您的問題并獲得更好的結果
- 什么是數據挖掘和KDD
- 為什么One-Hot在機器學習中編碼數據?
- 為什么你應該在你的機器學習問題上進行抽樣檢查算法
- 所以,你正在研究機器學習問題......
- Machine Learning Mastery Keras 深度學習教程
- Keras 中神經網絡模型的 5 步生命周期
- 在 Python 迷你課程中應用深度學習
- Keras 深度學習庫的二元分類教程
- 如何用 Keras 構建多層感知器神經網絡模型
- 如何在 Keras 中檢查深度學習模型
- 10 個用于 Amazon Web Services 深度學習的命令行秘籍
- 機器學習卷積神經網絡的速成課程
- 如何在 Python 中使用 Keras 進行深度學習的度量
- 深度學習書籍
- 深度學習課程
- 你所知道的深度學習是一種謊言
- 如何設置 Amazon AWS EC2 GPU 以訓練 Keras 深度學習模型(分步)
- 神經網絡中批量和迭代之間的區別是什么?
- 在 Keras 展示深度學習模型訓練歷史
- 基于 Keras 的深度學習模型中的dropout正則化
- 評估 Keras 中深度學習模型的表現
- 如何評價深度學習模型的技巧
- 小批量梯度下降的簡要介紹以及如何配置批量大小
- 在 Keras 中獲得深度學習幫助的 9 種方法
- 如何使用 Keras 在 Python 中網格搜索深度學習模型的超參數
- 用 Keras 在 Python 中使用卷積神經網絡進行手寫數字識別
- 如何用 Keras 進行預測
- 用 Keras 進行深度學習的圖像增強
- 8 個深度學習的鼓舞人心的應用
- Python 深度學習庫 Keras 簡介
- Python 深度學習庫 TensorFlow 簡介
- Python 深度學習庫 Theano 簡介
- 如何使用 Keras 函數式 API 進行深度學習
- Keras 深度學習庫的多類分類教程
- 多層感知器神經網絡速成課程
- 基于卷積神經網絡的 Keras 深度學習庫中的目標識別
- 流行的深度學習庫
- 用深度學習預測電影評論的情感
- Python 中的 Keras 深度學習庫的回歸教程
- 如何使用 Keras 獲得可重現的結果
- 如何在 Linux 服務器上運行深度學習實驗
- 保存并加載您的 Keras 深度學習模型
- 用 Keras 逐步開發 Python 中的第一個神經網絡
- 用 Keras 理解 Python 中的有狀態 LSTM 循環神經網絡
- 在 Python 中使用 Keras 深度學習模型和 Scikit-Learn
- 如何使用預訓練的 VGG 模型對照片中的物體進行分類
- 在 Python 和 Keras 中對深度學習模型使用學習率調度
- 如何在 Keras 中可視化深度學習神經網絡模型
- 什么是深度學習?
- 何時使用 MLP,CNN 和 RNN 神經網絡
- 為什么用隨機權重初始化神經網絡?
- Machine Learning Mastery 深度學習 NLP 教程
- 深度學習在自然語言處理中的 7 個應用
- 如何實現自然語言處理的波束搜索解碼器
- 深度學習文檔分類的最佳實踐
- 關于自然語言處理的熱門書籍
- 在 Python 中計算文本 BLEU 分數的溫和介紹
- 使用編碼器 - 解碼器模型的用于字幕生成的注入和合并架構
- 如何用 Python 清理機器學習的文本
- 如何配置神經機器翻譯的編碼器 - 解碼器模型
- 如何開始深度學習自然語言處理(7 天迷你課程)
- 自然語言處理的數據集
- 如何開發一種深度學習的詞袋模型來預測電影評論情感
- 深度學習字幕生成模型的溫和介紹
- 如何在 Keras 中定義神經機器翻譯的編碼器 - 解碼器序列 - 序列模型
- 如何利用小實驗在 Keras 中開發字幕生成模型
- 如何從頭開發深度學習圖片標題生成器
- 如何在 Keras 中開發基于字符的神經語言模型
- 如何開發用于情感分析的 N-gram 多通道卷積神經網絡
- 如何從零開始開發神經機器翻譯系統
- 如何在 Python 中用 Keras 開發基于單詞的神經語言模型
- 如何開發一種預測電影評論情感的詞嵌入模型
- 如何使用 Gensim 在 Python 中開發詞嵌入
- 用于文本摘要的編碼器 - 解碼器深度學習模型
- Keras 中文本摘要的編碼器 - 解碼器模型
- 用于神經機器翻譯的編碼器 - 解碼器循環神經網絡模型
- 淺談詞袋模型
- 文本摘要的溫和介紹
- 編碼器 - 解碼器循環神經網絡中的注意力如何工作
- 如何利用深度學習自動生成照片的文本描述
- 如何開發一個單詞級神經語言模型并用它來生成文本
- 淺談神經機器翻譯
- 什么是自然語言處理?
- 牛津自然語言處理深度學習課程
- 如何為機器翻譯準備法語到英語的數據集
- 如何為情感分析準備電影評論數據
- 如何為文本摘要準備新聞文章
- 如何準備照片標題數據集以訓練深度學習模型
- 如何使用 Keras 為深度學習準備文本數據
- 如何使用 scikit-learn 為機器學習準備文本數據
- 自然語言處理神經網絡模型入門
- 對自然語言處理的深度學習的承諾
- 在 Python 中用 Keras 進行 LSTM 循環神經網絡的序列分類
- 斯坦福自然語言處理深度學習課程評價
- 統計語言建模和神經語言模型的簡要介紹
- 使用 Keras 在 Python 中進行 LSTM 循環神經網絡的文本生成
- 淺談機器學習中的轉換
- 如何使用 Keras 將詞嵌入層用于深度學習
- 什么是用于文本的詞嵌入
- Machine Learning Mastery 深度學習時間序列教程
- 如何開發人類活動識別的一維卷積神經網絡模型
- 人類活動識別的深度學習模型
- 如何評估人類活動識別的機器學習算法
- 時間序列預測的多層感知器網絡探索性配置
- 比較經典和機器學習方法進行時間序列預測的結果
- 如何通過深度學習快速獲得時間序列預測的結果
- 如何利用 Python 處理序列預測問題中的缺失時間步長
- 如何建立預測大氣污染日的概率預測模型
- 如何開發一種熟練的機器學習時間序列預測模型
- 如何構建家庭用電自回歸預測模型
- 如何開發多步空氣污染時間序列預測的自回歸預測模型
- 如何制定多站點多元空氣污染時間序列預測的基線預測
- 如何開發時間序列預測的卷積神經網絡模型
- 如何開發卷積神經網絡用于多步時間序列預測
- 如何開發單變量時間序列預測的深度學習模型
- 如何開發 LSTM 模型用于家庭用電的多步時間序列預測
- 如何開發 LSTM 模型進行時間序列預測
- 如何開發多元多步空氣污染時間序列預測的機器學習模型
- 如何開發多層感知器模型進行時間序列預測
- 如何開發人類活動識別時間序列分類的 RNN 模型
- 如何開始深度學習的時間序列預測(7 天迷你課程)
- 如何網格搜索深度學習模型進行時間序列預測
- 如何對單變量時間序列預測的網格搜索樸素方法
- 如何在 Python 中搜索 SARIMA 模型超參數用于時間序列預測
- 如何在 Python 中進行時間序列預測的網格搜索三次指數平滑
- 一個標準的人類活動識別問題的溫和介紹
- 如何加載和探索家庭用電數據
- 如何加載,可視化和探索復雜的多變量多步時間序列預測數據集
- 如何從智能手機數據模擬人類活動
- 如何根據環境因素預測房間占用率
- 如何使用腦波預測人眼是開放還是閉合
- 如何在 Python 中擴展長短期內存網絡的數據
- 如何使用 TimeseriesGenerator 進行 Keras 中的時間序列預測
- 基于機器學習算法的室內運動時間序列分類
- 用于時間序列預測的狀態 LSTM 在線學習的不穩定性
- 用于罕見事件時間序列預測的 LSTM 模型體系結構
- 用于時間序列預測的 4 種通用機器學習數據變換
- Python 中長短期記憶網絡的多步時間序列預測
- 家庭用電機器學習的多步時間序列預測
- Keras 中 LSTM 的多變量時間序列預測
- 如何開發和評估樸素的家庭用電量預測方法
- 如何為長短期記憶網絡準備單變量時間序列數據
- 循環神經網絡在時間序列預測中的應用
- 如何在 Python 中使用差異變換刪除趨勢和季節性
- 如何在 LSTM 中種子狀態用于 Python 中的時間序列預測
- 使用 Python 進行時間序列預測的有狀態和無狀態 LSTM
- 長短時記憶網絡在時間序列預測中的適用性
- 時間序列預測問題的分類
- Python 中長短期記憶網絡的時間序列預測
- 基于 Keras 的 Python 中 LSTM 循環神經網絡的時間序列預測
- Keras 中深度學習的時間序列預測
- 如何用 Keras 調整 LSTM 超參數進行時間序列預測
- 如何在時間序列預測訓練期間更新 LSTM 網絡
- 如何使用 LSTM 網絡的 Dropout 進行時間序列預測
- 如何使用 LSTM 網絡中的特征進行時間序列預測
- 如何在 LSTM 網絡中使用時間序列進行時間序列預測
- 如何利用 LSTM 網絡進行權重正則化進行時間序列預測
- Machine Learning Mastery 線性代數教程
- 機器學習數學符號的基礎知識
- 用 NumPy 陣列輕松介紹廣播
- 如何從 Python 中的 Scratch 計算主成分分析(PCA)
- 用于編碼器審查的計算線性代數
- 10 機器學習中的線性代數示例
- 線性代數的溫和介紹
- 用 NumPy 輕松介紹 Python 中的 N 維數組
- 機器學習向量的溫和介紹
- 如何在 Python 中為機器學習索引,切片和重塑 NumPy 數組
- 機器學習的矩陣和矩陣算法簡介
- 溫和地介紹機器學習的特征分解,特征值和特征向量
- NumPy 對預期價值,方差和協方差的簡要介紹
- 機器學習矩陣分解的溫和介紹
- 用 NumPy 輕松介紹機器學習的張量
- 用于機器學習的線性代數中的矩陣類型簡介
- 用于機器學習的線性代數備忘單
- 線性代數的深度學習
- 用于機器學習的線性代數(7 天迷你課程)
- 機器學習的線性代數
- 機器學習矩陣運算的溫和介紹
- 線性代數評論沒有廢話指南
- 學習機器學習線性代數的主要資源
- 淺談機器學習的奇異值分解
- 如何用線性代數求解線性回歸
- 用于機器學習的稀疏矩陣的溫和介紹
- 機器學習中向量規范的溫和介紹
- 學習線性代數用于機器學習的 5 個理由
- Machine Learning Mastery LSTM 教程
- Keras中長短期記憶模型的5步生命周期
- 長短時記憶循環神經網絡的注意事項
- CNN長短期記憶網絡
- 逆向神經網絡中的深度學習速成課程
- 可變長度輸入序列的數據準備
- 如何用Keras開發用于Python序列分類的雙向LSTM
- 如何開發Keras序列到序列預測的編碼器 - 解碼器模型
- 如何診斷LSTM模型的過度擬合和欠擬合
- 如何開發一種編碼器 - 解碼器模型,注重Keras中的序列到序列預測
- 編碼器 - 解碼器長短期存儲器網絡
- 神經網絡中爆炸梯度的溫和介紹
- 對時間反向傳播的溫和介紹
- 生成長短期記憶網絡的溫和介紹
- 專家對長短期記憶網絡的簡要介紹
- 在序列預測問題上充分利用LSTM
- 編輯器 - 解碼器循環神經網絡全局注意的溫和介紹
- 如何利用長短時記憶循環神經網絡處理很長的序列
- 如何在Python中對一個熱編碼序列數據
- 如何使用編碼器 - 解碼器LSTM來回顯隨機整數序列
- 具有注意力的編碼器 - 解碼器RNN體系結構的實現模式
- 學習使用編碼器解碼器LSTM循環神經網絡添加數字
- 如何學習長短時記憶循環神經網絡回聲隨機整數
- 具有Keras的長短期記憶循環神經網絡的迷你課程
- LSTM自動編碼器的溫和介紹
- 如何用Keras中的長短期記憶模型進行預測
- 用Python中的長短期內存網絡演示內存
- 基于循環神經網絡的序列預測模型的簡要介紹
- 深度學習的循環神經網絡算法之旅
- 如何重塑Keras中長短期存儲網絡的輸入數據
- 了解Keras中LSTM的返回序列和返回狀態之間的差異
- RNN展開的溫和介紹
- 5學習LSTM循環神經網絡的簡單序列預測問題的例子
- 使用序列進行預測
- 堆疊長短期內存網絡
- 什么是教師強制循環神經網絡?
- 如何在Python中使用TimeDistributed Layer for Long Short-Term Memory Networks
- 如何準備Keras中截斷反向傳播的序列預測
- 如何在使用LSTM進行訓練和預測時使用不同的批量大小
- Machine Learning Mastery 機器學習算法教程
- 機器學習算法之旅
- 用于機器學習的裝袋和隨機森林集合算法
- 從頭開始實施機器學習算法的好處
- 更好的樸素貝葉斯:從樸素貝葉斯算法中獲取最多的12個技巧
- 機器學習的提升和AdaBoost
- 選擇機器學習算法:Microsoft Azure的經驗教訓
- 機器學習的分類和回歸樹
- 什么是機器學習中的混淆矩陣
- 如何使用Python從頭開始創建算法測試工具
- 通過創建機器學習算法的目標列表來控制
- 從頭開始停止編碼機器學習算法
- 在實現機器學習算法時,不要從開源代碼開始
- 不要使用隨機猜測作為基線分類器
- 淺談機器學習中的概念漂移
- 溫和介紹機器學習中的偏差 - 方差權衡
- 機器學習的梯度下降
- 機器學習算法如何工作(他們學習輸入到輸出的映射)
- 如何建立機器學習算法的直覺
- 如何實現機器學習算法
- 如何研究機器學習算法行為
- 如何學習機器學習算法
- 如何研究機器學習算法
- 如何研究機器學習算法
- 如何在Python中從頭開始實現反向傳播算法
- 如何用Python從頭開始實現Bagging
- 如何用Python從頭開始實現基線機器學習算法
- 如何在Python中從頭開始實現決策樹算法
- 如何用Python從頭開始實現學習向量量化
- 如何利用Python從頭開始隨機梯度下降實現線性回歸
- 如何利用Python從頭開始隨機梯度下降實現Logistic回歸
- 如何用Python從頭開始實現機器學習算法表現指標
- 如何在Python中從頭開始實現感知器算法
- 如何在Python中從零開始實現隨機森林
- 如何在Python中從頭開始實現重采樣方法
- 如何用Python從頭開始實現簡單線性回歸
- 如何用Python從頭開始實現堆棧泛化(Stacking)
- K-Nearest Neighbors for Machine Learning
- 學習機器學習的向量量化
- 機器學習的線性判別分析
- 機器學習的線性回歸
- 使用梯度下降進行機器學習的線性回歸教程
- 如何在Python中從頭開始加載機器學習數據
- 機器學習的Logistic回歸
- 機器學習的Logistic回歸教程
- 機器學習算法迷你課程
- 如何在Python中從頭開始實現樸素貝葉斯
- 樸素貝葉斯機器學習
- 樸素貝葉斯機器學習教程
- 機器學習算法的過擬合和欠擬合
- 參數化和非參數機器學習算法
- 理解任何機器學習算法的6個問題
- 在機器學習中擁抱隨機性
- 如何使用Python從頭開始擴展機器學習數據
- 機器學習的簡單線性回歸教程
- 有監督和無監督的機器學習算法
- 用于機器學習的支持向量機
- 在沒有數學背景的情況下理解機器學習算法的5種技術
- 最好的機器學習算法
- 教程從頭開始在Python中實現k-Nearest Neighbors
- 通過從零開始實現它們來理解機器學習算法(以及繞過壞代碼的策略)
- 使用隨機森林:在121個數據集上測試179個分類器
- 為什么從零開始實現機器學習算法
- Machine Learning Mastery 機器學習入門教程
- 機器學習入門的四個步驟:初學者入門與實踐的自上而下策略
- 你應該培養的 5 個機器學習領域
- 一種選擇機器學習算法的數據驅動方法
- 機器學習中的分析與數值解
- 應用機器學習是一種精英政治
- 機器學習的基本概念
- 如何成為數據科學家
- 初學者如何在機器學習中弄錯
- 機器學習的最佳編程語言
- 構建機器學習組合
- 機器學習中分類與回歸的區別
- 評估自己作為數據科學家并利用結果建立驚人的數據科學團隊
- 探索 Kaggle 大師的方法論和心態:對 Diogo Ferreira 的采訪
- 擴展機器學習工具并展示掌握
- 通過尋找地標開始機器學習
- 溫和地介紹預測建模
- 通過提供結果在機器學習中獲得夢想的工作
- 如何開始機器學習:自學藍圖
- 開始并在機器學習方面取得進展
- 應用機器學習的 Hello World
- 初學者如何使用小型項目開始機器學習并在 Kaggle 上進行競爭
- 我如何開始機器學習? (簡短版)
- 我是如何開始機器學習的
- 如何在機器學習中取得更好的成績
- 如何從在銀行工作到擔任 Target 的高級數據科學家
- 如何學習任何機器學習工具
- 使用小型目標項目深入了解機器學習工具
- 獲得付費申請機器學習
- 映射機器學習工具的景觀
- 機器學習開發環境
- 機器學習金錢
- 程序員的機器學習
- 機器學習很有意思
- 機器學習是 Kaggle 比賽
- 機器學習現在很受歡迎
- 機器學習掌握方法
- 機器學習很重要
- 機器學習 Q&amp; A:概念漂移,更好的結果和學習更快
- 缺乏自學機器學習的路線圖
- 機器學習很重要
- 快速了解任何機器學習工具(即使您是初學者)
- 機器學習工具
- 找到你的機器學習部落
- 機器學習在一年
- 通過競爭一致的大師 Kaggle
- 5 程序員在機器學習中開始犯錯誤
- 哲學畢業生到機器學習從業者(Brian Thomas 采訪)
- 機器學習入門的實用建議
- 實用機器學習問題
- 使用來自 UCI 機器學習庫的數據集練習機器學習
- 使用秘籍的任何機器學習工具快速啟動
- 程序員可以進入機器學習
- 程序員應該進入機器學習
- 項目焦點:Shashank Singh 的人臉識別
- 項目焦點:使用 Mahout 和 Konstantin Slisenko 進行堆棧交換群集
- 機器學習自學指南
- 4 個自學機器學習項目
- álvaroLemos 如何在數據科學團隊中獲得機器學習實習
- 如何思考機器學習
- 現實世界機器學習問題之旅
- 有關機器學習的有用知識
- 如果我沒有學位怎么辦?
- 如果我不是一個優秀的程序員怎么辦?
- 如果我不擅長數學怎么辦?
- 為什么機器學習算法會處理以前從未見過的數據?
- 是什么阻礙了你的機器學習目標?
- 什么是機器學習?
- 機器學習適合哪里?
- 為什么要進入機器學習?
- 研究對您來說很重要的機器學習問題
- 你這樣做是錯的。為什么機器學習不必如此困難
- Machine Learning Mastery Sklearn 教程
- Scikit-Learn 的溫和介紹:Python 機器學習庫
- 使用 Python 管道和 scikit-learn 自動化機器學習工作流程
- 如何以及何時使用帶有 scikit-learn 的校準分類模型
- 如何比較 Python 中的機器學習算法與 scikit-learn
- 用于機器學習開發人員的 Python 崩潰課程
- 用 scikit-learn 在 Python 中集成機器學習算法
- 使用重采樣評估 Python 中機器學習算法的表現
- 使用 Scikit-Learn 在 Python 中進行特征選擇
- Python 中機器學習的特征選擇
- 如何使用 scikit-learn 在 Python 中生成測試數據集
- scikit-learn 中的機器學習算法秘籍
- 如何使用 Python 處理丟失的數據
- 如何開始使用 Python 進行機器學習
- 如何使用 Scikit-Learn 在 Python 中加載數據
- Python 中概率評分方法的簡要介紹
- 如何用 Scikit-Learn 調整算法參數
- 如何在 Mac OS X 上安裝 Python 3 環境以進行機器學習和深度學習
- 使用 scikit-learn 進行機器學習簡介
- 從 shell 到一本帶有 Fernando Perez 單一工具的書的 IPython
- 如何使用 Python 3 為機器學習開發創建 Linux 虛擬機
- 如何在 Python 中加載機器學習數據
- 您在 Python 中的第一個機器學習項目循序漸進
- 如何使用 scikit-learn 進行預測
- 用于評估 Python 中機器學習算法的度量標準
- 使用 Pandas 為 Python 中的機器學習準備數據
- 如何使用 Scikit-Learn 為 Python 機器學習準備數據
- 項目焦點:使用 Artem Yankov 在 Python 中進行事件推薦
- 用于機器學習的 Python 生態系統
- Python 是應用機器學習的成長平臺
- Python 機器學習書籍
- Python 機器學習迷你課程
- 使用 Pandas 快速和骯臟的數據分析
- 使用 Scikit-Learn 重新調整 Python 中的機器學習數據
- 如何以及何時使用 ROC 曲線和精確調用曲線進行 Python 分類
- 使用 scikit-learn 在 Python 中保存和加載機器學習模型
- scikit-learn Cookbook 書評
- 如何使用 Anaconda 為機器學習和深度學習設置 Python 環境
- 使用 scikit-learn 在 Python 中進行 Spot-Check 分類機器學習算法
- 如何在 Python 中開發可重復使用的抽樣檢查算法框架
- 使用 scikit-learn 在 Python 中進行 Spot-Check 回歸機器學習算法
- 使用 Python 中的描述性統計來了解您的機器學習數據
- 使用 OpenCV,Python 和模板匹配來播放“哪里是 Waldo?”
- 使用 Pandas 在 Python 中可視化機器學習數據
- Machine Learning Mastery 統計學教程
- 淺談計算正態匯總統計量
- 非參數統計的溫和介紹
- Python中常態測試的溫和介紹
- 淺談Bootstrap方法
- 淺談機器學習的中心極限定理
- 淺談機器學習中的大數定律
- 機器學習的所有統計數據
- 如何計算Python中機器學習結果的Bootstrap置信區間
- 淺談機器學習的Chi-Squared測試
- 機器學習的置信區間
- 隨機化在機器學習中解決混雜變量的作用
- 機器學習中的受控實驗
- 機器學習統計學速成班
- 統計假設檢驗的關鍵值以及如何在Python中計算它們
- 如何在機器學習中談論數據(統計學和計算機科學術語)
- Python中數據可視化方法的簡要介紹
- Python中效果大小度量的溫和介紹
- 估計隨機機器學習算法的實驗重復次數
- 機器學習評估統計的溫和介紹
- 如何計算Python中的非參數秩相關性
- 如何在Python中計算數據的5位數摘要
- 如何在Python中從頭開始編寫學生t檢驗
- 如何在Python中生成隨機數
- 如何轉換數據以更好地擬合正態分布
- 如何使用相關來理解變量之間的關系
- 如何使用統計信息識別數據中的異常值
- 用于Python機器學習的隨機數生成器簡介
- k-fold交叉驗證的溫和介紹
- 如何計算McNemar的比較兩種機器學習量詞的測試
- Python中非參數統計顯著性測試簡介
- 如何在Python中使用參數統計顯著性測試
- 機器學習的預測間隔
- 應用統計學與機器學習的密切關系
- 如何使用置信區間報告分類器表現
- 統計數據分布的簡要介紹
- 15 Python中的統計假設檢驗(備忘單)
- 統計假設檢驗的溫和介紹
- 10如何在機器學習項目中使用統計方法的示例
- Python中統計功效和功耗分析的簡要介紹
- 統計抽樣和重新抽樣的簡要介紹
- 比較機器學習算法的統計顯著性檢驗
- 機器學習中統計容差區間的溫和介紹
- 機器學習統計書籍
- 評估機器學習模型的統計數據
- 機器學習統計(7天迷你課程)
- 用于機器學習的簡明英語統計
- 如何使用統計顯著性檢驗來解釋機器學習結果
- 什么是統計(為什么它在機器學習中很重要)?
- Machine Learning Mastery 時間序列入門教程
- 如何在 Python 中為時間序列預測創建 ARIMA 模型
- 用 Python 進行時間序列預測的自回歸模型
- 如何回溯機器學習模型的時間序列預測
- Python 中基于時間序列數據的基本特征工程
- R 的時間序列預測熱門書籍
- 10 挑戰機器學習時間序列預測問題
- 如何將時間序列轉換為 Python 中的監督學習問題
- 如何將時間序列數據分解為趨勢和季節性
- 如何用 ARCH 和 GARCH 模擬波動率進行時間序列預測
- 如何將時間序列數據集與 Python 區分開來
- Python 中時間序列預測的指數平滑的溫和介紹
- 用 Python 進行時間序列預測的特征選擇
- 淺談自相關和部分自相關
- 時間序列預測的 Box-Jenkins 方法簡介
- 用 Python 簡要介紹時間序列的時間序列預測
- 如何使用 Python 網格搜索 ARIMA 模型超參數
- 如何在 Python 中加載和探索時間序列數據
- 如何使用 Python 對 ARIMA 模型進行手動預測
- 如何用 Python 進行時間序列預測的預測
- 如何使用 Python 中的 ARIMA 進行樣本外預測
- 如何利用 Python 模擬殘差錯誤來糾正時間序列預測
- 使用 Python 進行數據準備,特征工程和時間序列預測的移動平均平滑
- 多步時間序列預測的 4 種策略
- 如何在 Python 中規范化和標準化時間序列數據
- 如何利用 Python 進行時間序列預測的基線預測
- 如何使用 Python 對時間序列預測數據進行功率變換
- 用于時間序列預測的 Python 環境
- 如何重構時間序列預測問題
- 如何使用 Python 重新采樣和插值您的時間序列數據
- 用 Python 編寫 SARIMA 時間序列預測
- 如何在 Python 中保存 ARIMA 時間序列預測模型
- 使用 Python 進行季節性持久性預測
- 基于 ARIMA 的 Python 歷史規模敏感性預測技巧分析
- 簡單的時間序列預測模型進行測試,這樣你就不會欺騙自己
- 標準多變量,多步驟和多站點時間序列預測問題
- 如何使用 Python 檢查時間序列數據是否是固定的
- 使用 Python 進行時間序列數據可視化
- 7 個機器學習的時間序列數據集
- 時間序列預測案例研究與 Python:波士頓每月武裝搶劫案
- Python 的時間序列預測案例研究:巴爾的摩的年度用水量
- 使用 Python 進行時間序列預測研究:法國香檳的月銷售額
- 使用 Python 的置信區間理解時間序列預測不確定性
- 11 Python 中的經典時間序列預測方法(備忘單)
- 使用 Python 進行時間序列預測表現測量
- 使用 Python 7 天迷你課程進行時間序列預測
- 時間序列預測作為監督學習
- 什么是時間序列預測?
- 如何使用 Python 識別和刪除時間序列數據的季節性
- 如何在 Python 中使用和刪除時間序列數據中的趨勢信息
- 如何在 Python 中調整 ARIMA 參數
- 如何用 Python 可視化時間序列殘差預測錯誤
- 白噪聲時間序列與 Python
- 如何通過時間序列預測項目
- Machine Learning Mastery XGBoost 教程
- 通過在 Python 中使用 XGBoost 提前停止來避免過度擬合
- 如何在 Python 中調優 XGBoost 的多線程支持
- 如何配置梯度提升算法
- 在 Python 中使用 XGBoost 進行梯度提升的數據準備
- 如何使用 scikit-learn 在 Python 中開發您的第一個 XGBoost 模型
- 如何在 Python 中使用 XGBoost 評估梯度提升模型
- 在 Python 中使用 XGBoost 的特征重要性和特征選擇
- 淺談機器學習的梯度提升算法
- 應用機器學習的 XGBoost 簡介
- 如何在 macOS 上為 Python 安裝 XGBoost
- 如何在 Python 中使用 XGBoost 保存梯度提升模型
- 從梯度提升開始,比較 165 個數據集上的 13 種算法
- 在 Python 中使用 XGBoost 和 scikit-learn 進行隨機梯度提升
- 如何使用 Amazon Web Services 在云中訓練 XGBoost 模型
- 在 Python 中使用 XGBoost 調整梯度提升的學習率
- 如何在 Python 中使用 XGBoost 調整決策樹的數量和大小
- 如何在 Python 中使用 XGBoost 可視化梯度提升決策樹
- 在 Python 中開始使用 XGBoost 的 7 步迷你課程