机器学习作业----KNN算法

一、k-近邻算法原理

为了判断未知样本的类别,以所有已知类别的样本作为参照,计算未知样本与所有已知样本的距离,从中选取与未知样本距离最近的K个已知样本,根据少数服从多数的投票法则,将未知样本与K个最邻近样本中所属类别占比较多的归为一类。

KNN的原理就是当预测一个新的值x的时候,根据它距离最近的K个点是什么类别来判断x属于哪个类别

机器学习作业----KNN算法_第1张图片

二、点距离的计算

通常使用的距离函数有:欧氏距离、余弦距离、汉明距离、曼哈顿距离等,一般选欧氏距离作为距离度量,但是这是只适用于连续变量。

机器学习作业----KNN算法_第2张图片

这里的p值是一个变量,

当p=1的时候就得到了 曼哈顿距离 ;

当p=2的时候就得到了欧氏距离。

三、k值的选择

如果 K 值比较小,就相当于未分类物体与它的邻居非常接近才行。这样产生的一个问题就是,如果邻居点是个噪声点,那么未分类物体的分类也会产生误差,这样 KNN 分类就会产生过拟合。
如果 K 值比较大,相当于距离过远的点也会对未知物体的分类产生影响,虽然这种情况的好处是鲁棒性强,但是不足也很明显,会产生欠拟合情况,也就是没有把未分类物体真正分类出来。

一般采用交叉验证的方式选取 K 值。交叉验证的思路就是,把样本集中的大部分样本作为训练集,剩余的小部分样本用于预测,来验证分类模型的准确性。

四、举例

此案例参考b站上一位博主的讲解~~~~~

机器学习作业----KNN算法_第3张图片

预测打斗100次,接吻5次的电影是什么电影类型

代码实现

import operator
import numpy as np


#设计knn算法,利用欧拉公式计算最短距离
def knn(trainDate, testData, labels, k):
    # print(trainDate)
    # print(testData)
    # 将测试数据转为和训练集相同形状,tile函数的作用使矩阵行数和列上复制相应的份额,是倍数的关系
    testData=np.tile(testData,(trainDate.shape[0],1))

    # 利用欧拉公式计算距离
    tempData=(testData-trainDate)**2
    # 将计算的矩阵跨列相加
    tempData=tempData.sum(axis=1)
    tempData=tempData**0.5
    print(tempData)

    # 对距离进行从小到大排序,返回的是数组的索引值
    sortData=np.argsort(tempData)

    # 统计前k个的类型数量
    count={}
    for i in range(k):
        # 取出下标对应的类型
        vote=labels[sortData[i]]
        # 字典中 的get方法返回指定键的值,如果键不在字典中返回默认值0
        count[vote]=count.get(vote,0)+1
        # 按照字典中对象的第二个元素降序排列,返回list
        sortNewData=sorted(count.items(),key=operator.itemgetter(1),reverse=True)
    return sortNewData[0][0]


# 训练数据
trainData = np.array([
    [115, 6],
    [109, 8],
    [120, 9],
    [5, 78],
    [6, 60],
    [8, 69]
])
# 训练数据对用的标签
labels = np.array(['动作片', '动作片', '动作片', '爱情片', '爱情片', '爱情片'])
# 测试数据
testData = np.array([100, 5])
print(knn(trainData, testData, labels, 3))

机器学习作业----KNN算法_第4张图片

五、预测毕业生的薪资等级

         自定义的数据集,可能会存在一些问题,有错误请多多包涵~~~~

professional:专业编号;gender:性别(1:男;0:女);age:年龄;socialSkill:社交能力;professionalSkill:专业能力;

isJob:薪资等级标签

机器学习作业----KNN算法_第5张图片

csv中各个属性的直方图表示

机器学习作业----KNN算法_第6张图片

 

import operator
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn import metrics


def knn(trainDate, testData, labels, k):
    # print(trainDate)
    # print(testData)
    # 将测试数据转为和训练集相同形状,tile函数的作用使矩阵行数和列上复制相应的份额,是倍数的关系
    testData = np.tile(testData, (trainDate.shape[0], 1))

    # 利用欧拉公式计算距离
    tempData = (testData - trainDate) ** 2
    # 将计算的矩阵跨列相加
    tempData = tempData.sum(axis=1)
    tempData = tempData ** 0.5
    # print(tempData)

    # 对距离进行从小到大排序,返回的是数组的索引值
    sortData = np.argsort(tempData)

    # 统计前k个的类型数量
    count = {}
    for i in range(k):
        # 取出下标对应的类型
        vote = labels[sortData[i]]
        # 字典中 的get方法返回指定键的值,如果键不在字典中返回默认值0
        count[vote] = count.get(vote, 0) + 1
        # 按照字典中对象的第二个元素降序排列,返回list
        sortNewData = sorted(count.items(), key=operator.itemgetter(1), reverse=True)
    return sortNewData[0][0]


data = pd.read_csv('movie.csv')
# 将 Pandas 数据框转换为 Numpy 数组
X = data[['professional', 'gender', 'age', 'socialSkill', 'professionalSkill']].values
print(X[0:5])
# 标签
y = data['isJob'].values
print(y[0:5])
# 标准化数据,利用到了sklearn库函数标准化的方法
X = preprocessing.StandardScaler().fit_transform(X.astype(float))
print(X[0:5])
# 利用到了sklearn库函数标准化的方法,划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=4)
print('Train set:', X_train.shape, y_train.shape)
print('Test set:', X_test.shape, y_test.shape)
# 绘制直方图
data.hist(bins=100)
plt.show()
x_predict = []
for item in X_test:
    temp = knn(X_train, item, y_train, 1)
    x_predict.append(temp)
print(y_test)
print(x_predict)
print("Train set Accuracy: ", metrics.accuracy_score(y_test, x_predict))
# print("Test set Accuracy: ", metrics.accuracy_score(y_test, ))

机器学习作业----KNN算法_第7张图片

 k=2

k=3

k=4

k=5

k=6

k的大小取值对精准率的影响不大,可能存在的原因是样本的自己制作的样本出现了一些不准确。在绘制样本的时候采用了excel的随机函数,比较不利于比较精确率。

 

 

 

 

你可能感兴趣的:(算法,机器学习,人工智能)