1. 程式人生 > >使用Decision Tree對MNIST資料集進行實驗

使用Decision Tree對MNIST資料集進行實驗

之前已經對MNIST使用過SVM和KNN的方法進行分類,效果看起來還不錯。今天使用決策樹來實驗,看看結果如何。

使用的Decision Tree中,對MNIST中的灰度值進行了0/1處理,方便來進行分類和計算熵。

使用較少的測試資料測試了在對灰度值進行多分類的情況下,分類結果的正確率如何。實驗結果如下。

#Test change pixel data into more categories than 0/1:
#int(pixel)/50: 37%
#int(pixel)/64: 45.9%
#int(pixel)/96: 52.3%
#int(pixel)/128: 62.48%
#int(pixel)/152: 59.1%
#int(pixel)/176: 57.6%
#int(pixel)/192: 54.0%

可見,在對灰度資料進行二分類,也就是0/1處理時,效果是最好的。

使用0/1處理,最終結果如下:

#Result:
#Train with 10k, test with 60k: 77.79%
#Train with 60k, test with 10k: 87.3%
#Time cost: 3 hours.

最終結果是87.3%的正確率。與SVM和KNN的超過95%相比,差距不小。而且消耗時間更長。

需要注意的是,此次Decision Tree演算法中,並未對決策樹進行剪枝。因此,還有可以提升的空間。

python程式碼見最下面。其中:

calcShannonEntropy(dataSet):是對矩陣的熵進行計算,根據各個資料點的分類情況,使用夏農定理計算;

splitDataSet(dataSet, axis, value): 是獲取第axis維度上的值為value的所有行所組成的矩陣。對於第axis維度上的資料,分別計算他們的splitDataSet的矩陣的熵,並與該維度上資料的出現概率相乘求和,可以得到使用第axis維度構建決策樹後,整體的熵。

chooseBestFeatureToSplit(dataSet): 根據splitDataSet函式,對比得到整體的熵與原矩陣的熵相比,熵的增量最大的維度。根據此維度feature來構建決策樹。

createDecisionTree(dataSet, features): 遞迴構建決策樹。若在葉子節點處沒法分類,則採用majorityCnt(classList)方法統計出現最多次的class作為分類。

程式碼如下:

#Decision tree for MNIST dataset by arthur503.
#Data format: 'class	label1:pixel	label2:pixel ...'
#Warning: without fix overfitting!
#
#Test change pixel data into more categories than 0/1:
#int(pixel)/50: 37%
#int(pixel)/64: 45.9%
#int(pixel)/96: 52.3%
#int(pixel)/128: 62.48%
#int(pixel)/152: 59.1%
#int(pixel)/176: 57.6%
#int(pixel)/192: 54.0%
#
#Result:
#Train with 10k, test with 60k: 77.79%
#Train with 60k, test with 10k: 87.3%
#Time cost: 3 hours.

from numpy import *
import operator

def calcShannonEntropy(dataSet):
	numEntries = len(dataSet)
	labelCounts = {}
	for featureVec in dataSet:
		currentLabel = featureVec[0]
		if currentLabel not in labelCounts.keys():
			labelCounts[currentLabel] = 1
		else:
			labelCounts[currentLabel] += 1
	shannonEntropy = 0.0
	for key in labelCounts:
		prob = float(labelCounts[key])/numEntries
		shannonEntropy -= prob  * log2(prob)
	return shannonEntropy

#get all rows whose axis item equals value.
def splitDataSet(dataSet, axis, value):
	subDataSet = []
	for featureVec in dataSet:
		if featureVec[axis] == value:
			reducedFeatureVec = featureVec[:axis]
			reducedFeatureVec.extend(featureVec[axis+1:])	#if axis == -1, this will cause error!
			subDataSet.append(reducedFeatureVec)
	return subDataSet

def chooseBestFeatureToSplit(dataSet):
	#Notice: Actucally, index 0 of numFeatures is not feature(it is class label).
	numFeatures = len(dataSet[0])	
	baseEntropy = calcShannonEntropy(dataSet)
	bestInfoGain = 0.0
	bestFeature = numFeatures - 1 	#DO NOT use -1! or splitDataSet(dataSet, -1, value) will cause error!
	#feature index start with 1(not 0)!
	for i in range(numFeatures)[1:]:
		featureList = [example[i] for example in dataSet]
		featureSet = set(featureList)
		newEntropy = 0.0
		for value in featureSet:
			subDataSet = splitDataSet(dataSet, i, value)
			prob = len(subDataSet)/float(len(dataSet))
			newEntropy += prob * calcShannonEntropy(subDataSet)
		infoGain = baseEntropy - newEntropy
		if infoGain > bestInfoGain:
			bestInfoGain = infoGain
			bestFeature = i
	return bestFeature

#classify on leaf of decision tree.
def majorityCnt(classList):
	classCount = {}
	for vote in classList:
		if vote not in classCount:
			classCount[vote] = 0
		classCount[vote] += 1
	sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
	return sortedClassCount[0][0]

