python knn代码详解_knn算法详解(附练习代码)

KNN算法

KNN算法是一个用于对数据样本进行分类预测的算法

KNN算法就是根据样本之间的距离,来对新的样本来进行分类

计算过程:将新的样本点,与历史样本点中的每一个样本点进行距离的计算 取前k个距离最近的样本点的分类结果 取分类结果频次最好的二分类项作为新样本的分类。

网络搜索:手动指定不同参数的检索范围,通过网络搜索来寻找最优的超参数或者模型参数

K就表示要取离新样本最近的K个样本进行分类决策

通常我们只提供已有数据的 90 %作为训练样本来训练分类器 ,而使用其余的 10% 数据去测试分类器(测试数据占总数据比例不同也会影响到算法的测试结果),且数据划分是随机的

机械学习中的两种类型参数

超参数:

在训练之前,需要设置的参数

​k值

​距离权重

​P值

​对于寻找最优超参数的过程,称之为网络搜索

模型参数

通过样本训练处的参数

数据归一化:将所有数据的量纲映射到同一尺度下。

​1.最值归一化:把所有数据映射到0~1上(数据边界确定,例如学生分数,最低0,最高1)

​2.均值方差归一化:把数据归一到均值为0,方差为1的分布中(数据分布没有明确边界,有可能存在极端数据值)

​优点:

简单,易于理解,易于实现,无需参数估计,无需训练;

对异常值不敏感(个别噪音数据对结果的影响不是很大);

适合对稀有事件进行分类;

适合于多分类问题(multi-modal,对象具有多个类别标签),KNN要比SVM表现要好;

​ 缺点:

​对测试样本分类时的计算量大,内存开销大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本;

​可解释性差,无法告诉你哪个变量更重要,无法给出决策树那样的规则;

​K值的选择:最大的缺点是当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进;

​KNN是一种消极学习方法、懒惰算法。

KNN算法是一个用于对数据样本进行分类预测的算法

#KNN算法

import numpy as np

import matplotlib.pyplot as plt

a_x = [np.random.random() * 10 for i in range(10)]

a_y = [np.random.random() * 10 for i in range(10)]

b_x = [np.random.random() * 10 for i in range(10)]

b_y = [np.random.random() * 10 for i in range(10)]

plt.scatter(a_x,a_y,color = 'r' , marker='+')

plt.scatter(b_x,b_y,color = 'b' , marker='o')

plt.show()

#新增样本

new_data = [np.random.random() * 10 for i in range(10)]

plt.scatter(a_x,a_y,color = 'r' , marker='+')

plt.scatter(b_x,b_y,color = 'b' , marker='o')

plt.scatter(new_data[0],new_data[1],color='g')

plt.show()

#KNN就是根据样本点之间的距离进行分类

#K就表示要取离新样本点最近的K个样本进行分类决策

#实现

train_data = np.array([np.random.random() * 10 for i in range(10)])

train_label = np.array([0,0,0,0,0,1,1,1,1,1])

print('train_data:',train_data)

print('train_label:',train_label)

test_data = [np.random.random() * 10]

distances = []

#计算两个样本之间的距离

for data in train_data:

distances.append(np.sqrt(np.sum((data - test_data)**2)))

#首先对样本进行从小到大的排序,并返回排序后的,原始数据的索引

nearest = np.array(distances).argsort()

K = 3

predict_label = [train_label[i] for i in nearest[:K]]

print(predict_label)

from collections import Counter

votes = Counter(predict_label)

​```

result = votes.most_common()[0][0]

​```

print(result)

tr_data = np.array([np.random.random() * 10 for i in range(20)])

tr_data = tr_data.reshape((10,2))

print(tr_data)

n_data = np.array([np.random.random() * 10,np.random.random() * 10])

print(n_data)

axis = 1 ,是以行为单位 , 如果不加就会将所有的数进行求和

s = np.sqrt(np.sum((tr_data - n_data)**2,axis = 1)).argsort()

print(s)

pre_label = [train_label[i] for i in s[:K]]

res = Counter(pre_label).most_common()[0][0]

print(res)

