当前位置: 首页 > article >正文

机器学习knnlearn1

import matplotlib.pyplot as plt
import numpy as np
import operator

# 定义一个函数用于创建数据集
def createDataSet():
    # 定义特征矩阵,每个元素是一个二维坐标点,代表不同策略数据点的坐标
    group = np.array([[20, 3], [15, 5], [18, 1], [5, 17], [2, 15], [3, 20]])
    # 定义每个数据点对应的标签,用于区分是服务策略还是平台策略
    labels = ["服务策略", "服务策略", "服务策略", "平台策略", "平台策略", "平台策略"]
    return group, labels



# classify()函数有4个输入参数:用于分类的输入向量是in_x,输
# 入的训练样本集为datas,标签向量为labels,最后的参数k表示用于
# 选择最近邻居的数目,其中标签向量的元素数目和datas的行数相同。
# 使用欧氏距离公式,计算两个向量点Axy和Bxy之间的




# 实现 K 近邻分类算法的函数
def classify(in_x, datas, labels, k):
    
    # 获取数据集的行数,即数据点的数量  得到了6个点
    data_size = datas.shape[0]
    # 将要分类的点复制 data_size 次,使其与数据集的形状一致,方便后续计算距离
    # 先复制出6个点都是4 17 分别和原始数据进行x轴减法,和y轴减法得到一个新的六个坐标值
    diff_mat = np.tile(in_x, (data_size, 1)) - datas
    # 计算差值的平方
    # 六个新的坐标值 平方一次
    sqrt_diff = diff_mat ** 2
    # 按行求和,得到每个数据点到待分类点的平方距离
    sub_distances = sqrt_diff.sum(axis=1)
    # 对平方距离开方,得到实际距离
    # [21.2602916254693, 16.278820596099706, 21.2602916254693, 1.0, 2.8284271247461903, 3.1622776601683795]
    distances = sub_distances ** 0.5
    # 对距离进行排序,返回排序后的索引

    # [3, 4, 5, 1, 0, 2]
    sorted_distances = distances.argsort()
    # 用于存储每个类别的投票数
    class_count = {}
    # 选取距离最近的 k 个数据点
    for i in range(k):
        # 获取第 i 个最近数据点的标签
        votel_label = labels[sorted_distances[i]]
        # 如果该标签已经在字典中,投票数加 1;否则初始化为 1
        class_count[votel_label] = class_count.get(votel_label, 0) + 1

    # 对投票结果进行排序,按投票数从大到小排列
    sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
    # 返回投票数最多的类别以及所有类别的投票情况
    return sorted_class_count[0][0], class_count

if __name__ == "__main__":
    # 调用 createDataSet 函数获取特征矩阵和标签
    group, labels = createDataSet()
    # 分离服务策略和平台策略的数据点
    service_strategy_points = group[:3]
    platform_strategy_points = group[3:]
    # 绘制服务策略的数据点,设置点的大小为 30,颜色为红色,形状为圆形
    plt.scatter(service_strategy_points[:, 0], service_strategy_points[:, 1], s=30, c="r", marker="o")
    # 绘制平台策略的数据点,设置点的大小为 100,颜色为蓝色,形状为叉号
    plt.scatter(platform_strategy_points[:, 0], platform_strategy_points[:, 1], s=100, c="b", marker="x")
    # 显示绘制好的散点图
    plt.show()


    # 对待分类点 [4, 17] 进行分类,k 值设为 3
    result, vote_count = classify([4, 17], group, labels, 3)
    print("分类分析结果:")
    # 遍历每个类别的投票数并输出
    for label, votes in vote_count.items():
        print(f"{label} 获得 {votes} 票")
    # 输出最终的分类结果
    print(f"最终分类结果: {result}")
    

在这里插入图片描述

