স্কাইকিট-শিখতে শ্রেণি-ওজনের পরামিতি কীভাবে কাজ করে?


115

class_weightবিজ্ঞান-শিখার লজিস্টিক রিগ্রেশনটির প্যারামিটারটি কীভাবে চালিত হয় তা বুঝতে আমার অনেক সমস্যা হচ্ছে ।

পরিস্থিতি

আমি খুব ভারসাম্যহীন ডেটা সেটে বাইনারি শ্রেণিবদ্ধকরণ করতে লজিস্টিক রিগ্রেশন ব্যবহার করতে চাই। ক্লাসগুলিকে 0 (নেতিবাচক) এবং 1 (ধনাত্মক) হিসাবে লেবেলযুক্ত এবং পর্যবেক্ষণ করা তথ্যগুলি প্রায় 19: 1 অনুপাতের সাথে সর্বাধিক নমুনার নেতিবাচক ফলাফল রয়েছে।

প্রথম প্রয়াস: ম্যানুয়ালি প্রশিক্ষণ ডেটা প্রস্তুত করা

প্রশিক্ষণ এবং পরীক্ষার (প্রায় 80/20) জন্য আমার বিতর্কিত সেটগুলিকে বিচ্ছিন্ন করে দিয়েছি। তারপরে আমি এলোমেলোভাবে 19: 1 এর চেয়ে বিভিন্ন অনুপাতে প্রশিক্ষণ ডেটা হাতে পাওয়ার জন্য প্রশিক্ষণ ডেটা নমুনা দিয়েছিলাম; 2: 1 -> 16: 1 থেকে।

তারপরে আমি এই বিভিন্ন প্রশিক্ষণের ডেটা সাবসেটগুলিতে লজিস্টিক রিগ্রেশন প্রশিক্ষণ দিয়েছি এবং বিভিন্ন প্রশিক্ষণের অনুপাতে একটি ফাংশন হিসাবে পুনরুদ্ধার (= টিপি / (টিপি + এফএন)) প্লট করেছি। অবশ্যই, পুনরুদ্ধারটি অসম্পূর্ণ টেস্টের নমুনাগুলিতে গণনা করা হয়েছিল যার পর্যবেক্ষণ অনুপাত 19: 1 ছিল। দ্রষ্টব্য, যদিও আমি বিভিন্ন মডেলকে বিভিন্ন প্রশিক্ষণের ডেটাতে প্রশিক্ষণ দিয়েছি, আমি তাদের সকলের জন্য একই (বিচ্ছিন্ন) পরীক্ষার ডেটাতে পুনরুদ্ধার গণনা করেছি।

ফলাফল প্রত্যাশার মতো ছিল: 2: 1 প্রশিক্ষণের অনুপাত অনুসারে পুনরুদ্ধারটি প্রায় 60% ছিল এবং এটি 16: 1 এ পৌঁছানোর সাথে সাথে দ্রুত পড়ে গিয়েছিল। বেশ কয়েকটি অনুপাত 2: 1 -> 6: 1 ছিল যেখানে রিকালটি শালীনভাবে 5% এর উপরে ছিল।

দ্বিতীয় প্রচেষ্টা: গ্রিড অনুসন্ধান

এরপরে, আমি বিভিন্ন নিয়মিতকরণের পরামিতিগুলি পরীক্ষা করতে চেয়েছিলাম এবং তাই আমি গ্রিডসন্ধান সিভি ব্যবহার করেছি এবং Cপ্যারামিটারের পাশাপাশি প্যারামিটারের বেশ কয়েকটি মানের একটি গ্রিড তৈরি করেছি class_weight। Nণাত্মক: আমার অনুক্রমের মি অনুপাতের অনুবাদ করতে class_weightআমি অভিধানের ভাষায় ধনাত্মক প্রশিক্ষণের নমুনাগুলি ভেবেছিলাম যে আমি বেশ কয়েকটি অভিধান নিম্নলিখিত হিসাবে নির্দিষ্ট করেছি:

{ 0:0.67, 1:0.33 } #expected 2:1
{ 0:0.75, 1:0.25 } #expected 3:1
{ 0:0.8, 1:0.2 }   #expected 4:1

এবং আমি এছাড়াও অন্তর্ভুক্ত করা Noneএবং auto

এবার ফলাফলগুলি পুরোপুরি নষ্ট হয়ে গেল। আমার সমস্ত স্মৃতিগুলি class_weightবাদে প্রতিটি মূল্যের জন্য ক্ষুদ্র (<0.05) প্রকাশিত হয়েছিল auto। সুতরাং আমি কেবল ধরে নিতে পারি যে অভিধানটি কীভাবে সেট করবেন সে সম্পর্কে আমার বোঝাটি class_weightভুল। মজার বিষয় হল, class_weightগ্রিড অনুসন্ধানে 'অটো' এর মান সমস্ত মানের জন্য প্রায় 59% ছিল Cএবং আমি অনুমান করেছি যে এটি 1: 1 এর ভারসাম্য?

