Class: Wuclan::Models::UserMetrics

Inherits:
Object
  • Object
show all
Defined in:
lib/wuclan/metrics/user_metrics_basic.rb,
lib/wuclan/metrics/user_metrics.rb

Overview

[

#
[:fo_day,            Float],      #   x       Followers accumulated / day
[:fr_day,            Float],      #   x       Friends   accumulated / day
[:tw_day,            Float],      #   x       Tweets    sent / day
[:fv_day,            Float],      #   x       Favorites accumulated / day
#
[:at_in_with,        Integer],    #       g   Users Atsigning you
[:at_out_with,       Integer],    #       g
[:rt_in_with,        Integer],    #       g   Users Retweeting you
[:rt_out_with,       Integer],    #       g
[:fv_in_with,        Integer],    #       g   Favorites by others of your tweets, with
[:fv_out_with,       Integer],    #     c     Number of users who Favorited you
#
[:at_tw_out,         Float],      #       g   Atsigns  out per tweet out
[:rt_tw_out,         Float],      #       g   Retweets out per tweet out
[:rt_at_out,         Float],      #       g   Retweets out per  atsign out seen
[:at_in_tw_out,      Float],      #       g   Atsigns  in  per tweet out
[:rt_in_tw_out,      Float],      #       g   Retweets in  per tweet out
[:rt_at_in,          Float],      #       g   Retweets in  seen per atsign in  seen
#
[:reach,             Integer],    #   x       Reach:   (your msgs/day) * |n1|

] [

  [:scraped_at,        Bignum],
  [:part_scraped_at,   Bignum],     #           Date of last user partial update
  #
  [:fo_coverage,       Float],      #     c     Friends seen   / known to exist
  [:fr_coverage,       Float],      #     c     Followers seen / known to exist
  [:tw_coverage,       Float],      #     c     Tweets seen    / known to exist
  [:fv_coverage,       Float],      #     c     Favorites seen / known to exist
  #
  [:fo_scraped_at,     Integer],      #     c     How long since your followers graph record was scraped
  [:fr_scraped_at,     Integer],      #     c     How long since your friends   graph record was scraped
  [:fv_scraped_at,     Integer],      #     c     How long since your favorites graph record was scraped
  #
]

Constant Summary collapse

SCRAPING_DAY_ZERO_STR =

# [:fo_sampled, Integer , “How many followers have we sampled”, ], # c [:fr_sampled, Integer , “How many friend have we sampled”, ], # c [:fo_coverage, Float , “Friends sampled / known to exist”, ], # c [:fr_coverage, Float , “Followers sampled / known to exist”, ], # c [:tw_coverage, Float , “Tweets sampled / known to exist”, ], # c [:fv_coverage, Float , “Favorites sampled / known to exist”, ], # c # [:scrape_age_fo, Integer , “How long since your followers graph record was scraped”, ], # c [:scrape_age_fr, Integer , “How long since your friends graph record was scraped”, ], # c [:scrape_age_fv, Integer , “How long since your favorites graph record was scraped”, ], # c

[:age, Integer , “Days between creation and now”, ], # x [:duration, Integer , “Days between last scrape and creation”, ], # x [:age_user_scrape, Integer , “How long since your user record was scraped”, ], # x

20081201000000
SCRAPING_DAY_ZERO =
DateTime.parse_safely(SCRAPING_DAY_ZERO_STR.to_s)
SINCE_DAY_ZERO =
DateTime.now - SCRAPING_DAY_ZERO

Instance Method Summary collapse

Instance Method Details

#adopt_graph_metrics(user_graph_metrics) ⇒ Object

From simple graph metrics



281
282
283
# File 'lib/wuclan/metrics/user_metrics.rb', line 281

def adopt_graph_metrics user_graph_metrics
  self.merge! user_graph_metrics
end

#adopt_scraping_metrics(usm) ⇒ Object



263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/wuclan/metrics/user_metrics.rb', line 263

def adopt_scraping_metrics usm
  [
    [:friends_ids,   :scrape_age_fr, ],
    [:followers_ids, :scrape_age_fo, ],
    [:favorites,     :scrape_age_fv, ],
  ].each do |context, attr|
    dt = usm.get context, :scraped_at
    next if (usm.get(context, :successes).to_i < 1) || (dt.blank?)
    # fudge bogus date records
    dt = (dt.to_i < SCRAPING_DAY_ZERO_STR) ? SCRAPING_DAY_ZERO : DateTime.parse_safely(dt)
    next if dt.blank?
    self[attr] = now - dt
  end
end

#adopt_tweet_metrics(user_tweet_metrics) ⇒ Object

User’s Tweets – from UserTweetMetrics



288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/wuclan/metrics/user_metrics.rb', line 288

