pandas - pandas 数据帧上的自定义 word2vec Transformer 并在 FeatureUnion 中使用它
问题描述
对于下面的 pandas DataFrame df
,我想将type
列转换为 OneHotEncoding,并word
使用字典将列转换为其向量表示word2vec
。然后我想将两个变换后的向量与count
列连接起来,形成最终的分类特征。
>>> df
word type count
0 apple A 4
1 cat B 3
2 mountain C 1
>>> df.dtypes
word object
type category
count int64
>>> word2vec
{'apple': [0.1, -0.2, 0.3], 'cat': [0.2, 0.2, 0.3], 'mountain': [0.4, -0.2, 0.3]}
我定义了自定义Transformer
,并用于FeatureUnion
连接功能。
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import OneHotEncoder
class w2vTransformer(TransformerMixin):
def __init__(self,word2vec):
self.word2vec = word2vec
def fit(self,x, y=None):
return self
def wv(self, w):
return self.word2vec[w] if w in self.word2vec else [0, 0, 0]
def transform(self, X, y=None):
return df['word'].apply(self.wv)
pipeline = Pipeline([
('features', FeatureUnion(transformer_list=[
# Part 1: get integer column
('numericals', Pipeline([
('selector', TypeSelector(np.number)),
])),
# Part 2: get category column and its onehotencoding
('categoricals', Pipeline([
('selector', TypeSelector('category')),
('labeler', StringIndexer()),
('encoder', OneHotEncoder(handle_unknown='ignore')),
])),
# Part 3: transform word to its embedding
('word2vec', Pipeline([
('w2v', w2vTransformer(word2vec)),
]))
])),
])
当我运行时pipeline.fit_transform(df)
,我得到了错误:blocks[0,:] has incompatible row dimensions. Got blocks[0,2].shape[0] == 1, expected 3.
但是,如果我从管道中删除了 word2vec Transformer(第 3 部分),则管道(第 1 部分 1 + 第 2 部分)工作正常。
>>> pipeline_no_word2vec.fit_transform(df).todense()
matrix([[4., 1., 0., 0.],
[3., 0., 1., 0.],
[1., 0., 0., 1.]])
如果我只在管道中保留w2v 变压器,它也可以工作。
>>> pipeline_only_word2vec.fit_transform(df)
array([list([0.1, -0.2, 0.3]), list([0.2, 0.2, 0.3]),
list([0.4, -0.2, 0.3])], dtype=object)
我的猜测是我的w2vTransformer
班级出了点问题,但不知道如何解决。请帮忙。
解决方案
这个错误是由于 FeatureUnion 期望它的每个部分都有一个二维数组。
现在您的 FeatureUnion 的前两部分:-'numericals'
并且'categoricals'
正在正确发送形状的二维数据(n_samples,n_features)。
n_samples
= 3 在您的示例数据中。n_features
将取决于各个部分(如 OneHotEncoder 将在第二部分更改它们,但在第一部分将是 1)。
但第三部分'word2vec'
返回一个具有一维形状的 pandas.Series 对象(3,)
。FeatureUnion 默认采用形状 (1, 3),因此抱怨它与其他块不匹配。
所以你需要纠正那个形状。
现在,即使您只是reshape()
在最后执行 a 并将其更改为 shape (3,1),您的代码也不会运行,因为该数组的内部内容是您的 word2vec 字典中的列表,这些列表未正确转换为 2- d 数组。相反,它将成为一个列表数组。
更改 w2vTransformer 以更正错误:
class w2vTransformer(TransformerMixin):
...
...
def transform(self, X, y=None):
return np.array([np.array(vv) for vv in X['word'].apply(self.wv)])
之后,管道将起作用。
推荐阅读
- cloudflare - Cloudflare:流量 -> 健康检查 - 403 响应代码不匹配错误
- r - 使用ggplotly时geom_tile瓷砖移位
- flutter - 使用 WiX 进行颤振验证
- cmd - windows cmd - 在快捷方式中执行命令
- scala - Scala 中 ZonedDateTime 的排序
- go - /vendor/github.com/weaveworks/promrus 的 golang build 给出错误:未定义:logrus.Level
- typescript - this 在成员函数中未定义
- mysql - error of 1824: failed to open the referenced table
- oracle - 无法从其他用户登录到 Oracle 数据库
- python - 将列表和元组列表转换为字典