少女Q的量化交易之路 #week6 之一

week4,week5忙成狗,做了差不多3个project,2个coding assignment, 信号系统期中考试,开了1300km去了趟新奥尔良。即使现在还是欠了一个due,下周还有个deep learning的考试。嘛…不过本来想做的职业就和学的很相关了,今天把STA5635 Applied Machine Learning按照作业再过一遍,时间问题会持续更新。

HW1.Decision Tree

在这里插入图片描述
此题是要求用决定树来二分类一个data,data的label是0,1。所以很简单,直接调用sklearn的DecisionTreeClassifier就可以了。
code:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier
# sklearn是机器学习中常用的一个python第三方模块,里面对一些常用的机器学习方法进行了封装
# 在进行机器学习任务时,并不需要实现每一个算法,只需要简单的调用sklearn里的木块就可以
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
# 加载数据
trainData = np.loadtxt('madelon_train.data')
trainLabel =  np.loadtxt('madelon_train.labels') 
testData = np.loadtxt('madelon_valid.data')
testLabel =  np.loadtxt('madelon_valid.labels') 

def myTree(v):
    # 调用树classifier来分类,传入v为树层次深度
    clf = DecisionTreeClassifier(max_depth = v)
    clf.fit(trainData, trainLabel)
    test_sc = 1 - clf.score(testData, testLabel)
    train_sc = 1 - clf.score(trainData, trainLabel)
    return (test_sc, train_sc)

dep = np.arange(1,13) # 树的深度
scores = [myTree(v) for v in dep]
te_scores = [s[0] for s in scores]
tr_scores = [s[1] for s in scores]
plt.figure(figsize=(6,4), dpi=120)
plt.grid()
plt.xlabel('max depth of decison tree')
plt.ylabel('Errors')
plt.plot(dep, te_scores, label='test_errors')
plt.plot(dep, tr_scores, label='train_errors')
plt.legend()

points:
1.sklearn的基本概念:
sklearn是机器学习中一个常用的python第三方模块,里面对一些常用的机器学习方法进行了封装,在进行机器学习任务时,并不需要每个人都实现所有的算法,只需要简单的调用sklearn里的模块就可以实现大多数机器学习任务。
机器学习任务通常包括分类(Classification)和回归(Regression),常用的分类器包括SVM、KNN、贝叶斯、线性回归、逻辑回归、决策树、随机森林、xgboost、GBDT、boosting、神经网络NN。
sklearn学习详解:https://blog.csdn.net/lilianforever/article/details/53780613

