人工智能_4_k近邻_贝叶斯_模型评估
机器学习常用算法
k近邻算法
求出未知点 与周围最近的 k个点的距离
查看这k个点中大多数是哪一类
根号((x已知-x未知)^2+(y已知-y未知)^2) 即平面间2点距离公式
收异常点影响较大,因此需要做标准化处理
API:sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm="auto")
algorithm:{"auto","ball_tree","kd_tree","brute"}
效率不同
ball_tree:会使用BallTree
kd_tree:会使用KdTree
auto:尝试根据传递的fit方法的值决定最适合的算法
n_neighbors: 邻居数,默认为5
处理:
时间特征:需要转为年,月,日,时,分,秒 ,当做几个新的特征处理,并不是全部要加入,要根据结果选择加入
目标值:可以去掉某些目标值
from sklearn.neighbors import KNeighborsClassifier
def knnCls():
"""
预测鸢尾花的种类
:return:
"""
# 读取数据
from sklearn.datasets import load_iris
iris = load_iris()
print(iris.feature_names)
print(iris.data[0:5,:])
print(iris.data) # 处理数据
# 1,缩小数据 对于csv中的数据可使用 data.query("id>8 & money <2000") 等过滤掉一些数据
# 2,时间处理
# time_value = pd.to_datetime(data中的时间列,unit="s") unit 表示时间最小的单位
# time_value格式为 1970-01-01 00:00:00 注意不能单独获取年月日
# time_value=pd.DatatimeIndex(time_value) 此时转换为字典格式的时间
# 增加特征,例如年相同,就不能当做特征
# data['day'] = time_value.day,weekday,hour等不建议使用 此方式
# 建议使用data.loc["day"] = xxx
# pandas使用data.drop(["time"],axis=1) 删除原来的时间戳,
# 数组使用np.delete(data,[1,2,3等列],axis=1) 删除原来的时间戳
# 3,目标值处理
# 目标值过多,单有的目标值数量太少,可以忽略
# 分组求和,本例中 可表示为 把数量少于n个的种类删除(虽然本类中目标值只有3个,其实不用删除,只为演示效果)
# group = data.groupby("目标值列名").count()
# 此时返回结果 列数不变,目标值列名列为所有的目标值,其他列不再是值,而是分组后该组的个数
# tf = group[group['非目标值列列名']>n].reset_index()
# data = data[data[目标列列名].isin(tf.目标列列名)]
# 取出目标值 y =data["目标列"]
# 取出目标值 x =data.drop(["目标列"],axis=1)
# x_train,y_train,x_test,y_test数据分割 train_test_spilt
# 特征工程(标准化)
# x_train 进行fit_transform
# 注意 也需要对 x_test进行标准化,注意使用 transform即可, 即 使用 训练集的参数进行标准化
# 标准化对数据最后结果影响很大
# 算法处理
knn = KNeighborsClassifier(n_neighbors=5)
# fit ,predict,score
knn.fit(x_train,y_train)
# 得出结果
y_predict = knn.predict(x_test) # 得出预测目标值
# 得出准确率
knn.score(x_test,y_test) # 也可以使用y_predict与y_test 得出
return None
问题1:k的取值问题,很大,很小?
很大:易受异常点影响
很小:容易受k值(数量)波动
性能问题:每一个未知数来都需要与全部数据进行计算
很费时间
调参:n_neighbors 的合适值 优点:易于理解,易实现,无需参数(算法里边的参数)估计,无需训练\
缺点:计算慢,耗内存,必须有k 朴素(条件独立)贝叶斯算法 (需要学习概率相关内容)
概率:
条件概率:P(A1,A2|B) = P(A1|B)*P(A2|B) A1,A2 不能相互影响 应该是条件独立
联合概率 P(A,B) = P(A)*P(B)
例:常用与对于文章的分类
每个文章会计算属于每个分类的概率,比较数据那个的概率较大,就是该分类
P(科技|文章1) 文档
P(科技|词1,词2.....) 文档:词1,词2.... (多个条件下 x的概率)
朴素贝叶斯-贝叶斯公式
P(A|B)=P(B|A)P(A)/P(B)
=====================================
个人体会:例 有两个箱子 A:两黑,两白球 B两黑球,1白球
随机从两个盒子中拿出一个球,是白球, 求是从A中拿出的概率
P(A|白) = (P(白|A)P(A))/P(白) = 0.5*0.5/(1/2*1/2+1/2*1/3)=7/12
P(B|白) = (P(白|B)P(B))/P(白) = 1/3*0.5/(1/2*1/2+1/2*2/3)=5/12
贝叶斯推导:https://www.cnblogs.com/lliuye/p/9178090.html
=====================================
求在包含这些词的情况下是科技类的概率=在科技分类下这些词(这个文档)出现的概率*科技类的概率/在所有文档中,这些词的概率
P(C|W)=(P(W|C)P(C))/P(W)
W为给定文档的特征值(频数统计,预测文档提供),C为文档类别
可理解为:P(C|F1,F2.....)=(P(F1,F2..|C)P(C))/P(F1,F2,....)
P(C):每个文档类别的概率(某类文档数/文档总数)
P(W|C):给定列别下 特征(词)的概率
P(F1|C) = Ni/N (表示该次出现在科技文章中的概率) F1,F2.....的概率乘积 表示 科技类文章中这些词都出现的概率
Ni为F1词在c类所有文档中出现的次数,(科技类文章中改词的次数)
N为c类文档下所有词的总和 .(科技类文章中 所有的词 和)
有些情况下得到文章属于某类的概率为0,不合理
解决办法:拉普拉斯平滑系数 P(F1|C) = (Ni+a)/N+am
a:指定系数一般为1,m为训练文档中出现的特征词的个数
算法API sklearn.native_bayes.MultinomiaNB
sklearn.native_bayes.MultinomiaNB(alpha=1.0) 拉普拉斯平滑系数,不属于超参数
例:新闻分类
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
def naviebayes():
"""
朴素贝叶斯进行文章分类
:return:
"""
# 加载数据,进行分割
news = fetch_20newsgroups(subset="all")
x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25)
# 生成文章特征词
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.classification import classification_report
tf = TfidfVectorizer() #以训练集中词的列表进行 每篇文章重要性统计
x_train = tf.fit_transform(x_train)
# print(tf.get_feature_names()) # 全部文章中所有的词
x_test = tf.transform(x_test)
# 朴素贝叶斯进行评估
from sklearn.naive_bayes import MultinomialNB
mlt = MultinomialNB(alpha=1.0)
#print(x_train) # .toarray 可转化为二维数组
"""
(0, 122986) 0.1189432263044612 # 第一篇文章中 feature_names下标122986的这个词 出现的频率
(0, 139798) 0.25782353561208343
(0, 117722) 0.12774899257629055
"""
mlt.fit(x_train,y_train)
y_predict = mlt.predict(x_test)
print(classification_report(y_test,y_predict,target_names=news.target_names))
# 算出准确率,由于文章词的数量确定,数据的正确性,因此 准确率不易提高
# print(mlt.score(x_test,y_test))
优点:
发源于古典数学,有稳定的分类效率
速度快,效率高
对数据缺失不敏感,常用于文本分类
缺点:
前提是一个词的出现与另一个无关,当词之间出现关联时,效果不好
if __name__ == "__main__":
# knnCls()
naviebayes()
pass
模型评估(不仅靠准确率,还有召回率)
准确率:estimator.score() 最常见是预测结果的准确率,即百分比
混淆矩阵
准确率 35%,但召回率 75%
""" 预测结果
正例(猫) 假例(不是猫)
真实结果 20正例(猫) 真正例(15) 伪反例(5)
真实结果 80假例(不是猫) 伪正例(60) 真反例(20)
"""
精确率:预测为正例的样本中,真正例的比例
召回率:真实值正例中,预测为正例的比例 15/20 越高越好
其他分类标准F1-SCORE 反映了模型的稳健性
F1 = 2*精确率*召回率/(精确率+召回率)
API sklearn.metrics.classification_reportly(y_true,y_pred,target_names=None)
y_true:真实目标值
y_pred:估计器预测目标值
terget_names:目标类别名称
return:每个类(目标值)的精确率与召回率
模型选择与调优
交叉验证:让别评估模型更加准确
训练集分为n份:训练集(n-1)份+验证集1份 得出一个准确率 模型一
再次训练集分为n份:训练集(n-1)份+验证集1份(就是修改验证集,可能此时第一份为验证集) 得出一个准确率 模型二
..... 依次进行 得出n个准确率 求平均 即可以作为可信一点的模型结果
分为n份就称为n折交叉验证
网格搜索(超参数搜索):调参数(k近邻)
与交叉验证组合k = 3,5,7 10折交叉验证
k=3 时的平均,k=5的平均... 比较即可得出比较可信的k值
当有两个找参数时:两两组合
API sklearn.model_selection.GridSearchCV(estimator,param_grid=none,cv=None)
estimator:估计器(knn) 此时估计器中不用再写超参数
param_grid:估计参数 {"n_neighbors":[1,2,3,4,5]}
cv:几折交叉验证
不用 knn.fit predict
此时返回的实例
fit(x_train,y_train):输入训练数据
score(x_test,y_test):准确率
best_score_:在交叉验证中最好的结果
best_estimator_:在交叉验证中最好的参数模型
cv_results_:每次交叉验证后验证集集准确率和训练集准确率(验证集平均值)
from sklearn.model_selection import GridSearchCV
gc = GridSearchCV(KNeighborsClassifier(),param_grid={"n_neighbors":[1,2,3,4,5]})
gc.fit(x_train,y_train)
机器学习常用算法
k近邻算法
求出未知点 与周围最近的 k个点的距离
查看这k个点中大多数是哪一类
根号((x已知-x未知)^2+(y已知-y未知)^2) 即平面间2点距离公式
收异常点影响较大,因此需要做标准化处理
API:sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm="auto")
algorithm:{"auto","ball_tree","kd_tree","brute"}
效率不同
ball_tree:会使用BallTree
kd_tree:会使用KdTree
auto:尝试根据传递的fit方法的值决定最适合的算法
n_neighbors: 邻居数,默认为5
处理:
时间特征:需要转为年,月,日,时,分,秒 ,当做几个新的特征处理,并不是全部要加入,要根据结果选择加入
目标值:可以去掉某些目标值
from sklearn.neighbors import KNeighborsClassifier
def knnCls():
"""
预测鸢尾花的种类
:return:
"""
# 读取数据
from sklearn.datasets import load_iris
iris = load_iris()
print(iris.feature_names)
print(iris.data[0:5,:])
print(iris.data) # 处理数据
# 1,缩小数据 对于csv中的数据可使用 data.query("id>8 & money <2000") 等过滤掉一些数据
# 2,时间处理
# time_value = pd.to_datetime(data中的时间列,unit="s") unit 表示时间最小的单位
# time_value格式为 1970-01-01 00:00:00 注意不能单独获取年月日
# time_value=pd.DatatimeIndex(time_value) 此时转换为字典格式的时间
# 增加特征,例如年相同,就不能当做特征
# data['day'] = time_value.day,weekday,hour等不建议使用 此方式
# 建议使用data.loc["day"] = xxx
# pandas使用data.drop(["time"],axis=1) 删除原来的时间戳,
# 数组使用np.delete(data,[1,2,3等列],axis=1) 删除原来的时间戳
# 3,目标值处理
# 目标值过多,单有的目标值数量太少,可以忽略
# 分组求和,本例中 可表示为 把数量少于n个的种类删除(虽然本类中目标值只有3个,其实不用删除,只为演示效果)
# group = data.groupby("目标值列名").count()
# 此时返回结果 列数不变,目标值列名列为所有的目标值,其他列不再是值,而是分组后该组的个数
# tf = group[group['非目标值列列名']>n].reset_index()
# data = data[data[目标列列名].isin(tf.目标列列名)]
# 取出目标值 y =data["目标列"]
# 取出目标值 x =data.drop(["目标列"],axis=1)
# x_train,y_train,x_test,y_test数据分割 train_test_spilt
# 特征工程(标准化)
# x_train 进行fit_transform
# 注意 也需要对 x_test进行标准化,注意使用 transform即可, 即 使用 训练集的参数进行标准化
# 标准化对数据最后结果影响很大
# 算法处理
knn = KNeighborsClassifier(n_neighbors=5)
# fit ,predict,score
knn.fit(x_train,y_train)
# 得出结果
y_predict = knn.predict(x_test) # 得出预测目标值
# 得出准确率
knn.score(x_test,y_test) # 也可以使用y_predict与y_test 得出
return None
问题1:k的取值问题,很大,很小?
很大:易受异常点影响
很小:容易受k值(数量)波动
性能问题:每一个未知数来都需要与全部数据进行计算
很费时间
调参:n_neighbors 的合适值 优点:易于理解,易实现,无需参数(算法里边的参数)估计,无需训练\
缺点:计算慢,耗内存,必须有k 朴素(条件独立)贝叶斯算法 (需要学习概率相关内容)
概率:
条件概率:P(A1,A2|B) = P(A1|B)*P(A2|B) A1,A2 不能相互影响 应该是条件独立
联合概率 P(A,B) = P(A)*P(B)
例:常用与对于文章的分类
每个文章会计算属于每个分类的概率,比较数据那个的概率较大,就是该分类
P(科技|文章1) 文档
P(科技|词1,词2.....) 文档:词1,词2.... (多个条件下 x的概率)
朴素贝叶斯-贝叶斯公式
=====================================
个人体会:例 有两个箱子 A:两黑,两白球 B两黑球,1白球
随机从两个盒子中拿出一个球,是白球, 求是从A中拿出的概率
P(A|白) = (P(白|A)P(A))/P(白) = 0.5*0.5/(1/2*1/2+1/2*1/3)=7/12
P(B|白) = (P(白|B)P(B))/P(白) = 1/3*0.5/(1/2*1/2+1/2*2/3)=5/12
=====================================
求在包含这些词的情况下是科技类的概率=在科技分类下这些词(这个文档)出现的概率*科技类的概率/在所有文档中,这些词的概率
P(C|W)=(P(W|C)P(C))/P(W)
W为给定文档的特征值(频数统计,预测文档提供),C为文档类别
可理解为:P(C|F1,F2.....)=(P(F1,F2..|C)P(C))/P(F1,F2,....)
P(C):每个文档类别的概率(某类文档数/文档总数)
P(W|C):给定列别下 特征(词)的概率
P(F1|C) = Ni/N (表示该次出现在科技文章中的概率) F1,F2.....的概率乘积 表示 科技类文章中这些词都出现的概率
Ni为F1词在c类所有文档中出现的次数,(科技类文章中改词的次数)
N为c类文档下所有词的总和 .(科技类文章中 所有的词 和)
有些情况下得到文章属于某类的概率为0,不合理
解决办法:拉普拉斯平滑系数 P(F1|C) = (Ni+a)/N+am
a:指定系数一般为1,m为训练文档中出现的特征词的个数
算法API sklearn.native_bayes.MultinomiaNB
sklearn.native_bayes.MultinomiaNB(alpha=1.0) 拉普拉斯平滑系数,不属于超参数
例:新闻分类
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
def naviebayes():
"""
朴素贝叶斯进行文章分类
:return:
"""
# 加载数据,进行分割
news = fetch_20newsgroups(subset="all")
x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25)
# 生成文章特征词
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.classification import classification_report
tf = TfidfVectorizer() #以训练集中词的列表进行 每篇文章重要性统计
x_train = tf.fit_transform(x_train)
# print(tf.get_feature_names()) # 全部文章中所有的词
x_test = tf.transform(x_test)
# 朴素贝叶斯进行评估
from sklearn.naive_bayes import MultinomialNB
mlt = MultinomialNB(alpha=1.0)
#print(x_train) # .toarray 可转化为二维数组
"""
(0, 122986) 0.1189432263044612 # 第一篇文章中 feature_names下标122986的这个词 出现的频率
(0, 139798) 0.25782353561208343
(0, 117722) 0.12774899257629055
"""
mlt.fit(x_train,y_train)
y_predict = mlt.predict(x_test)
print(classification_report(y_test,y_predict,target_names=news.target_names))
# 算出准确率,由于文章词的数量确定,数据的正确性,因此 准确率不易提高
# print(mlt.score(x_test,y_test))
优点:
发源于古典数学,有稳定的分类效率
速度快,效率高
对数据缺失不敏感,常用于文本分类
缺点:
前提是一个词的出现与另一个无关,当词之间出现关联时,效果不好
if __name__ == "__main__":
# knnCls()
naviebayes()
pass
模型评估(不仅靠准确率,还有召回率)
准确率:estimator.score() 最常见是预测结果的准确率,即百分比
混淆矩阵
准确率 35%,但召回率 75%
""" 预测结果
正例(猫) 假例(不是猫)
真实结果 20正例(猫) 真正例(15) 伪反例(5)
真实结果 80假例(不是猫) 伪正例(60) 真反例(20)
"""
精确率:预测为正例的样本中,真正例的比例
召回率:真实值正例中,预测为正例的比例 15/20 越高越好
其他分类标准F1-SCORE 反映了模型的稳健性
F1 = 2*精确率*召回率/(精确率+召回率)
API sklearn.metrics.classification_reportly(y_true,y_pred,target_names=None)
y_true:真实目标值
y_pred:估计器预测目标值
terget_names:目标类别名称
return:每个类(目标值)的精确率与召回率
模型选择与调优
交叉验证:让别评估模型更加准确
训练集分为n份:训练集(n-1)份+验证集1份 得出一个准确率 模型一
再次训练集分为n份:训练集(n-1)份+验证集1份(就是修改验证集,可能此时第一份为验证集) 得出一个准确率 模型二
..... 依次进行 得出n个准确率 求平均 即可以作为可信一点的模型结果
分为n份就称为n折交叉验证
网格搜索(超参数搜索):调参数(k近邻)
与交叉验证组合k = 3,5,7 10折交叉验证
k=3 时的平均,k=5的平均... 比较即可得出比较可信的k值
当有两个找参数时:两两组合
API sklearn.model_selection.GridSearchCV(estimator,param_grid=none,cv=None)
estimator:估计器(knn) 此时估计器中不用再写超参数
param_grid:估计参数 {"n_neighbors":[1,2,3,4,5]}
cv:几折交叉验证
不用 knn.fit predict
此时返回的实例
fit(x_train,y_train):输入训练数据
score(x_test,y_test):准确率
best_score_:在交叉验证中最好的结果
best_estimator_:在交叉验证中最好的参数模型
cv_results_:每次交叉验证后验证集集准确率和训练集准确率(验证集平均值)
from sklearn.model_selection import GridSearchCV
gc = GridSearchCV(KNeighborsClassifier(),param_grid={"n_neighbors":[1,2,3,4,5]})
gc.fit(x_train,y_train)
人工智能_4_k近邻_贝叶斯_模型评估的更多相关文章
- 吴裕雄 python 机器学习——伯努利贝叶斯BernoulliNB模型
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,naive_bayes from skl ...
- PGM:有向图模型:贝叶斯网络
http://blog.csdn.net/pipisorry/article/details/52489270 为什么用贝叶斯网络 联合分布的显式表示 Note: n个变量的联合分布,每个x对应两个值 ...
- PGM:贝叶斯网表示之朴素贝叶斯模型naive Bayes
http://blog.csdn.net/pipisorry/article/details/52469064 独立性质的利用 条件参数化和条件独立性假设被结合在一起,目的是对高维概率分布产生非常紧凑 ...
- 基于贝叶斯网(Bayes Netword)图模型的应用实践初探
1. 贝叶斯网理论部分 笔者在另一篇文章中对贝叶斯网的理论部分进行了总结,在本文中,我们重点关注其在具体场景里的应用. 2. 从概率预测问题说起 0x1:条件概率预测模型之困 我们知道,朴素贝叶斯分类 ...
- Python机器学习笔记:朴素贝叶斯算法
朴素贝叶斯是经典的机器学习算法之一,也是为数不多的基于概率论的分类算法.对于大多数的分类算法,在所有的机器学习分类算法中,朴素贝叶斯和其他绝大多数的分类算法都不同.比如决策树,KNN,逻辑回归,支持向 ...
- 贝叶斯网引论 by 张连文
贝叶斯网(Bayesian networks)是一种描述随机变量之间关系的语言,构造贝叶斯网是为了概率推理,理论上概率推理基于联合概率分布就行了,但是联合概率分布(基于表)的复杂度会呈指数增长,贝叶斯 ...
- 【转载】 自动化机器学习(AutoML)之自动贝叶斯调参
原文地址: https://blog.csdn.net/linxid/article/details/81189154 ---------------------------------------- ...
- NLP系列(5)_从朴素贝叶斯到N-gram语言模型
作者: 龙心尘 && 寒小阳 时间:2016年2月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/50646528 ...
- NLP系列(2)_用朴素贝叶斯进行文本分类(上)
作者:龙心尘 && 寒小阳 时间:2016年1月. 出处: http://blog.csdn.net/longxinchen_ml/article/details/50597149 h ...
随机推荐
- bs4笔记
1.网页输出乱码的解决办法 r= requests.get('https://www.baidu.com/') r.encoding = 'gbk2312' #有可能 gbk.utf-8 soup ...
- Java NIO学习笔记八 DatagramChannel
Java NIO DatagramChannel Java NIO DatagramChannel是可以发送和接收UDP数据包的通道.由于UDP是一种无连接网络协议,因此您不能默认读取和写入Datag ...
- JAVA 基础编程练习题35 【程序 35 最大最小交换】
35 [程序 35 最大最小交换] 题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组. package cskaoyan; public class cskaoyan35 { ...
- 按下F2编辑dxDBTreeView的节点
在TdxDBTreeView控件的OnKeyDown事件中写入if Key = VK_F2 thenbegin if DBTreeMain.DBSelected = nil then Exit ...
- 深入理解 iptables 和 netfilter 架构
[译] 深入理解 iptables 和 netfilter 架构 Published at 2019-02-18 | Last Update 译者序 本文翻译自 2015 年的一篇英文博客 A Dee ...
- 陷门函数Trapdoor Function
陷门函数:正向计算是很容易的,但若要有效的执行反向计算则必须要知道一些secret/knowledge/trapdoor(知识?),也称为伪随机置换,可用于构造公钥密码系统. 若 f 为陷门函数,则 ...
- 给数据库授权,否则程序、navicat无法连接数据库的,每创建一个数据库都要给数据库授权
给数据库授权,否则程序.navicat无法连接test1数据库的 mysql> grant all privileges on test1.* TO 'root'@'%' identified ...
- Jenkins创建镜像后无法推送到harbor的问题
https://blog.csdn.net/mydeman/article/details/79042848 1.先切换到root账号,用root登录harbor,就可以push $ sudo pas ...
- Unit Testing, Integration Testing and Functional Testing
转载自:https://codeutopia.net/blog/2015/04/11/what-are-unit-testing-integration-testing-and-functional- ...
- Centos7服务器环境搭建
1.Apache安装 yum install httpd systemctl start httpd.service #启动 systemctl stop httpd.service#停止 syste ...