NLP实战命名实体识别

news2024/11/17 23:57:09

文章目录

  • 一、导入相关包
  • 二、加载数据集
  • 三、数据预处理
  • 四、创建模型
  • 五、创建评估函数
  • 六、配置训练参数
  • 七、创建训练器
  • 八、模型训练
  • 九、模型预测

一、导入相关包

  • DataCollatorForTokenClassification 用于 Token 级别的分类任务
import evaluate
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForTokenClassification, 
	TrainingArguments, Trainer, DataCollatorForTokenClassification

二、加载数据集

# 如果可以联网,直接使用load_dataset进行加载,cache_dir将数据缓冲到该位置
ner_datasets = load_dataset("peoples_daily_ner", cache_dir="./data")
# 如果无法联网,则使用下面的方式加载数据集
# from datasets import DatasetDict
# ner_datasets = DatasetDict.load_from_disk("ner_data")
ner_datasets

'''
DatasetDict({
    train: Dataset({
        features: ['id', 'tokens', 'ner_tags'],
        num_rows: 20865
    })
    validation: Dataset({
        features: ['id', 'tokens', 'ner_tags'],
        num_rows: 2319
    })
    test: Dataset({
        features: ['id', 'tokens', 'ner_tags'],
        num_rows: 4637
    })
})
'''

  • 查看一条数据
ner_datasets["train"][0]
'''
{'id': '0',
 'tokens': ['海',
  '钓',
  '比',
  '赛',
  '地',
  '点',
  '在',
  '厦',
  '门',
  '与',
  '金',
  '门',
  '之',
  '间',
  '的',
  '海',
  '域',
  '。'],
 'ner_tags': [0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 5, 6, 0, 0, 0, 0, 0, 0]}
'''
  • 查看特征信息
ner_datasets["train"].features
'''
{'id': Value(dtype='string', id=None),
 'tokens': Sequence(feature=Value(dtype='string', id=None), length=-1, id=None),
 'ner_tags': Sequence(feature=ClassLabel(names=['O', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG', 'B-LOC', 'I-LOC'], id=None), length=-1, id=None)}
'''
  • 获取标签信息
label_list = ner_datasets["train"].features["ner_tags"].feature.names
label_list
'''
['O', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG', 'B-LOC', 'I-LOC']
'''

三、数据预处理

tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-macbert-base")

tokenizer(ner_datasets["train"][0]["tokens"], is_split_into_words=True)   
# 对于已经做好tokenize的数据,要指定is_split_into_words参数为True
'''
{'input_ids': [101, 3862, 7157, 3683, 6612, 1765, 4157, 1762, 1336, 7305, 680, 7032, 7305, 722, 7313, 4638, 3862, 1818, 511, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
'''

否则
tokenizer(ner_datasets["train"][0]["tokens"], is_split_into_words=False) 
'''
{'input_ids': [[101, 3862, 102], [101, 7157, 102], [101, 3683, 102], [101, 6612, 102], [101, 1765, 102], [101, 4157, 102], [101, 1762, 102], [101, 1336, 102], [101, 7305, 102], [101, 680, 102], [101, 7032, 102], [101, 7305, 102], [101, 722, 102], [101, 7313, 102], [101, 4638, 102], [101, 3862, 102], [101, 1818, 102], [101, 511, 102]], 'token_type_ids': [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]], 'attention_mask': [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]}
'''

- attention_mask取值为1指的是不需要做mask

  • 字词分词的时候(例如下面的英文数据)会存在一个 token 对应若干 id,所以不能简单的一一对应
res = tokenizer("interesting word")
res
'''
{'input_ids': [101, 10673, 12865, 12921, 8181, 8681, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1]}
'''
  • 解决方案:word_ids(),实现标签映射
res.word_ids()
'''
[None, 0, 0, 0, 0, 1, None] # None代表的是特殊token
'''

  • 实现label和token的一一对应
