ارتباط با مجموعه داده‌های برنامه‌های موبایل

شکل ۱. ارتباط با مجموعه داده‌های برنامه‌های موبایل
شکل ۱. ارتباط با مجموعه داده‌های برنامه‌های موبایل
منتشر‌شده در: towardsdatascience به تاریخ ۲۲ می ۲۰۲۱
لینک منبع: Tinkering with the Mobile Apps Dataset

مقدمه

شغل اصلی من مربوط به تبلیغات موبایل است، و من گاهی اوقات باید با مجموعه داده‌های برنامه‌های کاربردی موبایل کار کنم.

من تصمیم گرفتم برخی از داده‌ها را در دسترس عموم قرار دهم برای کسانی که می‌خواهند مدل‌های ساخت را تمرین کنند یا ایده‌ای از برخی از داده‌هایی که می‌توانند از منابع باز جمع‌آوری شوند، به دست آورند. من معتقدم که مجموعه داده‌های منبع باز همیشه مفید هستند چون به شما این امکان را می‌دهند که یاد بگیرید و رشد کنید. جمع‌آوری اطلاعات اغلب کاری دشوار و خسته‌کننده است و همه قادر به انجام آن نیستند.

در این تحقیق، من یک مجموعه داده را معرفی کرده و یک مدل را با استفاده از داده‌های آن ایجاد خواهم کرد.

داده‌ها

این مجموعه داده در Kaggle website منتشر شده‌ است.

DOI: 10.34740/KAGGLE/DSV/2107675.

توکن‌های توصیفیStemmed و داده‌های برنامه برای ۲۹۳۳۹۲ برنامه (محبوب‌ترین) جمع‌آوری شده‌اند. هیچ نام کاربردی در مجموعه داده وجود ندارد؛ شناسه منحصر به فرد آن‌ها را شناسایی می‌کند. قبل از آغاز به کار، بیشتر توصیفات به زبان انگلیسی ترجمه شدند.

مجموعه داده شامل چهار فایل است:

  • مجموعه _ desc.csv-تنها حاوی توضیحات است؛
  • مجموعه _ desc _ tokens.csv-شامل توکن ها و ژانرها است؛
  • مجموعه prop.csv, bundles_summary.csv -شامل ویژگی‌های کاربردی اضافی و تاریخ‌های به‌روزرسانی است.

مورد EDA

اول از همه، اجازه دهید ببینیم داده‌ها چگونه در سراسر سیستم‌های عامل توزیع شده‌اند.

شکل ۲. توزیع داده‌ها
شکل ۲. توزیع داده‌ها

برنامه‌های کاربردی اندروید بر داده‌ها تسلط دارند. به احتمال زیاد، این به این دلیل است که برنامه‌های کاربردی بیشتری برای اندروید در حال ایجاد هستند. با توجه به این که مجموعه داده تنها شامل محبوب‌ترین برنامه‌های کاربردی است، جالب است که شده است.

histnorm='probability' # type of normalization

شکل ۳. تاریخ انتشار برنامه‌ها
شکل ۳. تاریخ انتشار برنامه‌ها

بسیاری از برنامه‌های کاربردی به طور منظم به‌روزرسانی می‌شوند زیرا آخرین تاریخ به‌روزرسانی در گذشته چندان دور نیست.

شکل ۴. تاریخ به‌روز‌رسانی بسته نرم‌افزاری
شکل ۴. تاریخ به‌روز‌رسانی بسته نرم‌افزاری

داده‌های پایه در یک دوره زمانی کوتاه در ماه ژانویه جمع‌آوری شدند.

شکل ۵. تاریخ آپدیت دیتاست
شکل ۵. تاریخ آپدیت دیتاست

بیایید یک ویژگی جدید اضافه کنیم - تعداد ماه‌ها بین تاریخ انتشار و آخرین به‌روزرسانی.

df['bundle_update_period'] = \
  (pd.to_datetime(
  df['bundle_updated_at'], utc=True).dt.tz_convert(None).dt.to_period('M').astype('int') - 
  df['bundle_released_at'].dt.to_period('M').astype('int'))
شکل ۶. دوره‌های به‌روزرسانی برنامه‌ها
شکل ۶. دوره‌های به‌روزرسانی برنامه‌ها

جالب است بدانید که ژانرها چگونه توزیع می‌شوند. با در نظر گرفتن عدم تعادل سیستم‌عامل، من داده‌ها را برای هیستوگرام نرمال خواهم کرد.

شکل ۷. نرمال‌سازی داده‌ها را برای هیستوگرام
شکل ۷. نرمال‌سازی داده‌ها را برای هیستوگرام

ما می‌توانیم ببینیم که ژانرها به طور کامل هم پوشانی ندارند. این امر به ویژه در بازی‌ها قابل‌توجه است. آیا کاری هست که ما بتوانیم در مورد آن انجام دهیم؟ بدیهی‌ترین چیز کاهش تعداد ژانرها برای اندروید و آوردن آن‌ها به همان شکل iOS است. اما من فکر می‌کنم که این بهترین گزینه نیست، چون اطلاعات از دست می‌رود. بیایید سعی کنیم کار معکوس را حل کنیم. برای انجام این کار، من باید مدلی بسازم که بتواند ژانرها را برای برنامه‌های iOS پیش‌بینی کند.

مطالعه‌ مقاله‌ ۹سرور گوناگون دیسکورد برای ریاضیات، پایتون و علوم داده که امروزه به آن‌ها نیاز دارید! توصیه می‌شود.

مدل

من برخی ویژگی‌های اضافی را با استفاده از توصیف طول و تعداد توکن‌ها ایجاد کردم.

def get_lengths(df, columns=['tokens', 'description']):
  lengths_df = pd.DataFrame()
  for i, c in enumerate(columns):
  lengths_df[f&quot{c}_len&quot] = df[c].apply(len)
  if i > 0:
  lengths_df[f&quot{c}_div&quot] = \
  lengths_df.iloc[:, i-1] / lengths_df.iloc[:, i]
  lengths_df[f&quot{c}_diff&quot] = \
  lengths_df.iloc[:, i-1] - lengths_df.iloc[:, i]
  return lengths_dfdf = pd.concat([df, get_lengths(df)], axis=1, sort=False, copy=False)
شکل ۸. نتایج با استفاده از توصیف طول و تعداد توکن‌ها
شکل ۸. نتایج با استفاده از توصیف طول و تعداد توکن‌ها

به عنوان یکی دیگر از ویژگی‌ها، من تعداد ماه‌هایی را که از تاریخ انتشار برنامه می‌گذرد، صرف کردم. ایده این است که ممکن است برخی از ژانرهای بازی در بازار ارجحیت داشته باشند.

شکل ۹. ماه‌های پس از انتشار
شکل ۹. ماه‌های پس از انتشار

من از داده‌های برنامه‌های اندروید برای آموزش استفاده کردم.

android_df = df[df['store_os']=='android']
ios_df = df[df['store_os']=='ios']

فهرست نهایی ویژگی‌ها برای مدل به شرح زیر است:

columns = [
  'genre', 'tokens', 'bundle_update_period', 'tokens_len',
  'description_len', 'description_div', 'description_diff',
  'description', 'rating', 'reviews', 'score',
  'released_at_month'
]

من مجموعه داده‌ها را با کاربردهای اندروید به دو بخش تقسیم کردم-آموزش و اعتبارسنجی. لطفا توجه داشته باشید که تقسیم مجموعه داده به چند برابر باید طبقه‌بندی شود.

train_df, test_df = train_test_split(
  android_df[columns], train_size=0.7, random_state=0, stratify=android_df['genre'])y_train, X_train = train_df['genre'], train_df.drop(['genre'], axis=1)
y_test, X_test = test_df['genre'], test_df.drop(['genre'], axis=1)

من CatBoost را به عنوان کتابخانه رایگان مدل انتخاب کردم. کستوست یک کتابخانه با عملکرد بالا و منبع باز برای تقویت درخت‌های تصمیم‌گیری است. این روش با انتشار ۰.۱۹.۱ از ویژگی‌های متنی برای طبقه‌بندی در GPU آماده برای استفاده پشتیبانی می‌کند. مزیت اصلی این است که CatBoost می‌تواند شامل توابع قطعی و توابع متنی در داده‌های شما بدون پیش‌پردازش اضافی باشد.

در تحلیل احساسی غیراتمی: BERT در مقابل Catboost، مثالی از نحوه کار CatBoost با متن و مقایسه آن با BERT ارائه می‌دهم.

!pip install catboost

هنگام کار باCatBoost، من استفاده از Pool را توصیه می‌کنم. این یک روش مناسب برای ترکیب ویژگی‌ها، برچسب‌ها و فراداده های بیشتر مانند ویژگی‌های مطلق و متن است.

train_pool = Pool(
  data=X_train, 
  label=y_train,
  text_features=['tokens', 'description']
)test_pool = Pool(
  data=X_test, 
  label=y_test, 
  text_features=['tokens', 'description']
)

بیایید یک تابع برای مقداردهی اولیه و آموزش مدل بنویسیم. من پارامترهای بهینه رو انتخاب نکردم؛ بگذارید این تکلیف دیگر شما باشد.

def fit_model(train_pool, test_pool, **kwargs):
  model = CatBoostClassifier(
  random_seed=0,
  task_type='GPU',
  iterations=10000,
  learning_rate=0.1,
  eval_metric='Accuracy',
  od_type='Iter',
  od_wait=500,
  **kwargs
  )return model.fit(
  train_pool,
  eval_set=test_pool,
  verbose=1000,
  plot=True,
  use_best_model=True
  )

