জ্যামিতিক গড়: একটি অন্তর্নির্মিত আছে?


106

আমি জ্যামিতিক গড়ের জন্য একটি অন্তর্নির্মিত খোঁজার চেষ্টা করেছি কিন্তু পারি নি।

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

যদি এখানে একটি না থাকে (যা আমি সন্দেহ করি তবে) এটি আমার।

gm_mean = function(a){prod(a)^(1/length(a))}

11
নেতিবাচক সংখ্যা এবং ওভারফ্লো সম্পর্কে যত্নবান। (ক) খুব দ্রুত অধীনে বা উপচে পড়বে। আমি এটি একটি বড় তালিকা ব্যবহার করে সময় দেওয়ার চেষ্টা করেছি এবং দ্রুত আপনার পদ্ধতির সাথে 1.4 বনাম এক্সপ (মানে (লগ (এক্স))) ব্যবহার করে ইনফ পেয়েছি; গোলাকার সমস্যাটি বেশ তীব্র হতে পারে।
ত্রিস্তান

আমি কেবল দ্রুত উপরে ফাংশনটি লিখেছি কারণ আমি নিশ্চিত যে এই কিউ পোস্ট করার 5 মিনিট পরে, কেউ আমাকে জিএম এর জন্য অন্তর্নির্মিত বলবে। সুতরাং কোনও অন্তর্নির্মিত নয় তাই আপনার মন্তব্যগুলির আলোকে পুনরায় কোড দেওয়ার জন্য সময় নেওয়া উপযুক্ত। আমার কাছ থেকে + 1
ডগ

1
আমি 9 বছর পরে এই জ্যামিতিক-গড় এবং অন্তর্নির্মিতটিকে ট্যাগ করেছি ।
smci

উত্তর:


77

আর-তে জ্যামিতিক গড় গণনা করার জন্য এখানে একটি ভেক্টরাইজড, শূন্য- এবং এনএ-সহনশীল কাজ রয়েছে the যেসব ক্ষেত্রে অ-ধনাত্মক মান রয়েছে সেগুলির জন্য meanজড়িত ভার্বোজ গণনা length(x)প্রয়োজনীয় isx

gm_mean = function(x, na.rm=TRUE){
  exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
}

na.rmএটি সঠিকভাবে কাজ করে তা নিশ্চিত করার জন্য @ বেন-বলকারকে পাস -থ্রো এবং @ গ্রেগরকে লক্ষ করার জন্য ধন্যবাদ Thanks

আমি মনে করি কিছু মন্তব্য NAতথ্য এবং শূন্যের মানগুলির একটি মিথ্যা-সমতার সাথে সম্পর্কিত । অ্যাপ্লিকেশনটিতে আমার মনে ছিল সেগুলি একই, তবে অবশ্যই এটি সাধারণত সত্য নয়। সুতরাং, আপনি যদি জিরোগুলির alচ্ছিক প্রচারগুলি অন্তর্ভুক্ত করতে চান এবং অপসারণের length(x)ক্ষেত্রে আলাদাভাবে চিকিত্সা NAকরতে চান তবে উপরের ফাংশনের জন্য নিম্নলিখিতটি কিছুটা দীর্ঘতর বিকল্প।

gm_mean = function(x, na.rm=TRUE, zero.propagate = FALSE){
  if(any(x < 0, na.rm = TRUE)){
    return(NaN)
  }
  if(zero.propagate){
    if(any(x == 0, na.rm = TRUE)){
      return(0)
    }
    exp(mean(log(x), na.rm = na.rm))
  } else {
    exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
  }
}

নোট করুন যে এটি কোনও নেতিবাচক মানগুলির জন্যও পরীক্ষা করে এবং আরও তথ্যপূর্ণ এবং যথাযথ NaNসম্মানের সাথে প্রত্যাবর্তন করে যে জ্যামিতিক গড়টি নেতিবাচক মানগুলির জন্য সংজ্ঞায়িত নয় (তবে জিরোদের জন্য)। মন্তব্যকারীরা যারা এই বিষয়ে আমার মামলায় স্থির থাকে তাদের ধন্যবাদ জানাই।


