机器学习基础03_特征降维&KNN算法-分类&模型选择和调优

目录

一、特征降维

2、主成分分析(PCA)

二、KNN算法-分类

三、模型选择与调优

[1、交叉验证 -->模型选择](#1、交叉验证 -->模型选择)

[2、超参数搜索/网格搜索 Grid Search -->调优](#2、超参数搜索/网格搜索 Grid Search -->调优)


一、特征降维

2、主成分分析(PCA)

核心目标

从原始特征空间中找到一个新的坐标系统,使得数据在新坐标轴上的投影能够最大程度地保留数据的方差,同时减少数据的维度。

原理:根据主成分的方差确定保留的主成分个数,将原始数据通过矩阵进行线性变换得到新的数据矩阵,每一列是一个主成分(特征),每一行是一组数据

则降维操作得到的应是特征变少,数据不变,即列减少行不变的数据矩阵。

方差:保留方差大的主成分数据,如果一个特征的多个样本的值都相同,则方差为0,则说明该特征值不能区别样本,所以该特征没有用。

api:

  • from sklearn.decomposition import PCA

  • PCA(n_components=None)

    • 主成分分析

    • n_components:

      • 实参为小数时:表示降维后保留百分之多少的信息

      • 实参为整数时:表示减少到多少特征

python 复制代码
from sklearn.decomposition import PCA

data = [
    [1,2,3,4],
    [3,4,5,6],
    [7,8,9,10]
    ]
# n_components 为整数
transfer = PCA(n_components=3) # 降到3维
data_new = transfer.fit_transform(data)
print(data_new)
python 复制代码
# n_components为小数
transfer = PCA(n_components=0.95)# 降维后需保留原始数据0.95%的信息
data_new = transfer.fit_transform(data)# 自动降维
print(data_new)

二、KNN算法-分类

样本距离判断

两个样本的距离公式一般使用欧式距离或曼哈顿距离

欧式距离:

曼哈顿距离:

原理

如果一个样本在特征空间中的k个最相似(最邻近)样本中的大多数属于某个类别,则该类本也属于这个类别。

缺点

对于大规模数据集,计算量大,因为需要计算测试样本与所有训练样本的距离。

对于高维数据,距离度量可能变得不那么有意义,引发所谓的"维度灾难"。

api:

sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, algorithm='auto')

参数:

(1)n_neighbors:

int, default=5, 默认情况下用于kneighbors查询的近邻数,就是K

(2)algorithm:

{'auto', 'ball_tree', 'kd_tree', 'brute'}, default='auto'。找到近邻的方式,注意不是计算距离的方式,与机器学习算法没有什么关系,开发中请使用默认值'auto'

方法:

(1) fit(x, y)

使用X作为训练数据和y作为目标数据

(2) predict(X) 预测提供的数据,得到预测数据

python 复制代码
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 加载数据
iris = load_iris()
x,y = iris.data,iris.target

# 分割数据
x_train,x_test,y_train,y_test = train_test_split(x,y,train_size=0.6,random_state=666)

# 处理数据 标准化
scaler = StandardSacler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)

# 模型训练 KNN
knn = KNeighborsClassifier(n_neighbors=5)# 5个邻近单位
knn.fit(x_train,y_train)

# 模型预测
y_predict = knn.predict(x_test)
print(f'y_target_names:{iris.target_names}')
print(f'y_predict:{y_predict}')
print(f'y_test:{y_test}')

# 模型评估
# 01 比对真实值和预测值
re = y_predict==y_test
print(f'比对情况:{re}')
# 02 计算准确率
score = knn.score(x_test,y_test)
print(f'score:{score}')

# 模型推理
x_new = [[4.3,5.1,6.1,1.4],
         [1.7,2.1,3.3,1.8]]
x_new_standard = scaler.transform(x_new)
y_detect = knn.predict(x_new_standard)
print(f'y_detect:{y_detect}')
print(f'预测名称:{iris.target_names[y_detect]}')

模型保存和加载

为了下次更方便地使用已经训练的好的模型测试数据,可使用 joblib库 的函数保存模型和调用模型。

python 复制代码
import joblib

# 保存模型
joblib.dump(estimator,'路径名/命名.pkl') # estimator:训练的模型参数,如上例中为:knn
# 加载模型
estimator = joblib.load('路径名/命名.pkl')
# 使用模型预测
y_test = estimator.predict([[0.4,0.2,0.4,0.7]])
print(y_test)

三、模型选择与调优

1、交叉验证 -->模型选择

(1)保留交叉验证 HoldOut

在这种交叉验证技术中,整个数据集被随机地划分为训练集和验证集。根据经验法则,整个数据集的近70%被用作训练集,其余30%被用作验证集。

优点:简单、容易执行

缺点:不适用于不平衡的数据集。 会有数据被剥夺训练模型的机会。