از ویژگی‌های متنی برای ساخت ویژگی‌های عددی جدید استفاده می‌شود. اما برای این کار، لازم است بهCatBoost توضیح دهیم که دقیقا چه چیزی را می‌خواهیم از آن به دست آوریم. طبقه‌بندی کننده راه‌انداز دارای چندین پارامتر است که می‌تواند برای پارامتری کردن مورد استفاده قرار گیرد:

  • توکنایزرها - توکنایزرها برای پیش‌پردازش ستون‌های ویژگی نوع متن قبل از ایجاد فرهنگ لغت به کار می‌روند؛
  • لغت‌نامه‌ها - لغت‌نامه‌های مورد استفاده برای پیش پردازش ستون‌های ویژگی نوع متن به کار می‌روند؛
  • دستگاه‌های اندازه‌گیری ویژگی - برای محاسبه ویژگی‌های جدید بر اساس ستون‌های ویژگی نوع متن پیش‌پردازش شده مورد استفاده قرار می‌گیرند.
  • پردازش متن - مشخصات Json از توکنایزرها، دیکشنری‌ها و شناسه‌های ویژگی، که تعیین می‌کنند چگونه ویژگی‌های متن به لیستی از ویژگی‌های شناور تبدیل می‌شوند.

پارامتر چهارم جایگزین سه پارامتر اول می‌شود و، به نظر من، مناسب‌ترین پارامتر است، زیرا در یک مکان، به وضوح نشان داده می‌شود که چگونه با متن کار کنیم.

tpo = {
  'tokenizers': [
  {
  'tokenizer_id': 'Sense',
  'separator_type': 'BySense',
  }
  ],
  'dictionaries': [
  {
  'dictionary_id': 'Word',
  'token_level_type': 'Word',
  'occurrence_lower_bound': '10'
  },
  {
  'dictionary_id': 'Bigram',
  'token_level_type': 'Word',
  'gram_order': '2',
  'occurrence_lower_bound': '10'
  },
  {
  'dictionary_id': 'Trigram',
   'token_level_type': 'Word',
  'gram_order': '3',
  'occurrence_lower_bound': '10'
  },
  ],
  'feature_processing': {
  '0': [
  {
  'tokenizers_names': ['Sense'],
  'dictionaries_names': ['Word'],
  'feature_calcers': ['BoW']
  },
  {
  'tokenizers_names': ['Sense'],
  'dictionaries_names': ['Bigram', 'Trigram'],
  'feature_calcers': ['BoW']
  },
  ],
  '1': [
  {
  'tokenizers_names': ['Sense'],
  'dictionaries_names': ['Word'],
  'feature_calcers': ['BoW', 'BM25']
  },
  {
  'tokenizers_names': ['Sense'],
  'dictionaries_names': ['Bigram', 'Trigram'],
  'feature_calcers': ['BoW']
  },
  ]
  }
}

بیایید مدل را آموزش دهیم:

model_catboost = fit_model(
  train_pool, test_pool,
  text_processing = tpo
)
شکل ۱۰. دقت
شکل ۱۰. دقت


شکل ۱۱. از دست دادن
شکل ۱۱. از دست دادن

bestTest = 0.6454657601

شکل ۱۲. نمودار مدل
شکل ۱۲. نمودار مدل
ممکن است به مطالعه مقاله تابع نقشه در پایتون علاقمند باشید.

تنها دو ویژگی تاثیر عمده‌ای بر مدل دارند. به احتمال زیاد، کیفیت می‌تواند به دلیل ویژگی خلاصه افزایش یابد، اما از آنجا که در کاربردهای iOS در دسترس نیست، امکان اعمال سریع آن وجود نخواهد داشت. اگر مدلی داشته باشید که بتواند یک پاراگراف کوتاه از متن را از توصیف به دست آورد، به شما کمک خواهد کرد. من این وظیفه را به عنوان تکلیف شما رها می‌کنم.

با توجه به اعداد، کیفیت خیلی بالا نیست. دلیل اصلی این است که کاربردها اغلب برای نسبت دادن به یک ژانر خاص چالش برانگیز هستند و هنگام مشخص کردن ژانر، تعصب توسعه‌دهنده وجود دارد. یک ویژگی عینی‌تر مورد نیاز است که چندین ژانر مناسب برای هر برنامه را منعکس کند. این ویژگی می‌تواند بردار احتمالات باشد، که در آن هر عنصر بردار با احتمال تخصیص به یک یا چند ژانر متناظر است.