分类分析结果:
平台策略 获得 3 票
最终分类结果: 平台策略
# np.tile(in_x, (data_size, 1))
# np.tile 是 numpy 库中的一个函数,其作用是将数组重复指定次数来构建新数组。
# 它接收两个参数:第一个参数 in_x 是要重复的数组;第二个参数 (data_size, 1) 是重复的模式。data_size 代表数据集里数据点的数量,也就是 datas 数组的行数;1 表示在列方向上不进行重复。
# 举例来说,若 in_x = [4, 17],data_size = 6,那么 np.tile(in_x, (data_size, 1)) 的结果会是:
import numpy as np
in_x = [4, 17]
data_size = 6
result = np.tile(in_x, (data_size, 1))
print(result)




[[ 4 17]
 [ 4 17]
 [ 4 17]
 [ 4 17]
 [ 4 17]
 [ 4 17]]
import numpy as np

# 假设这是计算得到的距离数组
distances = np.array([3.2, 1.5, 2.7, 0.8, 4.1])

# 使用 argsort() 方法获取排序后的索引
sorted_distances = distances.argsort()

print("原始距离数组:", distances)
print("排序后的索引:", sorted_distances)
原始距离数组: [3.2 1.5 2.7 0.8 4.1]
排序后的索引: [3 1 2 0 4]
# np.tile(in_x, (data_size, 1)) - datas
# 这里把复制后的 in_x 数组和 datas 数组相减。因为二者形状相同,所以 numpy 会按元素进行减法运算

import numpy as np
in_x = [4, 17]
datas = np.array([[20, 3], [15, 5], [18, 1], [5, 17], [2, 15], [3, 20]])
data_size = datas.shape[0]
diff_mat = np.tile(in_x, (data_size, 1)) - datas
print(diff_mat)

# 相当于把他的x ^ 2 和 y ^ 2
sqrt_diff = diff_mat ** 2

print(sqrt_diff)

# 相当于256+196 = 452 121+144 = 265 以此类推 
sub_distances = sqrt_diff.sum(axis=1)

print(sub_distances)

# 相当于给开了平方
distances = sub_distances ** 0.5
print(distances)


sorted_distances = distances.argsort()

print(sorted_distances)
[[-16  14]
 [-11  12]
 [-14  16]
 [ -1   0]
 [  2   2]
 [  1  -3]]
[[256 196]
 [121 144]
 [196 256]
 [  1   0]
 [  4   4]
 [  1   9]]
[452 265 452   1   8  10]
[21.26029163 16.2788206  21.26029163  1.          2.82842712  3.16227766]
[3 4 5 1 0 2]

欧氏距离公式

二维空间

两点 P ( x 1 , y 1 ) P(x_1, y_1) P(x1,y1) Q ( x 2 , y 2 ) Q(x_2, y_2) Q(x2,y2) 之间的欧氏距离公式:
d = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} d=(x2x1)2+(y2y1)2

多维空间

对于 n n n 维空间中的点 P ( p 1 , p 2 , … , p n ) P(p_1, p_2, \dots, p_n) P(p1,p2,,pn) Q ( q 1 , q 2 , … , q n ) Q(q_1, q_2, \dots, q_n) Q(q1,q2,,qn)
d ( P , Q ) = ∑ i = 1 n ( q i − p i ) 2 d(P, Q) = \sqrt{\sum_{i=1}^{n} (q_i - p_i)^2} d(P,Q)=i=1n(qipi)2

import numpy as np
import operator

"""
Parameters:
    无
Returns:
    group - 数据集
    labels - 分类标签
"""
# 函数说明:创建数据集
def createDataSet():
    #六组二维特征
    group = np.array([[3,104],[2,100],[1,81],[101,10],[99,5],[98,2]])
    #六组特征的标签
    labels = ['爱情片','爱情片','爱情片','动作片','动作片','动作片']
    return group, labels

