2021-03-07 大数据课程笔记 day46

article/2025/9/20 4:11:31

时间煮雨
@R星校长

机器学习06【机器学习】

主要内容

  1. 理解推荐系统处理数据流程。
  2. python 文件预处理 Hive 数据。
  3. dubbo 服务使用。

学习目标

在这里插入图片描述

第一节 推荐系统-数据处理流程

推荐系统数据处理首先是将 Hive 中的用户 app 历史下载表与 app 浏览信息表按照设备 id 进行关联,然后将关联数据使用 python 文件进行处理,将数据预处理为 label 和 feature 两列的临时数据,后期经过处理转换成逻辑回归 模型的训练集,进而得到模型文件。

数据处理流程图如下:在这里插入图片描述

第二节 Hive构建训练数据

1. 创建临时表

 创建处理数据时所需要的临时表

1.	CREATE TABLE IF NOT EXISTS tmp_dw_rcm_hitop_prepare2train_dm 
2.	(
3.	device_id STRING,
4.	label STRING,
5.	hitop_id STRING,
6.	screen STRING,
7.	ch_name STRING,
8.	author STRING,
9.	sversion STRING,
10.	mnc STRING,
11.	interface STRING,
12.	designer STRING,
13.	is_safe INT,
14.	icon_count INT,
15.	update_date STRING,
16.	stars DOUBLE,
17.	comment_num INT,
18.	font STRING,
19.	price INT,
20.	file_size INT,
21.	ischarge SMALLINT,
22.	dlnum INT,
23.	idlist STRING,
24.	device_name STRING,
25.	pay_ability STRING
26.	)row format delimited fields terminated by '\t';
27.	

最终保存训练集的表

1.	CREATE TABLE IF NOT EXISTS dw_rcm_hitop_prepare2train_dm 
2.	(
3.	label STRING,
4.	features STRING
5.	)row format delimited fields terminated by '\t';
6.	

2. 训练数据预处理过程

 首先将数据从正负例样本和用户历史下载表数据加载到临时表中:

1.	INSERT OVERWRITE TABLE tmp_dw_rcm_hitop_prepare2train_dm
2.	  SELECT
3.	    t2.device_id,
4.	    t2.label,
5.	    t2.hitop_id,
6.	    t2.screen,
7.	    t2.ch_name,
8.	    t2.author,
9.	    t2.sversion,
10.	    t2.mnc,
11.	    t2.interface,
12.	    t2.designer,
13.	    t2.is_safe,
14.	    t2.icon_count,
15.	    to_date(t2.update_time),
16.	    t2.stars,
17.	    t2.comment_num,
18.	    t2.font,
19.	    t2.price,
20.	    t2.file_size,
21.	    t2.ischarge,
22.	    t2.dlnum,
23.	    t1.devid_applist,
24.	    t1.device_name,
25.	    t1.pay_ability
26.	FROM
27.	  (
28.	    SELECT
29.	      device_id,
30.	      devid_applist,
31.	      device_name,
32.	      pay_ability
33.	    FROM
34.	      dw_rcm_hitop_userapps_dm
35.	  ) t1
36.	  RIGHT OUTER JOIN 
37.	  (
38.	    SELECT
39.	      device_id,
40.	      label,
41.	      hitop_id,
42.	      screen,
43.	      ch_name,
44.	      author,
45.	      sversion,
46.	      IF (mnc IN ('00','01','02','03','04','05','06','07'), mnc,'x') AS mnc,
47.	      interface,
48.	      designer,
49.	      is_safe,
50.	      IF (icon_count <= 5,icon_count,6) AS icon_count,
51.	      update_time,
52.	      stars,
53.	      IF ( comment_num IS NULL,0,
54.	       IF ( comment_num <= 10,comment_num,11)) AS comment_num,
55.	      font,
56.	      price,
57.	      IF (file_size <= 2*1024*1024,2,
58.	       IF (file_size <= 4*1024*1024,4,
59.	        IF (file_size <= 6*1024*1024,6,
60.	         IF (file_size <= 8*1024*1024,8,
61.	          IF (file_size <= 10*1024*1024,10,
62.	           IF (file_size <= 12*1024*1024,12,
63.	            IF (file_size <= 14*1024*1024,14,
64.	             IF (file_size <= 16*1024*1024,16,
65.	              IF (file_size <= 18*1024*1024,18,
66.	               IF (file_size <= 20*1024*1024,20,21)))))))))) AS file_size,
67.	      ischarge,
68.	      IF (dlnum IS NULL,0,
69.	       IF (dlnum <= 50,50,
70.	        IF (dlnum <= 100,100,
71.	         IF (dlnum <= 500,500,
72.	          IF (dlnum <= 1000,1000,
73.	           IF (dlnum <= 5000,5000,
74.	            IF (dlnum <= 10000,10000,
75.	             IF (dlnum <= 20000,20000,20001)))))))) AS dlnum
76.	    FROM
77.	      dw_rcm_hitop_sample2learn_dm
78.	  ) t2
79.	ON (t1.device_id = t2.device_id);

