机器学习—数据的特征工程

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

1.字典的特征抽取

①语法
DictVectorizer.fit_transform(X)
X:字典或者包含字典的迭代器
返回值:返回sparse矩阵

DictVectorizer.inverse_transform(X)
X:array数组或者sparse矩阵
返回值:转换之前数据格式

DictVectorizer.get_feature_names()
返回类别名称

DictVectorizer.transform(X)
按照原先的标准转换

②流程

  • 导入API:
    from sklearn.feature_extraction import DictVectorizer
  • 实例化类:
    dict = DictVectorizer(sparse=False)
    默认为sparse=True,返回一个sparse矩阵;
    令sparse=False,则返回一个 ndarray二维数组;
  • 调用fit_transform
    data = dict.fit_transform(X)

③案例

from sklearn.feature_extraction import DictVectorizer
def dictvec():
    """
    字典数据抽取
    :return: None
    """
    # 实例化
    dict = DictVectorizer(sparse=False)

    # 调用fit_transform
    data = dict.fit_transform([{'city': '北京','temperature': 100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature': 30}])

    print(dict.get_feature_names())
    print(data)
    return None
    
dictvec()

[out]:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
[[  0.   1.   0. 100.]
 [  1.   0.   0.  60.]
 [  0.   0.   1.  30.]]

④One-hot 编码
在特征输入时会遇到类别型数据,为了避免将类别数据转换为数字编码带来的因数字大小的歧义,引入One-hot类别编码。

为每一个类别生成一个布尔列,这些列中只有一个列可以为每个样本值取 1。

  • 原样本
SampleCategoryNumerical
1Human1
2Human1
3Penguin2
4Octopus3
5Aliens4
6Octopus3
7Aliens4
  • One-hot 编码后
SampleHumanPenguinOctopusAliens
11100
21000
30100
40010
50001
60010
70001

2.文本特征抽取

1)Count 方法

①语法

CountVectorizer(max_df=1.0,min_df=1,…)
返回词频矩阵

CountVectorizer.fit_transform(X,y)
X:文本或者包含文本字符串的可迭代对象
返回值:返回sparse矩阵

CountVectorizer.inverse_transform(X)
X:array数组或者sparse矩阵
返回值:转换之前数据格式

CountVectorizer.get_feature_names()
返回值:单词列表

②流程

  • 导入API:
    from sklearn.feature_extraction.text import CountVectorizer
  • 实例化类
    cv=CountVectorizer()
  • 调用 fit_transform输入数据并转换
    data = cv.fit_transform(X)

注意返回格式,利用 toarray()将 sparse 矩阵转换 array 数组

③案例

from sklearn.feature_extraction.text import CountVectorizer

def countvec():
    cv=CountVectorizer()
    data = cv.fit_transform(["life is short,i like python", "life is too long,dislike python"])

    print(cv.get_feature_names())
    print(data.toarray())
    return None

countvec()

[out]:
['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']
[[0 1 1 1 0 1 1 0]
 [1 1 1 0 1 1 0 1]]

④特殊规则

  • 统计所有文章中所有的次,重复的只看做一次。
    如上述案例中 python在每篇文章中均出现了,但特征值列表只取一个;
  • 对每篇文章,在特征值列表中统计每个词出现的次数。
    如上述案例中,dislike 在第一篇文章中未出现,输出值中第一行第一列为 0;
  • 单个字母、无意义的中文字符等不出现;
  • 默认不支持中文分词,需引入jieba.cut;

⑤jieba.cut 分词处理器

  • 导入库:
    import jieba
  • 分词处理
def cutword():

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

    # 转换成列表
    content1 = list(con1)
    content2 = list(con2)
    content3 = list(con3)

    # 把列表转换成字符串
    c1 = ' '.join(content1)
    c2 = ' '.join(content2)
    c3 = ' '.join(content3)

	return c1, c2, c3
    
cutword()

[out]:
('今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。',
 '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。',
 '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。')
  • 汉字文本特征抽取
def hanzivec():
    """
    中文特征值化
    :return: None
    """
    c1, c2, c3 = cutword()
    print(c1, c2, c3)

    cv = CountVectorizer()
    data = cv.fit_transform([c1, c2, c3])

    print(cv.get_feature_names())
    print(data.toarray())
    return None

[out]:
['一种', '不会', '不要', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '这样']
[[0 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 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 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]]

2)Tf/Idf方法

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

  • Tf: term frequency 词的频率,即出现的次数
  • Idf: inverse document frenquency 逆文档频率,log(总文档数/该词出现的文档数)

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

① 语法
TfidfVectorizer(stop_words=None,…)
返回词的权重矩阵

TfidfVectorizer.fit_transform(X,y)
X:文本或者包含文本字符串的可迭代对象
返回值:返回sparse矩阵

TfidfVectorizer.inverse_transform(X)
X:array数组或者sparse矩阵
返回值:转换之前数据格式

TfidfVectorizer.get_feature_names()
返回值:单词列表

② 流程

  • 导入 API
    from sklearn.feature_extraction.text import TfidfVectorizer
  • 实例化类
    tf=CountVectorizer()
  • 调用 fit_transform输入数据并转换
    data = tf.fit_transform(X)

③ 案例

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


from sklearn.feature_extraction.text import TfidfVectorizer
def tfidfvec():
    """
    中文特征值化
    :return: None
    """
    c1, c2, c3 = cutword()
    print(c1, c2, c3)

    tf = TfidfVectorizer()
    data = tf.fit_transform([c1, c2, c3])

    print(tf.get_feature_names())
    print(data.toarray())
    return None
tfidfvec()

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

3.数据的特征预处理

通过特定的统计方法(数学方法)将数据转换成算法要求的数据

1)处理方法

