ما هو الصحيح algorthm عن logarthmic منحنى توزيع بين نقطتين ؟

StackOverflow https://stackoverflow.com/questions/604953

  •  03-07-2019
  •  | 
  •  

سؤال

لقد قرأت مجموعة من الدروس حول الطريقة الصحيحة لإنشاء لوغاريتمي توزيع تعريب الأوزان.معظمهم من مجموعة العلامات في الخطوات التالية.هذا يبدو سخيفا بعض الشيء بالنسبة لي, لذلك أنا وضعت بلدي خوارزمية بناء على ما قرأت حتى حيوي توزع العلامة الاعتماد على logarthmic منحنى بين العتبة القصوى.هنا هو جوهر الموضوع في بايثون:

from math import log
count = [1, 3, 5, 4, 7, 5, 10, 6]
def logdist(count, threshold=0, maxsize=1.75, minsize=.75):
    countdist = []
    # mincount is either the threshold or the minimum if it's over the threshold
    mincount = threshold<min(count) and min(count) or threshold
    maxcount = max(count)
    spread = maxcount - mincount
    # the slope of the line (rise over run) between (mincount, minsize) and ( maxcount, maxsize)
    delta = (maxsize - minsize) / float(spread)
    for c in count:
        logcount = log(c - (mincount - 1)) * (spread + 1) / log(spread + 1)
        size = delta * logcount - (delta - minsize)
        countdist.append({'count': c, 'size': round(size, 3)})
    return countdist

أساسا ، من دون لوغاريتمي حساب الفرد العد ، هذا من شأنه أن يولد الخط المستقيم بين نقطة (mincount, minsize) و (maxcount, maxsize).

الخوارزمية لا تقدير جيد على منحنى بين نقطتين ، لكنها تعاني من عيب واحد.على mincount هو حالة خاصة ، اللوغاريتم من وتنتج صفر.وهذا يعني حجم mincount يكون أقل من minsize.لقد حاولت طبخ أرقام لمحاولة حل هذه حالة خاصة ، ولكن لا يمكن أن يبدو للحصول على ذلك الحق.حاليا أنا مجرد علاج mincount بوصفها حالة خاصة إضافة "or 1"إلى logcount خط.

هل هناك المزيد من الصحيح خوارزمية رسم منحنى بين نقطتين ؟

تحديث Mar 3:إذا لم أكن مخطئا, أنا أخذ الدخول من العد ومن ثم توصيله إلى معادلة خطية.وضع وصف حالة خاصة وبعبارة أخرى ، y=lnx عند x=1, y=0.هذا هو ما يحدث في mincount.ولكن mincount لا يمكن أن يكون صفر العلامة لم تستعمل 0 مرات.

جرب الكود و المكونات في أرقام الخاصة بك إلى الاختبار.علاج mincount باعتبارها حالة خاصة هو جيد بالنسبة لي, لدي شعور بأنه سيكون أسهل من ما الفعلي حل هذه المشكلة.أنا فقط أشعر بأن هناك يجب أن أن حل هذا شخص ربما تصل إلى حل.

تحديث 6 أبريل:بسيطة جوجل البحث يتحول العديد من الدروس التي قرأتها ، ولكن هذا هو على الأرجح الأكثر اكتمالا سبيل المثال صعدت علامة الغيوم.

تحديث أبريل 28:ردا على antti.huima الحل:عندما رسوم بيانية ، منحنى الخاص بك خوارزمية يخلق تقع تحت خط بين نقطتين.لقد كنت تحاول أن توفق الأرقام ولكن لا يزال لا يمكن أن يبدو إلى الخروج مع وسيلة لقلب هذا المنحنى إلى الجانب الآخر من الخط.أنا أعتقد أنه إذا كانت وظيفة تم تغيير بعض أشكال اللوغاريتم بدلا من الأس أن تفعل بالضبط ما كنت بحاجة.هل هذا صحيح ؟ إذا كان الأمر كذلك, يمكن لأي شخص أن يشرح كيف يمكن تحقيق ذلك ؟

هل كانت مفيدة؟

المحلول

بفضل antti.huima ، إعادة التفكير في ما كنت تحاول القيام به.

أخذ طريقة حل المشكلة أريد معادلة حيث اللوغاريتم mincount يساوي معادلة خطية بين نقطتين.

weight(MIN) = ln(MIN-(MIN-1)) + min_weight
min_weight = ln(1) + min_weight

في حين أن هذا يعطيني نقطة انطلاق جيدة يجب أن يمر من خلال نقطة (ماكس max_weight).انها تسير في حاجة إلى ثابت:

weight(x) = ln(x-(MIN-1))/K + min_weight

حل ك نحصل على:

K = ln(MAX-(MIN-1))/(max_weight - min_weight)

لذا وضع كل الامور في كود بايثون:

from math import log
count = [1, 3, 5, 4, 7, 5, 10, 6]
def logdist(count, threshold=0, maxsize=1.75, minsize=.75):
    countdist = []
    # mincount is either the threshold or the minimum if it's over the threshold
    mincount = threshold<min(count) and min(count) or threshold
    maxcount = max(count)
    constant = log(maxcount - (mincount - 1)) / (maxsize - minsize)
    for c in count:
        size = log(c - (mincount - 1)) / constant + minsize
        countdist.append({'count': c, 'size': round(size, 3)})
    return countdist

