3.3 模型选择和调优(KNN)

发布时间 2023-06-10 17:07:51作者: 哎呦哎(iui)

1.什么是交叉验证(cross validation)

交叉验证:将拿到的训练数据,分为训练和验证集。以下图为例:将数据分成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉验证。
我们之前知道数据分为训练集和测试集,但是为了让从训练得到模型结果更加准确。做以下处理

训练集:训练集+验证集
测试集:测试集
image

2.超参数搜索-网格搜索(Grid Search)

通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。这个就是我们弄多个k值看看那个好的这一类问题的解决方法
image

3.模型选择与调优API

这里一个API既有网格搜索又有交叉验证

sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)

  • 对估计器的指定参数值进行详尽搜索
  • estimator:估计器对象
  • param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}
  • cv:指定几折交叉验证(一般10折)
  • fit():输入训练数据
  • score:准确率
  • 结果分析:
       最佳参数:best_params_
       最佳结果:best_score_
       最佳预估器:best_estimator_
       交叉验证结果: cv_results_

4.鸢尾花k值调优

    knn算法预估器
    estimator=KNeighborsClassifier()

    #加入网格搜素和验证
    param_dict={"n_neighbors":[1,3,5,7,9,11]}

    estimator=GridSearchCV(estimator,param_grid=param_dict,cv=10)

    estimator.fit(x_train,y_train)

完整代码就是:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
def knn_iris_gscv():
    """
    用KNN算法对鸢尾花进行分类,使用网格搜素和交叉验证
    :return:
    """
    #1) 获取数据
    iris = load_iris()
    #2) 划分数据集
    x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,random_state=6)##数据集,目标集
    ##训练集特征值,测试集特征值,训练集目标集,测试集目标集
    #3) 特征工程:标准化
    transfer=StandardScaler()
    x_train=transfer.fit_transform(x_train)
    x_test=transfer.transform(x_test)#这时候只需要让测试集转化就行,没有必要计算,fit时计算过程,transform是转化
    #4) knn算法预估器
    estimator=KNeighborsClassifier()

    #加入网格搜素和验证
    param_dict={"n_neighbors":[1,3,5,7,9,11]}

    estimator=GridSearchCV(estimator,param_grid=param_dict,cv=10)

    estimator.fit(x_train,y_train)
    #5) 模型评估
    #方法1:直接对比真实值和预测值
    y_predict=estimator.predict(x_test)
    print("y_perdict:\n",y_predict)
    print("直接比对真实值和预测值:\n",y_test==y_predict)
    #方法2:计算准确率
    score=estimator.score(x_test,y_test)
    print("准确率:\n",score)
    # 最佳参数:best_params_
    print("最佳参数:\n", estimator.best_params_)
    # 最佳结果:best_score_
    print("最佳结果:\n", estimator.best_score_)
    # 最佳估计器:best_estimator_
    print("最佳估计器:\n", estimator.best_estimator_)
    # 交叉验证结果:cv_results_
    print("交叉验证结果:\n", estimator.cv_results_)
    return None

5.预测facebook签到位置

image

def knncls():
    """
    K近邻算法预测入住位置类别
    :return:
    """
    # 一、处理数据以及特征工程
    # 1、读取收,缩小数据的范围
    data = pd.read_csv("./data/FBlocation/train.csv")

    # 数据逻辑筛选操作 df.query()
    data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75")

    # 删除time这一列特征
    data = data.drop(['time'], axis=1)

    print(data)

    # 删除入住次数少于三次位置
    place_count = data.groupby('place_id').count()

    tf = place_count[place_count.row_id > 3].reset_index()

    data = data[data['place_id'].isin(tf.place_id)]

    # 3、取出特征值和目标值
    y = data['place_id']
    # y = data[['place_id']]

    x = data.drop(['place_id', 'row_id'], axis=1)

    # 4、数据分割与特征工程?

    # (1)、数据分割
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

    # (2)、标准化
    std = StandardScaler()

    # 队训练集进行标准化操作
    x_train = std.fit_transform(x_train)
    print(x_train)

    # 进行测试集的标准化操作
    x_test = std.fit_transform(x_test)

    # 二、算法的输入训练预测
    # K值:算法传入参数不定的值    理论上:k = 根号(样本数)
    # K值:后面会使用参数调优方法,去轮流试出最好的参数[1,3,5,10,20,100,200]
    # 使用网格搜索和交叉验证找到合适的参数
	knn = KNeighborsClassifier()

	param = {"n_neighbors": [3, 5, 10]}

	gc = GridSearchCV(knn, param_grid=param, cv=2)

	gc.fit(x_train, y_train)

	print("选择了某个模型测试集当中预测的准确率为:", gc.score(x_test, y_test))

	# 训练验证集的结果
	print("在交叉验证当中验证的最好结果:", gc.best_score_)
	print("gc选择了的模型K值是:", gc.best_estimator_)
	print("每次交叉验证的结果为:", gc.cv_results_)