机器学习的核心

利用算法从数据中自动学习模式,并用这个模式对新数据进行预测或决策。

一个典型的机器学习过程包含三个关键要素:

  1. 数据:学习的“教材”,例子越多、质量越高,学得越好。

  2. 模型:从数据中学习的“算法”,像是一个待填充参数的数学公式。

  3. 学习/训练:模型通过不断调整内部参数,来减少预测错误的过程。

数据来源

数据不要自己爬,清洗工作很耗费时间

常用的数据集的组成

结构:特征值+目标值(有些没有目标值)

特征工程

特征工程是将原始数据转换为更好地代表预测模型的潜在问题的特征的过程,从而提高了模型对未知数据预测的准确性

Scikit-learn库

windows在命令行执行:(也可以在虚拟环境里面执行)
pip install -U scikit-learn

数据的特征处理

数据的特征处理是什么?
        特征处理是指将原始数据转换成适合机器学习模型使用的数值形式的一系列操作。
        因为大多数算法只能理解数字,不能直接处理文本、类别、缺失值或不同量纲的数据,所以特征处理是任何机器学习项目中最基础也最关键的步骤之一。

特征处理包括哪些内容?

通常分为几大类:

1. 特征提取(Feature Extraction)
        从原始数据中构造新的、更有信息量的特征。

  • 文本 → 词频向量(CountVectorizer、TfidfVectorizer)
  • 字典 → 数值矩阵(DictVectorizer)
  • 图像 → 像素值或HOG特征
  • 日期 → 拆出年、月、日、星期几

2. 特征变换(Feature Transformation)
        改变特征的分布或表现形式。

  • 标准化:减去均值,除以标准差 → 均值为0,方差为1
  • 归一化:缩放到 [0,1] 区间
  • 对数变换:将长尾分布拉近正态
  • 离散化:将连续值分箱(如年龄→青年/中年/老年)

3. 特征编码(Feature Encoding)
        将类别型数据转为数值。

  • One‑Hot 编码(DictVectorizer、pd.get_dummies)
  • 标签编码(Label Encoding)
  • 计数编码(Count Encoding)

4. 特征选择(Feature Selection)
        从众多特征中挑出最有用的一部分。

  • 过滤法(方差、相关系数)
  • 包裹法(递归特征消除)
  • 嵌入法(L1正则化、树模型特征重要性)

5. 特征降维(Dimensionality Reduction)
        在保留信息的前提下减少特征数量。

  • PCA(主成分分析)
  • t‑SNE(可视化用)

6. 缺失值处理

  • 删除含缺失值的行/列
  • 填充(均值、中位数、众数、前向填充、模型预测)

一、特征提取

从原始数据中构造新的、更有信息量的特征。

  • 文本 → 词频向量(CountVectorizer、TfidfVectorizer)
  • 字典 → 数值矩阵(DictVectorizer)
  • 图像 → 像素值或HOG特征
  • 日期 → 拆出年、月、日、星期几

1、字典特征抽取:DictVectorizer

作用:对字典数据进行特征值化

DictVectorizer 是 scikit-learn 中一个非常实用的特征提取工具,它的作用是将由字典(或键值对)组成的列表转换为机器学习模型可以直接使用的数值型特征矩阵。它尤其适合处理类别特征不规则数据

dic=DictVectorizer(sparse=True,…) #实例化,默认返回稀疏矩阵

  • dic.fit_transform(X)       #  X:字典或者包含字典的迭代器 返回值:返回稀疏矩阵(节约内存)
  • dic.inverse_transform(X)  #  X:array数组或者sparse矩阵 返回值:转换之前数据格式
  • dic.get_feature_names_out()  #返回类别名称
  • dic.transform(X)--用于测试集 按照原先的标准转换
from sklearn.feature_extraction import DictVectorizer

data = [
    {"city": "Beijing", "age": 25, "salary": 5000},
    {"city": "Shanghai", "age": 30, "salary": 6000},
    {"city": "Beijing", "age": 22, "salary": 4800},
    {"city": "Guangzhou", "age": 28, "salary": 5500}
]