আমার প্রশ্নগুলো

  1. class_weightআপনি আসলে যা দেন তা থেকে প্রশিক্ষণের ডেটাতে বিভিন্ন ভারসাম্য অর্জন করতে আপনি কীভাবে সঠিকভাবে ব্যবহার করবেন? বিশেষত, class_weightn: m অনুপাতের ইতিবাচক প্রশিক্ষণের নমুনাগুলি ব্যবহার করতে আমি কোন অভিধানটি পাস করতে পারি ?

  2. আপনি যদি class_weightগ্রিডসন্ধান সিভিতে বিভিন্ন অভিধানগুলি পাস করেন , ক্রস-বৈধকরণের সময়কালে এটি অভিধান অনুসারে প্রশিক্ষণ ভাড়ার ডেটাগুলিকে ভারসাম্য বজায় রাখে তবে পরীক্ষার ভাগে আমার স্কোরিং ফাংশনটি গণনার জন্য সত্য প্রদত্ত নমুনা অনুপাত ব্যবহার করবে? এটি গুরুত্বপূর্ণ কারণ যে কোনও মেট্রিকটি কেবলমাত্র তখনই কার্যকর যখন এটি পর্যবেক্ষণ অনুপাতে থাকা ডেটা থেকে আসে।

  3. অনুপাত পর্যন্ত autoমূল্য কি করতে পারে class_weight? আমি ডকুমেন্টেশনটি পড়েছি এবং আমি ধরে নিয়েছি "তাদের ফ্রিকোয়েন্সিটির সাথে বিপরীত সমানুপাতিক উপাত্তগুলিতে ভারসাম্য বোধ করি" এর অর্থ এটি এটিকে 1: 1 করে makes এটা কি সঠিক? তা না হলে কেউ কি স্পষ্ট করে বলতে পারেন?


যখন কেউ ক্লাসওয়েট ব্যবহার করে, ক্ষতির ফাংশনটি পরিবর্তিত হয়। উদাহরণস্বরূপ, ক্রস এনট্রপির পরিবর্তে, এটি ওজনযুক্ত ক্রস এনট্রপি হয়ে যায়। towardsdatascience.com/...
prashanth

উত্তর:


123

প্রথমত, কেবল একা প্রত্যাহার করে যাওয়া ভাল নাও হতে পারে। সমস্ত কিছুকে ইতিবাচক শ্রেণি হিসাবে শ্রেণিবদ্ধ করে আপনি কেবল 100% রিক্যাল অর্জন করতে পারেন। আমি প্যারামিটারগুলি নির্বাচন করার জন্য সাধারণত এওসি ব্যবহার করার পরামর্শ দিই এবং তারপরে অপারেটিং পয়েন্টের জন্য একটি প্রান্তিক সন্ধান (প্রদত্ত যথাযথ স্তর বলুন) যা আপনার আগ্রহী।

কি ভাবে class_weightকাজ করে: এটা নমুনা ভুল penalizes class[i]সঙ্গে class_weight[i]পরিবর্তে 1. উচ্চ শ্রেণী-ওজন মানে তাই আপনি যদি একটি বর্গ উপর বেশি জোর লাগাতে চান। আপনি যা বলছেন তা থেকে ক্লাস 0 ক্লাস 1 এর চেয়ে 19 গুণ বেশি ঘন ঘন হয় So সুতরাং আপনার class_weightক্লাস 0 এর সাথে তুলনামূলকভাবে 1 ক্লাসের বৃদ্ধি করা উচিত , 0: .1, 1: .9 say বলুন} যদি class_weight1 এর সমষ্টি না হয় তবে এটি মূলত নিয়মিতকরণের পরামিতিটি পরিবর্তন করে।

কীভাবে class_weight="auto"কাজ করে তার জন্য আপনি এই আলোচনার দিকে নজর রাখতে পারেন । দেব সংস্করণে আপনি ব্যবহার করতে পারেন class_weight="balanced", যা বোঝা সহজ it এটির অর্থ মূলত ছোট বর্গের প্রতিলিপি করা যতক্ষণ না আপনার যতক্ষণ না বড় আকারে যতগুলি নমুনা থাকে, তবে একটি অন্তর্নিহিত উপায়ে।


