1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 机器学习系列文章——算法的实现(knn 朴素贝叶斯 决策树 模型评估)

机器学习系列文章——算法的实现(knn 朴素贝叶斯 决策树 模型评估)

时间:2018-11-06 19:15:05

相关推荐

机器学习系列文章——算法的实现(knn 朴素贝叶斯 决策树 模型评估)

一、机器学习算法分类:

机器学习算法可分为两大类,即分类与回归。其中分类是针对离散型数据,比如判定一直动物是猫是狗,判断一个人的信用等级;而回归问题为针对连续型数据,如预测淘宝店铺销量,预测明天气温等。不同的问题对应不同的算法,其总结如下:

二、算法的实现

(一)数据集划分

在机器学习模型中,我们不可能将所有数据都用来训练,这样模型的效果得不到验证。所以我们会将数据划分为训练集和测试集,训练集和测试集划分的比例由自己制定,通常是按照训练集:测试集 = 3:1的比例,即testsize=0.25。 其中,训练集是用来构建模型,测试数据用来检验模型是否有效。

数据集划分API:sklearn.model_selection.train_test_split

(二)skearn自带数据集获取

sklearn中自带了供我们学习参考的数据集,其API如下:

import sklearn

sklearn.datasets.load_(),主要是获取小规模数据集,数据包含在datasets里。

sklearn.datasets.fetch_(data_home=None),主要是需要从网络上下载的大规模数据集,其中data_home为其保存数据的地址。

上面两种获取的数据都是datasets.base.Bunch(字典格式),

from sklearn.datasets import load_irisli=load_iris()print("加载的数据集类型为:\n",type(li))

返回的数据集的键包含以下内容:

下面来看看iris的数据详情:

#此处代码接上文代码print("iris的描述为:\n",li.DESCR)print("iris的特征数据为:\n",li.data)print("iris的目标数据为:\n",li.target)print("iris的特征名为:\n",li.feature_names)print("iris的目标名为:\n",li.target_names)

li.DESCR:此方法详细描述了数据集里含有的内容,可以看出一共有四个特征类型,150个数据,后面还有对每个特征的统计分析。

li.li.data:为四个特征值的具体数据,返回值为数组类型
li.target:为目标值的具体数据
估计器的工作流程:
首先将数据集划分为训练集、测试集

三、具体算法

(一)K近邻算法

k近邻算法是分类算法中较为简单的应用,其主要思想是计算目标值和已知点的距离,取距离最近的点为目标的分类。

比如要判断上图蓝色点的位置,则可依据和其他人的距离远近来判断。可以取最近的一个人,或两个人来确定。

其API为:

sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm=‘auto’)

n_neighbors:int,可选(默认= 5),k_neighbors查询默认使用的邻居数

algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算法:‘ball_tree’将会使用 BallTree,‘kd_tree’将使用 KDTree。‘auto’将尝试根据传递给fit方法的值来决定最合适的算法。 (不同实现方式影响效率)

该算法实践:

# 导入load_iris数据集from sklearn.datasets import load_iris# 实例化数据集li = load_iris()# print("iris的描述为:\n",li.DESCR)# print("iris的特征数据为:\n",type(li.data))# print("iris的目标数据为:\n",li.target)# print("iris的特征名为:\n",li.feature_names)# print("iris的目标名为:\n",li.target_names)# 分割数据集# 1.导入数据分割apifrom sklearn.model_selection import train_test_split# 2.传入特征值、目标值和划分比例.x_train, x_test, y_train, y_test分别为训练集特征值 测试集特征值 训练集目标值,测试集目标值x_train, x_test, y_train, y_test = train_test_split(li.data, li.target, test_size=0.25)print("训练集特征值:",x_train)print("训练集目标值:",y_train)print("测试集特征值:",x_test)print("测试集目标值:",y_test)# 用knn算法进行学习# 导入相关模块from sklearn.neighbors import KNeighborsClassifier# 实例化knn=KNeighborsClassifier(n_neighbors=5)# 拟合 传入训练集的特征值和目标值knn.fit(x_train,y_train)# 调用predict方法得出测试集的预测结果y_predict=knn.predict(x_test)print("测试集的预测结果为:",y_predict)# 调用score方法得出模型预测分数print("分数为:",knn.score(x_test,y_test))

可以看出,模拟拟合结果较好,可以通过调整n_neighbors的参数来进一步改进预测分数。

改进

在之前的帖子里,我们介绍过特征工程的处理,主要是将特征值进行标准化 归一化处理,来让数据更加适合学习计算。

# 特征工程std = StandardScaler()x_train = std.fit_transform(x_train)x_test = std.transform(x_test)

此处注意,fit_transform(),是先fit,再transform,我们对训练集的特征值进行了先fit 再transform处理,再对训练集特征值处理时,不能再fit,应该直接transform,否则会导致训练集和特征值标准化处理的方式不一致,从而影响拟合结果。最终改进后score为:

k近邻算法的优缺点:

(二)朴素贝叶斯算法

条件概率公式为:P(C|W)=P(CW)/P(W),即在事件W发生的前提下,事件C发生的概率。当事件C W独立时,也可写作:P(C|W)=P©P(W)/P(W).

