Python实现K临近法(KNN)回归(村里最笨的小鸡都可以学会)阅读预计20分钟

阅读预计20分钟

K临近法回归介绍

KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻的已知点,将它们的属性的平均值(或加权平均值)赋给该样本,得到该样本对应属性的值。

对于回归问题,解决流程为: 给定数据集中每个样本及其正确答案,选择一个模型函数h(hypothesis,假设),并为h找到适应数据的(未必是全局)最优解,即找出最优解下的h的参数。这里给定的数据集取名叫训练集(Training Set)。

算法(可以跳过)

import numpy as np
import pandas as pd
import math

def KNN(X_test, dataSet,labels,k):
    dataSet = pd.DataFrame(dataSet, index=None)
    dataSetSize = dataSet.shape[0]
    # sqDiffvec = []
    sqDiff = []
    X_test=pd.Series(X_test, index=None)
    for i in range(dataSetSize):
        sqDiffveci = dataSet[i]-X_test
        sqDiffveci = sqDiffveci.apply(lambda x: x**2)
        sqDiffi = math.sqrt(sum(list(sqDiffveci)))
        # sqDiffvec.append(list(sqDiffveci))
        sqDiff.append(sqDiffi) # 存下每个距离

    sortedsqDiffindex = np.argsort(sqDiff)

    # 选取距离最小的k个点
    votelabels=[]
    for i in range(k):
        votelabel = labels[sortedsqDiffindex[i]]
        votelabels.append(votelabel)
    result=sum(votelabels)/k
    return result

数据的导入与清洗

对于数据导入来说,一般利用pandas内的read_csv的函数来对数据进行导入操作,之后利用pandas和numpy对数据进行操作。在进行数据导入之间需要导入进行线性回归的包:

import pandas as pd                                            #利用pandas数据进行读取与操作
import numpy as np                                             #利用numpy对数据进行操作
import matplotlib.pyplot as plt                                #利用pyplot对数据进行可视化与图像化
from pandas import DataFrame,Series
from sklearn.model_selection import train_test_split           #利用train_test_split将样本分为测试集与试验集
from sklearn.neighbors import KNeighborsRegressor              #使用sklearn进行数据集训练与模型导入


简单的例子

下面举一个简单的例子,用学生的学习时间与学习成绩建立一个简单的回归模型。
首先需要将需要训练的样本转换为DataFrame格式。
in:

# 创建数据集
examDict = {'学习时间': [0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 1.75,
                     2.00, 2.25, 2.50, 2.75, 3.00, 3.25, 3.50, 4.00, 4.25, 4.50, 4.75, 5.00, 5.50],
            '分数': [10, 22, 13, 43, 20, 22, 33, 50, 62,
                   48, 55, 75, 62, 73, 81, 76, 64, 82, 90, 93]}
# 转换为DataFrame的数据格式
examDf = DataFrame(examDict)
print(examDf)

out:
在这里插入图片描述
转换成功之后,可以通过以下几种方法测试样本数据之间的相关性。
1.利用散点图来实现简单的观测
in:

# 绘制散点图
plt.scatter(examDf.分数, examDf.学习时间, color='b', label="Exam Data")

# 添加图的标签(x轴,y轴)
plt.xlabel("Hours")
plt.ylabel("Score")
# 显示图像
plt.show()

out:
在这里插入图片描述
2.计算相关系数
r(相关系数) = x和y的协方差/(x的标准差y的标准差) == cov(x,y)/σxσy(即person系数)

对于相关性强度来说的化有以下的关系:
0~0.3 弱相关
0.3~0.6 中等程度相关
0.6~1 强相关
in:

rDf = examDf.corr()
print(rDf)

out:

在这里插入图片描述
通过以上过程发现学习时间与分数具有较高的相关性。

之后,便可以开始K临近值回归的过程。
在建立回归模型之间需要将模型划分为训练集与测试集。
训练集用于建立模型,而测试集用于检测模型是否准确。
in:

# 将原数据集拆分训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(examDf.分数,examDf.学习时间, train_size=.8)
# X_train为训练数据标签,X_test为测试数据标签,exam_X为样本特征,exam_y为样本标签,train_size 训练数据占比

