在字母站看到的学习视频,做一个记录。
KNN(K近邻算法):
算法步骤
1)计算待分类点与已知类别的点之间的距离
2)按照距离递增次序排序
3)选取与待分类点距离最小的k个点
4)确定前k个点所在类别的出现次数
5)返回前k个点出现次数最高的类别作为待分类点的预测分类
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
iris=load_iris()
data=iris.data
target=iris.target
#feature特征
feature_names=iris.feature_names
target_names=iris.target_names
df=pd.DataFrame(data=data,columns=feature_names)
#鸢尾花的样本集(150,4)
ybj=data.shape
#鸢尾花样本标签150
ybbq=target.size
#为了避免样本集拆分不平衡,先把样本集打乱再分
random_index=np.random.permutation(150)
y=target[random_index]
X=data[random_index]
#因为研究目标表示的是鸢尾花的种类,所以这是一个分类模型
#目的:根据鸢尾花花瓣和花萼的长和宽来预测鸢尾花所属的分类
from sklearn.neighbors import KNeighborsClassifier
#用于拆分样本集的函数
def split_train_target(X,y,train_size,random_seed):
#添加一个种子,固定随机的结果,每次按相同的规律拆分
np.random.seed(random_seed)
random_index1 = np.random.permutation(y.size)
target = y[random_index1]
train = X[random_index1]
#按比例拆分样本集,训练集:train,测试集:test,X相当于试题,y为结果。
n_split = int(y.size * train_size)
X_train = train[:n_split]
X_test = train[n_split:]
y_train = target[:n_split]
y_test = target[n_split:]
return X_train, X_test,y_train, y_test
#用于模型评分的函数
def acc_model(knn,X,y,train_size,times):
train_acc_list = []
test_acc_list=[]
for i in range(times):
X_train, X_test,y_train, y_test = split_train_target(X, y, train_size, random_seed=i)
knn.fit(X_train, y_train)
# 对评分函数做优化,保留训练集的评分,score=答对的个数(预测正确的个数)/预测数据集总量
'''
# y_为预测结果
y_ = knn.predict(X_test)
# acc为评价模型的预测准确率
acc = (y_ == y_test).sum() / y_.size
'''
train_acc=knn.score(X_train,y_train)
train_acc_list.append(train_acc)
test_acc = knn.score(X_test, y_test)
test_acc_list.append(test_acc)
return np.array(train_acc_list),np.array(test_acc_list)
#K值的选择应该不大于样本集数据个数的平方根12*12=144<150,但这里多用几个作为参考
k_list=np.arange(1,20,step=2)
#k_list=[ 1 3 5 7 9 11 13 15 17 19]
#保存所有模型的平均准确率的列表
mean_acc_train_list=[]
mean_acc_test_list=[]
for k in k_list:
knn=KNeighborsClassifier(n_neighbors=k)
#每个参数100次训练的平均评分
mean_acc_train,mean_acc_test=acc_model(knn,X,y,0.8,100)
mean_acc_train_list.append(mean_acc_train.mean())
mean_acc_test_list.append(mean_acc_test.mean())
#算法参数
#函数参数=超参
#学习曲线(目标函数求值)
#画图
sns.set()
plt.plot(k_list,mean_acc_train_list,label="X_train_acc")
plt.plot(k_list,mean_acc_test_list,label="X_test_acc")
plt.xlabel("K-list",fontsize=16)
plt.ylabel("acc",fontsize=16)
plt.xticks(k_list)
plt.legend()
plt.show()
#训练集的评分,通常不期望模型对训练集的评分太高
#因为任何数据集一定存在噪声
#一个好的模型,测试集评分高,并且训练集评分相近
#训练集与测试集的评分差
plt.plot(k_list,np.array(mean_acc_train_list)-np.array(mean_acc_test_list))
plt.xticks(k_list)
plt.show()
#选择K=17,因为此时训练集评分和测试集评分都比较高,而且两者差较小
#最终解,最后使用全部数据,训练最优参数的算法对象,得到的模型就是最终的模型
best_model=KNeighborsClassifier(n_neighbors=17)
best_model.fit(X,y)
sc=best_model.score(X,y)
#sc=0.98
#总结:模型优化分三类。
#1.样本拆分
#2.超参数调整(算法函数的参数)
#3.数据清洗(最重要,直接决定算法高度,因为要考验人对业务的理解)
图1:
图2: