数据挖掘python实现,ID3、Bayes、Kmeans、Apriori、Knn(应付作业版)厂工

ID3

在决策树分类中,假设S是训练样本集合,|S|是训练样本数, 样本划分为n个不同的类C1,C2,….Cn,这些类的大小分别标记为 |C1|,|C2|,…..,|Cn|。则任意样本S属于类Ci的概率为: 

p(Si) = |Ci|/|S|

Entropy(S,A)=∑(|Sv|/|S|)* Entropy(Sv)

∑是属性A的所有可能的值v, Sv是属性A有v值的S子集 |Sv|是Sv 中元素的个数;

|S|是S中元素的个数。 ID3算法-信息量计算 

Gain(S,A)是属性A在集合S上的信息增益 

Gain(S,A)= Entropy(S) - Entropy(S,A)

Gain(S,A)越大,说明选择测试属性对分类提供的信息越多

判断青年,低收入,不是学生,信誉优的决策。

import numpy as np

computer = np.array([[1, 1, 1, 1, 1],
                     [1, 1, 1, 2, 1],
                     [2, 1, 1, 1, 2],
                     [3, 2, 1, 1, 2],
                     [3, 3, 2, 1, 2],
                     [3, 3, 2, 2, 1],
                     [2, 3, 2, 2, 2],
                     [1, 2, 1, 1, 1],
                     [1, 3, 2, 1, 2],
                     [3, 2, 2, 1, 2],
                     [1, 2, 2, 2, 2],
                     [2, 2, 1, 2, 2],
                     [2, 1, 2, 1, 2],
                     [3, 2, 1, 2, 1]])
# 准备做决策的例子,测试数据:
x0 = np.array([1, 3, 1, 2])


# 算熵
def entropy(p):
    if p.__contains__(0):  # 排除log2(0)的情况
        p = np.setdiff1d(p,0.0) # 若p中有元素为0,则删除0
        if p.size == 0: # 若删除后,p中概率为空,则返回0
            return 0
    return np.sum(-p * np.log2(p))


# 取出数据集的x,y
n, m = computer.shape
m = m - 1
x = computer[:, 0:m]    # 各属性条件
y = computer[:, m]  # 决策属性的情况

while np.size(np.unique(y)) != 1:  # 当决策属性只有一个时,结束决策
    n, m = x.shape
    y_max = np.max(y)#决策属性的种类
    y_stat = np.arange(y_max)   # 用于存储统计决策属性的数目
    p = np.zeros(y_max)
    for j in range(0, y_max):
        y_stat[j] = np.size(np.where(y == j + 1))  # 统计决策属性的数目
        # print(y_stat[j])
        # 算概率
        p[j] = y_stat[j] / n
    # print(p)

    I = entropy(p=p)  # 决策属性的熵
    G = np.zeros(m)  # 存放各属性的信息增益

    # 计算每个属性的熵和信息增益
    for k in range(0, m):
        x_max = np.max(x[:, k])
        x_stat = np.zeros((x_max, y_max))  # 存放各属性的条件的人数
        E = 0  # 平均信息期望
        for i in range(0, x_max):
            for j in range(0, y_max):
                # 统计各条件买与不买的人数
                x_stat[i, j] = np.size(np.where((x[:, k] == i + 1) & (y == j + 1)))
                # print(x_stat)
            # 概率
            p = np.zeros(y_max, dtype=np.float64)  # 存放各属性的条件的概率
            # 各属性条件的人数
            sum = np.sum(x_stat[i])
            # print(sum)
            for a in range(0, y_max):
                if sum == 0:    # 若决策树的一支中不包含某个属性的某个条件,则将该条件的概率设置为0
                    p[a] = 0
                else:
                    p[a] = x_stat[i][a] / sum
            E = E + entropy(p) * sum / n    # 平均信息期望
            # print(p)
        G[k] = I - E  # 用决策属性的熵-各属性的条件的平均信息期望
    # 获取信息增益最大的属性
    index = np.argmax(G)
    print(x[:, index])
    print(x0[index])
    if any(x[:, index] == x0[index]):   # 如果数据集不包含测试数据的数据时,则按概率对测试数据进行决策
        # 取出测试数据与信息增益最大的相同属性,再将其同一列从数据集中切出,形成新的数据集
        a = np.where(x[:, index] == x0[index])[0]
        x = np.hstack([x[a][:, 0:index], x[a][:, index + 1:m]])
        # 决策属性进行更新
        y = y[a]
        # 测试数据进行更新,将已经判断的属性删除
        x0 = np.hstack([x0[0:index], x0[index + 1:m]])
    else:
        y = np.argmax(np.bincount(y))   #选取出现次数最多,即最后概率最大的作为决策
        break

print('预测结果为:', np.unique(y))

Bayes