第三节 python文件处理数据

1. python文件预处理数据

针对 Hive 中 “tmp_dw_rcm_hitop_prepare2train_dm” 数据,可以使用 Hive 自定义函数进行预处理,得到逻辑回归模型的训练集,这种方式需要编写代码,并且打包上传集群处理数据。这里,我们也可以在 Hive 中直接使用 python 对 Hive 中的数据进行预处理。
将 python 文件加载到 Hive 中:

1.	ADD FILE /opt/sxt/recommender/script/dw_rcm_hitop_prepare2train_dm.py;
2.	

可以通过 list files; 查看是不是 python 文件加载到了 hive:在这里插入图片描述
在 hive 中使用 python 脚本处理数据的原理:Hive 会以输出流的形式将数据交给 python 脚本,python 脚本以输入流的形式来接受数据,接受来数据以后,在 python 中就可以一行行做一系列的数据处理,处理完毕后,又以输出流的形式交给 Hive,交给了 hive 就说明了就处理后的数据成功保存到 hive 表中。

2. python脚本内容

1.	import sys
2.	
3.	if __name__ == "__main__":
4.	    # random.seed(time.time())
5.	    for l in sys.stdin:
6.	        d = l.strip().split('\t')
7.	        if len(d) != 21:
8.	        continue
9.	        # Extract data from the line
10.	        label = d.pop(0)
11.	        hitop_id = d.pop(0)
12.	        screen = d.pop(0)
13.	        ch_name = d.pop(0)
14.	        author = d.pop(0)
15.	        sversion = d.pop(0)
16.	        mnc = d.pop(0)
17.	        interface = d.pop(0)
18.	        designer = d.pop(0)
19.	        icon_count = d.pop(0)
20.	        update_date = d.pop(0)
21.	        stars = d.pop(0)
22.	        comment_num = d.pop(0)
23.	        font = d.pop(0)
24.	        price = d.pop(0)
25.	        file_size = d.pop(0)
26.	        ischarge = d.pop(0)
27.	        dlnum = d.pop(0)
28.	
29.	        hitopids = d.pop(0)
30.	        device_name = d.pop(0)
31.	        pay_ability = d.pop(0)
32.	
33.	        # Construct feature vector
34.	        features = []
35.	        features.append(("Item.id,%s" % hitop_id, 1))
36.	        features.append(("Item.screen,%s" % screen, 1))
37.	        features.append(("Item.name,%s" % ch_name, 1))
38.	        features.append(("Item.author,%s" % author, 1))
39.	        features.append(("Item.sversion,%s" % sversion, 1))
40.	        features.append(("Item.network,%s" % mnc, 1))
41.	        features.append(("Item.dgner,%s" % designer, 1))
42.	        features.append(("Item.icount,%s" % icon_count, 1))
43.	        features.append(("Item.stars,%s" % stars, 1))
44.	        features.append(("Item.comNum,%s" % comment_num,1))
45.	        features.append(("Item.font,%s" % font,1))
46.	        features.append(("Item.price,%s" % price,1))
47.	        features.append(("Item.fsize,%s" % file_size,1))
48.	        features.append(("Item.ischarge,%s" % ischarge,1))
49.	        features.append(("Item.downNum,%s" % dlnum,1))
50.	
51.	        #User.Item and User.Item*Item
52.	        idlist = hitopids.split(',')
53.	        flag = 0;
54.	        for id in idlist:
55.	            features.append(("User.Item*Item,%s" % id +'*'+hitop_id, 1))
56.	            flag += 1
57.	            if flag >= 3:
58.	            break;
59.	
60.	        # Output
61.	
62.	        output = "%s\t%s" % (label, ";".join([ "%s:%d" % (f, v) for f, v in features ]))
63.	        print(output)
64.	

