我正在学习一些机器学习知识。我了解k-近邻算法(kNN)的基础知识,但我之前看到的例子都是用在连续数据上的。
我现在正在跟随的一个教程使用kNN来分类一些混合类型的数据(包括连续特征和几个分类特征)。我知道对于连续特征,通常使用欧几里得距离或其他类似的距离函数,但当数据混合时,它们是如何处理的呢?
我明白如何为二元变量计算距离,但对于没有“顺序”的分类变量,该如何处理呢?
编辑:我正在跟随这个Kaggle问题的教程。在清理数据后,他将其整理成如下形式:
Survived Pclass Sex Age Fare Embarked Title IsAlone Age*Class0 0 3 0 1 0 0 1 0 31 1 1 1 2 3 1 3 0 22 1 3 1 1 1 0 2 1 33 1 1 1 2 3 0 3 0 24 0 3 0 2 1 0 1 1 65 0 3 0 1 1 2 1 1 36 0 1 0 3 3 0 1 1 37 0 3 0 0 2 0 4 0 08 1 3 1 1 1 0 3 0 39 1 2 1 0 2 1 3 0 0
(其中第一列实际上是ID)
因此,这有点奇怪,因为它混合了二元(例如,性别)、有序分类(例如,年龄被分为4或5个年龄段)和无序分类(例如,上船港口被标记为0、1或2,仅根据他们上船的港口,因此我认为它没有顺序)。
数据被分割如下:
X_train = train_df.drop("Survived", axis=1)Y_train = train_df["Survived"]X_test = test_df.drop("PassengerId", axis=1).copy()X_train.shape, Y_train.shape, X_test.shape
然后所有这些都被传递给kNN,如下所示:
knn = KNeighborsClassifier(n_neighbors = 3)knn.fit(X_train, Y_train)Y_pred = knn.predict(X_test)acc_knn = round(knn.score(X_train, Y_train) * 100, 2)acc_knn
那么它是如何进行kNN处理的呢?我们没有给它提供任何信息或指示。
回答:
sklearn的kNN将对所有特征使用相同的(选择的)度量标准(这在API中有说明;没有选项可以混合度量标准!)。
你说的没错,在混合情况下这是有问题的,但你需要准备好你的数据来应对这一点!标准方法是使用这里解释的一键编码:
通常特征不是以连续值给出的,而是分类值。
…
这种整数表示不能直接与scikit-learn估计器一起使用,因为这些估计器期望连续输入,并且会将类别解释为有序的,这通常是不希望的(即,浏览器集是任意排序的)。
将分类特征转换为可以与scikit-learn估计器一起使用的特征的一种可能性是使用一对K或一键编码,这在OneHotEncoder中实现。该估计器将每个具有m个可能值的分类特征转换为m个二进制特征,其中只有一个是活跃的。
根据你的数据,这可能会大大增加特征的数量!在这种情况下,你需要做出决定:
- 使用密集数据结构(仍然能够内部使用kd树/球树)
- 使用稀疏数据结构(这将使用暴力查找;
注意:在稀疏输入上进行拟合将覆盖此参数的设置,使用暴力方法。
)