Phishing website analyse(一)——决策树方法分析

Phishing website analyse(一)

决策树方法分析

  • 数据集有1万多条记录,30个特征属性,1个结果属性,属性意义可以在下载数据的网页找到描述文件
    在这里插入图片描述

代码实现

生成决策树模型
import numpy as np
import pandas as pd
origin_data = pd.read_csv('phishing.csv')
data = origin_data.drop('id',axis=1)
# label = origin_data.Result
train = data[0:int(data.shape[0]*0.8)]
test = data[int(data.shape[0]*0.8):]

train_set_x_orig = np.array(train[train.columns[0:-1]]) # your train set features
train_set_y_orig = np.array(train.Result) # your train set labels

test_set_x_orig = np.array(test[test.columns[0:-1]]) # your test set features
test_set_y_orig = np.array(test.Result) # your test set labels

classes = np.array([-1,1]) # the list of classes

train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))

#计算信息熵
def calEnt(dataSet):
    n = dataSet.shape[0] #数据集总行数
    iset = dataSet.iloc[:,-1].value_counts() #标签的所有类别
    p = iset/n #每一类标签所占比
    ent = (-p*np.log2(p)).sum() #计算信息熵
    return ent

#选择最优的列进行切分
def bestSplit(dataSet):
    baseEnt = calEnt(dataSet) #计算原始熵
    bestGain = 0 #初始化信息增益
    axis = -1 #初始化最佳切分列,标签列
    for i in range(1,dataSet.shape[1]-1): #对特征的每一列进行循环
        levels= dataSet.iloc[:,i].value_counts().index #提取出当前列的所有取值
        ents = 0 #初始化子节点的信息熵
        for j in levels: #对当前列的每一个取值进行循环
            childSet = dataSet[dataSet.iloc[:,i]==j] #某一个子节点的dataframe
            ent = calEnt(childSet) #计算某一个子节点的信息熵
            ents += (childSet.shape[0]/dataSet.shape[0])*ent #计算当前列的信息熵
            #print(f'第{i}列的信息熵为{ents}')
        infoGain = baseEnt-ents #计算当前列的信息增益
        #print(f'第{i}列的信息增益为{infoGain}')
        if (infoGain > bestGain):
            bestGain = infoGain #选择最大信息增益
            axis = i #最大信息增益所在列的索引
    return axis

#按axis切分,并删除已用过的列
def mySplit(dataSet,axis,value):
    col = dataSet.columns[axis]
    redataSet = dataSet.loc[dataSet[col]==value,:].drop(col,axis=1)#用过就删除掉这个用过的列,保证下次选择信息增益最大的列
    return redataSet


#递归创建决策树
def createTree(dataSet):
    featlist = list(dataSet.columns)  # 提取出数据集所有的列
    classlist = dataSet.iloc[:, -1].value_counts()  # 获取最后一列类标签
    # 判断最多标签数目是否等于数据集行数,或者数据集是否只有一列
    if dataSet.shape[1] == 1:
        return classlist.index[0]  # 如果是,返回类标签
    axis = bestSplit(dataSet)  # 确定出当前最佳切分列的索引
    bestfeat = featlist[axis]  # 获取该索引对应的特征
    myTree = {bestfeat: {}}  # 采用字典嵌套的方式存储树信息
    del featlist[axis]  # 删除当前特征
    valuelist = set(dataSet.iloc[:, axis])  # 提取最佳切分列所有属性值
    for value in valuelist:  # 对每一个属性值递归建树
        print(value)
        myTree[bestfeat][value] = createTree(mySplit(dataSet, axis, value))

    return myTree


myTree = createTree(train)

#树的存储
np.save('./myTree.npy',myTree)
准确率
import numpy as np
import pandas as pd
#树的读取
read_myTree = np.load('myTree.npy',allow_pickle=True).item()
read_myTree

origin_data = pd.read_csv('phishing.csv')

data = origin_data.drop('id',axis=1)

train = data[0:int(data.shape[0]*0.8)]
test = data[int(data.shape[0]*0.8):]

classLabel = -1
def classify(inputTree, labels, testVec):
    global classLabel
    firstStr = next(iter(inputTree))  # 获取决策树第一个节点
    secondDict = inputTree[firstStr]  # 下一个字典
    featIndex = labels.index(firstStr)  # 第一个节点所在列的索引

    for key in secondDict.keys():
        if testVec[featIndex] == key:
            if type(secondDict[key]) == dict:
                classLabel = classify(secondDict[key], labels, testVec)
            else:
                classLabel = secondDict[key]
    return classLabel

def acc_classify(inputTree,train,test):
    labels = list(train.columns) #数据集所有的列名称
    result = []
    for i in range(test.shape[0]): #对测试集中每一条数据进行循环
        testVec = test.iloc[i] #测试集中的一个实例
        classLabel = classify(inputTree,labels,testVec) #预测该实例的分类
        result.append(classLabel) #将分类结果追加到result列表中
    test['predict']=result #将预测结果追加到测试集最后一列
    acc = (test.iloc[:,-1]==test.iloc[:,-2]).mean() #计算准确率
    print(f'模型预测准确率为{acc}')
    return test

#用决策树进行分类并计算有预测准确率
acc_classify(read_myTree,train,test)
  • 结果:
    在这里插入图片描述
  • 得到的pdf图为:

    没有经济基础不要随便在自己电脑上跑,消耗电脑资源,浪费时间;如果有服务器的,可以试一试
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值