这是一个完全没有意义的数据挖掘

综述:
 本文主要介绍数据挖掘算法中apriori的实现,其中导入的是从中国天气网中得到的天气数据。下面从获得天气数据开始说明算法的实现。 老师经常跟我说,要站在读者的角度写文章,你看一下我的论文```````今天我也试着从读者的角度写这篇文章。

1、获取天气数据
    天气数据的来源是从中国天气网,一开始是想通过爬虫的形似,把整个页面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),因为“购物蓝分析”很贴切的表达了适用该算法情景中的一个子集。关于这个算法有一个非常有名的故事:"尿布和啤酒"。故事是这样的:美国的妇女们经常会嘱咐她们的丈夫下班后为孩子买尿布,而丈夫在买完尿布后又要顺 手买回自己爱喝的啤酒,因此啤酒和尿布在一起被购买的机会很多。这个举措使尿布和啤酒的销量双双增加,并一直为众商家所津津乐道。


概念解析:
支持度(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
22、02、14点晴天的概率还是挺大的,不过一点价值都没有- -。要想得到一些比较有意义的数据还需要把天气的xml数据进行合适的量化,例如:气温这个部分,在同一个地点出现一模一样的气温的概率不高,除非在某个特定的时间点和地段。因此可以把气温分段,例如以3度为单位,21、22、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
源码还没有整理好,稍后补上
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值