#Create Decision Tree.
def createDecisionTree(dataSet, features):
	print 'create decision tree... length of features is:'+str(len(features))
	classList = [example[0] for example in dataSet]
	if classList.count(classList[0]) == len(classList):
		return classList[0]
	if len(dataSet[0]) == 1:
		return majorityCnt(classList)
	bestFeatureIndex = chooseBestFeatureToSplit(dataSet) 
	bestFeatureLabel = features[bestFeatureIndex]
	myTree = {bestFeatureLabel:{}}
	del(features[bestFeatureIndex])
	featureValues = [example[bestFeatureIndex] for example in dataSet]
	featureSet = set(featureValues)
	for value in featureSet:
		subFeatures = features[:]	
		myTree[bestFeatureLabel][value] = createDecisionTree(splitDataSet(dataSet, bestFeatureIndex, value), subFeatures)
	return myTree

def line2Mat(line):
	mat = line.strip().split(' ')
	for i in range(len(mat)-1):	
		pixel = mat[i+1].split(':')[1]
		#change MNIST pixel data into 0/1 format.
		mat[i+1] = int(pixel)/128
	return mat

#return matrix as a list(instead of a matrix).
#features is the 28*28 pixels in MNIST dataset.
def file2Mat(fileName):
	f = open(fileName)
	lines = f.readlines()
	matrix = []
	for line in lines:
		mat = line2Mat(line)
		matrix.append(mat)
	f.close()
	print 'Read file '+str(fileName) + ' to array done! Matrix shape:'+str(shape(matrix))
	return matrix

#Classify test file.
def classify(inputTree, featureLabels, testVec):
	firstStr = inputTree.keys()[0]
	secondDict = inputTree[firstStr]
	featureIndex = featureLabels.index(firstStr)
	predictClass = '-1'
	for key in secondDict.keys():
		if testVec[featureIndex] == key:
			if type(secondDict[key]) == type({}):	
				predictClass = classify(secondDict[key], featureLabels, testVec)
			else:
				predictClass = secondDict[key]
	return predictClass

def classifyTestFile(inputTree, featureLabels, testDataSet):
	rightCnt = 0
	for i in range(len(testDataSet)):
		classLabel = testDataSet[i][0]
		predictClassLabel = classify(inputTree, featureLabels, testDataSet[i])
		if classLabel == predictClassLabel:
			rightCnt += 1 
		if i % 200 == 0:
			print 'num '+str(i)+'. ratio: ' + str(float(rightCnt)/(i+1))
	return float(rightCnt)/len(testDataSet)

def getFeatureLabels(length):
	strs = []
	for i in range(length):
		strs.append('#'+str(i))
	return strs

#Normal file
trainFile = 'train_60k.txt'	
testFile = 'test_10k.txt'
#Scaled file
#trainFile = 'train_60k_scale.txt'
#testFile = 'test_10k_scale.txt'
#Test file
#trainFile = 'test_only_1.txt'	
#testFile = 'test_only_2.txt'

#train decision tree.
dataSet = file2Mat(trainFile)
#Actually, the 0 item is class, not feature labels.
featureLabels = getFeatureLabels(len(dataSet[0]))	
print 'begin to create decision tree...'
myTree = createDecisionTree(dataSet, featureLabels)
print 'create decision tree done.'

#predict with decision tree.	
testDataSet = file2Mat(testFile)
featureLabels = getFeatureLabels(len(testDataSet[0]))	
rightRatio = classifyTestFile(myTree, featureLabels, testDataSet)
print 'total right ratio: ' + str(rightRatio)


相關推薦

使用Decision TreeMNIST資料進行實驗

之前已經對MNIST使用過SVM和KNN的方法進行分類,效果看起來還不錯。今天使用決策樹來實驗,看看結果如何。 使用的Decision Tree中,對MNIST中的灰度值進行了0/1處理,方便來進行分類和計算熵。 使用較少的測試資料測試了在對灰度值進行多分類的情況下,分類結

使用libsvmMNIST資料進行實驗

svm_type c_svc kernel_type linear 使用線性分類器 nr_class 2二分類 total_sv 15支援向量個數 rho 0.307309 label 1 -1 nr_sv 8 7正負類的支援向量(SV)個數 SV 1 1:7.213038 2:0.198066  1 1:-

使用KNNMNIST資料進行實驗

之前使用SVM對MNIST資料集進行了分類實驗,得到了98.46%的分類正確率(見:使用libsvm對MNIST資料集進行實驗)。 今天用python寫了個小程式,來測試一下KNN的分類效果。 由於KNN的計算量太大,還沒有使用KD-tree進行優化,所以對於60000訓練

Tensorflow學習教程------利用卷積神經網路mnist資料進行分類_利用訓練好的模型進行分類

#coding:utf-8 import tensorflow as tf from PIL import Image,ImageFilter from tensorflow.examples.tutorials.mnist import input_data def imageprepare(ar

Bobo老師機器學習筆記第七課-使用PCAMNIST資料進行降噪

問題1:什麼是MNIST資料集?   MNIST 資料集來自美國國家標準與技術研究所, National Institute of Standards and Technology (NIST). 訓練集 (training set) 由來自 250 個不同人手寫的數字構成

