2013-11-16 2 views
13

Скажет, у меня есть dataframe в Панде, как следующее:векторизации dataframe панды для Scikit-Learn

> my_dataframe 

col1 col2 
A  foo 
B  bar 
C  something 
A  foo 
A  bar 
B  foo 

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

Как можно эффективно векторизовать это с использованием, например, DictVectorizer?

Нужно ли сначала конвертировать каждую запись в свой DataFrame в словарь? (так оно и делается в примере выше). Есть ли более эффективный способ сделать это?

ответ

11

Во-первых, я не понимаю, где в вашем массиве выборки есть функции и где наблюдения.

Во-вторых, DictVectorizer не содержит данных и предназначен только для утилиты преобразования и хранения метаданных. После преобразования он сохраняет имена функций и сопоставление. Он возвращает массив numpy, используемый для дальнейших вычислений. Размер массива матрицы (характер матрицы) равен features count x number of observations со значениями, равными значению функции для наблюдения. Поэтому, если вы знаете свои наблюдения и функции, вы можете создать этот массив любым другим способом.

В случае, если вы ожидаете sklearn сделать это для вас, вы не должны реконструировать Dict вручную, так как это может быть сделано с to_dict применительно к транспонированной dataframe:

>>> df 
    col1 col2 
0 A foo 
1 B bar 
2 C foo 
3 A bar 
4 A foo 
5 B bar 
>>> df.T.to_dict().values() 
[{'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}, {'col2': 'foo', 'col1': 'C'}, {'col2': 'bar', 'col1': 'A'}, {'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}] 

С scikit учиться 0.13.0 (3 января 2014) есть новый параметр 'records' для метода to_dict() доступен, так что теперь вы можете просто использовать этот метод без дополнительных манипуляций:

>>> df = pandas.DataFrame({'col1': ['A', 'B', 'C', 'A', 'A', 'B'], 'col2': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar']}) 
>>> df 
    col1 col2 
0 A foo 
1 B bar 
2 C foo 
3 A bar 
4 A foo 
5 B bar 
>>> df.to_dict('records') 
[{'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}, {'col2': 'foo', 'col1': 'C'}, {'col2': 'bar', 'col1': 'A'}, {'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}] 
+0

Благодаря @alko я просто обновил OP –

+0

Каждая строка является экземпляром ** **, то есть образец или наблюдение, и каждый column - это тип функции. В приведенном выше примере у меня есть 6 выборок, и каждый образец является двумерным, т. Е. Моя характеристическая матрица ** X ** будет (6,2) по размеру. Задача состоит в том, чтобы ** векторизовать ** каждый столбец в ** X **, поскольку они содержат текстовые записи и не могут быть поданы непосредственно в классификатор или регрессор. –

+1

@ пользователь815423426 окончательно понял. вы можете захотеть следовать Мэтту или использовать 'to_dict', чтобы получить необходимый dict (см. обновление). – alko

9

Посмотрите на sklearn-pandas, который обеспечивает именно то, что вы ищете. Соответствующим репо Github является here.

+1

Предположим, что у меня есть 40 столбцов, и я хочу выделить только несколько столбцов и сохранить остальные столбцы в DataFrame, чтобы я быть в состоянии обеспечить полученную матрицу numpy непосредственно в scikit-learn. Возможно ли это в склеарн-пандах? Я имею в виду, что sklearn-pandas хорош, но когда я вызываю mapper.transform(), он дает мне только преобразованные столбцы, а не все столбцы вместе с преобразованными. – gkcn

+0

Просто 'column_stack' преобразованные функции и оригинальные функции вместе. Что-то вроде: 'np.column_stack ([mapper.transform (train), train [['c1', 'c2', ...]]. Values])', где 'np' -' import numpy as np' – Matt

+0

Вы также можете использовать 'None' в качестве трансформатора в sklearn' DataFrameMapper' для столбцов, которые вы хотите сохранить без изменений. – dukebody

2

Вы хотите построить матрицу дизайна из pandas DataFrame, содержащей категориальные элементы (или просто строки), и самый простой способ сделать это - использовать библиотеку, которая реплицирует и расширяет функциональные возможности R-формул, используя patsy.

Используя ваш пример, преобразование будет:

import pandas as pd 
import patsy 

my_df = pd.DataFrame({'col1':['A', 'B', 'C', 'A', 'A', 'B'], 
         'col2':['foo', 'bar', 'something', 'foo', 'bar', 'foo']}) 

patsy.dmatrix('col1 + col2', data=my_df) # With added intercept 
patsy.dmatrix('0 + col1 + col2', data=my_df) # Without added intercept 

Полученные матрицы дизайна являются только Numpy массивы с некоторой дополнительной информацией и могут быть непосредственно использованы в scikit учиться.

Пример результата с перехватом добавлен:

DesignMatrix with shape (6, 5) 
    Intercept col1[T.B] col1[T.C] col2[T.foo] col2[T.something] 
      1   0   0   1     0 
      1   1   0   0     0 
      1   0   1   0     1 
      1   0   0   1     0 
      1   0   0   0     0 
      1   1   0   1     0 
    Terms: 
    'Intercept' (column 0) 
    'col1' (columns 1:3) 
    'col2' (columns 3:5) 

Обратите внимание, что Пэтси пытался избежать МУЛЬТИКОЛЛИНЕАРНОСТИ пути включения эффектов A и bar в перехват. Таким образом, например, предиктор col1[T.B] следует интерпретировать как дополнительный эффект B в отношении наблюдений, которые классифицируются как A.

3

Вы можете определенно использовать DictVectorizer.Поскольку DictVectorizer ожидает Iterable из dict -как объектов, вы можете сделать следующее:

from sklearn.base import TransformerMixin 
from sklearn.pipeline import make_pipeline 
from sklearn.feature_extraction import DictVectorizer 


class RowIterator(TransformerMixin): 
    """ Prepare dataframe for DictVectorizer """ 
    def fit(self, X, y=None): 
     return self 

    def transform(self, X): 
     return (row for _, row in X.iterrows()) 


vectorizer = make_pipeline(RowIterator(), DictVectorizer()) 

# now you can use vectorizer as you might expect, e.g. 
vectorizer.fit_transform(df) 
Смежные вопросы