# sparse=False 返回稠密矩阵,one-hot编码;(机器只能学习这个)
# 默认 sparse=True 返回稀疏矩阵(存储的时候节省内存,后面有方法可以转换为one-hot编码)
vec = DictVectorizer(sparse=False)
X = vec.fit_transform(data)
print("特征名称:", vec.get_feature_names_out(X))
print("\n特征矩阵:\n", X)
print(vec.inverse_transform(X))  #去看每个特征代表的含义,逆转回去

输出:

特征名称: ['age' 'city=Beijing' 'city=Guangzhou' 'city=Shanghai' 'salary']

特征矩阵:
 [[2.5e+01 1.0e+00 0.0e+00 0.0e+00 5.0e+03]
 [3.0e+01 0.0e+00 0.0e+00 1.0e+00 6.0e+03]
 [2.2e+01 1.0e+00 0.0e+00 0.0e+00 4.8e+03]
 [2.8e+01 0.0e+00 1.0e+00 0.0e+00 5.5e+03]]

[{'age': 25.0, 'city=Beijing': 1.0, 'salary': 5000.0}, {'age': 30.0, 'city=Shanghai': 1.0, 'salary': 6000.0}, {'age': 22.0, 'city=Beijing': 1.0, 'salary': 4800.0}, {'age': 28.0, 'city=Guangzhou': 1.0, 'salary': 5500.0}]

2.5e+01 是科学计数法 表示2.5*10^{1}

2、文本特征抽取:CountVectorizer

vec=CountVectorizer(max_df=1.0,min_df=1,…) # 实例化CountVectorizer,返回词频矩阵
                        # max_df, min_df是整数:指词频数小于等于min_df的不要,大于max_df的不要
                        # max_df, min_df小数(0-1之间的):表示的是频率

  • vec.fit_transform(X,y)        #X:文本或者包含文本字符串的可迭代对象 返回值:返回稀疏矩阵(节省内存)
  • vec.inverse_transform(X)  #X:array数组或者sparse矩阵 返回值:转换之前数据格式
  • vec.get_feature_names()  #返回值:单词列表
from sklearn.feature_extraction.text import CountVectorizer
vector = CountVectorizer(min_df=2)
res = vector.fit_transform(
    ["life is  short,i like python life",
     "life is too long,i dislike python",
     "life is short"])

print("特征名称:",vector.get_feature_names_out())
print("\n特征矩阵:\n",res)
print("特征矩阵类型:",type(res))
print("稀疏矩阵转换为数组",res.toarray())  
print(vector.inverse_transform(res))#拿每个样本里的特征进行显示
特征名称: ['is' 'life' 'python' 'short']

特征矩阵:
  (0, 1)    2 #第0个文本(中的第0个词)对应特征序列中的第1个词,出现的频率是2(这个文本的频率)
  (0, 0)    1 #第0个文本(中的第1个词)对应特征序列中的第0个词,出现的频率是1
  (0, 3)    1 #第0个文本(中的第2个词)对应特征序列中的第3个词,出现的频率是1
  (0, 2)    1
  (1, 1)    1 #第1个文本(中的第0个词)对应特征序列中的第1个词,出现的频率是1
  (1, 0)    1 #第1个文本(中的第2个词)对应特征序列中的第1个词,出现的频率是1
  (1, 2)    1
  (2, 1)    1
  (2, 0)    1
  (2, 3)    1
特征矩阵类型: <class 'scipy.sparse._csr.csr_matrix'>

稀疏矩阵转换为数组 :
[[1 2 1 1]
 [1 1 1 0]
 [1 1 0 1]]

#[1 2 1 1]表示第0个文本中['is' 'life' 'python' 'short']对应的频率是1 2 1 1 
 


[array(['life', 'is', 'short', 'python'], dtype='<U6'),

array(['life', 'is', 'python'], dtype='<U6'),

array(['life', 'is', 'short'], dtype='<U6')]

直接输出的特征矩阵是稠密矩阵

用.toarray()转换后的是稠密矩阵

中文的文本特征抽取:

要先分词,因为单词是用空格分开的,但中文里面没有空格,所以我们要用jeiba分词分开。

先pip install jieba

注意:jieba.cut(“我是一个好程序员”),返回的是一个生成器

import jieba
def cutword():
    """
    通过jieba对中文进行分词
    :return:
    """
    con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
    con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")
    con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")
    print("类型:",type(con1))
    # 把生成器转换成列表
    content1 = list(con1)
    content2 = list(con2)
    content3 = list(con3)
    print(content1)
    print(content2)
    print(content3)
    # 把列表转换成字符串,每个词之间用空格隔开
    print('-' * 50)
    c1 = ' '.join(content1)
    c2 = ' '.join(content2)
    c3 = ' '.join(content3)
    return c1, c2, c3


def hanzivec():
    """
    中文特征值化
    :return: None
    """
    c1, c2, c3 = cutword() #jieba分词好的中文文本
    print("jieba分词好的中文文本:")
    print(c1)
    print(c2)
    print(c3)
    cv = CountVectorizer()
    data = cv.fit_transform([c1, c2, c3])
    print("特征名称:",cv.get_feature_names_out())
    print("\n特征矩阵:\n",data)
    print(data.toarray())
    return None

# cutword()
hanzivec()

3、TfidfVectorizer

TF-IDF

TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高, 并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分 能力,适合用来分类。

TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。

Tf表示: term frequency词的频率出现的次数

IDF表示:  逆文档频率  =  \log_{10}(总文档数量/该词出现的文档数量)

TF*IDF :来代表重要性程度

什么是平滑处理?

平滑处理(Smoothing) 是一种用于修正概率或频次估计的技术,主要解决“零概率问题”——即某个事件在训练数据中没有出现,就被模型认为“不可能发生”,从而导致整体预测失效。

简单说:把原本为 0 的计数或概率,人为地加上一点小值,避免乘以 0 导致整个结果变成 0

本文平滑处理的目的:

         比如训练集中有某个词,测试集中没有,就是生僻词,就会造成分母为零

sklearn.feature_extraction.text.TfidfVectorizer

tf=TfidfVectorizer(stop_words=None,…) #返回词的权重矩阵

        tf.fit_transform(X)       X:文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵         tf.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式         tf.get_feature_names() 返回值:单词列表

from sklearn.feature_extraction.text import TfidfVectorizer

def tfidfvec():
    """
    中文特征值化,计算tfidf值
    :return: None
    """
    c1, c2, c3 = cutword()
    print("jieba分词好的中文文本:")
    print(c1, c2, c3)

    tf = TfidfVectorizer(smooth_idf=True)## smooth_idf布尔值,默认 = True
    data = tf.fit_transform([c1, c2, c3])

    print("特征名称:")
    print(tf.get_feature_names_out())
    print("特征类型:")
    print(type(data))
    print("特征矩阵:")
    print(data)
    print("特征矩阵转换成数组:")
    print(data.toarray())
    return None
类型: <class 'generator'>
['今天', '很', '残酷', ',', '明天', '更', '残酷', ',', '后天', '很', '美好', ',', '但', '绝对', '大部分', '是', '死', '在', '明天', '晚上', ',', '所以', '每个', '人', '不要', '放弃', '今天', '。']
['我们', '看到', '的', '从', '很', '远', '星系', '来', '的', '光是在', '几百万年', '之前', '发出', '的', ',', '这样', '当', '我们', '看到', '宇宙', '时', ',', '我们', '是', '在', '看', '它', '的', '过去', '。']
['如果', '只用', '一种', '方式', '了解', '某样', '事物', ',', '你', '就', '不会', '真正', '了解', '它', '。', '了解', '事物', '真正', '含义', '的', '秘密', '取决于', '如何', '将', '其', '与', '我们', '所', '了解', '的', '事物', '相', '联系', '。']
--------------------------------------------------
jieba分词好的中文文本:
今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。 我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。 如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。
特征名称:
['一种' '不会' '不要' '之前' '了解' '事物' '今天' '光是在' '几百万年' '发出' '取决于' '只用' '后天' '含义'
 '大部分' '如何' '如果' '宇宙' '我们' '所以' '放弃' '方式' '明天' '星系' '晚上' '某样' '残酷' '每个'
 '看到' '真正' '秘密' '绝对' '美好' '联系' '过去' '这样']
特征类型:
<class 'scipy.sparse._csr.csr_matrix'>
特征矩阵:
  (0, 20)	0.2182178902359924  第 0 篇文档,特征索引 20 的 TF‑IDF 值
  (0, 2)	0.2182178902359924
  (0, 27)	0.2182178902359924
  (0, 19)	0.2182178902359924
  (0, 24)	0.2182178902359924
  (0, 14)	0.2182178902359924
  (0, 31)	0.2182178902359924
  (0, 32)	0.2182178902359924
  (0, 12)	0.2182178902359924
  (0, 22)	0.4364357804719848
  (0, 26)	0.4364357804719848
  (0, 6)	0.4364357804719848
  (1, 34)	0.24108220270067757
  (1, 17)	0.24108220270067757
  (1, 35)	0.24108220270067757
  (1, 9)	0.24108220270067757
  (1, 3)	0.24108220270067757
  (1, 8)	0.24108220270067757
  (1, 7)	0.24108220270067757
  (1, 23)	0.24108220270067757
  (1, 28)	0.48216440540135513
  (1, 18)	0.5500476874707075
  (2, 33)	0.15698297076974738
  (2, 15)	0.15698297076974738
  (2, 10)	0.15698297076974738
  (2, 30)	0.15698297076974738
  (2, 13)	0.15698297076974738
  (2, 29)	0.31396594153949475
  (2, 1)	0.15698297076974738
  (2, 5)	0.47094891230924213
  (2, 25)	0.15698297076974738
  (2, 4)	0.6279318830789895
  (2, 21)	0.15698297076974738
  (2, 0)	0.15698297076974738
  (2, 11)	0.15698297076974738
  (2, 16)	0.15698297076974738
  (2, 18)	0.11938959557761185
特征矩阵转换成数组:
[[0.         0.         0.21821789 0.         0.         0.
  0.43643578 0.         0.         0.         0.         0.
  0.21821789 0.         0.21821789 0.         0.         0.
  0.         0.21821789 0.21821789 0.         0.43643578 0.
  0.21821789 0.         0.43643578 0.21821789 0.         0.
  0.         0.21821789 0.21821789 0.         0.         0.        ]
 [0.         0.         0.         0.2410822  0.         0.
  0.         0.2410822  0.2410822  0.2410822  0.         0.
  0.         0.         0.         0.         0.         0.2410822
  0.55004769 0.         0.         0.         0.         0.2410822
  0.         0.         0.         0.         0.48216441 0.
  0.         0.         0.         0.         0.2410822  0.2410822 ]
 [0.15698297 0.15698297 0.         0.         0.62793188 0.47094891
  0.         0.         0.         0.         0.15698297 0.15698297
  0.         0.15698297 0.         0.15698297 0.15698297 0.
  0.1193896  0.         0.         0.15698297 0.         0.
  0.         0.15698297 0.         0.         0.         0.31396594
  0.15698297 0.         0.         0.15698297 0.         0.        ]]

二、 特征变换

改变特征的分布或表现形式。
• 标准化:减去均值,除以标准差 → 均值为0,方差为1
• 归一化:缩放到 [0,1] 区间
• 对数变换:将长尾分布拉近正态
• 离散化:将连续值分箱(如年龄→青年/中年/老年)

1、归一化

特点:通过对原始数据进行变换把数据映射到(默认为[0,1])之间

如果不想映射到[0,1]之间,mx,mi分别为指定区间值

mm=MinMaxScalar(feature_range=(0,1)…) 每个特征缩放到给定范围(默认[0,1])

  •  mm.fit_transform(X)       X: NumPy 数组(或任何二维数组)其每行是一个样本,每列是一个特征。返回值:转换后的形状相同的array
from sklearn.preprocessing import MinMaxScaler
mm = MinMaxScaler(feature_range=(0, 1))
data = mm.fit_transform([[90, 2, 10, 40], [60, 4, 15, 45], [75, 3, 13, 46]])

print("归一化处理后数据为:")
print(data)
归一化处理后数据为:
[[1.         0.         0.         0.        ]
 [0.         1.         1.         0.83333333]
 [0.5        0.5        0.6        1.        ]]
fit_transform 和 transform 的区别(以归一化为例)

在 MinMaxScalerStandardScaler 等预处理类中:

  • fit_transform(X_train)用于训练集
    先根据训练数据计算参数(如最小值、最大值、均值、标准差),然后用这些参数直接转换训练数据

  • transform(X_test)用于测试集、验证集
    仅执行转换,不重新计算参数。使用已经在 fit 阶段得到的参数(最小值、最大值等)来转换新数据(如测试集、验证集)。

