0.机器学习框架
1.基本概念
机器学习主要目标是根据已有的属性,得到未知的结论,或者说预测,而能预测的前提是已经积累了很多的经验,等等类似的说法。从基本的监督学习,非监督学习,半监督学习,训练集,测试集等概念讲起。
第一个介绍的算法是DecisionTree:
以上,将数据模型转化为一个一个节点,满足条件即往下走的思路,走到最后就需要做出决策,这样一种算法称之为决策树。
2.数据预处理
简单的有比如,考虑西瓜甜不甜,我们可以将目标设置为甜还是不甜,即是0还是1。一般我们可以根据瓜蒂,声音,颜色等外在属性对西瓜进行预测。
假设瓜蒂有生、熟之分,声音有清脆、浑浊之分,颜色有深绿,浅绿,泛白之分。每一种属性我们都可以用0,1,来表示,主要是因为做数据处理之前需要将描述语言进行这样的数据处理。
瓜蒂生:0
瓜蒂熟:1
清脆:1
浑浊:0
深绿:1
浅绿:0
泛白:0
这样一组[0,1,10,1,0,0]的数据就可以表示瓜蒂熟,声音清脆,颜色深绿的西瓜,如果西瓜甜,则相当于结果是1。绍完基本思路之后,我们就开始用python做初步的demo。
3.代码分析
首先导入用到的库
from sklearn.feature_extraction import DictVectorizer #字典转换
import csv #读取csv数据
from sklearn import preprocessing #sklearn的一些类
from sklearn import tree
from sklearn.externals.six import StringIO ##输入输出
接着是创造数据:
#创建数据集
headers=['RID','age','income','student','credit_rating','class_buys_computer']
rows=[('1','youth','high','no','fair','no'),
('2','youth','high','no','excellent','no'),
('3','middle_aged','high','no','fair','yes'),
('4','senior','medium','no','fair','yes'),
('5','senior','low','yes','fair','yes'),
('6','senior','low','yes','excellent','no'),
('7','middle_aged','low','yes','excellent','yes'),
('8','youth','medium','no','fair','no'),
('9','youth','low','yes','fair','yes'),
('10','senior','medium','yes','fair','yes'),
('11','youth','medium','yes','excellent','yes'),
('12','middle_aged','medium','no','excellent','yes'),
('13','middle_aged','high','yes','fair','yes'),
('14','senior','medium','no','excellent','no')]
with open('data.csv','w',newline='') as f:
f_csv=csv.writer(f,dialect='excel')
f_csv.writerow(headers)
f_csv.writerows(rows)
以上代码会生成一个data.csv文件
csv里的数据如图:
读取数据
try:
#filename = r'.\test.csv' #绝对路径和相对路径
filename = r'data.csv'
allElectronicsData = open(filename,'rt')
reader = csv.reader(allElectronicsData) #读取数据每一行
#for row in reader:
# print(row)
headers = next(reader) #第一行的数据
#for index, column_header in enumerate(headers):
#print(index, column_header)
#print(headers) #第一行
except:
print("失败")
数据处理
featureList = []
labelList = []
for row in reader: #reader 内容里有14行,row就是每一行的元素
#len(row) = 6
labelList.append(row[len(row)-1]) #标签的最后一列row[0]~row[5]
rowDict = {} #创建字典
for i in range(1,len(row)-1): #从1到4
rowDict[headers[i]] = row[i] #字典的头和内容配对
featureList.append(rowDict)
#print(featureList)
#########以上是把数据从csv力读出来生成一一对应的字典#########
#########以下就是将字典转成我们所需要的数据结构###############
vec = DictVectorizer()
dummyX = vec.fit_transform(featureList).toarray() #集合转成数组
#单独转结论的数据结构
lb = preprocessing.LabelBinarizer()
dummyY = lb.fit_transform(labelList)
以上能得到可以处理的数据和所对应的标记结果:
训练分类器:
#entropy =>ID3
#树形分类用很多种方法,我们用的是熵来判断,在代码里就是参数的不同
clf = tree.DecisionTreeClassifier(criterion = 'entropy')
clf = clf.fit(dummyX,dummyY) #每个学习的过程都有这个
本来训练分类器应该是最核心的一步,python里都已经打包好了,只需要输入参数就好。
输出结果
#将决策树描述在了.dot上
with open("resultTree.dot",'w')as f:
f = tree.export_graphviz(clf, feature_names=vec.get_feature_names(),out_file = f)
验证决策树
怎么验证呢,通过创造新的数据,看输出结果是否符合预期。
# 验证决策
oneRowX = dummyX[0,:]
print("oneRowX: "+str(oneRowX))
#创造新的数据来测试
newRowX = oneRowX
newRowX[0] = 0
newRowX[1] = 1 #老年人 age=senior
newRowX[2] = 0
newRowX[3] = 1 #信用好 credit_rating=excellent
newRowX[4] = 0
newRowX[5] = 0
newRowX[6] = 0
newRowX[7] = 1 #收入中等
newRowX[8] = 0 #是学生
newRowX[9] = 1
predictedY = clf.predict([newRowX]) #预测结果
print("predictedY: "+ str(predictedY))
yesORno = lb.inverse_transform(predictedY) #转成 yes or no
print(yesORno)
4.后续可视化处理
生成.dot文件之后,打开一开和想象的树状图差别很大,视频里介绍了怎么用graphviz来将dot转成pdf的树状图的方法,先在官网上下载,点击msi
之后双击安装即可,需要记住安装路径,将下图所示的.bin路径添加到环境变量path里。
好了之后即可在cmd里验证:输入dot -version
即可
之后就是一个转换的代码输入:
dot -Tpdf src.dot -o des.pdf
src.dot表示的是带路径的.dot文件
des.pdf表示的是生成的.pdf文件,最好也带个路径
如我的,在cmd里直接输入:
dot -Tpdf D:\MLearning\Decisiontree\resultTree.dot -o D:\MLearning\Decisiontree\test.pdf
源代码下载连接:
以上源码
另一个简单的决策树算法:
主要是有个标签二值化的过程和反过程。
# -*- coding:UTF-8 -*-
from sklearn import preprocessing
from sklearn import tree
#help(preprocessing.LabelBinarizer)
#特征矩阵
featureList =[[1,0],[1,1],[0,1],[0,0]]
#将标签二值化
labelList = ['yes','no','yes','no']
lb = preprocessing.LabelBinarizer() #可以理解成先建立方法
dummY = lb.fit_transform(labelList)
#print(dummY)
#建立模型和训练
clf = tree.DecisionTreeClassifier() #类似可以理解成先建立这样的分类器
clf = clf.fit(featureList,dummY) #将数据代入
p = clf.predict([[0,1],[1,1]])
print(p)
yesORno = lb.inverse_transform(p)
print(yesORno)