目录

Python10-逻辑回归-决策树

Python10-逻辑回归-决策树

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

1. cart剪枝

https://i-blog.csdnimg.cn/direct/79c6cb4d3ddf499682d329a955884e64.png

https://i-blog.csdnimg.cn/direct/a93d0716cfff40dc96c8368845f74060.png

https://i-blog.csdnimg.cn/direct/735b0b035a504ee3ab45cb5f9edfa812.png

预剪枝就是一边构建决策树,一边决定要不要构造这个结点

后剪枝就是先构造好,然后从下往下决定要不要剪枝

https://i-blog.csdnimg.cn/direct/fe742242da154256a28c1a5628be9136.png

https://i-blog.csdnimg.cn/direct/2f689b7976254418b34a63930a665ea3.png

https://i-blog.csdnimg.cn/direct/ee2c1f603b004fb9a17d9f1132615266.png

2. 特征⼯程-特征提取

https://i-blog.csdnimg.cn/direct/485cb071b9164fc68ec7ec27e6499121.png
就是文本转化为数字,类别转化为数字
便于机器学习

2.1 特征提取

将任意数据(如⽂本或图像)转换为可⽤于机器学习的数字特征

特征提取分类:
	字典特征提取(特征离散化)---就是第二幅图
	本特征提取----就是第一幅图
	图像特征提取深度学习将介绍

2.2 特征提取API

sklearn.feature_extraction

2.3 字典特征提取

⽤:对字典数据进特征值化
sklearn.feature_extraction.DictVectorizer(sparse=True,)
	DictVectorizer.fit_transform(X)
		X:字典或者包含字典的迭代器返回值
		返回sparse矩阵
	DictVectorizer.get_feature_names() 返回类别名称

https://i-blog.csdnimg.cn/direct/2f17e373b82e499e89047e3c4b87c536.png

https://i-blog.csdnimg.cn/direct/e3bde4c930a543a2bb97f95032fcacc4.png

https://i-blog.csdnimg.cn/direct/3642773d07884678a4b50fcf16d39352.png
这个就是one-hot编码

from sklearn.feature_extraction import  DictVectorizer

def dict_demo():
    #字典特征提取
    #获取数据
    data = [{'city': '北京', 'temperature': 100},
            {'city': '上海', 'temperature': 60},
            {'city': '深圳', 'temperature':30}]
    #字典特征提取
    #实例化
    transfer = DictVectorizer(sparse=False)
    #转换
    new_data = transfer.fit_transform(data)
    print(new_data)

if __name__ == '__main__':
    dict_demo()

sparse=False表示返回非sparse矩阵

https://i-blog.csdnimg.cn/direct/e5f1f3e85b874f31870b67cb5a5bdf7a.png

第一列是上海,然后第二列是北京,第三列是深圳
怎么证明呢

    #获取具体属性名
    print("属性名字是:\n",transfer.get_feature_names_out())

https://i-blog.csdnimg.cn/direct/feaaf34d6fb940c0a791dc25e0e5e818.png
这样就成功了

from sklearn.feature_extraction import  DictVectorizer

def dict_demo():
    #字典特征提取
    #获取数据
    data = [{'city': '北京', 'temperature': 100},
            {'city': '上海', 'temperature': 60},
            {'city': '深圳', 'temperature':30}]
    #字典特征提取
    #实例化
    transfer = DictVectorizer(sparse=True)
    #转换
    new_data = transfer.fit_transform(data)
    print(new_data)
    #获取具体属性名
    print("属性名字是:\n",transfer.get_feature_names_out())

if __name__ == '__main__':
    dict_demo()

https://i-blog.csdnimg.cn/direct/c5489e5e8e8d4cdb8a3300fffdd2c16a.png

这个表示的就是非sparse矩阵中非0的坐标位置,和值
显然sparse=True存储比较节省空间
只存储了非0位置
而且找东西很快
这个就是sparse矩阵

2.4 英文⽂本特征提取

⽤:本数据进特征值化
sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
	返回词频矩阵
	CountVectorizer.fit_transform(X)
		X:本或者包含本字符串的可迭代对象
		返回值:返回sparse矩阵
	CountVectorizer.get_feature_names() 返回值:单词列表