3. python预处理数据使用

1.	INSERT OVERWRITE TABLE dw_rcm_hitop_prepare2train_dm
2.	  SELECT
3.	    TRANSFORM (t.*)
4.	    USING 'python dw_rcm_hitop_prepare2train_dm.py'
5.	    AS (label,features)
6.	  FROM
7.	    (
8.	      SELECT 
9.	        label,
10.	        hitop_id,
11.	        screen,
12.	        ch_name,
13.	        author,
14.	        sversion,
15.	        mnc,
16.	        interface,
17.	        designer,
18.	        icon_count,
19.	        update_date,
20.	        stars,
21.	        comment_num,
22.	        font,
23.	        price,
24.	        file_size,
25.	        ischarge,
26.	        dlnum,
27.	        idlist,
28.	        device_name,
29.	        pay_ability
30.	      FROM 
31.	        tmp_dw_rcm_hitop_prepare2train_dm
32.	    ) t;

4. 导出数据

将 “dw_rcm_hitop_prepare2train_dm” 表中的数据导入到本地处理,这里可以直接在集群中使用 SparkMLlib 直接处理,为了方便演示,将数据导入到本地处理。

1.	insert overwrite local directory '/opt/data/traindata' row format delimited fields terminated by '\t' select * from dw_rcm_hitop_prepare2train_dm;
2.	

注:这里是将数据导出到本地,方便后面再本地模式跑数据,导出模型数据。这里是方便演示真正的生产环境是直接用脚本提交 spark 任务,从 Hive 中获取数据经过 Spark 处理得到模型文件,将模型数据写往 Redis 中。

第四节 推荐系统-模型训练

1. 模型训练代码

模型训练代码参照 scala 文件:Recommonder.scala

1.	Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
2.	val conf = new SparkConf().setAppName("recommonder").setMaster("local[*]")
3.	val sc = new SparkContext(conf)
4.	//加载数据,用\t分隔开
5.	val data: RDD[Array[String]] = sc.textFile("./traindata").map(_.split("\t")).sample(false,0.1,100L)
6.	
7.	//得到第一列的值,也就是label
8.	val label: RDD[String] = data.map(_(0))
9.	
10.	//sample这个RDD中保存的是每一条记录的特征名
11.	//-1 Item.id,hitop_id53:1;Item.screen,screen6:1;Item.name,ch_name80:1;Item.author,author1:1
12.	val sample: RDD[Array[String]] = data.map(_(1)).map(x => {
13.	val arr: Array[String] = x.split(";").map(_.split(":")(0))
14.	arr
15.	})
16.	//将所有元素压平,得到的是所有分特征,然后去重,最后索引化,也就是加上下标,最后转成map是为了后面查询用
17.	//dict 是所有数据的所有不重复的特征
18.	val allFeaturesMap: Map[String, Long] = sample.flatMap(x =>x).distinct().zipWithIndex().collectAsMap()
19.	//得到稀疏向量,为每条数据的features,与dict对比,缺少的特征补成0
20.	val sam: RDD[SparseVector] = sample.map((sampleFeatures :Array[String])=> {
21.	//index中保存的是,未来在构建训练集时,下面填1的索引号集合
22.	val currentOneInfoAllFeatureIndexs: Array[Int] = sampleFeatures.map(feature => {
23.	//get出来的元素程序认定可能为空,做一个类型匹配
24.	val currentFeatureIndex: Long = allFeaturesMap.get(feature).get
25.	//非零元素下标,转int符合SparseVector的构造函数
26.	currentFeatureIndex.toInt
27.	})
28.	//SparseVector创建一个向量
29.	new SparseVector(allFeaturesMap.size, currentOneInfoAllFeatureIndexs, Array.fill(currentOneInfoAllFeatureIndexs.length)(1.0))
30.	})
31.	
32.	//mllib中的逻辑回归只认1.0和0.0,这里进行一个匹配转换
33.	val trainData: RDD[LabeledPoint] = label.map(x => {
34.	x match {
35.	case "-1" => 0.0
36.	case "1" => 1.0
37.	}
38.	//标签组合向量得到labelPoint
39.	}).zip(sam).map(tuple => new LabeledPoint(tuple._1, tuple._2.toDense))
40.	
41.	//逻辑回归训练,两个参数,迭代次数和步长,生产常用调整参数
42.	val model = new LogisticRegressionWithLBFGS()
43.	.setNumClasses(2)
44.	.setIntercept(true)
45.	.run(trainData)
46.	
47.	//模型结果权重
48.	val weights: Array[Double] = model.weights.toArray
49.	//将map反转,weights相应下标的权重对应map里面相应下标的特征名
50.	val map: Map[Long, String] = allFeaturesMap.map(_.swap)
51.	val pw = new PrintWriter("./model");
52.	for(i<- 0 until weights.length){
53.	//通过map得到每个下标相应的特征名
54.	val featureName = map.get(i)match {
55.	case Some(feature) => feature
56.	case None => ""
57.	}
58.	//特征名对应相应的权重
59.	val str = featureName+"\t" + weights(i)
60.	pw.write(str)
61.	pw.println()
62.	}
63.	pw.flush()
64.	pw.close()
65.	

