在决策树分类中,假设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))
朴素贝叶斯分类的工作过程如下:
(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)
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)
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