def get_data(self):
x_train, y_train, x_val, y_val, x_test, y_test = [], [], [], [], [], []
if self.data is None:
self.data = {}
if self.cache_dataset and os.path.exists(self.cache_file_name):
x_train, y_train, x_val, y_val, x_test, y_test = self._load_cache_train_val_test()
else:
x_train, y_train, x_val, y_val, x_test, y_test = self._generate_train_val_test()
self.feature_dim = x_train.shape[-1]
self.ext_dim = self.feature_dim - self.output_dim
self.scaler = self._get_scalar(self.scaler_type,
x_train[..., :self.output_dim], y_train[..., :self.output_dim])
self.ext_scaler = self._get_scalar(self.ext_scaler_type,
x_train[..., self.output_dim:], y_train[..., self.output_dim:])
x_train[..., :self.output_dim] = self.scaler.transform(x_train[..., :self.output_dim])
y_train[..., :self.output_dim] = self.scaler.transform(y_train[..., :self.output_dim])
x_val[..., :self.output_dim] = self.scaler.transform(x_val[..., :self.output_dim])
y_val[..., :self.output_dim] = self.scaler.transform(y_val[..., :self.output_dim])
x_test[..., :self.output_dim] = self.scaler.transform(x_test[..., :self.output_dim])
y_test[..., :self.output_dim] = self.scaler.transform(y_test[..., :self.output_dim])
if self.normal_external:
x_train[..., self.output_dim:] = self.ext_scaler.transform(x_train[..., self.output_dim:])
y_train[..., self.output_dim:] = self.ext_scaler.transform(y_train[..., self.output_dim:])
x_val[..., self.output_dim:] = self.ext_scaler.transform(x_val[..., self.output_dim:])
y_val[..., self.output_dim:] = self.ext_scaler.transform(y_val[..., self.output_dim:])
x_test[..., self.output_dim:] = self.ext_scaler.transform(x_test[..., self.output_dim:])
y_test[..., self.output_dim:] = self.ext_scaler.transform(y_test[..., self.output_dim:])
train_data = list(zip(x_train, y_train))
eval_data = list(zip(x_val, y_val))
test_data = list(zip(x_test, y_test))
self.train_dataloader, self.eval_dataloader, self.test_dataloader = \
generate_dataloader(train_data, eval_data, test_data, self.feature_name,
self.batch_size, self.num_workers, pad_with_last_sample=self.pad_with_last_sample,
distributed=self.distributed)
self.num_batches = len(self.train_dataloader)
self.pattern_key_file = os.path.join(
'./libcity/cache/dataset_cache/', 'pattern_keys_{}_{}_{}_{}_{}_{}'.format(
self.cluster_method, self.dataset, self.cand_key_days, self.s_attn_size, self.n_cluster, self.cluster_max_iter))
if not os.path.exists(self.pattern_key_file + ".npy"):
cand_key_time_steps = self.cand_key_days * self.points_per_day
pattern_cand_keys = x_train[:cand_key_time_steps, :self.s_attn_size, :, :self.output_dim].swapaxes(1, 2).reshape(-1, self.s_attn_size, self.output_dim)
self._logger.info("Clustering...")
if self.cluster_method == "kshape":
pattern_key_list = []
for i in range(self.output_dim):
km = KShape(n_clusters=self.n_cluster, max_iter=self.cluster_max_iter).fit(pattern_cand_keys[..., i: i+1])
pattern_key_list.append(km.cluster_centers_)
self.pattern_keys = np.concatenate(pattern_key_list, axis=-1)
else:
km = TimeSeriesKMeans(n_clusters=self.n_cluster, metric="euclidean", max_iter=self.cluster_max_iter).fit(pattern_cand_keys)
self.pattern_keys = km.cluster_centers_
np.save(self.pattern_key_file, self.pattern_keys)
self._logger.info("Saved at file " + self.pattern_key_file + ".npy")
else:
self.pattern_keys = np.load(self.pattern_key_file + ".npy")
self._logger.info("Loaded file " + self.pattern_key_file + ".npy")
return self.train_dataloader, self.eval_dataloader, self.test_dataloader
这段代码定义了一个名为`get_data`的方法,主要用于加载和处理训练、验证和测试数据,并生成对应的数据加载器。
1. `def get_data(self):`
定义`get_data`方法。
2. `x_train, y_train, x_val, y_val, x_test, y_test = [], [], [], [], [], []`
初始化六个空列表用于存储训练、验证和测试数据的特征和标签。
3. `if self.data is None:`
检查`self.data`是否为`None`。
4. `self.data = {}`
如果`self.data`为空,初始化为空字典。
5. `if self.cache_dataset and os.path.exists(self.cache_file_name):`
检查是否启用数据缓存并且缓存文件是否存在。
6. `x_train, y_train, x_val, y_val, x_test, y_test = self._load_cache_train_val_test()`
如果缓存文件存在,从缓存文件加载数据。
7. `else:`
否则,生成新的训练、验证和测试数据。
8. `x_train, y_train, x_val, y_val, x_test, y_test = self._generate_train_val_test()`
调用方法生成新的训练、验证和测试数据。
9. `self.feature_dim = x_train.shape[-1]`
获取特征的维度。
10. `self.ext_dim = self.feature_dim - self.output_dim`
计算外部特征的维度。
11. `self.scaler = self._get_scalar(self.scaler_type, x_train[..., :self.output_dim], y_train[..., :self.output_dim])`
初始化用于特征缩放的`scaler`对象。
12. `self.ext_scaler = self._get_scalar(self.ext_scaler_type, x_train[..., self.output_dim:], y_train[..., self.output_dim:])`
初始化用于外部特征缩放的`ext_scaler`对象。
13. `x_train[..., :self.output_dim] = self.scaler.transform(x_train[..., :self.output_dim])`
对训练数据的特征部分进行缩放。
14. `y_train[..., :self.output_dim] = self.scaler.transform(y_train[..., :self.output_dim])`
对训练数据的标签部分进行缩放。
15. `x_val[..., :self.output_dim] = self.scaler.transform(x_val[..., :self.output_dim])`
对验证数据的特征部分进行缩放。
16. `y_val[..., :self.output_dim] = self.scaler.transform(y_val[..., :self.output_dim])`
对验证数据的标签部分进行缩放。
17. `x_test[..., :self.output_dim] = self.scaler.transform(x_test[..., :self.output_dim])`
对测试数据的特征部分进行缩放。
18. `y_test[..., :self.output_dim] = self.scaler.transform(y_test[..., :self.output_dim])`
对测试数据的标签部分进行缩放。
19. `if self.normal_external:`
检查是否需要对外部特征进行标准化。
20. `x_train[..., self.output_dim:] = self.ext_scaler.transform(x_train[..., self.output_dim:])`
对训练数据的外部特征进行缩放。
21. `y_train[..., self.output_dim:] = self.ext_scaler.transform(y_train[..., self.output_dim:])`
对训练数据的外部标签进行缩放。
22. `x_val[..., self.output_dim:] = self.ext_scaler.transform(x_val[..., self.output_dim:])`
对验证数据的外部特征进行缩放。
23. `y_val[..., self.output_dim:] = self.ext_scaler.transform(y_val[..., self.output_dim:])`
对验证数据的外部标签进行缩放。
24. `x_test[..., self.output_dim:] = self.ext_scaler.transform(x_test[..., self.output_dim:])`
对测试数据的外部特征进行缩放。
25. `y_test[..., self.output_dim:] = self.ext_scaler.transform(y_test[..., self.output_dim:])`
对测试数据的外部标签进行缩放。
26. `train_data = list(zip(x_train, y_train))`
将训练数据的特征和标签组合成一个列表。
27. `eval_data = list(zip(x_val, y_val))`
将验证数据的特征和标签组合成一个列表。
28. `test_data = list(zip(x_test, y_test))`
将测试数据的特征和标签组合成一个列表。
29. `self.train_dataloader, self.eval_dataloader, self.test_dataloader = generate_dataloader(train_data, eval_data, test_data, self.feature_name, self.batch_size, self.num_workers, pad_with_last_sample=self.pad_with_last_sample, distributed=self.distributed)`
调用`generate_dataloader`方法生成训练、验证和测试数据加载器。
30. `self.num_batches = len(self.train_dataloader)`
获取训练数据加载器的批次数量。
31. `self.pattern_key_file = os.path.join('./libcity/cache/dataset_cache/', 'pattern_keys_{}_{}_{}_{}_{}_{}'.format(self.cluster_method, self.dataset, self.cand_key_days, self.s_attn_size, self.n_cluster, self.cluster_max_iter))`
构造保存模式键的文件路径。
32. `if not os.path.exists(self.pattern_key_file + ".npy"):`
检查模式键文件是否存在。
33. `cand_key_time_steps = self.cand_key_days * self.points_per_day`
计算候选键时间步数。
34. `pattern_cand_keys = x_train[:cand_key_time_steps, :self.s_attn_size, :, :self.output_dim].swapaxes(1, 2).reshape(-1, self.s_attn_size, self.output_dim)`
生成候选模式键。
35. `self._logger.info("Clustering...")`
记录聚类开始信息。
36. `if self.cluster_method == "kshape":`
检查是否使用KShape聚类方法。
37. `pattern_key_list = []`
初始化模式键列表。
38. `for i in range(self.output_dim):`
遍历输出维度。
39. `km = KShape(n_clusters=self.n_cluster, max_iter=self.cluster_max_iter).fit(pattern_cand_keys[..., i: i+1])`
对每个维度的候选模式键进行KShape聚类。
40. `pattern_key_list.append(km.cluster_centers_)`
将聚类中心添加到模式键列表中。
41. `self.pattern_keys = np.concatenate(pattern_key_list, axis=-1)`
将模式键列表拼接成一个数组。
42. `else:`
如果不是使用KShape方法。
43. `km = TimeSeriesKMeans(n_clusters=self.n_cluster, metric="euclidean", max_iter=self.cluster_max_iter).fit(pattern_cand_keys)`
使用TimeSeriesKMeans方法进行聚类。
44. `self.pattern_keys = km.cluster_centers_`
获取聚类中心。
45. `np.save(self.pattern_key_file, self.pattern_keys)`
将模式键保存到文件。
46. `self._logger.info("Saved at file " + self.pattern_key_file + ".npy")`
记录保存文件信息。
47. `else:`
如果模式键文件已存在。
48. `self.pattern_keys = np.load(self.pattern_key_file + ".npy")`
加载模式键文件。
49. `self._logger.info("Loaded file " + self.pattern_key_file + ".npy")`
记录加载文件信息。
50. `return self.train_dataloader, self.eval_dataloader, self.test_dataloader`
返回训练、验证和测试数据加载器。