levenshtein java_Spark Java API 计算 Levenshtein 距离
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 距离相关推荐
- 基于OpenStreetMap计算驾车距离(Java)
最近公司有个项目需要计算6000个点之间的驾车距离,第一时间想到的是利用Google的Distance Matrix API,但是免费Key每天只能计算2500个元素(元素 = 起点数量 * 终点数量 ...
- Java:计算地球上两个经纬度坐标之间的距离-geodesy和geotools实现
目录 方式一:自定义公式计算 方式二:geodesy计算距离 方式三:geotools计算距离 两个点的经纬度 latitude纬度 longitude经度 地点 22.678611 113.8056 ...
- Java SE 8新功能介绍:使用新的DateTime API计算时间跨度
使用Java SE 8新的DateTime API JSR 310-可以实现更清晰,可读且功能强大的编码. Java SE 8,JSR 310 在上一篇文章" 使用Streams API处理 ...
- oracle 经纬度算距离,根据经纬度诀别用java和Oracle存储过程计算两点距离
根据经纬度分别用java和Oracle存储过程计算两点距离 create or replace procedure SP_GET_DISTANCE (cx in number,cy in number ...
- 使用百度地图API计算两点直线距离、道路距离和行车时间
使用百度地图API计算两点直线距离.道路距离和行车时间 摘要 关键词 介绍 数据展示 工具介绍 根据经纬度计算两点之间的距离 根据经纬度计算两点之间的道路距离和行车时间 多进程 运行中 结果展示 问题 ...
- 基于百度地图API计算任意两点间的出行距离
文章目录 前言 使用步骤 1.导入相关包 2.计算小汽车距离 3.计算骑行距离 4.创建主函数 总结 前言 为了方便自己以后查找代码,也不想让自己的桌面变得凌乱不堪,所以将把自己之前的代码保存到这里面 ...
- springboot8==调用百度地图API从浏览器获取经纬度,后端使用geodesy依赖计算配送距离
见百度地图API调用文档 jspopularGL | 百度地图API SDK ================ <!--引入百度地图API用于从浏览器获取当前经纬度--> <scri ...
- Java计算当前日期距离生日还有多少天
1.键盘录入你的生日字符串 (如:"1998年08月08日")2.计算当前日期距离生日那天有多少天? public static void main(String[] args) ...
- 百度地图API计算俩点距离
百度地图提供了获取经度跟维度的方法: new BMap.Point(poi.point.lng, poi.point.lat) 1,首先得引入百度地图的js文件 2.这样就可以调用其中的方法了,接着在 ...
最新文章
- TP框架中同时使用“or”和“and”
- 选中下拉列表显示全部数据_小白都能学会的多级下拉列表,让你的Excel效率提升百倍...
- python中格式化字符串的作用_python中字符串格式化的意义(化妆)
- 代码在eclipse下不报错,在doc命令行下报错--jar file和runable jar file
- com.android.backupconfirm,终于去掉beta俱乐部了
- linux 条码识别,PDF417二维条码识别技术的研究及其在Linux平台下的实现
- mysql bit类型_Mysql:bit类型的查询与插入
- java版spring cloud+spring boot+redis社交电子商务平台-spring-cloud-config
- httphandler java_java – 使用HTTPHandler上传文件
- 游戏中的网络同步机制——Lockstep
- 推荐一款自己开发的剪映字幕翻译工具
- 计算机多媒体英语,基于计算机多媒体的英语个性化教学
- Python Excel教程之如何将多个 excel 文件合并为一个文件(教程含源码)
- 路飞学城python开发ftp_路飞学城-Python开发集训-第1章
- 电商和新媒体运营是做什么的
- 高精地图应用(四)横向定位
- 工业大数据特征有哪些 大数据工程师来告诉你
- html图片格式有什么,jpeg是一种什么格式?
- 重新思考人和计算机的关系
- 有关未雨绸缪:我国电子商务税收策略的思索