Web安全之机器学习入门
上QQ阅读APP看书,第一时间看更新

3.3 特征提取

机器学习中,特征提取被认为是个体力活,有人形象地称为“特征工程”,可见其工作量之大。特征提取中数字型和文本型特征的提取最为常见。

3.3.1 数字型特征提取

数字型特征可以直接作为特征,但是对于一个多维的特征,某一个特征的取值范围特别大,很可能导致其他特征对结果的影响被忽略,这时候我们需要对数字型特征进行预处理,常见的预处理方式有以下几种。

1.标准化:

    >>> from sklearn import preprocessing
    >>> import numpy as np
    >>> X = np.array([[ 1., -1.,   2.],
    ...                   [ 2.,   0.,   0.],
    ...                   [ 0.,   1., -1.]])
    >>> X_scaled = preprocessing.scale(X)
    >>> X_scaled
    array([[ 0.   ..., -1.22...,   1.33...],
            [ 1.22...,   0.   ..., -0.26...],
            [-1.22...,   1.22..., -1.06...]])

2.正则化:

    >>> X = [[ 1., -1.,   2.],
    ...        [ 2.,   0.,   0.],
    ...        [ 0.,   1., -1.]]
    >>> X_normalized = preprocessing.normalize(X, norm='l2')
    >>> X_normalized
    array([[ 0.40..., -0.40...,   0.81...],
            [ 1.   ...,   0.   ...,   0.   ...],
            [ 0.   ...,   0.70..., -0.70...]])

3.归一化:

    >>> X_train = np.array([[ 1., -1.,   2.],
    ...                          [ 2.,   0.,   0.],
    ...                          [ 0.,   1., -1.]])
    ...
    >>> min_max_scaler = preprocessing.MinMaxScaler()
    >>> X_train_minmax = min_max_scaler.fit_transform(X_train)
    >>> X_train_minmax
    array([[ 0.5         ,   0.          ,   1.          ],
            [ 1.          ,   0.5         ,   0.33333333],
            [ 0.          ,   1.          ,   0.          ]])

3.3.2 文本型特征提取

文本型数据提取特征相对数字型要复杂很多,本质上是做单词切分,不同的单词当作一个新的特征,以hash结构为例:

    >>> measurements = [
    ...      {'city'∶ 'Dubai', 'temperature'∶ 33.},
    ...      {'city'∶ 'London', 'temperature'∶ 12.},
    ...      {'city'∶ 'San Fransisco', 'temperature'∶ 18.},
    ... ]

键值city具有多个取值,“Dubai”、“London”和“San Fransisco”,直接把每个取值作为新的特征即可。键值temperature是数值型,可以直接作为特征使用。

    >>> from sklearn.feature_extraction import DictVectorizer
    >>> vec = DictVectorizer()
    >>> vec.fit_transform(measurements).toarray()
    array([[   1.,    0.,    0.,   33.],
            [   0.,    1.,    0.,   12.],
            [   0.,    0.,    1.,   18.]])
    >>> vec.get_feature_names()
    ['city=Dubai', 'city=London', 'city=San Fransisco', 'temperature']

文本特征提取有两个非常重要的模型。

● 词集模型:单词构成的集合,集合中每个元素都只有一个,即词集中的每个单词都只有一个。

● 词袋模型:如果一个单词在文档中出现不止一次,并统计其出现的次数(频数)。

两者本质上的区别,词袋是在词集的基础上增加了频率的维度:词集只关注有和没有,词袋还要关注有几个。

假设我们要对一篇文章进行特征化,最常见的方式就是词袋。

导入相关的函数库:

    >>> from sklearn.feature_extraction.text import CountVectorizer

实例化分词对象:

    >>> vectorizer = CountVectorizer(min_df=1)
    >>> vectorizer
    CountVectorizer(analyzer=...'word', binary=False, decode_error=...'strict',
        dtype=<... 'numpy.int64'>, encoding=...'utf-8', input=...'content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), preprocessor=None, stop_words=None,
        strip_accents=None, token_pattern=...'(? u)\\b\\w\\w+\\b',
        tokenizer=None, vocabulary=None)

将文本进行词袋处理:

    >>> corpus = [
    ...      'This is the first document.',
    ...      'This is the second second document.',
    ...      'And the third one.',
    ...      'Is this the first document? ',
    ... ]
    >>> X = vectorizer.fit_transform(corpus)
    >>> X
    <4x9 sparse matrix of type '<... 'numpy.int64'>'
        with 19 stored elements in Compressed Sparse ... format>

获取对应的特征名称:

    >>> vectorizer.get_feature_names() == (
    ...      ['and', 'document', 'first', 'is', 'one',
    ...        'second', 'the', 'third', 'this'])
    True

获取词袋数据,至此我们已经完成了词袋化。但是对于程序中的其他文本,如何使用现有的词袋的特征进行向量化呢?

    >>> X.toarray()
    array([[0, 1, 1, 1, 0, 0, 1, 0, 1],
            [0, 1, 0, 1, 0, 2, 1, 0, 1],
            [1, 0, 0, 0, 1, 0, 1, 1, 0],
            [0, 1, 1, 1, 0, 0, 1, 0, 1]]...)

我们定义词袋的特征空间叫做词汇表vocabulary:

    vocabulary=vectorizer.vocabulary_

针对其他文本进行词袋处理时,可以直接使用现有的词汇表:

    >>> new_vectorizer = CountVectorizer(min_df=1, vocabulary=vocabulary)

TensorFlow中有类似实现:

    from sklearn.feature_extraction.text import CountVectorizer
    MAX_DOCUMENT_LENGTH = 100
    vocab_processor =
    learn.preprocessing.VocabularyProcessor(MAX_DOCUMENT_LENGTH)
    x_train = np.array(list(vocab_processor.fit_transform(x_train)))
    x_test = np.array(list(vocab_processor.transform(x_test)))

3.3.3 数据读取

平时处理数据时,CSV是最常见的格式,文件的每行记录一个向量,其中最后一列为标记。TensorFlow提供了非常便捷的方式从CSV文件中读取数据集。

加载对应的函数库:

    import tensorflow as tf
import numpy as np

从CSV文件中读取数据:

        training_set = tf.contrib.learn.datasets.base.load_csv_with_header(
        filename=" iris_training.csv",
        target_dtype=np.int,
        features_dtype=np.float32)
    feature_columns = [tf.contrib.layers.real_valued_column("", dimension=4)]

其中各个参数定义为:

● filename,文件名;

● target_dtype,标记数据类型;

● features_dtype,特征数据类型。

访问数据集合的特征以及标记的方式为:

    x=training_set.data
    y=training_set.target