print("原始数据特征:", examDf.分数.shape,
      ",训练数据特征:", X_train.shape,
      ",测试数据特征:", X_test.shape)

out:
原始数据特征: (20,) ,训练数据特征: (16,) ,测试数据特征: (4,)
抽取20%的样本用作测试集。
其中测试集为随机抽取,绘制散点图可以看出:
in:

plt.scatter(X_train, Y_train, color="blue", label="train data")
plt.scatter(X_test, Y_test, color="red", label="test data")


plt.legend(loc=2)
plt.xlabel("Hours")
plt.ylabel("Pass")
plt.show()

out:
在这里插入图片描述
最后,便可以直接从sklearn中对模型进行调用并评价模型。

进行评价之间将会引入一个决定系数r平方的概念。

对于决定系数R平方常用于评估模型的精确度。

下列为R平方的计算公式:

● y误差平方和 = Σ(y实际值 - y预测值)^2
● y的总波动 = Σ(y实际值 - y平均值)^2
● 有多少百分比的y波动没有被回归拟合线所描述 = SSE/总波动
● 有多少百分比的y波动被回归线描述 = 1 - SSE/总波动 = 决定系数R平方

对于决定系数R平方来说

(1) 回归线拟合程度:有多少百分比的y波动刻印有回归线来描述(x的波动变化)
(2)值大小:R平方越高,回归模型越精确(取值范围0~1),1无误差,0无法完成拟合对于预测来说我们需要运用函数中的model.predict()来得到预测值

Tip:如果行数=-1的话可以使我们的数组所改的列数自动按照数组的大小形成新的数组
#因为model需要二维的数组来进行拟合但是这里只有一个特征所以需要reshape来转换为二维数组

in:

X_train = X_train.values.reshape(-1,1)
X_test = X_test.values.reshape(-1,1)
k = 5    #可以设置不同的k值,会产生不同优劣程度的模型,可以通过调整k值,选择出最优模型
knn = KNeighborsRegressor(k)
knn.fit(X_train, Y_train)
# 生成足够密集的点并进行预测
score = knn.score(X_test, Y_test)
print(score)

out:
0.8128421052631579

最后可以将测试集代入该模型进行预测,绘图来更直观的看出模型预测结果。
in:

Y_pred = knn.predict(X_test)
print(Y_pred)

plt.figure()
plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
plt.plot(range(len(Y_pred)),Y_test,'r',label="test")
plt.legend(loc="upper right") #显示图中的标签
plt.xlabel("the number of sales")
plt.ylabel('value of sales')
plt.savefig("ROC.jpg")
plt.show()