2. 将数据导入到Redis

将 app 基本信息表、app 历史下载表、app 浏览下载表导入到 Redis 中,供后期 dubbo 推荐服务使用。

1.	import redis
2.	
3.	# 将特征值模型文件数据存入redis数据库,将用户历史下载数据存入redis,将app基本描述商品词表存入redis数据库
4.	pool = redis.ConnectionPool(host='mynode4', port='6379', db=2)
5.	r = redis.Redis(connection_pool=pool)
6.	
7.	f = open('./ModelFile.txt', "rb")
8.	while True:
9.	    lines = f.readlines(100)
10.	    if not lines:
11.	        break
12.	    for line in lines:
13.	        kv = line.decode("utf-8").split('\t')
14.	        r.hset("rcmd_features_score", kv[0], kv[1])
15.	
16.	f = open('./UserItemsHistory.txt', "rb")
17.	while True:
18.	    lines = f.readlines(100)
19.	    if not lines:
20.	        break
21.	    for line in lines:
22.	        kv = line.decode("utf-8").split('\t')
23.	        r.hset('rcmd_user_history', kv[0], kv[1])
24.	
25.	f = open('./ItemList.txt', "rb")
26.	while True:
27.	    lines = f.readlines(100)
28.	    if not lines:
29.	    break
30.	    for line in lines:
31.	        kv = line.decode("utf-8").split('\t')
32.	        # line[:-2] 取line 字符串的开头到倒数第二个的位置 数据,含头不含尾,也就是-2 就是将s 字符串中倒数后两个字符删除,常用在从文本读入数据的时候消除换行符的影响
33.	        r.hset('rcmd_item_list', kv[0], line[:-2])
34.	print('all finished...')
35.	f.close()
36.	

第五节 推荐流程-dubbo介绍

dubbo 介绍参照文档:dubbo.doc在这里插入图片描述

第六节 推荐系统-dubbo实现推荐服务

利用 dubbo 实现推荐服务,核心代码如下:

1.	public List<String> getRcmdList(String uid) {
2.	
3.	  // 获得数据库连接
4.	  Jedis jedis = new Jedis("mynode4", 6379);
5.	  jedis.select(2);
6.	  // 从用户历史下载表来获取最近下载
7.	  String downloads = jedis.hget("rcmd_user_history", uid);
8.	  String[] downloadList = downloads.split(",");
9.	
10.	  // 获取所有appID列表
11.	  Set<String> appList = jedis.hkeys("rcmd_item_list");
12.	
13.	  // 存储总的特征分值
14.	  Map<String, Double> scoresMap = new HashMap<String, Double>();
15.	
16.	  // 分别计算所有应用的总权重
17.	  for (String appId : appList) {
18.	    if(Arrays.asList(downloadList).contains(appId)) {
19.	      continue;
20.	    }
21.	     // 计算关联权重
22.	     double relativeFeatureScore = getRelativeFeatureScore(appId, downloadList, jedis);
23.	     updateScoresMap(scoresMap, appId, relativeFeatureScore);
24.	     // 计算基本权重
25.	     double basicFeatureScore = getBasicFeatureScore(appId, jedis);
26.	     updateScoresMap(scoresMap, appId, basicFeatureScore);
27.	  }
28.	
29.	  //这里将map.entrySet()转换成list
30.	  List<Map.Entry<String, Double>> list = new ArrayList<Map.Entry<String, Double>>(scoresMap.entrySet());
31.	  //然后通过比较器来实现排序
32.	  Collections.sort(list, new Comparator<Map.Entry<String, Double>>() {
33.	  //降序排序
34.	  public int compare(Map.Entry<String, Double> entry1,
35.	      Map.Entry<String, Double> entry2) {
36.	     return -entry1.getValue().compareTo(entry2.getValue());
37.	    }
38.	  });
39.	  // 打印分值
40.	  for (Map.Entry<String, Double> mapping : list) {
41.	     System.out.println(mapping.getKey() + ":" + mapping.getValue());
42.	  }
43.	
44.	  // 取前10个appID返回
45.	  List<String> result = new ArrayList<>();
46.	  int count = 0;
47.	  for (Map.Entry<String, Double> mapping : list) {
48.	     count++;
49.	     result.add(mapping.getKey());
50.	    if(count==10){
51.	       break;
52.	    }
53.	  }
54.	
55.	  jedis.close();
56.	  return result;
57.	}
58.	