预处理 API:sklearn.processing

  • 数值型数据:标准缩放
    1.归一化
    2.标准化
    3.缺失值处理

  • 类别型数据:One-hot 编码

  • 时间类型:时间的切分

2)归一化

目的:使得特征对最终结果不会造成影响
缺点:异常值对最大值最小值影响太大

① 语法
通过对原始数据进行变换将数据映射到[0,1]之间
X ′ = ( x − m i n ) ( m a x − m i n ) X^′= \frac {(x−min)}{(max−min)} X=(maxmin)(xmin)
X ′ ′ = X ′ ∗ ( m x − m i ) + m i X^{′′}=X^′*(mx−mi)+mi X=X(mxmi)+mi

  • 其中 m a x max max m i n min min 分别为一列的最大值、最小值;
  • m x mx mx m i mi mi 分别为指定区间的上下界,默认为 0-1 区间;

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

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

② 流程

  • 导入 API
    from sklearn.preprocessing import MinMaxScaler
  • 实例化类
    mm=MinMaxScaler(feature_range=(0, 1))
  • 调用 fit_transform输入数据并转换
    data = mm.fit_transform(X)

③ 案例

from sklearn.preprocessing import MinMaxScaler
def mm():
    """
    归一化处理
    :return: None
    """
    mm = MinMaxScaler(feature_range=(2, 3))
    data = mm.fit_transform([[90,2,10,40],[60,4,15,45],[75,3,13,46]])

    print(data)
    return None
mm()

[out]:
[[3.         2.         2.         2.        ]
 [2.         3.         3.         2.83333333]
 [2.5        2.5        2.6        3.        ]]

3)标准化

对原始数据进行变换,将数据变换到均值为 0,标准差为 1 的范围内;

① 语法
计算公式:
X ′ = x − m e a n σ X^′=\frac{x-mean}{\sigma} X=σxmean

  • 作用于每一列, m e a n mean mean 为平均值, σ \sigma σ为标准差;
  • 其中方差用于考察数据的稳定性

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

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

StandardScaler.mean_
原始数据中每列特征的平均值

StandardScaler.std_
原始数据每列特征的方差

