深度学习对 xy 空间坐标的时间序列进行分类 - python

Posted

技术标签:

【中文标题】深度学习对 xy 空间坐标的时间序列进行分类 - python【英文标题】:Deep learning to classify a time series of xy spatial coordinates - python 【发布时间】:2021-10-02 01:07:18 【问题描述】:

我遇到了一些关于 DL 分类问题的问题。我将附上一个简短的训练数据示例来帮助描述问题。

数据是xy点的时间序列,由更小的子序列event组成。所以每个唯一的event 都是独立的。我有两个独特的序列(10,20) 低于偶数时间长度。对于给定的序列,每个单独的点都有自己的唯一标识符user_id。这些点的 xy 轨迹在给定序列上会略有不同,具体时间段可在 interval 中找到。我还有一个单独的 xy 点用作参考 (centre_x, center_y),它详细说明了所有点的大约中间/中心。

最后,target_label 对这些点相对于彼此的位置进行分类。所以以centre_x, center_y为参考,有5个类Middle、Top、Bottom、Right、Left。每个唯一的event 只能有一个标签。

问题:

    数据集显然很小,但我担心准确性。我想我需要合并参考点(centre_x, center_y)

    每次测试迭代我都会收到所有这些警告。我认为这与转换为张量有关,但它没有任何帮助。

    WARNING:tensorflow:7 次调用 触发了 tf.function 回溯。跟踪是昂贵的,过多的跟踪可能是由于(1)在循环中重复创建 @tf.function,(2)传递不同形状的张量,(3)传递 Python 对象而不是张量。对于 (1),请在循环之外定义您的 @tf.function。对于 (2),@tf.function 具有 Experimental_relax_shapes=True 选项,可以放宽可以避免不必要的回溯的参数形状。 (3) 详情请参考https://www.tensorflow.org/guide/function#controlling_retracing和https://www.tensorflow.org/api_docs/python/tf/function。

示例 df:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# number of intervals
n = 10

# center locations for points
locs_1 = 'A': (5,5),
      'B': (5,8),
      'C': (5,2),
      'D': (8,5)

# initialize data 
data_1 = pd.DataFrame(index=range(n*len(locs_1)), columns=['x','y','user_id'])
for i, group in enumerate(locs_1.keys()):

    data_1.loc[i*n:((i+1)*n)-1,['x','y']] = np.random.normal(locs_1[group], 
                                                       [0.2,0.2], 
                                                       [n,2]) 
    data_1.loc[i*n:((i+1)*n)-1,['user_id']] = group

# generate time interavls
data_1['interval'] = data_1.groupby('user_id').cumcount() + 1

# assign unique string to differentiate sequences
data_1['event'] = 10

# center of all points for unqiue sequence 1
data_1['center_x'] = 5
data_1['center_y'] = 5

# classify labels
data_1['target_label'] = ['Middle' if ele  == 'A' else 'Top' if ele == 'B' else 'Bottom' if ele == 'C' else 'Right' for ele in data_1['user_id']]

# center locations for points
locs_2 = 'A': (14,15),
      'B': (16,15),
      'C': (15,12),
      'D': (19,15)

# initialize data 
data_2 = pd.DataFrame(index=range(n*len(locs_2)), columns=['x','y','user_id'])
for i, group in enumerate(locs_2.keys()):

    data_2.loc[i*n:((i+1)*n)-1,['x','y']] = np.random.normal(locs_2[group], 
                                                       [0.2,0.2], 
                                                       [n,2]) 
    data_2.loc[i*n:((i+1)*n)-1,['user_id']] = group

# generate time interavls
data_2['interval'] = data_2.groupby('user_id').cumcount() + 1

# center of points for unqiue sequence 1
data_2['event'] = 20

# center of all points for unqiue sequence 2
data_2['center_x'] = 15
data_2['center_y'] = 15

# classify labels
data_2['target_label'] = ['Middle' if ele  == 'A' else 'Middle' if ele == 'B' else 'Bottom' if ele == 'C' else 'Right' for ele in data_2['user_id']]

df = pd.concat([data_1, data_2])

df = df.sort_values(by = ['event','interval','user_id']).reset_index(drop = True)

df:

            x          y user_id  interval  event  center_x  center_y target_label
0    5.288275   5.211246       A         1     10         5         5       Middle
1    4.765987   8.200895       B         1     10         5         5          Top
2    4.943518   1.645249       C         1     10         5         5       Bottom
3    7.930763   4.965233       D         1     10         5         5        Right
4    4.866746   4.980674       A         2     10         5         5       Middle
..        ...        ...     ...       ...    ...       ...       ...          ...
75  18.929254  15.297437       D         9     20        15        15        Right
76  13.701538  15.049276       A        10     20        15        15       Middle
77  16.028816  14.985672       B        10     20        15        15       Middle
78  15.044336  11.631358       C        10     20        15        15       Bottom
79   18.95508  15.217064       D        10     20        15        15        Right

