竞赛圈   > 【分享】汽车目的地智能预测大赛basline

小螺号

java
  • 关注者 9
  • 关注了 1

小螺号

官方 java

来源:XBuder


# 简单的方案,就是先统计用户星期最喜欢去的地方,之后对这些地方标记一下,如果未来真的去过,标记1否则0


import pandas as pd

import numpy as np

import warnings

warnings.filterwarnings('ignore')


from math import radians, atan, tan, sin, acos, cos

def getDistance(latA, lonA, latB, lonB):

    ra = 6378140  # radius of equator: meter

    rb = 6356755  # radius of polar: meter

    flatten = (ra - rb) / ra  # Partial rate of the earth

    # change angle to radians

    radLatA = radians(latA)

    radLonA = radians(lonA)

    radLatB = radians(latB)

    radLonB = radians(lonB)


    try:

        pA = atan(rb / ra * tan(radLatA))

        pB = atan(rb / ra * tan(radLatB))

        x = acos(sin(pA) * sin(pB) + cos(pA) * cos(pB) * cos(radLonA - radLonB))

        c1 = (sin(x) - x) * (sin(pA) + sin(pB)) ** 2 / cos(x / 2) ** 2

        c2 = (sin(x) + x) * (sin(pA) - sin(pB)) ** 2 / sin(x / 2) ** 2

        dr = flatten / 8 * (c1 - c2)

        distance = ra * (x + dr)

        return distance  # meter

    except:

        return 0.0000001


def f(d):

    return 1 / (1 + np.exp(-(d-1000)/250))


# 计算误差值

def getDistanceFromDF(data):

    tmp = data[['end_lat','end_lon','predict_end_lat','predict_end_lon']].astype(float)

    error = []

    for i in tmp.values:

        t = getDistance(i[0],i[1],i[2],i[3])

        error.append(t)

    print np.sum(f(np.array(error))) / tmp.shape[0]




def dateConvert(data,isTrain):

    print 'convert string to datetime'

    data['start_time'] = pd.to_datetime(data['start_time'])

    if isTrain:

        data['end_time'] = pd.to_datetime(data['end_time'])

    data['weekday'] = data['start_time'].dt.weekday + 1

    return data


#

def latitude_longitude_to_go(data,isTrain):

    tmp = data[['start_lat','start_lon']]

    start_geohash = []

    for t in tmp.values:

        start_geohash.append(str(round(t[0],5)) + '_' + str(round(t[1],5)))

    data['startGo'] = start_geohash

    if isTrain:

        tmp = data[['end_lat','end_lon']]

        end_geohash = []

        for t in tmp.values:

            end_geohash.append(str(round(t[0],5))+ '_' + str(round(t[1],5)))

        data['endGo'] = end_geohash

    return data


# 用户去过最多的三个地方

def getMostTimesCandidate(candidate):

    mostTimeCandidate = candidate[candidate['start_time']<='2018-06-30 23:59:59']

    mostTimeCandidate = mostTimeCandidate[['out_id','endGo','end_lat','end_lon','weekday']]

    mostTimeCandidate_3 = mostTimeCandidate.groupby(['out_id','endGo','weekday'],as_index=False)['endGo'].agg({'mostCandidateCount':'count'})

    mostTimeCandidate_3.sort_values(['mostCandidateCount','out_id'],inplace=True,ascending=False)

    mostTimeCandidate_3 = mostTimeCandidate_3.groupby(['out_id','weekday']).tail(7)

    return mostTimeCandidate_3


# 经纬度和 string 转化

def geoHashToLatLoc(data):

    tmp = data[['endGo']]

    predict_end_lat = []

    predict_end_lon = []

    for i in tmp.values:

        lats, lons = str(i[0]).split('_')

        predict_end_lat.append(lats)

        predict_end_lon.append(lons)

    data['predict_end_lat'] = predict_end_lat

    data['predict_end_lon'] = predict_end_lon

    return data



def calcGeoHasBetween(go1,go2):

    latA, lonA = str(go1).split('_')

    latB, lonB = str(go2).split('_')

    distence = getDistance(float(latA), float(lonA), float(latB), float(lonB))

    return distence


# start to end distance

def calcGeoHasBetweenMain(data):

    distance = []

    tmp = data[['endGo','startGo']]

    for i in tmp.values:

        distance.append(calcGeoHasBetween(i[0],i[1]) / 1000 )

    data['distance'] = distance

    return data


print 'begin'

# 用1-6月去提取最常去的地方

# 用7 月 7 月去训练

train = pd.read_csv('train.csv')

print train['start_time'].min(),train['start_time'].max()

print train[train['start_time']>'2018-06-30 23:59:59'].shape

print train[train['start_time']<='2018-06-30 23:59:59'].shape


test = pd.read_csv('test.csv')

print test['start_time'].min(),test['start_time'].max()

print test.shape


trainIndex = train.shape[0]

testIndex = test.shape[0]


print trainIndex,testIndex


train = dateConvert(train,True)

test = dateConvert(test,False)


train = latitude_longitude_to_go(train,True)

test = latitude_longitude_to_go(test,False)


train.to_csv('train1.csv',index=False)

test.to_csv('test1.csv',index=False)



print '##############################################'


userMostTimes3loc = getMostTimesCandidate(train)


val = train[train['start_time']>'2018-06-30 23:59:59']


val = val[['r_key','out_id','end_lat','end_lon','weekday','startGo','endGo','start_lat','start_lon']]

val.rename(columns={'endGo':'trueEndGo'},inplace=True)

val = pd.merge(val,userMostTimes3loc,on=['out_id','weekday'],how='left',copy=False)

val['endGo'] = val['endGo'].fillna(val['startGo'])

val['flag1'] = val['trueEndGo'] == val['endGo']

val['flag1'] = val['flag1'].astype(int)

val = calcGeoHasBetweenMain(val)



test = test[['r_key','out_id','weekday','startGo','start_lat','start_lon']]

test = pd.merge(test,userMostTimes3loc,on=['out_id','weekday'],how='left',copy=False)

test['endGo'] = test['endGo'].fillna(test['startGo'])

test = calcGeoHasBetweenMain(test)


# model

feature = ['start_lat','start_lon','weekday','distance','mostCandidateCount']

from sklearn.linear_model import LogisticRegression


print 'training'

lr = LogisticRegression()

lr.fit(val[feature].fillna(-1).values,val['flag1'].values)

pre = lr.predict_proba(val[feature].fillna(-1).values)[:,1]


val_result = val[['r_key','endGo','end_lat','end_lon',]]

val_result['predict'] = pre


val_result = val_result.sort_values(['predict'],ascending=False)

val_result = val_result.drop_duplicates(['r_key'])


val = geoHashToLatLoc(val)

getDistanceFromDF(val)


subPre = lr.predict_proba(test[feature].fillna(-1).values)[:,1]


test_result = test[['r_key','endGo']]

test_result['predict'] = subPre


test_result = test_result.sort_values(['predict'],ascending=False)

test_result = test_result.drop_duplicates(['r_key'])

test_result = geoHashToLatLoc(test_result)


submit = test_result[['r_key','predict_end_lat','predict_end_lon']]

submit.columns = ['r_key','end_lat','end_lon']


submit.to_csv('./result.csv',index=False)


3条评论

分享

3条评论
意见反馈
关注微信公众号 关注微信公众号

扫一扫分享给周围朋友