实验要求
第一个实验
数据集:Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。该数据集是4个最流行的机器学习数据集之一。通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。
实验要求:
- 读入Iris.csv数据,并将数据的70%做为训练数据,30%做为测试数据;
- 根据KNN算法思想,实现KNN算法,并使用训练数据训练KNN分类模型;
- 使用剩余30%数据对KNN分类模型进行测试,并计算出分类精度。(可考虑使用可视化界面进行分类效果分析)
- 可以直接用sklearn库中的neighbors.KNeighborsClassifier()
提示:
- from random import shuffle --shuffle()
- 可视化模块
第二个实验
数据集dataSet..txt共1000个样本,包括以下三个特征:每年飞行的里程数、玩视频游戏所耗时间百分数,以及每周消费的冰淇淋公升数。希望根据上面三个特征,将上述人群分成1、2、3类。
实验要求:
- 读取数据
- 归一化特征值
- 实现KNN算法
根据数据集提供的类别,计算误差比例,并统计各类别数量
数据:
dataSet.txt
iris.csv
1. 实验基本原理及目的
最近邻算法(k-NearestNeighbor-KNN):
图中,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?
如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角
形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。
由于没有事先学习出模型,KNN也称懒惰学习方法
输入:
T // 训练数据 K //邻居数目 t // 待分配元组
输出:
c //元组t被分配的类别
KNN算法:
N = Φ; //对于元组t发现的邻居集合N
for each do
if |N| ≤ K, then
else
if such that sim(t,u) ≤ sim(t,d),then
begin
N = N-{u};
N = N + {d}
end
c = class to which the most are classified.
2. 数据的准备及数据预处理
2.1实验1
将数据读入,按7:3分别分为训练集和测试集data_practice,data_predict,将字符串类型转换为数字类型对应为0,1,2。
2.2实验2
将数据读入,按330:670分别分为训练集和测试集data_practice,data_predict。
3. 实验过程
3.1实验1
1. 函数介绍:
read(datafile):数据预处理函数,datafile为文件所在位置,返回值为data_practice,data_predict,分别为训练集,预测集。
knn(practice_x,practice_y,predict_x):KNN函数,训练数据的数据和标签,practice_x为数据,practice_y为标签, predict_x为预测数据的的数据,返回值为predict_y,为分的标签。
transfer(a):将字符串数组转化为数字。
cm_plot(t1,output):画图函数,画出混淆矩阵,t1为数据的真实标签,output为预测标签。
2.源码:
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
#读取文件函数,数据预处理,70%做训练集,30%做预测集
def read(datafile):
data=pd.read_csv(datafile)
#打乱顺序
data=data.sample(frac=1).reset_index(drop=True)
length=len(data)
#70%做训练集,剩下的为预测集
data_practice=data[0:int(length*0.7)]
data_predict=data[int(length*0.7):]
return data_practice,data_predict
#KNN预测函数
def knn(practice_x,practice_y,predict_x):
#测试精度参数为n_neighbors
neigh=KNeighborsClassifier(n_neighbors=5)
neigh.fit(practice_x, practice_y)
predict_y=neigh.predict(predict_x)
return predict_y
#将字符类型数据转化为数字类型
def transfer(a):
b=[]
for i in a:
if i=='Iris-setosa':
b.append(0)
elif i=='Iris-versicolor':
b.append(1)
else:
b.append(2)
return b
#混淆矩阵画图
def cm_plot(t1,output):
from sklearn.metrics import confusion_matrix
cm=confusion_matrix(t1,output)
# print(cm)
# print(len(cm))
import matplotlib.pyplot as plt
plt.matshow(cm,cmap=plt.cm.Greens)
plt.colorbar()
for x in range(len(cm)):
for y in range(len(cm)):
plt.annotate(cm[x,y],xy=(x,y),horizontalalignment='center',verticalalignment='center')
plt.ylabel('True label')
plt.xlabel('Predict label')
return plt
#读取文件
datafile='D:/ProgramData/file5/iris.csv'
data_practice,data_predict=read(datafile)
#训练数据的数据和标签,practice_X为数据,practice_y为标签
practice_x=np.array(data_practice.iloc[0:,0:4])
practice_y=list(data_practice['class'])
#预测数据的结果和标签,predict_x为数据,predict_y为标签
predict_x=np.array(data_predict.iloc[0:,0:4])
predict_y=knn(practice_x,practice_y,predict_x)
#将预测的标签和数据真正的标签转化成数字类型,并画出混淆矩阵
true_y=transfer(list(data_predict['class']))
test_y=transfer(predict_y)
cm_plot(true_y,test_y).show()
#打印预测结果
print(predict_y)
3.2实验2
1. 函数介绍:
read(datafile):预处理函数,数据预处理函数,datafile为文件所在位置,将特征值进行归一化处理,返回值为归一化之后的数据。
knn(practice_x,practice_y,predict_x):KNN函数,同上个实验。
printf(true_y,predict_y):打印函数,打印结果,true_y为真实值,predict_y为预测值。
2.源码:
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
#预处理函数
def read(datafile):
data=np.array(pd.read_table(datafile,sep="\t",header=-1))
a=[0,0,0]
for i in range(0,3):
a[i]=max(data[:,i])-min(data[:,i])
for i in range(0,3):
data[:,i]=data[:,i]/a[i]
return data
#KNN预测函数
def knn(practice_x,practice_y,predict_x):
#测试精度参数为n_neighbors
neigh=KNeighborsClassifier(n_neighbors=5)
neigh.fit(practice_x, practice_y)
predict_y=neigh.predict(predict_x)
return predict_y
#分类错误函数
def printf(true_y,predict_y):
k=0
number1=0
number2=0
number3=0
for i in range(0,len(true_y)):
if true_y[i]!=predict_y[i]:
k+=1
if true_y[i]==1:
number1+=1
elif true_y[i]==2:
number2+=1
else:
number3+=1
for i in range(0,len(true_y)):
print('分类结果为:'+str(predict_y[i])+',实际结果为:'+str(true_y[i]))
print('错误率为:'+str(k/len(true_y)))
print('分类错误数:'+str(k)+',总样本数为:'+str(len(true_y)))
print('第一类 第二类 第三类')
print(str(number1)+' '+str(number2)+' '+str(number3))
return
datafile='D:/ProgramData/file5/dataSet.txt'
data=read(datafile)
practice_x=data[0:330,0:2]
practice_y=data[0:330,3]
predict_x=data[330:len(data),0:2]
true_y=data[330:len(data),3]
predict_y=knn(practice_x,practice_y,predict_x)
printf(true_y,predict_y)
4. 实验结果分析
4.1实验1
当精度K取3时:
图像:
预测结果:
当精度K取5时:
图像:
预测结果:
分析:对比K为3和5,5的精度更高。
4.2实验2
实验结果: