這是一個徹底沒有意義的數據挖掘

綜述:
 本文主要介紹數據挖掘算法中apriori的實現,其中導入的是從中國天氣網中獲得的天氣數據。下面從得到天氣數據開始說明算法的實現。 老師常常跟我說,要站在讀者的角度寫文章,你看一下個人論文```````今天我也試着從讀者的角度寫這篇文章。

一、獲取天氣數據
    天氣數據的來源是從中國天氣網,一開始是想經過爬蟲的形似,把整個頁面request下來而後進行結構化獲得數據。幸虧沒有這樣作,由於中國天氣網上面有一個api能夠得到裏面的天氣數據,具體的獲取方法能夠自行百度。
    使用這個接口前,須要知道待查詢城市在天氣網中的id,例如北京的id是101010100,而後調用接口訪問 http://m.weather.com.cn/data/%s.html,把%s替換成爲城市的id,獲得 http://m.weather.com.cn/data/101010100.html,把連接在瀏覽器打開,能夠看到獲得的json數據。
 
裏面的數據只有一部分是咱們須要的,因此先整理成爲xml的格式,至於爲何是xml,其實json更好,這隨便啦!
實現的代碼:getWeather.py
url = "http://m.weather.com.cn/data/%s.html"
path = "./conf/codeAPI.txt"

def main():
    for li in open(path, "r"):
        for l in re.findall(r'[\d]+', li):
            try:
                stream=urllib2.urlopen(url%l.strip())
                weatherAnalysis.xmlBuilder(stream.read())
            except Exception, e:
                continue
    首先經過urllib2從天氣網的web接口獲取信息,codeAPI.txt保存的是一些城市的id,把得到的數據流傳到weatherAnalysis.py中解析
root = etree.Element("weatherinfos")
data_xml = "data/weatherinfo%s.xml"
splitor='~'
subffixlow='L'
subffixhigh='H'
def xmlBuilder(f):
    js = json.loads(f)
    root.append(jsonAnalyser(js["weatherinfo"]))
    out= open(data_xml%datetime.datetime.now().strftime("%Y-%m-%d-%Hh"), "w")
    out.write(etree.tostring(root, pretty_print=True, encoding='utf-8'))


def jsonAnalyser(js):
    element = etree.Element("weatherinfo", city=js["city"], city_en=js["city_en"]\
        , date=js["date"], week=js["week"])

    for x in range(1,6):
        d=datetime.datetime.now()+datetime.timedelta(hours=4*(x-1))
        time_range= etree.Element("time_range")
        element.append(time_range)
        etree.SubElement(time_range, "time").text=d.strftime("%H")
        tempC=js["temp"+str(x)].split(splitor)
        etree.SubElement(time_range, "tempCL").text=tempC[0]+subffixlow
        etree.SubElement(time_range, "tempCH").text=tempC[1]+subffixhigh
        tempC=js["tempF"+str(x)].split(splitor)
        etree.SubElement(time_range, "tempFL").text=tempC[0]+subffixlow
        etree.SubElement(time_range, "tempFH").text=tempC[1]+subffixhigh
        etree.SubElement(time_range, "weather").text=js["weather"+str(x)]
        etree.SubElement(time_range, "wind").text=js["wind"+str(x)]
    return element
解析後的某個城市的數據:
<weatherinfo city="北京" city_en="beijing" date="" week="星期日">
    <time_range>
      <time>22</time>
      <tempCL>16℃L</tempCL>
      <tempCH>30℃H</tempCH>
      <tempFL>60.8℉L</tempFL>
      <tempFH>86℉H</tempFH>
      <weather>晴</weather>
      <wind>微風</wind>
    </time_range>
    <time_range>
      <time>02</time>
      <tempCL>17℃L</tempCL>
      <tempCH>29℃H</tempCH>
      <tempFL>62.6℉L</tempFL>
      <tempFH>84.2℉H</tempFH>
      <weather>多雲</weather>
      <wind>微風</wind>
    </time_range>
    <time_range>
      <time>06</time>
      <tempCL>17℃L</tempCL>
      <tempCH>25℃H</tempCH>
      <tempFL>62.6℉L</tempFL>
      <tempFH>77℉H</tempFH>
      <weather>多雲轉小雨</weather>
      <wind>微風</wind>
    </time_range>
    <time_range>
      <time>10</time>
      <tempCL>15℃L</tempCL>
      <tempCH>26℃H</tempCH>
      <tempFL>59℉L</tempFL>
      <tempFH>78.8℉H</tempFH>
      <weather>小雨轉陰</weather>
      <wind>微風轉北風3-4級</wind>
    </time_range>
    <time_range>
      <time>14</time>
      <tempCL>15℃L</tempCL>
      <tempCH>30℃H</tempCH>
      <tempFL>59℉L</tempFL>
      <tempFH>86℉H</tempFH>
      <weather>晴</weather>
      <wind>微風</wind>
    </time_range>
  </weatherinfo>
    python操做json數據是很方便的,首先新建一個json對象,而後本節點有什麼數據直接能夠經過json['xxx名稱']的形似得到。

2.apriori的理論及實現
理論部分:

    Apriori algorithm是關聯規則裏一項基本算法。是由Rakesh Agrawal和Ramakrishnan Srikant兩位博士在1994年提出的關聯規則挖掘算法。關聯規則的目的就是在一個數據集中找出項與項之間的關係,也被稱爲購物藍分析 (Market Basket analysis),由於「購物藍分析」很貼切的表達了適用該算法情景中的一個子集。關於這個算法有一個很是有名的故事:"尿布和啤酒"。故事是這樣的:美國的婦女們常常會囑咐她們的丈夫下班後爲孩子買尿布,而丈夫在買完尿布後又要順 手買回本身愛喝的啤酒,所以啤酒和尿布在一塊兒被購買的機會不少。這個舉措使尿布和啤酒的銷量雙雙增長,並一直爲衆商家所津津樂道。 html


概念解析:
支持度(Support):定 義爲 supp(X) = occur(X) / count(D) = P(X)。
置信度(Confidence/Strength): 定義爲 conf(X->Y) = supp(X ∪ Y) / supp(X) = P(Y|X)。
    老師常常跟我說,知識不在於你懂多少,而是在於別人能理解你知識的多少,因此你看一下個人論文`````我儘可能詳細的說出我對這個算法的理解,下面只是我我的的觀點。

假設如今一個數據集
I1:
N1: LBN, Brooklyn, 11204
N2: MBE, WEB, 11204
I1中有兩個子項N1,N2
第一步,把I1中全部的子項取出來,在把這些N1{LBN, Brooklyn, 11204},N2{MBE, WEB, 11204}子項中的元素所有取出來獲得一個集合M1,M1中包括元素以外還須要包含元素的頻率{LBN:1/2, Brooklyn:1/2, 11204:2/2, MBE:1/2, WEB:1/2}。
第二步,判斷這些元素有哪個符合最小support的要求,把符合的取出來組合成爲一個集合P。
第三步,獲得一個M2集合。M2裏面每一個元素都是由兩個元素組成的,最簡單的方法就是把M1的笛卡爾積去掉重複的部(忘記了具體的描述,離散數學老師死得早),獲得
M2{
[LBN, Broollyn]: 1/2, [LBN, 11204]: 1/2, [LBN, MBN]: 0/2, [LBN, WEB]: 0/2,
[Brooklyn, 11204]: 1/2, [Brooklyn, MBN]: 0/2, [Brooklyn, WEB]: 0/2,
[11204, MBN]: 1/2, [11204, WEB]: 1/2,
[MBE, WEB]: 1/2
}
判斷哪些元素符合最小support要求,把符合要求的組成一個集合P
第四步,回到第二步,第三步。可是第三步就不是生成M2,而是生成M3,也就是說生成多少階i的Mi集合,直到生成的P集合是一個空集。
第五部:計算置信度,把P做爲總集(分母),P中每一個元素做爲子集(分子),計算每一個子集佔這個總集的機率,只要子集包括在總集的的某個子集中就算一個,一個子集[Brooklyn, WEB]含義是由Brooklyn能夠推出WEB,總集中首先必定會有這個子集自己,因此結果老是大於等於1的,而後若是總集中有一個[Brooklyn, WEB, 11204],這個也算是一個。若是隻有這兩個那麼s=2,假設P中子集的數量是p=10,那麼機率就是2/10,換句話說就是計算這個推測佔整個推測集合的機率。若是設置的置信度小於0.2,那[Brooklyn, WEB]這個結果也是可信的(不過從上面的[Brooklyn, WEB]: 0/2 看來,這個結果連進入P集合的機會都沒有 - -),若是置信度比較高,那麼這個結果則是不可信的。
到此基本完成,只要把大於置信度的集合記錄下來就能夠了。
實現的具體代碼:
def returnItemsWithMinSupport(itemSet, transactionList, minSupport, freqSet):
    #把數據中大於最小支持度的項組成itemSet返回



def joinSet(itemSet,length):
    #這個功能就是所謂的對一個集合笛卡爾積去掉重複的部分


def getItemSetTransactionList(data_iterator):
    #把數據轉換成爲Set和list<Set>的形式


def runApriori(data_iter, minSupport, minConfidence):
    """
    run the apriori algorithm. data_iter is a record iterator
    Return both: 
     - items (tuple, support)
     - rules ((pretuple, posttuple), confidence)
    """
    itemSet, transactionList = getItemSetTransactionList(xmlAnalysis.parseWeatherXML(data_iter))

    freqSet        = defaultdict(int)
    largeSet        = dict()                # Global dictionary which stores (key=n-itemSets,value=support) which satisfy minSupport
    assocRules         = dict()                # Dictionary which stores Association Rules

    oneCSet        = returnItemsWithMinSupport(itemSet, transactionList, minSupport, freqSet)

    currentLSet    = oneCSet
    k = 2
    while(currentLSet != set([])):
        largeSet[k-1]     = currentLSet
        currentLSet     = joinSet(currentLSet,k)
        currentCSet     = returnItemsWithMinSupport(currentLSet, transactionList, minSupport, freqSet)
        currentLSet     = currentCSet
        k = k + 1

    toRetItems=[]
    for key,value in largeSet.items():
        toRetItems.extend([(tuple(item), getSupport(item)) 
                           for item in value])

    toRetRules=[]
    for key,value in largeSet.items()[1:]:
        for item in value:
            _subsets = map(frozenset,[x for x in subsets(item)])
            for element in _subsets:
                remain = item.difference(element)
                if len(remain)>0:
                    confidence = getSupport(item)/getSupport(element)
                    if confidence >= minConfidence:
                        toRetRules.append(((tuple(element),tuple(remain)), 
                                           confidence))
    return toRetItems, toRetRules
3.導入數據運行
導入今天晚上的天氣狀況:  
由於把置信度調到很低只要有0.2,因此獲得不少結果
晴 ==> 22h , 0.301
22h ==> 晴 , 0.378
02h ==> 晴 , 0.273
晴 ==> 02h , 0.217
14h ==> 晴 , 0.411
晴 ==> 14h , 0.328
2二、0二、14點晴天的機率仍是挺大的,不過一點價值都沒有- -。要想獲得一些比較有意義的數據還須要把天氣的xml數據進行合適的量化,例如:氣溫這個部分,在同一個地點出現如出一轍的氣溫的機率不高,除非在某個特定的時間點和地段。所以能夠把氣溫分段,例如以3度爲單位,2一、2二、23都歸結在21這個數字上,來提升21度時候的機率。這些量化的規則要按照挖掘的須要本身制定,裏面須要的統計學的知識還真很多的。
 
若是把間隔調成5,按照5度一個區間這樣子來統計獲得的結果:
------------------ RULES:
小雨 ==> 20℃H , 0.639
30℃H ==> 晴 , 0.859
北風小於3級 ==> 20℃H , 0.714
晴轉多雲 ==> 25℃H , 0.668
10h ==> 20℃H , 0.630
置信度調成0.6 ,感受此次結果有點科學
 
done
源碼尚未整理好,稍後補上
相關文章
相關標籤/搜索