归一化的异常值
  • 归一化(MinMax)对异常值非常敏感,因为它只看最大值和最小值。
  • 推荐使用 RobustScaler(基于中位数和 IQR)来获得对异常值不敏感的缩放。
  • 更好的策略是:先可视化数据,了解是否存在异常值,再选择合适的预处理方法

2、标准化

将数据转换为均值为 0、标准差为 1 的分布。

注意!!!不是标准正态分布,只是均值为0,标准差为1的分布(分布与之前保持一致)

μ:特征列的均值
σ:特征列的标准差

结果:变换后的数据不再有原始单位,而是以“距离均值多少个标准差”来衡量。

std=StandardScaler(…) 处理之后每列来说所有数据都聚集在均值0附近方差为1

  • std.fit_transform(X,y)     NumPy 数组(或任何二维数组)其每行是一个样本,每列是一个特征。返回值:转换后的形状相同的array
  • std.mean_ 原始数据中每列特征的平均值
  • std.var_ 原始数据每列特征的方差
from sklearn.preprocessing import StandardScaler

std = StandardScaler()

data = std.fit_transform([[1., -1., 3.], [2., 4., 2.], [4., 6., -1.]])
print("归一化处理后数据为:")
print(data)
print("均值:")
print(std.mean_)#[2.33333333 3.         1.33333333]
print("方差:")
print(std.var_)#[1.55555556 8.66666667 2.88888889]
print("样本数:")
print(std.n_samples_seen_)  # 3
归一化处理后数据为:
[[-1.06904497 -1.35873244  0.98058068]
 [-0.26726124  0.33968311  0.39223227]
 [ 1.33630621  1.01904933 -1.37281295]]
  • 对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变

  • 对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对 于平均值的影响并不大,从而方差改变较小。在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。

三. 缺失值处理

删除含缺失值的行/列:如果每列或者行数据缺失值达到一定的比例,建议放弃整行或者整列


• 填充(均值、中位数、众数、前向填充、模型预测)

 im=SimpleImputer(missing_values=np.nan, strategy='mean') 完成缺失值插补

  • im.fit_transform(X,y)       X:NumPy 数组(或任何二维数组)其每行是一个样本,每列是一个特征。返回值:转换后的形状相同的array
import numpy as np
from sklearn.impute import SimpleImputer
# 缺失值为np.nan时,填充值为平均值
im = SimpleImputer(missing_values=np.nan, strategy='mean')
data = im.fit_transform([[1, 2], [np.nan, 3], [7, 6], [3, 2]])
print(data)
[[1.         2.        ]
 [3.66666667 3.        ]
 [7.         6.        ]
 [3.         2.        ]]

四. 特征选择(Feature Selection)

从众多特征中挑出最有用的一部分。

因为:

  • 冗余:部分特征的相关度高,容易消耗计算性能 两个特征:一个身高 cm,一个个子高矮类别: 没必要用两个
  • 噪声:部分特征对预测结果有负影响

方法:

• 过滤法(方差、相关系数)
• 包裹法(递归特征消除)
• 嵌入法(L1正则化、树模型特征重要性)

1.过滤法(方差、相关系数)

 VarianceThreshold(threshold = 0.0) 删除所有低方差特征

  • Variance.fit_transform(X,y)     X:NumPy 数组(或任何二维数组)其每行是一个样本,每列是一个特征。返回值:转换后的形状相同的array默认值是保留所有非零方差特征,即删除所有样本 中具有相同值的特征。
from sklearn.feature_selection import VarianceThreshold

#默认只删除方差为0,threshold是方差阈值,删除比这个值小的那些特征
var = VarianceThreshold(threshold=0.1)

data = var.fit_transform([[0, 2, 0, 3],
                          [0, 1, 4, 3],
                          [0, 1, 1, 3]])

print(data)
print('获得剩余的特征的列编号%s' % var.get_support(True))
[[2 0]
 [1 4]
 [1 1]]
获得剩余的特征的列编号[1 2]

2.包裹式(递归特征消除)

