分类模型

分类模型

分类模型主要有
k近邻(KNN)
逻辑斯谛回归
决策树

核心思想

  • 在监督学习中,如果输出变量Y取有限个离散值时,预测问题就变成了分类问题
  • 监督学习从数据中学习一个分类模型或者分类决策函数,称为分类器,分类器对新的输入进行预测,称为分类
  • 包含学习和分类两部分,用数据得到一个分类器,用分类器对新的输入分类

在这里插入图片描述

分类模型核心就是如何分类,然后这样分类好不好

精确率和召回率

一般用分类准确率(accuracy)评价分类器性能:测试集正确分类的样本数 / 总样本数

对于二类分类问题,一般用精确率(precision)和召回率(recall)评价

  • 精确率:所有预测为正类的数据中,预测正确的比例
    在这里插入图片描述

  • 召回率:所有实际为正类的数据中,被正确预测找出的比例
    在这里插入图片描述
    对此,我们要明白几个概念

  • TP:将正类预测为正类

  • FN:将正类预测为负类

  • FP:将负类预测为正类

  • TN:将负类预测为负类

k近邻模型(KNN)

最初级的分类器,将所有的训练数据对应的类别记录下来,当测试对象的某个属性和训练对象的属性完全匹配时,对其进行分类

核心思想

KNN作为分类模型,核心其实就是如何分类:

  1. 计算测试数据和各个训练数据之间的距离
  2. 按照距离的递增关系进行排序
  3. 选取距离最小的 k 个点, 一般 k 不大于20
  4. 确定 k 个点所在类别的出现频率
  5. 返回 k 个点中出现频率最高的类别作为测试数据的预测分类

下面这个事例我们可以看到,KNN 的结果很大程度取决于 k 的取之,而且选择的邻居都要是被正确分类的对象

比如下列这个二维图形,绿色圆属于哪一类
k = 3 时,把离绿圆最近的 3 个点圈起来,有 2 红 1 蓝,那绿圆就被分类为红三角
k = 5 时,把离绿圆最近的 5 个点圈起来,有 2 红 3 蓝,那绿圆就被分类为蓝正方
同样的k = 11,还是蓝色正方形
在这里插入图片描述

距离函数

KNN中,通过计算对象间距离来作为各个对象之间的非相似性指标,避免了对象之间的匹配问题,我们一般使用欧氏距离或者曼哈顿距离
在这里插入图片描述

代码实现

  1. 引入依赖和数据
import numpy as np
import pandas as pd

#sklearn自带了入门学习用的数据集
from sklearn.datasets import load_iris 
#sklearn划分训练集和测试集的模块
from sklearn.model_selection import train_test_split
#计算分类预测准确率的模块
from sklearn.metrics import accuracy_score

#iris 有核心的两部分数据 data 和 target
iris = load_iris()
x = iris.data
# reshape是讲python中的数组结构改变,比如一维改为二维数组
y = iris.target.reshape(-1,1)

print(x.shape)
print(y.shape)
#x.shape is: (150, 4)   y.shape is: (150, 1)
#可以看到分别是4维数组 和 一维数组(只有0,1,2这样的类型值)
#所以应该是一堆 4维坐标点 和 坐标点对应的索引关联到对应的类型

在这里插入图片描述在这里插入图片描述
2. 划分训练集和测试集

# train_data:x 待划分样本数据
# train_target:y 待划分样本数据的结果(标签)
# test_size:测试数据占样本数据的比例,若整数则样本数量
# random_state:设置随机数种子,保证每次都是同一个随机数。若为0或不填,则每次得到数据都不一样
# stratify参数,按照谁划分,可以处理数据不平衡问题
x_train, x_test, y_train, y_test = train_test_split(
    x, y, test_size=0.3, random_state=35, stratify=y)

#python shape可以获取矩阵的形状
print('x_train is:',x_train.shape,'  x_test is:',x_test.shape
      ,'  y_train is:',y_train.shape,'  y_test is:',y_test.shape,)
#x_train is: (105, 4)   x_test is: (45, 4)   
#y_train is: (105, 1)   y_test is: (45, 1)

3.算法实现

# 第一步,定义距离
def l1_distance(a, b): # a是矩阵 ,b是向量 
    # np.sum(x)对输入参数中的所有元素进行求和,输入参数带有axis时,将按照指定axis进行对应求和
    # 有 b 为 ([[ 0,  1,  2,  3,  4,  5],
    #        [ 6,  7,  8,  9, 10, 11]])
    # 那么 np.sum(b) 为 666,np.sum(b,axis=1) 为 array([15, 51])
    return np.sum( np.abs(a-b), axis=1 )
def l2_distance(a, b):
    #sqrt 求平方根
    return np.sqrt( np.sum( (a-b)**2, axis=1 ) )