型号:

labels = df['target_label'].dropna().sort_values().unique()

n_samples = df.groupby(['user_id', 'event']).ngroups
n_ints = 10

X = df[['x','y']].values.reshape(n_samples, n_ints, 2).astype('float32')

y = df.drop_duplicates(subset = ['event','user_id','target_label'])

y = np.array(y['target_label'].groupby(level = 0).apply(lambda x: [x.values[0]]).tolist())

y = label_binarize(y, classes = labels)

# test, train split
trainX, testX, trainy, testy = train_test_split(X, y, test_size = 0.2)

# load the dataset, returns train and test X and y elements
def load_dataset():

    # test, train split
    trainX, testX, trainy, testy = train_test_split(X, y, test_size = 0.2)

    return trainX, trainy, testX, testy

# fit and evaluate a model
def evaluate_model(trainX, trainy, testX, testy):
    verbose, epochs, batch_size = 0, 10, 32
    n_timesteps, n_features, n_outputs = trainX.shape[1], trainX.shape[2], trainy.shape[1]
    model = Sequential()
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(n_timesteps,n_features)))
    model.add(Conv1D(filters=64, kernel_size=3, activation='relu'))
    model.add(Dropout(0.5))
    model.add(MaxPooling1D(pool_size=2))
    model.add(Flatten())
    model.add(Dense(100, activation='relu'))
    model.add(Dense(n_outputs, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    # fit network
    model.fit(trainX, trainy, epochs=epochs, batch_size=batch_size, verbose=verbose)
    # evaluate model
    _, accuracy = model.evaluate(testX, testy, batch_size=batch_size, verbose=0)
    return accuracy

# summarize scores
def summarize_results(scores):
    print(scores)
    m, s = np.mean(scores), np.std(scores)
    print('Accuracy: %.3f%% (+/-%.3f)' % (m, s))

# run an experiment
def run_experiment(repeats=10):
    # load data
    trainX, trainy, testX, testy = load_dataset()
    # repeat experiment
    scores = list()
    for r in range(repeats):
        #r = tf.convert_to_tensor(r, dtype=tf.int32)
        score = evaluate_model(trainX, trainy, testX, testy)
        score = score * 100.0
        print('>#%d: %.3f' % (r+1, score))
        scores.append(score)
    # summarize results
    summarize_results(scores)

# run the experiment
run_experiment()

【问题讨论】:

我不是要代码。我正在询问示例的说明或来源。在通过各种站点拖网几天后,我找不到任何使用 xy 坐标数据的东西。这就像你甚至没有阅读内容。我已经两次说明了问题的预期目的,但我会用粗体和大写字母表示。 您的 原始数据 的平均值是否只有 x 和 y 列?还是除目标之外的所有列?您可以根据需要使用所有架构和层。您可以尝试一下,看看哪一种更适合您的问题。但是,如果是序列,最好使用 LSTM、RNN、GRU 层,甚至结合 Conv1D 和 Dense 层。但你到底想要什么?您是否尝试过任何模型并且对它们不满意?你想提高准确性吗?我认为,如果您至少共享一个数据样本和可重现的代码,那将是一件好事,这样我们就可以为您修改您的代码。 示例数据框是我的训练数据集中的所有信息。对于测试数据集(target_label 除外),我将使用相同的方法。我理解您的观点,但我找不到任何将 xy 坐标数据作为单个输入变量的示例。还是您会将它们视为单独的变量? 是的。它们是单独的变量。假设您有 5 个变量输入(5 个特征)和 1 个输出。因此,您的输入数据形状应该类似于 (100,5),这意味着您有 100 个样本,每个样本都有 5 个特征,输出形状将是 (100,),这意味着您有 1 个标签(1 个数字)对应于每个输入。如果你想使用时间序列或序列(比如每个样本有 10 个时间步),那么输入形状应该像 (100,10,5) 和输出 (100,)。火车数据的第二个维度应该是时间步长。 警告似乎是关于可能的运行时优化,而不是影响结果。 【参考方案1】:

您正在尝试使用长度为 10 的 2d 时间序列进行时间序列分类。似乎每个类只有少数示例,这对于进行任何神经网络训练来说太少了。即使您有数百个示例,我也建议您使用一种能够处理较少数据的方法。一个例子是使用 K 近邻,使用时间序列特定的距离度量,例如动态时间规整。

【讨论】:

以上是关于深度学习对 xy 空间坐标的时间序列进行分类 - python的主要内容,如果未能解决你的问题,请参考以下文章

PointNetPointNet++ 基于深度学习的3D点云分类和分割

PointNetPointNet++ 基于深度学习的3D点云分类和分割

如何在python中对存储xy坐标的二维数组进行排序?

添加xy坐标生成面要素-建模方式实现

pytorch学习笔记:多维特征的分类问题

深度学习——机器学习策略