NaturalLanguage для Swift: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс
NaturalLanguage Swift: методы, примеры, установка | PythonLib

NaturalLanguage для Swift: полное руководство с примерами

Библиотека NaturalLanguage (фреймворк NaturalLanguage) — это мощный инструмент для обработки естественного языка (NLP), встроенный непосредственно в экосистему Apple. Она предоставляет разработчикам Swift доступ к передовым алгоритмам машинного обучения для анализа текста, не требуя внешних зависимостей или облачных сервисов. С её помощью можно выполнять такие задачи, как токенизация, распознавание языка, лемматизация, выделение именованных сущностей (NER), определение частей речи (POS) и многое другое.

Зачем нужна NaturalLanguage? В современной разработке приложений для iOS, macOS, watchOS и tvOS часто возникает необходимость «понимать» текст, введённый пользователем. Это может быть анализ отзывов, поиск ключевых слов, автоматический перевод, проверка орфографии или создание интеллектуальных чат-ботов. NaturalLanguage позволяет решать эти задачи на устройстве, что обеспечивает конфиденциальность данных (всё обрабатывается локально), высокую скорость работы и возможность функционирования в офлайн-режиме.

Фреймворк тесно интегрирован с другими технологиями Apple, такими как Core ML и Create ML. Это означает, что вы можете не только использовать готовые модели, но и обучать собственные на основе NaturalLanguage. Библиотека оптимизирована для работы на всех устройствах Apple, от iPhone до Mac, и поддерживает более 50 языков. В этой статье мы подробно разберём все ключевые возможности NaturalLanguage, начиная с установки и заканчивая сложными практическими примерами.

Важно: NaturalLanguage — это не сторонняя библиотека, а встроенный фреймворк Apple. Он доступен начиная с iOS 12, macOS 10.14, watchOS 5 и tvOS 12.

1. Установка

Поскольку NaturalLanguage является частью стандартных SDK Apple, его не нужно устанавливать через менеджеры пакетов (CocoaPods, Swift Package Manager, Carthage). Для использования достаточно импортировать фреймворк в ваш проект.

Точная команда (не требуется):

// Установка не требуется. Просто импортируйте фреймворк в файл Swift.
import NaturalLanguage

Настройка в Xcode:

  1. Откройте ваш проект в Xcode.
  2. В файле, где вы планируете использовать NLP, добавьте в самом верху: import NaturalLanguage.
  3. Убедитесь, что ваш проект настроен на iOS 12+ или macOS 10.14+ (проверьте в настройках проекта: Deployment Target).

Если вы используете Swift Package Manager для управления зависимостями, вам не нужно добавлять NaturalLanguage — он уже доступен. Для CocoaPods или Carthage также не требуется никаких дополнительных действий.

2. Быстрый старт — минимальный рабочий пример

Давайте начнём с простейшего примера: определения языка текста. Это одна из самых востребованных функций.

import NaturalLanguage

// Текст для анализа
let text = "Bonjour le monde! Как дела? Hello world!"

// Создаем распознаватель языка
let recognizer = NLLanguageRecognizer()

// Обрабатываем текст
recognizer.processString(text)

// Получаем основной язык
if let dominantLanguage = recognizer.dominantLanguage {
    print("Основной язык текста: \(dominantLanguage.rawValue)") // Например: "fr" (французский)
} else {
    print("Не удалось определить язык.")
}

// Получаем гипотезы по всем языкам
let languageHypotheses = recognizer.languageHypotheses(withMaximum: 3)
for (language, confidence) in languageHypotheses {
    print("Язык: \(language.rawValue), уверенность: \(confidence * 100)%")
}

Этот пример показывает, как за несколько строк кода определить, на каком языке написан текст, и даже получить список вероятных языков с процентом уверенности. Всё работает локально, без интернета.

3. Основные методы/функции/классы

Рассмотрим 8 ключевых компонентов NaturalLanguage, которые покроют 90% задач NLP.

3.1 NLLanguageRecognizer — распознавание языка

class NLLanguageRecognizer

Что делает: Определяет язык текста. Может возвращать как доминирующий язык, так и список гипотез с вероятностями.

import NaturalLanguage

let text = "This is an English sentence."
let recognizer = NLLanguageRecognizer()
recognizer.processString(text)

if let language = recognizer.dominantLanguage {
    print("Язык: \(language.rawValue)") // "en"
}

// Гипотезы
let hypotheses = recognizer.languageHypotheses(withMaximum: 2)
for (lang, prob) in hypotheses {
    print("\(lang.rawValue): \(prob)")
}

3.2 NLTokenizer — токенизация текста

class NLTokenizer

Что делает: Разбивает текст на токены (слова, предложения, абзацы, документы). Позволяет получить диапазоны (NSRange) каждого токена.

import NaturalLanguage

let text = "Hello, world! How are you? I am fine."
let tokenizer = NLTokenizer(unit: .word) // .word, .sentence, .paragraph, .document
tokenizer.string = text

