Векторизация фрейма Pandas для Scikit-Learn
Скажем, у меня есть dataframe в Pandas, как показано ниже:
> my_dataframe
col1 col2
A foo
B bar
C something
A foo
A bar
B foo
где строки представляют экземпляры и функции ввода столбцов (не отображая метку-мишень, но это было бы для задачи классификации), т.е. я пытаюсь построить X из my_dataframe
.
Как можно эффективно векторизовать это с помощью, например, DictVectorizer
?
Нужно ли сначала конвертировать каждую запись в моем DataFrame в словарь? (так, как это делается в примере в ссылке выше). Есть ли более эффективный способ сделать это?
Ответы
Ответ 1
Во-первых, я не понимаю, где в вашем массиве выборки есть функции и где наблюдения.
Во-вторых, DictVectorizer
не содержит данных и относится только к утилите утилиты преобразования и метаданных. После преобразования он сохраняет имена функций и сопоставление. Он возвращает массив numpy, используемый для дальнейших вычислений. Массив размера матрицы (характер матрицы) равен features count
x number of observations
со значениями, равными значению функции для наблюдения. Поэтому, если вы знаете свои наблюдения и функции, вы можете создать этот массив любым другим способом.
Если вы ожидаете, что sklearn сделает это за вас, вам не нужно вручную восстанавливать dict, так как это можно сделать с помощью to_dict
, примененного к транспонированному файловому кадру:
>>> 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-learn 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'}]
Ответ 2
Взгляните на sklearn-pandas
, который обеспечивает именно то, что вы ищете. Соответствующий репозиторий Github здесь.
Ответ 3
Вы можете определенно использовать DictVectorizer
. Поскольку DictVectorizer
ожидает итерабельность объектов dict
-like, вы можете сделать следующее:
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)
Ответ 4
Вы хотите построить матрицу дизайна из pandas DataFrame, содержащего категориальные элементы (или просто строки), и самый простой способ сделать это - использовать patsy, библиотека, которая реплицирует и расширяет функциональные возможности R-формул.
Используя ваш пример, преобразование будет выглядеть следующим образом:
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-learn.
Результат примера с добавлением перехвата:
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)
Обратите внимание, что patsy пытался избежать мультиколинеарности, включив эффекты A
и bar
в перехват. Таким образом, например, предиктор col1[T.B]
следует интерпретировать как дополнительный эффект B
в отношении наблюдений, которые классифицируются как A
.