Як я можу правильно поставити слово перед префіксом "a" та "an"?


93

У мене є програма .NET, де за іменником я хочу, щоб він правильно додавав це слово перед "a" або "an". Як би я це зробив?

Перш ніж подумати, що відповідь полягає в тому, щоб просто перевірити, чи перша буква є голосною, розгляньте такі фрази, як:

  • чесна помилка
  • вживаний автомобіль

4
Ви також повинні враховувати скорочення, які також можуть призвести до деяких плутанин щодо "а" або "ан", наприклад, "НХЛ", що також призводить до того, що звук букви починається з голосної, хоча ні, якщо абревіатура може бути вимовлена ​​як таке слово як "пристрій NAS" або "подія NASCAR"
JB King

5
Також майте на увазі, що вживання a або an може залежати від конкретної вимови у різноманітності англійської мови, якою говорять. Британська та американська вимова herb - один із таких прикладів.
Ерік,

12
@Eric: Дійсно, мій улюблений приклад цього (ботанік теж) - "SQL". Хтось вимовляє букви "SQL", хтось вимовляє це як слово "продовження". Кожен отримує різне "a" або "an". наприклад, це "висловлювання продовження", вірші "це вираз SQL"
Binary Worrier

Ще складніше, що думки навіть розходяться в межах одного діалекту англійської мови! Так, наприклад, офіційна (британська) англійська говорить, що "готель" - це правильна структура, але більшість людей користується "готелем" у щоденній розмові. Якщо ви напишете його, це було б дуже корисно для нас усіх!
h4xxr

Ах ... "претендент Н". Я живо пам’ятаю свою першу зустріч із нею. Книга соціальних досліджень другого класу під назвою "Історичне товариство", книга про колоніальний Вільямсбург.
Боб Кауфман,

Відповіді:


137
  1. Завантажте Вікіпедію
  2. Розпакуйте його та напишіть програму швидкого фільтрування, яка випльовує лише текст статті (завантаження, як правило, виконується у форматі XML, разом із метаданими, що не належать до статті).
  3. Знайдіть усі екземпляри a (n) .... і зробіть індекс для наступного слова та всіх його префіксів (для цього ви можете використовувати просту суфікстрію). Це має бути чутливим до регістру, і вам знадобиться максимальна довжина слова - 15 літер?
  4. (необов’язково) Відкиньте всі ті префікси, які трапляються менше 5 разів або де "a" проти "an" досягає більшості менше 2/3 (або деякі інші обмеження - налаштуйте тут). Переважно зберігайте порожній префікс, щоб уникнути кутових випадків.
  5. Ви можете оптимізувати свою базу даних префіксів, відкинувши всі ті префікси, батьки яких мають однакову анотацію "a" або "an".
  6. Визначаючи, чи використовувати "А" чи "АН", знайдіть найдовший відповідний префікс і дотримуйтесь його вказівок. Якщо ви не відкинули порожній префікс на кроці 4, тоді завжди знайдеться відповідний префікс (а саме порожній префікс), інакше вам може знадобитися особливий випадок для абсолютно невідповідного рядка (такий введення має бути дуже рідкісним) .

Напевно, ви не можете стати набагато кращими за це - і це, безсумнівно, переможе більшість систем, заснованих на правилах.

Редагувати: Я реалізував це в JS / C # . Ви можете спробувати його у своєму браузері або завантажити невелику багаторазову реалізацію JavaScript, яку він використовує. Реалізація .NET - це пакет AvsAnна nuget . Реалізації є тривіальними, тому при необхідності має бути легко перенести на будь-яку іншу мову.

Виявляється, "правила" набагато складніші, ніж я думав:

  • це непередбачений результат , але це одностайність
  • це чесне рішення , але жимолость чагарник
  • Символи: Це 0800 номерів, або ∞ орегано.
  • Скорочення: Це вчений NASA, але аналітик АНБ; автомобіль FIAT , але політика FAA.

... що просто підкреслює, що систему, засновану на правилах, буде складно будувати!


І якщо у цьому виведенні відсутній іменник, ви, безумовно, можете повернутися до простого механізму правил.
Джон Фішер