包裹式(Wrapper)特征选择方法是基于模型的性能来选择特征,它将特征选择看作是一个搜索问题,通过评估不同特征子集上模型的性能来选择最优的特征子集。常见的包裹式特征选择方法如下:

  • 递归特征消除(Recursive Feature Elimination,RFE)

原理:从包含所有特征的集合开始,递归地移除对模型性能贡献最小的特征。每次迭代都会训练一个模型,然后根据模型的系数或特征重要性(后面算法会涉及)等指标,确定要移除的特征,直到达到预设的特征数量或模型性能不再提升。

  • 顺序特征选择(Sequential Feature Selection, SFS):

这种方法通过逐步添加或移除特征来构建特征子集。常见的有前向选择(Sequential Forward Selection, SFS)和后向选择(Sequential Backward Selection, SBS)。前向选择从空集开始,逐步添加特征;后向选择从全集开始,逐步移除特征。

  • 遗传算法(Genetic Algorithm):

这是一种基于生物进化理论的优化算法,通过模拟自然选择的过程来选择特征子集。它通过交叉、变异等操作来生成新的特征子集,并根据模型性能来评估这些子集。 Las Vegas Wrapper(LVW):这种方法使用随机策略来进行特征子集的搜索,并以模型的误差作为特征子集的评价标准

3.嵌入法(L1正则化、树模型特征重要性)

 先了解

五. 特征降维(Dimensionality Reduction)

在保留信息的前提下减少特征数量。
• PCA(主成分分析)
• t‑SNE(可视化用)

1.PCA(主成分分析)

用原始特征的线性组合创建全新的特征,例如新特征1 = 0.5×年龄 + 0.3×身高 + 0.2×体重。这些新特征不再有直观的物理意义,但可以更紧凑地表示信息。

作用:可以削减回归分析或者聚类分析中特征的数量

特征数量达到上百的时候,开始使用PCA

PCA降维示例:虽然我们看不出来但是机器可以

pca的缺点:

PCA (Principal ComponentAnalysis,主成分分析)的结果可能会因为以下几个原因而不稳定:

  • 数据归一化的方式不同:对于PCA来说,数据的归一化可以采用标准化或者最大最小值归一化等方法。不同的归—化方式会导致不同的结果。
  • 特征值计算的精度:在特征值计算算精度也可能会影响结果的稳定 性。
  • 特征值相同时的特征向量计算:如征向量的计算就不唯一了,不同的计算方式也会导致结果不同。
  • 随机选择初始向量:在迭代计算特征向量的过程中,需要随机选择一个初始向量,这也可能会导致结果不稳定。

        为了提高结果的稳定性,可以采用多次运行PCA并取平均值的方法。另外,在进行PCA之前,可以对数据进行多次重复采样,然后对每次采样得到的数据进行PCA分析,以进一步提高结果的可靠性。

pca=PCA(n_components=None) :n_ components:为 0~1的小数:一般是90% 或90~95%   或  为整数时表示:减少到的特征数量

n_components = 0.95,意思是:

只用这 k 个主成分,就能描述原始数据中 95% 的变异性(信息),仅丢失 5% 的变异性。

那 5% 的丢失部分通常被认为是噪声或对整体结构影响很小的细微变化。

pca.fit_transform(X)     X:NumPy 数组(或任何二维数组)其每行是一个样本,每列是一个特征。返回值:转换后指定维度的array

from sklearn.decomposition import PCA

original_value = np.array([[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]])
print("最初数据的方差",np.var(original_value, axis=0).sum())  #最初数据的方差

pca = PCA(n_components=0.9)
data = pca.fit_transform(original_value)

print("pca之后的数据:",data)
print("pca之后的数据类型:",type(data))
print("pca之后的方差",np.var(data, axis=0).sum())
print("方差解释率:",pca.explained_variance_ratio_)
print("data的方差占总方差的比例",pca.explained_variance_ratio_.sum())
最初数据的方差 29.333333333333336
pca之后的数据: [[-3.13587302e-16  3.82970843e+00]
 [-5.74456265e+00 -1.91485422e+00]
 [ 5.74456265e+00 -1.91485422e+00]]
pca之后的数据类型: <class 'numpy.ndarray'>
pca之后的方差 29.333333333333346
[0.75 0.25]
data的方差占总方差的比例 1.0

