import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
from sklearn.datasets import load_iris
plt.rcParams['font.sans-serif'] = ['STFangsong']
plt.rcParams['axes.unicode_minus'] = False
%config InlineBackend.figure_format = 'svg'
iris = load_iris()
#加载iris数据集
xtrain = iris.data
# iris 数据集有四个部分:1.iris.data是样本特征
xtrain.shape
(150, 4)
ylabel = iris.target
# 2.iris.target 是样本特征对应的标签
df = pd.DataFrame(xtrain,columns=iris.feature_names)
# 将数据写成dataframe格式
df.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | |
---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 |
1 | 4.9 | 3.0 | 1.4 | 0.2 |
2 | 4.7 | 3.2 | 1.3 | 0.2 |
3 | 4.6 | 3.1 | 1.5 | 0.2 |
4 | 5.0 | 3.6 | 1.4 | 0.2 |
df['label'] = iris.target
# 在dataframe 中加入标签列
df.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | label | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | 0 |
1 | 4.9 | 3.0 | 1.4 | 0.2 | 0 |
2 | 4.7 | 3.2 | 1.3 | 0.2 | 0 |
3 | 4.6 | 3.1 | 1.5 | 0.2 | 0 |
4 | 5.0 | 3.6 | 1.4 | 0.2 | 0 |
X = np.array([5,2.7,2.1,0.4])
# 定义未知的数据
# 散点图,用随意两个特征,三个不同的花朵,用三个颜色
# plt.scatter(df[df['label']==0]['sepal length (cm)'],df[df['label']==0]['sepal width (cm)'])
# plt.scatter(df[df['label']==1]['sepal length (cm)'],df[df['label']==1]['sepal width (cm)'])
# plt.scatter(df[df['label']==2]['sepal length (cm)'],df[df['label']==2]['sepal width (cm)'])
for i in range(3):
plt.scatter(iris.data[ylabel==i,2],iris.data[ylabel==i,3])
# 用花朵类型:012做循环,画图
dist = np.sum((df.iloc[:,:4]-X)**2,axis =1)
# 计算未知样本X 与 已知样本xtrain 的距离
df['dist']= dist
# 将距离添加在主表df上
df.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | label | dist | |
---|---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | 0 | 1.18 |
1 | 4.9 | 3.0 | 1.4 | 0.2 | 0 | 0.63 |
2 | 4.7 | 3.2 | 1.3 | 0.2 | 0 | 1.02 |
3 | 4.6 | 3.1 | 1.5 | 0.2 | 0 | 0.72 |
4 | 5.0 | 3.6 | 1.4 | 0.2 | 0 | 1.34 |
df.sort_values(by='dist')[:3]['label'].mode().index[0]
# 对距离进行排序,并取前3(k)个最近的点,将取出的点的标签取众数,众数对应的index为预测标签
0
X = np.array([5.3,2.7,6.4,1.3])
xtrain = iris.data
ylabel = iris.target
def knn(xtrain,ylabel,k,X):
"实现knn:xtrain(nparray) m个特征的样本集;y样本集的标签;k邻居个数;X未知样本的特征"
"实现回归"
knn_list = [] # knn_list = [(dist,ylabel),(),()]
for i in range(k):
dist = np.sum((xtrain[i] - X)**2) #dist :返回X和样本点的距离
knn.list.append((dist,ylabel[i]))
for i in range(k,len(ylabel)):
dist = np.sum((xtrain[i] - X)**2) # 计算第四个的距离
max_index = knn_list.index(max(knn_list,key = lambda x:x[0]))
if knn_list[max_index][0]>dist:
knn_list[max_index] = (dist,ylabel[i])
#如果原本的点的距离大于新点的距离,那么,我们就把新点的距离和标签,替换到knn_list里面。
#knn_list[max_index][0] :list里的最大距离,
knn = [k[-1] for k in knn_list]
y_pre = np.mean(knn)
# 返回标签的平均值
return y_pre
# labels = [k[-1] for k in knn_list]
labels =[2,2,1,7,7,7]
counts = Counter(labels)
sorted(counts.items() ,key = lambda x:x[1])[-1][0]
7
def KNN(x_train,y_train,n_neighbours,X):
knn_list = []
#K个邻居,【(X和x_train第一个样本点的距离,y_train:第一个样本点的标签)】
for i in range(n_neighbours):
dist = np.linalg.norm(X - x_train[i],ord = 2)
#dist :返回X和样本点的距离
knn_list.append((dist,y_train[i]))
#将结果存入knn_list
for i in range(n_neighbours,len(x_train)):
#从第四(k)个点开始迭代
max_index = knn_list.index(max(knn_list , key = lambda x:x[0]))
#返回原本knn_list的最大dist的索引
dist = np.linalg.norm(X - x_train[i],ord = 2)
#计算X和第4(k)个点的距离
if knn_list[max_index][0]>dist:
knn_list[max_index] = (dist,y_train[i])
#如果原本的点的距离大于新点的距离,那么,我们就把新点的距离和标签,替换到knn_list里面。
knn = [k[-1] for k in knn_list]
#knn 返回,原本knn_list里的所有标签
max_count = np.mean(knn)
# 返回标签的平均值
# count_pairs = Counter(knn)
# max_count = sorted(count_pairs.items() ,key = lambda x:x[1])[-1][0]
# #计算所有标签的频数,并返回频数最大的标签
return max_count
鸢尾花数据集KNN分类
1.1导入数据
x = iris.data # 特征
y = iris.target # 标签
1.2 划分数据集
# 划分数据集
from sklearn.model_selection import train_test_split
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3,random_state=100)
# xtrain 训练集特征
# xtest 测试集特征
# ytrain 训练集标签
# ytest 测试集标签
1.3 导入模型
from sklearn.neighbors import KNeighborsClassifier # KNN分类
from sklearn.neighbors import KNeighborsRegressor # KNN回归
# 1.实例化
knn_clf = KNeighborsClassifier(n_neighbors=5,p=2) #n_neighbors:几个邻居;p:2范数距离
# 2.带入训练集训练
knn_clf.fit(xtrain,ytrain)
KNeighborsClassifier()
# 3.预测数据
knn_clf.predict(xtest)
array([2, 0, 2, 0, 2, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 1, 1, 1, 2, 2, 2, 0,
2, 0, 1, 2, 1, 0, 1, 2, 1, 1, 1, 0, 0, 1, 0, 1, 2, 2, 0, 1, 2, 2,
0])
# 准确率查询
knn_clf.score(xtest,ytest)
0.9777777777777777
array = []
for i in range(1,21):
knn_clf = KNeighborsClassifier(n_neighbors=i,p=2) #n_neighbors:几个邻居;p:2范数距离
knn_clf.fit(xtrain,ytrain)
knn_clf.predict(xtest)
array.append(knn_clf.score(xtest,ytest))
# array
# 学习曲线
labels = [i for i in range(1,21)]
plt.plot(labels,array)
plt.show()
knn = KNeighborsClassifier(7).fit(xtrain,ytrain)
knn
KNeighborsClassifier(n_neighbors=7)
NBA球员数据KNN回归
df = pd.read_excel('E:/QfPython/BI/files/NBA球员数据.xlsx')
df
球员姓名 | 位置 | 身高 | 体重 | 年龄 | 球龄 | 上场次数 | 场均时间 | 进攻能力 | 防守能力 | 是否入选过全明星 | 球队胜率 | 球队市值 | 球员薪金 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 斯蒂芬-库里 | 得分后卫 | 1.91 | 86 | 29 | 7 | 79 | 33.38 | 31.933 | 4 | 是 | 高 | 高 | 3468 |
1 | 勒布朗-詹姆斯 | 大前锋 | 2.03 | 113 | 32 | 13 | 74 | 37.75 | 36.140 | 8 | 是 | 高 | 中 | 3329 |
2 | 保罗-米尔萨普 | 中锋 | 2.03 | 112 | 32 | 10 | 69 | 33.95 | 22.712 | 7 | 是 | 高 | 低 | 3127 |
3 | 戈登-海沃德 | 小前锋 | 2.03 | 103 | 27 | 6 | 73 | 34.45 | 25.382 | 5 | 是 | 高 | 中 | 2973 |
4 | 布雷克-格里芬 | 中锋 | 2.08 | 114 | 28 | 6 | 61 | 34.03 | 27.488 | 6 | 是 | 高 | 高 | 2951 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
392 | 乔丹-麦克雷 | 得分后卫 | 1.98 | 84 | 26 | 1 | 37 | 10.35 | 4.864 | 0 | 否 | 高 | 中 | 50 |
393 | 德隆-威廉姆斯 | 控球后卫 | 1.91 | 91 | 33 | 11 | 50 | 16.08 | 6.640 | 2 | 是 | 高 | 中 | 40 |
394 | 詹姆斯-迈克尔-麦卡杜 | 大前锋 | 2.06 | 104 | 24 | 2 | 52 | 8.78 | 3.176 | 1 | 否 | 高 | 高 | 7 |
395 | 达伦-希利亚德 | 得分后卫 | 1.98 | 93 | 24 | 1 | 39 | 9.77 | 4.106 | 0 | 否 | 中 | 低 | 7 |
396 | CJ-威尔考克斯 | 得分后卫 | 1.96 | 88 | 26 | 2 | 22 | 4.88 | 1.495 | 0 | 否 | 低 | 中 | 7 |
397 rows × 14 columns
df.drop(columns=['是否入选过全明星','球队胜率','球队市值','位置','球员姓名'],inplace = True)
df
# 法二:
# df.select_dtypes(include='number')
身高 | 体重 | 年龄 | 球龄 | 上场次数 | 场均时间 | 进攻能力 | 防守能力 | 球员薪金 | |
---|---|---|---|---|---|---|---|---|---|
0 | 1.91 | 86 | 29 | 7 | 79 | 33.38 | 31.933 | 4 | 3468 |
1 | 2.03 | 113 | 32 | 13 | 74 | 37.75 | 36.140 | 8 | 3329 |
2 | 2.03 | 112 | 32 | 10 | 69 | 33.95 | 22.712 | 7 | 3127 |
3 | 2.03 | 103 | 27 | 6 | 73 | 34.45 | 25.382 | 5 | 2973 |
4 | 2.08 | 114 | 28 | 6 | 61 | 34.03 | 27.488 | 6 | 2951 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
392 | 1.98 | 84 | 26 | 1 | 37 | 10.35 | 4.864 | 0 | 50 |
393 | 1.91 | 91 | 33 | 11 | 50 | 16.08 | 6.640 | 2 | 40 |
394 | 2.06 | 104 | 24 | 2 | 52 | 8.78 | 3.176 | 1 | 7 |
395 | 1.98 | 93 | 24 | 1 | 39 | 9.77 | 4.106 | 0 | 7 |
396 | 1.96 | 88 | 26 | 2 | 22 | 4.88 | 1.495 | 0 | 7 |
397 rows × 9 columns
array = df.drop(columns='球员薪金')
x = []
for i in range(397):
x.append([array.loc[i]['身高'],array.loc[i]['体重'],array.loc[i]['年龄'],array.loc[i]['球龄'],array.loc[i]['上场次数'],array.loc[i]['场均时间'],array.loc[i]['身高'],array.loc[i]['进攻能力'],array.loc[i]['防守能力']])
y = df['球员薪金']
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3)
knn_clf = KNeighborsClassifier(n_neighbors=5,p=2) #n_neighbors:几个邻居;p:2范数距离
knn_clf.fit(xtrain,ytrain)
y_pre = knn_clf.predict(xtest)
plt.plot(range(len(xtest)), y_pre, label = '预测值')
plt.plot(range(len(xtest)), ytest, label = '真实值')
plt.legend()
plt.show()