26
З огляду на те, що завантаження Вікіпедії декомпресується до (на даний момент) 2,8 Терабайт, було б чудово, якби хтось, хто використовує цей метод, публікував отримані дані публічно, тому процес не потрібно багато повторювати.
Натан Лонг

10
Ця відповідь була не зовсім серйозною, але я зробив щось подібне, і файл .xml wikipedia із необробленим wikimarkup розміром близько 40 ГБ (найновіший завжди трохи більший), а не 2,8 ТБ - все в одному файлі - не завантажуйте розширену .html версію або будь-які зображення, можливо, це версія, яка становить 2.8 ТБ? У будь-якому випадку, насправді цілком здійсненний синтаксичний аналіз, якщо ви не вибагливі до розмітки.
Імон Нербонн

1
Це один з найбільших легко доступних, сучасних наборів даних на природній мові, про які я міг згадати. Однак, будь-яке додаткове джерело даних теж, звичайно, добре - зрештою, алгоритм не залежить від wikipedia. Ви можете спробувати онлайн-реалізацію на home.nerbonne.org/A-vs-An або в моєму щоденнику
Eamon Nerbonne

1
Це рішення мене не вразило. Я чесно вважав, що це буде набагато простіше, ніж завантаження Вікіпедії в цілому. Молодці, сер. +1
Келан Крумме

15

Вам потрібно скористатися списком винятків. Я не думаю, що всі винятки чітко визначені, оскільки це іноді залежить від акценту людини, яка вимовляє слово.

Один дурний спосіб - запитати у Google дві можливості (за допомогою одного з пошукових API) і використовувати найпопулярніші:

Або:

Тому "європа" та "чесний" є правильними версіями.


6
Це насправді дозволено використовувати чи це вимагає заборони? Регулярне таке використання, безумовно, не відповідає IIRC.
Імон Нербонн

1
@Eamon: Цікавий момент. Що робити, якщо додаток веде запис усіх слів, які раніше гуглив, тож йому потрібно гуглити лише один раз для кожного нового слова, з яким він стикається? Чи все одно це буде сумнівним використанням Google?
gnovice

2
Окрім очевидних технічних труднощів (використання результатів пошукової машини в автоматизованому режимі, як це не дозволяється і буде заблоковано досить швидко), це не вирішує проблему правильним чином - в гіршому випадку це повторює поширене неправильне використання синтаксис.
Guss

6
У гіршому? Існує досить вагомий аргумент, що дублювання "типового зловживання" - це саме те, до чого повинна прагнути система природної мови. Дивіться есе Девіда Фостера Уоллеса "Влада та американське використання" в " Розгляньмо омара" . Є кращі корпуси, ніж Google, але це вже інша проблема.
Роберт Росней,

2
"готель" і "героїня" здаються мені правильними. Думаю, ви виходите з точки зору злегка кокні. Різні наголоси означають, що на деякі з цих слів немає правильної відповіді.
rjmunro

15

Якщо ви могли знайти джерело написання слів для вимови слів, наприклад:

"honest":"on-ist"
"horrible":"hawr-uh-buhl, hor-"

Ви можете базувати своє рішення на першому символі написаного рядка вимови. Для підвищення продуктивності, можливо, ви могли б використовувати такий пошук для попереднього створення наборів винятків і замість цього використовувати ці менші набори пошуку під час виконання.

Відредаговано, щоб додати:

!!! - Я думаю, ви можете використати це для створення своїх винятків: http://www.speech.cs.cmu.edu/cgi-bin/cmudict

Звичайно, не все буде в словнику - це означає, що не всі можливі винятки потраплять у ваші набори винятків - але в такому випадку ви можете просто встановити значення для голосних / a для приголосних або використовувати якусь іншу евристику з кращими шансами.

(Переглядаючи словник КМУ, я був радий побачити, що він включає власні іменники для країн та деяких інших місць - тому він подасть приклади, такі як "українець", "стаття USA Today", "картина, натхненна Уралом".)

Ще раз відредагуйте, щоб додати: Словник CMU не містить загальних скорочень, і вам доведеться турбуватися про ті, що починаються з s, f, l, m, n, u та x. Але там є безліч списків скорочень, як у Вікіпедії, які ви можете використовувати для додавання до винятків.


