训练机器学习算法所涉及的五个主要步骤可以概述如下:
1、特征的选择
2、确定性能评价标准
3、选择分类器及其优化算法
4、对模型性能的评估
5、算法的调优
感知器是机器学习分类算法中优雅易用的一个入门级算法,不过其最大的缺点在于:在样本不是 完全线性可分的情况下,他永远不会收敛。
逻辑斯谛回归(logistics regression)分类模型 激励函数为sigmoid函数
可解释性 决策树
通过梯度下降进行优化的在线学习方法,给出带预测问题发生的概率 逻辑斯蒂回归
线性+非线性(核技巧映射) 为了达到好的效果要调整较多的参数 SVM
不需要调整过多参数且不像决策树那样容易过拟合 集成方法(如随机森林)
通过计算来完成 KNN
原文demo:
from sklearn.cross_validation import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=0)
一般形式:
train_test_split是交叉验证中常用的函数,功能是从样本中随机的按比例选取train data和testdata,形式为:
X_train,X_test, y_train, y_test =
cross_validation.train_test_split(train_data,train_target,test_size=0.4, random_state=0)
参数解释:
train_data:所要划分的样本特征集
train_target:所要划分的样本结果
test_size:样本占比,如果是整数的话就是样本的数量
random_state:是随机数的种子。
随机数种子是为了保证每次随机的结果都是一样的。这里的random_state就是为了保证程序每次运行都分割一样的训练集合测试集。否则,同样的算法模型在不同的训练集和测试集上的效果不一样。
当你用sklearn分割完测试集和训练集,确定模型和促初始参数以后,你会发现程序每运行一次,都会得到不同的准确率,无法调参。这个时候就是因为没有加random_state。加上以后就可以调参了。
随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:
种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。
随机数种子(random seed)在伪随机数生成器中用于生成伪随机数的初始数值(相当于一个算法)。对于一个伪随机数生成器,从相同的随机数种子出发,可以得到相同的随机数序列。随机数种子通常由当前计算机状态确定,如当前的时间。
原文代码:
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
使用该类的好处在于可以保存训练集中的参数(均值、方差)直接使用其对象转换测试集数据。
使用StandardScaler中的fit方法,计算训练数据中每个特征的均值和标准差,
通过调用transform方法,可以使用计算得到的均值和方差来对训练数据做标准化处理。
知识点4:使用Perceptron(感知器)类进行感知机模型进行训练
原文代码:
from sklearn.linear_model import Perceptron
ppn = Perceptron(max_iter =40,eta0=0.1,random_state=0)
ppn.fit(X_train_std,y_train)
max_iter :迭代次数
eta0:学习速率
random_state:在每次迭代后初始化重排训练数据集
原文代码:
from sklearn.metrics import accuracy_score
print('Accuracy:%.2f'% accuracy_score(y_test,y_pred))
eg:
import numpy as np
from sklearn.metrics import accuracy_score
y_pred = [0, 2, 1, 3,9,9,8,5,8]
y_true = [0, 1, 2, 3,2,6,3,5,9]
accuracy_score(y_true, y_pred)
Out[127]: 0.33333333333333331
accuracy_score(y_true, y_pred, normalize=False) # 类似海明距离,每个类别求准确后,再求微平均
Out[128]: 3
函数原型为:stack(arrays, axis=0),arrays可以传数组和列表。axis的含义我下面会讲解,我们先来看个例子,然后我会分析输出结果。
import numpy as np
a=[[1,2,3],
[4,5,6]]
print("列表a如下:")
print(a)
print("增加一维,新维度的下标为0")
c=np.stack(a,axis=0)
print(c)
print("增加一维,新维度的下标为1")
c=np.stack(a,axis=1)
print(c)
在Python中,经常会用到关于数组的堆叠,如np.stack函数就是一个用于numpy数组堆叠的函数,关于该函数的用法,大都是给出了示例,而没有分析其中原理,下面会举例关于np.stack函数的用法,示例和原理。
np.stack函数的调用方式:
import numpy as np
np.stack(arrays,axis)
下面给出一个具体的示例如下:
a = np.array([[1,2,3,4], [5,6,7,8]])
b = np.array([[2,2,1,4], [3,5,7,8]])
c = np.array([[5,7,7,3], [6,6,2,8]])
arrays = np.asarray([a, b , c])
a
Out[51]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
b
Out[58]:
array([[2, 2, 1, 4],
[3, 5, 7, 8]])
c
Out[65]:
array([[5, 7, 7, 3],
[6, 6, 2, 8]])
arrays
Out[61]:
array([[[1, 2, 3, 4],
[5, 6, 7, 8]],
[[2, 2, 1, 4],
[3, 5, 7, 8]],
[[5, 7, 7, 3],
[6, 6, 2, 8]]])
np.stack(arrays, axis=0)
Out[62]:
array([[[1, 2, 3, 4],
[5, 6, 7, 8]],
[[2, 2, 1, 4],
[3, 5, 7, 8]],
[[5, 7, 7, 3],
[6, 6, 2, 8]]])
np.stack(arrays, axis=1)
Out[63]:
array([[[1, 2, 3, 4],
[2, 2, 1, 4],
[5, 7, 7, 3]],
[[5, 6, 7, 8],
[3, 5, 7, 8],
[6, 6, 2, 8]]])
np.stack(arrays, axis=2)
Out[64]:
array([[[1, 2, 5],
[2, 2, 7],
[3, 1, 7],
[4, 4, 3]],
[[5, 3, 6],
[6, 5, 6],
[7, 7, 2],
[8, 8, 8]]])
下面分析一下其中原理。
arrays.shape
Out[66]: (3, 2, 4)
arrays[0] #axis=0
Out[67]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
arrays[0][0] #axis=1
Out[68]: array([1, 2, 3, 4])
arrays[0][0][0] #axis=2
Out[69]: 1
从arrays.shape可以看出arrays有三个轴,即axis=0, 1, 2。当axis=0时表示最外层的中括号,三个轴则最外层有三个中括号。axis=0则表示将向内一层的内容看做一个整体,比如示例中arrays[0]的值,axis=1在在axis=0的基础上再取更内一层的内容,层层向内解包,最后进入axis=2,则直接取得元素的值,如arrays[0][0][0]。
由以上的理论可知,np.stack(arrays, axis=0)则表示取出每个二维数组(最外层有两个中括号)相应的索引对应的数组进行堆叠,这里np.stack(arrays, axis=0)则表示arrays[0], arrays[1], arrays[2]进行堆叠,所以结果与原始数组一样。
np.stack(arrays, axis=1)则表示arrays[0][0], arrays[1][0]和arrays[2][0]进行堆叠,然后是arrays[0][1],arrays[1][1]与arrays[2][1]进行堆叠。
np.stack(arrays, axis=2)则表示arrays[0][0][0],arrays[1][0][0]和arrays[2][0][0]进行堆叠,然后是arrays[0][0][1],arrays[1][0][1]与arrays[2][0][1]进行堆叠,接着为arrays[0][0][2],arrays[1][0][2]与arrays[2][0][2]进行堆叠…
大家发现了没有,串起来的时候其实就是把arrays中每个元素在相同的位置套箱子的一些小块(这里叫小块这个名词可能不洽当,但是大家明白就行)放在一起后,再套箱子,就是外面套个中括号,这就是堆叠。
再看下面的代码的输出,测试下你理解的没有。
import numpy as np
a=[[1,2,3,4],
[5,6,7,8],
[9,10,11,12]]
print("列表a如下:")
print(a)
print("增加一维,新维度的下标为0")
c=np.stack(a,axis=0)
print(c)
print("增加一维,新维度的下标为1")
c=np.stack(a,axis=1)
print(c)
输出:
列表a如下:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
增加一维,新维度的下标为0
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
增加一维,新维度的下标为1
[[ 1 5 9]
[ 2 6 10]
[ 3 7 11]
[ 4 8 12]]
不知道和你想象的输出一样不一样,还有另一种情况,先看下面的代码。
import numpy as np
a=[1,2,3,4]
b=[5,6,7,8]
c=[9,10,11,12]
print("a=",a)
print("b=",b)
print("c=",c)
print("增加一维,新维度的下标为0")
d=np.stack((a,b,c),axis=0)
print(d)
print("增加一维,新维度的下标为1")
d=np.stack((a,b,c),axis=1)
print(d)
输出:
(‘a=’, [1, 2, 3, 4])
(‘b=’, [5, 6, 7, 8])
(‘c=’, [9, 10, 11, 12])
增加一维,新维度的下标为0
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
增加一维,新维度的下标为1
[[ 1 5 9]
[ 2 6 10]
[ 3 7 11]
[ 4 8 12]]
你会发现输出结果和上面的代码一样,其实它俩就是一样的。只不过当你对arrays传参的时候,如果你传的参数是类似于(a,b,c)这种,它会把(a,b,c)当做一个元组来看,a,b,c都是元组的每个元素。然后分别对每个元素处理,上面我已经说了,arrays传的参数可以是列表,元组,或者numpy数组。所以传(a,b,c)和传[a,b,c]或者当x=[a,b,c]的时候传x,效果都是一样的。
上面的代码处理的arrays元素都是一维变二维的情况,下面我们看看二维变三维是什么样的。
import numpy as np
a=[[1,2,3],
[4,5,6]]
b=[[1,2,3],
[4,5,6]]
c=[[1,2,3],
[4,5,6]]
print("a=",a)
print("b=",b)
print("c=",c)
print("增加一维,新维度的下标为0")
d=np.stack((a,b,c),axis=0)
print(d)
print("增加一维,新维度的下标为1")
d=np.stack((a,b,c),axis=1)
print(d)
print("增加一维,新维度的下标为2")
d=np.stack((a,b,c),axis=2)
print(d)
输出:
(‘a=’, [[1, 2, 3], [4, 5, 6]])
(‘b=’, [[1, 2, 3], [4, 5, 6]])
(‘c=’, [[1, 2, 3], [4, 5, 6]])
增加一维,新维度的下标为0
[[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]]
增加一维,新维度的下标为1
[[[1 2 3]
[1 2 3]
[1 2 3]]
[[4 5 6]
[4 5 6]
[4 5 6]]]
增加一维,新维度的下标为2
[[[1 1 1]
[2 2 2]
[3 3 3]]
[[4 4 4]
[5 5 5]
[6 6 6]]]
当axis=0的时候,列表a,b,c最外面都需要套箱子(就是加中括号),那么我把你们先放一起,变成下面这样
[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]]
然后在最外面套箱子,变成
[
[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]]
]
当axis=1的时候,列表a,b,c中的[1,2,3]需要套同样的箱子,列表a,b,c中的[4,5,6]需要套同样的箱子,好,我先把你们放一块变成下面这样
[
[1,2,3],[1,2,3],[1,2,3]
,
[4,5,6],[4,5,6],[4,5,6]
]
然后开始分别在 [1,2,3],[1,2,3],[1,2,3]的外面和[4,5,6],[4,5,6],[4,5,6]的外面套箱子,变成下面这样
[
[[1,2,3],[1,2,3],[1,2,3]]
,
[[4,5,6],[4,5,6],[4,5,6]]
]
当axis=2的时候,列表a,b,c中的1,2,3,4,5,6都需要套箱子,我把你们先放一起变成:
[
[1,1,1 , 2,2,2 , 3,3,3],
[4,4,4 , 5,5,5 , 6,6,6]
]
然后在1,1,1 ………6,6,6的外面分别套箱子变成:
[
[[1,1,1] , [2,2,2] , [3,3,3]],
[[4,4,4] , [5,5,5] , [6,6,6]]
]
2. hstack()函数
函数原型:hstack(tup) ,参数tup可以是元组,列表,或者numpy数组,返回结果为numpy的数组。看下面的代码体会它的含义
import numpy as np
a=[1,2,3]
b=[4,5,6]
print(np.hstack((a,b)))
输出:[1 2 3 4 5 6 ]
import numpy as np
a=[[1],[2],[3]]
b=[[1],[2],[3]]
c=[[1],[2],[3]]
d=[[1],[2],[3]]
print(np.hstack((a,b,c,d)))
输出:
[[1 1 1 1]
[2 2 2 2]
[3 3 3 3]]
它其实就是水平(按列顺序)把数组给堆叠起来,vstack()函数正好和它相反。
函数原型:vstack(tup) ,参数tup可以是元组,列表,或者numpy数组,返回结果为numpy的数组。看下面的代码体会它的含义
import numpy as np
a=[1,2,3]
b=[4,5,6]
print(np.vstack((a,b)))
输出:
[[1 2 3]
[4 5 6]]
import numpy as np
a=[[1],[2],[3]]
b=[[1],[2],[3]]
c=[[1],[2],[3]]
d=[[1],[2],[3]]
print(np.vstack((a,b,c,d)))
输出:
[[1]
[2]
[3]
[1]
[2]
[3]
[1]
[2]
[3]
[1]
[2]
[3]]
它是垂直(按照行顺序)的把数组给堆叠起来。
horizontal vertical
原文代码:
plt.axvline(0.0, color=‘k’) # 在坐标轴上加一条竖直的线,0.0为竖直线在坐标轴上的位置
axhline()表示绘制了一条y=0的水平线
axvline()表示绘制了一条x=0的垂直线
axhline(4)表示绘制了一条y=4的水平线
l=[-1, 1, -10, 10]
plt.axis(l)
plt.axhline()
plt.axvline()
plt.axhline(4)
原文代码:
plt.axhspan(0.0,1.0,facecokor='1.0',alpha=1.0,ls='dotted')
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(-1, 2, .01)
s = np.sin(2*np.pi*t)
plt.plot(t, s)
# draw a thick red hline at y=0 that spans the xrange
l = plt.axhline(linewidth=4, color='r')
# draw a default hline at y=1 that spans the xrange
l = plt.axhline(y=1)
# draw a default vline at x=1 that spans the yrange
l = plt.axvline(x=1)
# draw a thick blue vline at x=0 that spans the upper quadrant of
# the yrange
l = plt.axvline(x=0, ymin=0.75, linewidth=4, color='b')
# draw a default hline at y=.5 that spans the middle half of
# the axes
l = plt.axhline(y=.5, xmin=0.25, xmax=0.75)
p = plt.axhspan(0.25, 0.75, facecolor='0.5', alpha=0.5)
p = plt.axvspan(1.25, 1.55, facecolor='g', alpha=0.5)
plt.axis([-1, 2, -1, 2])
plt.show()
原文代码:
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(C=1000.0,random_state=0)
eg:
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(penalty=’l2’, dual=False, tol=0.0001, C=1.0,
fit_intercept=True, intercept_scaling=1, class_weight=None,
random_state=None, solver=’liblinear’, max_iter=100, multi_class=’ovr’,
verbose=0, warm_start=False, n_jobs=1)
减小参数C的值,也就是增大正则化项的系数(C与正则化系数互为倒数),可以导致权重系数逐渐收缩。
penalty:使用指定正则化项(默认:l2)
dual: n_samples > n_features取False(默认)
C:正则化lambda的倒数,值越小正则化强度越大
n_jobs: 指定线程数
random_state:随机数生成器
fit_intercept: 是否需要常量
“”"
知识点11+1:支持向量机(SVM)
在感知器算法中,我们可以最小化分类误差。而在SVM中,我们的优化目标是最大化分类间隔。此处分类间隔是指两个分离的超平面(决策边界)的距离,而最靠近超平面的训练样本称作支持向量。
前面在回归的正则化中已经做出了讨论,我们通过增加C的值来增加偏差并降低模型的方差。
SVM可以使用“核技术”来解决非线性可分问题
核方法处理此类非线性可分数据的基本理念就是:通过映射函数φ(·)将样本的原始特征映射到一个使样本线性可分的更高维空间中。
比如我们可以将二位数据集通过下列映射转换到新的三维特征空间中,从而使得样本可分:
φ(x1,x2)=(z1,z2,z3)=(x1,x2,x1²+x2²)
svm(kernel=‘rbf’,random_state=0,gamma=0.10,C=10.0)
gamma为截止函数,减小γ的值,会导致决策边界变得宽松。
使用sklearn中自带的决策树方法简单代码 如下:
from sklearn import tree
mode = tree.DecisionTreeClassifier(criterion=‘gini’)
mode.fit(X,Y)
y_test = mode.predict(x_test)
其中对于函数 tree.DecisionTreeClassifier()中的具体参数,在sklearn的官网中有给出,如下:
class sklearn.tree.DecisionTreeClassifier(criterion=‘gini’, splitter=‘best’,max_depth=None, min_samples_split=2,min_samples_leaf =1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None,class_weight=None, presort=False)
根据官网提供的信息,这里进行了简单的翻译(自己理解的也不够透彻,仅供简单参考):
criterion:string类型,可选(默认为"gini")
衡量分类的质量。支持的标准有"gini"代表的是Gini impurity(不纯度)与"entropy"代表的是information gain(信息增益)。
splitter:string类型,可选(默认为"best")
一种用来在节点中选择分类的策略。支持的策略有"best",选择最好的分类,"random"选择最好的随机分类。
max_features:int,float,string or None 可选(默认为None)
在进行分类时需要考虑的特征数。
1.如果是int,在每次分类是都要考虑max_features个特征。
2.如果是float,那么max_features是一个百分率并且分类时需要考虑的特征数是int(max_features*n_features,其中n_features是训练完成时发特征数)。
3.如果是auto,max_features=sqrt(n_features)
4.如果是sqrt,max_features=sqrt(n_features)
5.如果是log2,max_features=log2(n_features)
6.如果是None,max_features=n_features
注意:至少找到一个样本点有效的被分类时,搜索分类才会停止。
max_depth:int or None,可选(默认为"None")
表示树的最大深度。如果是"None",则节点会一直扩展直到所有的叶子都是纯的或者所有的叶子节点都包含少于min_samples_split个样本点。忽视max_leaf_nodes是不是为None。
min_samples_split:int,float,可选(默认为2)
区分一个内部节点需要的最少的样本数。
1.如果是int,将其最为最小的样本数。
2.如果是float,min_samples_split是一个百分率并且ceil(min_samples_split*n_samples)是每个分类需要的样本数。ceil是取大于或等于指定表达式的最小整数。
min_samples_leaf:int,float,可选(默认为1)
一个叶节点所需要的最小样本数:
1.如果是int,则其为最小样本数
2.如果是float,则它是一个百分率并且ceil(min_samples_leaf*n_samples)是每个节点所需的样本数。
min_weight_fraction_leaf:float,可选(默认为0)
一个叶节点的输入样本所需要的最小的加权分数。
max_leaf_nodes:int,None 可选(默认为None)
在最优方法中使用max_leaf_nodes构建一个树。最好的节点是在杂质相对减少。如果是None则对叶节点的数目没有限制。如果不是None则不考虑max_depth.
class_weight:dict,list of dicts,“Banlanced” or None,可选(默认为None)
表示在表{class_label:weight}中的类的关联权值。如果没有指定,所有类的权值都为1。对于多输出问题,一列字典的顺序可以与一列y的次序相同。
"balanced"模型使用y的值去自动适应权值,并且是以输入数据中类的频率的反比例。如:n_samples/(n_classes*np.bincount(y))。
对于多输出,每列y的权值都会想乘。
如果sample_weight已经指定了,这些权值将于samples以合适的方法相乘。
random_state:int,RandomState instance or None
如果是int,random_state 是随机数字发生器的种子;如果是RandomState,random_state是随机数字发生器,如果是None,随机数字发生器是np.random使用的RandomState instance.
persort:bool,可选(默认为False)
是否预分类数据以加速训练时最好分类的查找。在有大数据集的决策树中,如果设为true可能会减慢训练的过程。当使用一个小数据集或者一个深度受限的决策树中,可以减速训练的过程。
原文代码:
from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier(criterion=‘entropy’,max_depth=3,random_state=0)
调整图像边缘及图像间的空白间隔
图像外部边缘的调整可以使用plt.tight_layout()进行自动控制,此方法不能够很好的控制图像间的间隔。
如果想同时控制图像外侧边缘以及图像间的空白区域,使用命令:
plt.subplots_adjust(left=0.2, bottom=0.2, right=0.8, top=0.8,hspace=0.2, wspace=0.3)
步骤:
1)选择近邻的数量k和距离度量方法。
2)找到待3分类样本的k个最近邻居。
3)根据最近的类标邻居进行多少投票。
基于选定距离度量标准,KNN算法从训练集数据中找到与待预测目标点的k个距离最近的样本。目标点的类标基于这k个最近的邻居的类标使用多数投票确定。
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=5,p=2,metric=‘minkowski’)
n_neighbors=5
int 型参数 knn算法中指定以最近的几个最近邻样本具有投票权,默认参数为5
weights=‘uniform’
str参数 即每个拥有投票权的样本是按什么比重投票,'uniform’表示等比重投票,'distance’表示按距离反比投票,[callable]表示自己定义的一个函数,这个函数接收一个
距离数组,返回一个权值数组。默认参数为‘uniform’
algrithm=‘auto’
str参数 即内部采用什么算法实现。有以下几种选择参数:‘ball_tree’:球树、‘kd_tree’:kd树、‘brute’:暴力搜索、‘auto’:自动根据数据的类型和结构选择合适的算法。默认情况下是‘auto’。暴力搜索就不用说了大家都知道。具体前两种树型数据结构哪种好视情况而定。KD树是对依次对K维坐标轴,以中值切分构造的树,每一个节点是一个超矩形,在维数小于20时效率最高–可以参看《统计学习方法》第二章。ball tree 是为了克服KD树高维失效而发明的,其构造过程是以质心C和半径r分割样本空间,每一个节点是一个超球体。一般低维数据用kd_tree速度快,用ball_tree相对较慢。超过20维之后的高维数据用kd_tree效果反而不佳,而ball_tree效果要好,具体构造过程及优劣势的理论大家有兴趣可以去具体学习。
leaf_size=30
int参数 基于以上介绍的算法,此参数给出了kd_tree或者ball_tree叶节点规模,叶节点的不同规模会影响数的构造和搜索速度,同样会影响储树的内存的大小。具体最优规模是多少视情况而定。
matric=‘minkowski’
str或者距离度量对象 即怎样度量距离。默认是闵氏距离,闵氏距离不是一种具体的距离度量方法,它可以说包括了其他距离度量方式,是其他距离度量的推广,具体各种距离度量只是参数p的取值不同或者是否去极限的不同情况,具体大家可以参考这里,讲的非常详细
p=2
int参数 就是以上闵氏距离各种不同的距离参数,默认为2,即欧氏距离。p=1代表曼哈顿距离等等
metric_params=None
距离度量函数的额外关键字参数,一般不用管,默认为None
n_jobs=1
作者:joshuasea
来源:CSDN
原文:https://blog.csdn.net/u013841458/article/details/80932270
版权声明:本文为博主原创文章,转载请附上博文链接!