机器学习是人工智能的主要分支,深度学习又是机器学习的主要分支。
图片来源于网络
Kaggle数据集: https://www.kaggle.com/datasets
UCI数据集: https://archive.ics.uci.edu/ml/index.php
可以从数据集提供站点中获取数据集,也可以使用Python的机器学习库(sciket-learn)获取本地或网络上的数据集。
pip install scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple
导入scikit-learn将使用另一个名字sklearn,若要使用它提供的数据集,则必须(类似)这样导入。
from sklearn.datasets import load_iris
其中:
load_iris
data = load_iris()
print(data)
# 打印结果(仅展示部分)
#{'data': array([[5.1, 3.5, 1.4, 0.2],
# [4.9, 3. , 1.4, 0.2],
# [4.7, 3.2, 1.3, 0.2],
# [4.6, 3.1, 1.5, 0.2],
# ......
# [5.9, 3. , 5.1, 1.8]]),
# 'target': array([0, 0, 0, 0, 0, 0, 0,...... 2, 2, 2, 2, 2]),
# 'frame': None, 'target_names': array(['setosa', 'versicolor', 'virginica'], dt
# ype='
# \n--------------------\n\n**Data Set Chara......: 'sklearn.datasets.data'}
可以看到,返回的数据集是一个字典,部分键对应的值是一个ndarry(使用numpy创建的多维数组)。
因此:
键 | 值 |
---|---|
data | 特征值列表 |
target | 目标值列表 |
target_names | 目标值名称,即每个目标值的具体含义 |
feature_names | 特征值名称,即每个特征值的具体含义 |
DESCR | 数据集的描述信息,DESCR 是单次description的简写 |
获取数据集后,不能将数据集全部用于训练,必须留一部分用于模型评估。由于训练集数据量越多,训练后得到的模型就越是精确,因而训练集的占比往往远大于测试集。训练集的占比范围(通常):70%~80%。
数据集的划分常用
sklearn.model_selection.train_test_split(* arrays,** options)
参数 | 默认值 | 意义 |
---|---|---|
*arrays | 必填项,无默认值 | 允许的输入是列表,numpy数组,稀疏矩阵或padas中的DataFrame。第一个参数为特征值数组,第二个值为目标值数组。 |
train_size | None | 如果为float,则应在0.0到1.0之间,并表示要包含在训练集切分中的数据集的比例。如果为int,则表示训练集样本的绝对数量。如果为None,则该值将自动设置为测试集大小的补集。 |
test_size | None | 如果为float,则应在0.0到1.0之间,表示要包括在测试集切分中的数据集的比例。如果为int,则表示测试集样本的绝对数量。如果为None,则将值设置为训练集大小的补集。如果train_size也是None,则将其设置为0.25。 |
random_state | 无默认值 | 指定随机数种子,将特征值与其对应的目标值的组合打乱后按照指定比例划分,相同的随机数种子将获得相同的划分结果。 |
返回值:
该方法的返回值为一个列表,其中有四个元素,均为ndarray(numpy创建的多维数组对象)。
从左到右,每个对象代表的含义分别为:
特征值数组(训练集),特征值数组(测试集),目标值数组(训练集),目标值数组(测试集)
数据和特征决定机器学习的上限,而模型与算法只能通过对自身的不断优化来无限逼近这个上限。
特征工程旨在将数据中的有效值转换为相应的数值,便于后续的处理。
from sklearn.feature_extraction import DictVectorizer
# 需要矢量化的字典列表
data = [{'width': '36px', 'height': '12px', 'area': 432},
{'width':'60px', 'height':'10px', 'area':600},
{'width':'15px', 'height':'25px', 'area':375}]
# 返回一个DictVectorizer实例化对象,我们可以用它来解析数据
parser = DictVectorizer(sort=True, sparse=False)
result = parser.fit_transform(data)
# result 即为提取结果
print(result)
# parser.get_feature_names() 返回每个键值代表的含义(即每个键值对应的键)组成的列表
print(parser.get_feature_names())
其中:
sklearn.feature_extraction.DictVectorizer( sparse=True, sort=True, dtype=
sparse指定是否返回稀疏矩阵
sort指定是否进行排序
在指定dtype前需要导入numpy并使用numpy提供的类型(numpy.int等)作为参数值。
我们来对比一下(改变参数值后,主逻辑打印的结果有何不同):
返回稀疏数组(sparse=True)
(0, 0) 432.0
(0, 2) 1.0
(0, 5) 1.0
(1, 0) 600.0
(1, 1) 1.0
(1, 6) 1.0
(2, 0) 375.0
(2, 3) 1.0
(2, 4) 1.0
[‘area’, ‘height=10px’, ‘height=12px’, ‘height=25px’, ‘width=15px’,
‘width=36px’, ‘width=60px’]
返回多维数组(sparse=False)
[[432. 0. 1. 0. 0. 1. 0.]
[600. 1. 0. 0. 0. 0. 1.]
[375. 0. 0. 1. 1. 0. 0.]]
[‘area’, ‘height=10px’, ‘height=12px’, ‘height=25px’, ‘width=15px’,
‘width=36px’, ‘width=60px’]
多维数组(ndarray对象)中原有的字符串均被转成了数字0和一,我们称这样的列为布尔列。当本行的某一列存在相应的值(参看多维数组下方的列表),则该列的值为1,否则为零。
当数据量特别多的时候,很可能会产生很多的0。如果将0除去,用坐标表示非零数字的位置,就能得到对应的稀疏矩阵。
稀疏矩阵可以在不影响后续操作的情况下,将列表中的0除去,因此设计者在设计时将参数sparse的默认值设置为True。
2.是否排序(为了便于观察,使sparse=False)
排序(sort=True)
[[432. 0. 1. 0. 0. 1. 0.]
[600. 1. 0. 0. 0. 0. 1.]
[375. 0. 0. 1. 1. 0. 0.]]
[‘area’, ‘height=10px’, ‘height=12px’, ‘height=25px’, ‘width=15px’, ‘width=36px’, ‘width=60px’]
不排序(sort=False)
[[ 1. 1. 432. 0. 0. 0. 0.]
[ 0. 0. 600. 1. 1. 0. 0.]
[ 0. 0. 375. 0. 0. 1. 1.]]
[‘width=36px’, ‘height=12px’, ‘area’, ‘width=60px’, ‘height=10px’, ‘width=15px’, ‘height=25px’]
from sklearn.feature.text import CountVectorizer
文本特征提取即统计单词在文本中出现的次数。
# 此处不可为字符串,需要将字符串放在列表中。
data = ['God gives us evil at the same time, also gives us conquer evil weapons.']
# 对于CountVectorizer(),官方并没有提供sparse参数,但可以通过提取结果(result变量),也即稀疏矩阵对象的toarray()方法将稀疏矩阵对象转换为多维数组对象(ndarray)
parser = CountVectorizer()
result = parser.fit_transform(data)
# 返回每个单词的统计结果组成的多维数组对象(ndarray)
print(result.toarray())
# 返回一个列表对象,里面包含了与单词统计结果对应的单词。
print(parser.get_feature_names())
# 打印结果 ----->
# [[1 1 1 2 2 1 1 1 1 2 1]]
# ['also', 'at', 'conquer', 'evil', 'gives', 'god',
# 'same', 'the', 'time', 'us', 'weapons']
统计的原理是依据文本中出现的空格,将单词分离,然后分别计算每个单词出现的次数。这种方法仅适用于英文文本,中文文本则需要先经过分词处理,才能用该方法统计次数。
Python的免费中文分词库中,jieba比较成熟。我的另一篇博客有对该库的基础部分进行讲解,这里就不再赘述了。点击下方链接即可查看:
https://blog.csdn.net/qq_44879989/article/details/127400294
# 导入中文分词库jieba
import jieba
from sklearn.feature_extraction.text import CountVectorizer
data = '也是微云,也是微云过后月光明。只不见去年的游伴,只没有当日的心情。\
不愿勾起相思,不敢出门看月。偏偏月进窗来,害我相思一夜。'
# 进行中文分词处理,将返回一个包含词组(也包括符号)的列表
middle = jieba.cut(data)
parser = CountVectorizer()
result = parser.fit_transform(middle)
# print(result.toarray()) 最好不要这样做,数据量太多了,还是用稀疏矩阵比较好
print(result)
print(parser.get_feature_names())
# 打印结果 ----->
# (2, 10) 1
# (6, 10) 1
# (7, 15) 1
# (9, 5) 1
# (12, 3) 1
# (13, 8) 1
# (15, 13) 1
# (18, 12) 1
# (19, 9) 1
# (21, 11) 1
# (31, 1) 1
# (32, 7) 1
# (33, 14) 1
# (35, 2) 1
# (36, 6) 1
# (40, 4) 1
# (42, 16) 1
# (47, 14) 1
# (48, 0) 1
# ['一夜', '不愿', '不敢', '不见', '偏偏', '光明', '出门',
# '勾起', '去年', '当日', '微云', '心情', '没有', '游伴',
# '相思', '过后', '进窗']
TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。TF是词频(Term Frequency),IDF是逆文本频率指数(Inverse Document Frequency)。
字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
上述内容整理自百度百科
我们通常让我一个词语在一篇文章中出现的频率(词频)越高,就越能代表这篇文章。可这样会把文章中许多无统计意义的词(如我们,他们等)推向我们,于是TF-IDF出现了。
TF-IDF通过将词频(TF)与逆向文档频率(IDF)相乘来优化结果。
由上述公式可得到一个结论,即
字词的重要性随着它在文档中出现的次数成正比增加,但同时会随着它在语料库(由所有文档组成)中出现的频率成反比下降。
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
data = '月亮是那崇高而不可企及的梦想,六便士是为了生存而不得不赚取的卑微收入。\
有多少人只是胆怯的抬头望了一眼月光,又继续追逐赖以温饱的六便士'
middle = jieba.cut(data)
parser = TfidfVectorizer()
result = parser.fit_transform(middle)
print(result)
print(parser.get_feature_names())
# 打印结果 ------>
# (0, 11) 1.0
# (3, 8) 1.0
# (5, 1) 1.0
# (7, 13) 1.0
# (9, 4) 1.0
# (11, 3) 1.0
# (12, 15) 1.0
# (14, 2) 1.0
# (15, 19) 1.0
# (17, 5) 1.0
# (18, 10) 1.0
# (28, 7) 1.0
# (30, 6) 1.0
# (31, 17) 1.0
# (33, 9) 1.0
# (36, 0) 1.0
# (37, 12) 1.0
# (40, 16) 1.0
# (41, 20) 1.0
# (42, 18) 1.0
# (43, 14) 1.0
# (45, 4) 1.0
# ['一眼', '不可企及', '不得不', '为了', '六便士', '卑微',
# '只是', '多少', '崇高', '抬头', '收入', '月亮', '月光',
# '梦想', '温饱', '生存', '继续', '胆怯', '赖以', '赚取',
# '追逐']