2
Не можу втриматися, але hawr-uh-buhlзавжди мене смішить.
IllidanS4 хоче повернення Моніки

9

Вам доведеться впровадити вручну і додати винятки, які ви хочете, наприклад, якщо перша буква - H, а за нею - O, як чесний, година ... а також протилежні, такі як Європа, університет, що використовується ...


1
так справжня людина. Здається, я помилився в цьому. У ньому взагалі немає правила
Ахмад Фарід

8

Оскільки "a" та "an" визначаються фонетичними правилами, а не орфографічними умовами, я, мабуть, зробив би це так:

  1. Якщо перша буква слова приголосна -> 'a'
  2. Якщо перша буква слова - голосна -> 'an'
  3. Зберігайте список винятків (серце, рентген, будинок), як говорить Рюмнро .

5

Вам потрібно поглянути на граматичні правила для невизначених статей (в англійській граматиці є лише дві невизначені статті - "a" та "an). Ви можете не погодитися, що це звучить правильно, але правила граматики англійської мови дуже чіткі :

"Слова a і a - це невизначені артиклі. Ми використовуємо невизначений артикль перед словами, що починаються на голосний звук (a, e, i, o, u), а невизначений артикль - перед словами, що починаються на приголосний звук (усі інші листи). "

Зверніть увагу, що це означає голосний звук , а не голосну букву . Наприклад, слова, що починаються з мовчазного "h", такі як "честь" або "спадкоємець", розглядаються як голосні, а потім продовжуються з "an" - наприклад, "Це честь зустріти вас". Слова, що починаються на приголосний звук, мають префікс до - і саме тому ви говорите "вживаний автомобіль", а не "вживаний автомобіль", - оскільки "вживаний" має звук "йос", а не звук "ух".

Отже, як програміст, цих правил слід дотримуватися. Потрібно лише розробити спосіб визначення того, з якого звуку починається слово, а не з якої букви. Я бачив такі приклади, як цей у PHP Джеймі Сіровича:

function aOrAn($next_word) 
{ 
    $_an = array('hour', 'honest', 'heir', 'heirloom'); 
    $_a = array('use', 'useless', 'user'); 
    $_vowels = array('a','e','i','o','u'); 

    $_endings = array('ly', 'ness', 'less', 'lessly', 'ing', 'ally', 'ially'); 
    $_endings_regex = implode('|', $_endings); 

    $tmp = preg_match('#(.*?)(-| |$)#', $next_word, $captures); 
    $the_word = trim($captures[1]); 
    //$the_word = Format::trimString(Utils::pregGet('#(.*?)(-| |$)#', $next_word, 1)); 

    $_an_regex = implode('|', $_an); 
    if (preg_match("#($_an_regex)($_endings_regex)#i", $the_word)) { 
        return 'an'; 
    } 

    $_a_regex = implode('|', $_a); 
    if (preg_match("#($_a_regex)($_endings_regex)#i", $the_word)) { 
        return 'a'; 
    } 

    if (in_array(strtolower($the_word{0}), $_vowels)) { 
        return 'an';     
    } 

    return 'a'; 
}

Напевно, найпростіше створити правило, а потім створити список винятків і використовувати його. Не думаю, що їх буде стільки.


4

Чоловіче, я усвідомлюю, що це, мабуть, аргументований аргумент, але я думаю, що це можна вирішити простіше, ніж використання спеціальних граматичних правил з Вікіпедії, які б у кращому випадку вивели граматику просторіччя.

Здається, найкращим рішенням є використання a або тригера на основі фонеми відповідності наступного слова, з певними фонемами, завжди пов'язаними з "an", а решта належить "a".

Університет Карнегі-Меллона має чудовий онлайн-інструмент для такого роду перевірок - http://www.speech.cs.cmu.edu/cgi-bin/cmudict - і на 125 тис. Слів із відповідними 39 фонемами. Підключення слова забезпечує весь фонематичний набір, з яких важливим є лише перший.

Якщо слово не відображається у словнику, наприклад, "NSA", і воно все пишеться з великої літери, тоді система може припустити, що це слово є абревіатурою і за першою літерою визначити, яку невизначену статтю використовувати на основі того самого оригінального набору правил.


1
Що стосується економії ресурсів, це найкраща відповідь, і я не розумію, чому це могло б бути гіршим, ніж запропоновані набагато більш інтенсивні методи.
Проект

3

@ Натан Лонг: Завантаження вікіпедії насправді не є поганою ідеєю. Всі зображення, відео та інші засоби масової інформації не потрібні.

Я написав (дерьмову) програму на php та javascript (!) Для читання всієї шведської вікіпедії (або принаймні всіх статей, до яких можна було дістатись із статті про математику, що стало початком для мого павука).

Я зібрав усі слова та внутрішні посилання у базі даних, а також відстежував частоту кожного слова. Тепер я використовую це як базу даних слів для різних завдань: * Пошук усіх слів, які можна створити із заданого набору літер (включаючи підстановочні символи) * Створений простий файл синтаксису для шведської (усі слова, що не містяться в базі даних, вважаються неправильними).

О, і завантаження всієї вікі зайняло близько одного тижня, використовуючи ноутбук, який працював більшу частину часу, із 10 Мбіт підключення.

Коли закінчите, реєструйте всі випадки, що не відповідають англійській мові, і перевірте, чи є деякі з них помилковими. Піди виправляй їх і повертай щось спільноті.


2

Зверніть увагу, що між американським та британським діалектами існують відмінності, на що вказувала «Граматична дівчина» у своєму епізоді « А проти Ан» .

Одне з ускладнень полягає в тому, що слова вимовляються по-різному у британській та американській англійській мовах. Наприклад, слово для певного виду рослин вимовляється в американській англійській мові “erb”, а в британській - “herb”. У тих рідкісних випадках, коли це проблема, використовуйте форму, яка очікується у вашій країні або більшості читачів.



2

Я переніс функцію з Python (спочатку із пакету CPAN Lingua-EN-Inflect), яка правильно визначає голосні звуки в C #, і опублікував її як відповідь на запитання . . Ви можете побачити фрагмент коду тут .


1

Чи можете ви отримати англійський словник, який зберігає слова, написані нашим звичайним алфавітом, та Міжнародний фенетичний алфавіт ?

Потім використовуйте фонетику, щоб з’ясувати початковий звук слова, а отже, чи доречно “a” чи “an”?

Не впевнений, чи це насправді було б простіше, ніж (або настільки ж цікаво, як) статистичний підхід Вікіпедії.


0

Я б використовував алгоритм, заснований на правилах, щоб охопити якомога більше, а потім скористався списком винятків. Якщо ви хочете пофантазувати, ви можете спробувати визначити деякі нові "правила" зі списку винятків.


0

Я просто схожий на набір евристики. Це має бути дещо складніше і відповісти на деякі речі, на які я так і не отримав належної відповіді, наприклад, як ви ставитеся до скорочень ("RPM" або "RPM"? Я завжди думав, що останнє має більше сенсу).

Швидкий пошук дав лінгвістичні бібліотеки, які розповідають про те, як обробляти англійський префікс однини, але ви, мабуть, можете щось знайти, якщо достатньо скопати dip. А якщо ні - ви завжди можете написати власну бібліотеку флексій і здобути світову славу :-).


