机器学习2-KNN

1. 什么是机器学习?

让机器根据用户的输入来寻找规律,而无需进行显示的编程,同时可以根据用户的输入不断的调整从而进行更精准的预测。

2. 机器学习分类:

2.1 有监督学习

在训练集中,每个样本都有明确的目标值或标签。
应用:分类和回归。
    分类:数字识别,判断天气是否有雨。
    回归:放假预测等。

2.2 无监督学习

没有给定的目标值或者标签。(需要模型自己发现数据结构和规律)
应用:聚类和降维。(没有明显的特征
    聚类:将相似特征的点,归为一类。
    降维:降低原来的数据特征,并尽可能的保留原始的数据特征,减少计算的复杂度。常见的降维有:主成分分析,线性判别法等。

应用场景:异常检测:根据用户的消费习惯,来分析用户的某一笔消费是否是异常消费。

3. 机器学习基本步骤

1. 加载数据
2. 数据预处理
3. 选择模型
4. 训练模型
5. 评估模型:根据方差或者模型提供的函数来对模型进行评价。
6. 调整参数
7. 预测新数据

4. KNN算法简介:

4.1 简单介绍

KNN算法是一种简单而有效的监督学习算法,适用于分类和回归任务。根据点之间的距离,来对节点进行判断。
那么问题来了:
    1. K的选择?
    2. 举例的度量?怎么算距离
    3. 权重:不同的点权重是否一致。
    4. 不同的特征,可能如身高,体重差异较大,应该怎么处理?

4.2 KNN算法优缺点

优点:简单,直观。
缺点:
    1. 计算量大,因为每个待分类样本都需要计算与所有点之间的距离。
    2. K值的选择对模型的影响比较大。
    3. 存储需求高:需要存储所整个训练集,存储需求较大。
KNN算法计算量较大,对大型数据集的处理效率较低,所以在实际应用中,数据量不能过大。

K值的影响:
    K值过大:模型简单,决策边界更加平滑,而不是不规则和碎片化。
    K值过小:模型复杂,对噪声和异常值敏感。

4.3 代码实战:

机器中,最常用的算法库是sklearn,下面单独讲解sklearn关于KNN的建模使用。

1. 引入模型:在neighbors库中
2. model的参数详解:(自己的理解,最常用的参数)
	model = KNeighborsClassifier();
    1. n_neighbor: 邻居的数量,默认是5
    2. weights:    度量方式, 可以是 'uniform' -- 权重一样
								   'distance' -- 权重为 距离的倒数
    3. p:  距离计算: 1 --  曼哈顿距离,2--欧氏距离	

3. GridSearchCV: 网格搜索,交叉验证 
	1. estimator: 我们需要估计的模型
	2. param_grid: 字典,对于上述模型,我们需要优化哪些参数
	3. scoring: 模型评分,我们应该怎么对模型的好坏进行判断。
		1. 如果是分类的话,可以简单的使用 'accuracy'    表示准确率
		2. 如果是回归的话,可以简单的使用 'neg_mean_squared_error'  表示方差
 	4. cv: 交叉验证的时候,划分的份数
4. 后面有更高效的搜索方式:RandomizedSearchCV 。 其实用法和上面都是一样的。
4.3.1 鸢尾花分类(使用SKlearn)
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def test01():
    # 1. 记载数据集
    X, y = load_iris(return_X_y=True)

    # 2. 拆分数据集
    # 分为训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # 3. 选择模型/建立模型
    model = KNeighborsClassifier(n_neighbors=3)

    # 4. 进行训练
    model.fit(x_train, y_train)

    # 5. 进行预测
    score = model.score(x_test, y_test)
    print(score)
4.3.2 优化

根据上面的思考,由于影响模型的参数有很多,比如K值的选择,距离的度量(使用曼哈顿距离还是欧氏距离),权重的选择。所以我们不能单纯的自己决定使用哪些参数,而应该经过计算,选择出来在训练集上的最优参数。 GridSearchCV

from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV  # 网格搜索,交叉验证
import numpy as np

def test02():
    # 1. 加载数据
    X, y = load_iris(return_X_y=True)
    x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)

    # 2. 建模
    model = KNeighborsClassifier()

    # 3. 模型优化,下面的三个参数,是model需要优化的参数
    neighbors = np.arange(1, 15)
    weights = ['uniform', 'distance']
    p = [1, 2]
    param = {'n_neighbors': neighbors, 'weights': weights, 'p': p}

    # 4. 进行网格搜索
    gcv = GridSearchCV(estimator=model, param_grid=param, scoring='accuracy', cv=5)
    gcv.fit(x_train, y_train)
    print(gcv.best_params_)
    print(gcv.score(x_test, y_test))

4.3.3 KNN线性回归

