1. 程式人生 > >機器學習決策樹演算法解決影象識別

機器學習決策樹演算法解決影象識別

演算法介紹

 什麼是決策樹演算法

決策樹又稱判定樹,是一個類似於流程圖的樹結構:其中,每個內部結點表示在一個屬性上的測試,每個分支代表一個屬性輸出,而每個樹葉結點代表類或類分佈。樹的最頂層是根結點。

構造決策樹的基本演算法

主要評估標準,準確率,速度,健壯性,可規模性,可解釋性

樣例:研究某人今天會不會出去玩?

歷史資料:


從圖片中可以看出來,此人前14天中9天出去玩,5天沒有出去玩,其中由於天氣情況原因,晴天2天出去玩,3天沒有出去玩,陰天4天出去玩,0天沒有出去玩,雨天3天出去玩,2天沒有出去玩,然後由於溼度和風力影響,又有了下一輪決策是否出去玩的情況。以此類推分析分類此人是否會出去玩。

2.1.3 熵

例子:猜世界盃冠軍,假如一無所知,假如每個隊奪冠的機率都是相等的,那麼需要猜多少次?

 過程:是否是在前16只隊伍中,32/2,用二分法可知,需要猜5次。

熵的單位是bit

info(D) = -(1/32*log(1/32)+1/32*log(1/32)+1/32*log(1/32) +1/32*log(1/32)+1/32*log(1/32)...)累加32次


info(D)= 5bit

結論:資料量越大,熵值越大,不準確率越高


熵的差值則為有條件後的概率優化程度,以前面的案例分析,如果直接猜測某人會不會出去玩。結果為:


如果加上天氣情況分析,結果為:

所以在已知天氣情況的條件下,資料準確率優化了0.246

2.1.4 演算法優缺點

優點:直觀,便於理解,小規模資料集有效

缺點:處理連續變數不好,類別較多時,錯誤增加的比較快,可規模性一般

2.2 邏輯分析

此時不得不讓我非常開心,那如何利用決策樹來做影象識別呢?對此還是讓很多人無法理解,現在就慢慢向大家闡述。

再次對上述案例進行分析

天氣

溼度

風力

是否出去玩

sunny

<=70

sunny

<=70

sunny

>70

不玩

sunny

>70

不玩

sunny

>70

不玩

overcast

overcast

overcast

overcast

rain

不玩

rain

不玩

rain

沒風

rain

沒風

rain

沒風

然後程式化上述程式:

天氣為三維,設定晴天為[1,0,0],那麼多雲為[0,1,0],雨天為[0,0,1]

溼度為三維,設定<=70為[1,0,0],那麼>70為[0,1,0],無為[0,0,1]

風力為三維,設定有風為[1,0,0],那麼無風為[0,1,0],無為[0,0,1]

是否出去玩為二維,設定玩為[1],不玩為[0]

由此可知第一項則為 [1,0,0,1,0,0,0,0,1],結果為[1]

以此類推。

    之後得出矩陣的計算其最優單位向量個數,

[1,0,0,1,0,0,0,0,1

 1,0,0,1,0,0,0,0,1

 1,0,0,0,1,0,0,0,0]

每三列則為一個特徵向量,然後進行計算熵值最小情況下哪些向量所佔權重最大。

但是如何去分析影象相似還是有很大距離,在影象中會有很大畫素,例如60*60畫素的圖片,每個畫素點會轉換為類似[255,200,10]RGB型別,本報告進行簡單分析,首先將圖片進行灰度圖化,轉化為例如[245],然後對下個畫素點大小與之比較,大則為0,小則為1,由於影象畫素點大,之後會轉換為複雜矩陣,之後再對矩陣進行特徵向量切割,例如:

[1,0,0,1,0,0,0,0,1

 1,0,1,1,0,1,0,0,1

 1,0,0,0,1,0,0,0,0]

此矩陣特徵向量則為2,1,2,3,1分列,然後在進行熵值計算,權重比對,計算出最合理向量權重佔比,之後再對測試影象中的向量進行比對,就可以進算出其相似度。

影象分析結果相當出眾,可以對動態相似圖片與其他圖片有比較大的區分。

6.3 程式碼實現

程式語言為python ,利用Anaconda2環境編寫,測試圖片見附錄

# -*- coding: utf-8 -*-
import os
from PILimport Image
from PILimport ImageFilter
from PILimport ImageOps
from sklearnimport tree

def getCode(img,size):
    pixel_Y = []
    featurelist = []

   
for xin range(0,size[0]):
       
global tmp
        pixel_X = []
       
for yin range(0,size[1]):
            pixel = img.getpixel((x
, y))
            pixel_next = img.getpixel((x
, y+1))if y < size[1]-1else None
           
if pixel_nextis not None:
                feature =
0 ifpixel < pixel_next else1
               
pixel_X.append(feature)
           
else:
                featurelist.append(tmp)
                pixel_X.pop()
                feature =
0
           
tmp = feature
        pixel_Y.append(pixel_X)

   
return pixel_Y,featurelist


def OrginCode(dummyX,dummyY):
    clf = tree.DecisionTreeClassifier(
criterion='entropy')
    clf.fit(dummyX
, dummyY)
   
return clf


def Cmpcode(cls,dummyX, dummyY):
    equal =
0
   
predictedY = cls.predict(dummyX)
   
for n,y inenumerate(predictedY):
       
if y == dummyY[n]:
            equal +=
1
   
return equal


class imageOragin(object):

   
def __init__(self,size=(1366,768),*image):
        dummyX = []
        dummyY = []
       
for iin image:
            i = i.resize(size).convert(
'L')
            i = ImageOps.equalize(i)
            code1 = getCode(i
, size)
            dummyX += code1[
0]
            dummyY += code1[
1]
       
self.size = size
       
self.cls = OrginCode(dummyX,dummyY)

   
def cmp(self,image):
       
# image.resize(self.size).convert('L').filter(ImageFilter.BLUR)影象模糊化 filter為影象增強手段,不建議使用
        # 更多關於ImageFilter推薦部落格http://blog.csdn.net/icamera0/article/details/50708888
        # resize重新定義圖片大小
        image = image.resize(self.size).convert('L')
       
# ImageOps.equalize均衡影象的直方圖。該函式使用一個非線性對映到輸入影象,為了產生灰色值均勻分佈的輸出影象。
        #
更多關於ImageOps推薦部落格http://blog.csdn.net/icamera0/article/details/50785776
        image = ImageOps.equalize(image)
        code2 = getCode(image
, self.size)
        equal = Cmpcode(
self.cls,*code2)
       
return equal *1.00 / self.size[0]


if __name__ =='__main__':
    image = []
    image1 = Image.open(
r'C:\ML\imagetest\a1.png',"r")
    image2 = Image.open(
r'C:\ML\imagetest\a3.png',"r")
    image3 = Image.open(
r'C:\ML\imagetest\24.png',"r")
    image4 = Image.open(
r'C:\ML\imagetest\a8.png',"r")
    image.append(image4)
    image5 = Image.open(
r'C:\ML\imagetest\a12.png',"r")
    image.append(image5)
    image6 = Image.open(
r'C:\ML\imagetest\1.png',"r")
    image.append(image6)
    image7 = Image.open(
r'C:\ML\imagetest\3.png',"r")
    image.append(image7)
    image.append(image1)
    image.append(image2)
    image.append(image3)
    size = (
1366,768)
    ora = imageOragin(size
, *image)
    path =
'C:\\ML\\imagetest\\'
   
files = os.listdir(path)
   
for iin files:
       
print path+i
        imaged = Image.open(path+i
, "r")
       
print ora.cmp(imaged)