机器学习笔记——特征工程、常见机器学习算法及python_sklearn库的API使用

先推荐一款免费的笔记本,sublime_text
可以选择各种编程语言方便程序的编写和记录,如果用虚拟机登录mysql数据库也可以先在sublime上写sql语句,方便修改。

一、首先有两个基本问题

1.1 机器学习是干什么的?

从数据中自动分析获得规律(模型),并利用规律对未知数据进行预测

1.2 哪些使用场景?

医疗、航空、物流、电商…等自动化需求的场景

二、数据集的构成和处理

2.1 数据集的构成

数据集大多是csv格式文件,可以用pandas读取

(1)特征值+目标值(要干的事情),根据特征去判断目标,不是所有特征都需要,根据需要修改

(2)每一行是一个样本,每一列是一个特征

(3)有些数据集可以没有目标值(用非监督学习算法,典型代表聚类k-means)

获取特征值

li = 数据集

li.data

获取目标值

li.target

数据集进行分割

x_train,x_test,y_train,y_test =
sklearn.model_selection.train_test_split(li.data,li.target,test_size=0.25)

test_size= 比例    返回值包含训练集合测试集  用x_train代表训练集的特征值,x_target代表训练集的目标值
x_test测试集的特征值,y_test测试集的目标值
x:数据集的特征值
y:数据集的目标值
test_size:测试集的大小

2.2 对特征的处理

文本不能直接输入让机器计算,需要数据化,这就需要特征工程

对缺失值:数据转换

对重复值:不处理(机器学习中不需要去重)

特征工程包括:特征抽取、特征预处理、数据降维

2.2.1 特征抽取

比如将文本转换成数字类型

文本、字符串转换成数字形式

对文本等数据进行特征值化,为了计算机更好的理解数据,只能理解数据

1.字典特征抽取 对字典进行特征值化 转成one-hot编码形式

API:sklearn.feature_extraction.DictVectorizer 
#Vectorizer数字化
语法:DicVectorizer(sparse=True,...)
DictVectorizer.fit_transform(X)
X:字典或者包含字典的迭代器  字典放在列表里
返回值:返回sparse矩阵   #scipy中的数据类型 
DictVectorizer.get_feature_names()  
返回类别名称
DictVectorizer.transform(X)
按照原先的标准转换

2.文本特征抽取

对文本等数据进行特征值化

API:sklearn.feature_extraction.text.TfidfVectorizer
语法:TfidfVectorizer(stop_words=None,...)  #stop_words= 忽略哪些词
TfidfVectorizer.fit_transform(X)
X:文本或者包含文本字符串的可迭代对象
返回值:返回sparse矩阵
TfidfVectorizer.get_feature_names()  
第一行特征名称
返回值:单词列表
得到的列表是每个词的重要性程度

2.2.2 特征预处理

1.归一化

通过对原始数据进行变换把数据映射到(默认[0,1]之间)

公式: X’ =(x-min)/(max-min) X’’ = X’*(mx-mi)+mi

每一列特征,最大值max,最小值min mx,mi分别指定区间,默认mx为1,mi为0

API:sklearn.preprocessing.MinMaxScaler   
最小最大值缩放
语法:MinMaxScaler(feature_range=(0,1)...)  #feature_range 缩放到什么范围
MinMaxScaler.fit_transform(X)

各个特征同等重要的时候,需要进行归一化,使得一个特征对最终结果不会造成更大影响

数据中异常点较多(从公式考虑),列的最大值最小值改变,最终计算的结果有偏差

归一化容易受异常点影响,鲁棒性较差,只适合传统精确小数据场景,一般不使用归一化

2.标准化

不容易受到异常点影响

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

公式:X’ =(x-mean)/δ #作用于每一列,mean为平均值,δ为标准差

var(方差) =((x1-mean)^2 +(x2-mean)^2 +…)/m(每个特征的样本数) δ=√var

作用于每一列 方差为0,这个特征所有值都一样,方差越大,数据越离散

API:scikit-learn.preprocessing.StandardScaler    #标准缩放
StandardScaler.fit_transform(X)
X:numpy array 格式的数据[n_samples,n_features]
返回值:转换后的形状相同的array
StandardScaler.mean_
原始数据中每列特征的平均值
StandardScaler.std()
原始数据每列特征的方差

在已有样本足够多的情况下比较稳定,适合现代嘈杂的大数据场景

2.2.3 数据降维

维度:和数组的维度不一样,指特征的数量

降维:比如3个特征转换成2个特征,特征数量减少

两种方式:1.特征选择 2.主成分分析

过滤式

删除低方差的特征

把方差过小的、差不多的特征过滤掉

API:sklearn.feature_selection.VarianceThreshold

主成分分析

API:sklearn.decomposition    #主成分分析

PCA:数据维数压缩,尽可能降低数据的维数(复杂度),损失少量信息 #应用场景不是特别多

特征数量达到上百的时候,考虑pca数据简化

PCA:数据会改变,特征数量会减少

高维度数据容易出现的问题:特征之间通常是相关的