from sklearn.neighbors import KNeighborsRegressor
from sklearn.datasets import fetch_california_housing  # 403 forbidden
import pandas as pd
def test03():
    # 使用KNN进行线性回归分析
    data_url = "http://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data"
    df = pd.read_csv(data_url, header=None, sep='\s+')
    print(df.shape)
    X = df.iloc[:, :-1].values
    y = df.iloc[:, -1].values
    # print(X.shape, y.shape)

    # 开始进行数据的分割
    x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # 进行参数优化
    neighbors = np.arange(1, 15)
    weights = ['uniform', 'distance']
    p = [1, 2]

    param = {'n_neighbors': neighbors, 'weights': weights, 'p': p}
    model = KNeighborsRegressor()

    # 其实跟KNN的分类是一样的,除了对于误差的衡量,scoring不同
    gcv = GridSearchCV(estimator=model, param_grid=param, scoring='neg_mean_squared_error', cv=5)
    gcv.fit(x_train, y_train)
    print(gcv.score(x_test, y_test))

4.3.4 归一化、标准化提高准确率

由于在很多情况下,数据的差异相对较大,所以我们需要进行数据的统一之后,方便我们进行预测,也就是数据的预处理。
其实很多情况下,数据的预处理有,去除异常值,填补空值等。其实在机器学习中,前置的数据预处理是非常重要的一步,很大程度上关系着我们模型的训练效果。

# 回归优化,进行归一化和标准化
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# 在此处使用standardScaler进行归一化
import pandas as pd
def test04():
    # 在进行归一化的时候,只需要对X进行归一化,而不需要对y进行归一化。这是一定的
    # 在很多情况下,归一化的效果是要好于最大最小值归一化的。
    data = pd.read_csv("./cancer.csv", sep="\t")
    # print(data.head())

    datay = data["Diagnosis"]
    dataX = data.iloc[:, 2:].values

    # 进行minMax归一化
    # minMaxScaler = MinMaxScaler()
    # dataX = minMaxScaler.fit_transform(dataX)

    # 使用standardScaler进行归一化
    standardizer = StandardScaler()
    dataX = standardizer.fit_transform(dataX)

    # 开始进行训练
    x_train, x_test, y_train, y_test = train_test_split(dataX, datay, test_size=0.2, random_state=42)
    model = KNeighborsClassifier()
    neighbors = np.arange(1, 15)
    weights = ['uniform', 'distance']
    p = [1, 2]
    param = {'n_neighbors': neighbors, 'weights': weights, 'p': p}
    gcv = GridSearchCV(estimator=model, param_grid=param, scoring='accuracy', cv=5)
    gcv.fit(x_train, y_train)
    # print(gcv.best_params_)
    print(gcv.score(x_test, y_test))

4.3.5 标签数据化,归一化,去除异常数据(使用置信区间)

# 将不同的数据类型转换为数字数据
# 在我们的处理过程中,通常有很多的数据是非数值类型的,这个时候我们需要将数据进行数值化。
# 非数值类型转换为数值类型, labelEncoding
# 使用标准差的方式对数据进行过滤
from sklearn.preprocessing import LabelEncoder
def test05():
    # 1. 读取数据
    data = pd.read_csv("./adults.txt")
    print(data.head())
    X = data.iloc[:, :-1]
    y = data.iloc[:, -1].values

    # 首先进行数据处理
    non_numeric_columns = X.select_dtypes(exclude=[np.number]).columns
    # print(non_numeric_columns)

    # 对这些列进行处理
    le = LabelEncoder()
    for col in non_numeric_columns:
        X[col] = le.fit_transform(X[col])
    print(X.head())

    # 处理空值
    X = X.dropna(axis=0)
    print(X.shape)

    # 根据标准分布,去除掉在置信区间之外的数据
    for col in X.columns:
        mean = X[col].mean()
        std = X[col].std()
        lowerBound = mean - 3 * std;
        upperBound = mean + 3 * std;
        X = X[(X[col] >= lowerBound) & (X[col] <= upperBound)]

    # 筛选完成 -- 到这里才发现,其实也要对y进行同样的筛选。直接把x的索引拿过来用了
    print(X.shape)
    y = y[X.index]

    # 标准化
    standardizer = StandardScaler()
    X = standardizer.fit_transform(X)

    # 所有数据处理完毕,后面的训练过程就基本一样了
    x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    model = KNeighborsClassifier()
    neighbors = np.arange(1, 15)
    weights = ['uniform', 'distance']
    p = [1, 2]
    param = {'n_neighbors': neighbors, 'weights': weights, 'p': p}
    gcv = GridSearchCV(estimator=model, param_grid=param, scoring='accuracy', cv=5)
    gcv.fit(x_train, y_train)
    print(gcv.best_params_)
    print(gcv.score(x_test, y_test))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值