python机器学习基础01——sklearn开启

机器学习开发流程

  • 1.数据采集
    • 公司内部产生的数据
    • 和其他公司合作获取的数据
    • 购买的数据
  • 2.分析数据所对应要解决需求或者问题是什么?根据目标数据推断问题属于回归还是分类!
  • 3.数据的基本处理
    • 数据清洗
    • 合并
    • 级联等
  • 4.特征工程:对特征进行处理
    • 特征抽取
    • 特征预处理
    • 降维等
  • 5.选择合适的模型,然后对其进行训练
  • 6.模型的评估
  • 7.上线使用

特征工程

首要的任务是机器学习前的数据处理部分,这里讲解构建特征工程

字符串特征化

字符串数据尽量转换为数值型的数据,这里的工具采用sk-learn

one hot编码

#sparse矩阵转换成数组的形式
from sklearn.feature_extraction import DictVectorizer
alist = [
            {'city':'BeiJing','temp':33},
            {'city':'GZ','temp':42},
            {'city':'SH','temp':40}
        ]
#创建工具对象
d = DictVectorizer(sparse=False)
#使用该工具对象进行特征值化
result = d.fit_transform(alist)
names = d.get_feature_names()
print(names)
print(result) #返回的结果是一个sparse矩阵

结果:
[[ 1.  0.  0. 33.]
 [ 0.  1.  0. 42.]
 [ 0.  0.  1. 40.]]

OneHot编码

  • sparse矩阵中的0and1就是onehot编码

基于pandas实现独热编码(Onehot编码)

# 创建数据集
import pandas as pd
df = pd.DataFrame([
 ['green', 'M', 20, 'class1'],
 ['red', 'L', 21, 'class2'],
 ['blue', 'XL',30, 'class3']])
df.columns = ['color', 'size', 'weight', 'class label']

# 编码转换颜色和大小
r1 = pd.get_dummies(df['color']) # 将颜色转换为独热编码
new_df = pd.concat((df,r1),axis=1).drop(labels='color',axis=1)
new_df['new_size'] = new_df['size'].map({'M':1,'L':2,'XL':3})
new_df = new_df.drop(labels='size',axis=1)

文本特征化

- 作用:对文本数据进行特征值化
- API:from sklearn.feature_extraction.text import CountVectorizer
- fit_transform(X):X为文本或者包含文本字符串的可迭代对象,返回sparse矩阵
- inverse_transform(X):X为array数组或者sparse矩阵,返回转换之前的格式数据
- get_feature_names()
- toarray():将sparse矩阵换成数组
from sklearn.feature_extraction.text import CountVectorizer
alist = [
         'left is is short,i love python',
         'left is too long,i hate python'
        ]
c = CountVectorizer()
result = c.fit_transform(alist)
print(c.get_feature_names())
#toarray可以将sparse矩阵转换为数组
print(result.toarray())

结果:每个单词出现的次数,一个字母的不计数
['hate', 'is', 'left', 'long', 'love', 'python', 'short', 'too']
[[0 2 1 0 1 1 1 0]
 [1 1 1 1 0 1 0 1]]
  • 中文文本特征抽取

jieba分词

没有包需要导入:pip install jieba

为什么需要引入jieba分词,是因为文本识别只能对符合和空格分隔,一段文字不能分开

import jieba
from sklearn.feature_extraction.text import CountVectorizer

text = [
    '因为在自然语言处理中,我们是需要将一段中文文本中相关的词语,成语,形容词......都要进行抽取的',
    '目前CountVectorizer只可以对有标点符号和用分隔符对应的文本进行特征抽取,显然这是满足不了我们日常需求的'
]
new_text = []
for t in text:
    r = list(jieba.cut(t))
    s = ' '.join(r)
    new_text.append(s)
c = CountVectorizer()
result = c.fit_transform(new_text)
print(c.get_feature_names())
print(result.toarray())

