使用k-最近邻居而不分成训练和测试集

时间:2017-01-19 19:33:55

标签: python numpy machine-learning scikit-learn nearest-neighbor

我有以下数据集,超过20,000行:

enter image description here

我想使用列A到E来使用k近邻算法预测列X.我尝试使用sklearn中的KNeighborsRegressor,如下所示:

import pandas as pd
import random
from numpy.random import permutation
import math
from sklearn.neighbors import KNeighborsRegressor

df = pd.read_csv("data.csv")

random_indices = permutation(df.index)
test_cutoff = int(math.floor(len(df)/5))
test = df.loc[random_indices[1:test_cutoff]]
train = df.loc[random_indices[test_cutoff:]]

x_columns = ['A', 'B', 'C', D', E']
y_column = ['X']

knn = KNeighborsRegressor(n_neighbors=100, weights='distance')
knn.fit(train[x_columns], train[y_column])
predictions = knn.predict(test[x_columns])

这仅对测试数据进行预测,该测试数据是原始数据集的五分之一。我还想要训练数据的预测值。

为此,我试图通过计算每隔一行的每一行的欧几里德距离,找到k个最短距离,并对那些k行的X值求平均值来实现我自己的k-最近算法。这个过程只用了一行超过30秒,而且我有超过20,000行。有更快的方法吗?

3 个答案:

答案 0 :(得分:1)

  

为此,我试图通过计算每隔一行的每一行的欧几里德距离,找到k个最短距离,并对那些k行的X值求平均值来实现我自己的k-最近算法。这个过程只用了一行超过30秒,而且我有超过20,000行。有更快的方法吗?

是的,问题是python中的循环非常慢。您可以做的是矢量化您的计算。因此,假设您的数据在矩阵X(n x d)中,然后是距离矩阵D_ij = || X_i - X_j || ^ 2是

D = X^2 + X'^2 -  2 X X'

所以在Python中

D = (X ** 2).sum(1).reshape(-1, 1) + (X ** 2).sum(1).reshape(1, -1) - 2*X.dot(X.T)

答案 1 :(得分:1)

尝试使用此代码:

auto foo(iterator it) -> decltype(*it) {   

与您的解决方案的主要区别在于使用ShuffleSplit

注意:

  • import numpy as np import pandas as pd from sklearn.model_selection import ShuffleSplit from sklearn.neighbors import KNeighborsRegressor df = pd.read_csv("data.csv") X = np.asarray(df.loc[:, ['A', 'B', 'C', 'D', 'E']]) y = np.asarray(df['X']) rs = ShuffleSplit(n_splits=1, test_size=1./5, random_state=0) train_indices, test_indices = rs.split(X).next() knn = KNeighborsRegressor(n_neighbors=100, weights='distance') knn.fit(X[train_indices], y[train_indices]) predictions = knn.predict(X) 包含所有数据的预测值(测试和训练)。
  • 可以通过参数predictions调整测试数据的比例(我使用了您的设置,即五分之一)。
  • 有必要为迭代器调用方法test_size以生成列车和测试数据的索引。

答案 2 :(得分:0)

如果您只想对训练数据进行预测,则无需将数据拆分为训练和测试。

您可以调整原始数据,然后对其进行预测。

model.fit(original data, target)
model.predict(original data)