# 借助word_ids 实现标签映射
def process_function(examples):
    tokenized_exmaples = tokenizer(examples["tokens"], max_length=128, truncation=True, is_split_into_words=True)
    # 实现label和token的一一对应
    labels = []
    for i, label in enumerate(examples["ner_tags"]):
        word_ids = tokenized_exmaples.word_ids(batch_index=i)
        label_ids = []
        for word_id in word_ids:
            if word_id is None:
                label_ids.append(-100) # -100 softmax后会置为0
            else:
                label_ids.append(label[word_id])
        labels.append(label_ids)
    tokenized_exmaples["labels"] = labels
    return tokenized_exmaples
tokenized_datasets = ner_datasets.map(process_function, batched=True)
tokenized_datasets
'''
DatasetDict({
    train: Dataset({
        features: ['id', 'tokens', 'ner_tags', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 20865
    })
    validation: Dataset({
        features: ['id', 'tokens', 'ner_tags', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 2319
    })
    test: Dataset({
        features: ['id', 'tokens', 'ner_tags', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 4637
    })
})
'''

print(tokenized_datasets["train"][0])
'''
{'id': '0', 
'tokens': ['海', '钓', '比', '赛', '地', '点', '在', '厦', '门', '与', '金', '门', '之', '间', '的', '海', '域', '。'], 
'ner_tags': [0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 5, 6, 0, 0, 0, 0, 0, 0], 'input_ids': [101, 3862, 7157, 3683, 6612, 1765, 4157, 1762, 1336, 7305, 680, 7032, 7305, 722, 7313, 4638, 3862, 1818, 511, 102], 
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 
'labels': [-100, 0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 5, 6, 0, 0, 0, 0, 0, 0, -100]}
'''

四、创建模型

  • 对于所有的非二分类任务,切记要指定num_labels,否则就会device错误
# 对于所有的非二分类任务,切记要指定num_labels,否则就会device错误
model = AutoModelForTokenClassification.from_pretrained("hfl/chinese-macbert-base", 
                                                        num_labels=len(label_list))



model.config.num_labels
'''
7
'''

五、创建评估函数

# seqeval = evaluate.load("seqeval_metric.py") # 本地的加载方式
!pip install seqeval
seqeval = evaluate.load("seqeval")
seqeval

'''
Args:
    predictions: List of List of predicted labels (Estimated targets as returned by a tagger)
    references: List of List of reference labels (Ground truth (correct) target values)
    suffix: True if the IOB prefix is after type, False otherwise. default: False
    scheme: Specify target tagging scheme. Should be one of ["IOB1", "IOB2", "IOE1", "IOE2", "IOBES", "BILOU"].
        default: None
    mode: Whether to count correct entity labels with incorrect I/B tags as true positives or not.
        If you want to only count exact matches, pass mode="strict". default: None.
    sample_weight: Array-like of shape (n_samples,), weights for individual samples. default: None
    zero_division: Which value to substitute as a metric value when encountering zero division. Should be on of 0, 1,
        "warn". "warn" acts as 0, but the warning is raised.

Returns:
    'scores': dict. Summary of the scores for overall and per type
        Overall:
            'accuracy': accuracy,
            'precision': precision,
            'recall': recall,
            'f1': F1 score, also known as balanced F-score or F-measure,
        Per type:
            'precision': precision,
            'recall': recall,
            'f1': F1 score, also known as balanced F-score or F-measure
Examples:

    >>> predictions = [['O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'I-MISC', 'O'], ['B-PER', 'I-PER', 'O']]
    >>> references = [['O', 'O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'O'], ['B-PER', 'I-PER', 'O']]
    >>> seqeval = evaluate.load("seqeval")
    >>> results = seqeval.compute(predictions=predictions, references=references)
    >>> print(list(results.keys()))
    ['MISC', 'PER', 'overall_precision', 'overall_recall', 'overall_f1', 'overall_accuracy']
    >>> print(results["overall_f1"])
    0.5
    >>> print(results["PER"]["f1"])
    1.0
""", stored examples: 0)
'''
import numpy as np

def eval_metric(pred):
    # 返回的predictions只是logits
    predictions, labels = pred
    predictions = np.argmax(predictions, axis=-1)

    # 将id转换为原始的字符串类型的标签
    true_predictions = [
        [label_list[p] for p, l in zip(prediction, label) if l != -100] # simple
        for prediction, label in zip(predictions, labels) # batch
    ]

    true_labels = [
        [label_list[l] for p, l in zip(prediction, label) if l != -100] # simple
        for prediction, label in zip(predictions, labels) # batch
    ]

    result = seqeval.compute(predictions=true_predictions, references=true_labels, mode="strict", scheme="IOB2")

    return {
        "f1": result["overall_f1"]
    }