tokenizer.enumerateTokens(in: text.startIndex..<text.endIndex) { tokenRange, _ in
    let token = text[tokenRange]
    print("Токен: '\(token)'")
    return true // продолжаем перечисление
}
// Вывод:
// Токен: 'Hello'
// Токен: 'world'
// Токен: 'How'
// ... и т.д.

3.3 NLTagger — тегирование (лемматизация, POS, NER)

class NLTagger

Что делает: Универсальный класс для лемматизации, определения частей речи (POS), распознавания именованных сущностей (NER) и других видов тегирования.

import NaturalLanguage

let text = "Steve Jobs founded Apple in Cupertino."
let tagger = NLTagger(tagSchemes: [.lemma, .nameType, .lexicalClass])
tagger.string = text

let range = text.startIndex..<text.endIndex
tagger.enumerateTags(in: range, unit: .word, scheme: .nameType, options: [.omitWhitespace]) { tag, tokenRange in
    if let tag = tag {
        let token = text[tokenRange]
        print("Сущность: '\(token)' -> \(tag.rawValue)")
    }
    return true
}
// Вывод: Сущность: 'Steve' -> PersonalName, 'Jobs' -> PersonalName, 'Apple' -> OrganizationName, 'Cupertino' -> PlaceName

3.4 NLModel — использование обученных моделей

class NLModel

Что делает: Позволяет загружать и использовать модели машинного обучения (созданные в Create ML или Core ML) для классификации текста или анализа тональности.

import NaturalLanguage

// Предположим, у нас есть обученная модель SentimentClassifier.mlmodel
guard let model = try? NLModel(mlModel: SentimentClassifier().model) else {
    fatalError("Не удалось загрузить модель")
}

let text = "This product is amazing! I love it."
let prediction = model.predictedLabel(for: text)
print("Тональность: \(prediction ?? "неизвестно")") // "positive"

// Получить вероятности для всех классов
let hypotheses = model.predictedLabelHypotheses(for: text, maximumCount: 3)
for (label, probability) in hypotheses {
    print("\(label): \(probability * 100)%")
}

3.5 NLSequence — работа с последовательностями

class NLSequence

Что делает: Представляет последовательность токенов (например, слов) для передачи в модели, работающие с последовательностями (RNN, LSTM). Используется редко в простых задачах, но важен для продвинутых сценариев.

import NaturalLanguage

let words = ["I", "love", "Swift"]
let sequence = NLSequence(words: words, types: [.word])

// Используется в паре с NLModel для предсказания последовательностей
// Например, для тегирования частей речи на уровне последовательности
let tagger = NLTagger(tagSchemes: [.lexicalClass])
tagger.string = words.joined(separator: " ")
let tags = tagger.tags(in: words.startIndex..<words.endIndex, unit: .word, scheme: .lexicalClass)
print(tags) // Массив опциональных тегов

3.6 NLTagScheme — схемы тегирования

struct NLTagScheme

Что делает: Определяет, какие типы тегов вы хотите получить от NLTagger. Встроенные схемы: .lemma, .lexicalClass (POS), .nameType (NER), .sentimentScore, .script и другие.

import NaturalLanguage

let text = "She sells seashells by the seashore."
let tagger = NLTagger(tagSchemes: [.lexicalClass, .lemma])
tagger.string = text

let range = text.startIndex..<text.endIndex
tagger.enumerateTags(in: range, unit: .word, scheme: .lexicalClass, options: [.omitWhitespace]) { tag, tokenRange in
    if let tag = tag {
        let token = text[tokenRange]
        print("\(token) -> \(tag.rawValue)") // 'She' -> Pronoun, 'sells' -> Verb, etc.
    }
    return true
}

3.7 NLTag — сами теги

struct NLTag

Что делает: Представляет собой конкретный тег, возвращаемый NLTagger. Например, .personalName, .organizationName, .placeName, .verb, .noun, .adjective и т.д.

import NaturalLanguage

let tagger = NLTagger(tagSchemes: [.nameType])
tagger.string = "Tim Cook works at Apple."

tagger.enumerateTags(in: tagger.string!.startIndex..<tagger.string!.endIndex,
                     unit: .word,
                     scheme: .nameType,
                     options: [.omitWhitespace]) { tag, range in
    if let tag = tag {
        print("Тег: \(tag.rawValue)") // PersonalName, OrganizationName
    }
    return true
}

3.8 NLTokenizer — продвинутая токенизация с единицами

func enumerateTokens(in: Range<String.Index>, using: (Range<String.Index>, NLTokenizer.Attributes) -> Bool)

Что делает: Позволяет перечислять токены с дополнительными атрибутами, такими как числовые значения, даты и т.д. (доступно для unit .word).

import NaturalLanguage

let text = "I bought 3 apples for $5.99 on 2023-10-05."
let tokenizer = NLTokenizer(unit: .word)
tokenizer.string = text

tokenizer.enumerateTokens(in: text.startIndex..<text.endIndex) { tokenRange, attributes in
    let token = text[tokenRange]
    if attributes.contains(.numeric) {
        print("Число: '\(token)'")
    } else if attributes.contains(.hasDate) {
        print("Дата: '\(token)'")
    } else {
        print("Слово: '\(token)'")
    }
    return true
}

Рекомендаций