Spark Java API 计算 Levenshtein 距离

在上一篇文章中,完成了Spark开发环境的搭建,最终的目标是对用户昵称信息做聚类分析,找出违规的昵称。聚类分析需要一个距离,用来衡量两个昵称之间的相似度。这里采用levenshtein距离。现在就来开始第一个小目标,用Spark JAVA API 计算字符串之间的Levenshtein距离。

1. 数据准备

样本数据如下:

{"name":"Michael", "nick":"Mich","age":50}

{"name":"Andy", "nick":"Anc","age":30}

{"name":"Anch", "nick":"MmAc","age":19}

把数据保存成文件并上传到hdfs上:./bin/hdfs dfs -put levestein.json /user/panda

2. 代码实现

定义一个类表示样本数据:

public static class User{

private String name;

private String nick;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getNick() {

return nick;

}

public void setNick(String nick) {

this.nick = nick;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

创建SparkSession

SparkSession sparkSession = SparkSession.builder()

.appName("levenshtein example")

.master("spark://172.25.129.170:7077")

.config("spark.some.config.option", "some-value")

.getOrCreate();

在Spark命令行./bin/pyspark启动Spark时,会默认创建一个名称为 spark 的SparkSession。而这里是写代码,也需要创建SparkSession对象。

The SparkSession instance is the way Spark executes user-defined

manipulations across the cluster. There is a one-to-one correspondence between a SparkSession and

a Spark Application.

定义数据类型

Encoder userEncoder = Encoders.bean(User.class);

JAVA里面定义了一套数据类型,比如java.util.String是字符串类型;类似地,Spark也有自己的数据类型,因此Encoder就定义了如何将Java对象映射成Spark里面的对象。

Used to convert a JVM object of type T to and from the internal Spark SQL representation.

To efficiently support domain-specific objects, an Encoder is required. The encoder maps the domain specific type T to Spark's internal type system. For example, given a class Person with two fields, name (string) and age (int), an encoder is used to tell Spark to generate code at runtime to serialize the Person object into a binary structure. This binary structure often has much lower memory footprint as well as are optimized for efficiency in data processing (e.g. in a columnar format). To understand the internal binary representation for data, use the schema function.

构建Dataset:

Dataset userDataset = sparkSession.read().json(path).as(userEncoder);

说明一下Dataset与DataFrame区别,Dataset是针对Scala和JAVA特有的。Dataset是有类型的,Dataset的每一行是某种类型的数据,比如上面的User类型。

A Dataset is a strongly typed collection of domain-specific objects that can be transformed in parallel using functional or relational operations. Each Dataset also has an untyped view called a DataFrame, which is a Dataset of Row.

而DataFrame的每一行的类型是Row(看官方文档,我就这样理解了,哈哈。。)

DataFrame is represented by a Dataset of Row。While, in Java API, users need to use Dataset to represent a DataFrame.

这个图就很好地解释了DataFrame和Dataset的区别。

计算levenshtein距离,将之 transform 成一个新DataFrame中:

Column lev_res = functions.levenshtein(userDataset.col("name"), userDataset.col("nick"));

Dataset leveDataFrame = userDataset.withColumn("distance", lev_res);

完整代码

import org.apache.spark.sql.*;

public class LevenstenDistance {

public static class User{

private String name;

private String nick;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getNick() {

return nick;

}

public void setNick(String nick) {

this.nick = nick;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

public static void main(String[] args) {

SparkSession sparkSession = SparkSession.builder()

.appName("levenshtein example")

.master("spark://172.25.129.170:7077")

.config("spark.some.config.option", "some-value")

.getOrCreate();

String path = "hdfs://172.25.129.170:9000/user/panda/levestein.json";

Encoder userEncoder = Encoders.bean(User.class);

Dataset userDataset = sparkSession.read().json(path).as(userEncoder);

userDataset.show();

Column lev_res = functions.levenshtein(userDataset.col("name"), userDataset.col("nick"));

Dataset leveDataFrame = userDataset.withColumn("distance", lev_res);

// userDataset.show();

leveDataFrame.show();

System.out.println(lev_res.toString());

}

}

原来的Dataset:

计算Levenshtein距离后的得到的DataFrame:

根据上面的示例,下面来演示一下一个更实际点的例子:计算昵称和签名之间的levenshtein距离,若levenshtein距离相同,就代表该用户的 昵称 和 签名 是相同的:

数据格式如下:

{"nick":"赖求","uid":123456}

{"details":"时尚是一种态度,时尚第一品牌。看我的。","nick":"冰冷世家@蹦蹦","signature":"轻装时代看我的。艾莱依时尚羽绒服。。","uid":123456}

{"nick":"[潗團軍-6]明 明『招 募』","signature":"我是来擂人的,擂死人不偿命!","uid":123456}

加载数据

Dataset dataset = spark.read().format("json")

.option("header", "false")

.load("hdfs://172.25.129.170:9000/user/panda/profile_noempty.json");

取出昵称和签名

//空字符串 与 null 是不同的

Dataset nickSign = dataset.filter(col("nick").isNotNull())

.filter(col("signature").isNotNull())

.select(col("nick"), col("signature"), col("uid"));

计算昵称和签名的Levenshtein距离

Column lev_distance = functions.levenshtein(nickSign.col("nick"), nickSign.col("signature"));

Dataset nickSignDistance = nickSign.withColumn("distance", lev_distance);

按距离进行过滤

Dataset sameNickSign = nickSignDistance.filter("distance = 0");

这样就能找出昵称和签名完全一样的用户了。

levenshtein java_Spark Java API 计算 Levenshtein 距离相关推荐

  1. 基于OpenStreetMap计算驾车距离(Java)

    最近公司有个项目需要计算6000个点之间的驾车距离,第一时间想到的是利用Google的Distance Matrix API,但是免费Key每天只能计算2500个元素(元素 = 起点数量 * 终点数量 ...

  2. Java:计算地球上两个经纬度坐标之间的距离-geodesy和geotools实现

    目录 方式一:自定义公式计算 方式二:geodesy计算距离 方式三:geotools计算距离 两个点的经纬度 latitude纬度 longitude经度 地点 22.678611 113.8056 ...

  3. Java SE 8新功能介绍:使用新的DateTime API计算时间跨度

    使用Java SE 8新的DateTime API JSR 310-可以实现更清晰,可读且功能强大的编码. Java SE 8,JSR 310 在上一篇文章" 使用Streams API处理 ...

  4. oracle 经纬度算距离,根据经纬度诀别用java和Oracle存储过程计算两点距离

    根据经纬度分别用java和Oracle存储过程计算两点距离 create or replace procedure SP_GET_DISTANCE (cx in number,cy in number ...

  5. 使用百度地图API计算两点直线距离、道路距离和行车时间

    使用百度地图API计算两点直线距离.道路距离和行车时间 摘要 关键词 介绍 数据展示 工具介绍 根据经纬度计算两点之间的距离 根据经纬度计算两点之间的道路距离和行车时间 多进程 运行中 结果展示 问题 ...

  6. 基于百度地图API计算任意两点间的出行距离

    文章目录 前言 使用步骤 1.导入相关包 2.计算小汽车距离 3.计算骑行距离 4.创建主函数 总结 前言 为了方便自己以后查找代码,也不想让自己的桌面变得凌乱不堪,所以将把自己之前的代码保存到这里面 ...

  7. springboot8==调用百度地图API从浏览器获取经纬度,后端使用geodesy依赖计算配送距离

    见百度地图API调用文档 jspopularGL | 百度地图API SDK ================ <!--引入百度地图API用于从浏览器获取当前经纬度--> <scri ...

  8. Java计算当前日期距离生日还有多少天

    1.键盘录入你的生日字符串 (如:"1998年08月08日")2.计算当前日期距离生日那天有多少天? public static void main(String[] args) ...

  9. 百度地图API计算俩点距离

    百度地图提供了获取经度跟维度的方法: new BMap.Point(poi.point.lng, poi.point.lat) 1,首先得引入百度地图的js文件 2.这样就可以调用其中的方法了,接着在 ...

最新文章

  1. TP框架中同时使用“or”和“and”
  2. 选中下拉列表显示全部数据_小白都能学会的多级下拉列表,让你的Excel效率提升百倍...
  3. python中格式化字符串的作用_python中字符串格式化的意义(化妆)
  4. 代码在eclipse下不报错,在doc命令行下报错--jar file和runable jar file
  5. com.android.backupconfirm,终于去掉beta俱乐部了
  6. linux 条码识别,PDF417二维条码识别技术的研究及其在Linux平台下的实现
  7. mysql bit类型_Mysql:bit类型的查询与插入
  8. java版spring cloud+spring boot+redis社交电子商务平台-spring-cloud-config
  9. httphandler java_java – 使用HTTPHandler上传文件
  10. 游戏中的网络同步机制——Lockstep
  11. 推荐一款自己开发的剪映字幕翻译工具
  12. 计算机多媒体英语,基于计算机多媒体的英语个性化教学
  13. Python Excel教程之如何将多个 excel 文件合并为一个文件(教程含源码)
  14. 路飞学城python开发ftp_路飞学城-Python开发集训-第1章
  15. 电商和新媒体运营是做什么的
  16. 高精地图应用(四)横向定位
  17. 工业大数据特征有哪些 大数据工程师来告诉你
  18. html图片格式有什么,jpeg是一种什么格式?
  19. 重新思考人和计算机的关系
  20. 有关未雨绸缪:我国电子商务税收策略的思索

热门文章

  1. JUC并发编程之Java线程(二)
  2. cocos2d python教程_cocos2d-js开发入门
  3. DirectX 11---从空间变换来看3D场景如何转化到2D屏幕
  4. 码农创业,6年80万,有梦想才可能有机会
  5. mysql添加时间默认值_mysql 创建时间字段添加默认值
  6. 老大老二打架,怎么倒霉的总是老三?快手抖音PK陌陌暴跌!
  7. 探索canvas画布绘制技术
  8. 循环结构while及do...while的用法
  9. 用python写一个股票量化交易的选股代码
  10. 给PLC工程师搭个脚手架