Julia机器学习 ---- 特征选择

1、为什么要特征选择

特征选择也叫特征子集选择 ( FSS , Feature Subset Selection ) 。是指从已有的M个特征(Feature)中选择N个特征使得系统的特定指标最优化。这么做的理由如下:

一是可以缓解维数灾难,你的机器学习算法的上限,就是你放入的特征

二是降低学习任务的难度,需要寻求尽量少的特征,但是却能真正把握数据的趋势和模式

三是可以增强一点可解释性,不相关的特征就是噪声。

 

2、怎么做

特征选择的方式有很多比如:过滤式,包裹式,嵌入式。但是很多时候凭借人的直觉就可以去掉一些无关的特征。

1、Filter方法
      其主要思想是:对每一维的特征“打分”,即给每一维的特征赋予权重,这样的权重就代表着该维特征的重要性,然后依据权重排序。

      主要的方法有:Chi-squared test(卡方检验),ID3(信息增益),correlation coefficient scores(相关系数)

2、Wrapper方法:
      其主要思想是:将子集的选择看作是一个搜索寻优问题,生成不同的组合,对组合进行评价,再与其他的组合进行比较。这样就将子集的选择看作是一个是一个优化问题,这里有很多的优化算法可以解决,尤其是一些启发式的优化算法,如GA,PSO,DE,ABC等,详见“优化算法——人工蜂群算法(ABC)”,“优化算法——粒子群算法(PSO)”。

      主要方法有:recursive feature elimination algorithm(递归特征消除算法)

3、Embedded方法
      其主要思想是:在模型既定的情况下学习出对提高模型准确性最好的属性。这句话并不是很好理解,其实是讲在确定模型的过程中,挑选出那些对模型的训练有重要意义的属性。

      主要方法:正则化。如岭回归就是在基本线性回归的过程中加入了正则项。

 

3、怎么用

这里没有严格按照上面的分类给出响应的代码示例。但是会把scikit-learn中提到的一些方法,用Julia代码给出示例。

python代码可以参考:Feature selection

3.1 通过方差过滤(一种Filter方法)

VarianceThreshold是一种简单的特征选择基线方法。它删除了方差不满足某个阈值的所有特征。默认情况下,它会删除所有零方差特征,即在所有样本中具有相同值的特征

using LinearAlgebra
using DataFrames,CSV
using Statistics
using ScikitLearn
@sk_import feature_selection: VarianceThreshold

houses = DataFrame(CSV.File(joinpath(dirname(pathof(DataFrames)),"D:/houses.csv")));
feature = Matrix(houses[:, [:beds,:baths,:sq__ft,:price,:latitude,:longitude]])
#设置阈值,也就是会过滤方差<.8 * (1 - .8)
sel = VarianceThreshold(threshold=.8 * (1 - .8))
mapper = fit!(sel,feature)
#很明显过滤了两个不太相关的特征
fit_transform!(mapper, copy(feature))
# 985×4 Array{Float64,2}:
#  2.0  1.0   836.0   59222.0
#  3.0  1.0  1167.0   68212.0
#  2.0  1.0   796.0   68880.0
#  2.0  1.0   852.0   69307.0
#  2.0  1.0   797.0   81900.0
#  3.0  1.0  1122.0   89921.0
#  3.0  2.0  1104.0   90895.0

3.2单变量特征选择(卡方检验)

using LinearAlgebra
using DataFrames,CSV
using Statistics
using ScikitLearn
@sk_import feature_selection: SelectPercentile
@sk_import feature_selection: SelectKBest
#卡方检验是假设检验的一种,用于分析两个类别变量的相关关系
@sk_import feature_selection: chi2
@sk_import datasets: load_boston

houses = DataFrame(CSV.File(joinpath(dirname(pathof(DataFrames)),"D:/houses.csv")));
feature = Matrix(houses[:, [:beds,:baths,:sq__ft,:price,:latitude,:longitude]])
#负值转为正值
feature[:,6] = feature[:,6]*-1
X = feature
y = feature[:,4]
#设置要选择的特征维度
#这个地方要注意的是因变量Y 必须为整数,不能为浮点数。
selector  = SelectKBest(chi2, k=3)
fit_transform!(selector, X,y)

#使用百分比
X,y = load_boston(return_X_y=true)
y = [round(y[i])  for i in 1:length(y)]
selector  = SelectPercentile(chi2, percentile=50)
fit_transform!(selector, X,y)

3.3 递归特征消除(SVC)

SVM简介

支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM的的学习算法就是求解凸二次规划的最优化算法。

SVC和SVR

support vector classify(SVC)支持分类机做二分类的,找出分类面,解决分类问题

support vector regression(SCR)支持回归机做曲线拟合、函数回归 ,做预测,温度,天气,股票

代码示例:

using LinearAlgebra
using DataFrames,CSV
using Statistics
using ScikitLearn
using PyCall
using Colors
using PyPlot
import PyPlot:plot
@sk_import feature_selection: RFE
@sk_import svm: SVC
@sk_import datasets: load_digits
@pyimport numpy as pynumpy

digits = load_digits()
X = digits["images"]
y = digits["target"]

# julia reshape和 Python 中 numpy.reshape的用法还是有区别的,只能用下面的方式 模拟numpy.reshape算法
# X = pynumpy.reshape(digits["images"],(length(digits["images"][:,1,1]), -1))
vector_2D = [X[i,:,:] for i in 1:length(X[:,1,1]) ]
X = convert(Array{Float64,2},X)

