0%

1.查看hadoop某个目录下的文件

1
sudo hadoop  fs -ls path

2.从hdfs上下拉文件到本地

1
sudo hdfs fs -get file

3.获取部署在docker中的hadoop的挂载信息等元数据

1
sudo docker inspect hdp-server

由于C++已经多

1.动态数组的声明

1.在只需要考虑是不是存在元素的个数,只可考虑是否存在的情况下,先将list装换成set可以非常有效的提升计算效率

2.对Int类型数值的范围要保持敏感

​ Int类型数值范围为

​ Max 0x7fffffff 2^31-1 2147483647

​ Min 0x80000000 2^31 -2147483648

注意:负数的范围会比正数的范围大一,这按需要特别注意

3.常见数学问题要考虑的情况

​ 1.是否有负数

​ 2.是否有小数

​ 3.是否考虑错误输入?如何进行处理

​ 4.数据范围极端值

​ 5.0或空如何进行处理

​ .

1.除自身以外的数组乘积

给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

示例:

1
2
输入: [1,2,3,4]
输出: [24,12,8,6]

说明:不能使用除法,在O(n)时间复杂度内解决此问题

解决思路:

​ 可以使用先从左到右进行遍历,记录每个位置左面的元素相乘获得的值,存储在output的对应位置,再从右到左进行遍历,记录每个位置右侧的元素乘积,再和output中已经存储的该位置左侧的元素乘积相乘,就可以得到最终结果,时间复杂度为O(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution:
def productExceptSelf(self, nums):
"""
完美解
:type nums: List[int]
:rtype: List[int]
"""
left = 1
right = 1

len_nums = len(nums)

output = [0]*len_nums

#从左到右进行一次遍历,在output中对应位置记录该值左面的元素乘积
for i in range(0,len_nums):
output[i] = left
left = left*nums[i]

#从右到左进行一次遍历,记录每个值右面元素的乘积,和output中已经进行存储的左面乘积相乘,得到各个位置最终的结果
for j in range(len_nums-1,-1,-1):
output[j] *= right
right *= nums[j]

return output

2.缺失数字

给定一个包含 0, 1, 2, ..., nn 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。

示例 1:

1
2
输入: [3,0,1]
输出: 2

示例 2:

1
2
输入: [9,6,4,2,3,5,7,0,1]
输出: 8

说明:
你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现?

思路一:最常见的思路应该是先排序,然后顺序遍历,对不上则为缺失位置

1
2
3
4
5
6
7
8
9
10
11
class Solution:
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
for key,value in emumerate(nums):
if key!=value:
return key
else:
return key+1

思路二:另一种比较巧妙地思路就是直接利用数学的方法来解决这个问题,仔细研究题目,我们可以发现题目中所给的nums数组内所有元素的加和可以看做等差数列的加和减去缺失数,因此我们可以直接计算等差数列的加和(n*(n-1))/2,然后减去nums数组的加和,二者相减即为缺失的数.

1
2
3
4
5
6
7
class Solution:
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return (int(len(nums)*(len(nums)-1)/2)- sum(nums))

爬楼梯问题(动态规划)

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

1
2
3
4
5
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1
2. 2

示例 2:

1
2
3
4
5
6
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1
2. 1 阶 + 2
3. 2 阶 + 1

解题思路:首先经过题目分析我们最自然的可以想到,要想问到第n层楼梯的走法,那么一定为到第n-1和第n-2层楼梯走法之和,因此我们可以清楚地可以看出这是一道递归问题。即n(i) = n(i-1)+n(i-2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
def f(n):
if n==0|n==1:
return 1
else:
return f(n-1)+f(n-2)
if n>=2:
return f(n)
return 1

转换成非递归问题(其实本质就是讲递归问题由系统储存的信息改为程序储存,从而改编程序的运行方式,提高程序的运行效率

1
2
3
4
5
6
7
8
9
10
class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
way = [0,1,2]
for i in range(3,n+1):
way.append(way[i-1]+way[i-2])
return way[n]

​ 项目要求需要在pyspark的集群中将一部分程序做集群的自动化部署,本文记录了程序部署过程中,使用到的一些技术以及遇到的一些问题。

1.SparkSession创建时设置不生效

​ 首先,要进行程序的自动化部署首先要将程序封装成python文件,在这个过程中可能会出现sparkSession谁知不能生效的问题,不论对SparkSession进行什么设置,都不会生生效

这种问题是由于SparkSession的创建过程不能写在主程序中,必须要写在所有函数的外层,并且进行的在文件的初始部分穿创建

2.python 文件传入获取参数

​ python文件也可以和shell脚本一样进行运行时传入参数,这里主要使用的的是python自带的sys和getopt包

1
2
3
4
5
6
7
8
9
10
11
要接受参数的python文件:

import sys
import getopt

opts,args = getopt.getopt(sys.argv[1:],"d:",["d:"])

for opt,arg in opts:
if opt in ("-d","--d"):
input_file = arg
#后续可以直接使用input——file获取的变量名进行操作

3.将python文件执行封装到shell脚本中

​ 这里之所以将python文件进行封装主要是为了方便移植,其实也可以直接设置将python脚本文件执行设置成定时任务,这里是一波瞎操作。主要为了练习和方便移植

1
2
3
4
5
6
7
8
9
10
11
12
#首先在这个shell重要实现获取当前日期或前n天的日期
date = `date -d "1 days ago"+%Y-%m-%d`

#然后在将date作为参数后台执行这个程序并且生成日志
python ***.py -d date > /path/${date}.log 2>&1 &

#=====================注意==============================
#上面直接使用python执行时可能会出现系统中存在多个python导致部署时使用的python和之前测试使用的python不是一个python环境导致的,那么如何确定测试时使用的python环境呢?
#要解决上述问题可以先从新进入到测试用的python环境,然后进行下面操作
import sys
print(sys.execyutable)
#然后将python目录改为上面的python目录

1.在各个隐藏层和激活函数之间加入Batch Normalization层可以大大缩短训练时间,而且还存在隐藏效果,比如出现还可以改善效果。

调用:

​ Normalization(num_features)

参数设置:

​ CNN后接Batch Normalization: nums_feeatures为CNN感受野个数(即输出深度)

​ 全连接层后接Batch Normalization:num_features为输出的特征个数

2.Batch Normalization和Dropout层不要一起使用,因为BN以及具备了dropout的效果,一起使用不但起不到效果,而且会产生副作用

常见副作用:

​ 1.只能使用特别小的速率进行训练,使用较大的速率进行训练时,出现梯度消失,无法进行下降

​ 2.最终与训练集拟合程度不高,例如与训练集的拟合程度只能达到90%

若一定要将dropout和BN一起使用,那么可以采用下面方式:

​ 1.将dropout放在BN后面进行使用

​ 2.修改Dropout公式(如高斯Dropout),使其对对方差不那么敏感

总体思路:降低方差偏移

3.深度学习不收敛问题

​ 1.最常见的原因可能是由于学习速率设置的过大,这种情况一般先准确率不断上升,然后就开始震荡

​ 2.当训练样本较小,而向量空间较大时,也可能会产生不收敛问题,这种情况一般从一开始就开始震荡,机会没有准确率上升的过程

​ 3.训练网络问题。当面对的问题比较复杂,而使用的网络较浅时,可能会产生无法收敛问题

​ 4.数据没有进行归一化。数据输入模型之前如果没有进行归一化,很有可能会产生收敛慢或者无法进行收敛的问题

注意:收敛与否主要是看损失函数是否还在下降,而不是准确率是否还在上升,存在很多情况损失函数在迭代过程中还是在不断地下降,但是准确率基本上处于停滞状态,这种情况也是一种未完全拟合的表现,经过一段时间损失函数的下降后准确率还可能会迎来较大的提升

pyspark 的pyspark.ml.linalg包主要提供了向量相关(矩阵部分不是很常用因此本文不提)的定义以及计算操作

主体包括:

​ 1.Vector

​ 2.DenseVector

​ 3.SparseVector

1.Vector

​ 是下面所有向量类型的父类。我们使用numpy数组进行存储,计算将交给底层的numpy数组。

主要方法:

​ toArray() 将向量转化为numpy的array

2.DenseVector

​ 创建时,可以使用list、numpy array、等多种方式进行创建

常用方法:

​ dot() 计算点乘,支持密集向量和numpy array、list、SparseVector、SciPy Sparse相乘

​ norm() 计算范数

​ numNonzeros() 计算非零元素个数

​ squared_distance() 计算两个元素的平方距离

​ .toArray() 转换为numpy array

​ values 返回一个list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#密集矩阵的创建
v = Vectors.dense([1.0, 2.0])
u = DenseVector([3.0, 4.0])

#密集矩阵计算
v + u

output:
DenseVector([4.0, 6.0])

#点乘
v.dot(v) #密集向量和密集向量之间进行点乘
output:
5.0
v.dot(numpy.array([1,2])) #使用密集向量直接和numpy array进行计算
output:
5.0

#计算非零元素个数
DenseVector([1,2,0]).numNonzeros()

#计算两个元素之间的平方距离
a = DenseVector([0,0])
b = DenseVector([3,4])
a.squared_distance(b)
output:
25.0

#密集矩阵转numpy array
v = v.toArray()
v

output:
array([1., 2.])

3.SparseVector

​ 简单的系数向量类,用于将数据输送给ml模型。

​ Sparkvector和一般的scipy稀疏向量不太一样,其表示方式为,(数据总维数,该数据第n维存在值列表,各个位置对应的值列表)

常用方法:

​ dot() SparseVector的点乘不仅可以在SparseVector之间还可以与numpy array相乘

indices 有值的条目对应的索引列表,返回值为numpy array

size 向量维度

​ norm() 计算范数

​ numNonzeros() 计算非零元素个数

​ squared_distance() 计算两个元素的平方距离

​ .toArray() 转换为numpy array

​ values 返回一个list

注:加粗部分为SparseVector特有的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#创建稀疏向量
a = SparseVector(4, [1, 3], [3.0, 4.0])
a.toArray()
output:
array([0., 3., 0., 4.])

#计算点乘
a.dot(array([1., 2., 3., 4.]))
output:
22.0

#获得存值得对应的索引列表
a.indices
output:
array([1, 3], dtype=int32)

#获取向量维度
a.size
output:
4

​ 在pyspark中文本的向量化技术主要在包pyspark.ml.feature中,主要包括以下几种:

1.Ngram

2.tf-idf

3.Word2Vec

1.Ngram

2.tf-idf

​ 在pyspark中tf和idf是分开的两个步骤

​ (1)tf

​ 整个tf的过程就是一个将将各个文本进行计算频数统计的过程,使用前要先使用也定的算法来对语句进行分词,然后指定统计特征的数量再进行tf统计

常用参数:

​ 1.numsFeatures 统计的特征数量,这个值一般通过ParamGridBuilder尝试得出最合适的值

​ 2.inputCol 输入列,输入类列为ArrayType的数据

​ 3.outputCol 输出列 ,输出列为Vector类型的数据

1
2
3
4
5
6
7
8
9
10
11
12
df = spark.createDataFrame([(["this", "is", "apple"],),(["this", "is", "apple","watch","or","apple"],)], ["words"])

hashingTF = HashingTF(numFeatures=10, inputCol="words", outputCol="tf")
hashingTF.transform(df).show(10,False)

output:
+-----------------------------------+--------------------------------+
|words |tf |
+-----------------------------------+--------------------------------+
|[this, is, apple] |(10,[1,3],[2.0,1.0]) |
|[this, is, apple, watch, or, apple]|(10,[1,2,3,7],[3.0,1.0,1.0,1.0])|
+-----------------------------------+--------------------------------+

​ 其中,10代表了特征数,[1,3]代表了this和is对应的哈希值,[2.0,1.0]代表了this和is出现的频数.

​ (2)idf

常用参数:

​ 1.minDocFreq 最少要出现的频数,如果超过minDocFreq个样本中出现了这个关键词,这个频数将不tf-idf特征,直接为0

​ 2.inputCol 输入列

​ 3.ouputCol 输出列

1
2
3
4
5
6
7
8
9
10
11
12
idf = IDF(inputCol="tf",outputCol="tf-idf")
idf_model = idf.fit(df)

idf_model.transform(df).show(10,False)

output:
+-----------------------------------+--------------------------------+--------------------------------------------------------------+
|words |tf |tf-idf |
+-----------------------------------+--------------------------------+--------------------------------------------------------------+
|[this, is, apple] |(10,[1,3],[2.0,1.0]) |(10,[1,3],[0.0,0.0]) |
|[this, is, apple, watch, or, apple]|(10,[1,2,3,7],[3.0,1.0,1.0,1.0])|(10,[1,2,3,7],[0.0,0.4054651081081644,0.0,0.4054651081081644])|
+-----------------------------------+--------------------------------+--------------------------------------------------------------+

3.CountVec

​ CountVec是一种直接进行文本向量,直接词频统计的向量化方式,可以

常用参数包括:

​ minDF:要保证出现词的代表性。当minDF值大于1时,表示词汇表中出现的词最少要在minDf个文档中出现过,否则去除掉不进入词汇表;当minDF小于1,表示词汇表中出现的词最少要在包分之minDF*100个文档中出现才进入词汇表

​ minTF:过滤文档中出现的过于罕见的词,因为这类词机乎不在什么文本中出现因此作为特征可区分的样本数量比较少。当minTF大于1时,表示这个词出现的频率必须高于这个才会进入词汇表;小于1时,表示这个大于一个分数时才进入词汇表

​ binary: 是否只计算0/1,即是否出现该词。默认值为False。

​ inputCol:输入列名,默认为None

​ outputCol:输出列名,默认为None

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
df = spark.createDataFrame([(["this", "is", "apple"],),(["this", "is", "apple","watch","or","apple"],)], ["words"])

#使用Word2Vec进行词向量化
countvec = CountVectorizer(inputCol='words',outputCol='countvec')
countvec_model = countvec.fit(df)
countvec_model.transform(df).show(10,False)

output:
+-----------------------------------+----------------------------------------+-------------------------------------+
|words |tf |countvec |
+-----------------------------------+----------------------------------------+-------------------------------------+
|[this, is, apple] |(20,[1,11,13],[1.0,1.0,1.0]) |(5,[0,1,2],[1.0,1.0,1.0]) |
|[this, is, apple, watch, or, apple]|(20,[1,2,7,11,13],[1.0,1.0,1.0,2.0,1.0])|(5,[0,1,2,3,4],[2.0,1.0,1.0,1.0,1.0])|
+-----------------------------------+----------------------------------------+-------------------------------------+

#使用CountVec的binary模式进行向量化,
countvec = CountVectorizer(inputCol='words',outputCol='countvec',binary=True)
countvec_model = countvec.fit(df)
countvec_model.transform(df).show(10,False)
output:
+-----------------------------------+----------------------------------------+-------------------------------------+
|words |tf |countvec |
+-----------------------------------+----------------------------------------+-------------------------------------+
|[this, is, apple] |(20,[1,11,13],[1.0,1.0,1.0]) |(5,[0,1,2],[1.0,1.0,1.0]) |
|[this, is, apple, watch, or, apple]|(20,[1,2,7,11,13],[1.0,1.0,1.0,2.0,1.0])|(5,[0,1,2,3,4],[1.0,1.0,1.0,1.0,1.0])|
+-----------------------------------+----------------------------------------+-------------------------------------+

4.Word2Vec

​ Word2Vec 是一种常见的文本向量化方式,使用神经网络讲一个词语和他前后的词语来进行表示这个这个词语,主要分为CBOW和Skip-

​ 特点:Word2Vec主要是结合了前后词生成各个词向量,具有一定的语义信息

在pyspark.ml.feature中存在Word2Vec和Word2VecModel两个对象,这两个对象之间存在什么区别和联系呢?

​ Word2Vec是Word2Vec基本参数设置部分,Word2VecModel是训练好以后的Word2Vec,有些函数只有Word2VecModel训练好以后才能使用

常见参数:

​ 1.vectorSize 生成的词向量大小

​ 2.inputCol 输入列

​ 3.ouputCol 输出列

​ 4.windowSize 输出的词向量和该词前后多少个词与有关

​ 5.maxSentenceLength 输入句子的最大长度,超过改长度直接进行进行截断

​ 6.numPartitions 分区数,影响训练速度

常用函数:

​ 这里的常见函数要对Word2VecModel才能使用

​ getVectors() 获得词和词向量的对应关系,返回值为dataframe

​ transform() 传入一个dataframe,将一个词列转换为词向量

​ save() 保存模型

使用要先使用训练集对其进行训练:

1
2
3
4
5
6
7
8
9
10
11
12
输入数据:
已经使用一定的分词方式已经进行分词后的ArrayType数组
输出:
当前句子各个词进行word2vec编码后的均值,维度为vectorSize

word2vec = Word2Vec(vectorSize=100,inputCol="word",outputCol="word_vector",windowSize=3,numPartitions=300)
word2vec_model = word2vec.fit(data)

#features将会在data的基础上多出一列word_vector,为vectorSize维数组
features = word2vec.trandform(data)

word2vec_model.save("./model/name.word2vec")

Word2Vec如何查看是否已经训练的很好:

​ 1.选择两个在日常生活中已知词义相近的两个词A、B,再选一个与A词义不那么相近但也有一定相似度的词C

​ 2.计算A和B以及A和C的余弦距离

​ 3.比较其大小,当满足AB距离小于AC时,重新选择三个词重复上过程多次都满足,那么认为模型已经训练完毕;若不满足上述过程,那么继续加入样本进行训练

当word2vec中为了表达两个比较相近的词的相似性可以怎么做?比如在当前word2vec下tea、cooffe之间的相似性非常高,接近于1

​ 增加word2vec的向量维度。可能是在当前维度中向量维度过小,导致这两个词无法表达充分,因此我们可以增加向量维度,以期待在更高维的向量空间中,可以区分这个名词

过程中可能用的:

1
2
3
4
5
#获得某个词对应的词向量
word2vec_model.getVectors().filter("word=='0eva'").collect()[0]['vector']

#计算两个词向量之间距离平方
a1.squared_distance(a2)

​ ububtu默认情况下会存在一个默认回收站,当使用的文件被误删除需要找回时,可以进入到回收站找到该文件,将其恢复出来即可

回收站位置:

​ ~/.local/share/Trash

找回方式:

​ 进入该目录,直接将该目录中的文件考出即可

马尔科夫模型假设:

​ 1.马尔科夫模型认为每一时刻的表现x有一个状态z与其对应

​ 2.观测独立性假设:每个时刻的输出都只与当前的状态有关

​ 3.贝叶斯公式P(o|λ) = P(λ|o)P(o) / P(λ)

马尔科夫模型的推导过程

​ 对于马尔科夫模型,求解的最终目的是

1
maxP(o1o2...on|λ1λ2...λn)

​ 由于p(o|λ)是个关于2n各变量的条件概率,并且n不固定,因此没办法进行精确计算。因此马尔科夫链模型采用了一种更加巧妙地方式来进行建模。

​ 首先,根据贝叶斯公式可以得:

1
P(o|λ) = P(λ|o)P(o) / P(λ)

​ λ为给定的输入,因此P(λ)为常数,因此可以忽略.因此

1
P(o|λ) = P(λ|o)P(o)

​ 而根据观测独立性假设,可以得到

1
2
P(o1o2...on1λ2...λn) = P(o1|λ1)P(o2|λ2)...P(on|λn)
P(o) = P(o1)P(o2|o1)P(o3|o1,o2)...P(on|on-1,on-2,...,o1)

​ 而由于其次马尔科夫假设,每个输出仅与上一个一个输出有关,那么

1
P(o) = p(o1)P(o2|o1)....P(on|on-1)

​ 因此最终可得:

1
P(o|λ) ~ p(o1)P(o1|o2)P(λ|o2)P(o2|o3)P(λ3|o3)...P(on|on-1)P(λ|on)

​ 其中,P(λk|ok)为发射概率,P(ok|ok-1)为转移概率。

维特比算法

​ 维特比算法是隐马尔科夫模型最终求解当前表现链最可能对应的状态链使用的一种动态规划算法。主要思想是:

HMM模型训练后的输出为:初始状态概率矩阵、状态转移矩阵、发射概率矩阵三个结果,用来后续进行预测

概率图模型大部分都是这样,输出为几个概率矩阵

而LR模型的输出就为系数矩阵了

我们可以看出来,LR在使用训练好的模型进行与测试效率较高,而HMM使用训练好的模型进行训练时效率较低