前端与机器学习
前端与机器学习,很多时候不会有交集。但是当一个前端要去开发一个机器学习平台的UI时,交集就产生了。对一个前端来说,这是一个挑战,同时也是一个机遇。
从最开始接触到机器学习平台,面对各种组件、算法不知所措时,然后就疯狂地去看博客了解如何入门机器学习。一般博客会推荐你先学习线性代数、高数、概率论,然后再开始开免费的机器学习视频,推荐的入门书籍。你会发现这是一个门槛很高技术领域。如果从线性代数、高数、概率论学习完,再来了解机器学习,估计得耗费非常大的精力。
随着几个月的学习,发现有些机器学习的算法只需要简单的数学知识,就能开始入门了。从这些地方作为切入点,显得再好不过。
kNN算法
kNN,英文全名 为k-NearestNeighbor,中文叫k-近邻算法。它的工作原理是:存在一个样本数据集合(训练样本集),并且样本集中每个数据都存在标签;输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行对比,然后提取出样本集中特征最相似数据的分类标签。一般来说,只选取前k个数据,这就是k-邻近算法的由来。
假设有这样一组数据:
data = [
[1, 1.1],
[1, 1],
[0, 0],
[0, 0.1]
]
// data中每个数据对应的标签
lables = ['A', 'A', 'B', 'B']
当我输入数据 [0.2, 0.1]的时候,kNN算法就会判断这个点与哪个点最相近,进而得出输入数据属于哪个标签。
那这里涉及到了什么数学知识点呢?这就要提及欧式公式,计算两个向量点xA和xB之间的距离:
d = √((xA0-xB0)^2+(xA1-xB1)^2)
例如,点(0,0)和(1,2)之间的距离计算为:
√((1-0)^2+(2-0)^2) // =>√5
当遇到三个或三个以上特征的时候,该公式也适用。
kNN是一个非常简单的机器学习算法,我们用python实现一下。
import numpy
def classify0(inX, dataSet, labels, k):
# 获取训练样本的大小
dataSetSize = dataSet.shape[0]
# 用样本数据构建和训练数据集一样的数组,再减去训练数据集
diffMat = numpy.tile(inX, (dataSetSize, 1)) - dataSet
# 下面是应用欧式公式,先平方,再求和,最后开方
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
# 下面是从欧式公式计算的结果中选取k个最相似的标签
sortedDistIndicies = distances.argsort()
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]
kNN是一个非常简单的机器学习算法,对于入门机器学习再合适不过,只需要了解欧式公式即可。然后通过这里还可以补补向量的概念。
那它在实际应用中,可以应用在相亲网站的条件匹配上,同时也可以识别简单的手写数字等等。反正可以统一输出为数据,然后标签化的数据,都可以应用上它。
decisionTree算法
decisionTree,决策树算法。决策树算法,我们举邮件分类的例子来说明最好不过了。假如我们有一堆邮件,那如何将他们自动分类呢?假如邮件中包含”王者荣耀”的关键字自动分类为”无聊时需要阅读的邮件”;如果没有包含,进一步判断邮件中是否包含”工作”的关键字,如果有,自动分类为”需要及时处理的邮件”,否则分类为”无聊时需要阅读的邮件”。以此类推。
决策树算法里面涉及到的数学概念是”熵”。熵定义为信息的期望值。如果待分类的事务可能分类在多个分类中,则符号Xi的信息定义为:
# P(Xi)为选择该分类的概率
l(Xi)=-log2P(Xi)
为了计算熵,我们需要计算所有类别所有可能值包含的信息期望值,公式如下:
H=- SUM1-n (P(Xi) * log2P(Xi))
应用这个公式,我们用python来实现计算熵的。
def caclShannonEnt (dataSet):
numEntries = len(dataSet)
# 计算类别
labelCounts = {}
for featVec in dataSet:
currentLabel = featVec[-1]
if currentLabel not in labelCounts.keys():
labelCounts[currentLabel] = 0
labelCounts[currentLabel] += 1
# 计算熵
shannonEnt = 0.0
for key in labelCounts:
prob = float(labelCounts[key])/numEntries
shannonEnt -= prob * log(prob, 2)
return shannonEnt
然后对于给定的一个数据集(训练数据集,最后一个列为标签),就可以根据特征划分数据,度量划分数据集的熵,以便判断当前是否正确划分了数据集。
def splitDataSet(dataSet, axis, value):
retDataSet = []
for featVec in dataSet:
if featVec[axis] == value:
reducedFeatVec = featVec[:axis]
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
return retDataSet
def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0]) - 1
baseEntropy = caclShannonEnt(dataSet)
bestInfoGain = 0.0
bestFeature = -1
for i in range(numFeatures):
featList = [example[i] for example in dataSet]
uniqueVals = set(featList)
newEntropy = 0.0
for value in uniqueVals:
subDataSet = splitDataSet(dataSet, i, value)
prob = len(subDataSet)/float(len(dataSet))
newEntropy += prob * caclShannonEnt(subDataSet)
infoGain = baseEntropy - newEntropy
if (infoGain > bestInfoGain):
bestInfoGain = infoGain
bestFeature = i
return bestFeature
# 多数表决 ----------------------------------------------------------
def majorityCnt(classList):
classCount = {}
for vote in classList:
if vote not in classCount.keys():
classCount[vote] = 0
classCount[vote] += 1
sortedClassCount = sorted(classCount.iteritems(), key = operator.itemgetter(1), reverse = True)
return sortedClassCount[0][0]
# 创建树 ---
def createTree(dataSet, labels):
classList = [example[-1] for example in dataSet]
if classList.count(classList[0]) == len(classList):
return classList[0]
if len(dataSet[0]) == 1:
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet)
bestFeatLabel = labels[bestFeat]
myTree = {bestFeatLabel:{}}
del(labels[bestFeat])
featValues = [example[bestFeat] for example in dataSet]
uniqueVals = set(featValues)
for value in uniqueVals:
subLabels = labels[:]
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels)
return myTree
以上,就是决策树构建的代码。对于决策树,比较难以理解的是熵的概念。在了解了熵的基础上,决策树的算法逻辑也就比较简单地就写出来了。
总结
从这些简单的算法去入门机器学习,每个阶段让自己有一些产出,既能不断地学习,也能不断激励自己。然后不断补充自己的遗漏的数学知识,再去深入了解更多的机器学习算法。这样一个渐进的过程,对于了解机器学习这样高门槛的技术领域,也不妨是一条可行的道路。
当然上面使用到了python,对于前端来说,还要学习一下python的基础语法。不过python来说,花一个星期左右的时间去看看文档,基本上也就入门了。