برای به دست آوردن چنین برداری، ما باید فرآیند را با استفاده از پیش‌بینی‌های OOF (out-of-Fold) پیچیده کنیم. ما از کتابخانه‌های شخص‌ثالث استفاده نخواهیم کرد؛ بیایید یک تابع ساده بنویسیم.

def get_oof(n_folds, x_train, y, x_test, text_features, seeds):
  
  ntrain = x_train.shape[0]
  ntest = x_test.shape[0] 
  
  oof_train = np.zeros((len(seeds), ntrain, 48))
  oof_test = np.zeros((ntest, 48))
  oof_test_skf = np.empty((len(seeds), n_folds, ntest, 48))
  test_pool = Pool(data=x_test, text_features=text_features) 
  models = {}
  for iseed, seed in enumerate(seeds):
  kf = StratifiedKFold(
   n_splits=n_folds,
  shuffle=True,
  random_state=seed) 
  for i, (tr_i, t_i) in enumerate(kf.split(x_train, y)):
  print(f'\nSeed {seed}, Fold {i}')
  x_tr = x_train.iloc[tr_i, :]
   y_tr = y[tr_i]
  x_te = x_train.iloc[t_i, :]
  y_te = y[t_i]
  train_pool = Pool(
  data=x_tr, label=y_tr, text_features=text_features)
  valid_pool = Pool(
  data=x_te, label=y_te, text_features=text_features)
  model = fit_model(
  train_pool, valid_pool,
  random_seed=seed,
  text_processing = tpo
  )
  x_te_pool = Pool(
  data=x_te, text_features=text_features)
  oof_train[iseed, t_i, :] = \
  model.predict_proba(x_te_pool)
  oof_test_skf[iseed, i, :, :] = \
  model.predict_proba(test_pool)
  models[(seed, i)] = model
  oof_test[:, :] = oof_test_skf.mean(axis=1).mean(axis=0)
  oof_train = oof_train.mean(axis=0)
  return oof_train, oof_test, models

محاسبات بسیار وقت‌گیر است، اما در نتیجه، من دریافت کردم:

  • داده oof_train-پیش‌بینی‌های OOF برای برنامه‌های اندروید
  • داده oof_test-پیش‌بینی‌های OOF برای برنامه‌های iOS
  • مدل‌ها-همه مدل‌های OOF برای چین‌ها و دانه‌های تصادفی
from sklearn.metrics import accuracy_scoreaccuracy_score(
  android_df['genre'].values,
  np.take(models[(0,0)].classes_, oof_train.argmax(axis=1)))

به دلیل ترکیب و میانگین‌گیری از چندین دانه تصادفی، کیفیت کمی بهبود یافته‌است.

OOF accuracy: 0.6560790777135628

مطالعه مقاله استفاده از پایتون برای فرانت‌اند توصیه می‌شود.

من یک ویژگی جدید به نام android_genre_vec ایجاد کردم که در آن مقادیر oof_train را برای کاربردهای اندروید و oof_test را برای کاربردهای iOS کپی کردم.

idx = df[df['store_os']=='ios'].index
df.loc[df['store_os']=='ios', 'android_genre_vec'] = \
  pd.Series(list(oof_test), index=idx)
idx = df[df['store_os']=='android'].index
df.loc[df['store_os']=='android', 'android_genre_vec'] = \
  pd.Series(list(oof_train), index=idx)

علاوه بر این، ژانر اندروید نیز اضافه شد، که در آن من ژانر را با بیش‌ترین احتمال قرار دادم.

df.loc[df['store_os']=='ios', 'android_genre'] = \
  np.take(models[(0,0)].classes_, oof_test.argmax(axis=1))
df.loc[df['store_os']=='android', 'android_genre'] = \
  np.take(models[(0,0)].classes_, oof_train.argmax(axis=1))
شکل ۱۳. مقایسه اندروید و ios
شکل ۱۳. مقایسه اندروید و ios


خلاصه

در این گزارش، من:

  • یک مجموعه داده رایگان جدید معرفی کردم؛
  • تجزیه و تحلیل داده‌های اکتشافی انجام شد؛
  • چند ویژگی جدید به وجود آوردم؛
  • مدلی را برای پیش‌بینی ژانر یک کاربرد از روی توصیف آن ایجاد کردم.

امیدوارم که این مجموعه داده برای جامعه مفید باشد و در هر دو مدل و تحقیق مورد استفاده قرار گیرد.

کدهای این مقاله را می‌توان در اینجا مشاهده کرد.

این متن با استفاده از ربات ترجمه مقالات علم داده ترجمه شده و به صورت محدود مورد بازبینی انسانی قرار گرفته است.در نتیجه می‌تواند دارای برخی اشکالات ترجمه باشد.
مقالات لینک‌شده در این متن می‌توانند به صورت رایگان با استفاده از مقاله‌خوان ترجمیار به فارسی مطالعه شوند.