机器学习与特征提取(初级)---scikit-learn

机器学习与特征提取---scikit-learn

  • 关系
  • 数据集提供站点
  • 数据集的使用
    • scikit-learn的安装
    • scikit-learn的导入
    • 数据集的使用
  • 数据集的划分
  • 特征工程
    • 字典特征提取
      • 模块导入
      • 主逻辑
    • 文本特征提取
      • 导入模块
      • 主逻辑(英语等通过空格分开词组的语言)
      • 主逻辑(中文等语言)
    • TF-IDF
      • 相关公式
      • 导入模块
      • 主逻辑

关系

机器学习是人工智能的主要分支,深度学习又是机器学习的主要分支。
机器学习与特征提取(初级)---scikit-learn_第1张图片


图片来源于网络

数据集提供站点

Kaggle数据集: https://www.kaggle.com/datasets
UCI数据集: https://archive.ics.uci.edu/ml/index.php

数据集的使用

可以从数据集提供站点中获取数据集,也可以使用Python的机器学习库(sciket-learn)获取本地或网络上的数据集。

scikit-learn的安装

pip install scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple

scikit-learn的导入

导入scikit-learn将使用另一个名字sklearn,若要使用它提供的数据集,则必须(类似)这样导入。

from sklearn.datasets import load_iris

其中:

load_iris

  1. iris是需要使用的数据集,你也可以使用其他的数据集,只需要将iris改成你需要用的数据集的名字即可。
  2. iris是一个关于鸢尾花的数据集
  3. load是指定从本地获取数据集(规模较小,随scikit-learn一并安装到计算机),将load改为fetch,则是从网上下载指定的数据集(规模较大)。
  4. fetch_xxx(data_home=None, subset=‘train’)
    data_home指定数据集的安装路径。
    subset则指定安装的数据集的类别,有适用于训练,测试以及包含训练和测试的训练集,分别对应的参数值为train,test,all。

数据集的使用

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创建的多维数组)。
因此:

  1. 可以通过 data.键的名称 获取自己需要的数据
    下面介绍一下数据集中各个键对应的值的大致内容
data 特征值列表
target 目标值列表
target_names 目标值名称,即每个目标值的具体含义
feature_names 特征值名称,即每个特征值的具体含义
DESCR 数据集的描述信息,DESCR 是单次description的简写
  1. 由于部分值是一个ndarry对象,所以可以使用该对象的部分属性及方法,比如通过其shape属性获得多维数组的形状(维度)。

数据集的划分

获取数据集后,不能将数据集全部用于训练,必须留一部分用于模型评估。由于训练集数据量越多,训练后得到的模型就越是精确,因而训练集的占比往往远大于测试集。训练集的占比范围(通常):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等)作为参数值。
我们来对比一下(改变参数值后,主逻辑打印的结果有何不同):

  1. 是否返回稀疏矩阵

返回稀疏数组(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

TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。TF是词频(Term Frequency),IDF是逆文本频率指数(Inverse Document Frequency)。
字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。


上述内容整理自百度百科

我们通常让我一个词语在一篇文章中出现的频率(词频)越高,就越能代表这篇文章。可这样会把文章中许多无统计意义的词(如我们,他们等)推向我们,于是TF-IDF出现了。
TF-IDF通过将词频(TF)与逆向文档频率(IDF)相乘来优化结果。

相关公式

  1. 词频
    TF = n / N
    其中n指词组在某个文档中出现的频率,而N则指词组在所有文档中出现的频率。
  2. 逆向文档频率
    IDF =log10 (D / d)
    其中D指总的文档数,d指词组所在的文档数。

由上述公式可得到一个结论,即
字词的重要性随着它在文档中出现的次数成正比增加,但同时会随着它在语料库(由所有文档组成)中出现的频率成反比下降。

导入模块

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
# ['一眼', '不可企及', '不得不', '为了', '六便士', '卑微', 
# '只是', '多少', '崇高', '抬头', '收入', '月亮', '月光',
# '梦想', '温饱', '生存', '继续', '胆怯', '赖以', '赚取', 
# '追逐']

你可能感兴趣的:(机器学习,Python,机器学习,scikit-learn,python,人工智能)