机器学习(9)——特征工程(3)(补充)

目录

1 数据集

1.1 可用数据集

1.2 sklearn数据集

1.2.1 scikit-learn数据集API介绍

1.2.2 sklearn数据集的使用

1.2.3 数据集的划分

2 特征工程介绍

2.1 什么是特征工程

2.2 特征提取 

2.2.1 字典特征提取

2.2.2 文本特征提取

2.2.3 jieba分词处理

2.2.4 Tf-idf文本特征提取

 3 特征预处理

3.1 归一化

3.2 标准化

4 特征降维

4.1 特征选择

4.1.1 过滤式——低方差特征过滤

4.1.2 过滤式——相关系数

4.2 主成分分析


1 数据集

数据集可分为训练集和测试集。

1.1 可用数据集

Kaggle网址:Find Open Datasets and Machine Learning Projects | Kaggle

有关 Kaggle 注册时出现无法人机验证问题的解决可以参考该博文:

机器学习实训(2)——分类(补充)_WHJ226的博客-CSDN博客

UCI数据集网址: http://archive.ics.uci.edu/ml/

scikit-learn自带数据集

1.2 sklearn数据集

1.2.1 scikit-learn数据集API介绍

sklearn.datasets

  • 加载获取流行数据集
  • datasets.load_*()
    • 获取小规模数据集,数据包含在datasets里
    • sklearn.datasets.load_iris() 加载并返回鸢尾花数据集

    • sklearn.datasets.load_boston() 加载并返回波士顿房价数据集

  • datasets.fetch_*(data_home=None)
    • 获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是 ~/scikit_learn_data/
    • sklearn.datasets.fetch_houseprices(data_home=None,subset=‘train’)
    • subset:'train'或者'test','all',可选,选择要加载的数据集。
    • 训练集的“训练”,测试集的“测试”,两者的“全部”

1.2.2 sklearn数据集的使用

以鸢尾花数据集为例: 

sklearn数据集返回值介绍

  • load和fetch返回的数据类型datasets.base.Bunch(字典格式)
    • 1 data:特征数据数组,是 [n_samples * n_features] 的二维 numpy.ndarray 数组
    • 2 target:标签数组,是 n_samples 的一维 numpy.ndarray 数组
    • 3 DESCR:数据描述
    • 4 feature_names:特征名,新闻数据,手写数字、回归数据集没有
    • 5 target_names:标签名
    • 以上可以通过点属性获取:dict.key = values
from sklearn.datasets import load_iris

def datasets_demo():
    """
    sklearn数据采集用
    :return:
    """
    iris = load_iris()
    print("鸢尾花数据集: \n",iris)
    print("查看数据描述: \n", iris["DESCR"]) #通过键值对形式查看
    print("查看特征值的名字: \n", iris.feature_names) #通过点属性获取
    print("查看特征值及形状: \n", iris.data,iris.data.shape) #shape是属性不是方法,不用加括号

    return None

if __name__ == "__main__":
    #sklearn数据集使用
    datasets_demo()

运行结果如下:

鸢尾花数据集: 
 {'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. , 3.6, 1.4, 0.2],
       [5.4, 3.9, 1.7, 0.4],
       [4.6, 3.4, 1.4, 0.3],
       [5. , 3.4, 1.5, 0.2],
       [4.4, 2.9, 1.4, 0.2],
       [4.9, 3.1, 1.5, 0.1],
       [5.4, 3.7, 1.5, 0.2],
       [4.8, 3.4, 1.6, 0.2],
       [4.8, 3. , 1.4, 0.1],
       [4.3, 3. , 1.1, 0.1],
       [5.8, 4. , 1.2, 0.2],
       [5.7, 4.4, 1.5, 0.4],
       [5.4, 3.9, 1.3, 0.4],
       [5.1, 3.5, 1.4, 0.3],
       [5.7, 3.8, 1.7, 0.3],
       [5.1, 3.8, 1.5, 0.3],
       [5.4, 3.4, 1.7, 0.2],
       [5.1, 3.7, 1.5, 0.4],
       [4.6, 3.6, 1. , 0.2],
       [5.1, 3.3, 1.7, 0.5],
       [4.8, 3.4, 1.9, 0.2],
       [5. , 3. , 1.6, 0.2],
       [5. , 3.4, 1.6, 0.4],
       [5.2, 3.5, 1.5, 0.2],
       [5.2, 3.4, 1.4, 0.2],
       [4.7, 3.2, 1.6, 0.2],
       [4.8, 3.1, 1.6, 0.2],
       [5.4, 3.4, 1.5, 0.4],
       [5.2, 4.1, 1.5, 0.1],
       [5.5, 4.2, 1.4, 0.2],
       [4.9, 3.1, 1.5, 0.2],
       [5. , 3.2, 1.2, 0.2],
       [5.5, 3.5, 1.3, 0.2],
       [4.9, 3.6, 1.4, 0.1],
       [4.4, 3. , 1.3, 0.2],
       [5.1, 3.4, 1.5, 0.2],
       [5. , 3.5, 1.3, 0.3],
       [4.5, 2.3, 1.3, 0.3],
       [4.4, 3.2, 1.3, 0.2],
       [5. , 3.5, 1.6, 0.6],
       [5.1, 3.8, 1.9, 0.4],
       [4.8, 3. , 1.4, 0.3],
       [5.1, 3.8, 1.6, 0.2],
       [4.6, 3.2, 1.4, 0.2],
       [5.3, 3.7, 1.5, 0.2],
       [5. , 3.3, 1.4, 0.2],
       [7. , 3.2, 4.7, 1.4],
       [6.4, 3.2, 4.5, 1.5],
       [6.9, 3.1, 4.9, 1.5],
       [5.5, 2.3, 4. , 1.3],
       [6.5, 2.8, 4.6, 1.5],
       [5.7, 2.8, 4.5, 1.3],
       [6.3, 3.3, 4.7, 1.6],
       [4.9, 2.4, 3.3, 1. ],
       [6.6, 2.9, 4.6, 1.3],
       [5.2, 2.7, 3.9, 1.4],
       [5. , 2. , 3.5, 1. ],
       [5.9, 3. , 4.2, 1.5],
       [6. , 2.2, 4. , 1. ],
       [6.1, 2.9, 4.7, 1.4],
       [5.6, 2.9, 3.6, 1.3],
       [6.7, 3.1, 4.4, 1.4],
       [5.6, 3. , 4.5, 1.5],
       [5.8, 2.7, 4.1, 1. ],
       [6.2, 2.2, 4.5, 1.5],
       [5.6, 2.5, 3.9, 1.1],
       [5.9, 3.2, 4.8, 1.8],
       [6.1, 2.8, 4. , 1.3],
       [6.3, 2.5, 4.9, 1.5],
       [6.1, 2.8, 4.7, 1.2],
       [6.4, 2.9, 4.3, 1.3],
       [6.6, 3. , 4.4, 1.4],
       [6.8, 2.8, 4.8, 1.4],
       [6.7, 3. , 5. , 1.7],
       [6. , 2.9, 4.5, 1.5],
       [5.7, 2.6, 3.5, 1. ],
       [5.5, 2.4, 3.8, 1.1],
       [5.5, 2.4, 3.7, 1. ],
       [5.8, 2.7, 3.9, 1.2],
       [6. , 2.7, 5.1, 1.6],
       [5.4, 3. , 4.5, 1.5],
       [6. , 3.4, 4.5, 1.6],
       [6.7, 3.1, 4.7, 1.5],
       [6.3, 2.3, 4.4, 1.3],
       [5.6, 3. , 4.1, 1.3],
       [5.5, 2.5, 4. , 1.3],
       [5.5, 2.6, 4.4, 1.2],
       [6.1, 3. , 4.6, 1.4],
       [5.8, 2.6, 4. , 1.2],
       [5. , 2.3, 3.3, 1. ],
       [5.6, 2.7, 4.2, 1.3],
       [5.7, 3. , 4.2, 1.2],
       [5.7, 2.9, 4.2, 1.3],
       [6.2, 2.9, 4.3, 1.3],
       [5.1, 2.5, 3. , 1.1],
       [5.7, 2.8, 4.1, 1.3],
       [6.3, 3.3, 6. , 2.5],
       [5.8, 2.7, 5.1, 1.9],
       [7.1, 3. , 5.9, 2.1],
       [6.3, 2.9, 5.6, 1.8],
       [6.5, 3. , 5.8, 2.2],
       [7.6, 3. , 6.6, 2.1],
       [4.9, 2.5, 4.5, 1.7],
       [7.3, 2.9, 6.3, 1.8],
       [6.7, 2.5, 5.8, 1.8],
       [7.2, 3.6, 6.1, 2.5],
       [6.5, 3.2, 5.1, 2. ],
       [6.4, 2.7, 5.3, 1.9],
       [6.8, 3. , 5.5, 2.1],
       [5.7, 2.5, 5. , 2. ],
       [5.8, 2.8, 5.1, 2.4],
       [6.4, 3.2, 5.3, 2.3],
       [6.5, 3. , 5.5, 1.8],
       [7.7, 3.8, 6.7, 2.2],
       [7.7, 2.6, 6.9, 2.3],
       [6. , 2.2, 5. , 1.5],
       [6.9, 3.2, 5.7, 2.3],
       [5.6, 2.8, 4.9, 2. ],
       [7.7, 2.8, 6.7, 2. ],
       [6.3, 2.7, 4.9, 1.8],
       [6.7, 3.3, 5.7, 2.1],
       [7.2, 3.2, 6. , 1.8],
       [6.2, 2.8, 4.8, 1.8],
       [6.1, 3. , 4.9, 1.8],
       [6.4, 2.8, 5.6, 2.1],
       [7.2, 3. , 5.8, 1.6],
       [7.4, 2.8, 6.1, 1.9],
       [7.9, 3.8, 6.4, 2. ],
       [6.4, 2.8, 5.6, 2.2],
       [6.3, 2.8, 5.1, 1.5],
       [6.1, 2.6, 5.6, 1.4],
       [7.7, 3. , 6.1, 2.3],
       [6.3, 3.4, 5.6, 2.4],
       [6.4, 3.1, 5.5, 1.8],
       [6. , 3. , 4.8, 1.8],
       [6.9, 3.1, 5.4, 2.1],
       [6.7, 3.1, 5.6, 2.4],
       [6.9, 3.1, 5.1, 2.3],
       [5.8, 2.7, 5.1, 1.9],
       [6.8, 3.2, 5.9, 2.3],
       [6.7, 3.3, 5.7, 2.5],
       [6.7, 3. , 5.2, 2.3],
       [6.3, 2.5, 5. , 1.9],
       [6.5, 3. , 5.2, 2. ],
       [6.2, 3.4, 5.4, 2.3],
       [5.9, 3. , 5.1, 1.8]]), 'target': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), 'frame': None, 'target_names': array(['setosa', 'versicolor', 'virginica'], dtype='

1.2.3 数据集的划分

机器学习一般的数据集会划分为两个部分:

  • 训练数据:用于训练,构建模型
  • 测试数据:在模型检验时使用,用于评估模型是否有效

划分比例:

  • 训练集:70% 80% 75%
  • 测试集:30% 20% 30%

数据集划分api

  • sklearn.model_selection.train_test_split(arrays, *options)
    • x 数据集的特征值
    • y 数据集的标签值
    • test_size 测试集的大小,一般为float
    • random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
    • return 测试集特征训练集特征值值,训练标签,测试标签(默认随机取)
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

def datasets_demo():
    """
    sklearn数据采集用
    :return:
    """
    # 1、获取鸢尾花数据集
    iris = load_iris()
    print("鸢尾花数据集的返回值:\n", iris)
    # 返回值是一个继承自字典的Bench
    print("鸢尾花的特征值:\n", iris["data"])
    print("鸢尾花的目标值:\n", iris.target)
    print("鸢尾花特征的名字:\n", iris.feature_names)
    print("鸢尾花目标值的名字:\n", iris.target_names)
    print("鸢尾花的描述:\n", iris.DESCR)

    # 2、对鸢尾花数据集进行分割
    # 训练集的特征值x_train 测试集的特征值x_test 训练集的目标值y_train 测试集的目标值y_test
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
    print("x_train:\n", x_train.shape)
    # 随机数种子
    x_train1, x_test1, y_train1, y_test1 = train_test_split(iris.data, iris.target, random_state=6)
    x_train2, x_test2, y_train2, y_test2 = train_test_split(iris.data, iris.target, random_state=6)
    print("如果随机数种子不一致:\n", x_train == x_train1)
    print("如果随机数种子一致:\n", x_train1 == x_train2)

    return None

if __name__ == "__main__":
    #sklearn数据集使用
    datasets_demo()

运行结果如下:

鸢尾花数据集的返回值:
 {'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. , 3.6, 1.4, 0.2],
       [5.4, 3.9, 1.7, 0.4],
       [4.6, 3.4, 1.4, 0.3],
       [5. , 3.4, 1.5, 0.2],
       [4.4, 2.9, 1.4, 0.2],
       [4.9, 3.1, 1.5, 0.1],
       [5.4, 3.7, 1.5, 0.2],
       [4.8, 3.4, 1.6, 0.2],
       [4.8, 3. , 1.4, 0.1],
       [4.3, 3. , 1.1, 0.1],
       [5.8, 4. , 1.2, 0.2],
       [5.7, 4.4, 1.5, 0.4],
       [5.4, 3.9, 1.3, 0.4],
       [5.1, 3.5, 1.4, 0.3],
       [5.7, 3.8, 1.7, 0.3],
       [5.1, 3.8, 1.5, 0.3],
       [5.4, 3.4, 1.7, 0.2],
       [5.1, 3.7, 1.5, 0.4],
       [4.6, 3.6, 1. , 0.2],
       [5.1, 3.3, 1.7, 0.5],
       [4.8, 3.4, 1.9, 0.2],
       [5. , 3. , 1.6, 0.2],
       [5. , 3.4, 1.6, 0.4],
       [5.2, 3.5, 1.5, 0.2],
       [5.2, 3.4, 1.4, 0.2],
       [4.7, 3.2, 1.6, 0.2],
       [4.8, 3.1, 1.6, 0.2],
       [5.4, 3.4, 1.5, 0.4],
       [5.2, 4.1, 1.5, 0.1],
       [5.5, 4.2, 1.4, 0.2],
       [4.9, 3.1, 1.5, 0.2],
       [5. , 3.2, 1.2, 0.2],
       [5.5, 3.5, 1.3, 0.2],
       [4.9, 3.6, 1.4, 0.1],
       [4.4, 3. , 1.3, 0.2],
       [5.1, 3.4, 1.5, 0.2],
       [5. , 3.5, 1.3, 0.3],
       [4.5, 2.3, 1.3, 0.3],
       [4.4, 3.2, 1.3, 0.2],
       [5. , 3.5, 1.6, 0.6],
       [5.1, 3.8, 1.9, 0.4],
       [4.8, 3. , 1.4, 0.3],
       [5.1, 3.8, 1.6, 0.2],
       [4.6, 3.2, 1.4, 0.2],
       [5.3, 3.7, 1.5, 0.2],
       [5. , 3.3, 1.4, 0.2],
       [7. , 3.2, 4.7, 1.4],
       [6.4, 3.2, 4.5, 1.5],
       [6.9, 3.1, 4.9, 1.5],
       [5.5, 2.3, 4. , 1.3],
       [6.5, 2.8, 4.6, 1.5],
       [5.7, 2.8, 4.5, 1.3],
       [6.3, 3.3, 4.7, 1.6],
       [4.9, 2.4, 3.3, 1. ],
       [6.6, 2.9, 4.6, 1.3],
       [5.2, 2.7, 3.9, 1.4],
       [5. , 2. , 3.5, 1. ],
       [5.9, 3. , 4.2, 1.5],
       [6. , 2.2, 4. , 1. ],
       [6.1, 2.9, 4.7, 1.4],
       [5.6, 2.9, 3.6, 1.3],
       [6.7, 3.1, 4.4, 1.4],
       [5.6, 3. , 4.5, 1.5],
       [5.8, 2.7, 4.1, 1. ],
       [6.2, 2.2, 4.5, 1.5],
       [5.6, 2.5, 3.9, 1.1],
       [5.9, 3.2, 4.8, 1.8],
       [6.1, 2.8, 4. , 1.3],
       [6.3, 2.5, 4.9, 1.5],
       [6.1, 2.8, 4.7, 1.2],
       [6.4, 2.9, 4.3, 1.3],
       [6.6, 3. , 4.4, 1.4],
       [6.8, 2.8, 4.8, 1.4],
       [6.7, 3. , 5. , 1.7],
       [6. , 2.9, 4.5, 1.5],
       [5.7, 2.6, 3.5, 1. ],
       [5.5, 2.4, 3.8, 1.1],
       [5.5, 2.4, 3.7, 1. ],
       [5.8, 2.7, 3.9, 1.2],
       [6. , 2.7, 5.1, 1.6],
       [5.4, 3. , 4.5, 1.5],
       [6. , 3.4, 4.5, 1.6],
       [6.7, 3.1, 4.7, 1.5],
       [6.3, 2.3, 4.4, 1.3],
       [5.6, 3. , 4.1, 1.3],
       [5.5, 2.5, 4. , 1.3],
       [5.5, 2.6, 4.4, 1.2],
       [6.1, 3. , 4.6, 1.4],
       [5.8, 2.6, 4. , 1.2],
       [5. , 2.3, 3.3, 1. ],
       [5.6, 2.7, 4.2, 1.3],
       [5.7, 3. , 4.2, 1.2],
       [5.7, 2.9, 4.2, 1.3],
       [6.2, 2.9, 4.3, 1.3],
       [5.1, 2.5, 3. , 1.1],
       [5.7, 2.8, 4.1, 1.3],
       [6.3, 3.3, 6. , 2.5],
       [5.8, 2.7, 5.1, 1.9],
       [7.1, 3. , 5.9, 2.1],
       [6.3, 2.9, 5.6, 1.8],
       [6.5, 3. , 5.8, 2.2],
       [7.6, 3. , 6.6, 2.1],
       [4.9, 2.5, 4.5, 1.7],
       [7.3, 2.9, 6.3, 1.8],
       [6.7, 2.5, 5.8, 1.8],
       [7.2, 3.6, 6.1, 2.5],
       [6.5, 3.2, 5.1, 2. ],
       [6.4, 2.7, 5.3, 1.9],
       [6.8, 3. , 5.5, 2.1],
       [5.7, 2.5, 5. , 2. ],
       [5.8, 2.8, 5.1, 2.4],
       [6.4, 3.2, 5.3, 2.3],
       [6.5, 3. , 5.5, 1.8],
       [7.7, 3.8, 6.7, 2.2],
       [7.7, 2.6, 6.9, 2.3],
       [6. , 2.2, 5. , 1.5],
       [6.9, 3.2, 5.7, 2.3],
       [5.6, 2.8, 4.9, 2. ],
       [7.7, 2.8, 6.7, 2. ],
       [6.3, 2.7, 4.9, 1.8],
       [6.7, 3.3, 5.7, 2.1],
       [7.2, 3.2, 6. , 1.8],
       [6.2, 2.8, 4.8, 1.8],
       [6.1, 3. , 4.9, 1.8],
       [6.4, 2.8, 5.6, 2.1],
       [7.2, 3. , 5.8, 1.6],
       [7.4, 2.8, 6.1, 1.9],
       [7.9, 3.8, 6.4, 2. ],
       [6.4, 2.8, 5.6, 2.2],
       [6.3, 2.8, 5.1, 1.5],
       [6.1, 2.6, 5.6, 1.4],
       [7.7, 3. , 6.1, 2.3],
       [6.3, 3.4, 5.6, 2.4],
       [6.4, 3.1, 5.5, 1.8],
       [6. , 3. , 4.8, 1.8],
       [6.9, 3.1, 5.4, 2.1],
       [6.7, 3.1, 5.6, 2.4],
       [6.9, 3.1, 5.1, 2.3],
       [5.8, 2.7, 5.1, 1.9],
       [6.8, 3.2, 5.9, 2.3],
       [6.7, 3.3, 5.7, 2.5],
       [6.7, 3. , 5.2, 2.3],
       [6.3, 2.5, 5. , 1.9],
       [6.5, 3. , 5.2, 2. ],
       [6.2, 3.4, 5.4, 2.3],
       [5.9, 3. , 5.1, 1.8]]), 'target': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), 'frame': None, 'target_names': array(['setosa', 'versicolor', 'virginica'], dtype='

2 特征工程介绍

数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。

2.1 什么是特征工程

特征工程是使用专业背景知识和技巧处理数据使得特征能在机器学习算法上发挥更好的作用的过程

  • 意义:会直接影响机器学习的效果

特征工程包含内容

  • 特征提取
  • 特征预处理
  • 特征降维

2.2 特征提取 

将任意数据(如文本或图像)转换为可用于机器学习的数字特征

特征值化是为了计算机更好的去理解数据

2.2.1 字典特征提取

作用:对字典数据进行特征值化,将类别转换为one-hot编码

应用场景:

1.数据集当中类别特征比较多,将数据集的特征转换为字典类型,DictVectorizer转换

2.本身拿到的数据就是字典类型

  • sklearn.feature_extraction.DictVectorizer(sparse=True,…)
    • DictVectorizer.fit_transform(X) X:字典或者包含字典的迭代器返回值:返回sparse矩阵
    • DictVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式
    • DictVectorizer.get_feature_names_out() 返回类别名称

例如:对下面数据进行特征提取

[{'city': '北京','temperature':100}
{'city': '上海','temperature':60}
{'city': '深圳','temperature':30}]

流程分析:

  • 实例化类DictVectorizer
  • 调用fit_transform方法输入数据并转换(注意返回格式)
from sklearn.feature_extraction import DictVectorizer

def dict_demo():
    """
    对字典类型的数据进行特征抽取
    :return: None
    """
    data = [{'city': '北京','temperature':100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature':30}]
    # 1、实例化一个转换器类
    transfer = DictVectorizer(sparse=False) #默认sparse=True返回为稀疏矩阵,只按位置显示非零值
    # 2、调用fit_transform
    data = transfer.fit_transform(data)
    print("返回的结果:\n", data)
    # 打印特征名字
    print("特征名字:\n", transfer.get_feature_names_out())

    return None

if __name__ == '__main__':
    #代码2:字典特征提取
    dict_demo()

运行结果如下:

返回的结果:
 [[  0.   1.   0. 100.]
 [  1.   0.   0.  60.]
 [  0.   0.   1.  30.]]
特征名字:
 ['city=上海' 'city=北京' 'city=深圳' 'temperature']

当没有加上sparse=False参数时的结果如下:

返回的结果:
   (0, 1)	1.0
  (0, 3)	100.0
  (1, 0)	1.0
  (1, 3)	60.0
  (2, 2)	1.0
  (2, 3)	30.0
特征名字:
 ['city=上海' 'city=北京' 'city=深圳' 'temperature']

加上sparse=False参数时的数据处理效果类似于”one-hot“编码,对于特征当中存在类别信息的我们都会做one-hot编码处理。

2.2.2 文本特征提取

对文本数据进行特征值化

  • sklearn.feature_extraction.text.CountVectorizer(stop_words=[]),返回词频矩阵

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

例如:对下面数据进行特征提取 

["life is short,i like python",
"life is too long,i dislike python"]

流程分析:

  • 实例化类CountVectorizer
  • 调用fit_transform方法输入数据并转换 (注意返回格式,利用toarray()进行sparse矩阵转换array数组)
from sklearn.feature_extraction.text import CountVectorizer

def text_count_demo():
    """
    对文本进行特征抽取,countvetorizer
    :return: None
    """
    data = ["life is short,i like like python", "life is too long,i dislike python"]
    # 1、实例化一个转换器类
    # transfer = CountVectorizer(sparse=False)
    transfer = CountVectorizer()
    # 2、调用fit_transform
    data = transfer.fit_transform(data)
    print("文本特征抽取的结果:\n", data.toarray())
    print("返回特征名字:\n", transfer.get_feature_names_out())

    return None

if __name__ == '__main__':
    #代码3:文本进行特征抽取
    text_count_demo()

运行结果如下:

文本特征抽取的结果:
 [[0 1 1 2 0 1 1 0]
 [1 1 1 0 1 1 0 1]]
返回特征名字:
 ['dislike' 'is' 'life' 'like' 'long' 'python' 'short' 'too']

那么,我们拿到的是中文数据的话该怎么处理呢?

例如,我们把数据换成以下内容后运行:

"人生苦短,我喜欢Python","生活太长久,我不喜欢Python"

运行结果如下:

文本特征抽取的结果:
 [[1 0 1 0]
 [0 1 0 1]]
返回特征名字:
 ['人生苦短' '我不喜欢python' '我喜欢python' '生活太长久']

为什么会得到这样的结果呢,仔细分析之后会发现英文默认是以空格分开的。其实就达到了一个分词的效果,所以我们要对中文进行分词处理。

2.2.3 jieba分词处理

jieba.cut(),返回词语组成的生成器

对下面中文数据进行特征值化:

"一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"

  • 流程分析:
    • 准备句子,利用jieba.cut进行分词
    • 实例化CountVectorizer
    • 将分词结果变成字符串当作fit_transform的输入值

首先,构造分词函数。

import jieba
def cut_word(text):
    """
    进行中文分词,效果如:"我是好人"-->"我 是 好人"
    :param text:
    :return:
    """
    # print(jieba.cut(text))
    # a = list(jieba.cut(text)) #方式1
    # a = " ".join(list(jieba.cut(text))) #" ".join:将['我', '是', '好人']列表转换为"我 是 好人"的字符串类型,强转为列表后再转为字符串 #方式2
    # print(a)

    text = " ".join(list(jieba.cut(text))) #方式3
    print(text)

    return text

if __name__ == "__main__":
    cut_word("我是好人")

 运行结果如下:

我 是 好人

最后,进行特征值化:

from sklearn.feature_extraction.text import CountVectorizer
import jieba

def cut_word(text):
    """
    对中文进行分词
    进行中文分词,效果如:"我是好人"-->"我 是 好人"
    :param text:
    :return: text
    """
    # 用结巴对中文字符串进行分词
    text = " ".join(list(jieba.cut(text)))

    return text

def text_chinese_count_demo2():
    """
    对中文进行特征抽取
    :return: None
    """
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    # 将原始数据转换成分好词的形式
    text_list = []
    for sent in data:
        text_list.append(cut_word(sent))
    print(text_list)

    # 1、实例化一个转换器类
    # transfer = CountVectorizer(sparse=False)
    transfer = CountVectorizer() #stop_words=[]停用词
    # 2、调用fit_transform
    data = transfer.fit_transform(text_list)
    print("文本特征抽取的结果:\n", data.toarray()) # toarray()与sparse=False类似
    print("返回特征名字:\n", transfer.get_feature_names_out())

    return None

if __name__ == '__main__':
    #代码4:中文文本特征提取
    text_chinese_count_demo2()

运行结果如下:

['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']
文本特征抽取的结果:
 [[2 0 1 0 0 0 2 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 2 0 1 0 2 1 0 0 0 1 1 0 0 1
  0]
 [0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 1 0
  1]
 [1 1 0 0 4 3 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 2 1 0 0 1 0 0
  0]]
返回特征名字:
 ['一种' '不会' '不要' '之前' '了解' '事物' '今天' '光是在' '几百万年' '发出' '取决于' '只用' '后天' '含义'
 '大部分' '如何' '如果' '宇宙' '我们' '所以' '放弃' '方式' '明天' '星系' '晚上' '某样' '残酷' '每个'
 '看到' '真正' '秘密' '绝对' '美好' '联系' '过去' '还是' '这样']

那么如何处理某个词或短语在多篇文章中出现的次数高这种情况,下面接着学习。

2.2.4 Tf-idf文本特征提取

  • TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
  • TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
  • 词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率
  • 逆向文档频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到

 最终得出结果可以理解为重要程度。

注1:
假如一篇文件的总词语数是100个,而词语"非常"出现了5次,那么"非常"一词在该文件中的词频就是5/100=0.05。而计算文件频率(IDF)的方法是以文件集的文件总数,除以出现"非常"一词的文件数。所以,如果"非常"一词在1,000份文件出现过,而文件总数是10,000,000份的话,其逆向文件频率就是lg(10,000,000 / 1,0000)=3。最后"非常"对于这篇文档的tf-idf的分数为0.05 * 3=0.15

注2:
两个词语:“经济”,“非常”
1000篇文章-语料库 #总文件数目
100篇文章-“非常” #包含“非常”的文件数
10篇文章-“经济” #包含“经济”的文件数

两篇文章中:
文章A(100词):10次“经济”   
    tf:10/100=0.1 #词频,某一个给定的词语在该文件中出现的频率
    idf:log 10 1000/10 = 2  #逆向文档频率,一个词语普遍重要性的度量,由总文件数目除以包含该词语之文件的数目,再将得到的商除以10为底的对数得到
    TF_IDF=0.2 #TF_IDF=tf*idf
文章B(100词):10次“非常” 
    tf:10/100=0.1 #词频,某一个给定的词语在该文件中出现的频率
    idf:log 10 1000/100 = 1  #逆向文档频率,一个词语普遍重要性的度量,由总文件数目除以包含该词语之文件的数目,再将得到的商除以10为底的对数得到
    TF_IDF=0.1

例如:

from sklearn.feature_extraction.text import TfidfVectorizer
import jieba

def cut_word(text):
    """
    进行中文分词,效果如:"我是好人"-->"我 是 好人"
    :param text:
    :return:
    """
    return " ".join(list(jieba.cut(text)))

def text_chinese_tfidf_demo():
    """
    对中文进行特征抽取
    :return: None
    """
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    # 将原始数据转换成分好词的形式
    text_list = []
    for sent in data:
        text_list.append(cut_word(sent))
    print(text_list)

    # 1、实例化一个转换器类
    # transfer = CountVectorizer(sparse=False)
    transfer = TfidfVectorizer(stop_words=['一种', '不会', '不要'])
    # 2、调用fit_transform
    data = transfer.fit_transform(text_list)
    print("文本特征抽取的结果:\n", data.toarray())
    print("返回特征名字:\n", transfer.get_feature_names_out())

    return None

if __name__ == '__main__':
    #代码3:文本特征提取
    text_chinese_tfidf_demo()

运行结果如下:

['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']

文本特征抽取的结果:
 [[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.21821789 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.         0.2410822 ]
 [0.         0.644003   0.48300225 0.         0.         0.
  0.         0.16100075 0.16100075 0.         0.16100075 0.
  0.16100075 0.16100075 0.         0.12244522 0.         0.
  0.16100075 0.         0.         0.         0.16100075 0.
  0.         0.         0.3220015  0.16100075 0.         0.
  0.16100075 0.         0.         0.        ]]
返回特征名字:
 ['之前' '了解' '事物' '今天' '光是在' '几百万年' '发出' '取决于' '只用' '后天' '含义' '大部分' '如何'
 '如果' '宇宙' '我们' '所以' '放弃' '方式' '明天' '星系' '晚上' '某样' '残酷' '每个' '看到' '真正'
 '秘密' '绝对' '美好' '联系' '过去' '还是' '这样']

 3 特征预处理

通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程。

数值型数据的无量纲化:

  • 归一化(MinMaxScaler)
  • 标准化

为什么我们要进行归一化/标准化?

  • 特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级容易影响(支配)目标结果,使得一些算法无法学习到其它的特征。
  • 我们需要用到一些方法进行无量纲化使不同规格的数据转换到同一规格。

3.1 归一化

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

公式:

机器学习(9)——特征工程(3)(补充)_第1张图片

作用于每一列,max为一列的最大值,min为一列的最小值,那么X’’为最终结果,mx,mi分别为指定区间值默认mx为1,mi为0

下面我们给出一个例子:

机器学习(9)——特征工程(3)(补充)_第2张图片

 sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)… )

  • MinMaxScalar.fit_transform(X)
    • X:numpy array格式的数据[n_samples,n_features]
  • 返回值:转换后的形状相同的array

例如,我们利用以下数据进行运算,可以看到“milage,Liters,Consumtime”这3个特征值相差很大,但是在我们看来,他们是同等重要的特征,因此需要进行归一化处理。首先,将以下内容保存到dating.txt文件中。

milage,Liters,Consumtime,target
40920,8.326976,0.953952,3
14488,7.153469,1.673904,2
26052,1.441871,0.805124,1
75136,13.147394,0.428964,1
38344,1.669788,0.134296,1

流程分析:

1、实例化MinMaxScalar

2、通过fit_transform转换

from sklearn.preprocessing import MinMaxScaler
import pandas as pd
def minmax_demo():
    """
    归一化
    :return:
    """
    #1、获取数据
    data = pd.read_csv('dating.txt') #当前路径下的dating.txt文件
    data = data.iloc[:,:3]#只选择前3列进行归一化
    print("data:\n",data)
    # 2、实例化一个转换器类
    transfer = MinMaxScaler(feature_range=[2,3])#归一化到(2,3)区间内
    # 3、调用fit_transform
    data_new = transfer.fit_transform(data)
    print("data_new:\n",data_new)
    return None

    # data = pd.read_csv("dating.txt")
    # print(data)
    # # 1、实例化一个转换器类
    # transfer = MinMaxScaler(feature_range=(2, 3))
    # # 2、调用fit_transform
    # data = transfer.fit_transform(data[['milage','Liters','Consumtime']])
    # print("最小值最大值归一化处理的结果:\n", data)
    # 
    # return None

if __name__ == "__main__":
    #归一化
    minmax_demo()

 运行结果如下:

data:
    milage     Liters  Consumtime
0   40920   8.326976    0.953952
1   14488   7.153469    1.673904
2   26052   1.441871    0.805124
3   75136  13.147394    0.428964
4   38344   1.669788    0.134296
data_new:
 [[2.43582641 2.58819286 2.53237967]
 [2.         2.48794044 3.        ]
 [2.19067405 2.         2.43571351]
 [3.         3.         2.19139157]
 [2.3933518  2.01947089 2.        ]]

#    milage     Liters  Consumtime  target
# 0   40920   8.326976    0.953952       3
# 1   14488   7.153469    1.673904       2
# 2   26052   1.441871    0.805124       1
# 3   75136  13.147394    0.428964       1
# 4   38344   1.669788    0.134296       1
# 最小值最大值归一化处理的结果:
#  [[2.43582641 2.58819286 2.53237967]
#  [2.         2.48794044 3.        ]
#  [2.19067405 2.         2.43571351]
#  [3.         3.         2.19139157]
#  [2.3933518  2.01947089 2.        ]]

但是,注意最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性较差,只适合传统精确小数据场景。

3.2 标准化

定义:通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内。

公式:

机器学习(9)——特征工程(3)(补充)_第3张图片

作用于每一列,mean为平均值,σ为标准差。

对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变

对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小。

sklearn.preprocessing.StandardScaler( )

  • 处理之后每列所有数据都聚集在均值0附近,标准差为1
  • StandardScaler.fit_transform(X)
    • X:numpy array格式的数据[n_samples,n_features]
  • 返回值:转换后的形状相同的array

同样对上面dating.txt的数据进行处理。

流程分析:

1、实例化StandardScaler

2、通过fit_transform转换

from sklearn.preprocessing import StandardScaler
import pandas as pd
def stand_demo():
    """
    标准化
    :return:
    """
    #1、获取数据
    data = pd.read_csv('dating.txt')
    data = data.iloc[:,:3]#只选择前3列
    print("data:\n",data)
    # 2、实例化一个转换器类
    transfer = StandardScaler()
    # 3、调用fit_transform
    data_new = transfer.fit_transform(data)
    print("data_new:\n",data_new)
    return None
    
    # data = pd.read_csv("dating.txt")
    # print(data)
    # # 1、实例化一个转换器类
    # transfer = StandardScaler()
    # # 2、调用fit_transform
    # data = transfer.fit_transform(data[['milage', 'Liters', 'Consumtime']])
    # print("标准化的结果:\n", data)
    # print("每一列特征的平均值:\n", transfer.mean_)
    # print("每一列特征的方差:\n", transfer.var_)

    # return None


if __name__ == "__main__":
    #标准化
    stand_demo()

运行结果如下:

data:
    milage     Liters  Consumtime
0   40920   8.326976    0.953952
1   14488   7.153469    1.673904
2   26052   1.441871    0.805124
3   75136  13.147394    0.428964
4   38344   1.669788    0.134296
data_new:
 [[ 0.0947602   0.44990013  0.29573441]
 [-1.20166916  0.18312874  1.67200507]
 [-0.63448132 -1.11527928  0.01123265]
 [ 1.77297701  1.54571769 -0.70784025]
 [-0.03158673 -1.06346729 -1.27113187]]


#    milage     Liters  Consumtime  target
# 0   40920   8.326976    0.953952       3
# 1   14488   7.153469    1.673904       2
# 2   26052   1.441871    0.805124       1
# 3   75136  13.147394    0.428964       1
# 4   38344   1.669788    0.134296       1
# 标准化的结果:
#  [[ 0.0947602   0.44990013  0.29573441]
#  [-1.20166916  0.18312874  1.67200507]
#  [-0.63448132 -1.11527928  0.01123265]
#  [ 1.77297701  1.54571769 -0.70784025]
#  [-0.03158673 -1.06346729 -1.27113187]]
# 每一列特征的平均值:
#  [3.8988000e+04 6.3478996e+00 7.9924800e-01]
# 每一列特征的方差:
#  [4.15683072e+08 1.93505309e+01 2.73652475e-01]

因此,在已有样本足够多的情况下比较稳定,标准化适合现代嘈杂(噪声)大数据场景。

4 特征降维

猿创征文|机器学习实战(9)——降维_WHJ226的博客-CSDN博客

降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程。

维数:嵌套的层数

0维:标量

1维:向量

2维:矩阵

而我们现在降维的对象:二维数组

此处降维是指降低特征的个数(列数),得到一组“不相关”主变量的过程。正是因为在进行训练的时候,我们都是使用特征进行学习。如果特征本身存在问题或者特征之间相关性较强,对于算法学习预测会影响较大。

降维的两种方式:

  • 特征选择
  • 主成分分析(可以理解一种特征提取的方式)

4.1 特征选择

定义:

数据中包含冗余或无关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征。 

方法:

  • Filter(过滤式):主要探究特征本身特点、特征与特征和目标值之间关联
    • 方差选择法:低方差特征过滤
    • 相关系数
  • Embedded (嵌入式):算法自动选择特征(特征与目标值之间的关联)
    • 决策树:信息熵、信息增益
    • 正则化:L1、L2
    • 深度学习:卷积等

运用sklearn.feature_selection模块。

4.1.1 过滤式——低方差特征过滤

删除低方差的一些特征。

  • 特征方差小:某个特征大多样本的值比较相近
  • 特征方差大:某个特征很多样本的值都有差别

sklearn.feature_selection.VarianceThreshold(threshold = 0.0)

  • 删除所有低方差特征
  • Variance.fit_transform(X)
    • X:numpy array格式的数据[n_samples,n_features]
    • 返回值:训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征,即删除所有样本中具有相同值的特征。

下面我们利用某些股票的指标特征之间进行一个筛选, 并将这些数据保存在factor_returns.csv文件中,内容如下:

index,pe_ratio,pb_ratio,market_cap,return_on_asset_net_profit,du_return_on_equity,ev,earnings_per_share,revenue,total_expense,date,return
0,000001.XSHE,5.9572,1.1818,85252550922.0,0.8008,14.9403,1211444855670.0,2.01,20701401000.0,10882540000.0,2012-01-31,0.027657228229937388
1,000002.XSHE,7.0289,1.588,84113358168.0,1.6463,7.8656,300252061695.0,0.326,29308369223.2,23783476901.2,2012-01-31,0.08235182370820669
2,000008.XSHE,-262.7461,7.0003,517045520.0,-0.5678,-0.5943,770517752.56,-0.006,11679829.03,12030080.04,2012-01-31,0.09978900335112327
3,000060.XSHE,16.476,3.7146,19680455995.0,5.6036,14.617,28009159184.6,0.35,9189386877.65,7935542726.05,2012-01-31,0.12159482758620697
4,000069.XSHE,12.5878,2.5616,41727214853.0,2.8729,10.9097,81247380359.0,0.271,8951453490.28,7091397989.13,2012-01-31,-0.0026808154146886697

流程分析:

1、初始化VarianceThreshold,指定阀值方差

2、调用fit_transform

from sklearn.feature_selection import VarianceThreshold
import pandas as pd
def variance_demo():
    """
    过滤低方差特征
    :return:
    """
    #1、获取数据
    data = pd.read_csv('factor_returns.csv')
    data = data.iloc[:,1:-2]
    print('data:\n',data)

    # 2、实例化一个转换器类
    transfer = VarianceThreshold(threshold=0)#低于threshold的特征将被删除。默认是保留所有非零方差特征,即删除所有样本中具有相同值的特征,可更改threshold的值
    # 3、调用fit_transform
    data_new = transfer.fit_transform(data)
    print("删除低方差特征的结果:\n", data_new)
    print("形状:\n", data_new.shape)
    return None

if __name__ == "__main__":
    #低方差特征过滤
    variance_demo()

运行结果如下:

data:
    pe_ratio  pb_ratio  ...       revenue  total_expense
0    5.9572    1.1818  ...  2.070140e+10   1.088254e+10
1    7.0289    1.5880  ...  2.930837e+10   2.378348e+10
2 -262.7461    7.0003  ...  1.167983e+07   1.203008e+07
3   16.4760    3.7146  ...  9.189387e+09   7.935543e+09
4   12.5878    2.5616  ...  8.951453e+09   7.091398e+09

[5 rows x 9 columns]
删除低方差特征的结果:
 [[ 5.95720000e+00  1.18180000e+00  8.52525509e+10  8.00800000e-01
   1.49403000e+01  1.21144486e+12  2.01000000e+00  2.07014010e+10
   1.08825400e+10]
 [ 7.02890000e+00  1.58800000e+00  8.41133582e+10  1.64630000e+00
   7.86560000e+00  3.00252062e+11  3.26000000e-01  2.93083692e+10
   2.37834769e+10]
 [-2.62746100e+02  7.00030000e+00  5.17045520e+08 -5.67800000e-01
  -5.94300000e-01  7.70517753e+08 -6.00000000e-03  1.16798290e+07
   1.20300800e+07]
 [ 1.64760000e+01  3.71460000e+00  1.96804560e+10  5.60360000e+00
   1.46170000e+01  2.80091592e+10  3.50000000e-01  9.18938688e+09
   7.93554273e+09]
 [ 1.25878000e+01  2.56160000e+00  4.17272149e+10  2.87290000e+00
   1.09097000e+01  8.12473804e+10  2.71000000e-01  8.95145349e+09
   7.09139799e+09]]
形状:
 (5, 9)

4.1.2 过滤式——相关系数

皮尔逊相关系数(Pearson Correlation Coefficient),是反映变量之间相关关系密切程度的统计指标。

公式:

机器学习(9)——特征工程(3)(补充)_第4张图片

特点:

相关系数的值介于–1与+1之间,即–1≤ r ≤+1。其性质如下:

  • 当r>0时,表示两变量正相关,r<0时,两变量为负相关
  • 当|r|=1时,表示两变量为完全相关,当r=0时,表示两变量间无相关关系
  • 当0<|r|<1时,表示两变量存在一定程度的相关。且|r|越接近1,两变量间线性关系越密切;|r|越接近于0,表示两变量的线性相关越弱
  • 一般可按三级划分:|r|<0.4为低度相关;0.4≤|r|<0.7为显著性相关;0.7≤|r|<1为高度线性相关

例如:

import pandas as pd
from scipy.stats import pearsonr
data = pd.read_csv('factor_returns.csv')
data = data.iloc[:,1:-2]
#计算某两个变量之间的相关系数
r1 = pearsonr(data['pe_ratio'], data['pb_ratio'])[0]
r2 = pearsonr(data['revenue'], data['total_expense'])[0]
print("相关系数:",r1)
print("相关系数:",r2)

运行结果如下:

相关系数: -0.8930295775032194
相关系数: 0.9571876379112001

我们还可以通过for循环来实现:

import pandas as pd
from scipy.stats import pearsonr

def pearsonr_demo():
    """
    相关系数计算
    :return: None
    """
    data = pd.read_csv("factor_returns.csv")

    factor = ['pe_ratio', 'pb_ratio', 'market_cap', 'return_on_asset_net_profit', 'du_return_on_equity', 'ev',
              'earnings_per_share', 'revenue', 'total_expense']

    for i in range(len(factor)):
        for j in range(i, len(factor) - 1):
            print(
                "指标%s与指标%s之间的相关性大小为%f" % (factor[i], factor[j + 1], pearsonr(data[factor[i]], data[factor[j + 1]])[0]))

    return None
if __name__ == "__main__":
    pearsonr_demo()

运行结果如下:

指标pe_ratio与指标pb_ratio之间的相关性大小为-0.893030
指标pe_ratio与指标market_cap之间的相关性大小为0.646984
指标pe_ratio与指标return_on_asset_net_profit之间的相关性大小为0.656608
指标pe_ratio与指标du_return_on_equity之间的相关性大小为0.894059
指标pe_ratio与指标ev之间的相关性大小为0.329688
指标pe_ratio与指标earnings_per_share之间的相关性大小为0.393708
指标pe_ratio与指标revenue之间的相关性大小为0.643567
指标pe_ratio与指标total_expense之间的相关性大小为0.620577
指标pb_ratio与指标market_cap之间的相关性大小为-0.914568
指标pb_ratio与指标return_on_asset_net_profit之间的相关性大小为-0.250734
指标pb_ratio与指标du_return_on_equity之间的相关性大小为-0.756304
指标pb_ratio与指标ev之间的相关性大小为-0.625996
指标pb_ratio与指标earnings_per_share之间的相关性大小为-0.614458
指标pb_ratio与指标revenue之间的相关性大小为-0.848839
指标pb_ratio与指标total_expense之间的相关性大小为-0.752483
指标market_cap与指标return_on_asset_net_profit之间的相关性大小为-0.119383
指标market_cap与指标du_return_on_equity之间的相关性大小为0.485129
指标market_cap与指标ev之间的相关性大小为0.741861
指标market_cap与指标earnings_per_share之间的相关性大小为0.656701
指标market_cap与指标revenue之间的相关性大小为0.938999
指标market_cap与指标total_expense之间的相关性大小为0.817129
指标return_on_asset_net_profit与指标du_return_on_equity之间的相关性大小为0.664950
指标return_on_asset_net_profit与指标ev之间的相关性大小为-0.315526
指标return_on_asset_net_profit与指标earnings_per_share之间的相关性大小为-0.162061
指标return_on_asset_net_profit与指标revenue之间的相关性大小为0.008009
指标return_on_asset_net_profit与指标total_expense之间的相关性大小为0.119778
指标du_return_on_equity与指标ev之间的相关性大小为0.482977
指标du_return_on_equity与指标earnings_per_share之间的相关性大小为0.608145
指标du_return_on_equity与指标revenue之间的相关性大小为0.415312
指标du_return_on_equity与指标total_expense之间的相关性大小为0.308510
指标ev与指标earnings_per_share之间的相关性大小为0.977886
指标ev与指标revenue之间的相关性大小为0.547199
指标ev与指标total_expense之间的相关性大小为0.281761
指标earnings_per_share与指标revenue之间的相关性大小为0.449533
指标earnings_per_share与指标total_expense之间的相关性大小为0.177715
指标revenue与指标total_expense之间的相关性大小为0.957188

我们还可以通过散点图来观察,下面以前两个为例:

  • 指标pe_ratio与指标pb_ratio之间的相关性大小为-0.893030
  • 指标pe_ratio与指标market_cap之间的相关性大小为0.646984
import matplotlib.pyplot as plt
import pandas as pd

data = pd.read_csv("factor_returns.csv")
plt.figure(figsize=(20, 8), dpi=100)
plt.scatter(data['pe_ratio'], data['pb_ratio'])
plt.show()

 运行结果如下:

机器学习(9)——特征工程(3)(补充)_第5张图片

由于数据较少,图像观察也是不太直观。 

4.2 主成分分析

  • 定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量

  • 作用:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。

  • 应用:回归分析或者聚类分析当中

sklearn.decomposition.PCA(n_components=None)

  • 将数据分解为较低维数空间
  • n_components:
    • 小数:表示保留百分之多少的信息
    • 整数:减少到多少特征
  • PCA.fit_transform(X) X:numpy array格式的数据[n_samples,n_features]
  • 返回值:转换后指定维度的array

 我们先利用下面的数据简单运用一下:

[[2,8,4,5],
[6,3,0,8],
[5,4,9,1]]

代码如下:

from sklearn.decomposition import PCA

def pca_demo():
    """
    对数据进行PCA降维
    :return: None
    """
    data = [[2,8,4,5], [6,3,0,8], [5,4,9,1]]

    # 1、实例化PCA, 小数——保留多少信息
    transfer = PCA(n_components=0.9)
    # 2、调用fit_transform
    data1 = transfer.fit_transform(data)

    print("保留90%的信息,降维结果为:\n", data1)

    # 1、实例化PCA, 整数——指定降维到的维数
    transfer2 = PCA(n_components=3)
    # 2、调用fit_transform
    data2 = transfer2.fit_transform(data)
    print("降维到3维的结果:\n", data2)

    return None
if __name__ == "__main__":
    pca_demo()

运行结果如下:

保留90%的信息,降维结果为:
 [[ 1.28620952e-15  3.82970843e+00]
 [ 5.74456265e+00 -1.91485422e+00]
 [-5.74456265e+00 -1.91485422e+00]]
降维到3维的结果:
 [[ 1.28620952e-15  3.82970843e+00  5.26052119e-16]
 [ 5.74456265e+00 -1.91485422e+00  5.26052119e-16]
 [-5.74456265e+00 -1.91485422e+00  5.26052119e-16]]

持续补充中......

另外:ctrl+G定位功能变得快捷键真的好用!

学习笔记——黑马程序员之Python机器学习。

你可能感兴趣的:(机器学习,机器学习,python,数据挖掘)