目录
0x01 概述
0x02 算法
1.决策树
2.(朴素)贝叶斯
3.线性回归
4.KNN
5.随机森林
6.逻辑回归
7.SVM
8.KMeans
整理自华灿工场机器学习沙龙分享,部分代码来自分享会,之外参考了一些资料整理得到。
http://www.360doc.com/content/16/0301/13/17753496_538519867.shtml
#怎么实现的 在CV领域的落地的方向比较多 眼镜的问题,支付宝采集人脸的时候有眼镜,扫的时候没有眼镜,问是否可以识别? GAN??从无到有,可以把眼镜拆分开, 提升体验感 #CV主要用于图片和视频 安防 视频---图片 帧 #自然语言处理 nlp google 翻译 文本的处理 nlp做的还不是很到位 毕竟中国文化博大精深 #speech语音识别 天猫精灵 小爱同学 #深度学习 DL #统计 数据挖掘 #分类:监督(样本 标签) 无监督(样本 不给标签 聚类 聚在一起) 半监督 增强(人机大战、规则是逐渐学习出来的 棋盘 规则是有一定规则的) 迁移 #分类:分类(手写字符、花朵的分类)和回归(预测 风控金融、趋近于一些东西)
机器学习总体的流程
data------>特征工程------>训练-------->优化-------->部署
data有一个很重要的数据清洗阶段,避免出现不收敛的情况;
特征工程对应在深度学习中,如CNN,Alex,Resetnet 深度学习是端到端的
训练 监督训练 如识别猫和狗 见多识广的过程
优化 random crop 在深度学习中 random crop比resize效果好(不一定适合所有)
论文和实战的区别 论文不太关心硬件,而实战中需要注意pipeline
demo
from math import log
import operator
def calcShannonEnt(dataSet): # 计算数据的熵(entropy)
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
for key in labelCounts:
prob=float(labelCounts[key])/numEntries # 计算单个类的熵值
shannonEnt-=prob*log(prob,2) # 累加每个类的熵值
return shannonEnt
def createDataSet1(): # 创造示例数据
dataSet = [['长', '粗', '男'],
['短', '粗', '男'],
['短', '粗', '男'],
['长', '细', '女'],
['短', '细', '女'],
['短', '粗', '女'],
['长', '粗', '女'],
['长', '粗', '女']]
labels = ['头发','声音'] #两个特征
return dataSet,labels
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 = calcShannonEnt(dataSet) # 原始的熵
bestInfoGain = 0
bestFeature = -1
for i in range(numFeatures):
featList = [example[i] for example in dataSet]
uniqueVals = set(featList)
newEntropy = 0
for value in uniqueVals:
subDataSet = splitDataSet(dataSet,i,value)
prob =len(subDataSet)/float(len(dataSet))
newEntropy +=prob*calcShannonEnt(subDataSet) # 按特征分类后的熵
infoGain = baseEntropy - newEntropy # 原始熵与按特征分类后的熵的差值
if (infoGain>bestInfoGain): # 若按某特征划分后,熵值减少的最大,则次特征为最优分类特征
bestInfoGain=infoGain
bestFeature = i
return bestFeature
def majorityCnt(classList): #按分类后类别数量排序,比如:最后分类为2男1女,则判定为男;
classCount={}
for vote in classList:
if vote not in classCount.keys():
classCount[vote]=0
classCount[vote]+=1
sortedClassCount = sorted(classCount.items(),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
if __name__=='__main__':
dataSet, labels=createDataSet1() # 创造示列数据
print(createTree(dataSet, labels)) # 输出决策树模型结果
{'声音': {'粗': {'头发': {'长': '女', '短': '男'}}, '细': '女'}}
#confidence ImageNet 阈值设置为0.8 达到了就认为是 贝叶斯的方式 垃圾邮件 现在并没有做的很ok
朴素:独立的,Bayes可以看成是从结果看原因
P(类/特征) = (P(特征/类)*P(类))/P(特征)
以垃圾邮件为例:
P(垃圾邮件/我司可以办发票) = (P(特征/垃圾邮件)*P(垃圾邮件))/P(特征) #这里的特征可以是单个的字词
缺点在于:如果说是 可以办发票我司 就不能识别
demo
# -*- coding: UTF-8 -*-
import numpy as np
from functools import reduce
"""
函数说明:创建实验样本
Parameters:
无
Returns:
postingList - 实验样本切分的词条
classVec - 类别标签向量
Author:
Jack Cui
Blog:
http://blog.csdn.net/c406495762
Modify:
2017-08-11
"""
def loadDataSet():
postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], #切分的词条
['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
['stop', 'posting', 'stupid', 'worthless', 'garbage'],
['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
classVec = [0,1,0,1,0,1] #类别标签向量,1代表侮辱性词汇,0代表不是
return postingList,classVec #返回实验样本切分的词条和类别标签向量
"""
函数说明:将切分的实验样本词条整理成不重复的词条列表,也就是词汇表
Parameters:
dataSet - 整理的样本数据集
Returns:
vocabSet - 返回不重复的词条列表,也就是词汇表
Author:
Jack Cui
Blog:
http://blog.csdn.net/c406495762
Modify:
2017-08-11
"""
def createVocabList(dataSet):
vocabSet = set([]) #创建一个空的不重复列表
for document in dataSet:
vocabSet = vocabSet | set(document) #取并集
return list(vocabSet)
"""
函数说明:根据vocabList词汇表,将inputSet向量化,向量的每个元素为1或0
Parameters:
vocabList - createVocabList返回的列表
inputSet - 切分的词条列表
Returns:
returnVec - 文档向量,词集模型
Author:
Jack Cui
Blog:
http://blog.csdn.net/c406495762
Modify:
2017-08-11
"""
def setOfWords2Vec(vocabList, inputSet):
returnVec = [0] * len(vocabList) #创建一个其中所含元素都为0的向量
for word in inputSet: #遍历每个词条
if word in vocabList: #如果词条存在于词汇表中,则置1
returnVec[vocabList.index(word)] = 1
else: print("the word: %s is not in my Vocabulary!" % word)
return returnVec #返回文档向量
"""
函数说明:朴素贝叶斯分类器训练函数
Parameters:
trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵
trainCategory - 训练类别标签向量,即loadDataSet返回的classVec
Returns:
p0Vect - 非的条件概率数组
p1Vect - 侮辱类的条件概率数组
pAbusive - 文档属于侮辱类的概率
Author:
Jack Cui
Blog:
http://blog.csdn.net/c406495762
Modify:
2017-08-12
"""
def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix) #计算训练的文档数目
numWords = len(trainMatrix[0]) #计算每篇文档的词条数
pAbusive = sum(trainCategory)/float(numTrainDocs) #文档属于侮辱类的概率
p0Num = np.zeros(numWords); p1Num = np.zeros(numWords) #创建numpy.zeros数组,
p0Denom = 0.0; p1Denom = 0.0 #分母初始化为0.0
for i in range(numTrainDocs):
if trainCategory[i] == 1: #统计属于侮辱类的条件概率所需的数据,即P(w0|1),P(w1|1),P(w2|1)···
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i]) ## 该词条的总的词数目 这压样求得每个词条出现的概率 P(w1),P(w2), P(w3)...
else: #统计属于非侮辱类的条件概率所需的数据,即P(w0|0),P(w1|0),P(w2|0)···
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = p1Num/p1Denom #相除
p0Vect = p0Num/p0Denom
return p0Vect,p1Vect,pAbusive #返回属于侮辱类的条件概率数组,属于非侮辱类的条件概率数组,文档属于侮辱类的概率
"""
函数说明:朴素贝叶斯分类器分类函数
Parameters:
vec2Classify - 待分类的词条数组
p0Vec - 非侮辱类的条件概率数组
p1Vec -侮辱类的条件概率数组
pClass1 - 文档属于侮辱类的概率
Returns:
0 - 属于非侮辱类
1 - 属于侮辱类
Author:
Jack Cui
Blog:
http://blog.csdn.net/c406495762
Modify:
2017-08-12
"""
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = reduce(lambda x,y:x*y, vec2Classify * p1Vec) * pClass1 #对应元素相乘 这里需要好好理解一下
p0 = reduce(lambda x,y:x*y, vec2Classify * p0Vec) * (1.0 - pClass1)
print('p0:',p0)
print('p1:',p1)
if p1 > p0:
return 1
else:
return 0
"""
函数说明:测试朴素贝叶斯分类器
Parameters:
无
Returns:
无
Author:
Jack Cui
Blog:
http://blog.csdn.net/c406495762
Modify:
2017-08-12
"""
def testingNB():
listOPosts,listClasses = loadDataSet() #创建实验样本
myVocabList = createVocabList(listOPosts) #创建词汇表
trainMat=[]
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc)) #将实验样本向量化
p0V,p1V,pAb = trainNB0(np.array(trainMat),np.array(listClasses)) #训练朴素贝叶斯分类器
testEntry = ['love', 'my', 'dalmation'] #测试样本1
thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry)) #测试样本向量化
if classifyNB(thisDoc,p0V,p1V,pAb):
print(testEntry,'属于侮辱类') #执行分类并打印分类结果
else:
print(testEntry,'属于非侮辱类') #执行分类并打印分类结果
testEntry = ['stupid', 'garbage'] #测试样本2
thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry)) #测试样本向量化
if classifyNB(thisDoc,p0V,p1V,pAb):
print(testEntry,'属于侮辱类') #执行分类并打印分类结果
else:
print(testEntry,'属于非侮辱类') #执行分类并打印分类结果
if __name__ == '__main__':
testingNB()
p0: 0.0
p1: 0.0
['love', 'my', 'dalmation'] 属于非侮辱类
p0: 0.0
p1: 0.0
['stupid', 'garbage'] 属于非侮辱类
y = wx + b real
y' prediict
loss = (y - y')^2
为什么深度学习需要非线性的原因?
train val test
平时 月考 高考
demo
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.externals import joblib
# 3. Load red wine data.
dataset_url = 'http://mlr.cs.umass.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv'
data = pd.read_csv(dataset_url, sep=';')
# 4. Split data into training and test sets
y = data.quality
X = data.drop('quality', axis=1)
#训练集 验证集 测试集 val是验证 6:2:2 验证集
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2,
random_state=123,
stratify=y)
# 5. Declare data preprocessing steps
pipeline = make_pipeline(preprocessing.StandardScaler(),
RandomForestRegressor(n_estimators=100))
# 6. Declare hyperparameters to tune
hyperparameters = { 'randomforestregressor__max_features' : ['auto', 'sqrt', 'log2'],
'randomforestregressor__max_depth': [None, 5, 3, 1]}
# 7. Tune model using cross-validation pipeline
clf = GridSearchCV(pipeline, hyperparameters, cv=10)
clf.fit(X_train, y_train)
# 8. Refit on the entire training set
# No additional code needed if clf.refit == True (default is True)
# 9. Evaluate model pipeline on test data
pred = clf.predict(X_test)
print(r2_score(y_test, pred))
print(mean_squared_error(y_test, pred))
# 10. Save model for future use
joblib.dump(clf, 'rf_regressor.pkl')
# To load: clf2 = joblib.load('rf_regressor.pkl')
“近朱者赤,近墨者黑”
k值很难拿捏
demo
import numpy as np
from math import sqrt
import operator as opt
def normData(dataSet):
maxVals = dataSet.max(axis=0)
minVals = dataSet.min(axis=0)
ranges = maxVals - minVals
retData = (dataSet - minVals) / ranges
return retData, ranges, minVals
def kNN(dataSet, labels, testData, k):
distSquareMat = (dataSet - testData) ** 2 # 计算差值的平方
distSquareSums = distSquareMat.sum(axis=1) # 求每一行的差值平方和
distances = distSquareSums ** 0.5 # 开根号,得出每个样本到测试点的距离
sortedIndices = distances.argsort() # 排序,得到排序后的下标
indices = sortedIndices[:k] # 取最小的k个
labelCount = {} # 存储每个label的出现次数
for i in indices:
label = labels[i]
labelCount[label] = labelCount.get(label, 0) + 1 # 次数加一
sortedCount = sorted(labelCount.items(), key=opt.itemgetter(1), reverse=True) # 对label出现的次数从大到小进行排序
return sortedCount[0][0] # 返回出现次数最大的label
if __name__ == "__main__":
dataSet = np.array([[2, 3], [6, 8]])
normDataSet, ranges, minVals = normData(dataSet)
labels = ['a', 'b']
testData = np.array([3.9, 5.5])
normTestData = (testData - minVals) / ranges
result = kNN(normDataSet, labels, normTestData, 1)
print(result)
a
面经:
一般都是需要会算法或者会工程
算法需要对机器学习、深度学习很熟悉
工程呢,一般会问到在项目中参与什么工作?pipeline?使用了什么方法?有什么样的结果?是否在现实中得到了应用,比如app中?
AI很火(现在的一个趋势是考虑他的落地问题),但是要知道“不要完全跟着别人的脚步走,要学会用于解决自己的问题”
要在领域有自己的一些观点,如果你的观点,面试官还没有get到,那么