(2)K-折交叉验证 K-fold

K-Fold交叉验证技术中,整个数据集被划分为K个大小相同的部分。每个分区被称为 一个"Fold"。所以有K个部分被称之为K-Fold。一个Fold被用作验证集,其余的K-1个Fold被用作训练集。

该技术重复K次,直到每个Fold都被用作验证集,其余的作为训练集。

模型的最终准确度是通过取k个模型验证数据的平均准确度来计算的。

api:

from sklearn.model_selection import KFold

使用时只是KFold这个类名不一样其他代码完全一样

(3)分层k-折交叉验证 Stratified k-fold

K-折交叉验证的变种, 分层的意思是在每一折中都保持着原始数据中各个类别的比例关系,比如:原始数据有3类,比例为1:2:1,采用3折分层交叉验证,那么划分的3折中,每一折中的数据类别保持着1:2:1的比例,这样的验证结果更加可信。

api:

from sklearn.model_selection import StratifiedKFold

说明:普通K折交叉验证和分层K折交叉验证的使用是一样的 只是引入的类不同

strat_k_fold=sklearn.model_selection.StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

​ n_splits划分为几个折叠

​ shuffle是否在拆分之前被打乱(随机化),False则按照顺序拆分

​ random_state随机因子

indexs=strat_k_fold.split(X,y)

​ 返回一个可迭代对象,一共有5个折叠,每个折叠对应的是训练集和测试集的下标

然后可以用for循环取出每一个折叠对应的X和y下标来访问到对应的测试数据集和训练数据集 以及测试目标集和训练目标集:

for train_index, test_index in indexs:

​ X[train_index] y[train_index] X[test_index] y[test_index]

python 复制代码
from sklearn.datasets import load_iris
from sklearn.model_selection import StratifiedKFold
from sklearn.neighbors import KNeighborsClassifier

x,y = load_iris(return _X_y=True)
# 分层k-fold交叉验证器 分为5折 True随机打乱 随机数种子
folder = StratifiedKFold(n_split=5,shuffle=True,random_state=666)
# 返回每个折叠的训练集和测试集的下标
indexs = folder.split(x,y)
# 分类模型
knn = KNeighborsClassifier(n_neighbors=6)# 邻近单位设置为6

# 存储得分
score_arr = []
for train_index,test_index in indexs:
  # print(train_index, test_index)
  # 训练模型
  knn.fit(x[train_index],y[train_index])
  # 计算得分
  score = knn.score(x[test_index],y[test_index])
  score_arr.append(score)
print(score_arr)

比如在KNN算法中,k是一个可以人为设置的参数,所以就是一个超参数。网格搜索能自动的帮助我们找到最好的超参数值。

api:

sklearn.model_selection.GridSearchCV(estimator, param_grid)

说明:

同时进行交叉验证(CV)、和网格搜索(GridSearch),GridSearchCV实际上也是一个估计器(estimator),同时它有几个重要属性:

best_params_ 最佳参数

best_score_ 在训练集中的准确率

best_estimator_ 最佳估计器

cv_results_ 交叉验证过程描述

best_index_最佳k在列表中的下标

参数:

estimator: scikit-learn估计器实例

param_grid:以参数名称(str)作为键,将参数设置列表尝试作为值的字典

示例: {"n_neighbors": [1, 3, 5, 7, 9, 11]}

cv: 确定交叉验证切分策略,值为:

(1)None 默认5折

(2)integer 设置多少折

如果估计器是分类器,使用"分层k-折交叉验证(StratifiedKFold)"。在所有其他情况下,使用KFold。

python 复制代码
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighhborsClassifier
from sklearn.datasets import load_iris

x_train,y_train=load_iris(return_X_y=True)
estimator = KNeighborsClassifer()
estimator = GridSearchCV(estimator=estimator,param_grid="n_neighbors":[5,7,9,11]})

estimator.fit(X_train,y_train)
# 通常情况下,直接使用best_params_更为方便
print(estimator.best_params_)
print(estimator.best_score_)
print(estimator.best_estimator_)
print(estimator.best_index_)
相关推荐
努力学习编程的伍大侠7 分钟前
基础排序算法
数据结构·c++·算法
车轮滚滚__7 分钟前
uniapp对接unipush 1.0 ios/android
笔记
qq_5290252921 分钟前
Torch.gather
python·深度学习·机器学习
XiaoLeisj35 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
IT古董1 小时前
【漫话机器学习系列】017.大O算法(Big-O Notation)
人工智能·机器学习
Jasmine_llq1 小时前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
海棠AI实验室1 小时前
AI的进阶之路:从机器学习到深度学习的演变(三)
人工智能·深度学习·机器学习
Lenyiin1 小时前
01.02、判定是否互为字符重排
算法·leetcode