贝叶斯公式为:P(C|W)=P(W|C)P©/P(W),由条件概率公式作简单的替换即可得出。

朴素贝叶斯算法的思想是将w看为给定文档的特征值(频数统计,预测文档提供),c看为文档类别。求解在一定频次的条件下,该文档为c类别的概率是多少。

代码实现:

实现贝叶斯算法api:

sklearn.naive_bayes.MultinomialNB(alpha = 1.0)

其中alpha为拉普拉斯平滑系数,主要是为了避免出现概率为0的情况。

# 导入相关模块from sklearn.datasets import fetch_20newsgroups#导入数据集from sklearn.model_selection import train_test_split#数据集划分apifrom sklearn.naive_bayes import MultinomialNB#朴素贝叶斯api# 实例化数据news = fetch_20newsgroups(subset='all')# print(news.target)#查看数据集目标值# print(len(news.data))#查看数据集特征值# print(news.DESCR)#查看数据集描述# 进行数据分割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# 实例化tf = TfidfVectorizer()# 以训练集当中词的列表进行每篇文章重要性统计x_train = tf.fit_transform(x_train)# 查看词频矩阵print(tf.get_feature_names())# 此处不可再用fit_transform(),以保证测试集和训练集处理的一致性x_test = tf.transform(x_test)# 用朴素贝叶斯算法进行预测# 实例化mlt = MultinomialNB(alpha=1.0)print(x_train.toarray())mlt.fit(x_train,y_train)y_predict=mlt.predict(x_test)print("预测文章类别为:",y_predict)print("准确率为:",mlt.score(x_test,y_test))# 查看召回率和精确率from sklearn.metrics import classification_reportprint("精确率和召回率为:",classification_report(y_test,y_predict,target_names=news.target_names))

特征处理相关文章参见:

/weixin_4473/article/details/119571812

朴素贝叶斯分类的优缺点

(三)决策树算法

决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法 。

决策树的基本思想是通过一个个的条件判断,来确定最后的分类。比如一个女性的家长给她介绍对象,此时要对对象分出“去见面”和“不去见面”两类。分类的条件判断可以有“年龄”、“收入”、“样貌”等,按照这些条件的重要性先后进行判断,最后分类。

那么,怎么确定条件的先后判断顺序即重要性呢。此处有个重要依据:信息增益。如果该条件的信息增益较大,则可以将其放在前面判断。信息熵计算公式如下:【了解】

常见决策树使用的算法:

决策树api使用:

此处max_depth也为一个超参数,可通过调整此参数来优化模型。

案例代码:

def decision():"""决策树对泰坦尼克号进行预测生死:return: None"""# 获取数据titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")# 处理数据,找出特征值和目标值x = titan[['pclass', 'age', 'sex']]y = titan['survived']print(x)# 缺失值处理x['age'].fillna(x['age'].mean(), inplace=True)# 分割数据集到训练集合测试集x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)# 进行处理(特征工程)特征-》类别-》one_hot编码dict = DictVectorizer(sparse=False)x_train = dict.fit_transform(x_train.to_dict(orient="records"))print(dict.get_feature_names())x_test = dict.transform(x_test.to_dict(orient="records"))# 随机森林进行预测 (超参数调优)rf = RandomForestClassifier()param = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}# 网格搜索与交叉验证gc = GridSearchCV(rf, param_grid=param, cv=2)gc.fit(x_train, y_train)print("准确率:", gc.score(x_test, y_test))print("查看选择的参数模型:", gc.best_params_)return Nonedecision()

三、分类模型的评估

分类评估模型api:

四、模型的选择与调优

在建立好模型后,经常有拟合分数过低的情况,这时候就需要对参数进行调整和优化。如果一个一个试参数就势必会造成很大的内存负担和效率问题。在模型选择和调优中,通常有两个方法:交叉验证和网格搜索。

(一)交叉验证

交叉验证:将拿到的数据,分为训练和验证集。以下图为例:将数据分成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉验证。其往往和网格搜索搭配一起使用。

(二)超参数搜索——网格搜索

通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。

api:sklearn.model_selection.GridSearchCV

此处应该注意,param传入的应该是字典格式

代码实现:

from sklearn.neighbors import KNeighborsClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.model_selection import GridSearchCVx_train, x_test, y_train, y_test = train_test_split(li.data, li.target, test_size=0.25)# 实例化knn = KNeighborsClassifier()# 特征工程std = StandardScaler()x_train = std.fit_transform(x_train)x_test = std.transform(x_test)# 指定相关参数,注意:必须为字典格式,且字典的键必须与估计器的模型相对应。params = {"n_neighbors": [3, 5, 7,9,11,15]}# 实例化gv = GridSearchCV(knn, param_grid=params, cv=5)# 进行模型拟合gv.fit(x_train, y_train)# 预测准确率print("在测试集上准确率为:", gv.score(x_test, y_test))print("在交叉验证当中最好的结果:", gv.best_score_)print("最好的估计模型为:", gv.best_estimator_)print("每次交叉验证的结果:", gv.cv_results_)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。