ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

KNN分类与案例实战

2020-12-14 12:57:36  阅读:127  来源: 互联网

标签:KNN 实战 sub self 案例 knn np 100 append


本文主要对KNN的分类算法进行验证,以及如何编写KNN,以及KNN的应用。
KNN主要运用于数据分类,本文通过某电站的仿真数据进行验证分析。
官方KNN的调用:

from sklearn.neighbors import KNeighborsClassifier

# 3表示最近的3个点作为分类标准
knn = KNeighborsClassifier(3)
# x表示训练数据, y表示训练数据标签
knn.fit(x, y)
# X表示测试数据
result = knn.predict(X)

官方KNN验证,本文通过电厂仿真数据验证。数据分别是100%、90%、80%工况下的平稳数据。

# 制作数据
data1 = pd.read_excel("100.xlsx")
data2 = pd.read_excel("90.xlsx")
data3 = pd.read_excel("80.xlsx")

d1 = np.array(data1.values)[:, 1:]
d2 = np.array(data2.values)[:, 1:]
d3 = np.array(data3.values)[:, 1:]

# 取前100个数据作为训练数据
x = list(d1[:100, :])
x.extend(list(d2[:100, :]))
x.extend(list(d3[:100, :]))

# 制作数据标签
y = []
for i in range(100):
    y.append(1)
for i in range(100):
    y.append(2)
for i in range(100):
    y.append(3)

结果:

# 取100%工况下100后的所有数据测试
result = knn.predict(d1[100:, :])

# 取90%工况下100后的所有数据测试
result = knn.predict(d2[100:, :])

在这里插入图片描述

# 取80%工况下100后的所有数据测试
result = knn.predict(d3[100:, :])

在这里插入图片描述
KNN自己编写:

class KNeighborsClassifier:
    def __init__(self, k, d="e", p=3):
        """
        :param k: 样本的前几个最近点
        :param d: 距离的计算方式,"e" 欧式距离 "ma"曼哈顿距离 "c"切比雪夫距离 "mi"闵氏距离
        :param p: "mi"距离下p的值
        """
        self.k = k
        self.d = d
        self.p = p

    def EuchdeanDistance(self, sub_X, sub_x):
        # 欧氏距离
        return np.sqrt(np.dot(sub_x - sub_X, sub_x - sub_X))

    def ManhattanDistance(self, sub_X, sub_x):
        # 曼哈顿距离
        return np.sum(np.abs(sub_X - sub_x))

    def ChebyshevDistance(self, sub_X, sub_x):
        # 切比雪夫距离
        return max(np.abs(sub_x - sub_X))

    def MinkowskiDistance(self, sub_X, sub_x, p):
        # 闵氏距离
        return np.power(np.sum(np.power(sub_x - sub_X, p)), 1/p)

    def fit(self, x, y):
        """
        :param x: 训练样本
        :param y: 训练样本标签
        :return: 无返回值
        """
        # 检查数据格式是否正确
        self.x = np.array(x)
        self.y = np.array(y)
        if self.x.shape[0] != self.y.shape[0]:
            raise ValueError("x 与 y维度不同!需要相同的维度")
        if self.x.ndim != 2:
            raise ValueError("x必须是一个二维数组")

    def predict(self, X):
        """
        :param X: 测试样本
        :return result: 预测的测试样本标签
        """
        self.X = np.array(X)
        # 判断测试样本X与训练样本x的维度是否相同
        if self.X.shape[1] != self.x.shape[1]:
            ValueError("x与X维度不同!需要相同的维度")
        # 记录X中每一个样本所对应的标签
        result = []
        # 记录最小距离
        mini_dis = []
        # 计算X中每个样本与x中所有样本的距离
        for i in self.X:
            # 记录每一个X样本对应所有x样本的距离
            distance = []
            # 记录前self.k个距离最小样本对应的标签
            index = []
            for j in self.x:
                if self.d == "e":
                    distance.append(self.EuchdeanDistance(i, j))
                if self.d == "ma":
                    distance.append(self.ManhattanDistance(i, j))
                if self.d == "c":
                    distance.append(self.ChebyshevDistance(i, j))
                if self.d == "mi":
                    distance.append(self.MinkowskiDistance(i, j, self.p))
            # 将距离进行排序返回对应的索引,并选取前k个最短距离
            sort = np.argsort(distance)[:self.k]
            mini_dis.append(distance[sort[0]])
            for j in sort:
                index.append(self.y[j])
            # 计算重复元素的个数
            counter = Counter(index)
            # 查找最大元素对应的标签
            label = max(counter)
            result.append(label)
        return result, mini_dis

自己编写程序验证:

# 100%工况,曼哈顿距离下验证
knn = KNeighborsClassifier(3,d="ma")
knn.fit(x, y)
# 只取分类结果,_表示舍弃
result, _ = knn.predict(d1[100:, :])

在这里插入图片描述

# 90%工况,曼哈顿距离下验证
knn = KNeighborsClassifier(3,d="ma")
knn.fit(x, y)
# 只取分类结果,_表示舍弃
result, _ = knn.predict(d2[100:, :])

在这里插入图片描述

# 80%工况,曼哈顿距离下验证
knn = KNeighborsClassifier(3,d="ma")
knn.fit(x, y)
# 只取分类结果,_表示舍弃
result, _ = knn.predict(d3[100:, :])

在这里插入图片描述
从上面可以看出自己编写的KNN可以进行正确的分类。(但运行速度可能较慢,由于官方KNN由kd树,并行加速等,等学会再更)。

KNN进行异常或故障数据判断,KNN不仅可以用来分类,还能进行异常或故障数据判断,通过测试数据每个数据点与训练数据所有样本最小距离来判断,正常情况下的数据点最小距离较小,当发生异常时异常样本与正常样本距离会变大,可以通过此方法来判断异常数据。

验证:

    data1 = pd.read_excel("100.xlsx")
    data2 = pd.read_excel("90.xlsx")
    data3 = pd.read_excel("80.xlsx")
    data4 = pd.read_excel("100%工况下故障数据.xlsx")

    d1 = np.array(data1.values)[:, 1:]
    d2 = np.array(data2.values)[:, 1:]
    d3 = np.array(data3.values)[:, 1:]
    d4 = np.array(data4.values)[:, 1:]

    x = list(d1[:100, :])
    x.extend(list(d2[:100, :]))
    x.extend(list(d3[:100, :]))

    y = []
    for i in range(100):
        y.append(1)
    for i in range(100):
        y.append(2)
    for i in range(100):
        y.append(3)

    knn = KNeighborsClassifier(3, d="e")
    knn.fit(x, y)
    _, mini_dis = knn.predict(d4)
    print(mini_dis)
    plt.plot(mini_dis)
    plt.xlabel("时间(s)")
    plt.ylabel("距离")
    plt.show()

数据在400s左右发生异常。
在这里插入图片描述

由上图可见正常数据与异常数据可以通过距离来进行区别。

标签:KNN,实战,sub,self,案例,knn,np,100,append
来源: https://blog.csdn.net/husky66/article/details/111151421

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有