首先介绍以下KNN算法,KNN算法的全称是K近邻算法,基本的算法按流程就是:
1. 计算测试集中的样本到训练集中每个样本的距离
2. 对计算得到的距离进行排序
3. 选取和当前的测试样本距离最近的K个训练样本,作为这个测试样本的K个最近的邻居
4. 统计k个邻居的类别的概率
5. K个邻居里面所属的类别概率最高的即为该测试样本的类别
上面的是用KNN来做分类的算法流程,从上面的算法流程可以看出KNN是属于无参数的算法。要用KNN实现回归,其实算法流程和分类差不多,只不过将步骤3得到的K个邻居的值取平均作为该测试样本的回归值。小编比较懒,因为数据量不大,这里的数据就不做归一化处理了,当然了,如果归一化了之后要记得反归一。顺便提一下,归一化的目的是保证各个物理量之间处于同一个数量级之下,消除不同量纲之间的差异。
下面是简单的代码实现:
1.导入数据
import numpy as np
import scipy as sp
import sklearn as skit
import pandas as pd
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor
from sklearn.svm import SVR
from sklearn.metrics import mean_absolute_error
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = 12, 8
csv = './house18.npy' # 这是自己处理好的数据集,还没有经过归一化
data = np.load(csv)
df = pd.DataFrame(data,columns = ['main','lite','dryr','micr','bath','diff'])
# main是总线功率,其他名称各自代表一种电器
print(df.shape)
df.describe() # 看看数据的分布,均值、方差、最大值等等
数据的一些信息如下所示:
2. 总功率数据与各电器的功率消耗曲线
y = df.iloc[:,1:] # y是所有电器的dataframe
X = y.sum(axis=1).to_frame() #X是所有电器在同一时刻相加额度总和
X.plot()
y.plot()
曲线如下所示:
- 散点图 (横坐标为总功率,总坐标为单个电器)
column = 'lite'
plt.scatter(X, y[column]) #横坐标是所有电器的总和,纵坐标是某一电器在不同时刻的功率
4. 数据集划分
yc = y[column]
x_train = X.iloc[:int(X.shape[0] * 0.8),:]
y_train = yc.iloc[:int(yc.shape[0] * 0.8)]
x_test = X.iloc[int(X.shape[0] * 0.8):,:]
y_test = yc.iloc[int(yc.shape[0] * 0.8):]
5.训练与测试
knn = KNeighborsRegressor(n_neighbors=5)
knn.fit(x_train,y_train)
y_hat = pd.Series(knn.predict(x_test)[:], index=x_test.index)
y_hat.name = 'yhat'
train_acc = round(mean_absolute_error(y_train, knn.predict(x_train)) / y_train.max() * 100, 2)
test_acc = round(mean_absolute_error(y_test, knn.predict(x_test)) / y_test.max() * 100, 2)
print("Training Accuracy :", train_acc)
print("Test Accuracy :", test_acc)
print('\n')