1
ধন্যবাদ! তাত্ক্ষণিক প্রশ্ন: আমি স্পষ্টতার জন্য প্রত্যাহারের কথা উল্লেখ করেছি এবং আসলে আমি সিদ্ধান্ত নেওয়ার চেষ্টা করছি যে কোন এওসি আমার পরিমাপ হিসাবে ব্যবহার করবে। আমার বোধগম্যতা হল যে আমি হয় আরওসি বক্ররেখার অধীনে অঞ্চল বা পরামিতিগুলি সন্ধান করার জন্য যথার্থ বক্ররেখের অধীনে অঞ্চল হওয়া উচিত। এইভাবে পরামিতিগুলি বাছাই করার পরে, আমি বিশ্বাস করি যে আমি বক্ররেখার সাথে স্লাইড করে শ্রেণিবিন্যাসের জন্য প্রান্তিককরণটি বেছে নিই। এই আপনি কি বোঝাতে চেয়েছিলেন? যদি তা হয় তবে আমার লক্ষ্যটি যতটা সম্ভব টিপি'র ক্যাপচার করা উচিত কিনা তা দেখার জন্য দুটি বাঁকগুলির মধ্যে কোনটি সবচেয়ে সার্থক করে? এছাড়াও, আপনার কাজ এবং বিজ্ঞান-শিখতে অবদানের জন্য আপনাকে ধন্যবাদ !!!
কেজিওরআউটআউট

1
আমি মনে করি আরওসি ব্যবহার করা আরও মানসম্পন্ন উপায় হবে তবে আমি মনে করি না এখানে একটি বিশাল পার্থক্য থাকবে। যদিও আপনার বক্ররেখার পয়েন্টটি বাছাই করতে কিছু মানদণ্ড দরকার।
আন্দ্রেয়াস মুলার

3
@ মিআইএনডিএফআরইএকে আমি মনে করি অ্যান্ড্রু বলতে যা বোঝায় তার অর্থ হ'ল প্রাক্কলনকারী সংখ্যালঘু শ্রেণীর নমুনাগুলি প্রতিলিপি করে, যাতে বিভিন্ন শ্রেণির নমুনা ভারসাম্যপূর্ণ হয়। এটি কেবল একটি অন্তর্নিহিত উপায়ে ওভারস্যাম্পলিং।
শান টিআইএন 13

8
@ এমআইএনডিএফআরইএকে এবং শন টিয়ান: এসভি-ভিত্তিক শ্রেণিবদ্ধরা যখন আপনি 'ভারসাম্যকর' ব্যবহার করেন তখন ছোট শ্রেণির বেশি নমুনা তৈরি করে না । এটি ছোট শ্রেণীর উপর করা ভুলকে আক্ষরিক অর্থে শাস্তি দেয়। অন্যথায় বলা একটি ভুল এবং বিভ্রান্তিকর, বিশেষত বড় ডেটাসেটগুলিতে যখন আপনি বেশি নমুনা তৈরি করতে সক্ষম নন। এই উত্তরটি সম্পাদনা করতে হবে।
পাবলো রিভাস

4
scikit-learn.org/dev/glossary.html#term-class- ওজন শ্রেণীর ওজনগুলি অ্যালগোরিদমের উপর নির্ভর করে পৃথকভাবে ব্যবহৃত হবে: লিনিয়ার মডেলগুলির জন্য (যেমন লিনিয়ার এসভিএম বা লজিস্টিক রিগ্রেশন), শ্রেণীর ওজনগুলি ক্ষতির ক্রিয়াকলাপকে পরিবর্তন করবে শ্রেণীর ওজন অনুসারে প্রতিটি নমুনার ক্ষতি হ্রাস করা। গাছ-ভিত্তিক অ্যালগরিদমগুলির জন্য, শ্রেণি ওজন বিভাজনের মানদণ্ডকে আবার ওজনযুক্ত করার জন্য ব্যবহৃত হবে। তবে খেয়াল করুন যে এই পুনরায় ভারসাম্য প্রতিটি শ্রেণীর নমুনার ওজনকে বিবেচনায় নেয় না।
প্রশান্ত

2

এটি কীভাবে কাজ করে তা বোঝার জন্য প্রথম উত্তরটি ভাল। তবে আমি বুঝতে চাইছিলাম অনুশীলনে এটি কীভাবে আমার ব্যবহার করা উচিত।