数值型数据预处理

  • 无量纲化:
    • 在机器学习算法实践中,我们往往有着将不同规格的数据转换到同一规格,或不同分布的数据转换到某个特定分布的需求这种需求统称为将数据“无量纲化”。
      • 譬如梯度和矩阵为核心的算法中,譬如逻辑回归,支持向量机,神经 网络,无量纲化可以加快求解速度;
      • 而在距离类模型,譬如K近邻,K-Means聚类中,无量纲化可以帮我们提升模型精度,避免某一个取值范围特别大的特征对距离计算造成影响。
      • 一个特例是决策树和树的集成算法们,对决策 树我们不需要无量纲化,决策树可以把任意数据都处理得很好。
    • 那么预处理就是用来实现无量纲化的方式。
  • 含义:特征抽取后我们就可以获取对应的数值型的样本数据啦,然后就可以进行数据处理了。
  • 概念:通过特定的统计方法(数学方法),将数据转换成算法要求的数据
  • 方式:
    • 归一化
    • 标准化

归一化

如果认为每一个特征具有同等大小的权重都同等重要,则必须要对其进行归一化处理。

通过对原始数据进行变换将数据映射到0-1之间(默认),归一化后的数据服从正态分布

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3JcoDs57-1644320843730)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/image-20220207205801705.png)]

# 归一化处理
from sklearn.preprocessing import MinMaxScaler
mm = MinMaxScaler()
result = mm.fit_transform(feature)
print(result)
  • 问题:如果数据中存在的异常值比较多,会对结果造成什么样的影响?
    • 结合着归一化计算的公式可知,异常值对原始特征中的最大值和最小值的影响很大,因此也会影响对归一化之后的值。这个也是归一化的一个弊端,无法很好的处理异常值。
  • 归一化总结:
    • 在特定场景下最大值和最小值是变化的,另外最大最小值很容易受到异常值的影响,所以这种归一化的方式具有一定的局限性。因此引出了一种更好的方式叫做:标准化!!!

标准化

  • 标准化的处理

    • 当数据按均值中心化后,再按标准差缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布),而这个过程,就叫做数据标准化(Standardization,又称Z-score normalization),公式如下
      在这里插入图片描述

    • 从公式中可以看出,异常值对均值和标准差的影响不大

  • API

    • 处理后,每列所有的数据都聚集在均值为0,标准差为1范围附近
    • 标准化API:from sklearn.preprocessing import StandardScaler
      • fit_transform(X):对X进行标准化
      • mean_:均值
      • var_:方差
# 标准化处理
from sklearn.preprocessing import StandardScaler
s = StandardScaler()
result = s.fit_transform(feature)
print(result)
  • 归一化和标准化总结:

    • 对于归一化来说,如果出现了异常值则会响应特征的最大最小值,那么最终结果会受到比较大影响
    • 对于标准化来说,如果出现异常点,由于具有一定的数据量,少量的异常点对于平均值的影响并不大,从而标准差改变比较少。
  • StandardScaler和MinMaxScaler选哪个?

    • 看情况。大多数机器学习算法中,会选择StandardScaler来进行特征缩放,因为MinMaxScaler对异常值非常敏感。在PCA,聚类,逻辑回归,支持向量机,神经网络这些算法中,StandardScaler往往是最好的选择。 MinMaxScaler在不涉及距离度量、梯度、协方差计算以及数据需要被压缩到特定区间时使用广泛,比如数字图像处理中量化像素强度时,都会使用MinMaxScaler将数据压缩于[0,1]区间之中。
    • 建议先试试看StandardScaler,效果不好换MinMaxScaler。

特征选择

Filter过滤式(方差过滤)

  • 原理:这是通过特征本身的方差来筛选特征的类。比如一个特征本身的方差很小,就表示样本在这个特征上基本没有差异,可能特征中的大多数值都一样,甚至整个特征的取值都相同,那这个特征对于样本区分没有什么作用。所以无论接下来的特征工程要做什么,都要优先消除方差为0或者方差极低的特征。
    • 比如:朝阳区的房价预测,其中样本有一列特征为温度,则要知道朝阳区包含在样本中的房子对应的气象温度几乎一致或者大同小异,则温度特征则对房价的区分是无意义的。
  • API:from sklearn.feature_selection import VarianceThreshold
  • VarianceThreshold(threshold=x)threshold方差的值,删除所有方差低于x的特征,默认值为0表示保留所有方差为非0的特征
  • fit_transform(X)#:X为特征