六、配置训练参数

huggingface transformers使用指南之二——方便的trainer
详解Hugging Face Transformers的TrainingArguments_若石之上的博客-CSDN博客
LLM大模型之Trainer以及训练参数

!pip install accelerate # Using the `Trainer` with `PyTorch` requires `accelerate>=0.20.1`
args = TrainingArguments(
    output_dir="models_for_ner", # 断点和运行日志记录保存文件夹
    per_device_train_batch_size=64, 
    per_device_eval_batch_size=128,
    evaluation_strategy="epoch", # 评价策略,需要和保存策略保持一致
    save_strategy="epoch",
    metric_for_best_model="f1", # 选取最好模型的指标,这里是评价函数返回的字典的key f1
    load_best_model_at_end=True, # 训练完后加载最好的模型
    logging_steps=50, # 日志打印步数
    num_train_epochs=3
)


# 如果使用evaluation_strategy="steps",
# 则需要指定eval_steps参数,否则eval_steps=logging_steps
args = TrainingArguments(
    output_dir="models_for_ner", # 断点和运行记录保存文件夹
    per_device_train_batch_size=64, 
    per_device_eval_batch_size=128,
    evaluation_strategy="steps", # 评价策略,需要和保存策略保持一致
    save_strategy="steps",
    metric_for_best_model="f1", # 选取最好模型的指标,这里是评价函数返回的字典的key f1
    load_best_model_at_end=True, # 训练完后加载最好的模型
    logging_steps=50, # 日志打印步数
    num_train_epochs=1
)
  • 采用第二种参数:

image.png


七、创建训练器

  • 如果只有训练集还想实现在训练的时候评估的效果,则只需要将eval_dataset=tokenized_datasets[“train”] 即可
trainer = Trainer(
    model=model,
    args=args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    compute_metrics=eval_metric,
    data_collator=DataCollatorForTokenClassification(tokenizer=tokenizer)
)

八、模型训练

trainer.train()
  • 模型评估
trainer.evaluate() # 默认使用trainer中指定的eval_dataset

# 也可以更换其他数据集
trainer.evaluate(eval_dataset=tokenized_datasets["test"])

九、模型预测

res = trainer.predict(tokenized_datasets["test"])
res.predictions.argmax(axis=-1)
'''
array([[0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       ...,
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0]])
'''
res.predictions.argmax(axis=-1)[0]
'''
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
'''
from transformers import pipeline

# 使用pipeline进行推理,要指定id2label
model.config.id2label = {idx: label for idx, label in enumerate(label_list)}
model.config
'''
BertConfig {
  "_name_or_path": "hfl/chinese-macbert-base",
  "architectures": [
    "BertForTokenClassification"
  ],
  "attention_probs_dropout_prob": 0.1,
  "classifier_dropout": null,
  "directionality": "bidi",
  "gradient_checkpointing": false,
  "hidden_act": "gelu",
  "hidden_dropout_prob": 0.1,
  "hidden_size": 768,
  "id2label": {
    "0": "O",
    "1": "B-PER",
    "2": "I-PER",
    "3": "B-ORG",
    "4": "I-ORG",
    "5": "B-LOC",
    "6": "I-LOC"
  },
  "initializer_range": 0.02,
  "intermediate_size": 3072,
  "label2id": {
    "LABEL_0": 0,
    "LABEL_1": 1,
    "LABEL_2": 2,
    "LABEL_3": 3,
    "LABEL_4": 4,
    "LABEL_5": 5,
    "LABEL_6": 6
  },
  "layer_norm_eps": 1e-12,
  "max_position_embeddings": 512,
  "model_type": "bert",
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  "pad_token_id": 0,
  "pooler_fc_size": 768,
  "pooler_num_attention_heads": 12,
  "pooler_num_fc_layers": 3,
  "pooler_size_per_head": 128,
  "pooler_type": "first_token_transform",
  "position_embedding_type": "absolute",
  "torch_dtype": "float32",
  "transformers_version": "4.35.0",
  "type_vocab_size": 2,
  "use_cache": true,
  "vocab_size": 21128
}
'''
# 如果模型是基于GPU训练的,那么推理时要指定device
# 对于NER任务,可以指定aggregation_strategy为simple,得到具体的实体的结果,而不是token的结果
ner_pipe = pipeline("token-classification", 
                    model=model, 
                    tokenizer=tokenizer, 
                    device=0, 
                    aggregation_strategy="simple")