朴素贝叶斯分类的工作过程如下:

 (1)每个数据样本用一个 n维特征向量X= { x1,x 2,……,x n }表示, 分别描述对 n个属性A1,A 2,……,A n样本的 n个度量。

 (2)假定有 m个类 C1,C2,…,Cm,给定一个未知的数据样本 X (即没有类标号),分类器将预测 X属于具有最高后验概率(条件 X下)的类。

         也就是说,朴素贝叶斯分类将未知的样本分配给类 Ci (1≤ i ≤ m ) 当且仅当 P ( Ci |X)> P ( Cj |X),对任意的j=1,2,…,m,j ≠ i。

        这样,最大化 P ( Ci |X)。其 P ( Ci |X)最大的类 Ci称为最大后验假定。 根据贝叶斯定理

(3)由于P(X)对于所有类为常数,只需要P(X|Ci)*P(Ci)最大即可。

         如果Ci类的先验概率未知,则通常假定这些类是等概率的,即 P(C1)=P(C2)=…=P(Cm),因此问题就转换为对P(X|Ci)的最大化。 P(X|Ci)常被称为给定Ci时数据X的似然度,而使P(X|Ci)最大的 假设Ci称为最大似然假设。

        否则,需要最大化P(X|Ci)*P(Ci)。注意,类的先验概率可以用 P(Ci)=si/s计算,其中si是类Ci中的训练样本数,而s是训练样本 总数

(4)给定具有许多属性的数据集,计算P(X|Ci)的开销可能非常大。为降 低计算P(X|Ci)的开销,可以做类条件独立的朴素假定。

         给定样本的类标号,假定属性值相互条件独立,一个属性值在给 定类上的影响独立于其他属性的值,即在属性间,不存在依赖关 系。

 (5)对未知样本X分类,也就是对每个类Ci,计算P(X|Ci)*P(Ci)。样本X 被指派到类Ci,当且仅当P(Ci|X)> P(Cj|X),1≤j≤m,j≠i。  换言之,X被指派到其P(X|Ci)*P(Ci)最大的类

import numpy as np

weather = np.array([[1, 1, 1, 1, 1],
                    [1, 1, 1, 2, 1],
                    [2, 1, 1, 1, 2],
                    [3, 2, 1, 1, 2],
                    [3, 3, 2, 1, 2],
                    [3, 3, 2, 2, 1],
                    [2, 3, 2, 2, 2],
                    [1, 2, 1, 1, 1],
                    [1, 3, 2, 1, 2],
                    [3, 2, 2, 1, 2],
                    [1, 2, 2, 2, 2],
                    [2, 2, 1, 2, 2],
                    [2, 1, 2, 1, 2],
                    [3, 2, 1, 2, 1]])

x0 = [1, 3, 1, 2]
n, m = weather.shape
m = m -1
x = weather[:, 0:m]
y = weather[:, m]
y_max = np.max(y)

p = np.zeros(y_max)     # 决策属性的概率
pE= np.zeros((m,y_max))     # 条件属性的统计结果
k = np.zeros(y_max)     # 例子的决策属性的概率
for j in range(0, y_max):
    p[j] = np.size(np.where(y == j+1))/np.size(y)
    for i in range(0, m):
        pE[i,j] = np.size(np.where((y == j + 1) & (x[:, i] == x0[i]))) / np.size(np.where(y == j+1))
k = np.prod(pE,axis=0)
which = np.argmax(p*k)+1
print('决策结果',which)

 Knn

k值的选择 : – 如果 k 太小, 则对噪声点敏感 – 如果 k 太大, 邻域可能包含很 多其他类的点

定标问题(规范化) – 属性可能需要规范化,防止距 离度量被具有很大值域的属性 所左右

import numpy as np

X = np.array([[1.6, 1],
              [2, 2],
              [1.9, 3],
              [1.88, 3],
              [1.7, 1],
              [1.85, 3],
              [1.6, 1],
              [1.7, 1],
              [2.2, 2],
              [2.1, 2],
              [1.8, 3],
              [1.95, 3],
              [1.9, 3],
              [1.8, 3],
              [1.75, 3]])
x0 = np.array([1.6])    # 带决策的数据
k = 5
n, m = X.shape
# 取出前k个数据
x = X[:k]

for i in range(k,n):
    # 计算k个数据与决策数据的距离
    distance = np.sum((x[:, 0:m - 1] - x0) ** 2, axis=1)
    # 计算下一个数据与决策数据的距离
    a = np.sum(X[i,0:m-1]-x0)**2
    # 如果下一个数据的距离比k数据的距离小,则替换
    if a < np.max(distance):
        x[np.argmax(distance)] = X[i]

# 取出k个数据的决策属性,根据决策属性的最多的那个进行决策
x = x[:,m-1].astype('int32')
a = np.argmax(np.bincount(x))
print('决策结果',a)

Apriori

分为两个步骤:  第一步通过迭代,检索出事务数据库中的所有 频繁项集,即支持度不低于用户设定的阈值的 项集;  第二步利用频繁项集构造出满足用户最小信任 度的规则。

import itertools

import numpy as np