"""
Parameters:
    inX - 用于分类的数据(测试集)
    dataSet - 用于训练的数据(训练集)
    labes - 分类标签
    k - kNN算法参数,选择距离最小的k个点
Returns:
    sortedClassCount[0][0] - 分类结果
"""
# 函数说明:kNN算法,分类器
def classify0(inX, dataSet, labels, k):
    #numpy函数shape[0]返回dataSet的行数
    dataSetSize = dataSet.shape[0]
    #在列向量方向上重复inX共1次(横向),行向量方向上重复inX共dataSetSize次(纵向)
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    #二维特征相减后平方
    sqDiffMat = diffMat**2
    #sum()所有元素相加,sum(0)列相加,sum(1)行相加
    sqDistances = sqDiffMat.sum(axis=1)
    #开方,计算出距离
    distances = sqDistances**0.5
    #返回distances中元素从小到大排序后的索引值
    sortedDistIndices = distances.argsort()
    #定一个记录类别次数的字典
    classCount = {}
    for i in range(k):
        #取出前k个元素的类别
        voteIlabel = labels[sortedDistIndices[i]]
        #dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。
        #计算类别次数
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    #python3中用items()替换python2中的iteritems()
    #key=operator.itemgetter(1)根据字典的值进行排序
    #key=operator.itemgetter(0)根据字典的键进行排序
    #reverse降序排序字典
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    #返回次数最多的类别,即所要分类的类别
    return sortedClassCount[0][0],classCount

if __name__ == '__main__':
    #创建数据集
    group, labels = createDataSet()
    #测试集
    test = [101,20]
    #kNN分类
    test_class = classify0(test, group, labels, 3)
    #打印分类结果
    print(test_class)
('动作片', {'动作片': 3})
import numpy as np

"""
Parameters:
    filename - 文件名
Returns:
    returnMat - 特征矩阵
    classLabelVector - 分类Label向量
"""
# 函数说明:打开并解析文件,对数据进行分类:1代表不喜欢,2代表魅力一般,3代表极具魅力
def file2matrix(filename):
    #打开文件
    fr = open(filename)
    #读取文件所有内容
    arrayOLines = fr.readlines()
    #得到文件行数
    numberOfLines = len(arrayOLines)
    #返回的NumPy矩阵,解析完成的数据:numberOfLines行,3列
    returnMat = np.zeros((numberOfLines,3))
    #返回的分类标签向量
    classLabelVector = []
    #行的索引值
    index = 0
    for line in arrayOLines:
        #s.strip(rm),当rm空时,默认删除空白符(包括'\n','\r','\t',' ')
        line = line.strip()
        #使用s.split(str="",num=string,cout(str))将字符串根据'\t'分隔符进行切片。
        listFromLine = line.split('\t')
        #将数据前三列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵
        returnMat[index,:] = listFromLine[0:3]
        #根据文本中标记的喜欢的程度进行分类,1代表不喜欢,2代表魅力一般,3代表极具魅力
        if listFromLine[-1] == 'didntLike':
            classLabelVector.append(1)
        elif listFromLine[-1] == 'smallDoses':
            classLabelVector.append(2)
        elif listFromLine[-1] == 'largeDoses':
            classLabelVector.append(3)
        index += 1
    return returnMat, classLabelVector


if __name__ == '__main__':
    #打开的文件名
    filename = "datingTestSet.txt"
    #打开并处理数据
    datingDataMat, datingLabels = file2matrix(filename)
    print(datingDataMat)
    print(datingLabels)
[[4.0920000e+04 8.3269760e+00 9.5395200e-01]
 [1.4488000e+04 7.1534690e+00 1.6739040e+00]
 [2.6052000e+04 1.4418710e+00 8.0512400e-01]
 ...
 [2.6575000e+04 1.0650102e+01 8.6662700e-01]
 [4.8111000e+04 9.1345280e+00 7.2804500e-01]
 [4.3757000e+04 7.8826010e+00 1.3324460e+00]]
