本次实验模型的比较
模型 | f1_score值 |
---|---|
逻辑回归 | 0.692462311558 |
支持向量机 | 0.695477386935 |
lightgbm | 0.575879396985 |
KNN | 0.530653266332 |
KNN+网格搜索 | 0.556783919598 |
决策树 | 0.262311557789 |
贝叶斯 | 0.483417085427 |
1.介绍
通过前面的学习学会了逻辑回归,线性回归,lightgbm,kNN,最后再介绍一下决策树,和网格搜索,和贝叶斯。
2.决策树
2.1 决策树的定义
树想必大家都会比较熟悉,是由节点和边两种元素组成的结构。理解树,就需要理解几个关键词:根节点、父节点、子节点和叶子节点。
父节点和子节点是相对的,说白了子节点由父节点根据某一规则分裂而来,然后子节点作为新的父亲节点继续分裂,直至不能分裂为止。而根节点是没有父节点的节点,即初始分裂节点,叶子节点是没有子节点的节点,如下图所示
2. 2 决策树如何做决策
从一个分类例子说起:
银行希望能够通过一个人的信息(包括职业、年龄、收入、学历)去判断他是否有贷款的意向,从而更有针对性地完成工作。下表是银行现在能够掌握的信息,我们的目标是通过对下面的数据进行分析建立一个预测用户贷款一下的模型。
上边中有4个客户的属性,如何综合利用这些属性去判断用户的贷款意向?决策树的做法是每次选择一个属性进行判断,如果不能得出结论,继续选择其他属性进行判断,直到能够“肯定地”判断出用户的类型或者是上述属性都已经使用完毕。比如说我们要判断一个客户的贷款意向,我们可以先根据客户的职业进行判断,如果不能得出结论,再根据年龄作判断,这样以此类推,直到可以得出结论为止。然后做决策又涉及到根据什么做决策是最快最优的,通常特征选择的准则是信息增益或信息增益比(信息增益率)。本文就不详细讲解了,参考链接。
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
fp = open('data_w_tfidf.pkl', 'rb')
x_train,y_train=pickle.load(fp)
x_train,x_test,y_train,y_test=train_test_split(x_train,y_train,test_size=0.3, random_state=100)
# 3. 决策树
estimator=DecisionTreeClassifier(criterion="entropy")
estimator.fit(x_train,y_train)
y_pred = estimator.predict(x_test)
# print(y_pred.shape)
print("f值",f1_score(y_test,y_pred,average='micro'))
3.网格搜索
网格搜索法是指定参数值的一种穷举搜索方法,通过将估计函数的参数通过交叉验证的方法进行优化来得到最优的学习算法。
即,将各个参数可能的取值进行排列组合,列出所有可能的组合结果生成“网格”。然后将各组合用于SVM训练,并使用交叉验证对表现进行评估。在拟合函数尝试了所有的参数组合后,返回一个合适的分类器,自动调整至最佳参数组合,可以通过clf.best_params_获得参数值,本文利用KNN做例子,详情参考:https://blog.youkuaiyun.com/xiachong27/article/details/82154825
KNN
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
fp = open('data_w_tfidf.pkl', 'rb')
x_train,y_train=pickle.load(fp)
x_train,x_test,y_train,y_test=train_test_split(x_train,y_train,test_size=0.3, random_state=100)
estimator=KNeighborsClassifier(n_neighbors=4)
estimator.fit(x_train,y_train)
y_pred = estimator.predict(x_test)
print("f值",f1_score(y_test,y_pred,average='micro'))
KNN+网格搜索
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
fp = open('data_w_tfidf.pkl', 'rb')
x_train,y_train=pickle.load(fp)
x_train,x_test,y_train,y_test=train_test_split(x_train,y_train,test_size=0.3, random_state=100)
param_dict={"n_neighbors":[1,3,5,7,9,11]}
estimator=KNeighborsClassifier()
estimator=GridSearchCV(estimator,param_grid=param_dict,cv=10)
estimator.fit(x_train,y_train)
y_pred = estimator.predict(x_test)
print("f值",f1_score(y_test,y_pred,average='micro'))
4.贝叶斯
4.1朴素贝叶斯算法
朴素贝叶斯算法的数学基础都是围绕贝叶斯定理展开的,因此这一类算法都被称为朴素贝叶斯算法.
朴素贝叶斯的分类原理是通过对象的先验概率,利用贝叶斯公式计算出后验概率.即对象属于某一类的概率.
选择具有后验概率最大的类作为该对象所属的类.同时朴素–‘特征为独同分布’,
同时因为先验概率需要我们先假设一个事件分布的概率分布方式(三种),因此也就有了我们在sklearn中对应的三种朴素贝叶斯算法
高斯朴素贝叶斯分类器(默认条件概率分布概率符合高斯分布)
多项式朴素贝叶斯分类器(条件概率符合多项式分布)
伯努利朴素贝叶斯分类器(条件概率符合二项分布)
尽管其假设过于简单,但是在很多实际情况下,朴素贝叶斯工作得很好,特别是文档分类和垃圾邮件过滤。
这些工作都要求一个小的训练集来估计必需参数。
同时相比于其他更复杂的方法,朴素贝叶斯学习器和分类器非常快。
分类条件分布的解耦意味着可以独立单独地把每个特征视为一维分布来估计。这样反过来有助于缓解维度灾难带来的问题。
最后总结其特点有以下几个
属性可以离散可以连续
数学基础扎实,分类效率稳定
对噪音数据与缺失数据不太敏感
属性如果不相关,分类效果很好;如果相关,则不低于决策树
假设简单,但是在很多实际情况下表现很好
速度较快,一定程度上缓解了维度灾难
4.2 代码实现
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
fp = open('data_w_tfidf.pkl', 'rb')
x_train,y_train=pickle.load(fp)
x_train,x_test,y_train,y_test=train_test_split(x_train,y_train,test_size=0.3, random_state=100)
estimator=MultinomialNB()
estimator.fit(x_train,y_train)
y_pred = estimator.predict(x_test)
print("f值",f1_score(y_test,y_pred,average='micro'))