# 过滤方差小于阈值的
from sklearn.feature_selection import VarianceThreshold
# threshold:方差的阈值
v = VarianceThreshold(threshold=0.2) 
result = v.fit_transform(feature)

一般的手法是过滤一半,所以会选择所有特征的方差中位数作为方差阈值过滤的条件

import numpy as np
median_value = np.median(feature.var(axis=0).values)
v = VarianceThreshold(threshold=median_value)
result = v.fit_transform(feature)

一般衡量的方法也就看其最后模型训练的精度以及耗时

PCA降维

在误差较小的情况下,用低维度表示高纬度的事物

  • 目的:特征数量达到上百,上千的时候,考虑数据的优化。使数据维度压缩,尽可能降低源数据的维度(复杂度),损失少量信息。

  • 作用:可以削减回归分析或者聚类分析中特征的数量

  • 矩阵分解:

    • 我们用来找出n个新特征向量,让数据能够被压缩到少数特征上并且总信息量不损失太多的技术就是矩阵分解
  • PCA语法

    • from sklearn.decomposition import PCA
    • pca = PCA(n_components=None)
      • n_components可以为小数(保留特征的百分比),整数(减少到的特征数量)
    • pca.fit_transform(X)
from sklearn.decomposition import PCA
#将数据分解为较低维度的空间
#n_components可以为小数(保留特征的百分比),整数(减少到的特征数量)
pca = PCA(n_components=2)
pca.fit_transform([[0,2,4,3],[0,3,7,3],[0,9,6,3]])

WOE&IV编码

用于分类的问题,计算特征的重要性

分箱

实则就是将连续型数据转换为离散型

  • 分箱的作用&意义

    • 离散特征的增加和减少都很容易,易于模型的快速迭代,提升计算速度
    • 特征离散化后,模型会更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成一个完全不同的人。
    • 特征离散化以后,起到了简化了模型的作用,可以适当降低了模型过拟合的风险。
  • 分箱的实现

    • 等距分箱:cut
    • 等频分箱:qcut
import pandas as pd
import numpy as np

# 1、cut:等距分箱:每个范围大小一致
ages = np.random.randint(1,80,size=(25,)) #连续型变量
#使用分箱对连续性变量进行离散化
#bins:分箱的个数(分组的个数)
cut_resutl = pd.cut(ages,bins=5)  # [(16.0, 30.0], (16.0, 30.0], (16.0, 30.0], (1.93, 16.0], (1.93, 16.0], ..., (30.0, 44.0], (1.93, 16.0], (16.0, 30.0], (1.93, 16.0], (44.0, 58.0]] Length: 25 Categories (5, interval[float64, right]): [(1.93, 16.0] < (16.0, 30.0] < (30.0, 44.0] < (44.0, 58.0] < (58.0, 72.0]]

#labels可以替换原先箱子/组的名称
cut_result = pd.cut(ages,bins=5,labels=['a','b','c','d','e'])
v_result = cut_result.value_counts() 

# 结果
a    7
b    6
c    3
d    4
e    5


# 2、等频分箱-qcut
ages = np.random.randint(1,80,size=(25,)) #连续型变量
#q表示箱子的个数
qcut_result = pd.qcut(ages,q=5)
qcut_result.value_counts() 

# 结果:
(3.999, 16.8]    5
(16.8, 46.2]     5
(46.2, 61.4]     5
(61.4, 69.0]     5
(69.0, 79.0]     5
  • cut和qcut的区别:
    • 1,cut: 按连续数据的大小分到各个桶里,每个桶里样本量可能不同,但是,每个桶相当于一个等长的区间,即:以数据的最大和最小为边界,等分成p个桶。
    • 2,qcout: 与cut主要的区别就是每个桶里的样本数量是一定的。

WOE

  • WOE的全称是“Weight of Evidence”,即证据权重。WOE是对原始特征的一种编码形式。要对一个特征进行WOE编码,需要首先把这个变量进行分组处理(也叫离散化、分箱等等,说的都是一个意思)。分组后,对于第i组,WOE的计算公式如下:
    - [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hs9de3om-1644932140647)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/image-20220213173717053.png)]

