24/8/7算法笔记 决策树分类

决策树是一种常用的机器学习算法,用于分类和回归任务。它通过学习简单的决策规则从数据特征中推断出目标值。以下是决策树的一些关键特点:

  1. 树形结构:决策树由一系列的问题组成,每个问题对应一个特征和可能的取值。这些问题按照树状结构组织,从根节点到叶节点,形成决策路径。

  2. 特征选择:在每个节点上,决策树算法会选择一个特征和阈值,将数据集分割成尽可能纯净的子集。这通常基于某种标准,如信息增益、基尼不纯度或均方误差。

  3. 递归分割:决策树通过递归地分割数据集来构建。在每个节点上,算法选择最佳特征进行分割,然后对每个子集重复这个过程,直到满足停止条件。

  4. 停止条件:决策树的构建过程会在满足特定条件时停止,例如:

    • 达到预设的最大深度。
    • 所有数据点都属于同一类别。
    • 子集中的数据点数量小于某个阈值。
    • 没有更多的特征可以用来进一步分割数据。
  5. 分类和回归:决策树可以用于分类任务(预测离散标签)和回归任务(预测连续值)。

  6. 可解释性:决策树模型易于理解和解释,因为它们可以被可视化为一系列的问题和答案。

  7. 过拟合风险:决策树容易过拟合,特别是当树很深或训练数据中的噪声较多时。为了防止过拟合,可以采用剪枝技术,如预剪枝(设置最大深度或最小分割样本数)或后剪枝(构建完整的树然后回溯删除不必要的节点)。

  8. 集成方法:为了提高性能和鲁棒性,可以使用集成方法,如随机森林或梯度提升决策树,这些方法通过结合多个决策树的预测来提高整体性能。

  9. 处理缺失值:决策树算法可以处理具有缺失值的特征,因为它们可以在每个节点上为缺失值选择不同的分支。

  10. 特征重要性:决策树可以评估特征对预测结果的重要性,这有助于特征选择和数据理解。

import numpy as np
from sklearn.tree import DecisionTreeClassifier
加载数据
import pandas as pd
y = np.array(list('NYYYYYNYYN'))
print(y)
X = pd.DataFrame({'日志密度':list('sslmlmmlms'),
                  '好友密度':list('slmmmlsmss'),
                  '真实头像':list('NYYYYNYYYY')})
X

可以看见如果直接使用模型的化会报错

数据转换

#代码只执行一次
X['日志密度'] = X['日志密度'].map({'s': 0, 'm': 1, 'l': 2})
X['好友密度'] = X['好友密度'].map({'s':0,'m':1,'l':2})
X['真实头像'] = X['真实头像'].map({'N':0,'Y':1})
X

建模和预测
model = DecisionTreeClassifier(criterion = 'entropy')
model.fit(X,y)
model.score(X,y)

对上面的决策树进行可视化

from sklearn import tree
import matplotlib.pyplot as plt

plt.rcParams['font.family'] ='FangSong'#字体
plt.figure(figsize=(12,16))            #图像大小
fn = X.columns                         #将DataFrame X 的列名赋值给变量 fn。

_=tree.plot_tree(model,filled=True,feature_names=fn)          
plt.savefig('./决策树.png',dpi = 200)

手动计算决策树到底是如何实现分类的

p1 = (y =='N').mean()
p2 = (y =='Y').mean()
print(p1,p2)

p1 * np.log2(1/p1) +p2*np.log2(1/p2)

按照日志密度进行划分
X['真实用户'] = y
X

x = X['日志密度'].unique()
x.sort()#排序
print(x)
for i in range(len(x)-1):
    split = x[i:i+2].mean()
    #概率分布
    cond = X['日志密度']<=split
    
    #左边概率是多少,右边是多少
    p = cond.value_counts()/cond.size
    indexs = p.index
    entropy = 0
    for index in indexs:
        user = X[cond ==index]['真实用户']#取出了目标值y的数据
        
        p_user = user.value_counts()/user.size
        #每个分支的信息熵
        entropy += (p_user*np.log2(1/p_user)).sum()*p[index]
    print(split,entropy)

#信息增益
0.881 - 0.6897

按照好友密度划分
x = X['好友密度'].unique()
x.sort()#排序
print(x)
for i in range(len(x)-1):
    split = x[i:i+2].mean()
    #概率分布
    cond = X['好友密度']<=split
    
    #左边概率是多少,右边是多少
    p = cond.value_counts()/cond.size
    
    indexs = p.index#True,False
    
    entropy = 0
    for index in indexs:
        user = X[cond ==index]['真实用户']#取出了目标值y的数据
        
        p_user = user.value_counts()/user.size
        #每个分支的信息熵
        entropy += (p_user*np.log2(1/p_user)).sum()*p[index]
    print(split,entropy)

#信息增益
0.881-0.324

按照是否使用真实头像划分
x = X['真实头像'].unique()
x.sort()#排序
print(x)
for i in range(len(x)-1):
    split = x[i:i+2].mean()
    #概率分布
    cond = X['真实头像']<=split
    
    #左边概率是多少,右边是多少
    p = cond.value_counts()/cond.size
    
    indexs = p.index#True,False
    
    entropy = 0
    for index in indexs:
        user = X[cond ==index]['真实用户']#取出了目标值y的数据
        
        p_user = user.value_counts()/user.size
        #每个分支的信息熵
        entropy += (p_user*np.log2(1/p_user)).sum()*p[index]
    print(split,entropy)

#信息增益
0.881-0.849

所以总结下来,看好友密度最能判断一个账户是否是真人

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值