def adopt_tweet_metrics metrics
  case metrics
  when UserTweetMetrics
    self.tw_sampled   = metrics.tw_sampled
    self.last_tw_at   = DateTime.parse_safely(metrics.last_tw_at)
    self.tw_recent    = metrics.tw_recent
  when UserHashtagMetrics
    self.hashtag_sampled     = metrics.tw_sampled
  when UserTweetUrlMetrics
    self.tweet_url_sampled   = metrics.tw_sampled
  else raise "Can't adopt #{metrics}" end
end

#adopt_user(user) ⇒ Object



239
240
241
242
243
244
# File 'lib/wuclan/metrics/user_metrics.rb', line 239

def adopt_user user
  @user_adopted = true
  self.merge! user
  self.created_at = DateTime.parse_safely(created_at)
  self.scraped_at = DateTime.parse_safely(scraped_at)
end

#adopt_user_partial(user_partial) ⇒ Object



252
253
254
255
256
257
258
# File 'lib/wuclan/metrics/user_metrics.rb', line 252

def adopt_user_partial user_partial
  user_scraped_at    = self.scraped_at
  self.merge! user_partial
  # restore scraped dates
  self.part_scraped_at = DateTime.parse_safely(user_partial.scraped_at)
  self.scraped_at      = user_scraped_at
end

#ageObject

duration –



346
347
348
349
350
# File 'lib/wuclan/metrics/user_metrics.rb', line 346

def age()
  return @age if @age
  return unless crat
  @age             = ( now - crat ).to_i
end

#cratObject



326
327
328
# File 'lib/wuclan/metrics/user_metrics.rb', line 326

def crat
  @crat      ||= created_at
end

#durationObject



351
352
353
354
355
356
# File 'lib/wuclan/metrics/user_metrics.rb', line 351

def duration()
  return @duration if @duration
  return unless crat && (scat || part_scat)
  scat_latest = [scat, part_scat].compact.max
  @duration        = ( scat_latest - crat ).to_i
end

#favourites_countObject



308
# File 'lib/wuclan/metrics/user_metrics.rb', line 308

def favourites_count()    self.fv end

#favourites_count=(fv) ⇒ Object



304
# File 'lib/wuclan/metrics/user_metrics.rb', line 304

def favourites_count=(fv) self.fv = fv.to_i end

#fix!Object



205
206
207
208
209
210
211
212
213
# File 'lib/wuclan/metrics/user_metrics.rb', line 205

def fix!
  get_tw_day_bin
  get_tw_day_recent_bin
  get_fo_bin
  get_fr_bin
  get_nbhd_size_bin
  get_nbhd_bal_bin
  get_active
end

#followers_countObject



305
# File 'lib/wuclan/metrics/user_metrics.rb', line 305

def followers_count()     self.fo end

#followers_count=(fo) ⇒ Object



301
# File 'lib/wuclan/metrics/user_metrics.rb', line 301

def followers_count=( fo) self.fo = fo.to_i end

#friends_countObject



306
# File 'lib/wuclan/metrics/user_metrics.rb', line 306

def friends_count()       self.fr end

#friends_count=(fr) ⇒ Object



302
# File 'lib/wuclan/metrics/user_metrics.rb', line 302

def friends_count=(   fr) self.fr = fr.to_i end

#get_activeObject



425
426
427
428
429
430
431
# File 'lib/wuclan/metrics/user_metrics.rb', line 425

def get_active()
  exists        = (fo && fr && tw) or return
  tweets        = tw >= 3
  has_followers = fo > 15
  has_nbhd      = (fo >= 3) && (fr >= 2)
  self.active = ( exists && tweets && (has_followers || has_nbhd) ) ? 1 : 0
end

#get_ageObject

duration –



200
201
202
203
# File 'lib/wuclan/metrics/user_metrics_basic.rb', line 200

def get_age()
  return unless crat
  self.age             = ( now - crat ).to_i
end

#get_age_last_twObject



208
209
210
211
# File 'lib/wuclan/metrics/user_metrics_basic.rb', line 208

def get_age_last_tw()
  return unless twat
  self.age_last_tw     = ( now - twat ).to_i
end

#get_age_user_scrapeObject



361
362
363
364
# File 'lib/wuclan/metrics/user_metrics.rb', line 361

def get_age_user_scrape()
  return unless scat
  self.age_user_scrape = ( now - scat ).to_i
end

#get_at_in_tw_outObject



396
# File 'lib/wuclan/metrics/user_metrics.rb', line 396

def get_at_in_tw_out() self.at_in_tw_out = (at_in_sampled.to_f  / tw_sampled.to_f)     unless (tw_sampled.to_i == 0) || (! at_in_sampled)    end

#get_at_tw_outObject

Conversational metrics:

favorites, @atsigns and RT's per tweet, in and out
 RT per @atsign, in and out


393
# File 'lib/wuclan/metrics/user_metrics.rb', line 393