2
na.rmআর্গুমেন্ট হিসাবে উত্তীর্ণ হওয়ার কি ভাল হবে না (যেমন ব্যবহারকারীরা সিদ্ধান্ত নিতে দিন যে তারা এনএ-সহনশীল হতে চান কিনা, অন্যান্য আর সংক্ষিপ্ত ফাংশনগুলির সাথে সঙ্গতি রাখার জন্য)? আমি স্বয়ংক্রিয়ভাবে শূন্যগুলি বাদ দিয়ে ঘাবড়ে যাচ্ছি - আমি এটিকে একটি বিকল্প হিসাবে তৈরি করব।
বেন বলকার

1
na.rmএকটি বিকল্প হিসাবে পাস করার বিষয়ে আপনি সম্ভবত সঠিক । আমি আমার উত্তর আপডেট করব। শূন্যগুলি বাদ দেওয়ার ক্ষেত্রে জ্যামিতিক গড়টি জিরো সহ অ-ধনাত্মক মানের জন্য সংজ্ঞায়িত। উপরেরটি জ্যামিতিক গড়ের জন্য একটি সাধারণ সমাধান, যার মধ্যে শূন্যগুলি (বা এই ক্ষেত্রে সমস্ত জিরো) 1 এর ডামি মান দেওয়া হয়, যা পণ্যটির (বা সমতুল্য, লোগারিথমিক যোগফলে শূন্য) এর কোনও প্রভাব ফেলবে না।
পল ম্যাকমুরডি

* আমি অর্থ-ধনাত্মক মানগুলির জন্য একটি সাধারণ ফিক্স বোঝাতে চাইছি, জ্যামিতিক গড় যখন ব্যবহার করা হচ্ছে তখন শূন্যই সবচেয়ে সাধারণ।
পল ম্যাকমার্ডি

1
আপনার na.rmপাস-থ্রি কোডড হিসাবে কাজ করে না ... দেখুন gm_mean(c(1:3, NA), na.rm = T)। আপনাকে & !is.na(x)ভেক্টর সাবসেট থেকে অপসারণ করতে হবে , এবং যেহেতু প্রথম যুক্তিটি sumহ'ল ..., আপনাকে na.rm = na.rmনাম দিয়ে পাস করতে হবে , এবং আপনাকে কলটিতে ভেক্টর থেকে 0'গুলি এবং NA' গুলি বাদ দিতে হবে need length
গ্রেগর থমাস

2
সাবধান থেকো, কারণ xশুধুমাত্র শূন্য (গুলি) ধারণকারী মত x <- 0, exp(sum(log(x[x>0]), na.rm = TRUE)/length(x))দেয় 1জ্যামিতিক গড়, যা অর্থে দেখা যায় না জন্য।
আদাতুম

88

না, তবে কয়েকটি যারা যেমন এক লিখিত আছে হয় এখানে

আরেকটি সম্ভাবনা হ'ল এটি ব্যবহার করা:

exp(mean(log(x)))

