Python10-逻辑回归-决策树
Python10-逻辑回归-决策树
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
1. cart剪枝
预剪枝就是一边构建决策树,一边决定要不要构造这个结点
后剪枝就是先构造好,然后从下往下决定要不要剪枝
2. 特征⼯程-特征提取
就是文本转化为数字,类别转化为数字
便于机器学习
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() 返回类别名称
这个就是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矩阵
第一列是上海,然后第二列是北京,第三列是深圳
怎么证明呢
#获取具体属性名
print("属性名字是:\n",transfer.get_feature_names_out())
这样就成功了
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()
这个表示的就是非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
我们发现这里也有对图像的特征处理哦
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)
这样就成功了,发现还是没有什么区别的,但是这样不方便看
这里是不能设置sparse=False这个参数的
print(new_data.toarray())
这个意思就是,比如第一行的数据就表示,第一句话中每个特征值出现的数量
比如like出现了一次,那么like那一列对应的第一行就是1
data = ["life is short,i is like python",
"life is too long,i dislike python"]
我们写两个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这个特征值
这样就没有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())
我们发现划分的不好
因为不是词语
这个是以空格划分的,或者语句
所以要让这个智能一点—》满足我们中文的分词
仔细分析之后会发现英⽂默认是以空格分开的。其实就达到了⼀个分词的效果,所以我们
要对中⽂进⾏分词处理
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
打印的是一个对象
def cut_word(text):
ret=list(jieba.cut(text))
print(ret)
pass
这样就可以对对象强制转换,然后获取对象里面的内容了
这样就分割开了
def cut_word(text):
ret=" ".join(list(jieba.cut(text)))
print(ret)
pass
这个表示用空格拼接
这样就可以被识别出来了
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)
这样就把这片文章切分开了
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())
transfer = CountVectorizer(stop_words=["一种","今天"])
停用词可以去网上找停用词库—-》这些词语无法表示这篇文章讲的什么
2.6 Tf-idf⽂本特征提取
TF-IDF的主要思想是:如果某个词或短语在⼀篇⽂章中出现的概率⾼,并且在其他⽂章中很少出现,则认为此词或
者短语具有很好的类别区分能⼒,适合⽤来分类。
TF-IDF作⽤:⽤以评估⼀字词对于⼀个⽂件集或⼀个语料库中的其中⼀份⽂件的重要程度
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的每个元素就是一篇文章
这样就划分出来了每篇文章每个次的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. 案例:泰坦尼克号乘客⽣存预测
import pandas as pd
# 1、获取数据
titan = pd.read_csv("http://hbiostat.org/data/repo/titanic.txt")
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
# 2.3 数据集划分
x_test ,x_train,y_test,y_train =train_test_split(x,y,test_size=0.25,random_state=22)
x_train
特征⼯程(字典特征抽取)的话,就是要对字典数据进行处理,那么就要先把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 的列名,值是该行对应列的数值
# 3.特征⼯程(字典特征抽取)
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
transfer.get_feature_names_out()
x_train.toarray()
# 4.机器学习(决策树)
estimator=DecisionTreeClassifier()
estimator.fit(x_train,y_train)
# 5.模型评估
y_predict = estimator.predict(x_test)
y_predict
ret=estimator.score(x_test,y_test)
ret
# 4.机器学习(决策树)
estimator=DecisionTreeClassifier(max_depth=5)
estimator.fit(x_train,y_train)
表示最深为五层
这里可以看到有什么参数可以使用
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', '⼥性', '男性'])
怎么看到树呢
全部复制到这个网站就可以看到树了
export_graphviz中的feature_names参数需要与get_feature_names_out()返回的特征顺序严格一一对应,其核心作用就是给特征取 “别名”,方便在可视化结果中更直观地展示。
或者安装对应的dot插件–dot 语言支持
刚好是五层
5. 回归决策树
前⾯已经讲到,关于数据类型,我们主要可以把其分为两类,连续型数据和离散型数据。在⾯对不同数据时,决策树也
可以分为两⼤类型:
分类决策树和回归决策树。
前者主要⽤于处理离散型数据,后者主要⽤于处理连续型数据
k近邻既可以处理回归,也可以处理分类
5.1 回归决策树和线性回归对⽐
x=np.array(list(range(1,11)))
x
x=np.array(list(range(1,11))).reshape(-1,1)
x
.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
#模型训练
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
#模型预测
x_test=np.arange(0,10,0.01).reshape(-1,1)
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()