② 流程

  • 导入 API
    from sklearn.preprocessing import StandardScaler
  • 实例化类
    std=StandardScaler()
  • 调用 fit_transform输入数据并转换
    data = std.fit_transform(X)

③ 案例

from sklearn.preprocessing import StandardScaler
def stand():
    """
    标准化缩放
    :return:None
    """
    std = StandardScaler()
    data = std.fit_transform([[ 1., -1., 3.],[ 2., 4., 2.],[ 4., 6., -1.]])

    print(data)
    return None
stand()

[out]:
[[-1.06904497 -1.35873244  0.98058068]
 [-0.26726124  0.33968311  0.39223227]
 [ 1.33630621  1.01904933 -1.37281295]]

4)缺失值处理

① 语法
Imputer(missing_values=‘NaN’,strategy=‘mean’,axis=0)
完成缺失值插补

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

② 流程

  • 导入 API
    from sklearn.preprocessing import Imputer
  • 实例化类
    im = Imputer(missing_values='NaN', strategy='mean', axis=0)
  • 调用 fit_transform输入数据并转换
    data = im.fit_transform(X)

③ 案例

def im():
    """
    缺失值处理
    :return:NOne
    """
    # NaN, nan
    im = Imputer(missing_values='NaN', strategy='mean', axis=0)
    data = im.fit_transform([[1, 2], [np.nan, 3], [7, 6]])

    print(data)
    return None
im()

[out]:
[[1. 2.]
 [4. 3.]
 [7. 6.]]

4.数据降维

1)特征选择

特征选择就是单纯地从提取到的所有特征中选择部分特征作为训练集特征,特征在选择前和选择后可以改变值、也不改变值,但是选择后的特征维数比选择前小,毕竟我们只选择了其中的一部分特征。

特征选择原因:

  • 冗余:部分特征的相关度高,容易消耗计算机性能;
  • 噪声:部分特征对预测结果有负影响;

特征选择主要方法:

  • Filter(过滤式):VarianceThreshold (最常用)
  • Embedded(嵌入式):正则化、决策树
  • Wrapper(包裹式)

VarianceThreshold 方法

①语法

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

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

② 流程

  • 导入 API
    from sklearn.feature_selection import VarianceThreshold
  • 实例化类
    var = VarianceThreshold(threshold=1.0)
  • 调用 fit_transform输入数据并转换
    data = var.fit_transform(X)

③ 案例

from sklearn.feature_selection import VarianceThreshold
def var():
    """
    特征选择-删除低方差的特征
    :return: None
    """
    var = VarianceThreshold(threshold=1.0)
    data = var.fit_transform([[0, 2, 0, 3], [0, 1, 4, 3], [0, 1, 1, 3]])

    print(data)
    return None
var()


[out]:
[[0]
 [4]
 [1]]

2)PCA降维

PCA是一种分析、简化数据集的技术,可以尽可能损失少量信息地来降低原数据的维数(复杂度)。它可以削减回归分析或者聚类分析中特征的数量

①语法
PCA(n_components=None)
将数据分解为较低维数空间

n_components 参数可以取小数或整数
取小数时,认为降维后的信息数量减少到原来的100*n%;
取整数时,降维后的特征为给定的 n 维;

PCA.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
返回值:转换后指定维度的array
② 流程

  • 导入 API
    from sklearn.decomposition import PCA
  • 实例化类
    pca = PCA(n_components=0.9)
  • 调用 fit_transform输入数据并转换
    data = pca.fit_transform(X)

③ 案例

from sklearn.decomposition import PCA
def pca():
    """
    主成分分析进行特征降维
    :return: None
    """
    pca = PCA(n_components=0.9)
    data = pca.fit_transform([[2,8,4,5],[6,3,0,8],[5,4,9,1]])

    print(data)
    return None
pca()


[out]:
[[ 1.22879107e-15  3.82970843e+00]
 [ 5.74456265e+00 -1.91485422e+00]
 [-5.74456265e+00 -1.91485422e+00]]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值