zoukankan      html  css  js  c++  java
  • K-近邻算法实例

    一、鸢尾花种类预测

    • 数据集分布

      • load和fetch返回的数据类型datasets.base.Bunch(字典格式)
      1. data:特征数据数组,是 [n_samples * n_features] 的二维 numpy.ndarray 数组
      2. target:标签数组,是 n_samples 的一维 numpy.ndarray 数组
      3. DESCR:数据描述
      4. feature_names:特征名,新闻数据,手写数字、回归数据集没有
      5. target_names:标签名
    • 数据集的划分

      • 训练数据:用于训练,构建模型
      • 测试数据:在模型检验时使用,用于评估模型是否有效
      • 训练集:70% 80% 75%
      • 测试集:30% 20% 25%
      • 数据集划分api
      1. x 数据集的特征值
      2. y 数据集的标签值
      3. test_size 测试集的大小,一般为float
      4. random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
      5. return 测试集特征训练集特征值值,训练标签,测试标签(默认随机取)

    # 内嵌绘图
    import seaborn as sns
    import matplotlib.pyplot as plt
    import pandas as pd
    from pylab import mpl
    # 设置显示中文字体
    mpl.rcParams["font.sans-serif"] = ["SimHei"]
    
    from sklearn.datasets import load_iris,fetch_20newsgroups
    from sklearn.model_selection import train_test_split
    # 数据集获取
    
    # 小数据集获取
    iris = load_iris()
    # print("鸢尾花数据集的返回值:
    ", iris)
    # 返回值是一个继承自字典的Bench
    # print("鸢尾花的特征值:
    ", iris["data"])
    # print("鸢尾花的目标值:
    ", iris.target)
    # print("鸢尾花特征的名字:
    ", iris.feature_names)
    # print("鸢尾花目标值的名字:
    ", iris.target_names)
    # print("鸢尾花的描述:
    ", iris.DESCR)
    
    # Seaborn 是基于 Matplotlib 核心库进行了更高级的 API 封装,可以让你轻松地画出更漂亮的图形。而 Seaborn 的漂亮主要体现在配色更加舒服、以及图形元素的样式更加细腻。
    # 安装 pip install seaborn
    # seaborn.lmplot() 是一个非常有用的方法,它会在绘制二维散点图时,自动完成回归拟合
    #     sns.lmplot() 里的 x, y 分别代表横纵坐标的列名,
    #     data= 是关联到数据集,
    #     hue=*代表按照 species即花的类别分类显示,
    #     fit_reg=是否进行线性拟合。
    
    # 把数据转换成dataframe的格式
    iris_d = pd.DataFrame(iris['data'], columns=['Sepal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width'])
    iris_d['target'] = iris.target
    # print(iris_d)
    
    def plot_iris(iris,col1,col2 ):
        sns.lmplot(x=col1, y=col2, data=iris, hue="target", fit_reg=False)
        plt.xlabel(col1)
        plt.ylabel(col2)
        plt.title('鸢尾花种类分布图')
        plt.show()
    plot_iris(iris_d, 'Petal_Width', 'Sepal_Length')
    plot_iris(iris_d, 'Petal_Width', 'Petal_Length')
    
    
    # 训练集的划分
    # 对鸢尾花数据集进行分割
    # 训练集的特征值x_train 测试集的特征值x_test 训练集的目标值y_train 测试集的目标值y_test
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
    print("训练集的特征值x_train:
    ", x_train.shape)
    print("测试集的特征值x_test:
    ", x_test.shape)
    print("训练集的目标值y_train:
    ", y_train.shape)
    print("测试集的目标值y_test:
    ", y_test.shape)
    # 随机数种子
    x_train1, x_test1, y_train1, y_test1 = train_test_split(iris.data, iris.target, random_state=6)
    x_train2, x_test2, y_train2, y_test2 = train_test_split(iris.data, iris.target, random_state=6)
    # print("如果随机数种子不一致:
    ", x_train == x_train1)
    # print("如果随机数种子一致:
    ", x_train1 == x_train2)
    
    

    进行模型预测的代码如下

    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.neighbors import KNeighborsClassifier
    
    """
    1.获取数据集
    2.数据基本处理
    3.特征工程
    4.机器学习(模型训练)
    5.模型评估
    """
    # 1.获取数据集
    iris = load_iris()
    
    # 2.数据基本处理
    # 2.1 数据分割
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22, test_size=0.2)
    
    # 3.特征工程
    # 3.1 实例化一个转换器
    transfer = StandardScaler()
    # 3.2 调用fit_transform方法
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.fit_transform(x_test)
    
    # 4.机器学习(模型训练)
    # 4.1 实例化一个估计器
    estimator = KNeighborsClassifier(n_neighbors=5)
    # 4.2 模型训练
    estimator.fit(x_train, y_train)
    
    # 5.模型评估
    # 5.1 输出预测值
    y_pre = estimator.predict(x_test)
    print("预测值是:
    ", y_pre)
    print("预测值和真实值对比:
    ", y_pre == y_test)
    
    # 5.2 输出准确率
    ret = estimator.score(x_test, y_test)
    print("准确率是:
    ", ret)
    


    我们可以看出这样预测的准确率并不高,所以就要对算法进行优化,提高预测的准确率,就要用到下面的交叉验证网格搜索的方法

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

    • 训练集:训练集+验证集

    • 测试集:测试集

    什么是网格搜索(Grid Search)
    通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。

    • sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
      • 对估计器的指定参数值进行详尽搜索
      • estimator:估计器对象
      • param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}
      • cv:指定几折交叉验证
      • fit:输入训练数据
      • score:准确率
      • 结果分析:
        • bestscore__:在交叉验证中验证的最好结果
        • bestestimator:最好的参数模型
        • cvresults:每次交叉验证后的验证集准确率结果和训练集准确率结果

    调优后的代码

    """
    1.获取数据集
    2.数据基本处理
    3.特征工程
    4.机器学习(模型训练)
    5.模型评估
    """
    
    
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split, GridSearchCV
    from sklearn.preprocessing import StandardScaler
    from sklearn.neighbors import KNeighborsClassifier
    
    if __name__=='__main__':
    # 1.获取数据集
        iris = load_iris()
    
        # 2.数据基本处理
        # 2.1 数据分割
        x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2)
    
        # 3.特征工程
        # 3.1 实例化一个转换器
        transfer = StandardScaler()
        # 3.2 调用fit_transform方法
        x_train = transfer.fit_transform(x_train)
        x_test = transfer.fit_transform(x_test)
    
    
        # 4.机器学习(模型训练)
        # 4.1 实例化一个估计器
        estimator = KNeighborsClassifier()
    
        # 4.2 调用交叉验证网格搜索模型
        param_grid = {"n_neighbors": [1, 3, 5, 7, 9]}
        estimator = GridSearchCV(estimator, param_grid=param_grid, cv=10, n_jobs=-1)
    
        # 4.3 模型训练
        estimator.fit(x_train, y_train)
    
        # 5.模型评估
        # 5.1 输出预测值
        y_pre = estimator.predict(x_test)
        print("预测值是:
    ", y_pre)
        print("预测值和真实值对比:
    ", y_pre == y_test)
    
        # 5.2 输出准确率
        ret = estimator.score(x_test, y_test)
        print("准确率是:
    ", ret)
    
        # 5.3 其他评价指标
        print("最好的模型:
    ", estimator.best_estimator_)
        print("最好的结果:
    ", estimator.best_score_)
        print("整体模型结果:
    ", estimator.cv_results_)
    
    
    

    二、预测facebook签到位置
    数据介绍:将根据用户的位置,准确性和时间戳预测用户正在查看的业务。

    train.csv,test.csv
    row_id:登记事件的ID
    xy:坐标
    准确性:定位准确性
    时间:时间戳
    place_id:业务的ID,这是您预测的目标

    • 步骤分析
      • 对于数据做一些基本处理(这里所做的一些处理不一定达到很好的效果,我们只是简单尝试,有些特征我们可以根据一些特征选择的方式去做处理)

        • 1 缩小数据集范围 DataFrame.query()

        • 2 选取有用的时间特征

        • 3 将签到位置少于n个用户的删除

      • 分割数据集

      • 标准化处理

      • k-近邻预测

    本数据集的数据较多

    https://www.kaggle.com/navoshta/grid-knn/data

    代码

    import pandas as pd
    
    from sklearn.model_selection import train_test_split, GridSearchCV
    from sklearn.preprocessing import StandardScaler
    from sklearn.neighbors import KNeighborsClassifier
    
    facebook = pd.read_csv("../../data/train.csv")
    
    # 2.基本数据处理
    # 2.1 缩小数据范围
    facebook_data = facebook.query("x>2.0 & x<2.5 & y>2.0 & y<2.5")
    # 2.2 选择时间特征
    time = pd.to_datetime(facebook_data["time"], unit="s")
    time = pd.DatetimeIndex(time)
    facebook_data["day"] = time.day
    facebook_data["hour"] = time.hour
    facebook_data["weekday"] = time.weekday
    # 2.3 去掉签到较少的地方
    place_count = facebook_data.groupby("place_id").count()
    place_count = place_count[place_count["row_id"]>3]
    facebook_data = facebook_data[facebook_data["place_id"].isin(place_count.index)]
    # 2.4 确定特征值和目标值
    x = facebook_data[["x", "y", "accuracy", "day", "hour", "weekday"]]
    y = facebook_data["place_id"]
    # 2.5 分割数据集
    x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
    
    # 3.特征工程--特征预处理(标准化)
    # 3.1 实例化一个转换器
    transfer = StandardScaler()
    # 3.2 调用fit_transform
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.fit_transform(x_test)
    
    # 4.机器学习--knn+cv
    # 4.1 实例化一个估计器
    estimator = KNeighborsClassifier()
    # 4.2 调用gridsearchCV
    param_grid = {"n_neighbors": [1, 3, 5, 7, 9]}
    estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5)
    # 4.3 模型训练
    estimator.fit(x_train, y_train)
    
    # 5.模型评估
    # 5.1 基本评估方式
    score = estimator.score(x_test, y_test)
    print("最后预测的准确率为:
    ", score)
    
    y_predict = estimator.predict(x_test)
    print("最后的预测值为:
    ", y_predict)
    print("预测值和真实值的对比情况:
    ", y_predict == y_test)
    
    # 5.2 使用交叉验证后的评估方式
    print("在交叉验证中验证的最好结果:
    ", estimator.best_score_)
    print("最好的参数模型:
    ", estimator.best_estimator_)
    print("每次交叉验证后的验证集准确率结果和训练集准确率结果:
    ",estimator.cv_results_)
    
    

    因为数据量较大,即使已经做过了数据截取,依然需要运行几分钟的时间,请耐心等待

  • 相关阅读:
    关于大型网站技术演进的思考(二)--存储的瓶颈(2)[转]
    根据 Sourcemap 调试打包后的js
    webpack 中某些配置
    Javascript 中的数组
    浮动元素的display属性
    安装升级npm依赖
    锚点定位
    我所认识的java泛型(主要讨论通配符的使用)
    快速排序的递归非递归实习java
    java 选择排序
  • 原文地址:https://www.cnblogs.com/yeyueweiliang/p/14310813.html
Copyright © 2011-2022 走看看