看看例子
import math
-(0.5*math.log2(0.5)+0.5*math.log2(0.5)) # 模棱两可
-(0.9*math.log2(0.9)+0.1*math.log2(0.1))
-(0.999*math.log2(0.999)+0.001*math.log2(0.001)) # 不确定性以及很小了
-(1*math.log2(1))
# 计算这个系统中的信息熵
inof_D =-((3/10)*math.log2(3/10)+(7/10)*math.log2(7/10))
# 求 依据日志密度判断 帐号是否真实 的 信息熵
# s - 3 p=0.3 n y n
# m - 4 p=0.4 y y n y
# l - 3 p=0.3 y y y
info_L_D = -0.3*(math.log2(1))
info_L_D=-0.3*((2/3)*math.log2(2/3)+(1/3)*math.log2(1/3))-0.4*((1/4)*math.log2(1/4)+(3/4)*math.log2(3/4))
inof_D-info_L_D # 日志密度这个特征 带来的 信息增益
# 导入 数据集 和 模型 knn lgc dtree
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression # 虽然名字里有回归 但是是用来分类的
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import DecisionTreeClassifier
dtree = DecisionTreeClassifier() # 创建一个决策树模型
from sklearn.datasets import load_iris
1、使用自带的iris数据集
iris = load_iris()
# max_depth=None 最大深度 其实就是 决策树 决策的次数
dtree = DecisionTreeClassifier(max_depth=6) # 深度太小 容易欠拟合 深度太大 容易过拟合
dtree.fit(data,target)
# 范围
xmin = data[:,0].min() - 0.5
xmax = data[:,0].max() + 0.5
ymin = data[:,1].min() - 0.5
ymax = data[:,1].max() + 0.5
# 取遍范围
x = np.linspace(xmin,xmax,100)
y = np.linspace(ymin,ymax,100)
# 网格化处理x和y 让他们做交叉
xx,yy = np.meshgrid(x,y)
X_test = np.c_[xx.flatten(),yy.flatten()] # 画布上的每一个点
# 使用X_test去预测
y_ = dtree.predict(X_test)
from matplotlib.colors import ListedColormap
cmap1 = ListedColormap(['r','g','b'])
# 绘图
plt.scatter(X_test[:,0],X_test[:,1],c=y_)
plt.scatter(data[:,0],data[:,1],c=target,cmap=cmap1) # 先画背景 后画点
# 处理分类问题
# 有明确的业务逻辑(反映到图上 是 很规整的散点) 这个时候适合用决策树
# knn(容易过拟合)和lgc(容易欠拟合)
# 能不用knn 尽量不用knn 速度太慢 内存消耗太大
朴素贝叶斯
# 例如:
# 现分别有 A、B 两个容器,
# 在容器 A 里分别有 7 个红球和 3 个白球,
# 在容器 B 里有 1 个红球和 9 个白球,
# 现已知从这两个容器里任意抽出了一个球,且是红球,
# 问这个红球是来自容器 A 的概率是多少?
# 假设已经抽出红球为事件 B,选中容器 A 为事件 A,则有:P(B) = 8/20,P(A) = 1/2,P(B|A) = 7/10,按照公式,则有:P(A|B) = (7/10)*(1/2) / (8/20) = 0.875
# 抽出来的球是红球 是 B P(B)= 8 / 20
# 抽出来的球是从A容器中抽出来的 是 A P(A)= 1/2
# 已经确定了 求是从A容器中取出来的 此时 红球的概率 P(B|A)
# 其实就是从A容器中取出红球的概率 P(B|A) = 7/10
# 则 问 已经知道这个球是红球 这个红球是从容器A中取出来的 的 概率 P(A|B) = P(B|A)*P(A)/P(B)
# P(A|B) = P(B|A)*P(A)/P(B)
(7/10)*(1/2)/(8/20)
# 一座别墅在过去的 20 年里一共发生过 2 次被盗,
# 别墅的主人有一条狗,狗平均每周晚上叫 3 次,
# 在盗贼入侵时狗叫的概率被估计为 0.9,
# 问题是:在狗叫的时候发生入侵的概率是多少?
# 我们假设 A 事件为狗在晚上叫,B 为盗贼入侵,则以天为单位统计,P(A) = 3/7,P(B) = 2/(20*365) = 2/7300,P(A|B) = 0.9,按照公式很容易得出结果:P(B|A) = 0.9*(2/7300) / (3/7) = 0.00058
# A 事件为狗在晚上叫 P(A) = 3/7
# B 为盗贼入侵 P(B) = 2 / (20*365)
# P(A|B) = 0.9
# 狗叫了 发生 盗贼 入侵 的 概率 P(B|A) = P(A|B)*P(B)/P(A)
(9/10)*(2/(20*365))/(3/7)
二、3种贝叶斯模型
1、高斯分布朴素贝叶斯¶
高斯分布就是正态分布
【用途】用于一般分类问题(两种类型的分布差异明显时适合使用)
2、多项式分布朴素贝叶斯
【用途】适用于文本数据(特征表示的是次数,例如某个词语的出现次数)
3、伯努利分布朴素贝叶斯
【用途】适用于伯努利分布,也适用于文本数据(此时特征表示的是是否出现,例如某个词语的出现为1,不出现为0)
绝大多数情况下表现不如多项式分布,但有的时候伯努利分布表现得要比多项式分布要好,尤其是对于小数量级的文本数据
垃圾邮件分类
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB,MultinomialNB,BernoulliNB
ham=[]
spam=[]
for i in range(1,26):
path = './email/ham/%d.txt'%(i)
data = open(path,encoding='gbk',errors='ignore').read()
ham.append([data,'ham'])
for i in range(1,26):
path = './email/spam/%d.txt'%(i)
data = open(path,encoding='gbk',errors='ignore').read()
spam.append([data,'sham'])
ham_data = DataFrame(ham)
spam_data = DataFrame(spam)
data = pd.concat([ham_data,spam_data])
X_train,X_test,y_train,y_test = train_test_split(data[0],data[1],test_size=0.4)
tf = TfidfVectorizer()
tf.fit(X_train,y_train)
tf_data = tf.transform(X_train)
mnb = MultinomialNB()
bnb = BernoulliNB()
tf_data_test = tf.transform(X_test)
mnb.fit(tf_data,y_train)
bnb.fit(tf_data,y_train)
bnb.score(tf_data_test,y_test)
网友评论