2.loadtext函数
def loadtxt(fname,dtype=float,comments=’#’,delimiter=None,converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)
Returns: str or recarray or tuple or list
返回:字符串,recarray,元组,列表
从文本文件中导入数据 ,文本文件中的每一行必须具有相同数量的值。

delimiter : str, optional
用于分隔值的字符,缺省值为任何空白字符,如空格 ,制表符

fname :文件或字符串
机读的文件,文件名 . 如果文件的扩展名是 .gz or .bz2,这个文件首先要解压缩。

skiprows : int, optional 整数
跳过开头的 skiprows 行数 ;缺省值:0

usecols : sequence, optional(队列)
确定那几列被读取。从0开始。例:“usecols=(1,4,5)” ,将读取第2列,5列和第6列。缺省值为none,读取所有的列。

3.Decision Tree
目标:决策树的学习,就是根据数据集构建出一棵决策树。我们希望构建出来的决策树,既能很好的对数据集进行分类,又具有很好的泛化能力。
学习过程:决策树学习算法通常就是递归的选择最优特征,根据该特征对训练集进行划分,在划分之后的训练集上再进行决策树学习算法,如果能够大致分类,则设置成叶节点,否则继续选择最优特征,知道所有的训练数据子集都能被正确的分类或者没有可选的特征为止。
剪枝:这样的算法生成的决策树,一般对训练集的分类效果很好、但泛化能力不强,也就是说容易产生过拟合现象。因此需要对构建好的数据集进行剪枝,将树变得更简单,因而具有更好的泛化能力。

可以看出决策树的学习算法一般包含三个过程:特征选择、决策树生成和决策树剪枝。

HW2.Random Forest

在这里插入图片描述
此题要求用随机森林,进行二分类。
code:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from matplotlib.colors import ListedColormap

trainData = np.loadtxt('madelon_train.data')
trainLabel =  np.loadtxt('madelon_train.labels') 
testData = np.loadtxt('madelon_valid.data')
testLabel =  np.loadtxt('madelon_valid.labels') 

def myForest(v):
	
	# v表示有多少棵树。max_feature表示选择feature的多少,可决定树的相关性和分类能力。选择max_feature是重要的。
    clf = RandomForestClassifier(n_estimators = v, max_features = 50)
    clf.fit(trainData, trainLabel)
    test_sc = 1 - clf.score(testData, testLabel)
    train_sc = 1 - clf.score(trainData, trainLabel)
    return (test_sc, train_sc)

dep = np.array([3,6,8,9])
scores = [myForest(v) for v in dep]
te_scores = [s[0] for s in scores]
tr_scores = [s[1] for s in scores]
plt.figure(figsize=(6,4), dpi=120)
plt.grid()
plt.xlabel('numbers of decison tree')
plt.ylabel('Errors')
plt.plot(dep, te_scores, label='test_errors')
plt.plot(dep, tr_scores, label='train_errors')
plt.legend()

points:
1.随机森林:
随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树,而它的本质属于机器学习的一大分支——集成学习(Ensemble Learning)方法。随机森林的名称中有两个关键词,一个是“随机”,一个就是“森林”。“森林”很好理解,一棵叫做树,那么成百上千棵就可以叫做森林了,这样的比喻还是很贴切的,其实这也是随机森林的主要思想–集成思想的体现。

每棵决策树都是一个分类器(假设现在针对的是分类问题),那么对于一个输入样本,N棵树会有N个分类结果。而随机森林集成了所有的分类投票结果,将投票次数最多的类别指定为最终的输出,这就是一种最简单的 Bagging 思想。

2.信息熵的理解:
特征的前后选择,是根据信息熵来选择的。

2.1 信息
引用香农的话,信息是用来消除随机不确定性的东西,从数学的角度来说可能更加清楚一些,如果带分类的事物集合可以划分为多个类别当中,则某个类 x i xi xi的信息定义如下:

I ( X = x i ) = − l o g 2 p ( x i ) I(X = x_i) = -log_2p(x_i) I(X=xi)=log2p(xi)

I ( x ) I(x) I(x)用来表示随机变量的信息, p ( x i ) p(xi) p(xi)指是当 x i xi xi发生时的概率,这里说一下随机变量的概念,随机变量时概率论中的概念,是从样本空间到实数集的一个映射,样本空间是指所有随机事件发生的结果的并集,比如当你抛硬币的时候,会发生两个结果,正面或反面,而随机事件在这里可以是,硬币是正面;硬币是反面;两个随机事件,而{正面,反面}这个集合便是样本空间,但是在数学中不会说用‘正面’、‘反面’这样的词语来作为数学运算的介质,而是用0表示反面,用1表示正面,而“正面->1”,"反面->0"这样的映射便为随机变量,即类似一个数学函数。

2.2 熵
在信息论和概率论中熵是对随机变量不确定性的度量,与上边联系起来,熵便是信息的期望值,可以记作:

H ( x ) = ∑ i = 1 n p ( x i ) I ( x i ) = − ∑ i = 1 n p ( x i ) l o g b p ( x i ) H(x) = \sum_{i=1}^np(x_i)I(x_i)=-\sum_{i=1}^np(xi)log_bp(x_i) H(x)=i=1np(xi)I(xi)=i=1np(xi)logbp(xi)

熵只依赖X的分布,和X的取值没有关系,熵是用来度量不确定性,当熵越大,概率说X=xi的不确定性越大,反之越小,在机器学期中分类中说,熵越大即这个类别的不确定性更大,反之越小。

2.3 条件熵
条件熵是用来解释信息增益而引入的概念,概率定义:随机变量X在给定条件下随机变量Y的条件熵,对定义描述为:X给定条件下Y的条件概率分布的熵对X的数学期望,在机器学习中为选定某个特征后的熵,公式如下:

H ( Y ∣ X ) = ∑ x p ( x ) H ( Y ∣ X = x ) H(Y|X) = \sum_xp(x)H(Y|X=x) H(YX)=xp(x)H(YX=x)

个人认为, x x x为样本, y y y为特征,sum是求所有样本下这个 y y y的熵对于样本的数学期望。(理解有困难)

这个公式是对条件概率熵求期望,但是上边说是选定某个特征的熵,没错,是选定某个特征的熵,因为一个特征可以将待分类的事物集合分为多类,即一个特征对应着多个类别,因此在此的多个分类即为X的取值。

2.4 信息增益

信息增益在决策树算法中是用来选择特征的指标,信息增益越大,则这个特征的选择性越好,在概率中定义为:待分类的集合的熵和选定某个特征的条件熵之差(这里只的是经验熵或经验条件熵,由于真正的熵并不知道,是根据样本计算出来的),公式如下:
I G ( Y ∣ X ) = H ( Y ) − H ( Y ∣ X ) IG(Y|X)=H(Y)-H(Y|X) IG(YX)=H(Y)H(YX)

HW3.Gradient Ascent

在这里插入图片描述
code:

import os
from sklearn.preprocessing import scale
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
 
#这里是放你要训练数据的目录,把包里面的三组data,放到一个新建的文件夹里
os.chdir('/Users/Yueqi/Documents/Courses/Datasets/Gisette')

#这是你选择的activation function(激活函数),因为这个是逻辑回归,就是分类
#一定要选一个函数在(0,1)之间,这样可以用概率解决,所以要选用sigmoid
def sigmoid(z):
    return 1.0/(1+np.exp(-z))

#梯度上升部分,
def gradAscent(dataMatIn, classLabels):
	# 这里我转换成矩阵了,但是其实不要转换更好,做这个作业时候不太懂,这是x的
    dataMatrix = np.mat(dataMatIn)           
    # 这是y的
    labelMat = np.mat(classLabels).T #m,n = np.shape(dataMatrix) 
    # 参数(可改)
    alpha = 1 
    # 参数 
    lenda = 0.001
    # 循环次数
    maxCycles = 1000 
    # 这是你自己设定的预测的y和真实y之间可以相差值
    level=1e-3
    b = 0
    # weights根据输入x的纬度来定,一般是纬度是(x.shape[1],1)
    weights = np.zeros((5000,1)) 
    list = []
    for k in range(maxCycles):          
        # 这个h就是输入的x,和weights做了运算之后的输出,也就是预测的y    
        h = sigmoid(dataMatrix * weights)   
        # 这里是错误率
        error = (labelMat - h)            
        # 权重更新公式,一般都差不多的
        weights = weights -alpha * lenda * weights + alpha * dataMatrix.transpose()* error/5000  
        #print ('第 {} 次循环,error[0]= {}'.format(k + 1, error[5]))
        b0=b;
        # 这个b是条件概率似然公式,不用知道为什么,搞数学的推导的,我们希望他越大越好。(这个越大,越接近真实值)
        b=np.sum(np.multiply(labelMat,dataMatrix.dot(weights))-np.log(1+np.exp(dataMatrix.dot(weights))))
        #print('第%g次循环,b = %f' % (k+1, b))
        list.append( b )
        list1 = np.transpose(list)
        # 这一步是在判断,当循环>300并且b在收敛了很小了就推出循环
        if (k>=300) & (abs(b-b0)<level):
            break
    return (weights,list1)
# 输入确切数据的部分,对x和y进行了normolize
dataMat=scale(np.loadtxt('gisette_train.data'))
labelMat= np.loadtxt('gisette_train.labels')
labelMat[labelMat == -1] = 0

#gradAscent(dataMat, labelMat)
#print (gradAscent(dataMat, labelMat))
#dataMatIn=dataMat
#classLabels=labelMat

# 这里是在画图
scores = [gradAscent(dataMat, labelMat)]
c = [ s[1] for s in scores]
cycles = np.arange(1,c[0].shape[0]+1)
plt.figure(figsize=(6,4), dpi=120)
plt.grid()
plt.xlabel('iterations')
plt.ylabel('Log-Likelihood')
plt.plot(cycles, c[0], label='test')
plt.legend()
plt.show()

points:
Gradient Descent 没有太大的理解难度,这一章作业的code开始有难度了,也算是正式认识python,matrix在python里的操作真的很不友好,.dot,*,np.multiply等也会在后面的作业再写到。这里总结一点常用python用法。
1.python编程给numpy矩阵加一列方法

import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = np.ones(3)
c = np.array([[1,2,3,1],[4,5,6,1],[7,8,9,1]])
PRint(a)
print(b)
print(c)
 
a[[1 2 3]
 [4 5 6]
 [7 8 9]]
b[ 1. 1. 1.]
c[[1 2 3 1]
 [4 5 6 1]
 [7 8 9 1]]

1.1使用np.c_[]和np.r_[]分别添加列和行
用这个方法要注意纬度一样

np.c_[a,b] #把b当成列加到最后一行
array([[ 1., 2., 3., 1.],
    [ 4., 5., 6., 1.],
    [ 7., 8., 9., 1.]])
 
np.c_[a,a]
array([[1, 2, 3, 1, 2, 3],
    [4, 5, 6, 4, 5, 6],
    [7, 8, 9, 7, 8, 9]])
 
np.c_[b,a] # b作为列放到最前面一列
array([[ 1., 1., 2., 3.],
    [ 1., 4., 5., 6.],
    [ 1., 7., 8., 9.]])

1.2 使用np.insert
numpy.insert(arr, obj, values, axis=None)

arr: Input array

obj: int,slice or sequence of ints
这里是insert到什么位子,0就是第一列

values: array_like
这里是插入的值,类型要与arr一致,不一致会转换成arr的

axis:int,optional
0行1列,如果没有,将会默认先flattened.

np.insert(a, 0, values=b, axis=1)
 
array([[1, 1, 2, 3],
    [1, 4, 5, 6],
    [1, 7, 8, 9]])
 
np.insert(a, 3, values=b, axis=1)
 
array([[1, 2, 3, 1],
    [4, 5, 6, 1],
    [7, 8, 9, 1]])

1.3使用’column_stack’,‘row_stack’
np.row_stack等价于np.vstack
np.column_stack(up)相当于np.concatenate((a1, a2, …), axis=1),对竖轴的数组进行操作,即操作对象是column实例:

#如果开始传入的是一维数组,首先将一维数组转化为2维数组
In [1]: a = np.array((1,2,3))
    ...: b = np.array((2,3,4))
    ...: np.column_stack((a,b))
    ...:
Out[1]:
array([[1, 2],
       [2, 3],
       [3, 4]])
#如果开始传入的是多维数组,则直接进行拼接操作
In [2]: a = np.array(((1,2,3),(4,3,2)))
    ...: b = np.array(((2,3,4),(2,12,2)))
    ...: np.column_stack((a,b))
Out[2]:
array([[ 1,  2,  3,  2,  3,  4],
       [ 4,  3,  2,  2, 12,  2]])

2.ndarray中的一些冒号用法

X=array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]])
>>> X
>array([[1,  2,  3,  4],
		[5,  6,  7,  8],
		[9, 10, 11, 12],
		[13,14, 15, 16],
		[17,18, 19, 20]])
#第一种:默认全部选择:逗号左边是行操作,右边是列操作
#如X[:,0]就是取矩阵X的所有行的第0列的元素,X[:,1]就是取第一列的元素
>>>X[:,0]
>array([1, 5, 9, 13, 17])

#第二种,指定范围,注意含左不含右
#如X[:,m:n]即取矩阵X的所有行中的第m到n-1列数据
X[:,2:3]
>>>array([[3],
		  [7],
		  [11],
		  [15],
		  [19]])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值