使用 make_column_transformer 处理分类变量时在拟合过程中出现错误

问题是多元线性回归。X包含8个分类变量,其余的分类变量被编码为0和1。

当尝试构建列转换器并拟合行时,出现了下面的错误。’TypeError: unhashable type: ‘Index”

cat_cols=df_train.select_dtypes(include="object").columnsy.head()0    130.811     88.532     76.263     80.624     78.02Name: y, dtype: float64X.head()X0  X1  X2  X3  X4  X5  X6  X8  X10 X11 ... X375    X376    X377    X378    X379    X380    X382    X383    X384    X3850   k   v   at  a   d   u   j   o   0   0   ... 0   0   1   0   0   0   0   0   0   01   k   t   av  e   d   y   l   o   0   0   ... 1   0   0   0   0   0   0   0   0   02   az  w   n   c   d   x   j   x   0   0   ... 0   0   0   0   0   0   1   0   0   03   az  t   n   f   d   x   l   e   0   0   ... 0   0   0   0   0   0   0   0   0   04   az  v   n   f   d   h   d   n   0   0   ... 0   0   0   0   0   0   0   0   0   05 rows × 376 columnsct=make_column_transformer((OneHotEncoder(),[cat_cols]),remainder='passthrough')ColumnTransformer(remainder='passthrough',                  transformers=[('onehotencoder',                                 OneHotEncoder(handle_unknown='ignore'),                                 [Index(['X0', 'X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X8'], dtype='object')])])    ct.fit(X_train)

在这个阶段出现错误

TypeError                                 Traceback (most recent call last)<ipython-input-180-8ea255dead4d> in <module>----> 1 ct.fit(X_train)D:\Anaconda\lib\site-packages\sklearn\compose\_column_transformer.py in fit(self, X, y)    492         # we use fit_transform to make sure to set sparse_output_ (for which we    493         # need the transformed data) to have consistent output type in predict--> 494         self.fit_transform(X, y=y)    495         return self    496 D:\Anaconda\lib\site-packages\sklearn\compose\_column_transformer.py in fit_transform(self, X, y)    527         self._validate_transformers()    528         self._validate_column_callables(X)--> 529         self._validate_remainder(X)    530     531         result = self._fit_transform(X, y, _fit_transform_one)D:\Anaconda\lib\site-packages\sklearn\compose\_column_transformer.py in _validate_remainder(self, X)    317     318         # Make it possible to check for reordered named columns on transform--> 319         self._has_str_cols = any(_determine_key_type(cols) == 'str'    320                                  for cols in self._columns)    321         if hasattr(X, 'columns'):D:\Anaconda\lib\site-packages\sklearn\compose\_column_transformer.py in <genexpr>(.0)    317     318         # Make it possible to check for reordered named columns on transform--> 319         self._has_str_cols = any(_determine_key_type(cols) == 'str'    320                                  for cols in self._columns)    321         if hasattr(X, 'columns'):D:\Anaconda\lib\site-packages\sklearn\utils\__init__.py in _determine_key_type(key, accept_slice)    256         return key_stop_type    257     if isinstance(key, (list, tuple)):--> 258         unique_key = set(key)    259         key_type = {_determine_key_type(elt) for elt in unique_key}    260         if not key_type:D:\Anaconda\lib\site-packages\pandas\core\indexes\base.py in __hash__(self)   3905    3906     def __hash__(self):-> 3907         raise TypeError(f"unhashable type: {repr(type(self).__name__)}")   3908    3909     def __setitem__(self, key, value):TypeError: unhashable type: 'Index'

再次尝试对仅8个分类变量使用OneHot编码,并对一些行样本使用fit_transform,它被逆变换回原始状态。因此,对于值为字母的分类变量,它工作得很好。由于X8之后的其他列已经直接以0和1的形式存在,因此直接传递给转换器。

当我尝试对整个数据集X使用OHE并传递给线性回归时,在以下过程中出现了错误

ohe=OneHotEncoder()X_train_transformed=ohe.fit_transform(X_train)ohe.categories_array(['a', 'b', 'c', 'd', 'e', 'f', 'g'], dtype=object), array(['a', 'b', 'c', 'd'], dtype=object), array(['aa', 'ab', 'ac', 'ad', 'ae', 'af', 'ag', 'ah', 'c', 'd', 'f', 'g',        'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 'v',        'w', 'x', 'y'], dtype=object), array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],       dtype=object), array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',        'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y'],       dtype=object), array([0, 1], dtype=int64), array([0], dtype=int64), array([0, 1], dtype=int64), array([0, 1], dtype=int64), array([0, 1], dtype=int64), array([0, 1], dtype=int64), array([0, 1], dtype=int64),linereg=LinearRegression()linereg.fit(X_train_transformed,y_train)X_test_transformed=ohe.fit_transform(X_test)X_train_transformed.shape(2946, 906)X_test_transformed.shape(1263, 872)linereg.predict(X_test_transformed)ValueError: dimension mismatch

不确定为什么训练和测试的维度会被转换。

感谢您的帮助来解决这些问题


回答:

对于您的第一个问题,我认为它来自于列转换器的声明。当您提供转换器应该操作的列时,您以列表的列表形式提供它们(通过在[cat_cols]中使用[])。我在自己这边进行了一个测试,移除[]解决了我的问题,如下所示:

ct = make_column_transformer((OneHotEncoder(), cat_cols), remainder = 'passthrough')

关于您的第二个问题,我认为测试数据和训练数据的维度不同是因为您在转换之前对测试数据进行了拟合。测试数据应该只被转换而不被拟合,如下所示:

X_test_transformed = ohe.transform(X_test)

当您在测试数据上再次拟合转换器时,我认为在您的情况下发生的是测试数据中的某些分类列包含的组别比训练数据少,因此一些虚拟列不会被创建,这使得转换后的测试数据的列数少于转换后的训练数据的列数。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注