res = ner_pipe("小明在北京上班")
res
'''
Asking to truncate to max_length but no maximum length is provided and the model has no predefined maximum length. Default to no truncation.
[{'entity_group': 'PER',
  'score': 0.44049227,
  'word': '明',
  'start': 1,
  'end': 2},
 {'entity_group': 'LOC',
  'score': 0.9994525,
  'word': '北 京',
  'start': 3,
  'end': 5}]
'''


# 可以用model_max_length参数解决Asking to truncate to max_length but no maximum length is provided and the model has no predefined maximum length. Default to no truncation.
tokenizer = AutoTokenizer.from_pretrained('google/bert_uncased_L-4_H-256_A-4', 
                                          model_max_length=512)


# 指定aggregation_strategy为simple
ner_pipe = pipeline("token-classification", model=model, tokenizer=tokenizer, device=0)
res = ner_pipe("小明在北京上班")
res
'''
[{'entity': 'I-PER',
  'score': 0.44049227,
  'index': 2,
  'word': '明',
  'start': 1,
  'end': 2},
 {'entity': 'B-LOC',
  'score': 0.99940526,
  'index': 4,
  'word': '北',
  'start': 3,
  'end': 4},
 {'entity': 'I-LOC',
  'score': 0.9994997,
  'index': 5,
  'word': '京',
  'start': 4,
  'end': 5}]
'''
# 根据start和end取实际的结果
ner_result = {}
x = "小明在北京上班"
for r in res:
    if r["entity_group"] not in ner_result:
        ner_result[r["entity_group"]] = []
    ner_result[r["entity_group"]].append(x[r["start"]: r["end"]])

ner_result
'''
{'PER': ['明'], 'LOC': ['北京']}
'''

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1200459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Redis系列】Redis上设置key,value的时候出现NOAUTH Authentication required提示如何解决?

哈喽,大家好,我是小浪。相信大家在初学一门新的知识点的时候都会遇到各种各样的问题,在网上找了一大堆的解决方案,最后还是无功而返,那么今天博主就记录一下在进行Redis的一些操作中遇到的问题~ 当我们好不容易安装好R…

基于SSM的KTV包厢管理系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

Windows server 2008 R2 IIS搭建ASP网站教程

一、安装应用程序服务器 提示安装成功 二、添加角色服务asp 三、asp网站配置 放入源码 设置网站首页为index.asp: 设置应用程序池 四、设置网站目录属性 五、access数据库连接配置 Cd c:\Windows\System32\inetsrv appcmd list apppool /xml | appcmd set apppool /…

HarmonyOS应用开发者高级认证(88分答案)

看好选择题,每个2分多答对2个刚好88分,祝你顺利。 其它帮扶选择题。 一、判断 只要使用端云一体化的云端资源就需要支付费用(错)所有使用Component修饰的自定义组件都支持onPageShow,onBackPress和onPageHide生命周期…

栈和队列:栈

栈的概念: 栈: 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。 栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。…

【零基础小白也能轻松学会】3DMAX编织建模教程