def get_at_tw_out()    self.at_tw_out    = (at_out_sampled.to_f / tw_sampled.to_f)     unless (tw_sampled.to_i == 0) || (! at_out_sampled)  end

#get_created_onObject



322
323
324
# File 'lib/wuclan/metrics/user_metrics.rb', line 322

def get_created_on
  self.created_on = self.created_at
end

#get_durationObject



204
205
206
207
# File 'lib/wuclan/metrics/user_metrics_basic.rb', line 204

def get_duration()
  return unless crat && scat
  self.duration        = ( scat - crat ).to_i
end

#get_fo_binObject

Bins



419
# File 'lib/wuclan/metrics/user_metrics.rb', line 419

def get_fo_bin()        self.fo_bin        = FoBin[fo]   end

#get_fo_coverageObject

Coverage: how many seen vs. how many known to exist.



383
# File 'lib/wuclan/metrics/user_metrics.rb', line 383

def get_fo_coverage()  self.fo_coverage = (fo_sampled.to_f     / fo) unless (fo.to_i == 0)  end

#get_fo_dayObject

Per-day metrics

Should possibly use duration but need to worry about which one.



222
# File 'lib/wuclan/metrics/user_metrics_basic.rb', line 222

def get_fo_day()    self.fo_day = (fo.to_f / age)  unless (age.to_i == 0) end

#get_fo_weekObject

Per-day metrics

Should possibly use duration but need to worry about which one.



371
# File 'lib/wuclan/metrics/user_metrics.rb', line 371

def get_fo_week()    self.fo_week = 7 * (fo.to_f / duration)     unless (duration.to_i == 0) || (!fo) end

#get_fr_binObject



420
# File 'lib/wuclan/metrics/user_metrics.rb', line 420

def get_fr_bin()        self.fr_bin        = FrBin[fr]   end

#get_fr_coverageObject



384
# File 'lib/wuclan/metrics/user_metrics.rb', line 384

def get_fr_coverage()  self.fr_coverage = (fr_sampled.to_f     / fr) unless (fr.to_i == 0)  end

#get_fr_dayObject



223
# File 'lib/wuclan/metrics/user_metrics_basic.rb', line 223

def get_fr_day()    self.fr_day = (fr.to_f / age)  unless (age.to_i == 0) end

#get_fr_foObject



226
# File 'lib/wuclan/metrics/user_metrics_basic.rb', line 226

def get_fr_fo()     self.fr_fo  = (fr.to_f / fo)        unless (fo.to_i       == 0) end

#get_fr_weekObject



372
# File 'lib/wuclan/metrics/user_metrics.rb', line 372

def get_fr_week()    self.fr_week = 7 * (fr.to_f / age)          unless (age.to_i == 0)      || (!fr) end

#get_fv_coverageObject



386
# File 'lib/wuclan/metrics/user_metrics.rb', line 386

def get_fv_coverage()  self.fv_coverage = (fv_out_sampled.to_f / fv) unless (fv.to_i == 0)  end

#get_fv_dayObject



225
# File 'lib/wuclan/metrics/user_metrics_basic.rb', line 225

def get_fv_day()    self.fv_day = (fv.to_f / age)  unless (age.to_i == 0) end

#get_fv_moObject



374
# File 'lib/wuclan/metrics/user_metrics.rb', line 374

def get_fv_mo()      self.fv_mo   = 30.4368499 * (fv.to_f / age) unless (age.to_i == 0)      || (!fv) end

#get_last_tw_ageObject



357
358
359
360
# File 'lib/wuclan/metrics/user_metrics.rb', line 357

def get_last_tw_age()
  return unless twat && crat
  self.last_tw_age     = ( crat - twat ).to_i
end

#get_nbhd_balObject



316
317
318
319
320
321
# File 'lib/wuclan/metrics/user_metrics.rb', line 316

def get_nbhd_bal
  return unless fr && fo && ((fr.to_i > 0) || (fo.to_i > 0))
  self.nbhd_bal = ((fr > fo) ?
    (      (0.5 * fo.to_f / fr.to_f)) :
    (1.0 - (0.5 * fr.to_f / fo.to_f)) )
end

#get_nbhd_bal_binObject



422
# File 'lib/wuclan/metrics/user_metrics.rb', line 422

def get_nbhd_bal_bin()  self.nbhd_bal_bin  = NbhdBalBin[nbhd_bal]    end

#get_nbhd_sizeObject

Larger of fr and fo



312
313
314
# File 'lib/wuclan/metrics/user_metrics.rb', line 312

def get_nbhd_size
  self.nbhd_size = [fr, fo].compact.max
end

#get_nbhd_size_binObject



421
# File 'lib/wuclan/metrics/user_metrics.rb', line 421

def get_nbhd_size_bin() self.nbhd_size_bin = NbhdSizeBin[nbhd_size]  end