[3, 2, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 2, 1, 2, 3, 2, 3, 2, 3, 2, 1, 3, 1, 3, 1, 2, 1, 1, 2, 3, 3, 1, 2, 3, 3, 3, 1, 1, 1, 1, 2, 2, 1, 3, 2, 2, 2, 2, 3, 1, 2, 1, 2, 2, 2, 2, 2, 3, 2, 3, 1, 2, 3, 2, 2, 1, 3, 1, 1, 3, 3, 1, 2, 3, 1, 3, 1, 2, 2, 1, 1, 3, 3, 1, 2, 1, 3, 3, 2, 1, 1, 3, 1, 2, 3, 3, 2, 3, 3, 1, 2, 3, 2, 1, 3, 1, 2, 1, 1, 2, 3, 2, 3, 2, 3, 2, 1, 3, 3, 3, 1, 3, 2, 2, 3, 1, 3, 3, 3, 1, 3, 1, 1, 3, 3, 2, 3, 3, 1, 2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 1, 1, 3, 2, 3, 3, 1, 2, 1, 3, 1, 2, 3, 2, 3, 1, 1, 1, 3, 2, 3, 1, 3, 2, 1, 3, 2, 2, 3, 2, 3, 2, 1, 1, 3, 1, 3, 2, 2, 2, 3, 2, 2, 1, 2, 2, 3, 1, 3, 3, 2, 1, 1, 1, 2, 1, 3, 3, 3, 3, 2, 1, 1, 1, 2, 3, 2, 1, 3, 1, 3, 2, 2, 3, 1, 3, 1, 1, 2, 1, 2, 2, 1, 3, 1, 3, 2, 3, 1, 2, 3, 1, 1, 1, 1, 2, 3, 2, 2, 3, 1, 2, 1, 1, 1, 3, 3, 2, 1, 1, 1, 2, 2, 3, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 3, 2, 3, 3, 3, 3, 1, 2, 3, 1, 1, 1, 3, 1, 3, 2, 2, 1, 3, 1, 3, 2, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 3, 3, 2, 3, 3, 2, 3, 1, 3, 1, 3, 3, 1, 3, 2, 1, 3, 1, 3, 2, 1, 2, 2, 1, 3, 1, 1, 3, 3, 2, 2, 3, 1, 2, 3, 3, 2, 2, 1, 1, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3, 3, 3, 2, 3, 2, 1, 1, 1, 1, 1, 3, 2, 2, 1, 2, 1, 3, 2, 1, 3, 2, 1, 3, 1, 1, 3, 3, 3, 3, 2, 1, 1, 2, 1, 3, 3, 2, 1, 2, 3, 2, 1, 2, 2, 2, 1, 1, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 3, 1, 1, 2, 2, 1, 2, 2, 2, 3, 1, 1, 1, 3, 1, 3, 1, 3, 3, 1, 1, 1, 3, 2, 3, 3, 2, 2, 1, 1, 1, 2, 1, 2, 2, 3, 3, 3, 1, 1, 3, 3, 2, 3, 3, 2, 3, 3, 3, 2, 3, 3, 1, 2, 3, 2, 1, 1, 1, 1, 3, 3, 3, 3, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 2, 3, 2, 1, 2, 2, 2, 3, 2, 1, 3, 2, 3, 2, 3, 2, 1, 1, 2, 3, 1, 3, 3, 3, 1, 2, 1, 2, 2, 1, 2, 2, 2, 2, 2, 3, 2, 1, 3, 3, 2, 2, 2, 3, 1, 2, 1, 1, 3, 2, 3, 2, 3, 2, 3, 3, 2, 2, 1, 3, 1, 2, 1, 3, 1, 1, 1, 3, 1, 1, 3, 3, 2, 2, 1, 3, 1, 1, 3, 2, 3, 1, 1, 3, 1, 3, 3, 1, 2, 3, 1, 3, 1, 1, 2, 1, 3, 1, 1, 1, 1, 2, 1, 3, 1, 2, 1, 3, 1, 3, 1, 1, 2, 2, 2, 3, 2, 2, 1, 2, 3, 3, 2, 3, 3, 3, 2, 3, 3, 1, 3, 2, 3, 2, 1, 2, 1, 1, 1, 2, 3, 2, 2, 1, 2, 2, 1, 3, 1, 3, 3, 3, 2, 2, 3, 3, 1, 2, 2, 2, 3, 1, 2, 1, 3, 1, 2, 3, 1, 1, 1, 2, 2, 3, 1, 3, 1, 1, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 2, 2, 3, 1, 3, 1, 2, 3, 2, 2, 3, 1, 2, 3, 2, 3, 1, 2, 2, 3, 1, 1, 1, 2, 2, 1, 1, 2, 1, 2, 1, 2, 3, 2, 1, 3, 3, 3, 1, 1, 3, 1, 2, 3, 3, 2, 2, 2, 1, 2, 3, 2, 2, 3, 2, 2, 2, 3, 3, 2, 1, 3, 2, 1, 3, 3, 1, 2, 3, 2, 1, 3, 3, 3, 1, 2, 2, 2, 3, 2, 3, 3, 1, 2, 1, 1, 2, 1, 3, 1, 2, 2, 1, 3, 2, 1, 3, 3, 2, 2, 2, 1, 2, 2, 1, 3, 1, 3, 1, 3, 3, 1, 1, 2, 3, 2, 2, 3, 1, 1, 1, 1, 3, 2, 2, 1, 3, 1, 2, 3, 1, 3, 1, 3, 1, 1, 3, 2, 3, 1, 1, 3, 3, 3, 3, 1, 3, 2, 2, 1, 1, 3, 3, 2, 2, 2, 1, 2, 1, 2, 1, 3, 2, 1, 2, 2, 3, 1, 2, 2, 2, 3, 2, 1, 2, 1, 2, 3, 3, 2, 3, 1, 1, 3, 3, 1, 2, 2, 2, 2, 2, 2, 1, 3, 3, 3, 3, 3, 1, 1, 3, 2, 1, 2, 1, 2, 2, 3, 2, 2, 2, 3, 1, 2, 1, 2, 2, 1, 1, 2, 3, 3, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, 3, 2, 3, 2, 3, 3, 2, 2, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 2, 1, 2, 1, 1, 2, 2, 1, 1, 1, 3, 1, 1, 2, 3, 2, 2, 1, 3, 1, 2, 3, 1, 2, 2, 2, 2, 3, 2, 3, 3, 1, 2, 1, 2, 3, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 3, 3]

