直奔主题:
import numpy as np
import pandas as pd
data = pd.read_csv(r"iris.csv")
# 删除不需要的列
# 用drop可以删除一个字段,或者删除多个字段
# axis 为1表示列,为0表示行
# inplace = True 表示在现在这个数据源上修改结果,也称:就地修改
data.drop(["class"],axis = 1, inplace=True)
# 删除重复的记录
data.drop_duplicates(inplace=True)
KNN:
"""使用python实现K近邻算法(回归预测)
该算法用于回归预测,根据前3特征属性,寻找最近的K个邻居,
然后再根据K个邻居的第四个特征属性,去预测当前样本的第4个特征值
"""
def __init__(self,k):
"""初始化方法
Parameters
-----
k : int
邻居的个数
"""
self.k = k
def fit(self,X,y):
"""训练方法
Parameters
-----
X : 类数组类型(特征矩阵),形状为【样本数量,特征数量】
待训练的样本特征
y :类数组类型(目标标签),形状为【样本数量】
每个样本的目标值(标签)
"""
#为了代码通用性,把X,y的数据类型全部转化为array数组类型,
#有两种转化方式,
#【np.asarray】转为array数组类型,如果数据本身就是array类型,
#那么用asarray就不用新建array赋值对象了,
#【np.array】转为array数组类型,不管数据源是否为array类型,都要新建一个array类型的新对象
self.X = np.asarray(X)
self.y = np.asarray(y)
def predict(self,X):
"""根据参数传递的X,对样本数据进行预测
Paramters:
-----
X : 类数组类型,形状为【样本数量,特征数量】
待测试的样本特征(属性)
Returns
-----
result : 数组类型
预测的结果值
"""
# 转换成数组类型
X = np.asarray(X)
# 保存预测的结果值
result = []
for x in X:
# 计算距离,(计算与训练集中的每个X的距离)
dis = np.sqrt(np.sum((x-self.X) ** 2,axis = 1))
# 返回数组排序后,每个元素再原数组中的(排序之前的数据)索引
index = dis.argsort()
# 取前k个距离最近的索引()
index = index[:self.k]
# 现以拿到最近的邻居索引值,下面就直接把索引值带入到结果集(self.y)中就可以了
#计算均值,然后加入到结果列表当中
#result.append(np.mean(self.y[index]))
# 现在为了确保数据的准确性,要加入权重分配
# 求所有邻居节点距离的倒数之和,【注意:最后加上一个很小的值,为了避免除数为0的情况】
s = np.sum(1 / (dis[index] + 0.001))
# 使用每个节点距离的倒数,除以倒数之和,得到权重
weight = (1 / (dis[index] + 0.001)) / s
# 使用邻居节点的标签值,乘以对应的权重,然后相加得到最终的预测结果
result.append(np.sum(self.y[index] * weight))
return np.asarray(result)
# 准备训练数据集,每次要打乱数据集顺序,random_state是为了能返回上一次的数据顺序,
t = data.sample(len(data),random_state=0)
train_X = t.iloc[:120,:-1]
train_y = t.iloc[:120,-1]
test_X = t.iloc[120:,:-1]
test_y = t.iloc[120:,-1]
knn = KNN(k=3)
knn.fit(train_X,train_y)
result = knn.predict(test_X)
display(result)
np.mean((result-test_y) ** 2)
display(test_y.values)
display(np.mean((result - test_y) ** 2))
# 可视化部分
import matplotlib as mpl
import matplotlib.pylab as plt
mpl.rcParams["font.family"] = "SimHei"
mpl.rcParams["axes.unicode_minus"] = False
# 调整画布大小
plt.figure(figsize = (10 , 10))
# 绘制预测值
plt.plot(result, "ro-",label="预测值")
# 绘制真实值
plt.plot(test_y.values,"go--",label = "真实值")
plt.title("KNN连续值预测展示")
plt.xlabel("节点序号")
plt.ylabel("花瓣宽度")
plt.legend()
plt.show()