Создание последовательной модели с использованием keras / python и CSV-файла, но получение плохой точности

#python #pandas #tensorflow #keras #keras-layer

#python #панды #тензорный поток #keras #keras-layer

Вопрос:

я хочу создать классификатор, но у меня возникли проблемы с поиском источников, которые могли бы четко объяснить функции keras и как делать то, что я пытаюсь сделать. я хочу использовать следующие данные:

          0    1    2        3          4       5    6     7
0     Name  TRY  LOC   OUTPUT     TYPE_A   SIGNAL  A-B  SPOT
1    inc 1    2   20   TYPE-1    TORPEDO   ULTRA    A   -21
2    inc 2    3   16   TYPE-2    TORPEDO     ILH    B   -14
3    inc 3    2   20  BLACK47    TORPEDO    LION    A    49
4    inc 4    3   12   TYPE-2  CENTRALPA    LION    A    25
5    inc 5    3   10   TYPE-2      THREE    LION    A   -21
6    inc 6    2   20   TYPE-2        ATF    LION    A   -48
7    inc 7    4    2  NIVEA-1        ATF    LION    B   -23
8    inc 8    3   16  NIVEA-1        ATF    LION    B    18
9    inc 9    3   18  BLENDER  CENTRALPA    LION    B    48
10   inc 10   4   20    DELCO        ATF    LION    B   -26
11   inc 11   3   20    VE248        ATF    LION    B    44
12   inc 12   1   20   SILVER  CENTRALPA    LION    B   -35
13   inc 13   2   20  CALVIN3     SEVENX    LION    B   -20
14   inc 14   3   14  DECK-BT  CENTRALPA    LION    B   -38
15   inc 15   4    4  10-LEVI    BERWYEN     OWL    B   -29
16   inc 16   4   14   TYPE-2        ATF     NOV    B   -31
17   inc 17   4   10     NYNY    TORPEDO     NOV    B    21
18   inc 18   2   20  NIVEA-1  CENTRALPA     NOV    B    45
19   inc 19   3   27   FMRA97    TORPEDO     NOV    B   -26
20   inc 20   4   18   SILVER        ATF     NOV    B   -46
 

я хочу использовать столбцы 1, 2, 4, 5, 6, 7 в качестве входных данных и выходных данных будет 3 (OUTPUT).

код, который у меня сейчас есть:

 import os
import pandas as pd
from sklearn.model_selection import train_test_split
import tensorflow as tf
import numpy as np
from sklearn import metrics
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.callbacks import EarlyStopping
from keras.callbacks import ModelCheckpoint
from keras.preprocessing.text import one_hot

df = pd.read_csv("file.csv")

df.drop('Name', axis=1, inplace=True)

obj_df = df.select_dtypes(include=['object']).copy()
# print(obj_df.head())
obj_df["OUTPUT"] = obj_df["OUTPUT"].astype('category')
obj_df["TYPE_A"] = obj_df["TYPE_A"].astype('category')
obj_df["SIGNAL"] = obj_df["SIGNAL"].astype('category')
obj_df["A-B"] = obj_df["A-B"].astype('category')
# obj_df.dtypes
obj_df["OUTPUT_cat"] = obj_df["OUTPUT"].cat.codes
obj_df["TYPE_A_cat"] = obj_df["TYPE_A"].cat.codes
obj_df["SIGNAL_cat"] = obj_df["SIGNAL"].cat.codes
obj_df["A-B_cat"] = obj_df["A-B"].cat.codes
# print(obj_df.head())
df2 = df[['TRY', 'LOC', 'SPOT']]
df3 = obj_df[['OUTPUT_cat', 'TYPE_A_cat', 'SIGNAL_cat', 'A-B_cat']]
df4 = pd.concat([df2, df3], axis=1, sort=False)

target_column = ['OUTPUT_cat']
predictors = list(set(list(df4.columns))-set(target_column))
df4[predictors] = df4[predictors]/df4[predictors].max()
print(df4.describe())

X = df4[predictors].values
y = df4[target_column].values

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=40)
print(X_train.shape); print(X_test.shape)

