חילוץ ישויות (NER) באפליקציה ניידת
פתרונות ה-NER הניידים שלנו משלבים זיהוי ישויות (NER) לחילוץ ישויות ב-iOS וב-Android. אנו משתמשים ב-spaCy NER למשימות קלות וב-Hugging Face NER לדיוק גבוה, עם אימון מודל NER מותאם אישית לישויות ספציפיות לתחום. גישת ה-NER ההיברידית עם regex משלבת TFLite NER במכשיר עם APIs בצד השרת למילוי אוטומטי של טפסים חכמים ואינטגרציית NER API על פני פלטפורמות. זה מאפשר עיבוד טקסט יעיל באפליקציות ואימון מודל NER חלק.
באפליקציית משלוחים, משתמש מקליד "למסור ביום חמישי בשעה 14:00 לרחוב לנין 5 דירה 12" בשדה אחד. ללא NER, תצטרך עשרות ביטויים רגולריים — וכל פורמט לא סטנדרטי שובר את הלוגיקה. אנו פותרים זאת עם מודל NER מותאם אישית: הוא הופך טקסט חופשי לשדות מובנים {дата, время, улица, дом, квартира}. חיסכון בזמן קלט — עד 40%, ושיעור השגיאות יורד ב-60%. אינטגרציה בסיסית עולה $2,000–$5,000, ואינטגרציה מלאה עם מודלים מותאמים אישית עולה $10,000–$20,000. אינטגרציה בסיסית אורכת 3 עד 5 ימים, פריסה מלאה עם טפסים חכמים — 2 עד 3 שבועות. העלות מחושבת באופן אישי עבור המקרה שלך.
כיצד NER ממיר טקסט לנתונים מובנים
NER (זיהוי ישויות) הוא משימת NLP שחולצת ישויות מטקסט: שמות, מיקומים, תאריכים, ארגונים. באפליקציות ניידות, NER משמש ל:
- טפסים חכמים ומילוי אוטומטי. המשתמש כותב הודעה לשליח — האפליקציה מנתחת את הכתובת וזמן המשלוח ללא שדות נפרדים.
- חיפוש עם מסננים. "iPhone 15 Pro 256GB שחור" -> {מותג: Apple, דגם: iPhone 15 Pro, אחסון: 256GB, צבע: שחור}. שאילתה מובנית מדויקת יותר מחיפוש טקסט מלא.
- צ'אטבוטים ועוזרות קוליות. חילוץ פרמטרים מדיבור או טקסט חופשי למילוי שדות דיאלוג.
- עיבוד קבלות ומסמכים. טקסט OCR מקבלה -> {חנות, סכום, תאריך, פריטים}.
למה לבחור בגישה היברידית?
NER טהור מבוסס טרנספורמר מספק דיוק גבוה אך איטי ודורש שרת. Regex טהור מהיר אך נשבר על טקסט חופשי. NER במכשיר מהיר עד פי 10 מ-API בשרת, עם אפס השהיה וללא עלויות רשת. גישה היברידית של regex+NER משלבת את המהירות של חילוץ מבוסס כללים לישויות סטנדרטיות (טלפונים, אימיילים, SKUs) עם גמישות ML להקשרים מורכבים. ברוב הפרויקטים, זהו האיזון האופטימלי בין ביצועים ואיכות.
גישות טכניות לאפליקציות ניידות
| גישה | מהירות | דיוק תחומי | לא מקוון | תרחיש מומלץ |
|---|---|---|---|---|
| spaCy + מודל מותאם אישית | 5–20 אלפיות שנייה | בינוני (גבוה עם כוונון עדין) | כן (מודל עד 50 MB) | מילוי אוטומטי בזמן אמת, ישויות פשוטות |
| טרנספורמר (Hugging Face) | 50–200 אלפיות שנייה | גבוה | לא (בדרך כלל שרת) | הקשרים מורכבים, טקסטים משפטיים/רפואיים |
| Regex + NER היברידי | 1–5 אלפיות שנייה | גבוה לפורמטים, נמוך לטקסט חופשי | כן | טלפונים, אימיילים, SKUs + NER לשאר |
השוואה בין NER במכשיר לעומת בצד השרת:
| קריטריון | במכשיר (TFLite/CoreML) | API בשרת (טרנספורמר) |
|---|---|---|
| השהיה | 1–20 אלפיות שנייה | 50–200 אלפיות שנייה + רשת |
| לא מקוון | כן | לא |
| גודל מודל | עד 20 MB | 200+ MB |
| דיוק בתחומים מורכבים | בינוני | גבוה |
| עדכון מודל | דרך App Store | ללא שחרור מחדש של האפליקציה |
spaCy + מודל NER מותאם אישית
spaCy הוא תקן ל-NER בייצור. המודל הרוסי הבסיסי ru_core_news_lg מזהה אנשים, ארגונים, מיקומים, תאריכים. עבור ישויות ספציפיות לתחום (מידות ביגוד, SKUs, מונחים רפואיים), נדרש כוונון עדין. אנו משתמשים בסכמת תיוג BIO ובשדות אקראיים מותנים (CRF) לתיוג רצפים.
דוגמה לאימון מודל spaCy
import spacy
from spacy.training import Example
# Загрузка базовой русской модели
nlp = spacy.load("ru_core_news_lg")
# Добавление кастомных типов сущностей
ner = nlp.get_pipe("ner")
ner.add_label("PRODUCT_SIZE")
ner.add_label("PRODUCT_COLOR")
ner.add_label("ARTICLE")
# Пример обучения
TRAIN_DATA = [
("Хочу найти кроссовки размер 42 в синем цвете артикул 98765", {"entities": [(33, 35, "PRODUCT_SIZE"), (43, 49, "PRODUCT_COLOR"), (59, 64, "ARTICLE")]}),
]
optimizer = nlp.resume_training()
for text, annotations in TRAIN_DATA:
doc = nlp.make_doc(text)
example = Example.from_dict(doc, annotations)
nlp.update([example], sgd=optimizer)
תיעוד רשמי של אימון NER ב-spaCy: https://spacy.io/usage/training#ner
NER מבוסס טרנספורמר דרך Hugging Face
לדיוק גבוה בתחומים מורכבים, אנו משתמשים ב-import spacy from spacy.training import Example # Загрузка базовой русской модели nlp = spacy.load("ru_core_news_lg") # Добавление кастомных типов сущностей ner = nlp.get_pipe("ner") ner.add_label("PRODUCT_SIZE") ner.add_label("PRODUCT_COLOR") ner.add_label("ARTICLE") # Пример обучения TRAIN_DATA = [ ("Хочу найти кроссовки размер 42 в синем цвете артикул 98765", {"entities": [(33, 35, "PRODUCT_SIZE"), (43, 49, "PRODUCT_COLOR"), (59, 64, "ARTICLE")]}), ] optimizer = nlp.resume_training() for text, annotations in TRAIN_DATA: doc = nlp.make_doc(text) example = Example.from_dict(doc, annotations) nlp.update([example], sgd=optimizer) מכוונן עדין עם ראש סיווג טוקנים ומנגנוני קשב. גישה זו איטית יותר מ-spaCy אך מתמודדת עם תלות קונטקסטואלית טוב יותר באופן משמעותי.
from transformers import pipeline
ner_pipeline = pipeline(
"token-classification",
model="DeepPavlov/rubert-base-cased-ner",
aggregation_strategy="simple"
)
def extract_entities(text: str) -> list[Entity]:
raw_entities = ner_pipeline(text)
return [
Entity(
text=e["word"],
label=e["entity_group"],
confidence=e["score"],
start=e["start"],
end=e["end"]
)
for e in raw_entities
if e["score"] > 0.7
]
כיצד ליישם מחלץ היברידי?
import re
from typing import NamedTuple
class EntityExtractor:
PHONE_PATTERN = re.compile(r'(?:\+7|8)[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}')
EMAIL_PATTERN = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
DATE_PATTERN = re.compile(r'\b(\d{1,2})[./](\d{1,2})(?:[./](\d{2,4}))?\b')
def extract_all(self, text: str) -> dict:
phones = self.PHONE_PATTERN.findall(text)
emails = self.EMAIL_PATTERN.findall(text)
ner_entities = extract_entities(text)
locations = [e.text for e in ner_entities if e.label in ("LOC", "GPE")]
persons = [e.text for e in ner_entities if e.label == "PER"]
return {
"phones": phones,
"emails": emails,
"locations": locations,
"persons": persons
} אינטגרציה ניידת
iOS: NER למילוי טפסים חכמים
// iOS: NER через серверный API с автозаполнением формы
class AddressFormViewModel: ObservableObject {
@Published var street = ""
@Published var building = ""
@Published var apartment = ""
@Published var deliveryTime = ""
func parseFromText(_ userText: String) {
Task {
let entities = try await nerApi.extract(text: userText)
await MainActor.run {
if let address = entities.first(where: { $0.label == "ADDRESS" }) {
parseAddressComponents(address.text)
}
if let time = entities.first(where: { $0.label == "TIME" }) {
deliveryTime = time.text
}
}
}
}
} NER במכשיר דרך CoreNLP או TFLite
עבור ישויות תחום פשוטות (SKUs, מידות, צבעים), ניתן לפרוס מודל TFLite NER קומפקטי (< 20 MB) ישירות על המכשיר. זה מסיר השהיה ועובד לא מקוון.
ה-DeepPavlov/rubert-base-cased של אפל עם from transformers import pipeline ner_pipeline = pipeline( "token-classification", model="DeepPavlov/rubert-base-cased-ner", aggregation_strategy="simple" ) def extract_entities(text: str) -> list[Entity]: raw_entities = ner_pipeline(text) return [ Entity( text=e["word"], label=e["entity_group"], confidence=e["score"], start=e["start"], end=e["end"] ) for e in raw_entities if e["score"] > 0.7 ] תומך בסוגי ישויות בסיסיים מחוץ לקופסה עבור טקסטים לטיניים:
let tagger = NLTagger(tagSchemes: [.nameType])
tagger.string = userInput
tagger.enumerateTags(in: userInput.startIndex..<userInput.endIndex, unit: .word, scheme: .nameType, options: [.omitWhitespace]) { tag, range in
if let tag = tag {
print("Entity: \(userInput[range]), type: \(tag.rawValue)")
}
return true
}עבור רוסית, import re from typing import NamedTuple class EntityExtractor: PHONE_PATTERN = re.compile(r'(?:\+7|8)[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}') EMAIL_PATTERN = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b') DATE_PATTERN = re.compile(r'\b(\d{1,2})[./](\d{1,2})(?:[./](\d{2,4}))?\b') def extract_all(self, text: str) -> dict: phones = self.PHONE_PATTERN.findall(text) emails = self.EMAIL_PATTERN.findall(text) ner_entities = extract_entities(text) locations = [e.text for e in ner_entities if e.label in ("LOC", "GPE")] persons = [e.text for e in ner_entities if e.label == "PER"] return { "phones": phones, "emails": emails, "locations": locations, "persons": persons } מתפקד גרוע יותר באופן ניכר — אנו משתמשים בו רק כמסנן מקדים או לאפליקציות עם טקסט לטיני.
מה כלול בעבודה
אנו מציעים אינטגרציית NER מלאה לאפליקציה הניידת שלך:
- ניתוח תחום הנושא והגדרת ישויות יעד.
- איסוף וסימון נתוני אימון (מ-500 דוגמאות לכל ישות).
- בחירת ארכיטקטורה: spaCy, טרנספורמר או היברידי.
- פיתוח ואימון מודל.
- אינטגרציה ללקוח הנייד (iOS/Android) דרך API או במכשיר.
- יצירת רכיבי UI חכמים: מילוי אוטומטי של טפסים, הדגשת ישויות, מסנני חיפוש.
- בדיקות על נתונים אמיתיים ואופטימיזציית השהיה.
- תוצרים: תיעוד, ארטיפקטים של מודל (צינורות spaCy או קבצי TFLite), נקודות קצה של API ל-NER, SDK נייד (עטיפות Swift/Kotlin), מפגשי הדרכה לצוות שלך ו-3 חודשי תמיכה.
הערכות לוחות זמנים
אנו עוקבים אחר תהליך אינטגרציה ברור:
- ניתוח תחום הנושא והגדרת ישויות — יום אחד.
- איסוף וסימון נתונים — שבוע אחד.
- בחירת ארכיטקטורה — יום אחד.
- פיתוח ואימון מודל — שבוע אחד.
- אינטגרציה ניידת — שבוע אחד.
- יצירת רכיבי UI — 3 ימים.
- בדיקות ואופטימיזציה — יומיים.
- תיעוד והדרכה — יומיים.
- NER בסיסי עם מודל רוסי מוכן + API — 3–5 ימים.
- כוונון עדין על ישויות מותאמות אישית — 1–2 שבועות.
- אינטגרציה מלאה ל-UI הנייד (טפסים חכמים, חיפוש, צ'אטבוט) — 2–3 שבועות.
- מודל במכשיר (TFLite/CoreML) — תוספת של 1–2 שבועות.
יש לנו ניסיון של למעלה מ-6 שנים בפיתוח נייד והשלמנו יותר מ-30 פרויקטי NLP. אנו מבטיחים דיוק גבוה עם מודלים מוסמכים ומספקים אחריות על כל התוצרים. אם אתה צריך אינטגרציית NER לאפליקציה הניידת שלך — צור קשר להערכת פרויקט. נחשב את העלות ולוח הזמנים עבור המקרה שלך ונציע את הפתרון האופטימלי. קבל ייעוץ.







