| Yang |


  • Home

  • Tags

  • Archives

Presto 踩坑笔记

Posted on 2019-11-28

查 MySQL 不走索引

查一个大表,只需要计算当天的数据,建立的联合索引里面有 createdtime 这个字段。但是查的时候,只限定 createdtime 这个字段,但是极慢没有走索引。

先 Presto 查询单个订单,秒出,即索引是有效的。然后怀疑是 Presto 日期函数处理结果的问题,发现果然不对劲。我们在 SQL 利用to_unixtime() 函数生成的结果是 timestamp类型的,MySQL表中 createdtime 的类型是 bigint,而 Presto 要求类型严格,所以踩坑了。。。

解决办法很简单,使用 cast 做一下类型转化即可

找不到表名

订单表命名为 order,在 Hive 和 MySQL 中都是使用’`’去做转义,Presto死活找不到,后来发现是使用’”‘去搞的。。。

存成文件查询报错

cli 中可以无错执行,presto -f 则报错。

若存成文件执行,要在末尾加;。

重定向内容每一段包含’”‘

例如查询出来的结果像这样:"123","123","123"

处理的时候很不方便,可以直接使用 sed 命令修改文件:

1
2
3
# sed 's/要被取代的字串/新的字串/g'
sed -i 's/","/\t/g' demo.txt
sed -i 's/"//g' demo.txt

数据量太大

  1. 不要选取全部字段,选自己使用的
  2. 减少数据量常规方法…
  3. join 的时候大表放在左边,Presto 默认 broadcast join,即将 join 左边的表分割到多个 worker,然后将 join 右边的表数据整个复制一份发送到每个 worker 进行计算。如果右边的表数据量太大,则可能会报内存溢出错误。

未完待续

Hive内置的常见算术运算符和逻辑运算符

Posted on 2019-10-10

在我们日常地使用中,我们经常会使用 hive 进行各种运算操作,其实这之中发生了很多 hive 数据类型之前的转换操作,比如 string + int 。今天我们来大概看一看,以便踩坑的时候可以更快地出坑。

基本知识

可以先看看后面这篇文章:Hive内置数据类型

假如我们需要对两个不同数据类型的数字进行比较,一个是 int,一个是 smallint,那么在比较的时候,都会被隐式转化为 int 类型再进行比较。不顾我们不可以隐式地将一个 int 类型的数据转化成一个 smallint 类型的数据,除非使用 cast 。

任何整数类型都可以隐式转换成一个范围更大的类型。任意 int 类型、float、string 都可以隐式转换成 double 类型!boolean不可以转化为其他任意类型。

​

具体操作

算术运算符

无特殊说明,则默认返回是变量的最小父类型

  • 等值比较

    语法:A = B

    说明:如果表达式 A 和表达式 B 相等,则为 True ,否则为 False

  • 加法操作

    语法: A + B

    说明:返回 A+B 相加的结果。结果的数值类型等于 A 的类型和 B 的类型的最小父类型。比如 int + int 结果为 int 类型,int + double 为 double 类型

  • 减法操作

    语法:A - B

    说明:同加法操作

  • 乘法操作

    语法: A * B

    说明:同样是返回 A 与 B 的最小父类型,不过如果结果超过默认的结果类型的数值范围,为需要通过 cast 将结果转换成范围更大的数值类型

  • 除法操作

    语法: A / B

    说明:返回 A 除以 B 的结果。结果的数值为 double 类型。Hive中最高精度的数据类型是 double ,只精确到小数点后面16位

  • 取余操作

    语法: A % B

    说明:pass

  • 位与操作

    语法: A & B

    说明:返回 A 和 B 按位进行与操作的结果

    1
    2
    3
    4
    hive (temp)> select 4 & 8;
    0
    hive (temp)> select 4 & 6;
    4
  • 位或操作

    语法:A | B

    说明:返回 A 和 B 按位进行或操作的结果

    1
    2
    hive (temp)> select 4 | 6;
    6
  • 位异或操作

    语法:A ^ B

    说明:返回 A 和 B 按位进行异或操作的结果

  • 位取反操作

    语法:~A

    说明:返回 A 按位取反操作的结果,结果的数值类型等于 A 的类型

逻辑运算符

  • 逻辑与操作

    语法:A and B 或者 A && B

    操作类型: boolean

    说明: pass

  • 逻辑或操作

    语法:A or B 或者 A || B

    操作类型:boolean

    说明:pass

  • 逻辑非操作

    语法:not A 或者 !A

    操作类型:boolean

    说明:pass

了解逻辑回归

Posted on 2019-10-08

什么是逻辑回归

逻辑回归是最简单的分类算法之一,简单但是好用。

基础知识

Sigmoid 函数

对于二分类问题来说,sigmoid 函数可以较为平滑地处理 01 瞬时阶跃问题。其计算公式为:

图像为:

Sigmoid

当然我们也可以利用这个工具来可视化地了解 sigmoid 函数。总所周知,分类的时候会处理多个特征,那我们可以对于每一个特征 $x_i$ 乘以一个回归系数 $w_i$ ,得到 $z=w_0x_0+w_1x_0+…+w_nx_n$ ,即

可以很明显地看到,sigmoid 函数的值域是 $(0,1)$ ,且 $z$ 的值越大,则样本 $x_i$ 表示正例的概率越大,反之同理。$z$ 是一个线性函数,后面会经常用到。

定义条件概率

在 $x_i$ 出现的情况下,原本为正的条件概率为:

在 $x_i$ 出现的情况下,原本为负的条件概率为:

那么条件概率既是:

几率相关

事件发生的几率等于该事件发生的概率除以不发生的概率

那么对数几率则是:

对于 LR 而言,则输出 $Y=1$ 的对数几率则是:

即输出 $Y=1$ 的对数几率是由输入 $x$ 表示的线性模型。

导函数形式

梯度

梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)

回顾一下梯度的计算公式:

其中 i, j, k 为标准的单位向量,分别指向 x, y 跟 z 坐标的方向。

梯度下降法

参考维基百科梯度下降法)

局部最优现象

梯度下降的最终点不一定是全局最优点,所以初始点的点选择对最终结果有很大程度影响。

LR 原理

LR 的工作原理

  1. 初始化每一个回归系数为1

  2. 重复计算R次:

    • 计算整个数据集的梯度

    • 使用 步长 x 梯度,更新回归系数

  3. 更新回归系数

LR 算法特点

优点:简单好用

缺点:容易欠拟合,分类精度可能不高

LR 实现

sigmoid函数

1
2
3
import math
def sigmoid(z):
return 1 / ( 1 + math.exp(-z) )

梯度上升

1
2
def gradasend():
pass

核心代码

1
2
def lr():
pass

LR实战

《日本纪行》

Posted on 2019-09-25

🇯🇵一行感受到很多个点:
街道干净、有礼貌、排队、厕所干净、加热马桶盖、牛奶和水一样价格、对国产产品很执着、日本女生化妆很浓、食物酱油为主、便利店遍布大街小巷、喜爱啤酒、自来水可以直接饮用、打车很贵、新宿站人很多、神社很多、古迹保存完好、公共交通发达、都市圈、中国游客很多、小学生的书包很大、人与人之间有距离感。

有以下几个要点:

  • 主要城市靠海有风,居民环保意识与垃圾分类意识很强,整体建筑冷色系,所以大多地方都很干净。
  • 人多地少,对资源利用率与空间利用率很高
  • 耻感与“不要麻烦别人的心态”处处约束着他们的行事,但喝酒之后的日本人又是不一样,会变得放肆。

动态规划的经典例题

Posted on 2019-09-10

偷珠宝问题


一条直线上,有 n 个房间,每个房间数量不等的财宝,一个盗贼希望从房屋中盗取财宝,由于房屋有警报器,同时从相邻两个房间盗取珠宝就会触发警报,若不触发警报,最多可获取多少财宝?

解决思路

从动态规划的角度考虑,假设小偷站在第 i 个 房间的门前,这个时候他偷不偷是受前面状态影响的。如果第 i-1 个房间可以获得的最大金钱比第 i-2 个加上第 i 个要多的话,那么就应该选择偷取第 i-2 个房间和第 i 个房间,反之则偷取第 i-1 个房间,而放弃第 i 个房间。
状态转移公式:

算法实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import random
def stealMoney(n):
"""
输入房子有 n 座,随机生成金额
"""
value = np.random.randint(20,size=n)
dp = np.zeros(value.shape)
print(value)
for i in range(n):
if i <= 1 :
dp[i] = value[i]
else:
dp[i] = max( dp[i-2] + value[i] , dp[i-1] )
print(dp)
return dp[-1]

假设房间是围成一个圆圈呢?思考了一下,给一个大概的思路:

任意选择一点,切分圆成为一条线段,按照上文的思路去计算前三个点,那么

  • 如果取第一个点,则对[2,-2]进行dp,最后加上第一个点的值
  • 如果取第二个点,则对[1,-1]进行dp

最大子序列和问题


给定一个数组(考虑正负),求这个数组的连续子数组中,最大的那一段的和。

解决思路

假设我们考虑第 i 个数,这个时候我们有记录了前面最大子数组的 dp[i-1],那我们只需要取 dp[i-1] + value[i] 和 value[i] 的最大值即可。
状态迭代公式:

算法实现

1
2
3
4
5
6
def getArrMaxSubSum(arr):
dp = [0 for i in range(len(arr))]
dp[0] = arr[0]
for k in range(1,len(arr)):
dp[k] = max(dp[k-1]+arr[k],arr[k])
return dp[-1]

找零钱问题


已知不同面值的钞票,求如何用最少数量的钞票组成某个金额,求可以使用的最少钞票数量。如果任意数量的已知面值钞票都无法组成该金额,则返回 -1 。

解决思路

给定一个 account 和一个 coins[1,2,5,10] 数组。我们从头开始看:

  • 如果金额是 1 元,则肯定是 1 张,即dp[1] = 1
  • 如果是 2 元的话,那么其实有两种选择,1 + 1 或者 2 , 有两种选择
  • 如果是 8 元的话,那么
    • 8 = dp[7] + 1 , 1 元配上 7 元的最优解
    • 8 = dp[6] + 1 , 2 元配上 6 元的最优解
    • …

也就是需要遍历一下,才可以得到最优解。即归纳出 dp[i] = min(dp[i],dp[i-coins[j]] + 1 )

算法实现

1
2
3
4
5
6
7
8
9
10
11
12
def checkCoins(money):
coins = [1,5,11] # 初始化硬币
dp = [money + 1 for i in range(money+1)] #初始化 dp 数组
dp[0] = 0
for i in range(1,money+1):
for j in range(len(coins)):
if coins[j] <= i: # 硬币如果比钱小,则计算,如果一个硬币刚好够,则只需要一次, dp[0] = 0
dp[i] = min(dp[i],dp[i-coins[j]]+1) # 两次遍历得到最优结果
if dp[money] > money:
return -1
else:
return dp[money]

动态规划基本概念

Posted on 2019-09-06

我们先看一个问题:

有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶。要求用程序来求出一共有多少种走法。

这个问题暴力求解是可以,但是不够美。我们从动态规划的角度来理解下。

动态规划( DP )是一种分阶段求解决策问题的数学思想。总结起来就是一句话,大事化小,小事化了。

问题建模


假如用户最后只差一步就可以走完整个楼梯,根据条件我们知道,这个时候会有两种情况出现

  • 用户在还差一级台阶,9 -> 10
  • 用户还差两级台阶,8 -> 10

意味着我们只要知道了前九级和前八级分别需要多少种走法,即可知道走完十级需要多少种走法。

现在假设$F(n)$表示到第$n$个台阶一共的走法,即:

同理可得,假设用户还差一步可以走到第九级,那么:
…
到最后:

当只有1级台阶和2级台阶时走法很明显,即$ F(1) = 1,F(2) = 2$。现在我们已经成功地把一个复杂地问题简单化啦,这就是动态规划。

最后我们可以得到归纳出以下公式$F$:

动态规划中包含三个重要的概念,最优子结构、边界、状态转移公式

  • 上面问题中,我们知道了$F(10) = F(9) + F(8)$,后两者就是前者的最优子结构。
  • $F(1)$和$F(2)$我们已经不需要简化,这个我们称之为边界。
  • $F$就是状态转移公式。

问题代码实现


使用递归的方法去做:

1
2
3
4
5
6
7
8
def calcWalkWays(n):

if n == 1:
return 1
if n == 2:
return 2
else:
return calcWalkWays(n-1) + calcWalkWays(n-2)

使用dp的方法去做:

1
2
3
4
5
6
def calcWalkWays(n):
dp = [0 for k in range(n)]
dp[0],dp[1] = 1,2
for i in range(2,n):
dp[i] = dp[i-1] + dp[i-2]
return dp[-1]

两种方法都可以取得正确答案,但是第二种明显会快很多,这个可以自己去测试一下。

中文书写的一些规范与参考

Posted on 2019-09-02

胡说八道


一直觉得自己博客的排版不太好,反思了一下,还是细节不到位。

学习了大佬的中文技术文档的写作规范,虽然现在很少写技术文档,不过好的习惯需要有。参考链接很有用。

参考链接


  • 产品手册中文写作规范, by 华为
  • 写作规范和格式规范, by DaoCloud
  • 技术写作技巧在日汉翻译中的应用, by 刘方
  • 简体中文规范指南, by lengoo
  • 文档风格指南, by LeanCloud
  • 豌豆荚文案风格指南, by 豌豆荚
  • 中文文案排版指北, by sparanoid
  • 中文排版需求, by W3C
  • 为什么文件名要小写?, by 阮一峰
  • Google Developer Documentation Style Guide, by Google
  • 出版物上数字用法的规定(国家标准GBT15835-2011)
  • 中华人民共和国国家标准出版物数字用法

了解倒排索引

Posted on 2019-08-31

最开始了解到这个概念是在【终于有人把elasticsearch的原理讲通了】这篇文章,看完只是知道了一个很模糊的概念。今年在《计算广告》这本书里再次看到这个点,决定学习记录一下。

2019-09-03
麻蛋,发现我自己写的一点都没有别人好。。转载了吧: 终于有人把elasticsearch的原理讲通了

其实简单地看,我们常见的正常索引是通过 key 去寻找 value , 反向索引则是通过 value 去寻找 key 就可以了。搜索引擎的原理也就是建立倒排索引。

水了水了。

关于分析工作的一点想法

Posted on 2019-08-28

企业内部的数据工作无非就是两个:分析决策 与 产品赋能 ,现在我从 分析决策 这个角度来看一下。

什么是分析

怎么分析

分析结果的推动与落地

算法的时间复杂度

Posted on 2019-08-27

时间复杂度


时间复杂度是衡量算法性能的重要标准。

在进行算法分析的时候,我们用 T(n) 来表示语句的执行次数,记作:T(n)= O(f(n))。表示随着问题规模n的增大, 算法的执行时间的增长率和 f(n) 的增长率趋于一致,我们可以选择性地忽略某些项只保留最高次项,我们可以称之为 大O表示法。

举点例子:

O(1)

这样的常数项,T(n) = 100 我们可以总结为 O(1)

1
2
3
count = 0 
for i in range(10):
count += 1

O(n)

肉眼可见地答案~

1
2
3
count = 0 
for i in range(n):
count += 1

O(n^2)

T(n) = n + (n-1) + (n-2) + ... + 1 = n(n-1)/2 = O(n^2)

1
2
3
for i in range(n):
for j in range(i,n):
print(i+j)

O(logn)

满足 2^t = n, 即O(logn)

1
2
3
4

while i < n :
i += 1
i = i ** 2

O(nlogn)

1
2
3
4
for n in range(100,10000,1000):
while i < n :
i += 1
i = i ** 2
1234…12
zhangyang

zhangyang

120 posts
39 tags
© 2022 zhangyang
Powered by Hexo
|
Theme — NexT.Mist v5.1.4