Мой вопрос касается предварительной обработки файлов csv перед их вводом в нейронную сеть.
Я хочу построить глубокую нейронную сеть для известного набора данных iris, используя tflearn в python 3.
Набор данных: http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data
Я использую tflearn для загрузки файла csv. Однако в столбце классов моего набора данных есть такие слова, как iris-setosa, iris-versicolor, iris-virginica.
Обычные сети работают только с числами. Итак, мне нужно найти способ изменить классы со слов на числа. Поскольку это очень маленький набор данных, я могу сделать это вручную с помощью Excel / текстового редактора. Я вручную назначал номера для разных классов.
Но я не могу сделать это для каждого набора данных, с которым работаю. Итак, я попытался использовать pandas для выполнения одного горячего кодирования.
preprocess_data = pd.read_csv("F:\Gautam\.....\Dataset\iris_data.csv")
preprocess_data = pd.get_dummies(preprocess_data)
Но теперь я не могу использовать этот фрагмент кода:
data, labels = load_csv('filepath', categorical_labels=True,
n_classes=3)
'filepath' должен быть только каталогом для файла csv, а не какой-либо переменной, такой как preprocess_data.
Исходный набор данных:
Sepal Length Sepal Width Petal Length Petal Width Class
89 5.5 2.5 4.0 1.3 iris-versicolor
85 6.0 3.4 4.5 1.6 iris-versicolor
31 5.4 3.4 1.5 0.4 iris-setosa
52 6.9 3.1 4.9 1.5 iris-versicolor
111 6.4 2.7 5.3 1.9 iris-virginica
Набор данных, измененный вручную:
Sepal Length Sepal Width Petal Length Petal Width Class
89 5.5 2.5 4.0 1.3 1
85 6.0 3.4 4.5 1.6 1
31 5.4 3.4 1.5 0.4 0
52 6.9 3.1 4.9 1.5 1
111 6.4 2.7 5.3 1.9 2
Вот мой код, который работает отлично, но я изменил набор данных вручную.
import numpy as np
import pandas as pd
import tflearn
from tflearn.layers.core import input_data, fully_connected
from tflearn.layers.estimator import regression
from tflearn.data_utils import load_csv
data_source = 'F:\Gautam\.....\Dataset\iris_data.csv'
data, labels = load_csv(data_source, categorical_labels=True,
n_classes=3)
network = input_data(shape=[None, 4], name='InputLayer')
network = fully_connected(network, 9, activation='sigmoid', name='Hidden_Layer_1')
network = fully_connected(network, 3, activation='softmax', name='Output_Layer')
network = regression(network, batch_size=1, optimizer='sgd', learning_rate=0.2)
model = tflearn.DNN(network)
model.fit(data, labels, show_metric=True, run_id='iris_dataset', validation_set=0.1, n_epoch=2000)
Я хочу знать, есть ли в tflearn (или в любом другом модуле, если на то пошло) какая-либо другая встроенная функция, которую я могу использовать для изменения значения моих классов со слов на числа. Я не думаю, что ручное изменение наборов данных будет продуктивным.
Я также новичок в обучении и нейронных сетях. Любая помощь будет оценена по достоинству. Спасибо.
Самое простое решение - map
by dict
из всех возможных значений:
df['Class'] = df['Class'].map({'iris-versicolor': 1, 'iris-setosa': 0, 'iris-virginica': 2})
print (df)
Sepal Length Sepal Width Petal Length Petal Width Class
0 89 5.5 2.5 4.0 1.3 1
1 85 6.0 3.4 4.5 1.6 1
2 31 5.4 3.4 1.5 0.4 0
3 52 6.9 3.1 4.9 1.5 1
4 111 6.4 2.7 5.3 1.9 2
Если хотите сгенерировать dictionary
по всем уникальным значениям:
d = {v:k for k, v in enumerate(df['Class'].unique())}
print (d)
{'iris-versicolor': 0, 'iris-virginica': 2, 'iris-setosa': 1}
df['Class'] = df['Class'].map(d)
print (df)
Sepal Length Sepal Width Petal Length Petal Width Class
0 89 5.5 2.5 4.0 1.3 0
1 85 6.0 3.4 4.5 1.6 0
2 31 5.4 3.4 1.5 0.4 1
3 52 6.9 3.1 4.9 1.5 0
4 111 6.4 2.7 5.3 1.9 2
Используйте кодировщик этикеток из библиотеки sklearn
:
from sklearn.preprocessing import LabelEncoder,OneHotEncoder
df = pd.read_csv('iris_data.csv',header=None)
df.columns=[Sepal Length,Sepal Width,Petal Length,Petal Width,Class]
enc=LabelEncoder()
df['Class']=enc.fit_transform(df['Class'])
print df.head(5)
если вы хотите One-hot encoding
, сначала вам нужно labelEncode, а затем выполнить OneHotEncoding:
enc=LabelEncoder()
enc_1=OneHotEncoder()
df['Class']=enc.fit_transform(df['Class'])
df['Class']=enc_1.fit_transform([df['Class']]).toarray()
print df.head(5)
Эти кодировщики сначала сортируют слова в алфавитном порядке, а затем присваивают им метки. Если вы хотите узнать, какой ярлык назначен какому классу, выполните:
for k in list(enc.classes_) :
print 'name ::{}, label ::{}'.format(k,enc.transform([k]))
Если вы хотите сохранить этот фрейм данных как файл csv, выполните:
df.to_csv('Processed_Irisdataset.csv',sep=',')
@GautamJ - хммм, так что решение карты не лучше для вас? Почему? Мне интересно :)
@PratikKumar, еще одно ValueError: ожидаемый 2D-массив, вместо этого получил 1D-массив. Но я думаю, что справлюсь только с LabelEncoding. Работает нормально. Как вы думаете, нужно ли использовать одно горячее кодирование?
Кодирования меток достаточно для выходных меток, если характеристиками были слова, то становится необходимо однозначно. что касается roor, внимательно посмотрите enc_1.fit_transform([df['Class']])
, df ['Class'] заключен в пару квадратных скобок
@PratikKumar, Ой ... Я пропустил квадратные скобки ... Но теперь у меня другая проблема ... Во вновь созданном csv файле есть дополнительный столбец (нулевой столбец) чисел от 0, 1, 2 ... для каждой строки. Однако у него нет заголовка. Любые идеи о том, как удалить этот столбец ??? Спасибо!
LabelEncoder отлично работает. Однако OneHotEncoder возвращает «ошибку значения». ValueError: не удалось преобразовать строку в число с плавающей запятой: 'Iris-virginica'. Спасибо.