【发布时间】:2022-10-15 03:02:23
【问题描述】:
我有许多来自不同设备的时间序列数据(时间和电压)。我试图将这个时间序列数据转换为图像数组,以便它可以用作图像,我可以在图像上应用 CNN 并可以分类数据来自哪个设备。它基于假设不同的设备产生不同的电压特征,这些特征应该是可区分的。我应用了一个函数,将时间序列数据拆分为图像数组,然后使用 CNN 进行分类。图像尺寸为 14x100 像素。问题是模型的准确性没有改变或几乎没有改变。请在下面找到完整的编码
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import os
import tensorflow as tf
from sklearn.metrics import plot_confusion_matrix, ConfusionMatrixDisplay, confusion_matrix
#Reading data from directory
import pathlib
data_dir = ('Test')
data_dir = pathlib.Path(data_dir)
#File name dictionary
file_name_dict = {
'Device_1' : list(data_dir.glob('Device_1/*.csv')),
'Device_2' : list(data_dir.glob('Device_2/*.csv')),
'Device_3' : list(data_dir.glob('Device_3/*.csv')),
'Device_4' : list(data_dir.glob('Device_4/*.csv')),
'Device_5' : list(data_dir.glob('Device_5/*.csv')),
'Device_6' : list(data_dir.glob('Device_6/*.csv'))
}
#File label dictionary
file_label_dict = {
'Device_1' : 0,
'Device_2' : 1,
'Device_3' : 2,
'Device_4' : 3,
'Device_5' : 4,
'Device_6' : 5,
}
#Processing and labelling the data
device_list, device_label = [],[] #compressed
#Reading each file, replacing original value with moving average value
for device_name, folder in file_name_dict.items():
for file in folder:
file_df = pd.read_csv(str(file))
file_df.columns = ['time', 'voltage']
file_df['MA'] = file_df['voltage'].rolling(10,min_periods=0).mean()# moving average
file_df= file_df.drop('voltage',axis=1)
file_df.rename(columns={'MA':'voltage'},inplace=True)
#Applying a function
threshold = file_df['voltage'].diff().gt(1)
group = (threshold&~threshold.shift(fill_value=False)).cumsum().add(1)
time= lambda i: i['time'].groupby(group).apply(lambda j: j- j.iloc[0])
df_2 = (file_df.assign(bit=group,time=time).pivot(index='bit', columns='time', values='voltage'))
df_3 = df_2.copy()
df_3.reset_index(drop=True, inplace=True)
df_3 = df_3.rename_axis(None, axis=1)
#Compressing to 14 rows 100 columns
df_4=df_3.iloc[:10, :100]
#Filling out null values
df_4= df_4.fillna(method='pad')
#Saving each dataframe to a list
device_list.append(df_4)
device_label.append(file_label_dict[device_name])
#Converting to numpy array
X = np.array(device_list)
y = np.array(device_label)
#Train test split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size= 0.30,random_state=42)
#Adding 1 dimension to make it, two dimension, to use Conv2D
X_train = X_train.reshape(X_train.shape[0],X_train.shape[1],X_train.shape[2],1)
X_test = X_test.reshape(X_test.shape[0],X_test.shape[1],X_test.shape[2],1)
#scaling data from 0 to 1
X_train_scaled = X_train/36 #Max voltage value 36
X_test_scaled = X_test/36
#Building a CNN a model
#Set random seed
tf.random.set_seed(42)
model_2 = tf.keras.Sequential([
tf.keras.layers.Conv2D(filters=3, kernel_size=3, strides=1, padding="same", activation='relu',kernel_initializer='normal',
input_shape=(X_train_scaled[0].shape)),
tf.keras.layers.MaxPool2D(pool_size=2),
tf.keras.layers.Conv2D(6,3, padding="same", activation='relu',kernel_initializer='normal',),
tf.keras.layers.MaxPool2D(pool_size=2),
tf.keras.layers.Conv2D(12,3, padding="same",activation='relu',kernel_initializer='normal',),
tf.keras.layers.MaxPool2D(pool_size=2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(72,activation='relu',kernel_initializer='normal',),
tf.keras.layers.Dense(6, activation= 'softmax') #Output layer
])
model_2.summary()
#Training
from tensorflow import keras
opt = keras.optimizers.Adam(lr=0.01)
model_2.compile(optimizer=opt,
loss='sparse_categorical_crossentropy',
metrics= ['accuracy'])
history= model_2.fit(X_train_scaled, y_train,batch_size= 128 , epochs=200,validation_split=0.20, verbose=1)
history
#Test
loss, accuracy= model_2.evaluate(X_test_scaled, y_test)
print(f'Loss: {loss}, Accuracy: {accuracy}')
print('Test accuracy : ',accuracy*100,'%')
准确度从 0.16 开始上升到 0.18,不超过 0.18。我尝试更改 CNN 模型的不同参数,例如添加更多卷积层、密集层、更改 adam 优化器的学习率、使用不同的优化器、尝试使用不同的 batch_size,但模型的准确性根本没有提高。
如果我在处理数据期间做错了什么,我会感到困惑。有人可以看看编码并告诉我我标记数据的方式是好的,或者我的编码有问题。如果代码很好,任何关于如何提高准确性的建议都非常感谢。我只是不确定这是编码问题还是模型有任何问题,或者数据不足以完成分类任务。
【问题讨论】:
-
你有什么理由认为你的标签可以从你的数据中推断出来吗?如果是的话,你是怎么想到这个架构的? CNN 可用于时间序列,但您很可能希望使用 Conv1D。一旦你的架构有了理论基础,你可能想从一个小得多的开始,然后再增加它的大小。其他相关问题:有多少数据点?输入数据是否标准化/去相关?
-
很抱歉我很难理解你的问题。我在机器学习方面的经验并不多。我没看懂你的第一个问题。你能换一种说法吗?关于数据点,我有来自每个设备的 500 个 csv 文件,总共有 6 个设备,总共有 3000 个 csv 文件。但是我从每个设备上只取了 100 个文件,总共 600 个文件。为了标准化数据,我用移动平均值替换了电压值以消除一些噪声,应用了一个函数来分割曲线。如果您查看编码,您可以看到它。
-
你的数据能预测标签吗?例如,要预测天气,有一些大气数据很有用。知道你午餐吃了什么是没有用的。结论:可以从大气数据中推断出天气预报。无法从您上次的午餐中推断出天气预报。
标签: python tensorflow machine-learning keras deep-learning