语法:PCA(n_components=None)
n_components:小数 0-1  指定保留多少信息 经验 90%-95%之间
整数 减少到的特征数量(一般不使用)
PCA.fit_transform(X)
X:numpy array 格式的数据[n_samples,n_features]
返回值:转换后指定维度的array

2.3 转换器

特征工程步骤:

1.实例化API

2.调用fit_transform

fit_transform() #输入数据直接转换
fit() #输入数据,不转换
计算平均值标准差
+transform() #进行数据的转换
先加数据用fit_transform(),再加数据直接用transform(),不用fit()和fit_transform(),fit输入内容不同转换的标准改变

三、常见机器学习算法

3.1 k近邻算法(KNN)

定义:一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别

核心思想:比较特征的远近,相似的样本特征之间的值应该是相近的

需要做标准化处理,防止某特征距离过大影响过大

欧式距离:√((a1-b1)^2 + (a2-b2)^2 +(a3-b3)^2)

API:sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
n_neighbors=5 默认使用的邻居数

3.2 朴素贝叶斯

预测每个文档是各个类别的概率,可能性,然后划分类别

朴素贝叶斯的前提:特征独立

P(科技|文档)替换成 P(科技|词1,词2,词3…)

P(娱乐|文档…) 文档2:词1,词2,词3…

和条件概率不一样,条件概率是一个条件下多个结果,现在是多个条件一个类别

此时需要贝叶斯公式

P(C|W)=(P(W|C)P(C ))/P(W)

W:为给定文档的特征值 C:为文档类别

可以理解为:P(C|F1,F2,…)=(P(F1,F2,…|C)P(C ))/P(F1,F2,…)

API:sklearn.naive_bayes.MultinomialNB
参数:alpha = 1.0默认  拉普拉斯平滑系数 防止出现0

算法不需要调参,影响准确率的因素就是训练集,训练集影响非常大

3.3 决策树、随机森林

问题:哪个特征放在最上面

1个字节8比特 信息定义成比特

比如:32个球队,不知道任何一支球队信息,猜对冠军的最大代价是5比特

开放一些数据信息,代价小于5比特

5=-(1/32log(1/32)+1/32log(1/32)+…)

把比特理解成代价,这个代价就是信息熵

H(X)=∑P(x)logP(x) H信息熵,单位:比特

信息和消除不确定性是相联系的

信息熵越大不确定性越大,越小不确定性越小

决策树的划分依据之一—————信息增益

当得知一个特征条件之后,减少的信息熵的大小

g(D,A)=H(D)-H(D|A) g:信息增益(某一个特征减少信息熵的大小)
A:一个特征

H(D):初始信息熵大小 H(D|A):A条件下的信息熵

决策树API:sklearn.tree.DecisionTreeClassifier(criterion='gini',max_depth=None,random_state=None)
criterion:默认是'gini'系数,也可以选择信息增益的熵'entropy'
max_depth:树的深度大小  几层
random_state:随机数种子
decision_path:返回决策树的路径
criterion= 选择依据

随机森林:

随机森林包含多个决策树的分类器,输出的类别是由个别树输出的类别的众数而定

多个决策树投票

单个树建立过程:N个样本,M个特征

1.样本
随机在N个样本当中选择一个样本(复制拿过来,不减少),重复N次
样本有可能重复

2.特征
随机在M个特征当中选出m个(小于M)特征

建立了10颗决策树,样本,特征大多不一样 随机有放回的抽样(bootstrap抽样)

为什么随机抽样训练集:每个决策树不一样

为什么有放回的抽样:无放回会使每个树都是完全不同的,每棵树训练出来有很大的差异,而随机森林最后分类取决于多棵树(弱分类器)的投票表决

API:sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion='gini',max_depth=None,bootstrap=True,random_state=None,max_features="auto")    #还有很多参数
n_estimators=  建立多少棵决策树 一般给120,200,300,500,800,1200
超参数
criterion=  分类依据 基尼系数,信息增益  一般用基尼系数gini
max_depth=  每一棵树的深度限制                               超参数
bootstrap=True  随机有放回  默认True
random_state=  随机种子  不用管
max_features="auto"  每个决策树的最大特征数量  m的最大值,防止过拟合
auto:自动  最大特征数是特征数开根号
sqrt:根号 最大特征数是特征数开根号
log2: 以log2求  比如 3=log2(8)  8是总特征值

3.4 线性回归

定义:通过一个或多个自变量与因变量之间进行建模的回归分析。

目标值是连续的值就可以用回归算法来做,回归就是在找一种趋势

线性关系模型:f(x)=w1x1+w2x2+…+wdxd+b

线性关系模型中:w表示权重(找出这个值) b偏置项

损失函数(误差大小) 损失函数就是误差

yi为第i个样本的真实值,hw(xi)为第i个样本特征值组合预测函数,
(预测结果-真实结果)^2和

总损失:J(θ)=(hw(x1)-y1)^2 + (hw(x2)-y2)^2 +…=∑(hw(xi)-yi)^2

如何寻找w

1.正规方程 当特征过于复杂,求解速度太慢

2.梯度下降 α学习速率,需手动指定(超参数)

理解:沿着函数下降方向找,最后找到最低点,更新W值

