先来个例子:
import Foundation
func tokenize(sentence: String) -> [String] {
var tokens:[String] = [String]()
let tagger = NSLinguisticTagger(tagSchemes: [.tokenType], options: 0)
tagger.string = sentence
let range = NSMakeRange(0, sentence.utf16.count)
let options: NSLinguisticTagger.Options = [.omitWhitespace, .omitPunctuation]
tagger.enumerateTags(in: range, unit: .word, scheme: .tokenType, options: options) { (tag, tokenRange, stop) in
let word = (sentence as NSString).substring(with: tokenRange)
tokens.append(word)
}
return tokens
}
let texts: [String] = ["有個大夫叫白朮,他有個徒弟叫七七。"]
for text in texts {
let tokens = tokenize(sentence: text)
print("\(text) --> \(tokens)")
}
直接运行该 swift 脚本,可以发现「白朮」(「白术」的繁体中文写法)被拆开了。 该怎样定义这个词、使其不被误拆呢?
1
blackcat888 247 天前 via Android
不玩原神即可
|
2
chenY520 247 天前
自定义词典吧
|
3
ShikiSuen OP |
5
chenY520 247 天前
@ShikiSuen #4
import Foundation // 创建自定义词典,将需要保留的词汇映射到一个数组,以便后续检查 let customDictionary: [String: [String]] = [ "白术": ["白术"], "大夫": ["大夫"], "七七": ["七七"] ] func tokenize(sentence: String) -> [String] { var tokens: [String] = [] let tagger = NSLinguisticTagger(tagSchemes: [.tokenType], options: 0) tagger.string = sentence let range = NSMakeRange(0, sentence.utf16.count) let options: NSLinguisticTagger.Options = [.omitWhitespace, .omitPunctuation] tagger.enumerateTags(in: range, unit: .word, scheme: .tokenType, options: options) { (tag, tokenRange, stop) in let word = (sentence as NSString).substring(with: tokenRange) if let specialCases = customDictionary[word] { tokens.append(contentsOf: specialCases) } else { tokens.append(word) } } return tokens } let texts: [String] = ["有個大夫叫白朮,他有個徒弟叫七七。"] for text in texts { let tokens = tokenize(sentence: text) print("\(text) --> \(tokens)") } |
7
zjuster 247 天前
之前做过知识图谱,用的 NLP 相关技术和模型。其中的专有词都是走 NER 的(命名实体识别)。NLP 的技术模型另说,NER 就要调教很多模型了。
楼主的这个命题都是人工打标的。分两种 1. 模型建设 先用第三方的中英文语料库调教启动语料库,然后迭代模型,设置在不同的 context 下,某些特定的字符组合将被识别为 entity 模型的概率组合,然后给到人工评估模型结果,打分来调教。这个算是日常模型调教,有更新就需要做定量对比模型版本的。 如果语料库的质量比较高,能够减少很多术语的问题。 前公司是搜索出身的,本身就积累了大量的 user query 库,所以这方便少了很多麻烦。 2. 强制识别 这没啥好说的,直接人工干预模型结果,一般是纠错 case ,需要一个一个积累。比较麻烦的是以后 context 模型调整,或者划分,需要人工重新做一遍。 不清楚楼主的目的和背景,我建议先找一下中文语料库,别的不说,新华词典啊就能解决你的“白术”问题。 抛开原神,这也是一款中药材。龙葵之类的,都应该是能识别出来的。 难点应该是如何识别是游戏角色白术,还是中药材白术。 |
8
ShikiSuen OP @chenY520 您不妨把「白术」全改成「白朮」再試試看?
我這邊測試結果: ["有", "個", "大夫", "叫", "白", "朮", "他", "有", "個", "徒弟", "叫", "七七"] 白朮還是被切了。 |
9
ShikiSuen OP 感觉五楼 @chenY520 的方法作用有限:唯一用到自订辞典的场合居然在 enumerateTags 的 loop 内部。此时的 word 断然不可能是「白朮」,只可能是「白」与「朮」。
得想办法在 enumerateTags 执行之前就将自订辞典给介入到里面去。 |
10
yuhu96 247 天前
jieba 自定义词库。不知道你 swift 里有没有这一套,你上网抓取领域相关的词汇(随便哪里,比如百度百科)做好词库,加载这个词库,分词的时候就不容易错分。
|
11
oxoxoxox 247 天前
ChatGPT 3.5 的答案:
有個大夫叫白朮,他有個徒弟叫七七。 拆分为单词: 有 / 個 / 大夫 / 叫 / 白朮 / , / 他 / 有 / 個 / 徒弟 / 叫 / 七七。 |
12
kingbill 247 天前
你得有个牛逼的词库
|
13
S1deny 247 天前
感觉得需要大量的语义词库进行训练才行啊 自定义的词库以哈工大词典和百度情感词典为例 好像那个腾讯的词向量模型涉及到了很多的词库
|
14
ShikiSuen OP |
15
iugo 236 天前
如果 NSLinguisticTagger 内置会更好, 即便没有, 也是有一些笨方法解决的.
```swift let customDictionary = ["白朮": 1] func tokenize(sentence: String) -> [String] { var tokens:[String] = [String]() let tagger = NSLinguisticTagger(tagSchemes: [.tokenType], options: 0) tagger.string = sentence let range = NSMakeRange(0, sentence.utf16.count) let options: NSLinguisticTagger.Options = [.omitWhitespace, .omitPunctuation] tagger.enumerateTags(in: range, unit: .word, scheme: .tokenType, options: options) { (tag, tokenRange, stop) in let word = (sentence as NSString).substring(with: tokenRange) // 找到上一个单词, 如果本单词加上一个单词和词库匹配, 则修改之前的词 let oldnew = (tokens.last ?? "") + word if customDictionary.keys.contains(oldnew) { tokens.removeLast() tokens.append(oldnew) } else { tokens.append(word) } } return tokens } ``` |
16
iugo 236 天前
因为是笨办法, 所以这里面有两个问题:
1. 如果多个组合怎么处理? 比如这个大夫姓 "叫" , 全名 "叫白朮". 因为代码只能将两个词进行匹配, 那么则匹配不上. 如果不是完全匹配而是匹配字符串前面的部分, 则可能出现误匹配. 所以当前的两个字完全匹配是一个简单做法. 2. 换用 Set. 不过这个 Set 做不了替换, 比如今后想将 白朮 替换为 白术 用字典就简单, 用集合就做不到. 总之, 这种分词办法比较笨, 因为并没有了解真实的语义. 最好还是服务端做, 用 python 这种库. |
17
BB9z 189 天前
训练自定义模型打标签,再结合标签结果分词?
https://developer.apple.com/documentation/naturallanguage/creating_a_word_tagger_model |