
مع الانتقال إلى العزلة الذاتية في مارس من هذا العام ، قمنا ، مثل العديد من الشركات ، بنقل جميع أحداث البقالة لدينا عبر الإنترنت. حسنًا ، تتذكر هذه الصورة الرائعة عن الندوات عبر الإنترنت مع القرود. على مدار الأشهر الستة الماضية ، فيما يتعلق فقط بموضوع مراكز البيانات ، التي يكون فريقي مسؤولاً عنها ، قمنا بتجميع حوالي 25 ندوة عبر الإنترنت مدتها ساعتان ، أي ما مجموعه 50 ساعة من الفيديو. المشكلة التي ظهرت في النمو الكامل هي كيفية فهم الفيديو الذي تبحث فيه عن إجابات لأسئلة معينة. الكتالوج والعلامات والوصف المختصر جيدة ، حسنًا ، وجدنا أخيرًا أن هناك 4 مقاطع فيديو مدتها ساعتان حول الموضوع ، ثم ماذا؟ مشاهدة على الترجيع؟ هل هو ممكن بطريقة مختلفة؟ وإذا كنت تتصرف بطريقة عصرية وحاولت إفساد الذكاء الاصطناعي؟
المفسد لفارغ الصبر : لم أتمكن من العثور على نظام معجزة كامل أو تجميعه على ركبتي ، ومن ثم لن يكون هناك فائدة في هذه المقالة. ولكن نتيجة البحث لعدة أيام (أو بالأحرى في المساء) ، حصلت على MVP عاملة ، والتي أود إخباركم عنها. الغرض من المقالة هو إلقاء نظرة على مستوى الاهتمام بالقضية ، والحصول على المشورة من الأشخاص المطلعين ، وربما العثور على شخص آخر لديه نفس المشكلة.
ماذا اريد ان افعل
للوهلة الأولى ، بدا كل شيء بسيطًا - يمكنك التقاط مقطع فيديو وتشغيله عبر الشبكة العصبية والحصول على نص ، ثم البحث عن جزء في النص يصف موضوع الاهتمام. سيكون أكثر ملاءمة البحث في جميع مقاطع الفيديو في الكتالوج مرة واحدة. في الواقع ، لقد تم اختراعه لتحميل نسخ نصية مع مقاطع الفيديو لفترة طويلة ، ويمكن لـ Youtube ومعظم المنصات التعليمية القيام بذلك ، على الرغم من أنه من الواضح أن الأشخاص هناك يقومون بتحرير هذه النصوص. يمكنك مسح النص ضوئيًا بأعينك بسرعة وفهم ما إذا كانت هناك إجابة على السؤال المطلوب. ربما ، من خلال وظيفة ملائمة ، لن يضر أن تكون قادرًا على الوخز في مكان الاهتمام بالنص والاستماع إلى ما يقوله المحاضر ويظهر هناك ، وهذا ليس بالأمر الصعب أيضًا إذا كان هناك ترميز للكلمات في الوقت المناسب ، حيث توجد في النص. حسنًا ، كنت أحلم بالاتجاهات المحتملة للتنمية ، فلنتحدث في النهاية ،والآن دعونا نحاول تنفيذ السلسلة بأكبر قدر ممكن من الكفاءة
ملف فيديو -> جزء نصي -> بحث نص غامض .
في البداية اعتقدت ، بما أن كل شيء بسيط للغاية ، وقد تم الحديث عن هذه الحالة لمدة 4 سنوات في جميع المؤتمرات حول الذكاء الاصطناعي ، يجب أن تكون هذه الأنظمة جاهزة. أظهرت بضع ساعات من البحث وقراءة المقالات أن الأمر لم يكن كذلك. يستخدم الفيديو بشكل أساسي للبحث عن الوجوه والسيارات والأشياء المرئية الأخرى (الأقنعة / الخوذات) والصوت - الأغاني والمسارات بالإضافة إلى نغمة / نغمة السماعة ، كجزء من حلول مراكز الاتصال. كان من الممكن العثور فقط على هذا الذكر لنظام Deepgram . لكنها ، للأسف ، لا تحظى بدعم اللغة الروسية. أيضًا ، تمتلك Microsoft وظائف مشابهة جدًا في Streams ، لكن لم أجد في أي مكان ذكرًا لدعم اللغة الروسية ، على ما يبدو ، ليس هناك أيضًا.
حسنًا ، دعنا نعيد الابتكار. أنا لست مبرمجًا محترفًا (وبالمناسبة ، سأقبل بكل سرور النقد البناء على الكود) ، لكن من وقت لآخر أكتب شيئًا "لنفسي". تسمى الشبكات العصبية التي يمكنها تحويل الكلام إلى نص (مفاجأة مفاجئة) ، تحويل الكلام إلى نص . إذا تمكنت من العثور على خدمة تحويل الكلام إلى نص عامة ، فيمكنك استخدامها "لرقمنة" الكلام في جميع الندوات عبر الإنترنت ، ثم إجراء بحث غامض في النص - مهمة أسهل. أعترف أنني في البداية لم أفكر في "التسلق إلى السحابة" ، أردت جمع كل شيء محليًا ، ولكن بعد قراءة هذا المقال عن حبري ، قررت أن التعرف على الكلام أفضل حقًا في السحابة.
البحث عن الخدمات السحابية لتحويل الكلام إلى نص
أظهر البحث عن الخدمات القادرة على إجراء تحويل الكلام إلى نص أن هناك الكثير من هذه الأنظمة ، بما في ذلك تلك التي تم تطويرها في روسيا ، وهناك أيضًا مزودي خدمة سحابية عالمية مثل Google و Amazon و MS Azure بينهم . وصف العديد من الخدمات، بما في ذلك تلك التي باللغة الروسية ، وهنا . بشكل عام ، ستكون أول 20 سطرًا في نتائج محرك البحث فريدة من نوعها. لكن هناك عقبة أخرى - أود إطلاق هذا النظام في الإنتاج في المستقبل ، هذه تكلفة ، وأنا أعمل لدى شركة Cisco ، التي لديها عقود مع السحب الرائدة عالميًا. لذا من القائمة بأكملها ، قررت أن أفكر فيها فقط الآن.
لذلك تم تخفيض قائمتي ل جوجل ، أمازون ، أزور ،IBM Watson (روابط العناوين هي نفسها الواردة في الجدول أدناه). تحتوي جميع الخدمات على واجهات برمجة تطبيقات يمكن استخدامها من خلالها. بعد تحليل بقية الاحتمالات ، قمت بتجميع جدول صغير:
ترك IBM Watson السباق في هذه المرحلة ، نظرًا لأن جميع التسجيلات التي أمتلكها باللغة الروسية ، فقد تقرر اختبار بقية مقدمي الخدمة في مقتطف قصير من الندوة عبر الإنترنت. لقد قمت بإعداد حسابات في AWS و Azure. بالنظر إلى المستقبل ، سأقول أن Microsoft أصبحت صعبة الاختراق من حيث إنشاء حساب. عملت من شبكة شركة "تهبط" على الإنترنت في مكان ما في أمستردام ، أثناء عملية التسجيل ، سئلت مرتين عما إذا كنت متأكدًا من أن عنواني هو روسيا ، وبعد ذلك عرض النظام رسالة مفادها أن الحساب كان في حالة حظر إداري "توضيح معلق" ... بعد 5 أيام ، بينما كنت أكتب هذا المقال ، لم يتغير الوضع ، لذلك لم أتمكن من اختبار Azure حتى الآن ، وهذا أمر مؤسف! أفهم - الأمان ، لكن هذا لم يسمح لي بعد بتجربة الخدمة. سأحاول القيام بذلك لاحقًا ، عندما يتم حل الوضع.
بشكل منفصل ، أود اختبار مثل هذه الوظيفة في Yandex.Cloud ، يجب أن يكون اعترافهم بالكلام الروسي ، من الناحية النظرية ، الأفضل. ولكن لسوء الحظ ، في صفحة الوصول التجريبي للخدمة ، لا يوجد سوى القدرة على "قول" النص ، ولا يتم توفير تنزيل الملف. لذلك ، سوف نؤجل مع Azure في المركز الثاني.
لذا ، غادرت Google و Amazon ، فلنختبرها قريبًا! قبل كتابة أي رمز ، يمكنك التحقق من كل شيء ومقارنته يدويًا ، حيث يمتلك كلا الموفرين ، بالإضافة إلى واجهة برمجة التطبيقات ، واجهة إدارية. بالنسبة للاختبار ، قمت أولاً بإعداد جزء مدته 10 دقائق ذو طبيعة عامة ، إن أمكن ، مع حد أدنى من المصطلحات المتخصصة. ولكن بعد ذلك اتضح أن Google تدعم جزءًا يصل إلى دقيقة واحدة في وضع الاختبار ، لذلك استخدمت هذا الجزء الذي يبلغ طوله 57 ثانية لمقارنة الخدمات .
بناءً على نتائج العمل ، تصدر كلتا الخدمتين النص الذي تم التعرف عليه ، يمكنك مقارنة نتائج عملهما في فاصل زمني مدته دقيقة واحدة.
النتيجة ، بصراحة ، ليست كما هو متوقع ، ولكن ليس من قبيل الصدفة أن توفر النماذج خيارات مختلفة لتخصيصها. كما نرى ، تعرف محرك Google "خارج الصندوق" على معظم النص بشكل أكثر وضوحًا ، وتمكن أيضًا من رؤية أسماء بعض المنتجات ، وإن لم يكن كلها. يشير هذا إلى أن نموذجهم يسمح بنص متعدد اللغات. أما أمازون (تم تأكيد ذلك لاحقًا) ليس لديها مثل هذه الفرصة - قالوا بالروسية ، مما يعني أننا سنغني: "Kin babe lom" والفترة!
لكن القدرة على الحصول على علامة JSON التي توفرها Amazon بدت مثيرة جدًا بالنسبة لي. بعد كل شيء ، سيسمح هذا في المستقبل بتنفيذ انتقال مباشر إلى جزء الملف حيث تم العثور على الجزء المطلوب. ربما تمتلك Google أيضًا مثل هذه الوظيفة ، لأن جميع الشبكات العصبية للتعرف على الكلام تعمل بهذه الطريقة ، لكن البحث السريع في الوثائق فشل في العثور على هذه الميزة.
بالنظر إلى JSON هذا ، يمكنك أن ترى أنه يتكون من ثلاثة أقسام: النص المترجم (نسخة) ، ومجموعة من الكلمات (العناصر) ، ومجموعة من المقاطع (المقاطع). بالنسبة إلى مجموعة من الكلمات والمقاطع لكل عنصر ، تتم الإشارة إلى أوقات بدايته ونهايته ، بالإضافة إلى ثقة (ثقة) الشبكة العصبية في أنها تعرفت عليه بشكل صحيح.
تعليم الشبكة العصبية لفهم مراكز البيانات
لذلك ، في نهاية هذه المرحلة ، قررت اختيار Amazon Transcribe لمزيد من التجارب ومحاولة إعداد نموذج تعليمي. وإذا لم تتمكن من تحقيق اعتراف مستقر - تعامل مع Google. تم إجراء مزيد من الاختبارات على جزء مدته 10 دقائق.
لدى AWS Transcribe خياران لضبط ما تتعرف عليه الشبكة العصبية ، وميزات أخرى لنص ما بعد المعالجة:
- Custom Vocabularies – «» , , «» , . : «, , » Word 97- . , , .. .
- Custom Language Models – «» 10 . , . , , , .
- , , -. , – , .. -, .
لذلك ، قررت أن أصنع كلمتي الخاصة للنص. من الواضح أنه سيتضمن كلمات مثل "الشبكة ، الخوادم ، الملفات الشخصية ، مركز البيانات ، الجهاز ، وحدة التحكم ، البنية التحتية". بعد 2-3 اختبارات ، نمت مفرداتي إلى 60 كلمة. يجب إنشاء هذا القاموس في ملف نصي عادي ، كلمة واحدة في كل سطر ، وكلها بأحرف كبيرة. هناك أيضًا خيار أكثر تعقيدًا ( موصوف هنا ) مع القدرة على تحديد كيفية نطق الكلمة ، لكن في المرحلة الأولية قررت أن أفعل بقائمة بسيطة.
قبل استخدام القاموس ، تحتاج إلى إنشائه. في علامة تبويب المفردات المخصصة في Amazon Transcribe ، انقر فوق Create Vocabulary ، وقم بتحميل نص الملف الخاص بنا ، وحدد اللغة الروسية ، وأجب على بقية الأسئلة ، وستبدأ عملية إنشاء قاموس. بمجرد أن يخرجتصبح المعالجة جاهزة - يمكن استخدام القاموس.
يبقى السؤال - كيف نتعرف على مصطلحات "اللغة الإنجليزية"؟ دعني أذكرك أن القاموس يدعم لغة واحدة فقط. في البداية فكرت في إنشاء قاموس منفصل بمصطلحات إنجليزية وتشغيل نفس النص من خلاله. عند اكتشاف مصطلحات مثل Cisco و VLAN و UCSإلخ ج معدل الاحتمال 100٪ - خذهم للجزء الزمني المحدد. لكنني سأقول على الفور أنه لم ينجح ، لم يتعرف محلل اللغة الإنجليزية على أكثر من نصف المصطلحات في النص. بعد التفكير ، قررت أن هذا أمر منطقي ، لأننا نلفظ كل هذه المصطلحات بـ "اللهجة الروسية" ، حتى الأنجلو أميركيين لم يفهمونا في المرة الأولى. دفع هذا الفكرة إلى إضافة هذه المصطلحات ببساطة إلى القاموس الروسي وفقًا لمبدأ "كما يُسمع ، لذا يُكتب". Cisco و usies و eisiai و vilan و viikslan - بعد كل شيء ، نحن بكل صدق نقول ذلك عندما نتواصل مع بعضنا البعض. أدى هذا إلى زيادة القاموس ببضع عشرات من الكلمات ، ولكن بالنظر إلى المستقبل ، فقد أدى ذلك إلى تحسين جودة التعرف بترتيب من حيث الحجم!
كما يقول المثل ، "تأتي فكرة جيدة بعد ذلك" ، فقد تم بالفعل إنشاء أول قاموس ، لذلك قررت إنشاء قاموس آخر ، وإضافة جميع الاختصارات إليه ، ومقارنة ما يحدث.
بدء الاعتراف مع القاموس هو مجرد بسيطة، في على ترجمة خدمة على وظيفة النسخ التبويب، حدد خلق فرص العمل ، تحديد اللغة الروسية، و لا تنسى لتحديد نحتاج القاموس. إجراء مفيد آخر - يمكنك أن تطلب من الشبكة العصبية أن تعطينا عدة نتائج بحث بديلة ، النتائج البديلة - عنصر نعم ، لقد قمت بتعيين 3 خيارات بديلة. في وقت لاحق ، عندما أقوم بإجراء عمليات بحث عن نص غامض ، سيكون هذا مفيدًا.
يستغرق بث جزء من النص مدته 10 دقائق من 4 إلى 5 دقائق ، حتى لا يضيع الوقت ، قررت أن أكتب أداة صغيرة تسهل عملية مقارنة النتائج. سأعرض النص النهائي من ملف JSON في المتصفح ، مع إبراز "موثوقية" اكتشاف الكلمات الفردية بواسطة الشبكة العصبية (نفس معامل الثقة ). لدي ثلاثة خيارات للنص الناتج - الترجمة الافتراضية ، وقاموس بدون مصطلحات ، وقاموس بالمصطلحات. دع النصوص الثلاثة تُعرض في وقت واحد في ثلاثة أعمدة. أبرز الكلمات ذات الموثوقية التي تزيد عن 95٪ باللون الأخضر ، ومن 95٪ إلى 70٪ باللون الأصفر ، وأقل من 70٪ باللون الأحمر. الشفرة المترجمة على عجل لصفحة HTML الناتجة أدناه ، يجب أن تكون ملفات JSON في نفس الدليل مثل الملف. يتم تحديد أسماء الملفات في متغيرات FILENAME1 ، إلخ.
كود صفحة HTML لعرض النتائج
<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8"> <title>Title</title> </head>
<body onload="initText()">
<hr> <table> <tr valign="top">
<td width="400"> <h2 >- </h2><div id="text-area-1"></div></td>
<td width="400"> <h2 > 1: / </h2><div id="text-area-2"></div></td>
<td width="400"> <h2 > 2: / </h2><div id="text-area-3"></div></td>
</tr> </table> <hr>
<style>
.known { background-image: linear-gradient(90deg, #f1fff4, #c4ffdb, #f1fff4); }
.unknown { background-image: linear-gradient(90deg, #ffffff, #ffe5f1, #ffffff); }
.badknown { background-image: linear-gradient(90deg, #feffeb, #ffffc2, #feffeb); }
</style>
<script>
// File names
const FILENAME1 = "1-My_CiscoClub_transcription_10min-1-default.json";
const FILENAME2 = '2-My_CiscoClub_transcription_10min-2-Russian_only.json';
const FILENAME3 = '3-My_CiscoClub_transcription_10min-v3_Russian_terminilogy.json';
// Read file from disk and call callback if success
function readTextFile(file, textBlockName, callback) {
let rawFile = new XMLHttpRequest();
rawFile.overrideMimeType("application/json");
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4 && rawFile.status == "200") {
callback(textBlockName, rawFile.responseText);
}
};
rawFile.send(null);
}
// Insert text to text block and color words confidence level
function updateTextBlock(textBlockName, text) {
var data = JSON.parse(text);
let translatedTextList = data['results']['items'];
const listLen = translatedTextList.length;
const textBlock = document.getElementById(textBlockName);
for (let i=0; i<listLen; i++) {
let addWord = translatedTextList[i]['alternatives'][0];
// load word probability and setup color depends on it
let wordProbability = parseFloat(addWord['confidence']);
let wordClass = 'unknown';
// setup the color
if (wordProbability > 0.95) {
wordClass = 'known';
} else if (wordProbability > 0.7) {
wordClass = 'badknown';
}
// insert colored word to the end of block
let insText = '<span class="' + wordClass+ '">' + addWord['content'] + ' </span>';
textBlock.insertAdjacentHTML('beforeEnd', insText)
}
}
function initText() {
// read three files each to it's area
readTextFile(FILENAME1, "text-area-1", function(textBlockName, text){
updateTextBlock(textBlockName, text);
});
readTextFile(FILENAME2, "text-area-2", function(textBlockName, text) {
updateTextBlock(textBlockName, text);
});
readTextFile(FILENAME3, "text-area-3", function(textBlockName, text) {
updateTextBlock(textBlockName, text);
});
}
</script>
</body></html>
أقوم بتنزيل ملفات asrOutput.json لجميع المهام الثلاث ، وأعد تسميتها كما هو مكتوب في نص HTML ، وهذا ما يحدث.
من الواضح أن إضافة مصطلحات باللغة الروسية سمحت للشبكة العصبية بالتعرف بشكل أكثر دقة على المصطلحات المحددة - " ملف تعريف الخدمة " ، إلخ. وإضافة النسخ الروسي في الخطوة الثانية حولت CSKA إلى cisco . لا يزال النص "متسخًا" ، ولكن بالنسبة لمهمة البحث عن السياق ، يجب أن يكون مناسبًا بالفعل. مع إضافة ندوات جديدة وقراءتها ، ستتوسع المفردات تدريجياً ، وهذه عملية للحفاظ على مثل هذا النظام لا ينبغي نسيانه.
بحث غامض في نص تم التعرف عليه
من المحتمل أن تكون هناك عشرات الطرق لحل مشكلة البحث الضبابي ، ومعظمها تستند إلى مجموعة صغيرة من الخوارزميات الرياضية ، مثل مسافة ليفينشتاين. مقالة جيدة حول هذا ، واحد أكثر و أكثر واحد . لكنني أردت أن أجد شيئًا جاهزًا ، مثل الإطلاق والعمل.
من الحلول الجاهزة للبحث عن المستندات المحلية ، بعد القليل من البحث ، وجدت مشروعًا قديمًا نسبيًا SPHINX ، وكذلك إمكانية البحث عن النص الكامل ، على ما يبدو ، في PostgreSQL ، إنه مكتوب حول هذا هنا . ولكن تم العثور على معظم المواد ، بما في ذلك باللغة الروسية ، حول Elasticsearch . بعد قراءة أدلة بدء التشغيل والإعداد الجيدة مثلهذه الوظيفة أو هذا الدرس ، وهنا آخر ، فضلا عن وثائق و دليل API لبيثون ، وأنا قررت استخدامها.
بالنسبة لجميع التجارب المحلية ، كنت أستخدم Docker لفترة طويلة ، وأوصي بشدة كل من لم يكتشفها لسبب ما حتى الآن ، للقيام بذلك. في الواقع ، أحاول عدم تشغيل أي شيء بخلاف بيئات التطوير والمتصفحات و "المشاهدين" في نظام التشغيل المحلي. بصرف النظر عن عدم وجود مشكلات التوافق ، إلخ. يتيح لك هذا تجربة منتج جديد بسرعة ومعرفة ما إذا كان يعمل بشكل جيد.
نقوم بتنزيل الحاوية باستخدام Elasticsearch وتشغيلها باستخدام أمرين:
$ docker pull elasticsearch:7.9.1
$ docker run -d --name elasticsearch -p 9200:9200 -e "discovery.type=single-node" elasticsearch:7.9.1
بعد بدء الحاوية ،
http://localhost:9200تظهر الواجهة المرنة على العنوان ، ويمكن الوصول إليها باستخدام متصفح أو واجهة برمجة تطبيقات REST لأداة POSTMAN. لكنني وجدت مكونًا إضافيًا مفيدًا من Chrome .
هذا ما تبدو عليه نافذة البرنامج المساعد بمثال حول القطط المضحكة الموضحة في أحد الأدلة أعلاه .
على اليسار يوجد استعلام - على اليمين توجد إجابة ، وإكمال تلقائي ، وإبراز بناء الجملة ، وتنسيق تلقائي - ما هو المطلوب أيضًا لتكون منتجًا! بالإضافة إلى ذلك ، يمكن لهذا المكون الإضافي التعرف على تنسيق سطر أوامر CURL في النص الذي تم لصقه من الحافظة وتنسيقه بشكل صحيح ، على سبيل المثال ، حاول لصق السطر
" curl -X GET $ ES_URL " وشاهد ما يحدث. شيء مفيد بشكل عام.
ماذا وكيف سأخزن وأبحث؟يأخذ Elasticsearch جميع مستندات JSON ويخزنها في هياكل تسمى الفهارس. يمكن أن يكون هناك العديد من الفهارس المختلفة كما تريد ، ولكن يمكن أن يحتوي فهرس واحد على بيانات ووثائق متجانسة ، مع بنية متشابهة للحقول ونفس طريقة البحث.
لاستكشاف إمكانيات البحث الغامض ، قررت تنزيل قسم العبارة (المقاطع) والبحث فيه من ملف النسخ الذي تم الحصول عليه في الخطوة السابقة. في قسم المقاطع من ملف JSON ، يتم تخزين البيانات بالتنسيق التالي:
- 1 (segment)
-> /
->
--> 1
---->
----> , (confidence)
--> 2
---->
----> , (confidence)
أرغب في زيادة احتمالية نجاح البحث ، لذا سأقوم بتحميل جميع الخيارات البديلة إلى قاعدة البيانات للبحث ، ثم حدد الخيار الذي يتمتع بثقة إجمالية أعلى من الأجزاء التي تم العثور عليها.
لإعادة تنسيق مستند JSON وتحميله إلى Elasticsearch ، أستخدم نصًا برمجيًا صغيرًا من Python ، يكون منطق البرنامج النصي كما يلي:
- أولاً ، نتصفح جميع عناصر قسم المقاطع وجميع خيارات النسخ البديلة
- بالنسبة لكل متغير نسخ ، فإننا نعتبر الثقة الكاملة في التعرف عليه ، وأتخذ فقط المتوسط الحسابي للكلمات الفردية ، على الرغم من أنه ، على الأرجح ، يجب التعامل مع هذا في المستقبل بعناية أكبر
- لكل خيار نسخ بديل ، قم بتحميل سجل للنموذج في Elasticsearch
{ "recording_id" : < >, "seg_id" : <id >, "alt_id" : <id >, "start_time" : < >, "end_time" : < >, "transcribe_score" : < (confidence) >, "transcript" : < > }
برنامج Python النصي الذي يقوم بتحميل السجلات من ملف JSON إلى Elasticsearch
from elasticsearch import Elasticsearch
import json
from statistics import mean
#
TRANCRIBE_FILE_NAME = "3-My_CiscoClub_transcription_10min-v3_Russian_terminilogy.json"
LOCAL_IP = "192.168.2.35"
INDEX_NAME = 'ciscorecords'
# Setup Elasticsearch connection
es = Elasticsearch([{'host': LOCAL_IP, 'port': 9200}])
if not es.ping():
print ("ES connection error, check IP and port")
es.indices.create(index=INDEX_NAME) # Create index for our recordings
# Open and load file
res = None
with open(TRANCRIBE_FILE_NAME) as json_file:
data = json.load(json_file)
res = data['results']
#
index = 1
for idx, seq in enumerate(res['segments']):
# enumerate fragments
for jdx, alt in enumerate(seq['alternatives']):
# enumerate alternatives for each segments
score_list = []
for item in alt['items']:
score_list.append( float(item['confidence']))
score = mean(score_list)
obj = {
"recording_id" : "rec_1",
"seg_id" : idx,
"alt_id" : jdx,
"start_time" : seq["start_time"],
"end_time" : seq ["end_time"],
"transcribe_score" : score,
"transcript" : alt["transcript"]
}
es.index( index=INDEX_NAME, id = index, body = obj )
index += 1
إذا لم يكن لديك Python ، فلا تقلق ، فسوف يساعدنا Docker مرة أخرى. عادةً ما أستخدم حاوية بها دفتر ملاحظات Jupyter - يمكنك الاتصال به من خلال متصفح عادي والقيام بكل ما تريد القيام به ، الشيء الوحيد الذي تحتاج إلى التفكير فيه بشأن حفظ النتائج ، حيث يتم فقد جميع المعلومات عند تدمير الحاوية. إذا لم تكن قد استخدمت هذه الأداة من قبل ، فإليك مقالًا جيدًا للمبتدئين ، بالمناسبة ، يمكنك تخطي القسم الخاص بالتثبيت بأمان.
نبدأ حاوية مع دفتر ملاحظات Python بالأمر:
$ docker run -p 8888:8888 jupyter/base-notebook sh -c 'jupyter notebook --allow-root --no-browser --ip=0.0.0.0 --port=8888'
ونقوم بالاتصال به مع أي متصفح على العنوان الذي نراه على الشاشة بعد الإطلاق الناجح للبرنامج النصي ، وهذا
http://127.0.0.1:8888باستخدام مفتاح الأمان المحدد.
نقوم بإنشاء دفتر ملاحظات جديد ، في الخلية الأولى نكتب:
!pip install elasticsearch
تشغيل ، انتظر حتى يتم تثبيت الحزمة الخاصة بالعمل مع ES من خلال API ، وانسخ البرنامج النصي الخاص بنا في الخلية الثانية وقم بتشغيله. بعد عملها ، إذا نجح كل شيء ، يمكننا التحقق في وحدة التحكم Elasticsearch من أنه تم تحميل بياناتنا بنجاح. ندخل الأمر
GET /ciscorecords/_searchونرى سجلاتنا المحملة في نافذة الاستجابة ، بإجمالي 173 قطعة ، كما يخبرنا حقل hit.total.value .
حان الوقت الآن لتجربة البحث الغامض - هذا هو كل شيء. على سبيل المثال ، للبحث عن عبارة "core of the data center network" ، يلزمك إعطاء الأمر التالي:
POST /ciscorecords/_search
{
"size" : 20,
"min_score" : 1,
"sort": { "_score": { "order": "desc" } },
"query": {
"multi_match": {
"query" : " ",
"fuzziness" : 2,
"fields": [ "transcript" ],
"analyzer" : "russian"
}
},
"_source": [ "transcript", "transcribe_score" ]
}
لقد حصلنا على ما يصل إلى 47 نتيجة!
لا عجب ، لأن معظمهم أشكال مختلفة من نفس القطعة. دعنا نكتب برنامجًا نصيًا آخر للاختيار من كل مقطع سجل واحد بأعلى قيمة ثقة.
نص Python للاستعلام عن قاعدة بيانات Elasticsearch
#####
#
# PHRASE = " "
# PHRASE = " "
PHRASE = " "
LOCAL_IP = "192.168.2.35"
INDEX_NAME = 'ciscorecords'
#
elastic_queary = {
"size" : 40,
"min_score" : 1,
"sort": { "_score": { "order": "desc" } },
"query": {
"multi_match": {
"query" : PHRASE,
"fuzziness" : 2,
"fields": [ "transcript" ],
"analyzer" : "russian"
}
},
}
# Setup Elasticsearch connection
es = Elasticsearch([{'host': LOCAL_IP, 'port': 9200}])
if not es.ping():
print ("ES connection error, check IP and port")
#
res = es.search(index=INDEX_NAME, body = elastic_queary)
print ("Got %d Hits:" % res['hits']['total']['value'])
#
search_results = {}
for hit in res['hits']['hits']:
seg_id = hit["_source"]['seg_id']
if seg_id not in search_results or search_results[seg_id]['score'] < hit["_score"]:
_res = hit["_source"]
_res["score"] = hit["_score"]
search_results[seg_id] = _res
print ("%s unique results \n-----" % len(search_results))
for rec in search_results:
print ("seg %(seg_id)s: %(score).4f : start(%(start_time)s)-end(%(end_time)s) -- %(transcript)s" % \
(search_results[rec]))
مثال الإخراج:
Got 47 Hits:
16 unique results
-----
seg 39: 7.2885 : start(374.24)-end(377.165) -- , ..
seg 49: 7.0923 : start(464.44)-end(468.065) -- , ...
seg 41: 4.5401 : start(385.14)-end(405.065) -- . , , , , , ...
seg 30: 4.3556 : start(292.74)-end(298.265) -- , , ,
seg 44: 2.1968 : start(415.34)-end(426.765) -- , , , . -
seg 48: 2.0587 : start(449.64)-end(464.065) -- , , , , , .
seg 26: 1.8621 : start(243.24)-end(259.065) -- . . , . ...
نرى أن النتائج أصبحت أصغر بكثير ، والآن يمكننا عرضها واختيار النتيجة التي تهمنا أكثر.
أيضًا ، نظرًا لأن لدينا وقت البداية والنهاية لجزء الفيديو ، يمكننا إنشاء صفحة بمشغل فيديو و "إرجاعها" برمجيًا إلى جزء الاهتمام.
لكنني سأضع هذه المهمة في مقال منفصل إذا كان هناك اهتمام بمزيد من المنشورات حول هذا الموضوع.
بدلا من الاستنتاج
لذلك ، في إطار هذه المقالة ، أوضحت كيف حللت مشكلة إنشاء نظام بحث نصي باستخدام أداة فيديو مع تسجيلات لندوات عبر الإنترنت حول موضوعات تقنية. والنتيجة هي ما يسمى عادة MVP ، أي الحد الأدنى من خوارزمية العمل التي تتيح لك الحصول على نتيجة وتثبت أن النتيجة ، من حيث المبدأ ، قابلة للتحقيق باستخدام التقنيات الحالية.
لا يزال الطريق طويلاً للوصول إلى المنتج النهائي ، من الأفكار التي يمكن تنفيذها في المستقبل القريب:
- قم بربط مشغل الفيديو حتى تتمكن من الاستماع إليه ، وعرض الجزء الذي تم العثور عليه
- فكر في إمكانية تحرير النص ، بينما يمكنك ترك نقطة ارتساء لنص الكلمات التي تم التعرف عليها بنسبة 100٪ ، قم بتحرير الأجزاء التي تكون فيها جودة التعرف "ضعيفة"
- elasticsearch, -
- speech-to-text, Google, Yandex, Azure. –
- , «»
- BERT (Bi-directional Encoder Representation from Transformer), . – « xx yy».
- , - - . Youtube , 15-20 , ,
- – , , ,
إذا كانت لديك أي أسئلة / تعليقات ، فسأكون سعيدًا للإجابة عليها ، وسأكون سعيدًا أيضًا لسماع أي اقتراحات لتحسين أو تبسيط العملية ككل. هذا هو أول مقال تقني لي عن هبر ، وآمل حقًا أن يكون مفيدًا وممتعًا.
حظًا سعيدًا للجميع في بحثك الإبداعي ، وقد تكون القوة معك!