机器学习算法-KNN算法

KNN 算法介绍:

k-近邻算法(k-Nearest Neighbour algorithm),又称为KNN算法,是数据挖掘技术中原理最简单的算法。KNN的工作原理:给定一个已知标签类别的训练数据集,输入没有标签的新数据后,在训练数据集中找到与新数据最邻近的k个实例,如果这k个实例的多数属于某个类别,那么新数据就属于这个类别。可以简单理解为:由那些离X最近的k个点来投票决定X归为哪一类。

在这里插入图片描述

图1中有红色三角和蓝色方块两种类别,我们现在需要判断绿色圆点属于哪种类别:
当k=3时,绿色圆点属于红色三角这种类别;
当k=5时,绿色圆点属于蓝色方块这种类别。
举个简单的例子,可以用k近邻算法分类判断一个电影是爱情片还是动作片。(打斗镜头和接吻镜头数量为虚构)

在这里插入图片描述

表1就是我们已有的数据集合,也就是训练样本集。这个数据集有两个特征一-打斗镜头数和接吻镜头数。 除此之外,我们也知道每部电影的所属类型,即分类标签。粗略看来,接吻镜头多的就是爱情片,打斗镜头多的就是动作片。如果现在给我一部新的电影,告诉我电影中的打斗镜头和接吻镜头分别是多少,可以根据给出的信息进行判断,这部电影是属于爱情片还是动作片。而k- 近邻算法也可以像我们人一样做到。

在这里插入图片描述

我们可以从散点图中大致推断,这个末知电影有可能是爱情片,因为看起来距离已知的三个爱情片更近一点。k-近邻算法就是距离度量来判断分类情况。这个电影分类例子中有两个特征,也就是在二维平面中计算两点之间的距离,就可以用我们高中学过的距离计算公式:

在这里插入图片描述

如果是多个特征扩展到N维空间,我们可以使用欧氏距离(也称欧几里得度量),计算公式如下所示:

在这里插入图片描述

代码实现(一):

#导入包
import pandas as pd
#设置数据集
rowdate={'电影名称':['无问东西','后来的我们','前任3','红海行动','唐人街探案','战狼'],
         '打斗镜头':[1,5,12,108,112,115],
         '接吻镜头':[101,89,97,5,9,8],
         '电影类型':['爱情片','爱情片','爱情片','动作片','动作片','动作片']}
movie_date=pd.DataFrame(rowdate);#将数据集转换为pd模式
# print(rowdate);
print(movie_date);
#传入新的数据
new_date=[24,67];
#计算离每个电影的距离
dist=list((((movie_date.iloc[:6,1:3])-new_date)**2).sum(1)**0.5)
#print(dist);
#将计算好的距离排序
dist_1=pd.DataFrame({'dist':dist,'lables':(movie_date.iloc[:6,3])})
print(dist_1);
dr=dist_1.sort_values(by='dist')[:4]#找到距离最近的四个
print(dr)
#确定前4个所出现的频率
re=dr.loc[:,'lables'].value_counts();
print(re)
result=[];
result.append(re.index[0]);
print(result)

数据归一化

我们发现,上面计算式子中差值最大的属性对计算结果的影响最大, 所以接下来我们要进行数值归-化的处理,使得这三个特征的权重相等。数据归-化的处理方法有很多种,比如0-1标准化、Z-score标准化、 Sigmoid压缩法等等,在这里我们使用最简单的0-1标准化,公式如下:

在这里插入图片描述

代码实现(二):k-近邻算法之约会网站配对效果判定

介绍:海伦-直使用在线约会网站寻找适合自己的约会对象,尽管约会网站会推荐不同的人选,但她并不是每一个都喜欢,经过一番总结,她发现曾经交往的对象可以分为三类:

●不喜欢的人
●魅力一般的人
●极具魅力得人

海伦收集约会数据已经有了一段时间, 她把这些数据存放在文本文件datingTestSet.txt中, 其中各字段分别

1.每年飞行常客里程
2.玩游戏视频所占时间比
3.每周消费冰淇淋公升数

import pandas as pd
#导入数据集
datetest=pd.read_table("datingTestSet.txt",header=None);
#print(datetest);#输出数据集
#print(datetest.head())#输出前五行的数据集
#print(datetest.shape);
#分析t数据(散点图来表示)
import matplotlib.pyplot as plt#绘制散点图
#把不同的标签用不同的颜色表示
Color=[]#设置标签的颜色
for i in range(datetest.shape[0]):
    m=datetest.iloc[i,-1]
    if m=="didntLike":
        Color.append('black')
    if m=="smallDoses":
        Color.append("orange")
    if m=="largeDoses":
        Color.append("red")