sklearn.feature_extraction.text.TfidfVectorizer

https://i-blog.csdnimg.cn/direct/05dee7fbe81249f29c783afad29875b8.png

我们发现这里也有对图像的特征处理哦

from sklearn.feature_extraction.text import CountVectorizer
def english_count_demo():
    # 英文文本特征提取
    # 获取数据
    data = ["life is short,i like python",
            "life is too long,i dislike python"]
    # 实例化
    transfer = CountVectorizer()
    # 进行特征提取
    new_data = transfer.fit_transform(data)
    print("特征名字是:\n",transfer.get_feature_names_out())
    print(new_data)

https://i-blog.csdnimg.cn/direct/ff01ff41f4f94ce1bd84b65a6d727a87.png

这样就成功了,发现还是没有什么区别的,但是这样不方便看
这里是不能设置sparse=False这个参数的

    print(new_data.toarray())

https://i-blog.csdnimg.cn/direct/24c11043b7fd41d094d1999d0b9438df.png

这个意思就是,比如第一行的数据就表示,第一句话中每个特征值出现的数量
比如like出现了一次,那么like那一列对应的第一行就是1

    data = ["life is short,i is like python",
            "life is too long,i dislike python"]

https://i-blog.csdnimg.cn/direct/fa3265bdd2c640e9a4d73927953f1001.png
我们写两个is,就变成2了
还有就是单个单词不做统计,标点符号也不统计

def english_count_demo():
    # 英文文本特征提取
    # 获取数据
    data = ["life is short,i is like python",
            "life is too long,i dislike python"]
    # 实例化
    transfer = CountVectorizer(stop_words=["dislike"])
    # 进行特征提取
    new_data = transfer.fit_transform(data)
    print("特征名字是:\n",transfer.get_feature_names_out())
    print(new_data)
    print(new_data.toarray())

stop_words=[“dislike”]就表示不要dislike这个特征值

https://i-blog.csdnimg.cn/direct/a345e24aa0b5448183f66a504d7df2cf.png
这样就没有dislike了

2.4 中文⽂本特征提取

def chinese_count_demo():
    # 英文文本特征提取
    # 获取数据
    data = ["⼈⽣苦短,我喜欢Python","生活太长久,我不喜欢Python"]
    # 实例化
    transfer = CountVectorizer()
    # 进行特征提取
    new_data = transfer.fit_transform(data)
    print("特征名字是:\n",transfer.get_feature_names_out())
    print(new_data)
    print(new_data.toarray())

https://i-blog.csdnimg.cn/direct/de49d6eaccff450f9c803df8153bb310.png

我们发现划分的不好

因为不是词语

这个是以空格划分的,或者语句
所以要让这个智能一点—》满足我们中文的分词

仔细分析之后会发现英⽂默认是以空格分开的。其实就达到了⼀个分词的效果,所以我们
要对中⽂进⾏分词处理

2.5 jieba分词处理

pip install jieba
import jieba
if __name__ == '__main__':
    # dict_demo()
    # chinese_count_demo()
    cut_word("我爱你python,人生苦短,我用python")
def cut_word(text):
    ret=jieba.cut(text)
    print(ret)
    pass

打印的是一个对象

https://i-blog.csdnimg.cn/direct/03100faeb6e844fe95c88deb985154ad.png

def cut_word(text):
    ret=list(jieba.cut(text))
    print(ret)
    pass

这样就可以对对象强制转换,然后获取对象里面的内容了
https://i-blog.csdnimg.cn/direct/c56469a4937b41478430c27a63c043de.png

这样就分割开了

def cut_word(text):
    ret=" ".join(list(jieba.cut(text)))
    print(ret)
    pass

https://i-blog.csdnimg.cn/direct/4fd25747d06446ccbe79b87f13d309e2.png
这个表示用空格拼接
这样就可以被识别出来了

def cut_word(text):
    ret=" ".join(list(jieba.cut(text)))
    print(ret)
    return ret
