目录
1 sklearn转换器和估计器
1.1 转换器
1.2 估计器
2 K-近邻算法(KNN)
2.1 案例1——鸢尾花种类预测
3 模型选择与调优
3.1 什么是交叉验证(cross validation)
3.2 超参数搜索-网格搜索(Grid Search)
3.2.1 模型选择与调优
3.3 案例2——预测facebook签到位置
4 朴素贝叶斯算法
4.1 拉普拉斯平滑系数
5 决策树
5.1 信息熵、信息增益
5.2 案例3——用决策树对鸢尾花进行分类
5.3 案例4——泰坦尼克号乘客生存预测
6 随机森林
本篇博文将对sklearn的转换器和估计器流程、sklearn的分类、回归数据集、K-近邻算法的距离公式、K-近邻算法的超参数K值以及取值问题、K-近邻算法的优缺点、应用KNeighborsClassifier实现分类、了解分类算法的评估标准准确率、说明朴素贝叶斯算法的原理、说明朴素贝叶斯算法的优缺点、应用MultinomialNB实现文本分类、应用模型选择与调优、说明决策树算法的原理、说明决策树算法的优缺点、应用DecisionTreeClassifier实现分类、说明随机森林算法的原理、说明随机森林算法的优缺点以及应用RandomForestClassifier实现分类 。
特征工程步骤如下:
我们把特征工程的接口称之为转换器,其中转换器调用有这么几种形式:
我们用代码演示一下这几种形式的区别:
from sklearn.preprocessing import StandardScaler
a = [[7,8,9], [10, 11, 12]]
std1 = StandardScaler()
print("fit:\n",std1.fit(a))
print("transform:\n",std1.transform(a))
print("fit_transform:\n",std1.fit_transform(a))
运行结果如下:
fit:
StandardScaler()
transform:
[[-1. -1. -1.]
[ 1. 1. 1.]]
fit_transform:
[[-1. -1. -1.]
[ 1. 1. 1.]]
从中可以看出,fit_transform的作用相当于transform加上fit。
在sklearn中,估计器(estimator)是一个重要的角色,是一类实现了算法的API:
工作流程:
估计器:
1 实例化一个estimator
2 estimator.fit(x_train,y_train)计算--->调用完毕,模型生成
3 模型评估:
1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
y_test == y_predict
2)计算准确率
accuracy = estimator.score(x_test,y_test)
定义:
如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
那么如何确定谁是邻居呢?
距离公式:
欧式距离、曼哈顿距离、明科夫斯基距离等。欧式距离计算公式如下:
假设我们有现在几部电影:
其中?号电影不知道类别,如何去预测?我们可以利用K近邻算法的思想。
如果取的最近的电影数量不一样?会是什么结果?
k=1 爱情片(取距离最近的1个样本,该样本为爱情片,所以为爱情片)。
k=2 爱情片(取距离最近的2个样本,该样本为爱情片,所以为爱情片)。
...
k=6 无法确定(取距离最近的6个样本,该样本中3个爱情片,3个动作片,最终无法确定)。
k=1 容易受到异常点的影响。
k取值过大,受到样本不均衡的影响。
K-近邻算法API:
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
用knn算法对鸢尾花进行分类:
1、获取数据
2、数据集划分
3、特征工程:标准化
4、KNN算法预估器
5、模型评估:
1)直接比对真实值和预测值
2)计算准确率
代码如下:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
def knn_iris():
"""
用knn算法对鸢尾花进行分类
:return:
"""
# 1、获取数据
iris = load_iris()
# 2、数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data,iris.target,random_state=6)
# 3、特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test) #训练集fit,测试集不fit,因为实际我们不知道要分类的未知数据,所以标准化的平均值和标准差只能用测试集的
# 4、KNN算法预估器
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)
# 5、模型评估
# 1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 2)计算准确率
score = estimator.score(x_test, y_test)
print("准确率:\n",score)
return None
if __name__ == "__main__":
#代码:用knn算法对鸢尾花进行分类
knn_iris()
运行结果如下:
y_predict:
[0 2 0 0 2 1 1 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1
2]
直接比对真实值和预测值:
[ True True True True True True False True True True True True
True True True False True True True True True True True True
True True True True True True True True True True False True
True True]
准确率:
0.9210526315789473
总结:
k值取很小:容易受到异常点的影响
k值取很大:受到样本均衡的问题
距离计算上面,时间复杂度高
交叉验证:将拿到的训练数据,分为训练和验证集。以下图为例:将数据分成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉验证。
为什么需要交叉验证?--->为了让被评估的模型更加准确可信。
那么这个只是对于参数得出更好的结果,那么怎么选择或者调优参数呢?
通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。
sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
下面,我们用knn算法对鸢尾花进行分类,并添加网格搜索和交叉验证。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
def knn_iris_gscv():
"""
用knn算法对鸢尾花进行分类,添加网格搜索和交叉验证
:return:
"""
# 1、获取数据
iris = load_iris()
# 2、数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data,iris.target,random_state=6)
# 3、特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test) #训练集fit,测试集不fit,因为实际我们不知道要分类的未知数据,所以标准化的平均值和标准差只能用测试集的
# 4、KNN算法预估器
estimator = KNeighborsClassifier()
#加入网格搜索与交叉验证
#参数准备
param_dict = {"n_neighbors":[1,3,5,7,9,11]}
estimator = GridSearchCV(estimator,param_grid=param_dict,cv=10)
estimator.fit(x_train,y_train)
# 5、模型评估
# 1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 2)计算准确率
score = estimator.score(x_test, y_test)
print("准确率:\n",score)
# 最佳参数:best_params_
print("最佳参数:\n", estimator.best_params_)
# 最佳结果:best_score_
print("最佳结果:\n", estimator.best_score_)
# 最佳预估器:best_estimator_
print("最佳预估器:\n", estimator.best_estimator_)
# 交叉验证结果:cv_results_
print("交叉验证结果:\n", estimator.cv_results_)
return None
if __name__ == "__main__":
#代码:用knn算法对鸢尾花进行分类,添加网格搜索和交叉验证
knn_iris_gscv()
运行结果如下:
y_predict:
[0 2 0 0 2 1 2 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1
2]
直接比对真实值和预测值:
[ True True True True True True True True True True True True
True True True False True True True True True True True True
True True True True True True True True True True False True
True True]
准确率:
0.9473684210526315
最佳参数:
{'n_neighbors': 11}
最佳结果:
0.9734848484848484
最佳预估器:
KNeighborsClassifier(n_neighbors=11)
交叉验证结果:
{'mean_fit_time': array([0.00086534, 0.00059962, 0.00075936, 0.00080037, 0.00040061,
0.00049934]), 'std_fit_time': array([0.00133643, 0.00048959, 0.00050251, 0.00040019, 0.00049067,
0.00049935]), 'mean_score_time': array([0.00142319, 0.00120194, 0.0012007 , 0.0014998 , 0.0012012 ,
0.00159819]), 'std_score_time': array([0.00062137, 0.00039834, 0.00039953, 0.00050006, 0.00039969,
0.00066429]), 'param_n_neighbors': masked_array(data=[1, 3, 5, 7, 9, 11],
mask=[False, False, False, False, False, False],
fill_value='?',
dtype=object), 'params': [{'n_neighbors': 1}, {'n_neighbors': 3}, {'n_neighbors': 5}, {'n_neighbors': 7}, {'n_neighbors': 9}, {'n_neighbors': 11}], 'split0_test_score': array([1., 1., 1., 1., 1., 1.]), 'split1_test_score': array([0.91666667, 0.91666667, 1. , 0.91666667, 0.91666667,
0.91666667]), 'split2_test_score': array([1., 1., 1., 1., 1., 1.]), 'split3_test_score': array([1. , 1. , 1. , 1. , 0.90909091,
1. ]), 'split4_test_score': array([1., 1., 1., 1., 1., 1.]), 'split5_test_score': array([0.90909091, 0.90909091, 1. , 1. , 1. ,
1. ]), 'split6_test_score': array([1., 1., 1., 1., 1., 1.]), 'split7_test_score': array([0.90909091, 0.90909091, 0.90909091, 0.90909091, 1. ,
1. ]), 'split8_test_score': array([1., 1., 1., 1., 1., 1.]), 'split9_test_score': array([0.90909091, 0.81818182, 0.81818182, 0.81818182, 0.81818182,
0.81818182]), 'mean_test_score': array([0.96439394, 0.95530303, 0.97272727, 0.96439394, 0.96439394,
0.97348485]), 'std_test_score': array([0.04365767, 0.0604591 , 0.05821022, 0.05965639, 0.05965639,
0.05742104]), 'rank_test_score': array([5, 6, 2, 3, 3, 1])}
数据介绍:将根据用户的位置,准确性和时间戳预测用户正在查看的业务。
train.csv,test.csv
row_id:登记事件的ID
xy:坐标
准确性:定位准确性
时间:时间戳
place_id:业务的ID,这是您预测的目标
数据来源:官网:grid_knn | Kaggle
分析:
对于数据做一些基本处理(这里所做的一些处理不一定达到很好的效果,我们只是简单尝试,有些特征我们可以根据一些特征选择的方式去做处理)
1、缩小数据集范围 DataFrame.query()
4、删除没用的日期数据 DataFrame.drop(可以选择保留)
5、将签到位置少于n个用户的删除
place_count = data.groupby('place_id').count()
tf = place_count[place_count.row_id > 3].reset_index()
data = data[data['place_id'].isin(tf.place_id)]
分割数据集
标准化处理
k-近邻预测
首先,用knn算法:
df.query():
pandas41 query-字符串表达式查询:大数据函数( tcy)_tcy23456的博客-CSDN博客_pandas query 字符串
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
def knncls():
"""
K近邻算法预测入住位置类别
:return:
"""
# 一、处理数据以及特征工程
# 1、读取收,缩小数据的范围
data = pd.read_csv("F:/BaiduNetdiskDownload/mechine learning/Machine_Learning/resources/FBlocation/train.csv")
# 数据逻辑筛选操作 df.query()
data = data.query("x > 1.0 & x < 1.25 & y > 2.5 & y < 2.75")
# 删除time这一列特征
data = data.drop(['time'], axis=1)
print(data)
# 删除入住次数少于三次位置
place_count = data.groupby('place_id').count()
tf = place_count[place_count.row_id > 3].reset_index()
data = data[data['place_id'].isin(tf.place_id)]
# 3、取出特征值和目标值
y = data['place_id']
x = data.drop(['place_id', 'row_id'], axis=1)
# 4、数据分割与特征工程?
# (1)、数据分割
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
# (2)、标准化
std = StandardScaler()
# 队训练集进行标准化操作
x_train = std.fit_transform(x_train)
print(x_train)
# 进行测试集的标准化操作
x_test = std.fit_transform(x_test)
# 二、算法的输入训练预测
# K值:算法传入参数不定的值 理论上:k = 根号(样本数)
# K值:后面会使用参数调优方法,去轮流试出最好的参数[1,3,5,10,20,100,200]
knn = KNeighborsClassifier(n_neighbors=1)
# 调用fit()
knn.fit(x_train, y_train)
# 预测测试数据集,得出准确率
y_predict = knn.predict(x_test)
print("预测测试集类别:", y_predict)
print("准确率为:", knn.score(x_test, y_test))
return None
if __name__ == "__main__":
#代码:用knn算法对鸢尾花进行分类,添加网格搜索和交叉验证
knncls()
运行结果如下:
row_id x y accuracy place_id
600 600 1.2214 2.7023 17 6683426742
957 957 1.1832 2.6891 58 6683426742
4345 4345 1.1935 2.6550 11 6889790653
4735 4735 1.1452 2.6074 49 6822359752
5580 5580 1.0089 2.7287 19 1527921905
... ... ... ... ... ...
29100203 29100203 1.0129 2.6775 12 3312463746
29108443 29108443 1.1474 2.6840 36 3533177779
29109993 29109993 1.0240 2.7238 62 6424972551
29111539 29111539 1.2032 2.6796 87 3533177779
29112154 29112154 1.1070 2.5419 178 4932578245
[17710 rows x 5 columns]
[[ 0.83245563 -1.74343908 0.05714877]
[ 0.52915898 0.49524962 -0.13620476]
[-0.85122962 0.69993791 -0.15461938]
...
[ 0.09495224 -1.37557271 -0.14541207]
[ 0.46175972 0.93897948 -0.56894839]
[ 0.52397442 -0.82448886 2.92062257]]
预测测试集类别: [5161681408 1097200869 3533177779 ... 2584530303 6237569496 6683426742]
准确率为: 0.40070921985815605
其次,预测K值调优,我们将会在jupyter中进行运算:
pd.to_datetime:
python的时间转换datetime和pd.to_datetime_-永不妥协-的博客-CSDN博客_python to_datetime
pd.to_datetime()_Kwoky的博客-CSDN博客_pd.to_datetime用法
import pandas as pd
#1、获取数据
data = pd.read_csv("F:/BaiduNetdiskDownload/mechine learning/Machine_Learning/resources/FBlocation/train.csv")
#2、基本数据处理
#1)缩小数据范围
data = data.query("x < 2.5 & x >2 & y< 1.5 & y > 1.0") # 数据逻辑筛选操作 df.query()
#2)处理时间特征
time_value = pd.to_datetime(data["time"],unit="s")
date = pd.DatetimeIndex(time_value)
data["day"] = date.day
data["weekday"] = date.weekday
data["hour"] = date.hour
#3)过滤签到次数少的地点
place_count = data.groupby("place_id").count()["row_id"]
#data.groupby("place_id").count() #统计数量
#place_count[place_count > 3].head()
data_final = data[data["place_id"].isin(place_count[place_count > 3].index.values)]
#筛选目标值和特征值
x = data_final[["x","y","accuracy","day","weekday","hour"]]
y = data_final["place_id"]
#数据集划分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x,y)
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
# 3、特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test) #训练集fit,测试集不fit,因为实际我们不知道要分类的未知数据,所以标准化的平均值和标准差只能用测试集的
# 4、KNN算法预估器
estimator = KNeighborsClassifier()
#加入网格搜索与交叉验证
#参数准备
param_dict = {"n_neighbors":[3,5,7,9]}
estimator = GridSearchCV(estimator,param_grid=param_dict,cv=3)
estimator.fit(x_train,y_train)
# 5、模型评估
# 1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 2)计算准确率
score = estimator.score(x_test, y_test)
print("准确率:\n",score)
# 最佳参数:best_params_
print("最佳参数:\n", estimator.best_params_)
# 最佳结果:best_score_
print("最佳结果:\n", estimator.best_score_)
# 最佳预估器:best_estimator_
print("最佳预估器:\n", estimator.best_estimator_)
# 交叉验证结果:cv_results_
print("交叉验证结果:\n", estimator.cv_results_)
运行结果如下:
y_predict:
[1540382716 3229876087 2852927300 ... 6706708436 1327075245 5632997879]
直接比对真实值和预测值:
14668111 False
27343822 True
15103904 False
1073508 False
22672114 False
...
25579756 False
14532786 True
20000562 True
8492671 False
819453 True
Name: place_id, Length: 20228, dtype: bool
准确率:
0.36607672533122404
最佳参数:
{'n_neighbors': 7}
最佳结果:
0.33528883188596975
最佳预估器:
KNeighborsClassifier(n_neighbors=7)
交叉验证结果:
{'mean_fit_time': array([0.10567093, 0.08900865, 0.08966986, 0.09933988]), 'std_fit_time': array([0.01061762, 0.00245127, 0.00589601, 0.00680692]), 'mean_score_time': array([1.00040642, 0.98540219, 1.09007986, 1.15351415]), 'std_score_time': array([0.04896799, 0.01601261, 0.03288546, 0.08910883]), 'param_n_neighbors': masked_array(data=[3, 5, 7, 9],
mask=[False, False, False, False],
fill_value='?',
dtype=object), 'params': [{'n_neighbors': 3}, {'n_neighbors': 5}, {'n_neighbors': 7}, {'n_neighbors': 9}], 'split0_test_score': array([0.3230176 , 0.33789796, 0.33839233, 0.3321139 ]), 'split1_test_score': array([0.32367627, 0.33395956, 0.33252583, 0.3277797 ]), 'split2_test_score': array([0.32347852, 0.33351461, 0.33494834, 0.3322292 ]), 'mean_test_score': array([0.3233908 , 0.33512404, 0.33528883, 0.3307076 ]), 'std_test_score': array([0.00027596, 0.00196985, 0.00240706, 0.00207087]), 'rank_test_score': array([4, 2, 1, 3])}
条件概率与联合概率:
我们通过一个例子,来计算一些结果:
这样我们计算结果为:
p(程序员, 匀称) = P(程序员)P(匀称) =3/7*(4/7) = 12/49
P(产品, 超重|喜欢) = P(产品|喜欢)P(超重|喜欢)=1/2 * 1/4 = 1/8
朴素贝叶斯如何分类,这个算法经常会用在文本分类,那就来看文章分类是一个什么样的问题?
这个了类似一个条件概率,那么仔细一想,给定文章其实相当于给定什么?结合前面我们将文本特征抽取的时候讲的?所以我们可以理解为
但是这个公式怎么求?前面并没有参考例子,其实是相似的,我们可以使用贝叶斯公式去计算 。
贝叶斯公式:
那么这个公式如果应用在文章分类的场景当中,我们可以这样看:
公式分为三个部分:
科技:P(科技|影院,支付宝,云计算) = (影院,支付宝,云计算|科技)∗P(科技)=(8/100)∗(20/100)∗(63/100)∗(30/90) = 0.00456109
娱乐:P(娱乐|影院,支付宝,云计算) = (影院,支付宝,云计算|娱乐)∗P(娱乐)=(56/121)∗(15/121)∗(0/121)∗(60/90) = 0
我们计算出来某个概率为0,合适吗?
目的:防止计算出的分类概率为0。
P(娱乐|影院,支付宝,云计算) =P(影院,支付宝,云计算|娱乐)P(娱乐) =P(影院|娱乐)*P(支付宝|娱乐)*P(云计算|娱乐)P(娱乐)=(56+1/121+4)(15+1/121+4)(0+1/121+1*4)(60/90) = 0.00002
sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
案例:20类新闻分类
1)获取数据
2)划分数据集
3)特征工程 文本特征抽取
4)朴素贝叶斯预估器流程
5)模型评估
代码如下:
def nbcls():
"""
朴素贝叶斯对新闻数据集进行预测
:return:
"""
# 获取新闻的数据,20个类别
news = fetch_20newsgroups(subset='all')
# 进行数据集分割
x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.3)
# 对于文本数据,进行特征抽取
tf = TfidfVectorizer()
x_train = tf.fit_transform(x_train)
# 这里打印出来的列表是:训练集当中的所有不同词的组成的一个列表
print(tf.get_feature_names())
# print(x_train.toarray())
# 不能调用fit_transform
x_test = tf.transform(x_test)
# estimator估计器流程
mlb = MultinomialNB(alpha=1.0)
mlb.fit(x_train, y_train)
# 进行预测
y_predict = mlb.predict(x_test)
print("预测每篇文章的类别:", y_predict[:100])
print("真实类别为:", y_test[:100])
print("预测准确率为:", mlb.score(x_test, y_test))
return None
在学习中未找到20newsgroups数据,所以在此将代码附上。
总结:
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法
怎么理解这句话?通过一个对话例子。
我们要理解为什么我们会把年龄放在第一位?可以利用当得知某个特征(比如年龄)之后,我们能够减少的不确定性大小。越大我们可以认为这个特征很重要。那怎么去衡量减少的不确定性大小呢?
决策树的划分依据之一------信息增益
定义与公式:
特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差,即公式为:
公式的详细解释:
注:信息增益表示得知特征X的信息而息的不确定性减少的程度使得类Y的信息熵减少的程度。
1、g(D, 年龄) = H(D) -H(D|年龄) = 0.971-[5/15H(青年)+5/15H(中年)+5/15H(老年]
2、H(D) = -(6/15log(6/15)+9/15log(9/15))=0.971
3、H(青年) = -(3/5log(3/5) +2/5log(2/5))
H(中年)=-(3/5log(3/5) +2/5log(2/5))
H(老年)=-(4/5og(4/5)+1/5log(1/5))
我们以A1、A2、A3、A4代表年龄、有工作、有自己的房子和贷款情况。最终计算的结果g(D, A1) = 0.313, g(D, A2) = 0.324, g(D, A3) = 0.420,g(D, A4) = 0.363。所以我们选择A3 作为划分的第一个特征。
决策树API:
代码如下:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier,export_graphviz
def decision_iris():
"""
用决策树对鸢尾花进行分类
:return:
"""
# 1)获取数据集
iris = load_iris()
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)
# 3)决策树预估器
estimator = DecisionTreeClassifier(criterion="entropy")
estimator.fit(x_train, y_train)
# 4)模型评估
# 5、模型评估
# 1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 2)计算准确率
score = estimator.score(x_test, y_test)
print("准确率:\n", score)
#可视化决策树
#网站显示结构:http://webgraphviz.com/
#http://dreampuf.github.io/GraphvizOnline/将dot文件内容复制该网站即可,等待一会出图
export_graphviz(estimator,out_file="iris_tree.dot")
return None
if __name__ == "__main__":
#用决策树对鸢尾花进行分类
decision_iris()
运行结果如下:
row_id x y accuracy place_id
600 600 1.2214 2.7023 17 6683426742
957 957 1.1832 2.6891 58 6683426742
4345 4345 1.1935 2.6550 11 6889790653
4735 4735 1.1452 2.6074 49 6822359752
5580 5580 1.0089 2.7287 19 1527921905
... ... ... ... ... ...
29100203 29100203 1.0129 2.6775 12 3312463746
29108443 29108443 1.1474 2.6840 36 3533177779
29109993 29109993 1.0240 2.7238 62 6424972551
29111539 29111539 1.2032 2.6796 87 3533177779
29112154 29112154 1.1070 2.5419 178 4932578245
[17710 rows x 5 columns]
[[ 1.50934208 1.58599493 -0.18615452]
[-1.02465789 -1.31117571 -0.1497283 ]
[-0.27183094 -0.82998474 -0.14062175]
...
[-0.20715509 0.15531106 -0.24079384]
[-1.38684267 -0.71541546 -0.10419553]
[ 0.63621805 -1.4715727 -0.13151519]]
预测测试集类别: [5009192468 5261906348 8048985799 ... 6683426742 3202755803 6399991653]
准确率为: 0.40622537431048067
y_predict:
[0 2 0 0 2 1 1 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1
2]
直接比对真实值和预测值:
[ True True True True True True False True True True True True
True True True False True True True True True True True True
True True True True True True True True True True False True
True True]
准确率:
0.9210526315789473
保存树的结构到dot文件:
export_graphviz(dc, out_file="./tree.dot", feature_names=['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
可视化决策树:
我们可以通过http://dreampuf.github.io/GraphvizOnline/将dot文件内容复制该网站即可,等待一会出图。
在泰坦尼克号和titanic2数据帧描述泰坦尼克号上的个别乘客的生存状态。这里使用的数据集是由各种研究人员开始的。其中包括许多研究人员创建的旅客名单,由Michael A. Findlay编辑。我们提取的数据集中的特征是票的类别,存活,乘坐班,年龄,登陆,home.dest,房间,票,船和性别。
1、乘坐班是指乘客班(1,2,3),是社会经济阶层的代表。
2、其中age数据存在缺失。
数据:http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt
分析:
流程分析:
特征值 目标值
1)获取数据
2)数据处理 缺失值处理 特征值->字典类型
3)准备好特征值,目标值
4)划分数据集
5)特征工程:字典特征抽取
6)决策树预估器流程
7)模型评估
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier,export_graphviz
#1)获取数据
titanic = pd.read_csv("titanic.csv")
# print(titanic)
#筛选特征值和目标值
x = titanic[["pclass","age","sex"]]
y = titanic["survived"]
#2)数据处理-缺失值处理
x["age"].fillna(x["age"].mean(),inplace=True)
#特征值->字典类型
x = x.to_dict(orient="records")
# 3)划分数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
#4)字典特征抽取
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 3)决策树预估器
estimator = DecisionTreeClassifier(criterion="entropy",max_depth=4)
estimator.fit(x_train, y_train)
# 4)模型评估
# 5、模型评估
# 1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 2)计算准确率
score = estimator.score(x_test, y_test)
print("准确率:\n", score)
#可视化决策树
#网站显示结构:http://webgraphviz.com/
#http://dreampuf.github.io/GraphvizOnline/将dot文件内容复制该网站即可,等待一会出图
export_graphviz(estimator,out_file="titanic_tree.dot",feature_names=transfer.get_feature_names_out())
运行结果如下:
row_id x y accuracy place_id
600 600 1.2214 2.7023 17 6683426742
957 957 1.1832 2.6891 58 6683426742
4345 4345 1.1935 2.6550 11 6889790653
4735 4735 1.1452 2.6074 49 6822359752
5580 5580 1.0089 2.7287 19 1527921905
... ... ... ... ... ...
29100203 29100203 1.0129 2.6775 12 3312463746
29108443 29108443 1.1474 2.6840 36 3533177779
29109993 29109993 1.0240 2.7238 62 6424972551
29111539 29111539 1.2032 2.6796 87 3533177779
29112154 29112154 1.1070 2.5419 178 4932578245
[17710 rows x 5 columns]
[[ 1.28921811 -0.64004279 -0.29066274]
[ 1.32150139 0.37661106 -0.39188425]
[ 1.38865063 -0.23710946 4.06186207]
...
[ 1.45450854 0.58309647 -0.73235659]
[-0.26296241 -1.03867434 0.35347413]
[ 0.26648353 0.28914154 -0.10662363]]
预测测试集类别: [1097200869 8047497583 3992589015 ... 2946102544 3741484405 5606572086]
准确率为: 0.4030732860520095
E:\PYTHON\base31.py:261: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
x["age"].fillna(x["age"].mean(),inplace=True)
y_predict:
[0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 1 0 0 0
0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0
0 1 1 1 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1]
直接比对真实值和预测值:
831 True
261 True
1210 True
1155 True
255 True
...
1146 True
1125 False
386 True
1025 False
337 True
Name: survived, Length: 329, dtype: bool
准确率:
0.78419452887538
可视化决策树:
决策树总结:
注:企业重要决策,由于决策树很好的分析能力,在决策过程应用较多, 可以选择特征
集成学习方法:集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测。
随机森林:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
例如, 如果你训练了5个树, 其中有4个树的结果是True, 1个数的结果是False, 那么最终投票结果就是True。
随机森林原理过程:
学习算法根据下列算法而建造每棵树:
API:
class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None, min_samples_split=2)
max_features=sqrt(n_features)
.max_features=sqrt(n_features)
(same as "auto").max_features=log2(n_features)
.max_features=n_features
.#随机森林对泰坦尼克号乘客的生存进行预测
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
# 1、获取数据
iris = load_iris()
# 2、数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data,iris.target,random_state=6)
# 3、特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test) #训练集fit,测试集不fit,因为实际我们不知道要分类的未知数据,所以标准化的平均值和标准差只能用测试集的
# 4、预估器
estimator = RandomForestClassifier()
#加入网格搜索与交叉验证
#参数准备
param_dict = {"n_estimators":[120,200,300,500,800,1200],"max_depth":[5,8,15,25,30]}
estimator = GridSearchCV(estimator,param_grid=param_dict,cv=3)
estimator.fit(x_train,y_train)
# 5、模型评估
# 1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 2)计算准确率
score = estimator.score(x_test, y_test)
print("准确率:\n",score)
# 最佳参数:best_params_
print("最佳参数:\n", estimator.best_params_)
# 最佳结果:best_score_
print("最佳结果:\n", estimator.best_score_)
# 最佳预估器:best_estimator_
print("最佳预估器:\n", estimator.best_estimator_)
# 交叉验证结果:cv_results_
print("交叉验证结果:\n", estimator.cv_results_)
运行结果如下:
row_id x y accuracy place_id
600 600 1.2214 2.7023 17 6683426742
957 957 1.1832 2.6891 58 6683426742
4345 4345 1.1935 2.6550 11 6889790653
4735 4735 1.1452 2.6074 49 6822359752
5580 5580 1.0089 2.7287 19 1527921905
... ... ... ... ... ...
29100203 29100203 1.0129 2.6775 12 3312463746
29108443 29108443 1.1474 2.6840 36 3533177779
29109993 29109993 1.0240 2.7238 62 6424972551
29111539 29111539 1.2032 2.6796 87 3533177779
29112154 29112154 1.1070 2.5419 178 4932578245
[17710 rows x 5 columns]
[[ 1.09435611 0.56130277 0.76872432]
[ 1.54790717 0.29704652 -0.08502879]
[-0.24420432 -1.12422357 -0.67538999]
...
[ 0.65639993 0.74271111 -0.14860615]
[-1.13441199 -1.35991158 -0.53007031]
[-1.18639491 -1.86699789 -0.08502879]]
预测测试集类别: [4908856767 3083446565 8048985799 ... 6780386626 1097200869 3312463746]
准确率为: 0.39322301024428685
y_predict:
[0 2 0 0 2 1 1 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1
2]
直接比对真实值和预测值:
[ True True True True True True False True True True True True
True True True False True True True True True True True True
True True True True True True True True True True False True
True True]
准确率:
0.9210526315789473
最佳参数:
{'max_depth': 15, 'n_estimators': 200}
最佳结果:
0.954954954954955
最佳预估器:
RandomForestClassifier(max_depth=15, n_estimators=200)
交叉验证结果:
{'mean_fit_time': array([0.19069211, 0.28113063, 0.43186251, 0.65972853, 1.01012961,
1.76756271, 0.15901343, 0.24606562, 0.42359718, 0.69383351,
1.04850507, 1.59277439, 0.16767907, 0.26868979, 0.42450213,
0.70297694, 1.03649386, 1.42610717, 0.16701055, 0.257689 ,
0.38503679, 0.68106254, 1.05675999, 1.73424919, 0.19213859,
0.35897946, 0.42781893, 0.65339128, 1.07486129, 1.68632817]), 'std_fit_time': array([0.0296609 , 0.03012727, 0.01528373, 0.04283441, 0.0084445 ,
0.07006111, 0.00864029, 0.00698337, 0.03101803, 0.00967518,
0.05733202, 0.06459257, 0.01250089, 0.01405433, 0.01574089,
0.04563225, 0.07845398, 0.07756379, 0.01640065, 0.01131789,
0.01208697, 0.0361776 , 0.03298022, 0.20727576, 0.01647266,
0.0528533 , 0.04387 , 0.02852244, 0.03336119, 0.04572077]), 'mean_score_time': array([0.01641631, 0.02590068, 0.03802443, 0.06310042, 0.09024596,
0.51562476, 0.01299977, 0.02167312, 0.03667625, 0.05863961,
0.08001328, 0.13175869, 0.01433881, 0.02233243, 0.03433967,
0.0613277 , 0.09727049, 0.13867863, 0.01434429, 0.02533237,
0.03666504, 0.05566462, 0.10700425, 0.13265236, 0.01866961,
0.02972047, 0.03933676, 0.05433536, 0.08657177, 0.15367524]), 'std_score_time': array([2.44372494e-03, 3.32565446e-03, 1.00583911e-02, 7.84084572e-03,
8.01341368e-03, 5.13812621e-01, 8.15561832e-04, 2.36230401e-03,
4.71915455e-03, 7.36537262e-03, 1.32073277e-05, 7.42504908e-03,
1.88896605e-03, 1.87958794e-03, 3.68637707e-03, 8.48372371e-03,
9.96518227e-03, 1.88046956e-02, 1.87969381e-03, 2.04987331e-03,
4.98841399e-03, 5.73041288e-03, 1.12157271e-02, 4.75877489e-03,
1.24783129e-03, 4.05398169e-04, 9.44314210e-04, 3.40242998e-03,
3.95548976e-03, 1.06577973e-02]), 'param_max_depth': masked_array(data=[5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 15, 15, 15, 15, 15,
15, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30],
mask=[False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False,
False, False, False, False, False, False],
fill_value='?',
dtype=object), 'param_n_estimators': masked_array(data=[120, 200, 300, 500, 800, 1200, 120, 200, 300, 500, 800,
1200, 120, 200, 300, 500, 800, 1200, 120, 200, 300,
500, 800, 1200, 120, 200, 300, 500, 800, 1200],
mask=[False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False,
False, False, False, False, False, False],
fill_value='?',
dtype=object), 'params': [{'max_depth': 5, 'n_estimators': 120}, {'max_depth': 5, 'n_estimators': 200}, {'max_depth': 5, 'n_estimators': 300}, {'max_depth': 5, 'n_estimators': 500}, {'max_depth': 5, 'n_estimators': 800}, {'max_depth': 5, 'n_estimators': 1200}, {'max_depth': 8, 'n_estimators': 120}, {'max_depth': 8, 'n_estimators': 200}, {'max_depth': 8, 'n_estimators': 300}, {'max_depth': 8, 'n_estimators': 500}, {'max_depth': 8, 'n_estimators': 800}, {'max_depth': 8, 'n_estimators': 1200}, {'max_depth': 15, 'n_estimators': 120}, {'max_depth': 15, 'n_estimators': 200}, {'max_depth': 15, 'n_estimators': 300}, {'max_depth': 15, 'n_estimators': 500}, {'max_depth': 15, 'n_estimators': 800}, {'max_depth': 15, 'n_estimators': 1200}, {'max_depth': 25, 'n_estimators': 120}, {'max_depth': 25, 'n_estimators': 200}, {'max_depth': 25, 'n_estimators': 300}, {'max_depth': 25, 'n_estimators': 500}, {'max_depth': 25, 'n_estimators': 800}, {'max_depth': 25, 'n_estimators': 1200}, {'max_depth': 30, 'n_estimators': 120}, {'max_depth': 30, 'n_estimators': 200}, {'max_depth': 30, 'n_estimators': 300}, {'max_depth': 30, 'n_estimators': 500}, {'max_depth': 30, 'n_estimators': 800}, {'max_depth': 30, 'n_estimators': 1200}], 'split0_test_score': array([0.97368421, 1. , 0.97368421, 0.97368421, 0.97368421,
1. , 1. , 0.97368421, 0.97368421, 0.97368421,
0.97368421, 1. , 0.97368421, 1. , 1. ,
1. , 1. , 1. , 0.97368421, 0.97368421,
1. , 1. , 1. , 0.97368421, 0.97368421,
0.97368421, 1. , 1. , 0.97368421, 0.97368421]), 'split1_test_score': array([0.94594595, 0.94594595, 0.94594595, 0.94594595, 0.94594595,
0.94594595, 0.94594595, 0.94594595, 0.94594595, 0.94594595,
0.94594595, 0.94594595, 0.94594595, 0.94594595, 0.94594595,
0.94594595, 0.94594595, 0.94594595, 0.94594595, 0.94594595,
0.94594595, 0.94594595, 0.94594595, 0.94594595, 0.94594595,
0.94594595, 0.94594595, 0.94594595, 0.94594595, 0.94594595]), 'split2_test_score': array([0.89189189, 0.89189189, 0.89189189, 0.89189189, 0.91891892,
0.89189189, 0.89189189, 0.91891892, 0.91891892, 0.91891892,
0.91891892, 0.89189189, 0.89189189, 0.91891892, 0.91891892,
0.91891892, 0.89189189, 0.91891892, 0.89189189, 0.91891892,
0.89189189, 0.89189189, 0.91891892, 0.91891892, 0.91891892,
0.89189189, 0.89189189, 0.91891892, 0.89189189, 0.91891892]), 'mean_test_score': array([0.93717402, 0.94594595, 0.93717402, 0.93717402, 0.94618303,
0.94594595, 0.94594595, 0.94618303, 0.94618303, 0.94618303,
0.94618303, 0.94594595, 0.93717402, 0.95495495, 0.95495495,
0.95495495, 0.94594595, 0.95495495, 0.93717402, 0.94618303,
0.94594595, 0.94594595, 0.95495495, 0.94618303, 0.94618303,
0.93717402, 0.94594595, 0.95495495, 0.93717402, 0.94618303]), 'std_test_score': array([0.03396278, 0.04413495, 0.03396278, 0.03396278, 0.02235847,
0.04413495, 0.04413495, 0.02235847, 0.02235847, 0.02235847,
0.02235847, 0.04413495, 0.03396278, 0.03370863, 0.03370863,
0.03370863, 0.04413495, 0.03370863, 0.03396278, 0.02235847,
0.04413495, 0.04413495, 0.03370863, 0.02235847, 0.02235847,
0.03396278, 0.04413495, 0.03370863, 0.03396278, 0.02235847]), 'rank_test_score': array([24, 16, 24, 24, 7, 16, 16, 7, 7, 7, 7, 16, 24, 1, 1, 1, 16,
1, 24, 7, 16, 16, 1, 7, 7, 24, 16, 1, 24, 7])}
总结:
学习笔记——黑马程序员之Python机器学习。