В прошлый раз, когда я проверял, Google Keep установил эти дополнения:
Они не документированы как часть документации Android, поэтому они не составляют API Android. Кроме того, Google Keep не полагается на намерение распознавателя рассмотреть эти дополнения. Было бы неплохо, если бы такие дополнения были популяризированы и задокументированы Google.
Чтобы узнать, какие дополнительные функции устанавливаются в Google Keep при вызове RecognizerIntent
, внедрите приложение, которое реагирует на RecognizerIntent
, и распечатайте все дополнительные данные, которые оно получает. Вы также можете установить Kõnele ( http://kaljurand.github.io/K6nele/ ), который является реализацией RecognizerIntent
. Когда Google Keep запускает Kõnele, нажмите и удерживайте значок настроек в виде гаечного ключа. Это показывает некоторые технические подробности о звонящем, а также включает в себя дополнительные дополнения.
Ответ @Iftah объясняет, как Google Keep возвращает аудиозапись абоненту из RecognizerIntent
.
Мне пришлось использовать различные предложенные техники. Спасибо, что указали мне правильное направление (а). Надеюсь, следующее поможет кому-то другому решить эту проблему.
Удаление лишних символов
CREATE FUNCTION [dbo].[fn_StripCharacters]
(
@String NVARCHAR(MAX),
@MatchExpression VARCHAR(255)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
SET @MatchExpression = '%['+@MatchExpression+']%'
WHILE PatIndex(@MatchExpression, @String) > 0
SET @String = Stuff(@String, PatIndex(@MatchExpression, @String), 1, '')
RETURN @String
END
Использование:
--remove all non-alphanumeric and non-white space
dbo.fn_StripCharacters(@Value, , '^a-z^0-9 ')
Разделить имя на части
CREATE FUNCTION [dbo].[SplitTable] (@sep char(1), @sList StringList READONLY)
RETURNS @ResultList TABLE
(
[ID] VARCHAR(MAX),
[Val] VARCHAR(MAX)
)
AS
BEGIN
declare @OuterCursor cursor
declare @ID varchar(max)
declare @Val varchar(max)
set @OuterCursor = cursor fast_forward for (SELECT * FROM @sList) FOR READ ONLY
open @OuterCursor
fetch next from @OuterCursor into @ID, @Val
while (@@FETCH_STATUS=0)
begin
INSERT INTO @ResultList (ID, Val)
select @ID, split.s from dbo.Split(@sep, @Val) as split
where len(split.s) > 0
fetch next from @OuterCursor into @ID, @Val
end
close @OuterCursor
deallocate @OuterCursor
CREATE FUNCTION [dbo].[Split] (@sep char(1), @s varchar(8000))
RETURNS table
AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(@sep, @s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT pn,
LTRIM(RTRIM(SUBSTRING(@s, start,
CASE WHEN stop > 0
THEN stop-start
ELSE 8000
END))) AS s
FROM Pieces
)
RETURN
Использование:
--create split name list
DECLARE @NameList StringList
INSERT INTO @NameList (ID, Val)
SELECT id, firstname FROM dbo.[User] u
WHERE PATINDEX('%[^a-z]%', u.FirstName) > 0
----remove split dups
select u.ID, COUNT(*)
from dbo.import_SplitTable(' ', @NameList) splitList
INNER JOIN dbo.[User] u
ON splitList.id = u.id
Общие прозвища:
I создал таблицу на основе этого списка и использовал ее для объединения общих эквивалентов имен.
Использование:
SELECT u.id
, u.FirstName
, u_nickname_maybe.Name AS MaybeNickname
, u.LastName
, c.ID AS ContactID from
FROM dbo.[User] u
INNER JOIN nickname u_nickname_match
ON u.FirstName = u_nickname_match.Name
INNER JOIN nickname u_nickname_maybe
ON u_nickname_match.relatedid = u_nickname_maybe.id
LEFT OUTER JOIN
(
SELECT c.id, c.LastName, c.FirstName,
c_nickname_maybe.Name AS MaybeFirstName
FROM dbo.Contact c
INNER JOIN nickname c_nickname_match
ON c.FirstName = c_nickname_match.Name
INNER JOIN nickname c_nickname_maybe
ON c_nickname_match.relatedid = c_nickname_maybe.id
WHERE c_nickname_match.Name <> c_nickname_maybe.Name
) as c
ON c.AccountHolderID = ah.ID
AND u_nickname_maybe.Name = c.MaybeFirstName AND u.LastName = c.LastName
WHERE u_nickname_match.Name <> u_nickname_maybe.Name
Фонетические алгоритмы (Яро Винклер):
Замечательная статья, Beyond SoundEx - Функции для нечеткого поиска в MS SQL Server , показывает, как установить и использовать библиотеку SimMetrics в SQL Server. Эта библиотека позволяет находить относительное сходство между строками и включает в себя множество алгоритмов. В итоге я в основном использовал Jaro Winkler для сопоставления имен.
Использование:
SELECT
u.id AS UserID
,c.id AS ContactID
,u.FirstName
,c.FirstName
,u.LastName
,c.LastName
,maxResult.CombinedScores
from
(
SELECT
u.ID
,
max(
dbo.JaroWinkler(lower(u.FirstName), lower(c.FirstName))
* dbo.JaroWinkler(LOWER(u.LastName), LOWER(c.LastName))
) AS CombinedScores
FROM dbo.[User] u, dbo.[Contact] c
WHERE u.ContactID IS NULL
GROUP BY u.id
) AS maxResult
INNER JOIN dbo.[User] u
ON maxResult.id = u.id
INNER JOIN dbo.[Contact] c
ON maxResult.CombinedScores =
dbo.JaroWinkler(lower(u.FirstName), lower(c.FirstName))
* dbo.JaroWinkler(LOWER(u.LastName), LOWER(c.LastName))
Я часто использую алгоритмы звукового типа для таких ситуаций. Попробуйте алгоритм Двойной метафон . Если вы используете SQL Server, существует некоторый исходный код для создания пользовательской функции.
Поскольку вы транспонировали данные, вы можете немного нормализовать их, например, удалить все запятые и сортировать полученные слова по первой букве . Это даст вам лучший потенциал соответствия. В случае, когда слова были добавлены посередине, становится немного сложнее. Вы можете разбить имя на слова, проверить с помощью Double Metaphone, есть ли слово в другом столбце, которое соответствует, а затем собрать общее количество совпадений по сравнению со словами, которое покажет вам, насколько близки эти два столбца.
Я бы также отфильтровал такие общие слова, как доктор, мистер, мисс, миссис и т. Д., Прежде чем проводить сравнения.
Вот несколько вариантов:
Фонетические алгоритмы ...
Soundex ( http://en.wikipedia.org/wiki/Soundex )
Двойной метафон ( http://en.wikipedia.org/wiki/Double_Metaphone )
Изменить расстояние ( http://en.wikipedia.org/wiki/Levenshtein_distance )
Расстояние Яро-Винклера ( http://en.wikipedia.org/wiki/Jaro-Winkler_distance )
Еще одна вещь, которую вы могли бы попробовать, - это сравнить каждое слово (разделение на пробел и, возможно, дефис) с каждым словом в другом имени и посмотрите, сколько слов совпадают. Возможно, объедините это с фонетическими алгоритмами для более нечеткого соответствия. Для огромного набора данных вам нужно проиндексировать каждое слово и сопоставить его с идентификатором имени. Для сопоставления аббревиатуры вы можете сравнить только первую букву.
Это очень сложная проблема, и для ее решения требуется множество дорогостоящих инструментов. делай это правильно.
Если вы когда-нибудь задумывались, почему вы не можете зарегистрироваться на рейс как Том, Дик или Гарри (или Билл)
Или почему запретные для полетов списки и списки наблюдения террористов не работают - подумайте:
(1) Муаммар Каддафи
(2) Моаммар Каддафи
(3) Муаммар Каддафи
{{1} } (4) Муаммар Каддафи
(5) Муаммар Эль Каддафи
(6) Муаммар Каддафи
(7) Муаммар аль-Кадафи
(8) Моамер эль-Каззафи
(9) Моамар аль-Каддафи
(10) Муаммар аль-Каттафи
{{ 1}} (11) Муаммар аль-Катдафи
(12) Моаммар эль-Каддафи
(13) Моамар эль-Каддафи
(14 ) Муаммар Каддафи
(15) Муаммар аль-Каддафи
(16) Муаммар Каддафи
(17) Моамар Каддафи
(18) Муаммар Каддафи
(19) Муаммар Каддафи
(20) Муаммар аль-Хаддафи
{{1} } (21) Муамар аль-Кадафи
(22) Муаммар Каддафи
(23) Муаммар Каддафи
{ {1}} (24) Муаммар Каддафи
(25) Муамар Каддафи
(26) Муаммар Кватафи
(27) Муаммар Каддафи
(28) Муамар Аль-Каддафи
(29) Муаммар Каддафи
(30) Муаммар Куддафи
(31) Муаммар аль-Каддафи
(32) Мулазим Аввал Муаммар Мухаммад Абу Миньяр аль-Каддафи
И это просто официальное написание - оно не включает опечаток!