IV

  • 概念:

    • IV的全称是Information Value,中文意思是信息价值,或者信息量。
  • IV其核心就是要理解“用IV去衡量变量预测能力”这句话。

  • 我们假设在一个分类问题中,目标变量的类别有两类:Y1,Y2。对于一个待预测的样本A,要判断A属于Y1还是Y2,我们是需要一定的信息,假设这个信息总量是I,而这些所需要的信息,就蕴含在所有的待预测样本的特征C1,C2,C3,……,Cn中,那么,对于其中的一个特征Ci来说,其蕴含的信息越多,那么它对于判断A属于Y1还是Y2的贡献就越大,Ci的信息价值就越大,Ci的IV就越大,它就越应该进入到入模变量列表中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q1dRt63f-1644932140648)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/image-20220213173756240.png)]

计算woe和iv

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mQmh9W8F-1644932140648)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/image-20220213174037928.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5t3X2SK-1644932140649)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/image-20220213174054160.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LtDfT1CB-1644932140649)(F:/ZNV/%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/python/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/image-20220213174145490.png)]

再计算该特征的总值IV,按照阈值划分:

IV预测能力
<0.03
0.03-0.09
0.1-0.29
0.3-0.49
>=0.5极高

练习测试

import sklearn.datasets as dt
import numpy as np
cancer = dt.load_breast_cancer()
feature = cancer['data']
target = cancer['target']

#通过value_counts检测特征是否为连续性变量
pd.Series(feature[:,0]).value_counts()

#函数的封装,最终返回一个特征的总IV值
def get_iv(f,bins,target): 
    #f表示一个维度的特征,bins表示分箱的箱数,taget表示样本标签
    target_count = pd.Series(target).value_counts()
    s_p = target_count[1]#样本中正例样本的数量
    s_n = target_count[0]#样本中反例样本的数量
    
    #对f1特征进行分箱
    f1_cut = pd.qcut(f,q=bins)
    #依次求出5个箱子中正反例样本的数量
    c_result_df = pd.crosstab(f1_cut,target)
    
    ivs = 0
    for index in c_result_df.index:
        #当前组中正例样本的数量
        n_count = c_result_df.loc[index][1]
        #当前组中反例样本的数量
        p_count = c_result_df.loc[index][0]
        woe = np.log((n_count/s_p)/(p_count/s_n))
        iv = ((n_count/s_p)-(p_count/s_n))*woe
        ivs += iv
    return ivs

#可以将每一个维度特征都进行iv计算
for col in range(0,30):
    f1 = feature[:,col]
    result = get_iv(f=f1,bins=3,target=target)
    print(result)

数据集

数据集划分

一般划分数据集分为训练集和测试集,也有验证集的部分,这里主要阐述训练集和验证集

  • 训练集:训练模型

  • 测试集:评估模型

  • 数据集划分的API

    • from sklearn.model_selection import train_test_split
    • train_test_split(x,y,test_size,random_state)参数介绍:
      • x:特征
      • y:目标
      • test_size:测试集的比例
      • random_state:打乱的随机种子
    • 返回值:训练特征,测试特征,训练目标,测试目标

数据集接口介绍

sklearn自带相关数据集

  • sklearn.datasets.load_*():获取小规模的数据集
  • sklearn.datasets.fetch_*(data_home=None,subset):获取大规模的数据集data_home表示数据集下载目录,None为默认值表示的是家目录/scikit_learn_data(自动创建该文件夹)下。需要从网络下载.subset为需要下载的数据集,可以为train,test,all
#获取小规模数据集
import sklearn.datasets as datasets
# 红酒数据集,有三类
data = datasets.load_wine()
#提取特征数据和标签数据
feature = data['data']
target = data['target']
#返回大规模数据集
#data_home:将数据存储到位置
#subset:all,train,test
#random_state:随机种子
datasets.fetch_20newsgroups(data_home='./datasets',subset='test')

切分数据集

#如何切分数据集
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
feature = iris['data']
target = iris['target']
# x_train:训练集的特征数据
# y_train:训练集的标签数据
# x_test:测试集的特征数据
# y_test:测试集的标签数据
# random_state就是为了保证程序每次运行都分割一样的训练集和测试集。否则,同样的算法模型在不同的训练集和测试集上的效果不一样
x_train,x_test,y_train,y_test = train_test_split(feature,target,test_size=0.2,random_state=2020)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

友培

数据皆开源!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值