plt.scatter(tr_data[train_label==0,0] , tr_data[train_label==0,1],color = 'r' , marker='+')

plt.scatter(tr_data[train_label==1,0] , tr_data[train_label==1,1],color = 'r' , marker='+')

plt.scatter(n_data[0],n_data[1],color='g')

plt.show()

from knn import KNNClassfer

from sklean.neighbors import KNeighborsClassifier

knn_clf = KNNClassfer(k = 3)

knn_clf.fit(tr_data,train_label)

x = knn_clf.predit(n_data)

print(x)

封装的KNN算法

import numpy as np

from collections import Counter

class KNNClassfer:

def __init__(self, k=3):

self.k = k

def fit(self, train_data, train_label):

self.train_data = train_data

self.train_label = train_label

def predit(self, test_data):

predit_label = [self.train_label[i] for i in np.sqrt(np.sum((self.train_data - test_data)**2,axis = 1)).argsort()[:self.k]]

return Counter(predit_label).most_common()[0][0]

数据集分割

from sklearn.model_selection import trai_test_spit

#加载数据

x = iris.data

#查看类别的目标值

y = iris.target

#打乱下标

np.random.permutation(len(x))

#随机数种子,以666作为种子随机,是保证以后每次随机结果都是一样的

train_data, test_data, train_label, test_label = train_test_split(x , y, test_size = 0.2, random_state=666)

模型训练

from sklearn.metrics import accuracy_score

accuracy_score(test_label, predict_label)

knn_clf.score(test_data, test_label)

超参数:在模型运行前需要决定的参数

模型参数:算法过程中学习的参数

KNN中的超参数

1.K值

2.p值

3.距离权重

找到最好的K值

best_k = 0

best_score = 0.0

for k in range(1,11):

knn_clf = KNeighborsClassifier(n_neighbors = k)

knn_clf.fit(train_data, train_label)

score = knn_clf.score(test_data, test_label)

if score > best_score:

best_score = score

best_k = k

print('best_k:',best_k)

print('best_score:',best_score)

距离权重

best_k = 0

best_method = ''

best_score = 0.0

for method in ['uniform','distance']:

for k in range(1,11):

knn_clf = KNeighborsClassifier(n_neighbors = k)

knn_clf.fit(train_data, train_label)

score = knn_clf.score(test_data, test_label)

if score > best_score:

best_method = method

best_score = score

best_k = k

print('best_k:',best_k)

print('best_score:',best_score)

print('best_method:',best_method)

寻找最好的P参数

best_k = 0

best_p = 0

best_score = 0.0

for k in range(1,11):

for p in range(1,6):

knn_clf = KNeighborsClassifier(n_neighbors = k, weights='distance',p=p)

knn_clf.fit(train_data, train_label)

score = knn_clf.score(test_data, test_label)

if score > best_score:

best_p = p

best_score = score

best_k = k

print('best_k:',best_k)

print('best_score:',best_score)

print('best_p:',best_p)

网格搜索

grid_param = [

{

"weight":['uniform'],

"n_neighbors":[i for i in range(1,11)]

},

{

"weight":['distance'],

"n_neighbors":[i for i in range(1,11)],

"p":[i for i in range(1,6)]

}

]

最值归一化

x_scaler = (x - np.min(x)) / (np.max(x) - np.min(x))

向量最值归一化

X = np.random.randint(1,100,200)

X = np.array(X ,dtype='float')

X = X.reshape(100,2)

#X[:,0] 是对第1列进行操作

X[:,0] = (X[:,0] - np.min(X[:,0])) /(np.max(X[:,0]) - np.min(X[:,0]))

X[:,1] = (X[:,1] - np.min(X[:,1])) /(np.max(X[:,1]) - np.min(X[:,1]))

均值方差归一化

(std_x - np.mean(std_x)) / np.var(std_x)

sklearn的归一化

from sklearn.preprocessing import StandardScaler

先进行归一化,再进行模型计算

std_train_data = std_scaler.transform(train_data)

std_test_data = std_scaler.transform(test_data)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

你可能感兴趣的:(python,knn代码详解)