TensorFlow深度學習實戰(一):AlexNetMNIST資料進行分類

概要 進來一段時間在看深度學習中經典的CNN模型相關論文。同時,為了督促自己學習TensorFlow,通讀論文之後開始,利用TensorFlow實現各個模型,復現相關實驗。這是第一篇論文講解的是AlexNet,論文下載網址為:ImageNet Classific

Tensorflow(五)使用CNNMNIST資料進行分類

在tensorflow(二)中對MNIST資料集進行分類使用單層神經網路,梯度下降法以0.2的學習因子迭代了100次取得了92%的準確率,這個網路很簡單,使用較大的學習因子也不會出現梯度爆炸或者梯度消失的情況,但是在複雜些的網路,比如這裡用到的三層CNN網路使用0.2的學習因

深度學習入門教程UFLDL學習實驗筆記二:使用向量化MNIST資料做稀疏自編碼

今天來做UFLDL的第二個實驗,向量化。我們都知道,在matlab裡面基本上如果使用for迴圈,程式是會慢的一逼的(可以說基本就執行不下去)所以在這呢,我們需要對程式進行向量化的處理,所謂向量化就是將matlab裡面所有的for迴圈用矩陣運算的方法實現,在這裡呢,因為之前的實驗我已經是按照向量化的形式編寫的程

R_Studio(關聯)Groceries資料進行關聯分析

          RGui的arules程式包裡含有Groceries資料集,該資料集是某個雜貨店一個月真實的交易記錄,共有9835條消費記錄,169個商品     #install.packages("arules") libra

[譯]使用 Pandas Kaggle 資料進行統計資料分析

原文地址:EXPLORATORY STATISTICAL DATA ANALYSIS WITH A KAGGLE DATASET USING PANDAS 原文作者:Strikingloo 譯文出自:掘金翻譯計劃 本文永久連結:github.com/xitu/gold-m…

keras RNN、LSTMIMDB資料進行分類

本文介紹如何基於keras採用RNN和LSTM對IMDB資料集進行分類。 示例程式碼: from keras.layers import SimpleRNN from keras.models import Sequential from keras.layers import Embedd

利用softmax函式mnist資料簡單分類

mnist資料集的特點 每一張圖片包含28**28個畫素,我們把這一個陣列展開成一個向量,長度是28*28=784。因此在 MNIST訓練資料集中mnist.train.images 是一個形狀為 [60000, 784] 的張量,第一個維度數字用 來索引圖片

[PyTorch小試牛刀]實戰三·DNN實現邏輯迴歸FashionMNIST資料進行分類

[PyTorch小試牛刀]實戰三·DNN實現邏輯迴歸對FashionMNIST資料集進行分類 內容還包括了網路模型引數的保存於載入。 資料集 下載地址 程式碼部分 import torch as t import torchvision as tv import numpy as n

樸素貝葉斯鳶尾花資料進行分類

注:本人純粹為了練手熟悉各個方法的用法 使用高斯樸素貝葉斯對鳶尾花資料進行分類 程式碼: 1 # 通過樸素貝葉斯對鳶尾花資料進行分類 2 3 from sklearn import datasets 4 from sklearn.model_selection import train_

LSTMMNIST資料做分類

https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-08-RNN2/ 1.設定 RNN 的引數 RNN 從每張圖片的第一行畫素讀到最後一行, 然後再進行分類判斷. (1)匯入 MN

Unigram 和bigram yelp資料進行垃圾評論識別分類 python

依舊是對yelp資料集處理,之前效果不理想,後來仔細看了論文,用的是SVMlight分類器…(使用方法見上一篇文章),效果就差不多了。。。。 過程就是對英文進行處理(去停用,去高頻和低頻),化為詞袋模型,處理成SVMlight的格式,進行分類。貼部分程式碼。

R語言MNIST資料分析:探索手寫數字分類

資料科學和機器學習之間區別的定義:資料科學專注於提取洞察力,而機器學習對預測有興趣。我還注意到這兩個領域大相徑庭:我在我的工作中同時使用了機器學習和資料科學:我可能會使用堆疊溢位流量資料的模型來確定哪些使用者可能正在尋找工作(機器學習),但是會構建摘要和視覺化來檢查為什麼(資

利用mnist資料進行深度神經網路

初始神經網路 這裡要解決的問題是,將手寫數字的灰度影象(28 畫素 x28 畫素)劃分到 10 個類別中(0~9)。我們將使用 MINST 資料集,它是機器學習領域的一個經典資料集,其歷史幾乎和這個領域一樣長,而且已被人們深入研究。這個資料集包含 60000 張訓練影象和 10000 張測試影象,由美國國家

TensorFlow學習筆記(1):使用softmax手寫體數字(MNIST資料進行識別

使用softmax實現手寫體數字識別完整程式碼如下: import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data mnist = input

使用PCA資料進行降維

使用PCA對資料集進行降維 一、實驗準備 1、實驗內容和目的 使用主成分分析(PCA)對鳶尾花資料集進行降維操作,其中要求繪製出降維後的資料分佈散點圖並說明降維後的維度,提取的主成分的特徵值 其中資料集檔案為iris.data.txt。