В итоге я хочу, чтобы функция Python 3:
- считывала данные из CSV-файла, разделенного табуляцией
- возвращала кортеж из двух частей, где обе части numpy массивы (примеры ниже):
- первая часть - это все данные из всех столбцов , за исключением первого столбца, с каждая строка является собственным списком ( 2-мерная матрица)
- вторая часть кортежа - это все данные из первого столбца в виде списка (или это одномерный массив?)
- на данный момент сохраняют правильные типы для каждого элемента данных, либо строковые, либо целочисленные
Два массива Numpy должны быть переданы в Scikit-Learn, в частности Id3Estimator.fit
Проблемы, с которыми я столкнулся:
- Я новичок в Python
- Я совершенно новичок в numpy, pandas и Scikit-learn
- Многие из примеров, которые я могу найти, либо тривиально просты и не соответствуют моим потребностям, либо неосуществимо сложны для eginner
- В некоторых ответах, которые я нашел в StackExchange, используются устаревшие методы
.to_matrix
и .values
, но я хочу быть в курсе
CSV
Данные CSV неоднородны. Первый столбец - это классификация, остальные - данные объекта:
(30k,38k) 45 male private m
(30k,38k) 50 female private m
(30k,38k) 61 other public b
(13k,15k) 40 male private none
(23k,30k) 34 other private b
Данные второго столбца (которые я обнаружил, пронумерованы 1 из-за 0-индексации) все целые числа. Все остальные столбцы полностью строковые.
Структуры данных
ID3Estimator поставляется с примером аппаратных данных, и я хочу адаптировать его для чтения из файла CSV, разделенного табуляцией. Встроенные данные имеют 3 явные структуры данных:
- имена элементов (которые я успешно прочитал из отдельного файла)
instances
, которые выглядят так:
np.array([[45, "male", "private", "m"],
[50, "female", "private", "m"],
[61, "other", "public", "b"],
[40, "male", "private", "none"],
[34, "other", "private", "b"]])
classifications
, которые выглядят так:
np.array(["(30k,38k)",
"(30k,38k)",
"(30k,38k)",
"(13k,15k)",
"(23k,30k)"])
Я использовал import numpy as np
Минимальный почти рабочий пример
import numpy as np
import pandas as pd
from id3 import Id3Estimator
def read_instances():
""" returns (instances, classifications)
"""
data = pd.read_csv('data.csv',
dtype=str, # UPDATE (see below)
header=None,
sep='\t')
# iloc[rows, column(s)] where : means "all"
return np.array(data.iloc[:, 1:]),\
np.array(list(data.iloc[:, 0]))
# the first part of the return seems to be incorrect
instances, classifications = read_instances()
clf = Id3Estimator()
clf.fit(instances, classifications, check_input=True)
Биты, которые работают
- Все данные считываются правильно
- Массив
classifications
отображается в правильном формате
Неработающие биты
- Неправильный массив
instances
Трассировка ошибок:
clf.fit(instances, classifications, check_input=True)
File "\Python38\lib\site-packages\id3\id3.py", line 92,
in fit
X_, y_ = check_X_y(X, y)
File "D:\_tools\Python38\lib\site-packages\sklearn\utils\validation.py", line 747,
in check_X_y
X = check_array(X, accept_sparse=accept_sparse,
File "\Python38\lib\site-packages\sklearn\utils\validation.py", line 531,
in check_array
array = np.asarray(array, order=order, dtype=dtype)
File "\Python38\lib\site-packages\numpy\core\_asarray.py", line 85,
in asarray
return array(a, dtype, copy=False, order=order)
ValueError: could not convert string to float: 'male'
Существует также множество предупреждений об устаревании, связанных с six.py
, которые я не включил. Я предполагаю, что это что-то в библиотеке id3
.
Я бы не удивился, если бы что-то действительно простое я пропустил, и не удивлюсь, если весь мой подход неверен. Я не уверен, что использование list
для создания одномерного массива для classifications
- это «правильный» способ сделать это. Что касается части instances
, я чувствую, что хочу объединить pandas.DataFrame.to_numpy
со срезом массива, но я в настоящее время слишком запутался, и мне и моей резиновой утке было достаточно отладки.
Любопытно, что аппаратный код не требует явного указания типов. Я видел что-то о dtype
или что-то подобное где-то, но сейчас я насыщен Я устал после дня установки python и библиотек (через обновление pip), пытаясь выяснить обработку параметров командной строки (до argparse
в конечном итоге после долгого getopt
wild- goose chase), пытаясь выяснить, как импортировать CSV против импорта Panda CSV, и возникла путаница с параметрами iloc
и обозначениями срезов массива.
Update 1
Я распечатал np.array
зашитой версии:
[['45' 'male' 'private' 'm']
['50' 'female' 'private' 'm']
.
.
.
['34' 'other' 'private' 'b']]
и версии, поступающей из CSV через read_instances ():
[[45 'male' 'private' 'm']
[50 'female' 'private' 'm']
.
.
.
[34 'male' 'private' 'b']
и заметил, что в последней (нерабочей) версии что числа являются числами, тогда как они являются строками в аппаратной версии. Я нахожу это странным, потому что они не указаны в жесткой версии. Поэтому я добавил dtype=str
к pd.read_csv()
, который обрабатывает числа как строки.
Так что теперь, когда я печатаю две версии np.array
, они печатаются одинаково. Однако он по-прежнему выдает ту же ошибку ValueError: could not convert string to float: 'male'
, вероятно, по той же причине (ам), что и до изменения.
Обновление 2
Я получил ее, добавив dtype=str
к np.array
call:
def read_instances():
""" returns (instances, classifications)
"""
data = pd.read_csv(args['instances'],
dtype=str, # makes everything strings
header=None,
sep='\t')
# iloc[rows, column(s)] where : means "all"
return np.array(data.iloc[:, 1:], dtype=str),\
np.array(list(data.iloc[:, 0]))
Но я все равно хотел бы знать, является ли способ чтения файла CSV и разбиения столбцов «лучшим» способом сделать это, где «лучшее» может быть «самый элегантный» или «самый эффективный» Мы должны предположить, что файл CSV не слишком большой, чтобы поместиться в память, потому что если бы он был, я не понимаю, как можно загрузить его для обучения алгоритму машинного обучения.