机器学习-数据集划分和特征工程

一.数据集划分

API函数:

sklearn.model_selection.train_test_split(*arrays,**options)

参数:

  • arrays:多个数组,可以是列表,numpy数组,也可以是dataframe数据框等

  • options:(包含以下参数)

  • shuffle = True 默认随机抽取

  • random_state=x,随机数种子,x是哪个都行,就是固定随机抽取的规则,保证每次都一样

  • train_size=x,就是训练集的比例,默认是0.75,和test_size两者选一个就行

  • stratify,如果数据集是多分类,则需要指定,比如是二分类,则指定为y(分层划分,这个留到后面再讲)

可以传入多个数据集,返回train与test数据集

python 复制代码
# 进行API导入
from sklearn.model_selection  import train_test_split

# 随手创建两个数据集
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [10,20,30,40,50,60,70,80,90,100]

# 调用train_test_split函数,将数据集分为训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42, shuffle=True)

# 打印训练集和测试集
print(x_train, x_test, y_train, y_test)

6, 1, 8, 3, 10, 5, 4, 7\] \[9, 2\] \[60, 10, 80, 30, 100, 50, 40, 70\] \[90, 20

可以看到,两个数据集以完全相同的方式进行划分,在函数中都是用相同的下标进行抽取,使用的是相同的划分规则

而在日常工作中,我们一般都会像上面一样传入两个数据集,一个就是特征数据集 ,一个就是标签数据集。我们以鸢尾花为例:

python 复制代码
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

iris = load_iris()
# 获取特征
data = iris.data
# 获取标签
target = iris.target

# 进行划分
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.3, random_state=42)

print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)

(105, 4) (45, 4) (105,) (45,)

这里取出来的每一整条特征数据都完美对应自己的标签,这也为后续的模型训练奠定了基础。

二.特征工程

2.1 概念

就是对特征进行相关的处理

一般使用pandas 来进行数据清洗和数据处理、使用sklearn来进行特征工程

特征工程是将任意数据(如文本或图像)转换为可用于机器学习的数字特征,比如:字典特征提取(特征离散化)、文本特征提取、图像特征提取。

2.2 API

实例化转换器对象(transfer),转换器类有很多:

|-------------------|----------------------|
| DictVectorize | 字典特征提取 |
| CountVectorizer | 文本特征提取 |
| TfidfVectorizer | TF-IDF文本特征词的重要程度特征提取 |
| MinMaxScaler | 归一化 |
| StandardScaler | 标准化 |
| VarianceThreshold | 底方差过滤降维 |
| PCA | 主成分分析降维 |

转换器对象调用 **fit_transform()**进行特定转换, fit用于计算数据,transform进行最终转换。fit_transform()可以使用fit()和transform()代替:

python 复制代码
data_new = transfer.fit_transform(data)

可写成

python 复制代码
transfer.fit(data)

data_new = transfer.transform(data)

2.3 DictVectorizer 字典列表特征提取

讲之前先了解一个概念,稀疏矩阵:

稀疏矩阵是指一个矩阵中大部分元素为零,只有少数元素是非零的矩阵。由于稀疏矩阵中零元素非常多,存储和处理稀疏矩阵时,通常会采用特殊的存储格式三元组表,以节省内存空间并提高计算效率。

比如:

(0,0) 10

(0,1) 20

(2,0) 90

(2,20) 8

(8,0) 70

表示除了列出的索引位置有值, 其余全是0

同样也有非稀疏矩阵(稠密矩阵),与稀疏矩阵相反。

API:

sklearn.feature_extraction.DictVectorizer(sparse=True)

参数:

sparse:默认以稀疏矩阵表示,为True时返回稀疏矩阵,为False时返回稠密矩阵。

这个API会返回一个字典列表特征提取器对象,再通过前面的fit_transform方法,就可以将字典列表转换为稀疏矩阵或稠密矩阵。

python 复制代码
# 导入相关库
from sklearn.feature_extraction import DictVectorizer

# 创建一个简单的字典列表数据
data = [
    {'city': '北京', 'temperature': 10},
    {'city': '上海', 'temperature': 20},
    {'city': '广州', 'temperature': 30},
    {'city': '广州', 'temperature': 29}]

# 创建一个DictVectorizer对象
vec = DictVectorizer(sparse=False)

# 转换字典列表数据为特征矩阵
data_new = vec.fit_transform(data)

# 看看转换后的特征名称
print(vec.get_feature_names_out())