六. 特征编码(Feature Encoding)

将类别型数据转为数值。
• One‑Hot 编码(DictVectorizer、pd.get_dummies)
• 标签编码(Label Encoding)
• 计数编码(Count Encoding)

有监督学习和无监督学习

监督学习:可以由输入数据中学到或建立一个模型,并依此模式推测新的结果。输入数据是由 输入特征值和目标值所组成。函数的输出可以是一个连续的值 (称为回归),或是输出是有限个离散值(称作分类)。

无监督学习:可以由输入数据中 学到或建立一个模型,并依此模式推测新的结果。输入数据是 由输入特征值所组成。

分类的应用:

分类在于根据其特性将数据“分门别类”,所以在许多领域都有广泛的应用 :

在银行业务中,构建一个客户分类模型,按客户按照贷款风险的大小进行分类

图像处理中,分类可以用来检测图像中是否有人脸出现,动物类别等

手写识别中,分类可以用于识别手写的数字

文本分类,这里的文本可以是新闻报道、网页、电子邮件、学术论文

回归的应用:

回归在多领域也有广泛的应用

房价预测,根据某地历史房价数据,进行一个预测

金融信息,每日股票走向

数据集的获取

from sklearn.datasets import ***
eg:from sklearn.datasets import load_iris, fetch_20newsgroups, fetch_california_housing

为什么用 Scikit-learn 自带数据集?

自己收集、清洗数据确实耗时,而且不一定具有代表性。
Scikit-learn 内置了多种经典数据集(如鸢尾花、手写数字、波士顿房价等),方便我们快速学习算法原型。

Scikit-learn 在 sklearn.datasets 模块中提供了两类加载函数:

函数前缀 说明 数据规模 是否需要网络
load_* 加载小规模数据集,数据已打包在库中 小(如 iris, digits)
fetch_* 下载大规模数据集,第一次需要联网 大(如 california housing, olivetti faces)

常用 load_* 数据集:
load_iris() – 鸢尾花(分类)

load_digits() – 手写数字(分类)

load_wine() – 葡萄酒(分类)

load_breast_cancer() – 乳腺癌(分类)

load_diabetes() – 糖尿病(回归)

常用 fetch_* 数据集:
fetch_california_housing() – 加州房价(回归)

fetch_olivetti_faces() – 人脸图像

fetch_20newsgroups() – 新闻文本

获取到的 数据集是<class 'sklearn.utils._bunch.Bunch'>类型

                “数据集.data”  是<class 'numpy.ndarray'>类型

ndarray常用的属性

         shape形状(行,列)

         size有多少个元素

        dtype数据类型

        itemsize元素字节数

Bunch(类似字典)常用的属性

data 特征数据 (n_samples, n_features) 的 numpy 数组
DESCR 数据集的详细描述 字符串
feature_names 每个特征的名称(列表) 回归/分类数据集通常有
target 标签(目标值) (n_samples,) 的一维数组
target_names 标签的名称(列表)

分类数据集有,回归数据集无

下载鸢尾花数据集:

from sklearn.datasets import load_iris
li = load_iris()

#鸢尾花数据集
from sklearn.datasets import load_iris
li = load_iris()
print(type(li)) #<class 'sklearn.utils._bunch.Bunch'>
print(type(li.data)) #<class 'numpy.ndarray'>
print("数据的形状",li.data.shape)  # (150, 4) 150个样本,4个特征
print("获取特征值",li.feature_names)
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
print("目标值",li.target)
print("数据集描述",li.DESCR) 
print("特征名字",li.feature_names) 
print("目标名",li.target_names)

下载自然语言处理(NLP)数据集:(比较大的数据)

from sklearn.datasets import fetch_20newsgroups

news = fetch_20newsgroups(subset='all', data_home='data')

#subset代表下载的数据集类型,默认是train,只有训练集

#data_home指定数据集的下载和缓存目录

  • 当你设置 data_home='data' 时,表示:在当前工作目录下(即运行 Python 脚本的文件夹),创建一个名为 data 的文件夹(如果不存在),并将 20newsgroups 数据集下载到该文件夹内。

  • 如果再次运行同样的代码,它会直接读取本地已下载的数据,不会重复下载

  •  如果不指定 data_home,数据会存放在:

                        Linux/macOS:~/scikit_learn_data

                        Windows:C:\Users\你的用户名\scikit_learn_data