# 继承式写法,代表KNN继承object
class KNN(object):
    # 定义一个初始化方法,__init__ 是python的构造方法
    # 函数编程特性,可以传入函数 l1_distance
    # n_neighbors 就是 k ,给默认值1
    def __init__(self, n_neighbors = 1, dist_func = l1_distance):
        self.n_neighbors = n_neighbors
        self.dist_func = dist_func
        
    # 训练模型方法
    # KNN实际上没有训练,只要有训练数据和要预测的数据
    def fit(self, x, y):
        self.x_train = x
        self.y_train = y
    
    # 模型预测方法
    def predict(self, x):
        # 初始化预测分类数组
        # np.zeros( 形状(几行几列),类型(默认给的是float) ), 初始化一个 0 矩阵
        y_pred = np.zeros( (x.shape[0],1), dtype=self.y_train.dtype )
        
        # 遍历输入的 x 数据点,取出每一个数据点的序号 i 和数据 x_test
        for i, x_test in enumerate(x):
            # x_test跟所有训练数据计算距离
            distances = self.dist_func( self.x_train, x_test )
            
            #由近到远排序,然后按照索引值记录数值由小到大的顺序
            # argsort 
            nn_index = np.argsort(distances)
            
            #选取最近的 k 个点,保存他们分类的类别
            #nn_index[:self.n_neighbors] 这个截取,ravel是用来将矩阵向量化
            nn_y = self.y_train[ nn_index[:self.n_neighbors] ].ravel()
            
            #统计每个类别出现的次数,找到最多的那个
            # a = [0,1,0,3]
            # np.bincount(a) 得到 array([2, 1, 0, 1])
            #返回第一个出现的最大值的位置 
            # a = [1, 2, 9, 2, 5, 6, 9]
            # np.argmax(a) 为 2, 9 的索引为 2 
            y_pred[i] = np.argmax( np.bincount(nn_y) )
        return y_pred

4.测试

# 定义一个knn实例
knn = KNN(n_neighbors = 3)
# 训练模型
knn.fit(x_train, y_train)
# 传入测试数据,做预测
y_pred = knn.predict(x_test)

print(y_test.ravel())
print(y_pred.ravel())

# 求出预测准确率
accuracy = accuracy_score(y_test, y_pred)

print("预测准确率: ", accuracy)

在这里插入图片描述
5. 测试不同的 距离函数 和 K 值 的效果哪种最好

# 定义一个knn实例
knn = KNN()
# 训练模型
knn.fit(x_train, y_train)

# 保存结果list
result_list = []

# 针对不同的参数选取,做预测
for p in [1, 2]:
    knn.dist_func = l1_distance if p == 1 else l2_distance
    
    # 考虑不同的k取值,步长为2
    for k in range(1, 10, 2):
        knn.n_neighbors = k
        # 传入测试数据,做预测
        y_pred = knn.predict(x_test)
        # 求出预测准确率
        accuracy = accuracy_score(y_test, y_pred)
        result_list.append([k, 'l1_distance' if p == 1 else 'l2_distance', accuracy])
df = pd.DataFrame(result_list, columns=['k', '距离函数', '预测准确率'])
df

在这里插入图片描述

逻辑斯谛回归(Logistic Regression)模型

和线性回归区别

这个和线性回归有点关系,但是他是分类模型
首先我们看一下线性回归预判肿瘤是否是恶性
在这里插入图片描述
一般是这样的直线,但是线性回归的健壮性不够,如果有噪声数据
在这里插入图片描述
我们随机选取一个噪点,我们看一下这个点的实际值是1,应该是恶性肿瘤,但是我们线性回归模型给出的是0.4,是更接近于良性吗,这肯定不行

此时我们需要用到逻辑斯谛回归,比如下面的这样去进行分类
在这里插入图片描述

sigmoid函数(压缩函数)

sigmoid函数是对数几率函数,sigmoid函数可以将输出压缩到0-1之内

但这样还是没有实现分类的效果,我们一般设置一个门槛,一般是 0.5 ,当大于 0.5 时,就将其结果判断为 1 ,反之判断为 0
在这里插入图片描述

案例一
我们用线性回归拟合出来的值用压缩函数进行压缩,压缩完成后用0.5做一个概率的判定边界,就能把样本分为两类,正样本和负样本
在这里插入图片描述
案例二
在这里插入图片描述

损失函数

如果我们和线性回归一样使用平方损失函数,会发现函数是下列这样,我们很可能只是找到一个局部最小值,而和实际最小值差距很大
在这里插入图片描述
我们想要的是一个凸函数
在这里插入图片描述
我们损失函数有一种是对数损失函数,而对数函数的特性如下
在这里插入图片描述
可以看到使用对数函数作为损失函数很合适,那么就有
在这里插入图片描述
当 y = 1 和 y = 0 时,其实就是
在这里插入图片描述
可以推导出
在这里插入图片描述
我们知道,为了防止过拟合,我们需要加一个正则化项,得到

在这里插入图片描述
这样,我们就得到一个凸函数,其中在上述公式中有
在这里插入图片描述

决策树

决策树是一种简单高效并且具有强解释性的模型,广泛用于数据分析领域,本质上是一个由上而下的由多个判断节点组成的树

核心思想

  1. 决策树是一个 if-then 规则的集合
  2. 由根节点到叶节点的每一条路径,构建一条规则,路径上内部节点的特征对应着规则的条件,叶节点对应规则的结论
  3. 决策树 if-then 规则的集合特性:互斥且完备,也就是每个实例都被一条规则(一条路径)所覆盖,并且只能被一条规则覆盖
    在这里插入图片描述
案列

预测打球问题
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

决策树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

orange大数据技术探索者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值