本节作业

  1. 理解推荐系统处理数据流程。
  2. 使用 python 处理 Hive 数据。
  3. 使用 dubbo 实现服务。

http://chatgpt.dhexx.cn/article/dZlB1Ev3.shtml

相关文章

java手机应用安装目录_如何获得Android手机的软件安装列表

Android的PackageManager类用于检索目前安装在设备上的应用软件包的信息。你可以通过调用getpackagemanager()得到PackageManager类的一个实例。对查询和操作安装包和相关的权限提供了方法&#xff0c;在下面这个Android的例子中&#xff0c;我们得到了在Android安装的应用程序…

这些信贷数据埋点中不得不知的埋点知识

国庆七天假&#xff0c;就这样飞快结束&#xff0c;似乎感觉还没休息够&#xff0c;再来一个七天都不觉得多多。 经过多年来移动互联网的普及&#xff0c;众多APP已采集到亿级乃至数十亿级别用户在设备端、通话、短信、地址等强变量的数据&#xff0c;伴随着近年来信贷行业高速…

新浪微博开发(五)AppList界面

这是客户端开发部分很重要的一个类&#xff0c;但是在开发之前需要用到有关GridView的知识。 若要临时充充电&#xff0c;请移步&#xff1a;GridView(九宫图)的使用介绍。 下面是AppList类的代码&#xff1a; /* * 用来显示、管理自己的微博账号&#xff0c;包括新浪微博账号…

使用react+redux+react-redux+react-router+axios+scss技术栈从0到1开发一个applist应用

先看效果图 github地址 github仓库 在线访问 初始化项目 #创建项目 create-react-app applist #如果没有安装create-react-app的话&#xff0c;先安装 npm install -g create-react-app 目录结构改造 |--config |--node_modules |--public |--scripts |--src|-----api //…

【无标题】https://e-cloudstore.com/ec/api/applist/index.html#/

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

AppList数据处理

本文参考: 风控数据—手机App数据挖掘实践思路 引言 作为移动互联网时代的主要载体,智能手机逐渐成为人们日常生活中不可或缺的一部分,改变着人们的生活习惯。比如,可以用“饿了么”点外卖,“支付宝”可以用来种树,“抖音”可以用来上厕所......强大的App给我们的生活带来…

Faststone capture注册码

转载整理 很好用的图片编辑软件&#xff01; 企业版序列号&#xff1a; name&#xff1a;bluman serial/序列号/注册码&#xff1a;VPISCJULXUFGDDXYAUYF FastStone Capture 注册码 序列号&#xff1a; name/用户名&#xff1a;TEAM JiOO key/注册码&#xff1a;CPCWXRVCZW30H…

FastStone Capture(超级强大的截图、屏幕录制软件)

FastStone Capture是一款体积极其小、功能强悍的屏幕捕捉软件&#xff0c;还有强大的图片编辑、视频录制编辑功能&#xff0c;能够完全满足你截屏、处理图片的要求。FastStone Capture &#xff08;FSCapture&#xff09; 是经典好用的屏幕截图软件&#xff0c;还具有图像编辑和…

截图工具FastStone Capture

文章目录 1 下载安装2 工具使用介绍2.1 截图2.1.1 截图2.1.2 滚动截图 2.2 录屏 FastStone Capture也常被简称为FS Capture&#xff0c;是一款小巧但强悍的软件&#xff0c;集截图、录屏、标尺、取色器等工具于一体。 1 下载安装 官方下载&#xff1a; https://faststone-capt…