# 打印特征矩阵
print(data_new)

'city=上海' 'city=北京' 'city=广州' 'temperature'

\[ 0. 1. 0. 10.

1. 0. 0. 20.

0. 0. 1. 30.

0. 0. 1. 29.\]

可以看到原先的数据集中含有中文特殊字符,在进行转化时转换器就把每个包含中文的键值对当作一个特征名保存。而打印出的特征矩阵中,其中每一行每个数字对应的位置就是特征名列表中的位置,为1则代表是该特征,为0则代表不是该特征。

再来看看三元组的表示:

python 复制代码
# 创建一个DictVectorizer对象
vec = DictVectorizer(sparse=True)

# 转换字典列表数据为特征矩阵
data_new = vec.fit_transform(data)

# 看看转换后的特征名称
print(vec.get_feature_names_out())

# 打印特征矩阵
print(data_new)

'city=上海' 'city=北京' 'city=广州' 'temperature'

<Compressed Sparse Row sparse matrix of dtype 'float64'

with 8 stored elements and shape (4, 4)>

Coords Values

(0, 1) 1.0

(0, 3) 10.0

(1, 0) 1.0

(1, 3) 20.0

(2, 2) 1.0

(2, 3) 30.0

(3, 2) 1.0

(3, 3) 29.0

三元组(稀疏矩阵)显示的就是除了0以外的所有数值的索引,也就可以根据索引可以还原之前的特征矩阵。

2.4 CountVectorizer 文本特征提取

API:

sklearn.feature_extraction.text.CountVectorizer()

参数:

  • stop_words : 又叫黑名单,其中存储的是停用词即不会被提取的词,值类型为list
python 复制代码
# 导入相关库
from sklearn.feature_extraction.text import CountVectorizer

# 创建一个简单的英文句子
data = ["I love machine learning.", "I love coding.", "I love both"]

# 创建一个CountVectorizer对象
cv = CountVectorizer(stop_words=["machine", "learning", "coding"])
# 转换句子为词频矩阵
data_new1 = cv.fit_transform(data)
# 查看特征名
print(cv.get_feature_names_out())
# 查看词频矩阵(三元组)
print(data_new1)
# 转化为特征矩阵
print(data_new1.toarray())

'both' 'love'

<Compressed Sparse Row sparse matrix of dtype 'int64'

with 4 stored elements and shape (3, 2)>

Coords Values

(0, 1) 1

(1, 1) 1

(2, 1) 1

(2, 0) 1

\[0 1

0 1

1 1\]

可以看到,其将每个英文单词提取出来作为特征,矩阵中的数字就是出现的次数(频率)。我们也可以不提取某些词,而且这个函数内部也隐式地去掉了一些特殊字符。

但,我们一般用的都是中文,而这又是特殊字符,能正常使用吗?

python 复制代码
# 导入相关库
from sklearn.feature_extraction.text import CountVectorizer

# 创建一个简单的中文句子
data = ["第一个句子","第二个句子"]

# 创建一个CountVectorizer对象
cv = CountVectorizer()
# 转换句子为词频矩阵
data_new1 = cv.fit_transform(data)
# 查看特征名
print(cv.get_feature_names_out())
# 查看词频矩阵(三元组)
print(data_new1)
# 转化为特征矩阵
print(data_new1.toarray())

'第一个句子' '第二个句子'

<Compressed Sparse Row sparse matrix of dtype 'int64'

with 2 stored elements and shape (2, 2)>

Coords Values

(0, 0) 1

(1, 1) 1

\[1 0

0 1\]

很明显,这个地方有大问题,由于英文单词天生就用空格 分隔,所以可以直接提取。但中文有自己的分词规则,我们需要用其他分词工具进行分词,比如jieba

使用下面的命令进行下载:

pip install jieba

python 复制代码
# 导入
from sklearn.feature_extraction.text import CountVectorizer
import jieba

data = "第一个句子"

# 用jieba分词,返回一个可迭代对象
data = jieba.cut(data)
data = list(data)
print(data)

# 再将分词结果转换为字符串
data = " ".join(data)
print(data)

# 用CountVectorizer进行特征提取
vec = CountVectorizer()
data_new = vec.fit_transform([data])

print(vec.get_feature_names_out())
print(data_new.toarray())

'第一个', '句子'

第一个 句子

'句子' '第一个'

\[1 1\]

python 复制代码
# 进行多个句子的提取
from sklearn.feature_extraction.text import CountVectorizer
import jieba