Скорочення, такі як RPM, не є проблемою. Як ти кажеш, з ними можна поводитися в будь-якому випадку. Отже, рішення очевидне: ігноруйте їх.
Ендрю Дж. Брем,

Я б не погодився, оскільки це спричиняє суперечливі префікси. Просто ігнорування цього призведе до "RPM" та "UGC", що явно неправильно.
Guss

0

Я не думаю, що ви можете просто заповнити деякі речі котла, такі як 'a / an', як одне крокове покриття. В іншому випадку ви отримаєте помилки припущення, як усі слова з "h", продовжуючи "o" get "an" замість "a" типу "home" - (a home?). В основному, ви в кінцевому підсумку врахуєте логіку англійської мови або випадково знайдете рідкісні випадки, які змусять вас виглядати нерозумно.


0

Перевірте, чи починається слово з голосного чи приголосного. "U" - це, як правило, приголосна та голосна ("yu"), отже, для ваших цілей належить до групи приголосних.

Буква "h" позначає gettal stop (приголосний) французькою та французькими словами, що вживаються в англійській мові. Ви можете скласти їх список (насправді, включаючи "честь", "честь" і "година" може бути достатньо) і зарахувати їх до початкових з голосних (оскільки англійська не визнає глотальної зупинки).

Також зараховуйте "eu" як приголосну тощо.

