特征工程介绍
特征工程是 为了提高了对未知数据的模型准确性,将原始数据转换为更好地代表预测模型的潜在问题的特征的过程。
例如预测一篇文章所在的类别,是否是新闻,首先得提取这篇文章的特征,如若这篇文章的特征更大程度上满足新闻的特征,那么我们便可预测其属于新闻类别。
其中主要包括了数据认知,数据清洗,特征提取,特征选择四个部分。
a) 数据认知:基于实际业务场景理解数据内容,发现数据与研究问题的关系。
b) 数据清洗:对数据进行规整,移除重复变量、处理缺失、异常数据等。
c) 特征提取:通过业务理解和技术实施,构造出描述研究问题的特征。
d) 特征选择:在构造的特征中筛选出最能刻画研究问题的特征。
工具:Scikit-learn

Python语言的机器学习工具 Scikit-learn包括许多知名的机器学习算法的实现 Scikit-learn文档完善,容易上手,丰富的API,使其在学术界颇受欢迎。
安装
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple Scikit-learn
导入
import sklearn
特征提取
api
字典特征提取
类:sklearn.feature_extraction.DictVectorizer
Vectorizer 矢量器
DictVectorizer(sparse=True,…) 返回一个sparse矩阵,如果是false 则返回ndarray数组
| 方法 | 解释 |
|---|---|
| DictVectorizer.fit_transform(X) | X:字典或者包含字典的迭代器 返回值:返回sparse矩阵 |
| DictVectorizer.inverse_transform(X) | X:array数组或者sparse矩阵 返回值:转换之前数据格式 |
| DictVectorizer.get_feature_names() | 返回类别名称 |
| DictVectorizer.transform(X) | 按照原先的标准转换 |
文本特征提取
类:sklearn.feature_extraction.text.CountVectorizer
| 方法 | 解释 |
|---|---|
| CountVectorizer.fit_transform(X,y) | X:文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵 |
| CountVectorizer.inverse_transform(X) | X:array数组或者sparse矩阵 返回值:转换之前数据格式 |
| CountVectorizer.get_feature_names() | 返回值:单词列表 |
注意点:一个字母的单词不会统计(因为ta无法代表文章的含义?)
>>> from sklearn.feature_extraction.text import CountVectorizer>>> texts = ['life is short, i love python','life is too long,i love python too']>>> cv = CountVectorizer()>>> data = cv.fit_transform(texts)>>> print(data)(0, 4) 1(0, 3) 1(0, 5) 1(0, 0) 1(0, 1) 1(1, 2) 1(1, 6) 2(1, 4) 1(1, 3) 1(1, 0) 1(1, 1) 1>>> print(cv.get_feature_names())['is', 'life', 'long', 'love', 'python', 'short', 'too']>>> print(data.toarray())[[1 1 0 1 1 1 0][1 1 1 1 1 0 2]]
但是如果是中文怎么办呢?
对于连续中文是不支持的,但是分词后的中文(以空格分开),同样可以特征提取。
简单介绍下jieba分词
cut
>>> import jieba>>> import os>>> f = '对于连续中文是不支持的,但是分词后的中文(以空格分开),同样可以特征提取。'>>> seg_list = jieba.cut(f)>>> print("jingque:","/".join(seg_list))
提取关键词
>>> import jieba.analyse>>> tags = jieba.analyse.extract_tags(f,topK = 10)>>> print("Keyword:","/".join(tags))
栗子
>>> f = '对于连续中文是不支持的,但是分词后的中文(以空格分开),同样可以特征提取。'>>> a = ' '.join(list(jieba.cut(f)))>>> a'对于 连续 中文 是 不 支持 的 , 但是 分词 后 的 中文 ( 以 空格 分开 ) , 同样 可以 特征提取 。'
我有一个疑问,在中文中,长度为一的字是有含义的,能够影响文本的特征 这样忽略单一字符串是不是有些欠妥呢?我想给ta组词或许能够增加准确性。
另外一种文本特征提取:tf-idf
主要思想
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高, 并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分 能力,适合用来分类。
Tf:term frequyency 词的频率
idf:inverse document frequyency 逆文档频率。log(总文档数量/该词出现的文档数量)
tf*idf = 该词的重要性程度
根据上方的定义,许多词语出现的次数多,但是它是不重要的。
**
使用
类:sklearn.feature_extraction.text.TfidfVectorizer
TfidfVectorizer(stop_words=None,…)
返回词的权重矩阵
| 方法 | 解释 |
|---|---|
| TfidfVectorizer.fit_transform([X],y) | X:文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵 |
| TfidfVectorizer.inverse_transform(X) | X:array数组或者sparse矩阵 返回值:转换之前数据格式 |
| TfidfVectorizer.get_feature_names() | 返回值:单词列表 |
栗子
>>> from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer>>> tv = TfidfVectorizer()>>> a'对于 连续 中文 是 不 支持 的 , 但是 分词 后 的 中文 ( 以 空格 分开 ) , 同样 可以 特征提取 。'>>> data = tv.fit_transform([a]) #可以传入多个 代表不同文档>>> print(data.toarray())[[0.53452248 0.26726124 0.26726124 0.26726124 0.26726124 0.267261240.26726124 0.26726124 0.26726124 0.26726124 0.26726124]]>>> print(tv.get_feature_names())['中文', '但是', '分开', '分词', '可以', '同样', '对于', '支持', '特征提取', '空格', '连续']
接着上面 第五行可以增加其他文本
# 例如增加一个b>>> b = 'TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高, 并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分 能力,适合用来分类。'>>> b = ' '.join(list(jieba.cut(b)))>>> b'TF - IDF 的 主要 思想 是 : 如果 某个 词 或 短语 在 一篇 文章 中 出现 的 概率 高 , 并且 在 其他 文章 中 很少 出现 , 则 认为 此词 或者 短语 具有 很 好 的 类别 区分 能力 , 适合 用来 分类 。'>>> data = tv.fit_transform([a,b])>>> print(tv.get_feature_names())['idf', 'tf', '一篇', '中文', '主要', '但是', '其他', '具有', '出现', '分开', '分类', '分词', '区分', '可以', '同样', '如果', '对于', '并且', '很少', '思想', '或者', '支持', '文章', '某个', '概率', '此词', '特征提取', '用来', '短语', '空格', '类别', '能力', '认为', '连续', '适合']>>> print(data.toarray())[[0. 0. 0. 0.53452248 0. 0.267261240. 0. 0. 0.26726124 0. 0.267261240. 0.26726124 0.26726124 0. 0.26726124 0.0. 0. 0. 0.26726124 0. 0.0. 0. 0.26726124 0. 0. 0.267261240. 0. 0. 0.26726124 0. ][0.17407766 0.17407766 0.17407766 0. 0.17407766 0.0.17407766 0.17407766 0.34815531 0. 0.17407766 0.0.17407766 0. 0. 0.17407766 0. 0.174077660.17407766 0.17407766 0.17407766 0. 0.34815531 0.174077660.17407766 0.17407766 0. 0.17407766 0.34815531 0.0.17407766 0.17407766 0.17407766 0. 0.17407766]]>>>