def chinese_count_demo2():
    # 英文文本特征提取
    # 获取数据
    data = ["⼀种还是⼀种今天很残酷,明天更残酷,后天很美好,但绝对⼤部分是死在明天晚上,所以每个⼈不要放弃今天。",
            "我们看到的从很远星系来的光是在⼏百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只⽤⼀种⽅式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    #文章分割
    list=[]
    for sentence in data:
        list.append(cut_word(sentence))
    print(list)

https://i-blog.csdnimg.cn/direct/7c8197109b2d4f7e952ebab081e3d39c.png

这样就把这片文章切分开了

def chinese_count_demo2():
    # 英文文本特征提取
    # 获取数据
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对⼤部分是死在明天晚上,所以每个⼈不要放弃今天。",
            "我们看到的从很远星系来的光是在⼏百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只⽤⼀种⽅式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    #文章分割
    list=[]
    for sentence in data:
        list.append(cut_word(sentence))
    print(list)
    # 实例化
    transfer = CountVectorizer()
    # 进行特征提取
    new_data = transfer.fit_transform(list)
    print("特征名字是:\n",transfer.get_feature_names_out())
    print(new_data)
    print(new_data.toarray())

https://i-blog.csdnimg.cn/direct/b7fbf615a1af47dbbe6d293e2ff9f4d6.png

    transfer = CountVectorizer(stop_words=["一种","今天"])

https://i-blog.csdnimg.cn/direct/e2dee5f700e74e8da6880d618240500f.png
停用词可以去网上找停用词库—-》这些词语无法表示这篇文章讲的什么

https://i-blog.csdnimg.cn/direct/f018e7985d1a44abba09b44fa14018e3.png

2.6 Tf-idf⽂本特征提取

TF-IDF的主要思想是:如果某个词或短语在⼀篇⽂章中出现的概率⾼,并且在其他⽂章中很少出现,则认为此词或
者短语具有很好的类别区分能⼒,适合⽤来分类。
TF-IDF作⽤:⽤以评估⼀字词对于⼀个⽂件集或⼀个语料库中的其中⼀份⽂件的重要程度

https://i-blog.csdnimg.cn/direct/9f055e83f85745a88ac7e2ce5a2856d3.png

Tf-idf的重要性
分类机器学习算法进⾏⽂章分类中前期数据处理⽅式

from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer
def tfidf_demo():
    # 英文文本特征提取
    # 获取数据
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对⼤部分是死在明天晚上,所以每个⼈不要放弃今天。",
            "我们看到的从很远星系来的光是在⼏百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只⽤⼀种⽅式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    #文章分割
    list=[]
    for sentence in data:
        list.append(cut_word(sentence))
    print(list)
    # 实例化
    # transfer = CountVectorizer(stop_words=["一种","今天"])
    transfer = TfidfVectorizer()
    # 进行特征提取
    new_data = transfer.fit_transform(list)
    print("特征名字是:\n",transfer.get_feature_names_out())
    print(new_data)
    print(new_data.toarray())

data的每个元素就是一篇文章
https://i-blog.csdnimg.cn/direct/4acdecfb4ffe494b8d7f526c033d231e.png

https://i-blog.csdnimg.cn/direct/8b2612ee5c2c4edf904ef13602e7af50.png
这样就划分出来了每篇文章每个次的tfidf

3. 决策树算法api

class sklearn.tree.DecisionTreeClassifier(criterion=gini, max_depth=None,random_state=None)
	criterion
		特征选择标准
		"gini"或者"entropy"前者代表基尼系数后者代表信息增益。⼀默认"gini"即CART算法
	min_samples_split
		内部节点再划分所需最样本数
		这个值限制了树继续划分的条件如果某节点的样本数少于min_samples_split则不会继续再尝试选择
		最优特征来进划分 默认是2.如果样本量不⼤,不需要管这个值如果样本量数量级⼤,则推荐增
		这个值我之前的个项⼦,概10万样本决策树时我选择了min_samples_split=10
		可以作为参考
	min_samples_leaf
		节点最少样本数
		这个值限制了叶节点最少的样本数如果某叶节点数⽬⼩于样本数则会和兄弟节点起被剪枝
		默认是1,可以输最少的样本数的整数或者最少样本数占样本总数的百分⽐。如果样本量不⼤,不需要
		管这个值如果样本量数量级⼤,则推荐增这个值之前的10万样本项使min_samples_leaf的
		值为5仅供参考
	max_depth
		决策树最深度
		决策树的最深度默认可以不输⼊,如果不输的话决策树在建⽴⼦树的时候不会限制树的深度
		般来说数据少或者特征少的时候可以不管这个值如果模型样本量多特征也多的情况下推荐限制
		这个最深度具体的取值取决于数据的分布的可以取值10-100之间
	random_state
		随机数种

min_samples_split就是最多划分的节点数

4. 案例:泰坦尼克号乘客⽣存预测

https://i-blog.csdnimg.cn/direct/6b086c8805864b6ba2b5f284745ab503.png

import pandas as pd
# 1获取数据
titan = pd.read_csv("http://hbiostat.org/data/repo/titanic.txt")

https://i-blog.csdnimg.cn/direct/df993200b0f444da86f9386f42157b07.png

1.获取数据
2.数据基本处理
2.1 确定特征值,标值
2.2 缺失值处理
2.3 数据集划分
3.特征(字典特征抽取)
4.机器学习(决策树)
5.模型评估
import numpy as np
#数据集划分
from sklearn.model_selection import train_test_split
#特征(字典特征抽取)
from  sklearn.feature_extraction import DictVectorizer
# 机器学习(决策树)
from sklearn.tree import DecisionTreeClassifier
# 2.数据基本处理
# 2.1 确定特征值,标值
x= titan[["pclass","age","sex"]]
y = titan["survived"]
x
# 2.2 缺失值处理,因为有很多的缺失值所以用均值填充缺失值不要删除
# 2.2 缺失值处理,因为有很多的缺失值所以用均值填充缺失值不要删除
# 使用.loc确保修改原始数据
x.loc[:, "age"] = x["age"].fillna(value=titan["age"].mean())
x["age"]
x

https://i-blog.csdnimg.cn/direct/584103f482be4a7fb1f5eee282b6beaf.png

# 2.3 数据集划分
x_test ,x_train,y_test,y_train =train_test_split(x,y,test_size=0.25,random_state=22)
x_train

https://i-blog.csdnimg.cn/direct/7228fdaa3c634ace8447db3f9d0e140a.png

特征⼯程(字典特征抽取)的话,就是要对字典数据进行处理,那么就要先把x_train转化为字典数据

# 3.特征(字典特征抽取)
x_train=x_train.to_dict(orient="records")
x_test=x_test.to_dict(orient="records")
x_train

当使用 orient=“records” 时:
转换后会得到一个列表(list)
列表中的每个元素都是一个字典(dict)
每个字典对应原 DataFrame 中的一行数据
字典的键是原 DataFrame 的列名,值是该行对应列的数值
https://i-blog.csdnimg.cn/direct/9bc0193b1c73445691c2ad8d2c514248.png

# 3.特征(字典特征抽取)
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
transfer.get_feature_names_out()

https://i-blog.csdnimg.cn/direct/6f1b1f60f7924c2697618ea936840d27.png

x_train.toarray()

https://i-blog.csdnimg.cn/direct/838b68b3bdbb415faf5222547ee5727c.png

# 4.机器学习(决策树)
estimator=DecisionTreeClassifier()
estimator.fit(x_train,y_train)
# 5.模型评估
y_predict = estimator.predict(x_test)

y_predict

https://i-blog.csdnimg.cn/direct/230fc3c4b009499daf984706ad8241f3.png

ret=estimator.score(x_test,y_test)
ret

https://i-blog.csdnimg.cn/direct/eace26bd3dd2452e87c5036e65d949d6.png

# 4.机器学习(决策树)
estimator=DecisionTreeClassifier(max_depth=5)
estimator.fit(x_train,y_train)

表示最深为五层

https://i-blog.csdnimg.cn/direct/5698bea7d57443639a73539a57c77261.png
这里可以看到有什么参数可以使用

4.1 决策树可视化

	sklearn.tree.export_graphviz() 该函数能够导出DOT格式
		tree.export_graphviz(estimator,out_file='tree.dot,feature_names=[‘’,’’])
# 机器学习(决策树)
from sklearn.tree import DecisionTreeClassifier,export_graphviz
export_graphviz(estimator,out_file="./source/tree.dot",
                feature_names=['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '⼥', '男性'])

https://i-blog.csdnimg.cn/direct/a0c408627c934700a3a1147906db83ef.png
怎么看到树呢

全部复制到这个网站就可以看到树了

export_graphviz中的feature_names参数需要与get_feature_names_out()返回的特征顺序严格一一对应,其核心作用就是给特征取 “别名”,方便在可视化结果中更直观地展示。

或者安装对应的dot插件–dot 语言支持

https://i-blog.csdnimg.cn/direct/4a9f03cc8ebe4f34b52ee96e8c0f3bd6.png

刚好是五层
https://i-blog.csdnimg.cn/direct/b04d6131f2b5483b8b1ed21a907517f3.png

5. 回归决策树

前⾯已经讲到,关于数据类型,我们主要可以把其分为两类,连续型数据和离散型数据。在⾯对不同数据时,决策树也
可以分为两⼤类型:
分类决策树和回归决策树。
前者主要⽤于处理离散型数据,后者主要⽤于处理连续型数据

k近邻既可以处理回归,也可以处理分类

https://i-blog.csdnimg.cn/direct/7d76da06b6ef409b82b052061e6f9e17.png
https://i-blog.csdnimg.cn/direct/29ef0e6f83fb4b3e95a9477ae1dc70ef.png

https://i-blog.csdnimg.cn/direct/09aa93990bd045f8ae1b203233563e88.png
https://i-blog.csdnimg.cn/direct/eb5738f5aba34cdf9cd04aa0fd28e898.png
https://i-blog.csdnimg.cn/direct/6adc23303e794b17a990154559cc7098.png

https://i-blog.csdnimg.cn/direct/6a448d10616645da801c8423b4f2144f.png

5.1 回归决策树和线性回归对⽐

x=np.array(list(range(1,11)))
x

https://i-blog.csdnimg.cn/direct/b2d24b7b7513492e8920b88369caedba.png

x=np.array(list(range(1,11))).reshape(-1,1)
x

https://i-blog.csdnimg.cn/direct/04ad2ec065b54f29ac50d1732bea5f95.png

.reshape(-1,1) 把一维数组重塑为二维数组,其中:
-1 表示让 NumPy 自动计算该维度的大小
1 表示第二维固定为 1 列

y = np.array([5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05])
y

https://i-blog.csdnimg.cn/direct/0d8e56dde6b940c3b2f2f37a8188244e.png

#模型训练
m1 = DecisionTreeRegressor(max_depth=1)
m2= DecisionTreeRegressor(max_depth=3)
m3=LinearRegression()
m1.fit(x,y)
m2.fit(x,y)
m3.fit(x,y)
#模型预测
np.arange(0,10,0.01)

表示生成)~10,间隔0.01
https://i-blog.csdnimg.cn/direct/6b15d305b1b54a1fb839e5eef171ea6c.png

#模型预测
x_test=np.arange(0,10,0.01).reshape(-1,1)

https://i-blog.csdnimg.cn/direct/62b28228bb97444fa091fd7b363b0043.png

y_1=m1.predict(x_test)
y_2=m2.predict(x_test)
y_3=m3.predict(x_test)
#结果可视化
plt.figure(figsize=(10,6),dpi=100)
plt.scatter(x,y,label='data')
plt.show()

x:散点图中每个点的 x 轴坐标数据(通常是特征数据),需要是数组或类似序列的结构。
y:散点图中每个点的 y 轴坐标数据(通常是目标值或对应的结果数据),同样需要是数组或类似序列的结构,且与 x 的长度必须一致(一一对应)。
label=‘data’:为这组散点数据添加 标签,标签内容为字符串 ‘data’。这个标签会在调用 plt.legend() 时显示在图例中,用于区分图中的不同数据系列(如果有多个数据集绘图时)。

#结果可视化
plt.figure(figsize=(10,6),dpi=100)
plt.scatter(x,y,label='data')

plt.plot(x_test,y_1,label='max_depth=1')
plt.plot(x_test,y_2,label='max_depth=3')
plt.plot(x_test,y_3,label='LinearRegression')
plt.legend()
plt.xlabel("数据")
plt.ylabel("预测结果")
plt.show()

https://i-blog.csdnimg.cn/direct/b8cfbb9af88046e9bded9e225580aa10.png

总结