من تا قبلاز معرفی CoreML توسط اپل، شاید درکل ۷ساعت درمورد یادگیری ماشین تحقیق کرده بودم، دلیل اصلیش هم اینبود که توی زمینهی فعالیتیم نبود و فقط برای اطلاعات عمومی بوده. بعد از انتشار مستندات آیاواس۱۱ رفتم ببینم چه امکاناتی اضافه شده که دیدم 'IdenitityLookup' و 'CoreML' شامل این لیست بودن.
براساس اون ۷ساعت اطلاعات یادگیری ماشین ? به این فکر افتادم که نرمافزاری که از این دو امکان جدید استفاده کنه، تا چه میزان میتونه در بلاک کردن پیامکهای تبلیغاتی موفق باشه. من به شخصه شاید سالی یکبار پیامک تبلیغاتی بگیرم، ولی میدونم که این مشکل واقعا بزرگی هست در داخل ایران. شنیده بودم که بعضیها کاملا استفاده از پیامک رو گذشتن کنار و نوتیفیکیشنهای پیامک رو قطع کرده بودن. از طرفی دیگه هم دیدن توییتهای کاربران توییتر به وزیر ارتباطات یا خوندن سایتهای خبری ناراضی بودن مردم رو نشون میده. لینکهای خبری دیجیاتو در این مورد:
وزیر ارتباطات از توقف ارسال پیامک های تبلیغاتی مزاحم خبر می دهد
ساماندهی پیامکهای تبلیغاتی تا پایان مهرماه
ساماندهی پیامکهای تبلیغاتی مشکل فنی دارد
از اونجایی که همهی ما میدونیم که به این زودیها این مشکل رفع نمیشه من ساخت نمونهاولیه getFilter رو شروع کردم. که الان تموم شده و توی اپاستور هست.
قبل از شروع کردن به نوشتن کد، یه سری مفاهیم و موارد هست که آشناییشون خیلی در یادگیری ماشین کمک میکنه.
برای پردازش متن در یادگیری ماشین، اولین قدم تناسب دادن عدد به یه میزان از اون متن هست. چندین روش رایج و کاربردی برای اینکار هست که هرکدوم خوبیها و بدیهای خودشون رو دارن و حتی ممکنه لازم باشه شما در مسئلهای که حل میکنید روشی کاملا مختص خودتون رو انجام بدید. این توضیح خیلی خلاصه و کوتا دو روشی هست که ممکنه اینجا استفاده شه:
توی این روش، 'تعداد دفعات تکرار'(gram) هر 'بازهای از لغات'(N) میشه معادل عددی اون متن. مثال:
در جملهی "من متن نمونه من هستم",
اگر n=1 باشه این حالت رو با نام 'کیسهای از لغات' میشناسن و وزنها به این شکل میشه:
من= ۲، متن=۱، نمونه=۱، هستم= ۱
اگر n=۲ باشه وزنها به این شکل میشه:
من متن=۱، متن نمونه=۱، نمونه من=۱، من هستم=۱
توی مسئله ما که هدف مشخص کردن اسپم بودن یا نبودن(دسته) متن هست، توی دیتابیسی که داریم برای هر دسته وزنمعادل رو برای تعداد N دلخواه حساب میکنید. یعنی 'من هستم' ممکنه توی اسپمها ۳بار تکرار شده باشه ولی توی غیراسپمها ۱۰بار.
بعداز اینکه این اطلاعات رو جمعآوری کردید، جمع وزنمعادل تمامی بازهها رو جداگونه برای هر دسته باید انجام بدید. نتیجه جمع اعداد هریکی که بیشتر شه یعنی اون متن توی اون دسته هست.
این روش شاید استفادش گاهی اوقات ایدهآل باشه مثلا: پیداکردن غلطهای املایی یا حدس زدن لغت بعدی توی متن، ولی در کل مقدار پردازشی که لازم داره توی دیتابیسهای بزرگ و وجود یه بازهای از کلمات که ممکنه خیلی معنی نداشته باشه توی یک دسته ولی معنی زیادی توی یکی دیگه میتونه جواب رو خیلی تحت تاثیر بده که اینجا مناسب نیست.
از توضیحی خوبی هست که boute.ir نوشته:
در روش TF-IDF وزن دهی کلمات تابعی از توزیع کلمات مختلف در مستندات است.
برای پیاده سازی این روش ابتدا یک مجموعه اسناد (برای مثال مجموعه اسناد همشهری) را در نظر می گیریم. به ازای تمام کلماتی که در پیکره وجود دارد ، بررسی می کنیم که هر کلمه در چه تعداد از سندها تکرار شده است و آن را ذخیره می کنیم .
سپس یک سند به عنوان ورودی دریافت می شود. هدف یافتن کلمات کلیدیِ سند دریافت شده است.
برای این منظور ابتدا بررسی می کنیم که هر یک از کلمات سند ورودی ، چند بار در همان سند استفاده شده است.
سپس به ازای تمام کلمات سند ورودی بررسی می کنیم که هر کلمه در چه تعداد از اسناد پیکره اصلی (برای مثال همشهری) وجود دارد.
این روش چون فراوانی هر سند رو نسبت به خودش هم مقایسه میکنه هم دقیقتره و اینکه مقدار اطلاعات بعد پردازش کمتر. برای همین هست که این روش رو برای حل مسئلهمون استفاده خواهیم کرد.
اولین چیزی رو که باید بدونید اینه که CoreML پلتفرمی برای ساخت و تمرین دادن هوشمصنوعی نیست. CoreML این اجازه رو به شما میده تا از مدلهای که قبلا با استفاده از کتابخانههای دیگه تمرین داده شدن بدون اینکه لازم باشه نگران سازگاری و سرعت باشید استفاده کنید و هیچگونه روشی برای بهبود همون مدل هم روی دستگاه نیست.
برای تبدیل مدلهایی که قبلا تمرین داده شدن به فرمت 'mlmodel.' میتونید از CoreMLTools استفاده کنید یا اینکه خودتون تبدیل مخصوص مدل خودتون رو بنویسید. ما اینجا از CoreMLTools استفاده خواهیم کرد. مستندات این پکیج
و یکی از کمبودهایی که درحال حاضر CoreMLTools داره مدلهایی که کارشون پردازش متن هست و مستقیما از tf-idf یا n-gram استفاده میکنن رو پشتیبانی نمیکنه، و باید خودمون این کار رو انجام بدیم.
ابزارهایی که لازم دارید:
python (2.7), numpy (1.12.1+), protobuf (3.1.0+), coremltools(0.6.3), scikit-learn (0.15+)
Xcode (9.0)
و یه نسخه کوچیک از دیتابیس getFilter رو آماده و دستهبندی شده که توی گیتهاب گذاشتم.
برای بالا بردن دقت و کمتر شدن احتمال پیدا کردن رفتار برای دستکاری نتیجهها توسط دوستان اسپمر طبقهبندی و مرتبکردن دیتا و پیامکها خیلی میتونه کمک کنه.
کارهایی که من انجام میدم هم داخل دیتابیس و هم پیامکها قبل پردازش هوش مصنوعی:
- پاک کردن اعداد و جایگزینی با " "
- پاک کردن علایم و جایگزینی با " "
- پاک کردن حروف عربی و جایگزینی با معادل فارسی
- پاک کردن تمامی فرمهای فاصله مثل خط بعدی و جایگزینی با " "
- پاک کردن " "های اضافی طوری که بین هر کلمه فقط یکبار وجود داشته باشه
# Required imports
import numpy as np
from sklearn.svm import LinearSVC
from sklearn.feature_extraction.text import TfidfVectorizer
import coremltools
۲. خوندن و آماده کردن دیتا
# Reading in and parsing data
raw_data = open('Archive.txt', 'r')
sms_data = []
for line in raw_data:
split_line = line.split("\t")
sms_data.append(split_line)
sms_data = np.array(sms_data)
۳. جدا کردن دسته و پیامکها
# Separating content and labesl
X = sms_data[:, 1]
y = sms_data[:, 0]
۴. تبدیل اطلاعات خام پیامکها به tf-idf
# Vectorize the data to tf-idf using sklearn extraction
vectorizer = TfidfVectorizer()
vectorized = vectorizer.fit_transform(X)
۵. ذخیره لیست لغات*
# Saving words into text file
words = open('Words.txt', 'w')
for feature in vectorizer.get_feature_names():
words.write(feature.encode('utf-8') + '\n')
words.close()
۶. مدل جدید و تمرین دادنش
# Saving words into text file
model = LinearSVC()
model.fit(vectorized, y)
۷. تبدیل مدل تمرین داده شده با فرمت coreml
# Converting the sklearn model to coreml
coreml_model = coremltools.converters.sklearn.convert(model, "message", 'label')
coreml_model.save('MessageClassifier.mlmodel')
*این مرحله لازمه برای محاسبه دستی tf-idf
بعد از اینکه این فایل پایتون رو اجرا کنید ۲تا فایل زیر براتون ساخته میشه.
MessageClassifier.mlmodel, Words.txt
اگر از یکی مدلهای دیگه که با متن سروکار ندارن میخواستید استفاده کنید تنها مرحلهای که لازم بود اضافه کردن mlmodel. بود توی Xcode، اما الان باید متنی رو که میخواید مدلی که تمرین دادید آزمایش بکنه باید قبلش به tf-idf تبدیل بکنید:
مممم، ظاهرا فرمت کد بهم میخوره اینجا واسه همین مجبورم عکس بزارم.
اینا همون مراحلی هستن که بالا توضیح دادم قبل پردازش خوبه که انجام شه.
فکر نکنم این بخش محاسبه tf-idf توضیح لازم داشته باشه چون خیلی واضحه مراحل انجامش.
اینجا هم متن داخل فایل testMessage رو میخونیم و بعد از آمادهسازی و تبدیل به tf-idf میدیم به مدل برای بررسی کردنش.
اینجا میتونید سورس این آموزش رو ببینید.
اگر سوالی دارید یا فکر میکنید جایی لازم به توضیح بیشتر داره بگید،چیزی هم اگر اشتباهه لطفا از طریق توییتر اطلاع بدید.