نصائح أخرى

دعونا نبدأ مع رسم الخرائط الخاصة بك من تسجيل عد إلى حجم.هذا هو خطي الخرائط التي ذكرتها:

   size
    |
max |_____
    |   /
    |  /|
    | / |
min |/  |
    |   |
   /|   |
0 /_|___|____
    0   a

حيث min و max min و max الأحجام, و=log(maxcount)-ب.الخط y=mx+c حيث x=log(العد)-ب

من الرسم البياني ، يمكننا أن نرى أن التدرج ، م ، (maxsize-minsize)/أ.

نحن بحاجة x=0 في y=minsize ، بحيث سجل(mincount)-ب=0 -> b=log(mincount)

هذا يترك لنا التالية بايثون:

mincount = min(count)
maxcount = max(count)
xoffset = log(mincount)
gradient = (maxsize-minsize)/(log(maxcount)-log(mincount))
for c in count:
    x = log(c)-xoffset
    size = gradient * x + minsize

إذا كنت ترغب في التأكد من أن الحد الأدنى الاعتماد دائما على الأقل 1 ، استبدال السطر الأول مع:

mincount = min(count+[1])

التي بإلحاق 1 إلى قائمة العد قبل القيام مين.الشيء نفسه ينطبق على التأكد من maxcount هو دائما 1 على الأقل.وهكذا النهائي الخاص بك رمز لكل ما سبق هو:

from math import log
count = [1, 3, 5, 4, 7, 5, 10, 6]
def logdist(count, maxsize=1.75, minsize=.75):
    countdist = []
    mincount = min(count+[1])
    maxcount = max(count+[1])
    xoffset = log(mincount)
    gradient = (maxsize-minsize)/(log(maxcount)-log(mincount))
    for c in count:
        x = log(c)-xoffset
        size = gradient * x + minsize
        countdist.append({'count': c, 'size': round(size, 3)})
    return countdist

ما عليك هو أن لديك العلامات التي تهم من دقيقة كحد أقصى ؛ عتبة المسألة يمكن تجاهلها هنا لأنه يرقى إلى وضع كل عدد أقل من عتبة إلى عتبة القيمة وأخذ الحد الأدنى والحد الأقصى إلا بعد ذلك.

تريد تعيين علامة التهم إلى "الأوزان" ولكن في "لوغاريتمي الموضة" ، وهو ما يعني أساسا (كما فهمت) التالية.أولا الكلمات الدليلية مع الاعتماد ماكس على max_weight الوزن (في المثال الخاص بك ، 1.75):

weight(MAX) = max_weight

ثانيا الكلمات الدليلية مع العد دقيقة على min_weight الوزن (في المثال الخاص بك, 0.75):

weight(MIN) = min_weight

وأخيرا ، فإنه يحمل ذلك عندما عد انخفاض بنسبة 1 ، الوزن تتضاعف مع ثابت K < 1 ، مما يدل على شدة الانحدار في منحنى:

weight(x) = weight(x + 1) * K

حل هذا, نحصل على:

weight(x) = weight_max * (K ^ (MAX - x))

مع ملاحظة أن x = ماكس الأس صفر المضروب على اليمين يصبح 1.

الآن لدينا إضافية شرط أن الوزن(دقيقة) = min_weight و يمكننا حل:

weight_min = weight_max * (K ^ (MAX - MIN))

من التي نحصل

K ^ (MAX - MIN) = weight_min / weight_max

و أخذ اللوغاريتم على كلا الجانبين

(MAX - MIN) ln K = ln weight_min - ln weight_max

أي

ln K = (ln weight_min - ln weight_max) / (MAX - MIN)

الجانب الأيمن هو سلبي على النحو المطلوب ، لأن ك < 1.ثم

K = exp((ln weight_min - ln weight_max) / (MAX - MIN))

حتى الآن لديك صيغة لحساب K.بعد هذا يمكنك فقط التقدم بطلب للحصول على أي الاعتماد x بين MIN و MAX:

weight(x) = max_weight * (K ^ (MAX - x))

وانت القيام به.

على مقياس, كنت مجرد مؤامرة سجل من أرقام خطيا (وبعبارة أخرى, تظاهر بأنك التآمر خطيا ، ولكن خذ سجل الأرقام إلى أن تآمر الأولى).

صفر مشكلة لا يمكن حلها تحليليا--لديك لاختيار من أجل الحد الأدنى من حجم نطاق الخاص بك ، بغض النظر عن ما كنت لا تستطيع أن تصل إلى الصفر.إذا كنت ترغب في مؤامرة شيء في صفر الخيارات الخاصة بك بشكل تعسفي تعطيه من أجل الحد الأدنى من ضخامة الحجم ، أو إسقاطها.

ليس لدي الجواب بالضبط لكن أعتقد أنك تريد أن تبدو حتى Linearizing الهائل من البيانات.تبدأ من خلال حساب معادلة خط يمر من خلال نقطة واتخاذ سجل كلا الجانبين من المعادلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top