out:
在这里插入图片描述
`

复杂的例子

虽然例子更加复杂,但是方法没有改变。
首先,需要数据集 Advertising.csv,其数据描述了一个产品的销量与广告媒体的投入之间影响,文章最后会给出。之后利用pandas的pd.read()来读取数据。
in:

#通过read_csv来读取我们的目的数据集
adv_data = pd.read_csv("G:\论文代码\机器学习\多元线性回归/样本.csv")   #编码类型可能为encoding="ISO-8859-1"
new_adv_data = adv_data.iloc[:,:]                                     #数据可能需要进行剪切
print(new_adv_data.describe())                                        #数据描述(数量,平均值等)
print(new_adv_data.shape)                                             #数据集大小

out:
在这里插入图片描述
可以使用相同的方法检验相关性,这里只使用corr。
in:

import seaborn as sns      #导入数据包
##相关系数矩阵 r(相关系数) = x和y的协方差/(x的标准差*y的标准差) == cov(x,y)/σx*σy
# 相关系数0~0.3弱相关0.3~0.6中等程度相关0.6~1强相关
print(new_adv_data.corr())
# 通过加入一个参数kind='reg',seaborn可以添加一条最佳拟合直线和95%的置信带。
sns.pairplot(new_adv_data, x_vars=['TV','radio','newspaper'], y_vars='sales', size=7, aspect=0.8,kind = 'reg')
plt.show()

out:
在这里插入图片描述
在这里插入图片描述
划分数据集,分为训练集与测试集。
in:

X_train, X_test, Y_train, Y_test = train_test_split(adv_data.iloc[:, :3], adv_data.sales,train_size=.80)

out:
在这里插入图片描述
最后从sklearn中调用模型,以及评价模型。
in:

k = 5
knn = KNeighborsRegressor(k)
knn.fit(X_train, Y_train)
# 生成足够密集的点并进行预测
score = knn.score(X_test, Y_test)
print(score)
Y_pred = knn.predict(X_test)
plt.figure()
plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
plt.plot(range(len(Y_pred)),Y_test,'r',label="test")
plt.legend(loc="upper right") #显示图中的标签
plt.xlabel("the number of sales")
plt.ylabel('value of sales')
plt.savefig("ROC.jpg")
plt.show()

out:
在这里插入图片描述
在这里插入图片描述

数据以及核心代码

数据(直接复制到csv即可):
TV radio newspaper sales
230.1 37.8 69.2 22.1
44.5 39.3 45.1 10.4
17.2 45.9 69.3 9.3
151.5 41.3 58.5 18.5
180.8 10.8 58.4 12.9
8.7 48.9 75 7.2
57.5 32.8 23.5 11.8
120.2 19.6 11.6 13.2
8.6 2.1 1 4.8
199.8 2.6 21.2 10.6
66.1 5.8 24.2 8.6
214.7 24 4 17.4
23.8 35.1 65.9 9.2
97.5 7.6 7.2 9.7
204.1 32.9 46 19
195.4 47.7 52.9 22.4
67.8 36.6 114 12.5
281.4 39.6 55.8 24.4
69.2 20.5 18.3 11.3
147.3 23.9 19.1 14.6
218.4 27.7 53.4 18
237.4 5.1 23.5 12.5
13.2 15.9 49.6 5.6
228.3 16.9 26.2 15.5
62.3 12.6 18.3 9.7
262.9 3.5 19.5 12
142.9 29.3 12.6 15
240.1 16.7 22.9 15.9
248.8 27.1 22.9 18.9
70.6 16 40.8 10.5
292.9 28.3 43.2 21.4
112.9 17.4 38.6 11.9
97.2 1.5 30 9.6
265.6 20 0.3 17.4
95.7 1.4 7.4 9.5
290.7 4.1 8.5 12.8
266.9 43.8 5 25.4
74.7 49.4 45.7 14.7
43.1 26.7 35.1 10.1
228 37.7 32 21.5
202.5 22.3 31.6 16.6
177 33.4 38.7 17.1
293.6 27.7 1.8 20.7
206.9 8.4 26.4 12.9
25.1 25.7 43.3 8.5
175.1 22.5 31.5 14.9
89.7 9.9 35.7 10.6
239.9 41.5 18.5 23.2
227.2 15.8 49.9 14.8
66.9 11.7 36.8 9.7
199.8 3.1 34.6 11.4
100.4 9.6 3.6 10.7
216.4 41.7 39.6 22.6
182.6 46.2 58.7 21.2
262.7 28.8 15.9 20.2
198.9 49.4 60 23.7
7.3 28.1 41.4 5.5
136.2 19.2 16.6 13.2
210.8 49.6 37.7 23.8
210.7 29.5 9.3 18.4
53.5 2 21.4 8.1
261.3 42.7 54.7 24.2
239.3 15.5 27.3 15.7
102.7 29.6 8.4 14
131.1 42.8 28.9 18
69 9.3 0.9 9.3
31.5 24.6 2.2 9.5
139.3 14.5 10.2 13.4
237.4 27.5 11 18.9
216.8 43.9 27.2 22.3
199.1 30.6 38.7 18.3
109.8 14.3 31.7 12.4
26.8 33 19.3 8.8
129.4 5.7 31.3 11
213.4 24.6 13.1 17
16.9 43.7 89.4 8.7
27.5 1.6 20.7 6.9
120.5 28.5 14.2 14.2
5.4 29.9 9.4 5.3
116 7.7 23.1 11
76.4 26.7 22.3 11.8
239.8 4.1 36.9 12.3
75.3 20.3 32.5 11.3
68.4 44.5 35.6 13.6
213.5 43 33.8 21.7
193.2 18.4 65.7 15.2
76.3 27.5 16 12
110.7 40.6 63.2 16
88.3 25.5 73.4 12.9
109.8 47.8 51.4 16.7
134.3 4.9 9.3 11.2
28.6 1.5 33 7.3
217.7 33.5 59 19.4
250.9 36.5 72.3 22.2
107.4 14 10.9 11.5
163.3 31.6 52.9 16.9
197.6 3.5 5.9 11.7
184.9 21 22 15.5
289.7 42.3 51.2 25.4
135.2 41.7 45.9 17.2
222.4 4.3 49.8 11.7
296.4 36.3 100.9 23.8
280.2 10.1 21.4 14.8
187.9 17.2 17.9 14.7
238.2 34.3 5.3 20.7
137.9 46.4 59 19.2
25 11 29.7 7.2
90.4 0.3 23.2 8.7
13.1 0.4 25.6 5.3
255.4 26.9 5.5 19.8
225.8 8.2 56.5 13.4
241.7 38 23.2 21.8
175.7 15.4 2.4 14.1
209.6 20.6 10.7 15.9
78.2 46.8 34.5 14.6
75.1 35 52.7 12.6
139.2 14.3 25.6 12.2
76.4 0.8 14.8 9.4
125.7 36.9 79.2 15.9
19.4 16 22.3 6.6
141.3 26.8 46.2 15.5
18.8 21.7 50.4 7
224 2.4 15.6 11.6
123.1 34.6 12.4 15.2
229.5 32.3 74.2 19.7
87.2 11.8 25.9 10.6
7.8 38.9 50.6 6.6
80.2 0 9.2 8.8
220.3 49 3.2 24.7
59.6 12 43.1 9.7
0.7 39.6 8.7 1.6
265.2 2.9 43 12.7
8.4 27.2 2.1 5.7
219.8 33.5 45.1 19.6
36.9 38.6 65.6 10.8
48.3 47 8.5 11.6
25.6 39 9.3 9.5
273.7 28.9 59.7 20.8
43 25.9 20.5 9.6
184.9 43.9 1.7 20.7
73.4 17 12.9 10.9
193.7 35.4 75.6 19.2
220.5 33.2 37.9 20.1
104.6 5.7 34.4 10.4
96.2 14.8 38.9 11.4
140.3 1.9 9 10.3
240.1 7.3 8.7 13.2
243.2 49 44.3 25.4
38 40.3 11.9 10.9
44.7 25.8 20.6 10.1
280.7 13.9 37 16.1
121 8.4 48.7 11.6
197.6 23.3 14.2 16.6
171.3 39.7 37.7 19
187.8 21.1 9.5 15.6
4.1 11.6 5.7 3.2
93.9 43.5 50.5 15.3
149.8 1.3 24.3 10.1
11.7 36.9 45.2 7.3
131.7 18.4 34.6 12.9
172.5 18.1 30.7 14.4
85.7 35.8 49.3 13.3
188.4 18.1 25.6 14.9
163.5 36.8 7.4 18
117.2 14.7 5.4 11.9
234.5 3.4 84.8 11.9
17.9 37.6 21.6 8
206.8 5.2 19.4 12.2
215.4 23.6 57.6 17.1
284.3 10.6 6.4 15
50 11.6 18.4 8.4
164.5 20.9 47.4 14.5
19.6 20.1 17 7.6
168.4 7.1 12.8 11.7
222.4 3.4 13.1 11.5
276.9 48.9 41.8 27
248.4 30.2 20.3 20.2
170.2 7.8 35.2 11.7
276.7 2.3 23.7 11.8
165.6 10 17.6 12.6
156.6 2.6 8.3 10.5
218.5 5.4 27.4 12.2
56.2 5.7 29.7 8.7
287.6 43 71.8 26.2
253.8 21.3 30 17.6
205 45.1 19.6 22.6
139.5 2.1 26.6 10.3
191.1 28.7 18.2 17.3
286 13.9 3.7 15.9
18.7 12.1 23.4 6.7
39.5 41.1 5.8 10.8
75.5 10.8 6 9.9
17.2 4.1 31.6 5.9
166.8 42 3.6 19.6
149.7 35.6 6 17.3
38.2 3.7 13.8 7.6
94.2 4.9 8.1 9.7
177 9.3 6.4 12.8
283.6 42 66.2 25.5
232.1 8.6 8.7 13.4

简单例子:

import pandas as pd                                            #利用pandas数据进行读取与操作
import numpy as np                                             #利用numpy对数据进行操作
import matplotlib.pyplot as plt                                #利用pyplot对数据进行可视化与图像化
from pandas import DataFrame,Series
from sklearn.model_selection import train_test_split           #利用train_test_split将样本分为测试集与试验集
from sklearn.neighbors import KNeighborsRegressor              #使用sklearn进行数据集训练与模型导入



# 创建数据集
examDict = {'学习时间': [0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 1.75,
                     2.00, 2.25, 2.50, 2.75, 3.00, 3.25, 3.50, 4.00, 4.25, 4.50, 4.75, 5.00, 5.50],
            '分数': [10, 22, 13, 43, 20, 22, 33, 50, 62,
                   48, 55, 75, 62, 73, 81, 76, 64, 82, 90, 93]}
# 转换为DataFrame的数据格式
examDf = DataFrame(examDict)
print(examDf)







# 将原数据集拆分训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(examDf.分数,examDf.学习时间)
# X_train为训练数据标签,X_test为测试数据标签,exam_X为样本特征,exam_y为样本标签,train_size 训练数据占比
X_train = X_train.values.reshape(-1,1)
X_test = X_test.values.reshape(-1,1)
k = 5
knn = KNeighborsRegressor(k)
knn.fit(X_train, Y_train)
# 生成足够密集的点并进行预测
score = knn.score(X_test, Y_test)
print(score)

Y_pred = knn.predict(X_test)
print(Y_pred)

plt.figure()
plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
plt.plot(range(len(Y_pred)),Y_test,'r',label="test")
plt.legend(loc="upper right") #显示图中的标签
plt.xlabel("the number of sales")
plt.ylabel('value of sales')
plt.savefig("ROC.jpg")
plt.show()

复杂例子:

#导入数据包
import pandas as pd                                            #利用pandas数据进行读取与操作
import numpy as np                                             #利用numpy对数据进行操作
import matplotlib.pyplot as plt                                #利用pyplot对数据进行可视化与图像化
from pandas import DataFrame,Series
from sklearn.model_selection import train_test_split           #利用train_test_split将样本分为测试集与试验集
from sklearn.neighbors import KNeighborsRegressor              #使用sklearn进行数据集训练与模型导入



#通过read_csv来读取我们的目的数据集
adv_data = pd.read_csv("G:\论文代码\机器学习\多元线性回归/样本.csv",encoding="ISO-8859-1")   #编码类型可能为encoding="ISO-8859-1"
new_adv_data = adv_data.iloc[:,:]                                     #数据可能进行剪切
'''
print(new_adv_data.describe())
print(new_adv_data.shape)
import seaborn as sns
##相关系数矩阵 r(相关系数) = x和y的协方差/(x的标准差*y的标准差) == cov(x,y)/σx*σy
# 相关系数0~0.3弱相关0.3~0.6中等程度相关0.6~1强相关
print(new_adv_data.corr())
# 通过加入一个参数kind='reg',seaborn可以添加一条最佳拟合直线和95%的置信带。
sns.pairplot(new_adv_data, x_vars=['TV','radio','newspaper'], y_vars='sales', size=7, aspect=0.8,kind = 'reg')
plt.show()
'''
X_train, X_test, Y_train, Y_test = train_test_split(adv_data.iloc[:, :3], adv_data.sales,train_size=.80)



k = 5
knn = KNeighborsRegressor(k)
knn.fit(X_train, Y_train)
# 生成足够密集的点并进行预测
score = knn.score(X_test, Y_test)
print("score:",score)
Y_pred = knn.predict(X_test)
plt.figure()
plt.plot(range(len(Y_pred)),Y_pred,'b',label="predict")
plt.plot(range(len(Y_pred)),Y_test,'r',label="test")
plt.legend(loc="upper right") #显示图中的标签
plt.xlabel("the number of sales")
plt.ylabel('value of sales')
plt.savefig("ROC.jpg")
plt.show()


文章思路参考CSDN博主「EircWonh」的原创文章,想学习可以去看他的博客,链接如下:

版权声明:本文为CSDN博主「EircWonh」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40014576/article/details/79918819

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值