目录
2.4数据预处理(把原数据 转更好用形式→标准,归一,二值)
2.5 特征提取(把文字转为可以用的→字典,中英文,DNA,TF)
2.1分类方法(KNN,逻辑回归,RF,朴素贝叶斯,SVM)
一.流程总览(本文主要是红框部分)
二.特征处理部分
简介:本节主要内容来自
【特征工程】呕心之作——深度了解特征工程_wx:wu805686220-CSDN博客
1.总体概述
1.1一些常见问题
(1)存在缺失值:缺失值需要补充( .dropna等)
(2)不属于同一量纲:即特征的规格不一样,不能够放在一起比较 (标准化)
(3)信息冗余:某些定量特征,区间划分> 如学习成绩,若只关心“及格”或不“及格”,那么将考分,转换成“1”和“0” 表示及格和未及格 (where >60..)
(4)定性特征不能直接使用:需要将定性特征转换为定量特征(如one-hot,TF等)
(5)信息利用率低:不同的机器学习
算法和模型对数据中信息的利用是不同的,选个合适的模型
2.具体处理(具体顺序看上面红框)
2.1缺失值处理(删or填)
1)缺失值删除(dropna)
2)缺失值填充(fillna):比较常用,一般用均值or众数
①用固定值填充
对于特征值缺失的一种常见的方法就是可以用固定值来填充,例如0,-99, 如下面对这一列缺失值全部填充为-99
data['第一列'] = data['第一列'].fillna('-99')
②用均值填充
对于数值型的特征,其缺失值也可以用未缺失数据的均值填充,下面对灰度分这个特征缺失值进行均值填充
data['第一列'] = data['第一列'].fillna(data['第一列'].mean()))
③用众数填充
与均值类似,可以用众数来填充缺失值
data['第一列'] = data['第一列'].fillna(data['第一列'].mode()))
其他填充如插值,KNN,RF详见原博客
2.2数据格式处理(数据集划分,时间格式等)
1)数据集的划分
一般的数据集会划分为两个部分:
- 训练数据:用于训练,构建模型
- 测试数据:在模型检验时使用,用于评估模型是否有效
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def datasets_demo():
# 获取数据集
iris = load_iris()
print("鸢尾花数据集:\n", iris)
print("查看数据集描述:\n", iris["DESCR"])
print("查看特征值的名字:\n", iris.feature_names)
print("查看特征值:\n", iris.data, iris.data.shape) # 150个样本
# 数据集划分 X为特征 Y为标签
"""random_state随机数种子,不同的种子会造成不同的随机采样结果"""
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
return None
if __name__ == "__main__":
datasets_demo()
2)时间格式的处理(主要是转换成年月日or星期几,然后找自己要的)
详见https://blog.csdn.net/kobeyu652453/article/details/108894807
# 处理时间数据
import datetime
# 分别得到年,月,日
years = features['year']
months = features['month']
days = features['day']
# datetime格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]
dates[:5]
3)表格操作,合并连接or取特征啥的
详见NP,PD教程
2.3数据采样(过采样or下采样,不均衡时候用)
→多的类别过采样/少的类别欠采样,来平衡分布。例:信用卡诈骗,骗子的数据太少了,这个时候用
def over_sample( y_origin, threshold):
y = to_one_hot(y_origin, NUM_LABELS)
y_counts = np.sum(y, axis=0)
sample_ratio = threshold / y_counts * y
sample_ratio = np.max(sample_ratio, axis=1)
sample_ratio = np.maximum(sample_ratio, 1)
index = ratio_sample(sample_ratio)
# x_token_train = [x_token_train[i] for i in index]
return y_origin[index]
def ratio_sample(ratio):
sample_times = np.floor(ratio).astype(int)
# random sample ratio < 1 (decimal part)
sample_ratio = ratio - sample_times
random = np.random.uniform(size=sample_ratio.shape)
index = np.where(sample_ratio > random)
index = index[0].tolist()
# over sample fixed integer times
row_num = sample_times.shape[0]
for row_index, times in zip(range(row_num), sample_times):
index.extend(itertools.repeat(row_index, times))
return index
2.4数据预处理(把原数据 转更好用形式→标准,归一,二值)
主要转换方式有以下几种(常用的 前四个):
1)标准化(很常用)
用在:特征之间数据差距特别大(比如存款金额与银行周围小区数,不在一个量级)
from sklearn.preprocessing import StandardScaler
#标准化,返回值为标准化后的数据
StandardScaler().fit_transform(iris.data)
2)归一化
含义:样本向量在点乘运算或其他核函数计算相似性时,转化为“单位向量”。
什么情况下(不)需要归一化:
- 需要: 基于参数的模型或基于距离的模型,都是要进行特征的归一化。
- 不需要:基于树的方法是不需要进行特征的归一化,例如随机森林,bagging 和 boosting等
from sklearn.preprocessing import Normalizer
#归一化,返回值为归一化后的数据
Normalizer().fit_transform(iris.data)
3)二值化(>60分及格,标为1)
用where或者Binarizer
from sklearn.preprocessing import Binarizer
#二值化,阈值设置为3,返回值为二值化后的数据
Binarizer(threshold=3).fit_transform(iris.data)
其他:区间放缩,等距离散啥的,看看原文
2.5 特征提取(把文字转为可以用的→字典,中英文,DNA,TF)
1)字典特征提取:(字典转矩阵)
from sklearn.feature_extraction import DictVectorizer
def dict_demo():
data = [{'city':'北京', 'temperature':100},
{'city':'上海', 'temperature':60},
{'city':'深圳', 'temperature':30}]
# 1、实例化一个转换器类
#transfer = DictVectorizer() # 返回sparse矩阵
transfer = DictVectorizer(sparse=False)
# 2、调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new) # 转化后的
print("特征名字:\n", transfer.get_feature_names())
return None
if __name__ == "__main__":
dict_demo()
结果:
data_new:
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
特征名字:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
2)文本特征提取(文本转矩阵)
应用 1.中英文分词,然后转矩阵 2.DNAseqs处理,词袋模型
2.1)英文文本分词
from sklearn.feature_extraction.text import CountVectorizer
def count_demo():
data = ['life is short,i like like python',
'life is too long,i dislike python']
# 1、实例化一个转换器类
transfer = CountVectorizer()
#这里还有一个stop_word(),就是 到哪个词停下来
transfer1 = CountVectorizer(stop_words=['is', 'too'])
# 2、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new.toarray()) # toarray转换为二维数组
print("特征名字:\n", transfer.get_feature_names())
return None
if __name__ == "__main__":
count_demo()
结果
data_new:
[[0 1 1 2 0 1 1 0]
[1 1 1 0 1 1 0 1]]
特征名字:
['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']
2.2)中文分词
from sklearn.feature_extraction.text import CountVectorizer
import jieba
def count_chinese_demo2():
data = ['一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。',
'我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。',
'如果只用一种方式了解某件事物,他就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相