利用机器学习将wgs84转到gcj02试探(一)

机器学习高精度研究(一)

我们知道机器学习是利用大量的数据资料进行学习的,而这些资料不存在明显的函数关系,更多是相关关系,所以利用机器学习来研究高精度的问题是一个巨大的挑战,日常生活中,我们知道经纬度这个数据一般都需要精确到小数点6,7位,属于高精度的范畴,那么怎么利用机器学习来研究高精度的问题呢?我们利用机器学习方法来牛刀小试,研究背景是,将wgs84坐标系转gcj02坐标系,并且使得转换精度足够高,原数据的天地图是wgs84坐标系,幢号是gcj02坐标系,现在的任务是找一个精度足够高的算法,将wgs84转到gcj02上面去。

  • 原数据

在这里插入图片描述

  • 数据可视化
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
data = pd.read_excel("幢号地址验证数据.xlsx") #读取数据
gcj_lon, gcj_lat = data["幢号经度"], data["幢号纬度"]
wgs_lon, wgs_lat = data["天地图经度"], data["天地图纬度"]
plt.figure(figsize = (9, 9))
plt.scatter(gcj_lon, gcj_lat, marker = 'x',color = 'orange', label = 'gcj02')
plt.scatter(wgs_lon, wgs_lat, marker = 'x', color = 'blue',label = "wgs84")
plt.xlim([np.min(gcj_lon) - 0.005, np.max(gcj_lon) + 0.005])
plt.ylim([np.min(gcj_lat) - 0.005, np.max(gcj_lat) + 0.005])
plt.legend()
plt.show()

wgs_gcj
从两个坐标系的对比可以发现gcj02在wgs84的右下角一些,也就是说经度要大一些,纬度要小一些

  • 特征映射

特征映射主要讲把原来的经度,纬度转更高维的特征,研究发现,当指数为1的时候拟合度最高。

X = np.array(data[["天地图经度","天地图纬度"]])
X = np.insert(X, 0, 1, axis =1)
y1, y2  = np.array(gcj_lon), np.array(gcj_lat) #gcj经度,gcj纬度

def generateFunction(x1, x2): #定义生成多项式
    power = 1
    out = np.ones((x1.shape[0],1))
    for i in range(1, power +1):
        for j in range(0, i+1):
            term1 = x1**(i-j)
            term2 = x2**(j)
            term = (term1*term2).reshape(term1.shape[0], 1)
            out = np.hstack((out, term))
    return out

X_mapped = generateFunction(X[:,1], X[:,2]) #(1855, 6)
  • 经度训练

因为经度纬度是两个标签,因变量,所以,需要分别训练。

from scipy import optimize

def h(mytheta, myx): #定义假设函数
    return np.dot(myx, mytheta)

def costFunction(mytheta, myx, myy): #定义损失函数
    return 1/(2*len(myx))*np.dot((h(mytheta, myx)- myy).T, (h(mytheta, myx)-myy))


def optimizeTheta(mytheta, myx, myy): #定义最优化参数函数
    result = optimize.minimize(costFunction, mytheta, args = (myx, myy), method = "TNC", options = {
    
    "maxiter": 50000, "disp": False})
    return  np.array([result.x]), result.fun

initial_theta1 = np.array([0, 0, -1]).T
#initial_theta1 = np.random.randint(-1, 1,(X_mapped.shape[1], 1)) 

theta1, mincost1 = optimizeTheta(initial_theta1, X_mapped, y1)


print(theta1, mincost1)


def predict_lon(x1, x2): #定义预测函数
    X = generateFunction(x1, x2) #1855*6
    pred_lon = h(theta1.T, X)
    return pred_lon

pred_lon = pd.Series(predict_lon(X[:,1], X[:,2]).reshape(-1))

data1 = pd.concat([data, pred_lon], axis = 1)
data1.columns = list(data.columns) + ["预测经度"]
print(data1.head())
data1.to_excel("带预测经度.xlsx") 

[[0.00818154 0.99357317 0.02479023]] 7.416383108455166e-08

经度训练精度 1 0 − 8 10^{-8} 108

  • 纬度训练
from scipy import optimize

def h(mytheta, myx): #定义假设函数
    return np.dot(myx, mytheta)

def costFunction(mytheta, myx, myy): #定义损失函数
    return 1/(2*len(myx))*np.dot((h(mytheta, myx)- myy).T, (h(mytheta, myx)-myy))


def optimizeTheta(mytheta, myx, myy): #定义最优化参数函数
    result = optimize.minimize(costFunction, mytheta, args = (myx, myy), method = "BFGS", options = {
    
    "maxiter": 50000, "disp": False}) #TNC,Powell
    return  np.array([result.x]), result.fun


#initial_theta2 = np.random.randint(-1, 10,(X_mapped.shape[1], 1)) 
initial_theta2 = np.array([0, -1, 0]).T
print(initial_theta2)

theta2, mincost2 = optimizeTheta(initial_theta2, X_mapped, y2)

print(theta2, mincost2)

def predict_lat(x1, x2): #定义预测函数
    X = generateFunction(x1, x2) #1855*6
    pred_lat = h(theta2.T, X)
    return pred_lat

pred_lat = pd.Series(predict_lat(X[:,1], X[:,2]).reshape(-1))

data2 = pd.concat([data, pred_lat], axis = 1)
data2.columns = list(data.columns) + ["预测纬度"]
#print(data2.head())
data2.to_excel("带预测纬度.xlsx")

[ 0 -1 0]
[[0.0244514 0.03245597 0.8733089 ]] 1.7107261219293713e-06

纬度训练精度 1 0 − 6 10^{-6} 106

本次只是用机器学习做一个高精度的试探,如果有感兴趣的朋友可以联系我。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zengbowengood/article/details/107718060