使用 sklearn 或 pandas 进行一次热编码后,如何在混合数据集(数值 + 分类)上应用 KNN

Posted

技术标签:

【中文标题】使用 sklearn 或 pandas 进行一次热编码后,如何在混合数据集(数值 + 分类)上应用 KNN【英文标题】:How to apply KNN on a mixed dataset(numerical + categorical) after doing one hot encoding using sklearn or pandas 【发布时间】:2018-10-24 09:39:03 【问题描述】:

我正在尝试根据对象的各种特征(例如:类别、标签、作者、标题、视图、共享等)创建推荐器。如您所见,这些功能属于混合类型,而且我没有任何特定于用户的数据。在显示其中一个对象的详细信息后,我想再显示 3 个类似的对象。我正在尝试将 kNN 与 sklearn 一起使用,并发现单热编码在这种情况下很有用。但我不知道如何将它们与 KNN 一起应用。欢迎任何帮助,即使使用完全不同的库或方法。我是机器学习新手。

【问题讨论】:

【参考方案1】:

我假设您已经将数据清理并存储在 pandas.DataFrame 或其他类似数组的结构中。在这一步你会做

import pandas as pd

# Retrieve and clean your data.
# Store it in an object df

df_OHE = pd.get_dummies(df)

# At this stage you will want to rescale your variable to bring them to a similar numeric range
# This is particularly important for KNN, as it uses a distance metric
from sklearn.preprocessing import StandardScaler
df_OHE_scaled = StandardScaler().fit_transform(df_OHE)

# Now you are all set to use these data to fit a KNN classifier.

见pd.get_dummies() doc。 this discussion 用于解释 KNN 缩放的需要。请注意,您可以在 sklearn 中试验其他类型的缩放器。

附:我假设您对 python 中的解决方案感兴趣,因为您提到了那些特定的包。

【讨论】:

非常感谢您的帮助。在对分类数据进行数据转换后,我在使用 KNN 时遇到了问题,因为我只知道将 kNN 与数值数据一起使用,因为它使用欧几里得距离。我可以寻找任何视频/演示代码吗?到那时,我已经对每个具有特定权重的分类数据使用了 jaccard 相似性,并计划将其与其他数值数据(如 view_count 等)结合起来,以进一步与 KNN 一起使用。虽然标题、正文等功能仍然会留下。对我的案例有什么完整的解决方案参考建议吗? “麻烦”如 KNN 分类器拟合崩溃输出 KNN 分类器是垃圾并且没有显示任何相似性?我不知道有完整的教程可以显示 KNN 中的 OHE 用法。但我过去是在 kaggle 上的泰坦尼克号比赛中这样做的。可在此处获得:github.com/mlisovyi/TitanicSurvivalGuide。我并不声称它是一个完美的教程,但它是我所知道的唯一示例:) 为什么不使用sklearn.preprocessing.MultiLabelBinarizer 而不是get_dummies(df)?还是两种方法都行?只是好奇。【参考方案2】:

查看Pipeline接口和this很好的介绍。流水线是一种通过模型和超参数选择组织预处理的简洁方式。

我的基本设置如下所示:

from sklearn.pipeline import Pipeline, FeatureUnion, make_pipeline
from sklearn.preprocessing import OneHotEncoder
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.neighbors import KNeighborsClassifier

class Columns(BaseEstimator, TransformerMixin):
    def __init__(self, names=None):
        self.names = names

    def fit(self, X, y=None, **fit_params):
        return self

    def transform(self, X):
        return X[self.names]

numeric = [list of numeric column names]
categorical = [list of categorical column names]

pipe = Pipeline([
    ("features", FeatureUnion([
        ('numeric', make_pipeline(Columns(names=numeric),StandardScaler())),
        ('categorical', make_pipeline(Columns(names=categorical),OneHotEncoder(sparse=False)))
    ])),
    ('model', KNeighborsClassifier())
])

这使您可以简单地尝试不同的分类器、特征变换器(例如 MinMaxScaler() 而不是 StandardScaler()),即使在大网格搜索和分类器超参数中也是如此。

【讨论】:

以上是关于使用 sklearn 或 pandas 进行一次热编码后,如何在混合数据集(数值 + 分类)上应用 KNN的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 sklearn 进行一次热编码后给出列名?

如何在使用 sklearn 进行一次热编码后给出列名?

循环对 PANDAS 数据帧进行一次热编码质量检查

如何使用 LabelBinarizer 对正确的训练和测试进行一次热编码

将多个预处理步骤应用于 sklearn 管道中的列

一次对多列进行一次热编码并附加到主数据集?