data = ["第一个句子","第二个句子"]

# 写一个函数完成分词和转化字符串
def cut_words(str):
    return " ".join(list(jieba.cut(str)))

# 给data里的句子分词
data = [cut_words(i) for i in data]

# 用CountVectorizer进行特征提取
vec = CountVectorizer()
data_new = vec.fit_transform(data)

# 打印特征提取后的结果
print(vec.get_feature_names_out())
print(data_new.toarray())

'句子' '第一个' '第二个'

\[1 1 0

1 0 1\]

2.5 TfidfVectorizer TF-IDF文本特征词的重要程度特征提取

词频(Term Frequency, TF), 表示一个词在当前篇文章中的重要性

逆文档频率(Inverse Document Frequency, IDF), 反映了词在整个文档集合中的稀有程度

API:

sklearn.feature_extraction.text.TfidfVectorizer()

参数:

  • stop_words:表示词特征黑名单

使用示例:

python 复制代码
# 导入相关库
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba

# 自定义数据集
data = ["第一个句子","第二个句子"]
def cut_words(str):
    return " ".join(list(jieba.cut(str)))

# 给data里的句子分词
data = [cut_words(i) for i in data]

# 创建TF-IDF向量化器
tool = TfidfVectorizer()

# 拟合并转换数据集
data_new = tool.fit_transform(data)

# 输出结果
print(tool.get_feature_names_out())
print(data_new.toarray())

Building prefix dict from the default dictionary ...

Loading model from cache C:\Users\Clocky7\AppData\Local\Temp\jieba.cache

Loading model cost 0.529 seconds.

Prefix dict has been built successfully.

'句子' '第一个' '第二个'

\[0.57973867 0.81480247 0.

0.57973867 0. 0.81480247\]

可以看到,有几个句子(文档)就有几个列表,其中的数据表明对应词语在当前文档中的重要程度

扩展:

在sklearn库中 TF-IDF算法做了一些细节的优化:

  • TfidfVectorizer 中,TF 默认是:直接使用一个词在文档中出现的次数也就是CountVectorizer的结果

  • TfidfVectorizer 中,IDF 的默认计算公式是:

  • 而且机器学习中还会进行归一化(L2归一化)处理

下面是手动实现TF-IDF算法的代码:

python 复制代码
# 手动实现tfidf向量(跟上面的api实现出一样的效果)
import numpy as  np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.preprocessing import normalize
import jieba

data = ["第一个句子","第二个句子"]
def cut_words(str):
    return " ".join(list(jieba.cut(str)))

data = [cut_words(i) for i in data]

def tfidf(x):
    cv = CountVectorizer()
    # 获取词频
    tf = cv.fit_transform(x).toarray()
    # 计算idf
    idf = np.log((len(tf)+1)/(np.sum(tf!=0,axis=0)+1))+1
    tfidf = tf*idf
    # 归一化
    tfidf = normalize(tfidf, norm='l2', axis=1)
    return tfidf

data_new = tfidf(data)
print(data_new)

\[0.57973867 0.81480247 0.

0.57973867 0. 0.81480247\]

相关推荐
lisw052 小时前
6G频段与5G频段有何不同?
人工智能·机器学习
2501_941623323 小时前
人工智能赋能智慧农业互联网应用:智能种植、农业数据分析与产量优化实践探索》
大数据·人工智能
不爱吃糖的程序媛3 小时前
华为 CANN:昇腾 AI 的异构计算架构核心与开源生态解析
人工智能·华为·架构
AKAMAI4 小时前
从客户端自适应码率流媒体迁移到服务端自适应码率流媒体
人工智能·云计算
jinxinyuuuus4 小时前
GTA 风格 AI 生成器:跨IP融合中的“视觉语义冲突”与风格适配损失
人工智能·网络协议
如何原谅奋力过但无声4 小时前
TensorFlow 1.x常用函数总结(持续更新)
人工智能·python·tensorflow
翔云 OCR API4 小时前
人脸识别API开发者对接代码示例
开发语言·人工智能·python·计算机视觉·ocr
咚咚王者4 小时前
人工智能之数据分析 numpy:第十三章 工具衔接与迁移
人工智能·数据分析·numpy
咚咚王者4 小时前
人工智能之数据分析 numpy:第九章 数组运算(二)
人工智能·数据分析·numpy
YangYang9YangYan4 小时前
网络安全专业职业能力认证发展路径指南
大数据·人工智能·安全·web安全