使用:面对训练数据十分庞大的任务

正规方程API:sklearn.linear_model.LinearRegression
普通最小二乘线性回归(正规方程)
coef_:回归系数  最终的W值  W就是回归系数

梯度下降API:sklearn.linear_model.SGDRegressor
通过使用SGD最小化线性模型
coef_:回归系数  最终的W值  W就是回归系数

回归性能评估(均方误差) 平均每一个样本的差值的平方

MSE=(1/m)∑(yi(预测值)-y(真实值))^2

回归评估API:sklearn.metrics.mean_squared_error  #metrics度量
mean_squared_error(y_true,y_pred)
y_true 真实值
y_pred 预测值
return:浮点数结果

真实值、预测值为标准化之前的值

过拟合欠拟合

训练的很好,但是测试数据时却没有很好的效果,怎么办?

线性回归拟合的数据不一定是线性的,对线性模型进行训练学习会变成复杂模型

模型复杂的原因:数据的特征和目标值之间的关系不仅仅是线性关系

根据结果现象判断过拟合还是欠拟合

通过交叉验证看训练集的结果:

欠拟合:训练集表现不好,测试集表现不好,看准确率和误差

过拟合:训练集特别好,测试集表现不好,考虑特征数据是不是过于复杂

过拟合原因:原始特征过多,存在嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点

正则化解决过拟合

影响模型复杂度的是高次项,尝试调整把高次项系数(权重)减少趋近于0,尽量减少高次项特征影响,不断尝试得来

L2正则化:使得W的每个元素都很小,都接近于0(把高次项权重减小,使权重趋近于0 )

优点:越小的参数说明模型越简单,越简单的模型越不容易产生过拟合现象

线性回归:LinearRegression 容易出现过拟合,为了使训练集数据表现更好

岭回归:Ridge 带有正则化的线性回归

岭回归API:sklearn.linear_model.Ridge
sklearn.linear_model.Ridge(alpha=1.0)    #0-1 1-10 小数或整数 可以用网格搜索选择
alpha:正则化力度   超参数 

正则化力度越大,权重趋近于0(不是等于0),模型越来越简单,但是不能过简单,正则化力度是一个需要调参的过程

coef_:回归系数

3.5 分类算法-逻辑回归

二分类问题利器,线性回归的式子作为输入

应用场景:广告点击率、是否为垃圾邮件、是否患病、金融诈骗、虚假账号

只能做二分类问题,任何二分类场景都能得出概率值

逻辑回归的输入:和线性回归一样

输入:Z(w)=w0+w1x1+w2x2+…=wTx
#得出一个值

也和线性回归一样存在过拟合问题

sigmoid函数:将输入(x)转换成 0-1之间的某个值

与y轴交叉的地方默认 0.5 #因为sigmoid函数把输入转换成0-1之间的概率值

g(z)=1/(1+e-z) # -z为上角标 e:2.71 z=回归的结果

g(z)输出:[0,1]区间的概率值,默认0.5作为阈值(小于0.5归为0,大于0.5归为1)

逻辑回归的损失函数:

与线性回归原理相同,但由于是分类问题,损失函数不一样,只能通过梯度下降求解

对数似然损失函数(类型信息熵的角度)

损失函数:均方误差(只有一个最小值,不存在多个局部最低点)

对数似然损失:有多个局部最小值(到目前没有更好的解决办法,目前解决不了)

解决办法(尽量改善,不能最终解决,尽管没有全局最低点,但是效果不错):

1.多次随机初始化,多次比较最小值结果

2.在求解过程中,调整学习率(比如加大学习率直接跳过局部最低点)

逻辑回归API:sklearn.linear_model.LogisticRegression
sklearn.linear_model.LogisticRegression(penalty='l2',C=1.0)
penalty= 正则化
有线性回归的过拟合,参数penalty='l2'以l2的形式正则化,C=1.0正则化力度
Logistic回归分类器
coef_:回归系数

3.6 非监督学习算法

只有特征值,没有目标值

k-means:聚类 把有相似特征的归成一类

比如:一些数据有2个特征,分成3个类别

k:把数据划分成多少个类别

k的取值:一般知道类别的个数

不知道类别个数,超参数,比如取3

1.随机在数据当中抽取三个样本,当做三个类别的中心点(k1,k2,k3)

2.计算其余的点分别到这三个中心点的距离(每一个样本有三个距离,从中选出距离最近的一个点,作为自己的标记,形成三个族群)

3.分别计算三个族群的平均值,把三个平均值与之前的三个旧中心点比较,如果相同,结束聚类;如果不同,把这三个平均值当做新的中心点,重复第二步

k-meansAPI:sklearn.cluster.KMeans    #cluster聚类    KMeans k均值
sklearn.cluster.KMeans(n_clusters=8,init='k-means++')
n_clusters:开始的聚类中心数量  把样本分为多少个类别
init:初始化方法,默认为'k-means++'
labels_:默认标记的类型,可以和真实值比较(不是值比较)

一般聚类做在分类之前

你可能感兴趣的:(机器学习笔记——特征工程、常见机器学习算法及python_sklearn库的API使用)