D = np.array([[1, 1, 0, 0, 1],
             [0, 1, 0, 1, 0],
             [0, 1, 1, 0, 0],
             [1, 1, 0, 1, 0],
             [1, 0, 1, 0, 0],
             [0, 1, 1, 0, 0],
             [1, 0, 1, 0, 0],
             [1, 1, 1, 0, 1],
             [1, 1, 1, 0, 0]])
min_sup = 0.2
min_conf = 0.6
m,n = D.shape
# print(n,m)
# 候选1项集
C1 = np.eye(n)

# 生成候选项集Ck(k>=2)    从Lk-1--->Ck,并计算置信度
def getCk(Lk):
    n_Lk,m= Lk.shape
    Ck = np.empty(shape=[0,m],dtype=np.int32)
    for i in range(0,n_Lk):
        if i+1 < n_Lk:
            for j in range(i+1,n_Lk):
                a = Lk[i,:]|Lk[j,:]
                Ck = np.append(Ck,[a],axis=0)
    return Ck


#根据最小支持度计算,对候选项集Dk进行计数,生成频繁项集Lk
def getLk(Ek):
    n_Ek,m_Ek = Ek.shape
    Lk = np.empty(shape=[0,m_Ek])
    for j in range(0, n_Ek):
        sup = computer_sup(Ek[j,:],D)
        if sup >= min_sup:
            Lk = np.append(Lk,[Ek[j,:]],axis=0)
    Lk = np.array(list(set([tuple(t) for t in Lk])))    #去重
    Lk = Lk.astype(np.int32)
    return Lk

# 计算支持度 S:候选集的一行数据  D:原始数据集
def computer_sup(S,D):
    n,m = D.shape
    sup = 0
    for i in range(n):
        if all(D[i, :] >= S):
            sup = sup + 1
    sup = sup / n
    return sup

# 计算置信度  # -1--->1  L:频繁项集  D:原始数据集
def computer_conf(L,D):
    rules = []
    for i in range(L.shape[0]):
        data = L[i, :]
        data2 = np.where(data == 1)[0]  # 1的索引位置集合
        length = len(data2)
        for j in range(1, length):  # 从1开始,排除掉频繁1项集的计算
            for k in itertools.combinations(data2, j):   # 迭代器,实现所有数据的排列组合
                a = np.array(k)
                b = np.array(data)
                b[a] = -1
                rules.append(b)
    rules = np.array(rules)
    Rq = np.empty(shape=[0,n])
    for i in rules:
        L1 = np.abs(i)
        L2 = (L1 - i) / 2
        if computer_sup(L1, D) / computer_sup(L2, D) >= min_conf:
            Rq = np.append(Rq, [i], axis=0)
    return Rq

rq = np.empty(shape=[0,n])
while(True):# 当频繁项集的长度为1时,结束决策
    # 1.根据最小支持度计算,对候选项集Dk进行计数,生成频繁项集Lk
    L1 = getLk(C1)
    # print(L1)

    # 2.由Lk生成候选项集Dk
    C1 = getCk(L1)
    # 对频繁项集计算置信度
    rq = np.append(rq,computer_conf(L1, D),axis=0)
    if C1.size == n or 0:
        break
print(rq)

Kmeans

 1.选择k个点作为初始的质心  2.repeat  3. 将每个点指派到最近的质心,形成k个簇  4. 重新计算每个簇的质心  5.until 质心不发生变化

import numpy as np
import pandas as pd

X = np.array([[0, 1, 2, 4, 5, 5, 6, 1, 1, 1],
              [0, 1, 1, 3, 3, 4, 5, 4, 5, 6]], dtype=float).transpose()
n, m = X.shape
# print(n, m)
k = 3
# 随机抽取三个质心
np.random.seed(0)   # 设置随机数种子
rand_ch = np.random.choice(X.shape[0], k, replace=False)
rand = X[rand_ch]
# print(rand)

# 计算每个点到质心的距离
def count_dis(rand_ch, x):
    return np.sqrt(np.sum((rand_ch - x) ** 2))

# 计算新的质心
def cluster(dis):
    min_dis = np.argmin(dis,axis=1)
    new_clu = pd.DataFrame(X).groupby(min_dis).mean()   # 利用pandas库分类,并计算均值
    return new_clu.values

while(True):
    # 计算每个点与各个类之间的距离
    dis = np.empty(shape=(1,k)) #存放全部点的距离
    for i in range(n):
        temp = np.empty(k)
        # 存放每个点与三个类的距离
        for j in range(k):
            temp[j]=count_dis(rand[j],X[i])
            # print(temp[j])
        dis = np.append(dis,[temp],axis=0)
    dis = np.delete(dis,0,axis=0)
    print(dis)
    # 计算每个类新的中心
    new_clu = cluster(dis)
    # 比较每个新的中心与原来的是否相同,若相同则结束归类
    if (new_clu - rand == 0).all():
        # 打印分类情况
        for i in range(n):
            for j in range(k):
                temp[j]=count_dis(rand[j],X[i])
            print(X[i],'属于',np.argmin(temp))
        break
    else:
        rand = new_clu


你可能感兴趣的:(python,数据挖掘,Id3,数据挖掘,kmeans,python,pycharm)