Це не надто складно.


0

вибір слова a або a залежить від способу вимови слова. Дивлячись на слово, ви не можете визначити його правильну вимову, наприклад, жаргон або абревіатуру тощо. Одним із способів може бути наявність словника з підтримкою фонем та використання інформації про фонему, пов’язану зі словом, для визначення, чи є “a "або" an "слід використовувати.


0

Не можу бути впевненим, що в ній є відповідна інформація для розмежування "a" та "an", але база даних WordNet в Принстоні існує саме для цілей подібного роду завдань, тому я думаю, що цілком ймовірно, що дані є там . Він містить кілька десятків тисяч слів і сотні тисяч взаємозв’язків між цими словами (IIRC; я не можу знайти поточну статистику на сайті). Погляньте. Його можна безкоштовно завантажити.


0

Як? Як щодо того, коли? Отримайте іменник із артиклем у додатку. Попросіть це у конкретній формі.

Запитайте іменник із артиклем. Багато кодової бази MUD зберігають елементи як інформацію, що складається з:

  • одне або кілька ключових слів
  • коротка форма
  • довга форма

Формою ключового слова може бути "короткий меч іржавий". Короткою формою буде "меч". Довгою формою буде "іржавий короткий меч".

Ви пишете веб-службу "проти"? Зробіть крок назад і подивіться, чи зможете ви атакувати цей витік далі за течією. Ви можете побудувати дамбу, але якщо ви не зупините її текти, вона врешті-решт розллється.

Визначте, наскільки це критично важливо, і, як припускають інші, перейдіть до "швидкого, але грубого", або "дорогого, але міцного".


0

Правило дуже просте. Якщо наступне слово починається з голосного звуку, тоді використовуйте 'an', якщо воно починається зі приголосного, використовуйте 'a'. Складність полягає в тому, що наша шкільна класифікація голосних і приголосних не працює. "H" у "честі" - голосна, а "h" у "лікарні" - приголосна.

Навіть гірше, деякі слова, такі як "чесний", починаються з голосної або приголосної звуку залежно від того, хто їх вимовляє. Навіть гірше, деякі слова змінюються залежно від слів навколо них для деяких мовців.

Проблема обмежена лише тим, скільки часу та зусиль ви хочете докласти до неї. Ви можете написати щось за пару, використовуючи "aeiou" як голосні за пару хвилин, або можете витратити місяці, проводячи лінгвістичний аналіз своєї цільової аудиторії. Між ними є величезна кількість евристик, які будуть правильними для одних мовців, а неправильними для інших - але оскільки різні мовці мають різні визначення для одного і того ж слова, просто неможливо постійно мати рацію, як би ти не робив це.


0

Ідеальним підходом було б знайти десь в Інтернеті, яке може дати вам відповіді, динамічно запитувати їх та кешувати відповіді. Для початківців можна продемонструвати систему кількома сотнями слів.

(Я не знаю такого джерела в Інтернеті, але я б не здивувався, якщо воно є).


0

Отже, розумне рішення можливе без завантаження всього Інтернету. Ось що я зробив:

Я згадав , що Google опублікував свої вихідні дані для частот Google Книги N-Gram тут . Тож я завантажив 2-грамові файли для "a_" та "an". Це близько 26 концертів, якщо я правильно згадую. З цього я створив список рядків, де їм переважно передувала протилежна стаття, яку ви очікували (якщо ми очікували, що голосні приймають "an"). Цей остаточний список слів я зміг зберегти менше 7 кілобайт.


-2

Ви використовуєте "a", коли наступне слово не є голосною? І ви використовуєте "an", коли є голосна?

З огляду на це, чи не могли б ви просто зробити регулярний вираз типу "a \ s [a, e, i, o, u]. *"? А потім замініть його на "an?"


Ні, оскільки правило стосується голосних звуків , а не голосних букв . "Користувач" починається з голосної, але вимова - ні.
Joris Groosman
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.