#SVM简介
#支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM的的学习算法就是求解凸二次规划的最优化算法。
#对SVC和SVR的理解
#support vector classify(SVC)支持分类机做二分类的,找出分类面,解决分类问题
#support vector regression(SCR)支持回归机做曲线拟合、函数回归 ,做预测,温度,天气,股票
svc = SVC(kernel="linear", C=1)
rfe = RFE(estimator=svc, n_features_to_select=1, step=1)
mapper = fit!(rfe, X, y)

# 最终的矩阵
#fit_transform!(mapper,X, y)

#这里毕竟处理的是图像,尝试画一下图吧
ranking = pynumpy.reshape(rfe.ranking_,pynumpy.shape(images[1,:,:]))

# Plot pixel ranking
PyPlot.matshow(ranking, cmap=PyPlot.cm.Blues)
PyPlot.colorbar()
PyPlot.title("Ranking of pixels with RFE")
PyPlot.show()

 

画图:

 

 

3.4 使用SelectFromModel选择功能

3.4. L1 和 L2

L1、L2这种在机器学习方面叫做正则化,统计学领域的人喊她惩罚项,数学界会喊她范数。范数(norm)是数学中的一种基本概念。在泛函分析中,它定义在赋范线性空间中,并满足一定的条件,即①非负性;②齐次性;③三角不等式。它常常被用来度量某个向量空间(或矩阵)中的每个向量的长度或大小。 L1就是曼哈顿距离 和  L2就是欧式距离

使用注意点:
分别使用L1和L2拟合,如果两个特征在L2中系数相接近,在L1中一个系数为0一个不为0,那么其实这两个特征都应该保留,原因是L1对于强相关特征只会保留一个, L2不能直接特征选择,只能约束系数大小。L1可以,因为L1 penalty是一个高维菱形,与最小二乘结合起来的损失函数最优解往往在菱形的边或顶点上,这时候就有系数为0

LinearSVC函数的参数说明如下:

# LinearSVC 线性拟合函数
# penalty : string, ‘l1’ or ‘l2’ (default=’l2’)指定惩罚中使用的规范。 'l2'惩罚是SVC中使用的标准。 'l1'导致稀疏的coef_向量。
# loss : string, ‘hinge’ or ‘squared_hinge’ (default=’squared_hinge’)指定损失函数。 “hinge”是标准的SVM损失(例如由SVC类使用),而“squared_hinge”是hinge损失的平方。
# dual : bool, (default=True)选择算法以解决双优化或原始优化问题。 当n_samples> n_features时,首选dual = False。
# tol : float, optional (default=1e-4)公差停止标准
# C : float, optional (default=1.0) 正则化参数。正则化的强度与C成反比。必须是严格正的。
# multi_class : string, ‘ovr’ or ‘crammer_singer’ (default=’ovr’)如果y包含两个以上的类,则确定多类策略。 “ovr”训练n_classes one-vs-rest分类器,而“crammer_singer”优化所有类的联合目标。 虽然crammer_singer在理论上是有趣的,因为它是一致的,但它在实践中很少使用,因为它很少能够提高准确性并且计算成本更高。 如果选择“crammer_singer”,则将忽略选项loss,penalty和dual。
# fit_intercept : boolean, optional (default=True)是否计算此模型的截距。 如果设置为false,则不会在计算中使用截距(即,预期数据已经居中)。
# intercept_scaling : float, optional (default=1) 当self.fit_intercept为True时,实例向量x变为[x,self.intercept_scaling],即具有等于intercept_scaling的常量值的“合成”特征被附加到实例向量。 截距变为intercept_scaling *合成特征权重注意! 合成特征权重与所有其他特征一样经受l1 / l2正则化。 为了减小正则化对合成特征权重(并因此对截距)的影响,必须增加intercept_scaling。
# class_weight : {dict, ‘balanced’}, optional将类i的参数C设置为SVC的class_weight [i] * C. 如果没有给出,所有课程都应该有一个重量。 “平衡”模式使用y的值自动调整与输入数据中的类频率成反比的权重,如n_samples /(n_classes * np.bincount(y))
# verbose : int, (default=0)启用详细输出。 请注意,此设置利用liblinear中的每进程运行时设置,如果启用,可能无法在多线程上下文中正常工作。
# random_state : int, RandomState instance or None, optional (default=None) 在随机数据混洗时使用的伪随机数生成器的种子。 如果是int,则random_state是随机数生成器使用的种子; 如果是RandomState实例,则random_state是随机数生成器; 如果为None,则随机数生成器是np.random使用的RandomState实例。
# max_iter : int, (default=1000) 要运行的最大迭代次数。

样例代码:

using LinearAlgebra
using DataFrames,CSV
using Statistics
using ScikitLearn
@sk_import feature_selection: SelectFromModel
@sk_import linear_model: LassoCV
@sk_import svm: LinearSVC
@sk_import datasets : load_iris

X, y = load_iris(return_X_y=true)

lsvc = LinearSVC(C=0.01, penalty="l1", dual=false)
model = SelectFromModel(lsvc, prefit=false)
fit_transform!(model, copy(X),y)

lsvc2 = LinearSVC(C=0.01, penalty="l2", dual=false)
model2 = SelectFromModel(lsvc2, prefit=false)
fit_transform!(model, copy(X),y)

待补充.......

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

October-

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值