সারসংক্ষেপ

  • কোলাহল ছাড়া মাঝারিভাবে ভারসাম্যহীন ডেটার জন্য, শ্রেণি ওজন প্রয়োগের ক্ষেত্রে খুব বেশি পার্থক্য নেই
  • শব্দের সাথে মাঝারিভাবে ভারসাম্যহীন ডেটার জন্য এবং দৃ strongly়ভাবে ভারসাম্যহীন, শ্রেণি ওজন প্রয়োগ করা ভাল
  • PARAM class_weight="balanced"তোমার অবর্তমানে শালীন কাজ করে ম্যানুয়ালি নিখুত অনুপস্থিত
  • class_weight="balanced"আপনি আরও সত্য ঘটনা ক্যাপচার সঙ্গে (উচ্চতর সত্য প্রত্যাহার) কিন্তু আপনি মিথ্যা সতর্কতা পেতে আরও সম্ভবত (সত্য সত্য যথার্থ)
    • ফলস্বরূপ, সমস্ত মিথ্যা ধনাত্মকতার কারণে মোট% সত্য সত্যের চেয়ে বেশি হতে পারে
    • মিথ্যা অ্যালার্মগুলি যদি কোনও সমস্যা হয় তবে এইউসি আপনাকে এখানে বিভ্রান্ত করতে পারে
  • ভারসাম্যহীনতা% এর সিদ্ধান্তের প্রান্তিক পরিবর্তন করার দরকার নেই, এমনকি শক্তিশালী ভারসাম্যহীনতার জন্যও 0.5 রাখুন (বা আপনার প্রয়োজনের উপর নির্ভর করে কোথাও কোথাও)

বিশেষ দ্রষ্টব্য

আরএফ বা জিবিএম ব্যবহার করার সময় ফলাফলটি পৃথক হতে পারে। স্কলারনটি জিবিএমের class_weight="balanced" জন্য নয় তবে লাইটজিবিএম রয়েছেLGBMClassifier(is_unbalance=False)

কোড

# scikit-learn==0.21.3
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, classification_report
import numpy as np
import pandas as pd

# case: moderate imbalance
X, y = datasets.make_classification(n_samples=50*15, n_features=5, n_informative=2, n_redundant=0, random_state=1, weights=[0.8]) #,flip_y=0.1,class_sep=0.5)
np.mean(y) # 0.2

LogisticRegression(C=1e9).fit(X,y).predict(X).mean() # 0.184
(LogisticRegression(C=1e9).fit(X,y).predict_proba(X)[:,1]>0.5).mean() # 0.184 => same as first
LogisticRegression(C=1e9,class_weight={0:0.5,1:0.5}).fit(X,y).predict(X).mean() # 0.184 => same as first
LogisticRegression(C=1e9,class_weight={0:2,1:8}).fit(X,y).predict(X).mean() # 0.296 => seems to make things worse?
LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X).mean() # 0.292 => seems to make things worse?

roc_auc_score(y,LogisticRegression(C=1e9).fit(X,y).predict(X)) # 0.83
roc_auc_score(y,LogisticRegression(C=1e9,class_weight={0:2,1:8}).fit(X,y).predict(X)) # 0.86 => about the same
roc_auc_score(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X)) # 0.86 => about the same

# case: strong imbalance
X, y = datasets.make_classification(n_samples=50*15, n_features=5, n_informative=2, n_redundant=0, random_state=1, weights=[0.95])
np.mean(y) # 0.06

LogisticRegression(C=1e9).fit(X,y).predict(X).mean() # 0.02
(LogisticRegression(C=1e9).fit(X,y).predict_proba(X)[:,1]>0.5).mean() # 0.02 => same as first
LogisticRegression(C=1e9,class_weight={0:0.5,1:0.5}).fit(X,y).predict(X).mean() # 0.02 => same as first
LogisticRegression(C=1e9,class_weight={0:1,1:20}).fit(X,y).predict(X).mean() # 0.25 => huh??
LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X).mean() # 0.22 => huh??
(LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict_proba(X)[:,1]>0.5).mean() # same as last

roc_auc_score(y,LogisticRegression(C=1e9).fit(X,y).predict(X)) # 0.64
roc_auc_score(y,LogisticRegression(C=1e9,class_weight={0:1,1:20}).fit(X,y).predict(X)) # 0.84 => much better
roc_auc_score(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X)) # 0.85 => similar to manual
roc_auc_score(y,(LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict_proba(X)[:,1]>0.5).astype(int)) # same as last

print(classification_report(y,LogisticRegression(C=1e9).fit(X,y).predict(X)))
pd.crosstab(y,LogisticRegression(C=1e9).fit(X,y).predict(X),margins=True)
pd.crosstab(y,LogisticRegression(C=1e9).fit(X,y).predict(X),margins=True,normalize='index') # few prediced TRUE with only 28% TRUE recall and 86% TRUE precision so 6%*28%~=2%

print(classification_report(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X)))
pd.crosstab(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X),margins=True)
pd.crosstab(y,LogisticRegression(C=1e9,class_weight="balanced").fit(X,y).predict(X),margins=True,normalize='index') # 88% TRUE recall but also lot of false positives with only 23% TRUE precision, making total predicted % TRUE > actual % TRUE
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.