阿里云音乐流行趋势预测数据清洗整合——纯python,没有用数据库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w1573007/article/details/52471012

赛题和数据

https://tianchi.shuju.aliyun.com/competition/information.htm?spm=5176.100067.5678.2.3yG798&raceId=231531
离线数据:http://pan.baidu.com/s/1o8TjuPG

数据内容

这里写图片描述
这里写图片描述
这里写图片描述

分析

第一次参加这样的比赛,边学机器学习和python,面对这样的数据,先交7,8月的数据改成9,10数据看看结果。然而刚学编程和没学数据库,其中一个队友用一下午来导入数据,最后也没成功。

播放量的预测就是统计播放量。。。

这是我们一开始想到的。开始放写程序,这里是p2的数据,利用字典,元组,列表之间的关系创建类似二维表的数据结构,在以歌曲名为主键将两个表和起来。
最后我们采用的是时间序列预测模型,进入复赛,然后就没有然后了。时间序列预测是有瓶颈的,如果要做用户的聚类分析,再进行这样的统计可能会更好。

程序

#! usr/bin/env python
# -*- coding: utf-8 -*-
import time    #引入时间函数
start = time.clock()  #开始计时

actsong={}  #艺人——歌曲字典
user={}     #用户数据
fu=open("mars_tianchi_user_actions.csv","rb")
fo=open("p2.csv","w")
fs=open("mars_tianchi_songs.csv","rb")

#生成歌曲—艺人字典

for line in fs :
    arry=line.split(",")   #数据分片
    song=str(arry[0])
    acts=str(arry[1])
    if acts in actsong :
    #如果有这个艺人就添加数据,没有的话初始化数据
        actsong[acts].append(arry[0])  #数据第一列,歌曲
    else :
        actsong[acts]=[arry[0]]     #数据第二列,艺人
print "生成歌曲—艺人字典...ok"
print len(actsong) #长度应该是100


#生成歌曲—每天的操作和行数   {歌曲名:[(操作,时间)]}  
for line in fu:
    lis=line.split(",")
    action=int(lis[3])

    song=str(lis[1])
    if action==1:   #这里是判断操作数,要的是播放的操作
        if song in user:
            user[song].append((lis[3],lis[4]))#lis[3]是操作,4是时间,思想同上
        else :
            user[song]=[(lis[3],lis[4])]
    else:
        continue
    #print user
print "生成歌曲—每天的操作和行数....ok"
print len(user)




#生成每首歌的统计结果
newlist={}#歌曲的统计字典
for linesong in user:

    counts={}  #临时计数字典
    allshuju=user[linesong] #取出字典,user[linesong]是列表名,也是键
    #print allshuju  
    for i in allshuju:  #取元组的数据
        j=list(i)   #因为allshuju是一个列表,所以从第i个开始取
        k=int(j[1])     #取第i个的元组的第二个数据,也就是时间
        if k in counts:  #思想同上,这次是直接计数了
            counts[k]+=1
        else:
            counts[k]=1
    newlist[linesong]=counts  #生成新的字典,歌曲和每天统计的数据,字典套字典
    #print  newlist[linesong]
print "成每首歌的统计结果.....ok"



#生成每个艺人的总的统计结果

allactplay={}  #总表
for oneact in actsong:      #取艺人字典中一个艺人x
    songlist=actsong[oneact]    #取x的所有歌曲
    timedisk={}         #临时时间字典,最后要生成艺人时间播放量的数据
    for song in newlist:    #取歌曲统计中的歌曲名
        if song in songlist:    #如果取的歌曲在x的歌曲表中
            for time1 in newlist[song]:     #取时间,newlist[song]是歌曲之后对应的统计结果的字典,取字典的键值,时间
                if time1 in timedisk:         #将时间放入总表
                      timedisk[time1]+=newlist[song][time1]  #newlist[song][time1]这个是歌曲字典->时间字典->到播放量
                else:
                    timedisk[time1]=newlist[song][time1]
                #print time1 是日期,timedisk[time1] 是这天的总播放量
        #将所有x的歌曲的相同每天的播放量相加
        else:
            allactplay[oneact]=timedisk
print "生成每个艺人的总的统计结果.....ok"
#输出文件,类型为字典套字典的结构
for act1 in allactplay:
    for play2 in allactplay[act1]:
        fo.write(str(act1)+","+str(play2)+","+str(allactplay[act1][play2])+"\n")

print "输出文件.....ok"
end = time.clock()
print "read: %f s" % (end - start)



评估函数

这里写图片描述

代码

这里注意除法是不是地板除,还有列表的类型,从而保证不会取整

#!/usr/bin/python
# -*- coding: utf-8 -*-
import math
import numpy
f=open("7-8text.csv","rb")
ff=open("7-8.csv","rb")
dict1={}#预测结果集合
dict2={}#实际结果集合
list3=[]#单个艺人的总成绩
for line in f:
    artplaytime=line.split(',')
    art=str(artplaytime[0])
    #play=int(artplaytime[1])
    #time=int(artplaytime[2])
    if art in dict1:
        dict1[art].append((artplaytime[2],artplaytime[1]))
    else:
        dict1[art]=[]
print len(dict1)

for line1 in ff:
    artplaytime1=line1.split(',')
    art1=str(artplaytime1[0])
    play1=int(artplaytime1[1])
    time1=int(artplaytime1[2])
    if art1 in dict2:
        dict2[art1].append((artplaytime1[2],artplaytime1[1]))
    else:
        dict2[art1]=[]
print len(dict2)
for art in dict1:
    list1=[]#方差归一化内部每天的计算结果
    list2=[]#艺人j在的权重根据艺人的播放量平方根
    for tuple1 in dict1[art]:#读取预测集中某一个歌手的所有数据
        if art in dict2:
           #判断歌手
            for tuple2 in dict2[art]:#读取实际集中这一个歌手的所有数据
                if tuple1[1]==tuple2[1]:#判断时间
                    a=int(tuple1[0])
                    b=int(tuple2[0])
                    count=float((float(float((a-b))/b))**2)
                    list1.append(count)
                    list2.append(int(tuple2[0]))   
                else:
                    continue
        else:
            continue
    oneart=float((1-math.sqrt(float(sum(list1))/60)) *math.sqrt(float(sum(list2))))
    list3.append(oneart)
result=sum(list3)
print result




猜你喜欢

转载自blog.csdn.net/w1573007/article/details/52471012