Swift Natural Language и CoreML: как улучшить NLTagger для чтения держателя карты - PullRequest
1 голос
/ 02 февраля 2020

Я использую фреймворк Natural Language, чтобы найти свое имя на кредитной карте. Сначала я читаю тексты кредитных карт, используя Vision Framework. Тогда я соединяю это.

Итак, у меня есть текст, который содержит формат, подобный следующему:

"Citi 6011 1111 1111 1117 07/25 ELON MUSK Discover Debit"

Я устал просто находить .personalName NLTags в такой строке, но он не работает идеально.

let tagger = NLTagger(tagSchemes: [.nameType])
    tagger.string = text
    tagger.setLanguage(.english, range: range)

    var fullNames = [String]()

    // 1) personalName
    let options : NLTagger.Options = [.omitPunctuation, .omitWhitespace, .omitOther, .joinNames]
    let foundTags = tagger.tags(in: range, unit: .word, scheme: .nameType, options: options)

    foundTags.forEach { (tag, tokenRange) in
        if tag == .personalName {
            let name = text[tokenRange]
            fullNames.append(String(name))
        }
    }

Поэтому я пытаюсь использовать CreateML на игровой площадке macOS для создания модели CoreML, которая будет использоваться для тегов пользовательских тегов CARDHOLDER в такой строке.

Сколько примеров помечено данных, необходимых для обучения такой модели для использования?

Теперь у меня есть такой относительно простой случай

[
    {
        "tokens": ["Inteligo", "4242 4242 4242 4242", "09/21", "JOHN SMITH", "VISA", "Debit"],
        "labels": ["ORG", "NONE", "NONE", "CARDHOLDER", "ORG", "NONE"]
    },
    {
        "tokens": ["mBank", "4000 0566 5566 5556", "10/23", "STEVE JOBS", "VISA", "Debit"],
        "labels": ["ORG", "NONE", "NONE", "CARDHOLDER", "ORG", "NONE"]
    },
    {
        "tokens": ["ING", "5555 5555 5555 4444", "03/22", "EMMA WATSON", "mastercard", "Debit"],
        "labels": ["ORG", "NONE", "NONE", "CARDHOLDER", "ORG", "NONE"]
    },
    {
        "tokens": ["Bank of America", "3782 822463 10005", "05/24", "JULIA ROBERTS", "American Express", "Debit"],
        "labels": ["ORG", "NONE", "NONE", "CARDHOLDER", "ORG", "NONE"]
    },
    {
        "tokens": ["Citi", "6011 1111 1111 1117", "07/25", "ELON MUSK", "Discover", "Debit"],
        "labels": ["ORG", "NONE", "NONE", "CARDHOLDER", "ORG", "NONE"]
    }
]

Затем я создаю модель CoreML из этой

import Foundation
import CreateML

let trainingData = try MLDataTable(contentsOf:
    Bundle.main.url(forResource: "data", withExtension: "json")!)

let model = try MLWordTagger(trainingData: trainingData, tokenColumn: "tokens", labelColumn: "labels")

try model.write(to: URL(fileURLWithPath: "#path/to/Desktop/creditcardtagger.mlmodel"))

Затем я использую ее:

let tagger = CreditCardTagger.shared
        tagger.string = text
        tagger.setLanguage(.english, range: range)
tagger.enumerateTags(in: range, unit: .word, scheme: CreditCardTagger.Scheme, options: options) { (tag, tokenRange) -> Bool in

            if tag == CreditCardTagger.cardHolderTag {
                let cardHolder = text[tokenRange]
                print("CARD HOLDER: \(cardHolder)")
            }
            return true
        }

Но я думаю, что данных, которые я использую для обучения, недостаточно. Знаете ли вы, сколько таких записей данных необходимо для покрытия большинства случаев кредитных карт?

...