model = Sequential()
model.add(Dense(5000, activation='relu', input_dim=6))
model.add(Dense(1000, activation='relu'))
model.add(Dense(500, activation='relu'))
model.add(Dense(1, activation='softmax'))

# Compile the model
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# build the model
model.fit(X_train, y_train, epochs=20, batch_size=150)
 

я не могу понять, почему я получаю именно такой результат:

 Epoch 20/20
56/56 [==============================] - 4s 77ms/step - loss: 0.0000e 00 - accuracy: 1.8165e-04
 

кажется, я также не могу найти никаких ответов, связанных с этой проблемой. я неправильно использую функции keras? это то, как я преобразовываю тип объекта в целые числа? предполагая, что существует 1250 выходов, как бы я исправил слои? любые советы или помощь будут оценены по достоинству. Спасибо.

Комментарии:

1. У вас есть 3 полностью взаимосвязанных плотных слоя с 5000, 1000 и 500 нейронами, что в общей сложности составляет 2,5 * 10 ^ 9 нейронов в модели. Вводимые вами данные распределяются по огромному количеству нейронов, и у вас так мало точек данных, что они практически не влияют на результат. Что вам нужно сделать, так это резко сократить количество нейронов в плотных слоях. И я имею в виду радикально . Может быть, как (20, 10, 5) или что-то в этом роде.

2. привет, спасибо за эту очень полезную информацию. однако это просто ускорило запуск программы, и результат остался тем же.

3. Вы пробовали более традиционные классификаторы, такие как SVM или Random Forest? Может быть, ваша метка не связана с входными переменными? Кроме того, сколько классов у вас есть в категории «выходные данные»? И сколько всего точек данных?

4. я не изучал svm или случайный лес, но я могу изучить это. имеется 1250 выходных данных и 5000 точек данных (строк?)

Ответ №1:

Как я уже сказал в комментариях, это похоже на явный случай недостаточной подгонки модели — у вас слишком мало данных для размера самой модели. Вместо того, чтобы играть с размерами слоев, просто сначала попробуйте классификаторы SVM или randomForest и посмотрите, возможно ли вообще получить какую-либо разумную классификацию с вашими данными. Кроме того, при таком объеме данных нейронная сеть вряд ли когда-либо будет хорошим выбором.

Так что сделайте это вместо:

 from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

import pandas as pd

df = blablabla # This is your data
X = df.iloc[:, [i for i in range(8) if i != 3]]
y = df.iloc[:, 3]

X = pd.get_dummies(X)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)

rf = RandomForestClassifier(n_estimators=50, min_samples_leaf=5, n_jobs=-1)
rf.fit(X_train, y_train)
predictions = rf.predict(X_test)

accuracy = accuracy_score(y_test, predictions)
 

Если это работает и может сделать некоторые прогнозы, вы можете продолжить и попытаться настроить свою последовательную модель.

РЕДАКТИРОВАТЬ: просто прочитайте ваш комментарий о том, что у вас есть 1250 ярлыков классов и всего 5000 образцов. Это, вероятно, не будет работать с большинством классификаторов. Слишком много классов и слишком мало поддержки образцов.

Комментарии:

1. спасибо за этот ответ. это было очень полезно. я, очевидно, подробнее рассмотрю этот ответ и то, на что я смотрю, но с самого начала, есть какие-нибудь идеи, что означает эта ошибка? TypeError: __init__() got an unexpected keyword argument 'max_samples_leaf'

2. Извините, так и должно быть min_samples_leaf . Сегодня был долгий день.

3. вполне понятно, лол. я получил еще одну ошибку, ValueError: Input contains NaN, infinity or a value too large for dtype('float32') . я собираюсь изучить этот код, чтобы разобраться с ошибками и получить лучшее представление о функциях. спасибо вам за вашу помощь.

4. О, тогда вам, вероятно, нужно запустить df.dropna(inplace=True) в начале. Однако вы можете потерять несколько записей.

5. Похоже, что у вас отсутствуют записи в каждой строке, и в результате все данные удаляются. Вы можете добавить опцию subset=[column_names] в dropna и вместо column_names указать имена столбцов, которые вы хотите использовать в своей классификации.