এক্সপ (মানে (লগ (এক্স)) ব্যবহার করার আরেকটি সুবিধা হ'ল আপনি প্রচুর সংখ্যক দীর্ঘ তালিকা নিয়ে কাজ করতে পারেন যা প্রোড () ব্যবহার করে আরও সুস্পষ্ট সূত্র ব্যবহার করার সময় সমস্যাযুক্ত। নোট করুন যে প্রোড (ক) ^ (1 / দৈর্ঘ্য (ক)) এবং এক্সপ (মানে (লগ (ক))) একই উত্তর দেয়।
lukeholman

লিঙ্কটি ঠিক করা হয়েছে
প্যাট্রিকটি

15

আমরা সাইক প্যাকেজ ব্যবহার করতে পারি এবং জিওমেট্রিক.মিয়ান ফাংশনটি কল করতে পারি ।


1
psych::geometric.mean()
smci

এই ফাংশনগুলি সিরিজটি গ্রহণ করা উচিত এবং তাদের বৃদ্ধি নয়, অন্তত একটি বিকল্প হিসাবে, আমি বলব।
ক্রিস্টোফ হ্যাঙ্ক

12

দ্য

exp(mean(log(x)))

x এ 0 না থাকলে কাজ করবে। যদি তা হয় তবে লগটি -Inf (-ইনফিমেন্ট) তৈরি করবে যা সর্বদা 0 এর জ্যামিতিক গড়ের ফলাফল করে।

একটি সমাধান হ'ল গড় গণনা করার আগে -Inf মানটি মুছে ফেলা:

geo_mean <- function(data) {
    log_data <- log(data)
    gm <- exp(mean(log_data[is.finite(log_data)]))
    return(gm)
}

এটি করার জন্য আপনি ওয়ান-লাইনার ব্যবহার করতে পারেন তবে এর অর্থ লগটি দুবার গণনা করা যা অকার্যকর।

exp(mean(log(i[is.finite(log(i))])))

আপনি যখন করতে পারেন তখন
লগটিকে

উভয় পদ্ধতিরই গড়টি ভুল হয়ে যায়, কারণ sum(x) / length(x)যদি আপনি এক্স ফিল্টার করেন এবং তারপরে এটি পাস করেন তবে গড়ের জন্য ডিনোমিনেটরটি ভুল mean
পল ম্যাকমার্ডি

আমি মনে করি ফিল্টারিং একটি খারাপ ধারণা, যদি না আপনি স্পষ্টভাবে এটি না করতে চান (উদাহরণস্বরূপ যদি আমি একটি সাধারণ উদ্দেশ্যমূলক ফাংশন লিখি তবে আমি ফিল্টারিং ডিফল্ট করতাম না) - ঠিক আছে যদি এটি কোডের এক-বিভক্ত অংশ এবং আপনি ফিল্টারিং শূন্যগুলি কী কী আপনার সমস্যা (!) এর প্রেক্ষাপটে আসলে কী তা সম্পর্কে খুব সাবধানতার সাথে চিন্তা করেছিলেন
বেন বলকার

সংজ্ঞা অনুসারে শূন্যযুক্ত সংখ্যার সংখ্যার জ্যামিতিক গড়টি শূন্য হওয়া উচিত! math.stackexchange.com/a/91445/221143
ক্রিস

6

আমি মার্ক যা বলে ঠিক তাই ব্যবহার করি। এই পদ্ধতিতে, এমনকি টেপলি দিয়ে আপনি অন্তর্নির্মিত meanফাংশনটি ব্যবহার করতে পারেন , নিজের সংজ্ঞা দেওয়ার দরকার নেই! উদাহরণস্বরূপ, প্রতিটি গ্রুপের জ্যামিতিক উপাত্তের গণনা করতে $ মান:

exp(tapply(log(data$value), data$group, mean))

3

এই সংস্করণটি অন্যান্য উত্তরের চেয়ে বেশি বিকল্প সরবরাহ করে।

  • এটি ব্যবহারকারীর ফলাফল (বাস্তব) সংখ্যা নয় এবং যা উপলভ্য নয় ফলাফলগুলির মধ্যে পার্থক্য করতে দেয়। যদি negativeণাত্মক সংখ্যা উপস্থিত থাকে তবে উত্তরটি আসল সংখ্যা হবে না, তাই NaNফেরত দেওয়া হবে। যদি এটি সমস্ত NAমান হয় তবে ফাংশনটি NA_real_পরিবর্তিত হয়ে প্রতিফলিত করবে যে প্রকৃত মান আক্ষরিক অর্থে উপলব্ধ নয়। এটি একটি সূক্ষ্ম পার্থক্য, তবে একটি যা আরও শক্তিশালী ফলাফল পেতে পারে yield

  • প্রথম alচ্ছিক প্যারামিটারটি zero.rmশূন্য না করে ব্যবহারকারীকে জিরো আউটপুটকে প্রভাবিত করতে দেয় to যদি zero.rmসেট করা থাকে FALSEএবং etaএটিতে সেট করা হয় NA_real_(এর ডিফল্ট মান), শূন্যগুলির ফলাফল একের দিকে সঙ্কুচিত করার প্রভাব থাকে effect এর জন্য আমার কাছে কোন তাত্ত্বিক ন্যায়সঙ্গততা নেই - এটি শূন্যদের উপেক্ষা করার জন্য নয় বরং "কিছু করার" পক্ষে স্বয়ংক্রিয়ভাবে ফলাফলকে শূন্য করার সাথে জড়িত না বলে আরও বুদ্ধিমান মনে হয়েছে।

  • etaজিরোগুলি পরিচালনা করার একটি উপায় যা নিম্নলিখিত আলোচনায় অনুপ্রাণিত হয়েছিল: https://support.bioconductor.org/p/64014/

geomean <- function(x,
                    zero.rm = TRUE,
                    na.rm = TRUE,
                    nan.rm = TRUE,
                    eta = NA_real_) {
    nan.count <- sum(is.nan(x))
     na.count <- sum(is.na(x))
  value.count <- if(zero.rm) sum(x[!is.na(x)] > 0) else sum(!is.na(x))

  #Handle cases when there are negative values, all values are missing, or
  #missing values are not tolerated.
  if ((nan.count > 0 & !nan.rm) | any(x < 0, na.rm = TRUE)) {
    return(NaN)
  }
  if ((na.count > 0 & !na.rm) | value.count == 0) {
    return(NA_real_)
  }

  #Handle cases when non-missing values are either all positive or all zero.
  #In these cases the eta parameter is irrelevant and therefore ignored.
  if (all(x > 0, na.rm = TRUE)) {
    return(exp(mean(log(x), na.rm = TRUE)))
  }
  if (all(x == 0, na.rm = TRUE)) {
    return(0)
  }

  #All remaining cases are cases when there are a mix of positive and zero
  #values.
  #By default, we do not use an artificial constant or propagate zeros.
  if (is.na(eta)) {
    return(exp(sum(log(x[x > 0]), na.rm = TRUE) / value.count))
  }
  if (eta > 0) {
    return(exp(mean(log(x + eta), na.rm = TRUE)) - eta)
  }
  return(0) #only propagate zeroes when eta is set to 0 (or less than 0)
}

1
বিদ্যমান সমাধানগুলিতে এটি কীভাবে পৃথক / উন্নতি করে তা ব্যাখ্যা করতে আপনি কিছু বিশদ যুক্ত করতে পারেন? (আমি ব্যক্তিগতভাবে এ dplyrজাতীয় ইউটিলিটির জন্য প্রয়োজনীয় না হলে ভারী নির্ভরতা যুক্ত করতে চাই না ...)
বেন বলকার

আমি সম্মত হই, case_whenএসগুলি কিছুটা নির্বোধ ছিল, তাই আমি তাদের এবং ifএস এর পক্ষে নির্ভরতা সরিয়েছি । আমি কিছু বিশদ বিবরণ প্রদান।
ক্রিস কফি

1
আমি আপনার পরবর্তী ধারণাটি নিয়ে গিয়েছিলাম এবং তিনটি r `` .rm`` পরামিতিগুলিকে সারিবদ্ধ nan.rmকরতে ডিফল্টটি পরিবর্তন করেছি TRUE
ক্রিস কফি

1
অন্য একটি স্টাইলিস্টিক নিটপিক। ifelseভেক্টরাইজেশন জন্য ডিজাইন করা হয়েছে। একক শর্ত যাচাই করার সাথে সাথে এটি ব্যবহার করা আরও মূর্তিমান হবেvalue.count <- if(zero.rm) sum(x[!is.na(x)] > 0) else sum(!is.na(x))
গ্রেগোর টমাস

এটি দেখতেও সুন্দর ifelseলাগছে। পরিবর্তন হয়েছে। ধন্যবাদ!
ক্রিস কফি


3

আপনার ডেটাতে মানগুলি অনুপস্থিত থাকলে, এটি বিরল ঘটনা নয়। আপনার আরও একটি যুক্তি যুক্ত করা দরকার।

আপনি নিম্নলিখিত কোড চেষ্টা করতে পারেন:

exp(mean(log(i[ is.finite(log(i)) ]), na.rm = TRUE))

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.