10 days ago

1.使用sklearn的鸢尾花数据集

from sklearn.datasets import load_iris
iris = load_iris()

2.调用K近邻分类器API

from sklearn.neighbors import KNeighborsClassifier

3.代码实现KNN

def knn(data):
    """
    K近邻算法预测鸢尾花种类
    :return:
    """
    # 一、处理数据以及特征工程

    # 1、取出特征值和目标值
    y = data['target']
    x = data.drop(['target'], axis=1)

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

    # (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)

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

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

    # 调用fit()
    knn.fit(x_train, y_train)

    # 预测测试数据集,得出准确率
    y_predict = knn.predict(x_test)

    print("预测测试集类别:", y_predict)

    print("准确率为:", knn.score(x_test, y_test))

    return None

此时直接调用函数 knn(iris) 即可得出预测结果

4.超参数调优----网格搜索(Grid Search)

# 网格搜索调优
from sklearn.model_selection import GridSearchCV
from pprint import pprint
def knn2(data):
    """
    K近邻算法预测鸢尾花种类
    :return:
    """

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

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

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

    # (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)
    
    # 网格搜索调优
    knn = KNeighborsClassifier()

    param = {"n_neighbors": [i for i in range(1,10)]}

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

    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_)
    pprint(gc.cv_results_)
    
    return None

运行函数 knn2(iris) 即可得到预测结果

5.追求准确率的稳定性----多次计算求平均值

以上代码运行中发现一个问题:每次运行后产生的准确率不同,甚至相差悬殊——最小70%,最大90%
产生原因:算法相同,训练集随机产生,带来不同的结果
由此验证机器学习领域经典语录:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已
为了追求准确率的稳定性,这里尝试采用 多次计算求取平均值的做法
首先需要对KNN代码返回值做下修改

def iris_knn(iris):
    x=iris.data
    y=iris.target
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
    x_train=std.fit_transform(x_train)
    x_test=std.fit_transform(x_test)
    knn=KNeighborsClassifier(n_neighbors=3)
    knn.fit(x_train,y_train)
    # 返回准确率
    return knn.score(x_test,y_test)

多次运算求取平均值

from matplotlib.pyplot as plt
def score_avg():
    num=5000
    score_sum=0
    a=[]
    b=[]
    for i in range(1,num+1):
        score_sum += iris_knn(iris)
        # 每10次查看一下准确率
        if i%10==0:
            score_ave = score_sum/(i)
            a.append(i)
            b.append(score_ave)
    # 获取最终的准确率
    print(score_ave)
    # 将准确率变化过程展示出来
    plt.plot(a,b)
    plt.grid()
    plt.show()

运行函数 score_avg()即可得到结果


可以看到迭代2000次之后准确率稳定在0.919附近

以上 超参数调优稳定准确率 方法可以应用与各种任何数据集和算法

参考资料:
探索sklearn | 鸢尾花数据集

← 【机器学习】sklearn手动下载数据集20newsgroup 【机器学习】20newsgroup数据集KNN与贝叶斯算法比较 →