有没有想过这些木质材料是如何在椅子上相互交织的?复杂吗?也许是也许不是……本教程将指导您一步一步地以任何形式提出自己的复杂编织图案。本教程将重点关注建模部分,并让您从那里开始发挥想象力。 1.首先创建一个新平面(长度55&…

【原创课设】java+swing+mysql选课管理系统设计与实现

摘要: 随着学校规模的扩大和课程设置的多样化,传统的手工选课管理方式已经无法满足现代教育的需求。因此,开发一款高效、便捷的选课管理系统变得尤为重要。该系统可以提高选课工作的效率,减少人为错误,同时也能为学生…

第27章_事务原理之MVCC与锁机制

文章目录 MVCCread view聚集索引的隐藏列事务的可见性问题快照读当前读 redologundolog锁机制锁类型共享锁(S)排他锁(X)意向共享锁(IS)意向排他锁(IX)锁的兼容性 锁算法锁兼容关于锁…

lesson05-C++模板

个人主页:Lei宝啊 愿所有美好如期而遇 目录 泛型编程 函数模板 类模板 泛型编程 我们先看一个代码: 看着是不是有点麻烦,我们有没有一种通用的办法,让编译器能够根据不同的类型自动生成不同的函数呢?有&#xff…

c primer plus_chapter_four——字符串和格式化输入/输出

1、strlen();const;字符串;用c预处理指令#define和ANSIC的const修饰符创建符号常量; 2、c语言没有专门储存字符串的变量类型,字符串被储存在char类型的数组中;\0标记字符串的结束&a…

Java中的7大设计原则

在面向对象的设计过程中,首先需要考虑的是如何同时提高一个软件系统的可维护性和可复用性。这时,遵从面向对象的设计原则,可以在进行设计方案时减少错误设计的产生,从不同的角度提升一个软件结构的设计水平。 1、单一职责 一个类…

js案例:打地鼠游戏(打灰太狼)

效果预览图 游戏规则 当灰太狼出现的时候鼠标左键点击灰太狼加10分,小灰灰出现的时候鼠标左键点小灰灰击减10分,不点击不减分不加分。 整体思路 1.把获取背景图片中每个地洞的位置,把所有位置放到一个数组中。 2.封装随机数函数,随…

基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码

基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于飞蛾扑火优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神…

【每日逆向】BUUCTF--[ACTF新生赛2020] easyre

拿到exe文件先查下信息,是一个32位程序,加了壳。 不会脱,直接拿到自动脱壳机潦草结束 看着有点乱,稍微改改 嗯,这样舒服多了。就是将V6扩展到18个字节大小,V5也扩展到12个字节大小,这样更符合源…

从0开始python学习-33.夹具@pytest.fixture(scope=““,params=““,autouse=““,ids=““,name=““)

目录 1. 创建夹具 1.1 pytest方式 1.2 unittest方式 2. 使用夹具 2.1 通过参数引用 2.2 通过函数引用 3. 参数详解 3.1 scope:作用域 3.2 params-参数化 3.3 autouseTrue表示自动使用,默认为False 3.4 ids:设置变量名 3.5 name&am…

基于斑点鬣狗算法优化概率神经网络PNN的分类预测 - 附代码

基于斑点鬣狗算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于斑点鬣狗算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于斑点鬣狗优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神…

推荐系统笔记--基于物品的协同过滤(Item CF)

1--基本原理 Item CF的原理是根据物品的相似度来将新的物品推荐给用户;下图中用户对红色物品的感兴趣度为 [2, 1, 4, 3],红色物品与橙色物品的相似度为 [0.1, 0.4, 0.2, 0.6],因此可以计算出用户对橙色物品的感兴趣度。 Item CF的基本思想是&…

江西开放大学引领学习新时代:电大搜题助力学子迈向成功

江西开放大学(简称江西电大)一直以来致力于为学子提供灵活便捷的学习服务。近年来,携手电大搜题微信公众号,江西开放大学以其卓越的教学质量和创新的教学手段,为广大学子开启了一扇通向成功的大门。 作为一家知名的远…

LiteVNA 能做什么?

最近入手了一台 LiteVNA 设备,性价比非常高。因为之前没有接触过 VNA 这种测试仪器,所以准备好好研究一下。和它类似的一个项目是 NanoVNA6000,价格要高些,但可能性能要好点,另外,文档也要全一些。 VNA …

上机4KNN实验4

目录 编程实现 kNN 算法。一、步骤二、实现代码三、总结知识1、切片2、iloc方法3、归一化4、MinMaxScale()5、划分测试集、训练集6、KNN算法 .py 编程实现 kNN 算法。 1、读取excel表格存放的Iris数据集。该数据集有5列,其中前4列是条件属性…