, 2, 2, 3, 2, 2, 2, 3, 1, 2, 1, 2, 2, 1, 1, 2, 3, 3, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, 3, 2, 3, 2, 3, 3, 2, 2, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 2, 1, 2, 1, 1, 2, 2, 1, 1, 1, 3, 1, 1, 2, 3, 2, 2, 1, 3, 1, 2, 3, 1, 2, 2, 2, 2, 3, 2, 3, 3, 1, 2, 1, 2, 3, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 3, 3]


http://www.kler.cn/a/597141.html

相关文章:

  • 嵌入式硬件工程师从小白到入门-原理图(三)
  • YOLO编程:开启计算机视觉的神奇之门
  • 我被AI骗了—关于CAN总线填充机制的回答
  • AWS中通过Endpoint Security(如Amazon GuardDuty)与安全组、网络ACL联动实现协同防御
  • 【大语言模型_8】vllm启动的模型通过fastapi封装增加api-key验证
  • ci如何做才能做到每秒rps 为3000+
  • Doris性能优化建议
  • 失物招领|校园失物招领系统|基于Springboot的校园失物招领系统设计与实现(源码+数据库+文档)
  • 【JavaEE进阶】部署Web项目到Linux服务器
  • shell流程控制
  • 操作系统导论——第13章 抽象:地址空间
  • Python网络编程入门
  • C语言入门教程100讲(2)变量与常量
  • 随笔(1)
  • 大模型-提示词工程与架构
  • MySQL Router被HTTP流量击穿
  • linux之 内存管理(1)-armv8 内核启动页表建立过程
  • Python协程调度
  • 一文分清重载与重写:Java 编程基础的关键辨析
  • OBOO鸥柏丨广告机终端控制端KylinOS麒麟、统信UOS/鸿蒙国产系统