#设置将不同心动的人设置不同的颜色
#print(Color);#输出Color颜色
#绘制两两之间的特征值得散点图
#plt.rcParams['font.sans-serif']=['SimHei']#设置图中的字体为黑体
pl=plt.figure(figsize=(12,8));#设置画布的大小
fig1=pl.add_subplot(221);
plt.scatter(datetest.iloc[:,1],datetest.iloc[:,2],marker='.',c=Color)
plt.xlabel("玩游戏的时间");
plt.ylabel("每周消费冰激凌的公升数");
#plt.show();
fig2=pl.add_subplot(222);
plt.scatter(datetest.iloc[:,0],datetest.iloc[:,1],marker='.',c=Color)
plt.xlabel("每年飞行里程");
plt.ylabel("玩游戏的时间")

fig3=pl.add_subplot(223);
plt.scatter(datetest.iloc[:,0],datetest.iloc[:,2],marker=".",c=Color);
plt.xlabel("每年飞行的时间");
plt.ylabel("每周消费冰激凌的公升数");
plt.show();
#数据归一化
#由于每年飞行常客的旅程站的比例比较大
#=(x-xmin)/(xmax-xmin);
def minax(datetest):
    mindf=datetest.min();
    maxdf=datetest.max();
    normset=(datetest-mindf)/(maxdf-mindf)
    return normset;
dating=pd.concat([minax(datetest.iloc[:,:3]),datetest.iloc[:,3]],axis=1)
#pd.concat是合并函数,axis: 需要合并链接的轴,0是行,1是列
#print(dating.head())
#划分训练集和测试集
def randSplit(dateset,rate=0.9):
    n=datetest.shape[0];
    m=int(n*0.9);
    train=datetest.iloc[:m,:];
    test=datetest.iloc[m:n,:];
    test.index=range(test.shape[0]);
    return train,test;
#输出训练集与测试集
# a=randSplit(datetest)
# print(a);
#定义一个分类器函数
def dateClass(train,test,k):
    n=train.shape[1]-1;#除去标签的那一列
    m=test.shape[0];
    result=[];
    for i in range(m):
        dist=list(((train.iloc[:,:n]-test.iloc[i,:n])**2).sum(1)**0.5)
        dist_l=pd.DataFrame({'dist':dist,'labels':(train.iloc[:,n])})
        dr=dist_l.sort_values(by='dist')[:k];
        re=dr.loc[:,'labels'].value_counts();
        result.append(re.index[0])
    result=pd.Series(result);
    test['predict']=result
    acc=(test.iloc[:,-1]==test.iloc[:,-2]).mean();
    print(f"准确率为{acc}");
    return test
#测试
train,test=randSplit(datetest)
dateClass(train,test,5)
数据可视化截图

在这里插入图片描述

案例三(通过scikit-learn代码实现KNN代码):

一、
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor

X_train = np.array([
    [158, 64, 1],
    [170, 86, 1],
    [183, 84, 1],
    [191, 80, 1],
    [155, 49, 0],
    [163, 59, 0],
    [180, 67, 0],
    [158, 54, 0],
    [170, 67, 0]
])
y_train = [7, 12, 29, 18, 11, 16, 29, 22, 36]

X_test = np.array([
    [160, 66, 1],
    [196, 87, 1],
    [168, 68, 0],
    [177, 74, 0]
])
y_test = [9, 13, 26, 21]

K = 1
clf = KNeighborsRegressor(n_neighbors=K)
clf.fit(X_train, y_train)
predictions = clf.predict(np.array(X_test))
print(predictions)
from sklearn.metrics import r2_score
print(r2_score(y_test, predictions))
二、
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor

X_train = np.array([
    [158, 1],
    [170, 1],
    [183, 1],
    [191, 1],
    [155, 0],
    [163, 0],
    [180, 0],
    [158, 0],
    [170, 0]
])
y_train = [64, 86, 84, 80, 49, 59, 67, 54, 67]

X_test = np.array([
    [160, 1],
    [196, 1],
    [168, 0],
    [177, 0]
])
y_test = [66, 87, 68, 74]

K = 3
clf = KNeighborsRegressor(n_neighbors=K)
clf.fit(X_train, y_train)
predictions = clf.predict(np.array(X_test))
print('Predicted weights: %s' % predictions)
print('Actual weights: %s' % y_test)
from sklearn.metrics import r2_score
print(r2_score(y_test, predictions))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值