from sklearn.datasets import fetch_20newsgroups
news = fetch_20newsgroups(subset='all', data_home='data')

# print(news.feature_names)  #这个数据集是没有的,因为没有特征,只有文本数据
# print(news.DESCR)
print('特征类型',type(news.data))
print('第一个样本',news.data[0])
print("前15个目标值",news.target[0:15])

news.target[0:15]  为  :[10 3 17 3 4 12 4 10 10 19 19 11 19 13 0]

,news.target_names 为  :['alt.atheism', 'comp.graphics', 'comp.os.ms-windows.misc', 'comp.sys.ibm.pc.hardware', 'comp.sys.mac.hardware', 'comp.windows.x', 'misc.forsale', 'rec.autos', 'rec.motorcycles', 'rec.sport.baseball', 'rec.sport.hockey', 'sci.crypt', 'sci.electronics', 'sci.med', 'sci.space', 'soc.religion.christian', 'talk.politics.guns', 'talk.politics.mideast', 'talk.politics.misc', 'talk.religion.misc']

上面的10指得就是这个特征值表里的第10个,0指第一个

测试集和训练集的划分

机器学习一般的数据集会划分为两个部分:
训练数据:用于训练,构建模型
测试数据:在模型检验时使用,用于评估模型是否有效

sklearn 数据集划分 

可以帮我们划分训练集和测试集,因为自己准备数据集,耗时耗力,不一定真实
sklearn.model_selection.train_test_split

train_test_split(*arrays, test_size=None, train_size=None, random_state=None, 
shuffle=True, stratify=None)
 
1. *arrays:要划分的数据
  • 通常传入 X(特征)和 y(标签),也可以传入多个数组(如 X, y, weights 等)。

  • 函数会按照相同的索引划分所有数组,保证特征和标签的对应关系不变。

2. test_size:测试集大小
  • 浮点数(0.0~1.0):表示测试集占总样本的比例,如 0.2 表示 20% 作为测试集。

  • 整数:表示测试集的绝对样本数量,如 50 表示取 50 个样本作为测试集。

  • 默认值:0.25(即 25% 作为测试集)。

3. train_size:训练集大小
  • 用法与 test_size 相同,通常只指定其中一个,另一个会自动计算。

  • 如果都不指定,默认 train_size = 0.75, test_size = 0.25

4. random_state:随机数种子
  • 作用:控制随机划分的确定性。

  • 设为整数(如 42:每次运行代码,划分结果完全相同(方便复现实验)。

  • 设为 None:每次划分结果不同(真正的随机)。

  • 常见做法:调试时固定一个种子(如 0 或 42),最终调优后再用不同种子验证稳定性。

5. shuffle:是否打乱数据
  • 默认 True:在划分前先随机打乱样本顺序(推荐)。

  • False:不打乱,按原始顺序取前 train_size 个作为训练集,后面作为测试集(适用于时序数据等有顺序依赖的情况)。

6. stratify:分层抽样
  • 默认 None:普通随机抽样。

  • 传入数组(通常是 y:按照标签的类别比例进行分层抽样,保证训练集和测试集中各类别比例与原始数据集一致(对于不平衡分类问题非常重要)。

x_train, x_test, y_train, y_test = train_test_split(li.data, li.target, test_size=0.25, random_state=1)

  •  random_state=1一定要设置一个值
  •  注意返回值, 训练集 train  x_train, y_train    测试集  test   x_test, y_test,顺序千万别搞错了

# 注意返回值, 训练集 train  x_train, y_train    测试集  test   x_test, y_test,顺序千万别搞错了
# 默认是乱序的,random_state为了确保两次的随机策略一致,就会得到相同的随机数据,往往会带上
x_train, x_test, y_train, y_test = train_test_split(li.data, li.target, test_size=0.25, random_state=1)

print("训练集特征值和目标值:", x_train, y_train)
print("训练集特征值shape", x_train.shape)
print('-'*50)
print("测试集特征值和目标值:", x_test, y_test)
print("测试集特征值shape", x_test.shape)

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