FastStone Capture—视频绘制

博客概要 已经写了好些篇博文来介绍FSP了&#xff0c;广告费付一下&#xff1f; 在博主的某篇博文中&#xff0c;粗略介绍了FSP的“屏幕录像”功能&#xff0c;其中“录像编辑”一栏其实没有过多赘述&#xff0c;那么本篇就稍微&#xff0c;真的是稍微&#xff0c;再多介绍一些…

巨好用的截图录屏工具-FastStone Capture

哈喽&#xff0c;大家好呀。想问问小伙伴们平时若是不打开微信、QQ的时候一般是用什么工具截图呢&#xff0c;是微软自带的截图工具&#xff0c;还是其它的呢&#xff1f;今天给大家测试一款非常好用的截图录屏一体轻量级工具哦&#xff0c;也是小编用了好多年的一款工具了&…

FastStoneCapture 截图软件的使用

1:下载解压好 下载后,不要放在桌面,怕把这个截图软件删除掉,把这个FastStoneCapture_9.3_汉化版放在你的,D盘E盘都可以。 放在桌面以后容易当垃圾清理掉!! 下载后,鼠标右键解压成文件夹,文件里面双击打开这个软件就可以用 把软件图标,从你的电脑拖放到桌面就可使用了…

FastStone Capture(FSCapture) 注册码

FSCapture是一款抓屏工具&#xff0c;附带的其他两个小功能&#xff1a;取色器和屏幕放大镜。对抓取的图像提供缩放、旋转、减切、颜色调整等功能。只要点点鼠标就能随心抓取屏幕上的任何东西&#xff0c;拖放支持可以直接从系统、浏览器或其他程序中导入图片。 破解方法&#…

FastStone Capture—截图处理

博客概要 上一篇博文中介绍了FSC的七大截图功能&#xff0c;FSC除了能方便的截图外&#xff0c;还能在很大程度上对所截获的图片进行处理&#xff0c;本博文简单分享几个FSC的“截图处理”功能~ 文章目录 博客概要FastStone Capture-使用案例_总目录截图处理1.绘制2.模糊3.调整…

FastStone Capture 9.3 汉化绿色便携版 - 极品屏幕截图工具

FastStone Capture http://blog.sina.com.cn/flyonzone 是一款极好用的图像浏览、编辑和截屏工具&#xff0c;支持 BMP、JPG、JPEG、GIF、PNG、TIFF、WMF、ICO 和 TGA 在内的主流图片格式&#xff0c;其独有的光滑和毛刺处理技术让图片更加清晰&#xff0c;提供缩放、旋转、剪…

FastStone Capture(定时自动截图)

FastStone Capture(定时自动截图) 点击设置的自动屏幕捕捉。 然后设置捕捉的对象。 选项里记得去掉右下角的时间戳选项。(默认是有的) 然后自行设置间隔时间。 设置输出的文件夹(图片保存的文件夹)

FastStone Capture—屏幕录像

博客概要 FSC还有一个简易的“视频录制”功能&#xff0c;即“屏幕录像”&#xff0c;可以满足一般精度的录制需求&#xff0c;本博文分享利用FSC录制的简要过程&#xff0c;以及对视频的简易处理~ 文章目录 博客概要FastStone Capture-使用案例_总目录屏幕录像1.打开-选择区域…

faststone capture没声音

右键桌面-->个性化 主题-->声音 录音-->右键“立体声混音”&#xff0c;单击启用 并且 设置为默认设备。 以上就是faststone capture录制视频没声音的解决方法.

FastStone Capture监视器上拍摄和拍摄

FastStone Capture监视器上拍摄和拍摄 FastStone Capture是一个功能强大且简单的程序&#xff0c;用于在监视器上拍摄和拍摄。该程序识别并拍摄您在页面上看到的几乎所有内容。 你可以把我当作屏幕截图。您可以轻松复制页面的稳定区域。对于复杂的情况&#xff0c;您甚至可以自…

FastStone Capture 截图工具 YYDS

FastStone Capture 截图工具 YYDS FastStone Capture中文版免费下载 https://www.faststonecapture.cn/download FastStone Capture注册安装教程 https://www.faststonecapture.cn/article/1001.html