#get_reachObject

Reach:

(your msgs/day) * |n1|

How many of your messages/day might get read. Audience Share (tw_out_share) is a better measure of your impact.



410
411
412
413
# File 'lib/wuclan/metrics/user_metrics.rb', line 410

def get_reach()
  self.get_tw_day or return
  self.reach = (tw_day.to_f * fo)
end

#get_rt_at_inObject



400
# File 'lib/wuclan/metrics/user_metrics.rb', line 400

def get_rt_at_in()     self.rt_at_in     = (rt_in_sampled.to_f  / at_in_sampled.to_f)  unless (at_in_sampled.to_i == 0)  || (! rt_in_sampled)    end

#get_rt_at_outObject



399
# File 'lib/wuclan/metrics/user_metrics.rb', line 399

def get_rt_at_out()    self.rt_at_out    = (rt_out_sampled.to_f / at_out_sampled.to_f) unless (at_out_sampled.to_i == 0) || (! rt_out_sampled)   end

#get_rt_in_tw_outObject



397
# File 'lib/wuclan/metrics/user_metrics.rb', line 397

def get_rt_in_tw_out() self.rt_in_tw_out = (rt_in_sampled.to_f  / tw_sampled.to_f)     unless (tw_sampled.to_i == 0) || (! rt_in_sampled)    end

#get_rt_tw_outObject



394
# File 'lib/wuclan/metrics/user_metrics.rb', line 394

def get_rt_tw_out()    self.rt_tw_out    = (rt_out_sampled.to_f / tw_sampled.to_f)     unless (tw_sampled.to_i == 0) || (! rt_out_sampled)    end

#get_tw_coverageObject



385
# File 'lib/wuclan/metrics/user_metrics.rb', line 385

def get_tw_coverage()  self.tw_coverage = (tw_sampled.to_f     / tw) unless (tw.to_i == 0)  end

#get_tw_dayObject



373
# File 'lib/wuclan/metrics/user_metrics.rb', line 373

def get_tw_day()     self.tw_day  =     (tw.to_f / duration)     unless (duration.to_i == 0) || (!tw) end

#get_tw_day_binObject



423
# File 'lib/wuclan/metrics/user_metrics.rb', line 423

def get_tw_day_bin()    self.tw_day_bin    = TwDayBin[tw_day]      end

#get_tw_day_recentObject

def get_fr_fo() self.fr_fo = (fr.to_f / fo) unless (fo.to_i == 0) end



376
377
378
# File 'lib/wuclan/metrics/user_metrics.rb', line 376

def get_tw_day_recent()
  self.tw_day_recent = TWEETS_SAMPLED_FRACTION * (tw.to_f / SINCE_DAY_ZERO) unless (! tw)
end

#get_tw_day_recent_binObject



424
# File 'lib/wuclan/metrics/user_metrics.rb', line 424

def get_tw_day_recent_bin()  self.tw_day_recent_bin  = TwDayRecentBin[tw_day_recent]   end

#nowObject



338
339
340
# File 'lib/wuclan/metrics/user_metrics.rb', line 338

def now
  @now       ||= DateTime.now
end

#part_scatObject



332
333
334
# File 'lib/wuclan/metrics/user_metrics.rb', line 332

def part_scat
  @part_scat ||= part_scraped_at
end

#protected?Boolean

Returns:

  • (Boolean)


232
233
234
# File 'lib/wuclan/metrics/user_metrics.rb', line 232

def protected?
  protected.to_i == 1
end

#scatObject



329
330
331
# File 'lib/wuclan/metrics/user_metrics.rb', line 329

def scat
  @scat      ||= scraped_at
end

#statuses_countObject



307
# File 'lib/wuclan/metrics/user_metrics.rb', line 307

def statuses_count()      self.tw end

#statuses_count=(tw) ⇒ Object



303
# File 'lib/wuclan/metrics/user_metrics.rb', line 303

def statuses_count=(  tw) self.tw = tw.to_i end

#to_aObject

Fix formatting as we flatten



218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/wuclan/metrics/user_metrics.rb', line 218

def to_a
  members.zip(mtypes).map do |member, type|
    val = self[member]
    next if val.nil?
    case
    when member.to_sym == :id     then "%010d"  % val.to_i
    when type == Float            then "%f"  % val.to_f
    when type == Integer          then "%7d"    % val.to_i
    when type == DateTime         then val.strftime("%Y/%m/%d %H:%M:%S")
    when type == Date             then val.strftime("%Y/%m/%d")
    else val
    end
  end
end

#twatObject



335
336
337
# File 'lib/wuclan/metrics/user_metrics.rb', line 335

def twat
  @twat      ||= last_tw_at
end

#user_adopted?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/wuclan/metrics/user_metrics_basic.rb', line 115

def user_adopted?
  @user_adopted
end