Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

Ruby NLP:การวิเคราะห์ N-gram เพื่อความสนุกและผลกำไร

คุณจะทำอย่างไรถ้าคุณมีข้อความจำนวนมากและต้องการแยกความหมายออกจากข้อความนั้น

การเริ่มต้นที่ดีคือแบ่งข้อความออกเป็น n-grams .

นี่คือคำอธิบาย :

ในสาขาภาษาศาสตร์เชิงคำนวณและความน่าจะเป็น n-gram คือลำดับที่ต่อเนื่องกันของ n รายการจากลำดับข้อความที่กำหนด – วิกิพีเดีย

ตัวอย่างเช่น :

หากเราใช้คำว่า “สวัสดี สบายดีไหม” จากนั้นยูนิแกรม (ngrams ขององค์ประกอบหนึ่ง) จะเป็น:"Hello", "there", "how", "are", "you" และ bigrams (ngrams ของสององค์ประกอบ):["Hello", "there"], ["there", "how"], ["how", "are"], ["are", "you"] .

หากคุณเรียนรู้ได้ดีขึ้นด้วยรูปภาพ นี่คือรูปภาพ:

Ruby NLP:การวิเคราะห์ N-gram เพื่อความสนุกและผลกำไร

ตอนนี้เรามาดูกันว่าคุณจะใช้สิ่งนี้ใน Ruby ได้อย่างไร!

กำลังดาวน์โหลดข้อมูลตัวอย่าง

ก่อนที่เราจะทำมือสกปรก เราต้องการข้อมูลตัวอย่างก่อน

หากคุณไม่มีงานใดๆ คุณสามารถดาวน์โหลด Wikipedia หรือบทความในบล็อกได้ ในกรณีนี้ ฉันตัดสินใจดาวน์โหลดบันทึก IRC บางรายการจากช่องของ #ruby freenode

สามารถดูบันทึกได้ที่นี่ :

irclog.whitequark.org/ruby

หมายเหตุเกี่ยวกับรูปแบบข้อมูล :

หากไม่มีเวอร์ชันข้อความธรรมดาของทรัพยากรที่คุณต้องการวิเคราะห์ คุณสามารถใช้ Nokogiri เพื่อแยกวิเคราะห์หน้าและดึงข้อมูลได้

บันทึก irc มีอยู่ในข้อความธรรมดาโดยต่อท้าย .txt ที่ส่วนท้ายของ URL ดังนั้นเราจะใช้ประโยชน์จากสิ่งนั้น

ชั้นเรียนนี้จะดาวน์โหลดและบันทึกข้อมูลให้เรา:

require 'restclient'

class LogParser
  LOG_DIR  = 'irc_logs'

  def initialize(date)
    @date = date
    @log_name = "#{LOG_DIR}/irc-log-#{@date}.txt"
  end

  def download_page(url)
    return log_contents if File.exist? @log_name
    RestClient.get(url).body
  end

  def save_page(page)
    File.open(@log_name, "w+") { |f| f.puts page }
  end

  def log_contents
    File.readlines(@log_name).join
  end

  def get_messages
    page = download_page("https://irclog.whitequark.org/ruby/#{@date}.txt")
    save_page(page)
    page
  end
end

log = LogParser.new("2015-04-15")
msg = log.get_messages

นี่เป็นชั้นเรียนที่ค่อนข้างตรงไปตรงมา

เราใช้ RestClient เป็นไคลเอนต์ HTTP ของเรา จากนั้นเราบันทึกผลลัพธ์ในไฟล์ ดังนั้นเราจึงไม่ต้องร้องขอหลายครั้งในขณะที่เราทำการแก้ไขโปรแกรมของเรา

วิเคราะห์ข้อมูล

เมื่อเรามีข้อมูลแล้ว เราก็สามารถวิเคราะห์ได้

นี่คือคลาส Ngram ง่ายๆ

ในคลาสนี้เราใช้เมธอด Array#each_cons ซึ่งสร้าง ngrams

เนื่องจากวิธีนี้ส่งคืน Enumerator เราต้องเรียก to_a เพื่อรับ Array .

class Ngram
  def initialize(input)
    @input = input
  end

  def ngrams(n)
    @input.split.each_cons(n).to_a
  end
end

จากนั้นเราก็รวมทุกอย่างเข้าด้วยกันโดยใช้ลูป Hash#merge! &Enumerable#sort_by .

ถูกใจสิ่งนี้ :

# Filter words that appear less times than this
MIN_REPETITIONS = 20

total = {}

# Get the logs for the first 15 days of the month and return the bigrams
(1..15).each do |n|
  day = '%02d' % [n]
  total.merge!(get_trigrams_for_date "2015-04-#{day}") { |k, old, new| old + new }
end

# Sort in descending order
total = total.sort_by { |k, v| -v }.reject { |k, v| v < MIN_REPETITIONS }

total.each { |k, v| puts "#{v} => #{k}" }

หมายเหตุ:get_trigrams_for_date เมธอดไม่ได้อยู่ที่นี่เพื่อความกระชับ แต่คุณสามารถหาได้ใน github

นี่คือสิ่งที่ผลลัพธ์ออกมา :

112 => i want to
83  => link for more
82  => is there a
71  => you want to
66  => i don't know
66  => i have a
65  => i need to

อย่างที่คุณเห็น อยากทำสิ่งต่างๆ เป็นที่นิยมอย่างมากใน #ruby 🙂

บทสรุป

ตอนนี้ถึงตาคุณแล้ว!

เปิดโปรแกรมแก้ไขของคุณและเริ่มเล่นกับการวิเคราะห์ n-gram อีกวิธีหนึ่งในการดูการทำงานของ n-grams คือ Google Ngram Viewer

การประมวลผลภาษาธรรมชาติ (NLP) อาจเป็นหัวข้อที่น่าสนใจ Wikipedia มีภาพรวมที่ดีของหัวข้อ

คุณสามารถค้นหาโค้ดที่สมบูรณ์สำหรับโพสต์นี้ได้ที่นี่:https://github.com/matugm/ngram-analysis/blob/master/irc_histogram.rb