# **بسم الله الرحمن الرحیم**
# مقدمه
به نظر مسخره میآید که هر بار میخواهیم متنی فارسی که پر از لغات انگلیسی است را تایپ کنیم، مجبور هستیم مدام از کلیدهای میانبر تغییر زبان استفاده کنیم.
حتما تا به حال برای همه ی ما پیش آمده که وقتی در مرورگر یک آدرس اینترنتی را تایپ میکنند، پس از نگاه کردن به صفحه ی نمایشگر خود به اشتباه با چیزی شبیه به «صصص.لخخلمث.زخپ» مواجه می شویم. تصور کنید که چقدر کار راحت تر می شود اگر صفحه کلید یا رایانه خودش بفهمد که هدف ما در آنجا انگلیسی تایپ کردن بوده است و نه فارسی.
هدف این پروژه در واقع نرم افزاری است که بتوان در آن بدون نیاز به تغییر زبان کیبورد و استفاده ی مدام و خسته کننده از دکمه های میانبر صفحه کلید، فارسی و انگلیسی را با هم نوشت و خود نرم افزار تشخیص دهد که کلمهی مورد نظر فرد در هر جمله و عبارت، فارسی بوده است یا انگلیسی.
این نرم افزار در درجه ی اول باعث راحتی و آسودگی کاربر می گردد و همچنین سرعت تایپ کاربر را مخصوصا در مواردی که متن مورد نظر آمیزه ای از جملات و کلمات دو زبانه می باشد،بالاتر می برد.
----------
# کارهای مرتبط
شاید بتوان گفت که سایت گوگل یکی از بهترین تشخیص دهنده ها برای زبان ورودی می باشد. هنگامی که شما بدون توجه به این که صفحه کلید در چه حالتی است، مشغول به تایپ هستید و مثلا یک کلمه ی فارسی را به اشتباه به صورت انگلیسی تایپ می کنید و یا برعکس، سایت گوگل این اشتباه شما را تشخیص داده و خطای شما را در هنگام نمایش دادن نتایج، تصحیح می کند.
با اینکه این سایت از لحاظ هدف و نتیجه بسیار شبیه این پروژه می باشد اما متاسفانه منبع و مرجعی برای روش کار آن یافت نشد.
![نمونه ای از تشخیص زبان ورودی کیبورد توسط سایت گوگل](https://boute.s3.amazonaws.com/152-1.JPG)
از جمله کارهای مرتبط دیگر می توان به [Ninja Keyboard](http://www.keyboard-ninja.com/) و [Key Switcher](http://www.keyswitcher.com/) اشاره کرد.این نرم افزار ها که بر روی ویندوز نصب می شوند، کلمات ورودی کاربر در برنامه های مختلف رو کنترل کرده و اگر کاربر فراموش کرده باشد که حالت صفحه کلید خود را تعویض کند، به صورت خودکار این کار را برای کاربر انجام می دهند.
اما دونکته قابل توجه وجود دارد : اولا اینکه این نرم افزارها از زبان فارسی پشتیبانی نمی کنند و به تعداد کمی از زبان ها محدود می شوند. ثانیا روش کار خود را برای پیاده سازی پروژه توضیح نداده اند و مشخص نیست که از چه روشی برای انجام پروژه ی شان استفاده کرده اند.
مواردی که در بالا ذکر شد، نمونه هایی از انجام این پروژه بودند. اما با توجه به اینکه هیچکدام روش کار خود را توضیح نداده و روش حل مسئله را در اختیار عموم قرار نداده بودند، بنابراین در انجام این پروژه نمی توان از آنها استفاده کرد و یا کمک گرفت.
----------
# حل مسئله
با توجه به اینکه مسائلی که به زبان طبیعی انسان و یا نوشتار مربوط هستند عموما با **Language Modeling** حل می شوند، به نظر می رسد برای حل این مسئله نیز باید از تکنیک های **Language Modeling** بهره گرفت. حال به تعریف مختصری از این عبارت می پردازیم :
**مدل های طبیعی زبان**:
به زبانی می گویند که بین انسان ها رایج است و انسان ها می توانند از آن برای ارتباط با یکدیگر به صورت های نوشتن، حرف زدن، خواندن و ... استفاده کنند. وقتی می گوییم مدل سازی زبان طبیعی، یعنی بیاییم و روابط و قواعد زبان را به طور هدفمند، ساده کنیم تا به ابزاری برسیم که بتوان از آن برای بررسی زبان و یا استفاده یا حتی تولید آن استفاده کرد. بسیاری از این مدل ها از یک پس زمینه ریاضی برخوردار هستند،مانند گراف، احتمالات و ... .
برای کسب اطلاعات بیشتر در این زمینه می توانید به [اینجا](http://en.wikipedia.org/wiki/Language_model) یا [اینجا](https://web.stanford.edu/class/cs124/lec/languagemodeling.pdf) مراجعه کنید.
یکی از مدل هایی که مبتنی بر زبان های طبیعی می باشد و می توان در این پروژه از آن استفاده کرد مدل **n-gram** می باشد :
در این مدل، از آمار کلاسیک و احتمال بهره گرفته شده است. فرض کنید که یک سری اشیا یا نشانه ها و یا هر چیز دیگری داشته باشیم. هر کدام از این ها را به صورت یک رأس در گراف تصور کنید که می تواند به رأس دیگری یال جهت دار داشته باشد. این یال جهت دار، نشان دهنده یک نوع رابطه است که با توجه به مورد دلخواه ما می تواند معانی متفاوتی داشته باشد. مثلاً در مورد زبان، می تواند توالی دو کلمه باشد (اگر کلمه ای بعد از کلمه دیگری بیاید، یک یال از اولی به دومی وجود دارد). به یک توالی n تایی از این رأس ها، n-gram می گوییم (توالی های 3gram، 2gram و ... داریم). در این مدل، یک مجموعه داده های آماری بسیار بزرگ نیاز داریم که هر کدام مجموعه ای از این نشانه ها به همراه روابط بین آن ها است. برای مثال، در مورد یک زبان خاص، یک سری متن در آن زبان می باشد.
روابطی در این مدل تعریف می شود که می توان با استفاده از آن، درستی یک توالی خواص از این نشانه ها را بررسی کرد.
حال به توضیح مختصری در مورد روابط این مدل می پردازیم :
فرض کنید می خواهیم درستی عبارت ![](https://boute.s3.amazonaws.com/152-daum_equation_1429197102283.jpg) را بررسی کنیم. در این مدل، احتمال درستی به صورت یک عدد تعیین می شود که هرچه داده های آماری ما بیشتر باشد، نتیجه دقیق تر است. عبارت بالا را به اجزای زیر تقسیم می کنیم و تعداد تکرار هر کدام را در داده های آماری پیدا می کنیم :
![اجزای عبارت](https://boute.s3.amazonaws.com/152-daum_equation_1429199221659.jpg) حال احتمال های 3gram ، 2gram و ... به صورت زیر تعریف می شوند :
![توضیح تصویر](https://boute.s3.amazonaws.com/152-daum_eq1uation_1429198919508.jpg) هر کدام از عبارت های بالا یعنی احتمال آمدن آخرین حرف مورد نظر بعد از حروف قبلی که مقدار آن برابر است با :
![احتمال درستی یک عبارت](https://boute.s3.amazonaws.com/152-image002.jpg) در عبارت بالا، تابع C یعنی تعداد تکرار توالی مورد نظر در داده های آماری.
در حالت کلی، احتمال درستی عبارت بالا در مدل n-gram به صورت رابطه زیر است :
![حالت کلی احتمال درستی یک عبارت](https://boute.s3.amazonaws.com/152-image004.jpg) در این جا، تنها یک مشکل باقی می ماند و آن هم این است که اگر تنها یکی از این احتمال ها صفر شود، احتمال کل صفر خواهد شد. در حالی که می دانیم داده های آماری ما محدودیت دارند و ممکن است بالاخره یکی از توالی ها، مخصوصاً اگر تعداد آن زیاد باشد، در داده ها وجود نداشته باشد. راه حل این است که به هر کدام، یک مقدار ثابت (مثلاً 1) اضافه کنیم.
برای آشنایی بیشتر با این مدل می توانید به [اینجا](http://en.wikipedia.org/wiki/N-gram) مراجعه کنید.
این مدل می تواند در انجام این پروژه به ما بسیار کمک کند. زیرا با استفاده از آن می توان فهمید که هر کلمه که در متن آمده است، اساسا صحیح نوشته شده و مورد نظر نویسنده بوده و یا صرفا به خاطر صحیح نبودن حالت صفحه کلید، به آن شکل خاص نوشته شده است.
----------
# آزمایش ها
در فاز دوم، پیاده سازی این پروژه با استفاده از زبان جاوا صورت گرفته است. اساس و پایه ی این پیاده سازی به این صورت است که هنگامی که یک متن برای پردازش به برنامه داده می شود، برنامه با توجه به پردازش هایی که از قبل بر روی متون فارسی و انگلیسی مختلف انجام داده است، صورت صحیح یک کلمه را تشخیص داده و آن را به خروجی برنامه اضافه می کند. در واقع برنامه این را بررسی می کند که صورت فارسی یک رشته از کاراکترها بیشتر در متون پردازش شده وجود داشته است یا صورت انگلیسی آن. سپس با توجه به احتمالی که هرکدام از کلمات داشته اند، هر کلمه ای را که احتمالش بیشتر باشد به عنوان پاسخ مسئله در نظر می گیرد.
+ **داده های مورد استفاده** :
همانطور که گفته شد، در انجام این پروژه از متون فارسی و انگلیسی مختلفی استفاده شده است تا بتوان هنگامی که یک کلمه به برنامه داده شد، صورت صحیح آن را تشخیص دهد.
داده های انگلیسی این پروژه از متون مختلفی جمع آوری شده است که بالغ بر 1,000,000 کلمه می باشد. از طریق این [لینک](http://norvig.com/big.txt) می توانید به این داده ها دست پیدا کنید.
همچنین از دادگان [پرسیکا](http://dadegan.ir/catalog/persica) که شامل بر 10,000 خبر از خبرگزاری ایسنا می باشد استفاده شده است که البته برای اینکه حجم داده های فارسی و انگلیسی مورد بررسی یکسان باشد، تنها از 2500 خبر آن استفاده شده است.
+ **روش پیاده سازی شده** :
در این قسمت به توضیح مختصری در خصوص برنامه ی پیاده سازی شده می پردازیم :
برنامه به طوری نوشته شده است که ابتدا به بررسی دو فایل `big.txt` و `bigfa.txt` می پردازد و بر اساس آنها یک hashmap می سازد. hashmap در واقع ساختمان داده ای می باشد که کارکرد آن نگهداری لیستی از مقادیر است که هرکدام از آنها توسط یک کلید قابل تشخیص و بازیابی می باشد. در این hashmap کلید ها همان کلمات درون هر فایل متنی است و مقادیر بر اساس تکرار هر کلمه در هر یک از متن ها مقداردهی می شود.
چون این فرآیند نسبتا زمان بر است، بعد از این که یکبار این کار انجام می شود hashmap های ساخته شده درون یک فایل ذخیره می شوند که بتواند به سرعت مورد بازیابی قرار گیرد. البته یک انتخاب درون برنامه وجود دارد که میتواند این hashmap ها را به روز رسانی کند.
بعد از ساختن این دو hashmap که یکی مربوط به کلمات زبان فارسی و دیگری مربوط به کلمات زبان انگلیسی است ورودی از کاربر گرفته شده و تک تک کلمات بررسی می شوند. اگر کلمه ای به صورتی که در ورودی داده شده است، در متونی که از قبل پردازش شده است وجود داشته باشد، آن کلمه به همان صورت که داده شده است به خروجی منتقل می شود ولی اگر اینچنین نباشد و کاربر بدون توجه به زبان صفحه کلید کلمه ای را تایپ کرده باشد، برنامه صورت صحیح آن را تشخیص داده و سپس به خروجی منتقل می کند.
اساس تبدیل و جایگزینی حروف فارسی به انگلیسی یا برعکس بر این است که مثلا بر روی صفحه کلید،اگر صفحه به زبان فارسی باشد دکمه ی **A** همان حرف **ش** می باشد و برنامه نیز جایگزینی حروف را بر این اساس انجام می دهد.
توجه داشته باشید که هم برای متون از پیش پردازش شده و هم برای متن ورودی که می خواهد برای پردازش به برنامه داده شود، کاراکتر فاصله جداکننده ی کلمات در نظر گرفته شده است و به طور مثال کلمه ی **سی ان ان** به عنوان سه کلمه در نظر گرفته می شود که این موضوع از ضعف ها و محدودیت های پروژه بوده و باید در آینده اصلاح شود.
برنامه برای تشخیص صورت صحیح کلمات به این صورت عمل می کند که به طور مثال اگر کلمه ی **sghl** در متن ورودی موجود باشد عینا این کلمه را مورد بررسی و جستجو در لیست کلماتی که از قبل پردازش شده است، قرار می دهد. همچنین این بررسی را برای صورت فارسی آن کلمه که مثلا در اینجا از تبدیل حروف ** S و G و H و L ** به حروف ** س و ل و ا و م ** ساخته می شود و کلمه ی سلام را شکل می دهد، انجام می دهد. پس از بررسی آن صورتی را در خروجی چاپ می کند که تعداد تکرارش بیشتر بوده باشد که در این مثال برای شکل انگلیسی کلمه **0** تکرار و برای شکل فارسی آن بیش از **100** تکرار موجود بوده است.
همچنین با توجه به اینکه ممکن است کلمه وجود داشته باشد که هم صورت فارسی آن و هم صورت انگلیسی آن در هر دو زبان وجود داشته باشد، کلمه ای توسط برنامه انتخاب می شود که در آن زبان پرکاربرد تر باشد. مثلا کلمه ی **شد** اگر صفحه کلید به زبان انگلیسی باشد، کلمه ی **An** را می سازد که این دو کلمه هر دو، در زبان های مربوط به خودشان قابل استفاده هستند و برنامه آن صورتی را انتخاب می کند که در متون از پیش پردازش شده، بیشتر تکرار شده باشد.
+ **روش کار با برنامه** :
هر کاربر برای استفاده از این برنامه کافی ست که ورودی و متنی را که می خواهد مورد پردازش قرار بگیرد را درون فایل `voroodi.txt` تایپ کرده و سپس از طریق یک IDE برنامه را RUN کند. برنامه به کاربر دو انتخاب می دهد که با انتخاب گزینه ی دوم برنامه اجرا شده و خروجی هم بر روی کنسول IDE و هم درون فایل `khorooji.txt` قابل مشاهده خواهد بود.
نکته : با توجه به تنظیماتی که برای یک فایل txt. وجود دارد، ورودی باید از خط دوم در فایل مربوطه نوشته شود.
![تصویری از برنامه](https://boute.s3.amazonaws.com/152-choose.JPG)
در زیر می توان نمونه ای از پزدازش یک متن را توسط برنامه مشاهده کرد :
متن ورودی برنامه :
`hdk d; jsj dh d; فثسف fvhd hdk hsj ;i ببینیم حقخلقشئ nvsj ;hv می ;kn ؟`
`hdk \v,Ci باید بتواند که d; ;gli thvsd و ثدلمهسا را از هم تشخیص دهد`
`فاشدن غخع lja;vl`
متن خروجی برنامه :
`این یک تست یا یک test برای این است که ببینیم program درست کار می کند ؟`
`این پروژه باید بتواند که یک کلمه فارسی و english را از هم تشخیص دهد`
`thank you متشکرم`
همانطور که دیده می شود دقت وصحت برنامه برای این متن ساده **100** درصد صحیح می باشد.
با توجه به اینکه یک منبع و نوشته ای که سرشار از لغات انگلیسی و فارسی باشد یافت نشد، بنابراین نمی توان دقت و صحت عملکرد دقیق این برنامه را سنجید. اما دو نمونه متن فارسی و انگلیسی که به برنامه داده شد، دقت برای هر کدام به ترتیب بیش از**98** و **99** درصد بود. این به این معنا است که برنامه با دقت بسیار بالایی اگر متن درستی به آن داده شود شکل صحیح آن را تغییر نمی دهد و آن را عوض نمی کند و تنها کلماتی را تغییر می دهد که واقعا به صورت صحیح نیستند.
+ **کد ها** :
شما برای استفاده از این برنامه و مشاهده ی کدها می توانید به این [لینک](https://github.com/smhhy/Language-Detection) که در سایت گیت هاب قرار دارد مراجعه نمایید.
# کارهای آینده :
مواردی که به نظر می رسد باید به برنامه اضافه شود تا شاهد برنامه ی کامل تری باشیم به شرح زیر می باشد :
+ برنامه باید بتواند صورت صحیح کلماتی را که با همدیگر یک کلمه را تشکیل می دهند تشخیص دهد. مانند کلمه ی **بی بی سی**
+ برنامه باید برای یک رشته ی خاص استثناء قائل شود و به هیچ وجه متن مورد نظر را دستکاری نکند. مثلا اگر جمله ای درون علامت {} آمد به درون آن کاری نداشته باشد و مستقیما آن را به خروجی منتقل کند.
+ یکی از نقاط ضعفی که در برنامه موجود می باشد این است که متن خروجی به صورت پشت سرهم چاپ می شود و مثلا اگر در متن ورودی سرخط رفته باشیم، این امر نادیده گرفته می شود. این اشکال باید در آینده تصحیح شود.
+ برنامه باید قابلیت این را پیدا کند که از کاربر بازخورد گرفته و بر اساس آن بازخورد عملکرد خود را بهبود بخشد.
+ باید قابلیتی به برنامه اضافه شود تا خود برنامه پس از نصب بر روی دستگاه طرح بندی یا همان Layout صفحه کلید را تشخیص داده و بر اساس آن جایگزینی حروف را انجام دهد. زیرا طرح بندی تمام صفحه کلید ها یکسان نیست و با یکدیگر تفاوت دارند.
----------
# منابع و مراجع
+ Third international joint on conference on Natural Language Processing , January 2008
+ Natural Language Processing , Raymond J. Mooney
+ A general language model for information retrieval , Fei Song and W.Bruce Croft
+ All our N-gram are belong to you , Alex Franz and Thorsten Brants
+ [مدل های زبان های طبیعی](http://ce.sharif.edu/~h_forghani/%D9%85%D8%AF%D9%84%20%D9%87%D8%A7%DB%8C%20%D8%B2%D8%A8%D8%A7%D9%86%20%D8%B7%D8%A8%DB%8C%D8%B9%DB%8C.htm)