一般划分两部分
训练集:用于训练,构建模型 (70%,75%,80%)
测试集:在模型检验时使用,用于评估模型是否有效 (30%,25%,20%)
一般划分75%,25%比较好
API
sklearn.model_selection.train_test_split
- sklearn.datasets
加载获取流行数据集
获取数据集返回的类型
load和fetch返回的数据类型datasets.base.Bunch(字典格式)
from sklearn.datasets import load_iris
iris = load_iris()
print("获取特征值",iris.data)
print("获取目标值",iris.target)
print(iris.DESCR)
数据集进行分割
**sklearn.model_selection.train_test_split(*arrays,options)
示例:划分训练集与测试集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=0,test_size=0.25)
sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)
sklearn.datasets.load_boston()
加载并返回波士顿房价数据集
sklearn.datasets_load_diabetes()
加载并返回糖尿病数据集
转换器类(transformer)
fit():输入数据 (类似建立公式f(x),不同的数据调用fit(),会得到不同的公式)
transform(): 进行数据的转换 (类似运算)
fit_transform():输入数据直接转换
sklear机器学习算法的实现-估计器(estimator)
在sklearn中,估计器(estimator)是一个重要的角色,是一类实现了算法的API
1.用于分类的估计器:
2.用于回归的估计器
1.y_predict= predict(x_test)
2.预测的准确率:score(x_test,y_test)
定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
欧式距离公式:
( a 1 + b 1 ) 2 + ( a 2 + b 2 ) 2 + ( a 3 + b 3 ) 2 \sqrt {(a_1+b_1)^2+(a_2+b_2)^2+(a_3+b_3)^2} (a1+b1)2+(a2+b2)2+(a3+b3)2
k-近邻算法需要做标准化处理
sklearn k-近邻算法API
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto)
以鸢尾花数据集示例:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
iris_datasets = load_iris() #实例化数据集
print(iris_datasets.keys())
X_train, X_test, y_train, y_test = train_test_split(iris_datasets['data'], iris_datasets['target'],random_state=0)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train,y_train)
prediction = knn.predict(X_test)
print(prediction)
print("Predicted target name: {}".format(iris_datasets['target_names'][prediction]))
问题:
1.K值取多大? 有什么影响?
K值取很小:容易受异常点影响
K值取很大:容易受K值数量(类别)波动)
2.性能问题
**优点:**简单,易于理解,容易实现,无需估计参数,无需训练
缺点:
懒惰算法,对测试样本分类时的计算量大。内存开销大
必须指定K值,K值选择不当则分类精度不能保证
**使用场景:**小数据场景,几千~几万样本,具体场景具体业务去测试
1.概率基础
所有特征之间是条件独立的
2.朴素贝叶斯介绍
特征独立
公式:
P ( C ∣ W ) = P ( W ∣ C ) P ( C ) P ( W ) P(C|W) = \frac{P(W|C)P(C)}{P(W)} P(C∣W)=P(W)P(W∣C)P(C)
注:W为给定文档的特征值(频数统计,预测文档提供),C为文档类别
公式可以理解为:
P ( C ∣ F 1 , F 2 , . . . ) = P ( F 1 , F 2 , . . . ∣ C ) P ( C ) P ( F 1 , F 2... ) P(C|F1,F2,...) = \frac{P(F1,F2,...|C)P(C)}{P(F1,F2...)} P(C∣F1,F2,...)=P(F1,F2...)P(F1,F2,...∣C)P(C)
其中C可以是不同类别
公式分为三个部分:
P( C ):每个文档类别的概率(某文档类别数/总文档数量)
P(W|C):给定类别下特征(被预测文档中出现的词)的概率
计算方法:P(F1|C) = Ni/N (训练文档中去计算)
Ni为该F1词在C类别所有文档中出现的次数
N为所属类别C下的文档所有词出现的次数和
P(F1,F2,…)预测文档中每个词的概率
示例:
训练集统计结果(指定统计词频):
特征\统计 | 科技(30篇) | 娱乐(60篇) | 汇总(90篇) |
---|---|---|---|
“商场” | 9 | 51 | 60 |
“影院” | 8 | 56 | 64 |
“支付宝” | 20 | 15 | 35 |
“云计算” | 63 | 0 | 63 |
“汇总(求和)” | 100 | 121 | 221 |
现有一篇被预测文档:出现了影院,支付宝,云计算,计算属于科技/娱乐的类别概率?
P(科技|影院,支付宝,云计算)=P(影院,支付宝,云计算|科技)P(科技)
=8/10020/10063/100*30/90
P(娱乐|影院,支付宝,云计算)=P(影院,支付宝,云计算|娱乐)P(娱乐)
=56/12115/1210/121*60/90
=0
问题:从上面的例子我们得到娱乐概率为0,这是不合理的,如果词频列表里面有很多出现次数都为0,很可能计算结果都为零。
解决方法:拉普拉斯平滑系数
P ( F 1 ∣ C ) = N I + α N + α m P(F1|C)= \frac{N_I + α}{N+α_m} P(F1∣C)=N+αmNI+α
α为指定的系数一般为1,m为训练文档中统计出的特征词个数
以上式子变为:
=(56+1)/(121+1) * (15+1)/(121+1)*(0+1)/(121+1)*60/90
API
sklearn.naive_bayes.MultinomiaNB(alpha=1.0)
注:朴素贝叶斯没有超参数,不能通过调参调优,所以对训练集要求比较高。
朴素贝叶斯算法优缺点:
优点:
缺点:
示例:
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
#实例化加载新闻数据,’all’加载全部数据
news = fetch_20newsgroups(subset="all")
#数据分割
x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,random_state=0)
# Tfidf文本特征抽取
tf = TfidfVectorizer()
x_train=tf.fit_transform(x_train)
# print(tf.get_feature_names())
#出问题:MemoryError: Unable to allocate 14.9 GiB for an array with shape (14134, 141276) and data type float64
# print(x_train.toarray())
x_test = tf.transform(x_test)
# 实例化朴素贝叶斯算法
mlt = MultinomialNB(alpha=1.0)
mlt.fit(x_train,y_train)
#进行朴素贝叶斯算法预测
y_prediction = mlt.predict(x_test)
print('预测文章类别为',y_prediction)
print('训练集集准确率为:',mlt.score(x_test,y_test))
print('测试集准确率为:',mlt.score(x_test,y_test))
1.estimator.score()
2.混淆矩阵
在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适合于多分类)
正例 | 反例 | |
---|---|---|
正例 | 真正例TP(true positive) | 伪反利FN(false negative) |
反例 | 伪正例FP | 真反利TN |
评估标准:
精确率(Precision)和召回率(Recall)
精确率: 预测结果为正例样本中真实为正例的比例(查得准)
召回率: 真实为正例的样本中预测结果为正例的比例(查得全,对正样本得区分能力)
准确率就是找得对,召回率就是找得全
其他分类标准:F1-score,反映了模型得稳健性
公式:
F 1 = 2 T P 2 T P + F N + F P = 2 ∗ P r e c i s i o n ∗ R e c a l l P r e c i s i o n + R e c a l l F_1= \frac{2TP}{2TP+FN+FP} = \frac{2*Precision*Recall}{Precision+Recall} F1=2TP+FN+FP2TP=Precision+Recall2∗Precision∗Recall
API
sklearn.metrics.classification_report
sklearn.metrics.classification_report(y_true,y_pred,target_names=None)
接上例 朴素贝叶斯算法 - fetch_20newsgroups数据集 为示例
from sklearn.metrics import classification_report
report=classification_report(y_test,y_prediction,target_names=news.target_names)
print(report)
目的:为了让评估的模型更加准确可信
所有数据分为n等份,每份进行数据验证,最后求平均值得到结果。(常用10折)
作用:调参数
通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的k值),这种叫超参数,但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都是采用交叉验证来进行评估。最后选出最优参数组合建立模型。
K值 | K=3 | K=5 | k=7 |
---|---|---|---|
模型 | 模型1 | 模型2 | 模型3 |
API
sklearn.model_selection.GridSearchCV
sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)
示例:
from sklearn.datasets import load_iris
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
iris = load_iris()
cv = GridSearchCV(KNeighborsClassifier(),param_grid={'n_neighbors':[5,7,10]},cv=2)
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=0,test_size=0.25)
cv.fit(x_train,y_train)
print('在测试集上准确率',cv.score(x_test,y_test))
print('交叉验证最好的结果',cv.best_score_)
print('最好的模型是',cv.best_estimator_)
print('每个超参数每次交叉验证的结果',cv.cv_results_)
认识决策树:
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法。
信息的度量和作用:信息和消除不确定性是相联系的
决策树的划分依据之一:信息增益
特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件熵H(D|A)之差,即公式为:
g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)−H(D∣A)
注:信息增益表示得知特征X的信息而使得类Y的信息的不确定性减少的程度。
常见决策树使用的算法:
ID3
信息增益 最大的准则
C4.5
信息增益比 最大的准则
CART
回归树:平方误差 最小
分类树:基尼系数 最小的准则 在sklearn中可以选择划分的默认原则
API
class sklearn,tree.DecisionTreeClasssifier(criterion=‘gini’,max_depth=None,random_state=None)
示例:泰坦尼克号生存预测数据集
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.feature_extraction import DictVectorizer
train = pd.read_csv(r'C:\Desktop\titanic\train.csv')
test = pd.read_csv(r'C:\Desktop\titanic\test.csv')
y_test = pd.read_csv(r'C:\Desktop\titanic\gender_submission.csv')
print('训练集表头:',train.columns)
print('测试集表头:',test.columns)
x_train = train[['Pclass','Age','Sex']]
y_train = train['Survived']
x_train['Age'].fillna(x_train['Age'].mean(),inplace=True)
x_test = test[['Pclass','Age','Sex']]
x_test['Age'].fillna(x_test['Age'].mean(),inplace=True)
y_test = y_test['Survived']
#进行特征工程(one-hot)
dict =DictVectorizer(sparse=False)
#pd转换字典,x_train.to_dict('records')把每一行转换成字典
x_train=dict.fit_transform(x_train.to_dict('records'))
x_test = dict.transform(x_test.to_dict('records'))
tree = DecisionTreeClassifier()
tree.fit(x_train,y_train)
print(tree.score(x_test,y_test))
1.sklearn.tree.export_graphviz 该函数能够导出DOT格式
tree.export_graphviz(estimator,out_file=‘tree.dot,feature_names=[","])
from sklearn.tree import export_graphviz
print(dict.get_feature_names())
export_graphviz(tree,out_file='tree.dot',feature_names=['Age', 'Pclass', 'Sex=female', 'Sex=male'])
2.工具:(能够将dot文件转换为pdf、pdg)
安装graphviz
Windows下载请参考https://www.cnblogs.com/onemorepoint/p/8310996.html
3.运行命令
先在命令窗口切换到dot文件所在目录再运行命令
$ dot-Tpng tree.dot -o tree.png
图片如下:
决策树的优缺点:
优点:
缺点:
改进:
注:企业重要决策,由于决策树很好地分析能力,在决策过程应用较多。
集成学习方法
集成学习通过建立几个模型组合来解决单一预测问题。它的工作原理是生产多个分类/模型,各自独立地学习和做出预测,这些预测最后结合成单预测,因此由于任何一个单分类的做出预测。
什么是随机森林
定义:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
单个决策树建立:
假设有N个样本,M个特征
1.在N个样本当中选择一个样本,重复N次,样本有可能重复
2.随机在M个特征当中选出m个特征,m<
为什么要随机抽样训练集?
如果不进行随机抽样,每棵树的训练集一样,那么最终训练出的树分类结果也是完全一样的
为什么要又放回抽样?
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。
API
class sklearn.ensemble.RandomForestClassfier(n_estimators=10,criterion=‘gini’,max_depth=None,bootstrap=True,random_state=None)
调参:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
rf = RandomForestClassifier(random_state=0)
param = {'n_estimators':[50,100,150],'max_depth':[5,10,20]}
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_)
随机森林的优缺点:
几乎没有缺点
优点: