Днес реших да разбера кои са най-често срещаните български думи в българската Wikipedia. И разбрах ;) По-нататък в поста ще ви обясня как съм направил анализа и по-интересното кои са най-срещаните букви и думи. Освен списък с честотата на срещане на отделните букви, има и списък с първите 100 най-срещани думи (заедно с броя срещания) и списък с 550-те най-срещани думи (без броя им). Добавил съм и кода на програмата, обяснение за работата му, както и текстов файл, съдържащ всичките намерени думи, заедно с броя на срещанията им измежду статиите на българската Wikipedia.
Анализирани са 220681 статии, в тях са намерени общо 46707608 думи, съдържащи само български букви, от които думи 714876 различни. Броят букви в тези думи общо е 259452643, което прави средно по 5.55 букви на 1 българска дума. Данните са актуални към 20-ти август 2011 г. Трите най-често срещани думи са „на“, „и“ и „в“. Десетте най-често срещани букви са: „а“, „и“, „е“, „о“, „н“, „т“, „р“, „с“, „л“ и „в“.
Предимно с мерак. Е, и малко код ;) Първо, за да не пиша web crawler, който да обикаля като луд по страниците на Wikipedia, направих кратък research и открих нещо много интересно. Wikipedia си правят редовно backup на всичките данни, и голямата част от тези бекъпи са публични. Кое не е публично? Ами, потребителските данни, например. Всичко останало свързано със съдържанието е абсолютно публично, дъмпнато от базата данни, експортнато в XML формат, компресирано, бекъпнато и шернато (все хубави български думички). Тези бекъпи можете да намерите тук. И така дъмпа, който съм използвал за анализа е от „2011-08-19 22:37:35“ и по-специално „Articles, templates, image descriptions, and primary meta-pages.“, съдържащо последните версии на статиите в българската Wikipedia, които са точно 220681 на брой. Ето и директен линк към файла: pages-articles.xml.bz2 (Размер: 147.4 MB). Както споменах, в този архив се намира XML файл. За обработката на файла използвах любимия ми C#. Драснах едно конзолно приложение, което използва XmlTextReader за парсване на данните от XML файла. Защо избрах XmlTextReader? Защото той обработва файла елемент по елемент и поради тази причина работи доста добре с огромни файлове, а все пак XML файлът е над 1 GB след разархивиране. За броене на думите се наложи да си напиша клас WordsDictionary, който всъщност представлява една обвивка на класа Dictionary<string, int>. От всяка дума се махат всички символи, които не са букви, след това се отделят само думите, които съдържат само букви от българската азбука. Всички думи са с малки букви, за да може еднакви думи, започващи с главна буква и такива с малка да се считат за една и съща дума. И едно оправдание: въобще не претендирам кода да е качествен, все пак целта да го напиша беше да видя резултата от работата му, а не толкова да мога да го преизползвам. И така ето съдържанието на Main метода:
class Program { static void Main(string[] args) { WordsDictionary words = new WordsDictionary(); using (XmlTextReader reader = new XmlTextReader("bgwiki-20110819-pages-articles.xml")) { while (reader.Read()) { if (reader.Name == "title" || reader.Name == "text") { string text = reader.ReadInnerXml(); words.AddWords(text); } } } Console.WriteLine("Parsing ready!"); words.ExportToTextFile("words.txt"); Console.WriteLine("Exporting ready!"); Console.ReadLine(); } }
А ето и съдържанието на класа WordsDictionary.
class WordsDictionary { Dictionary< string, int > words = new Dictionary< string, int >(); public void ExportToTextFile(string fileName) { using (StreamWriter sw = new StreamWriter(fileName)) { var sortedList = words.OrderByDescending(x => x.Value); foreach (var item in sortedList) { sw.WriteLine("{0} {1}", item.Key, item.Value); } } } private void AddWord(string word) { if (string.IsNullOrWhiteSpace(word) || !word.ContainsOnlyCyrilicChars()) { return; } //Console.WriteLine(word); if (words.ContainsKey(word)) { words[word]++; } else { words.Add(word, 1); } } public void AddWords(string text) { text = text.HTMLDecodeSpecialChars(); StringBuilder sb = new StringBuilder(text.Length); foreach (char ch in text) { if (char.IsLetter(ch)) { sb.Append(ch); } else { sb.Append(' '); } } text = sb.ToString().ToLower(); MatchCollection collection = Regex.Matches(text, @"[\S]+"); foreach (Match item in collection) { this.AddWord(item.Value.Trim()); } } }
Може би ще ви е от полза и статичния клас, в който си дефинирам два разширяващи метода на класа String, които използвам в класа WordsDictionary.
public static class StringExtensions { public static string HTMLDecodeSpecialChars(this string s) { return HttpUtility.HtmlDecode(s); } public static bool ContainsOnlyCyrilicChars(this string word) { char[] bgletters = { 'а', 'б', 'в', 'г', 'д', 'е', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ь', 'ю', 'я' }; foreach (var ch in word) { if (!bgletters.Contains(ch)) return false; } return true; } }
Още един анализ ми хрумна в последствие. Да видя честотата на срещане на българските букви в Wikipedia, което до голяма степен ми дава ясна представа за честотата на срещането на буквите в българския език като цяло. И така ако се интересувате кои са най-често срещаните букви, ето списъка с нашите любими 30 букви, заедно с броя и процентното съотношение на срещанията им:
а => 29403401 пъти => 11,33%
и => 26352009 пъти => 10,16%
е => 22625006 пъти => 8,72%
о => 21607305 пъти => 8,33%
н => 18812860 пъти => 7,25%
т => 18343878 пъти => 7,07%
р => 16328288 пъти => 6,29%
с => 13654518 пъти => 5,26%
л => 10384543 пъти => 4,00%
в => 9972137 пъти => 3,84%
к => 9397716 пъти => 3,62%
п => 8942733 пъти => 3,45%
д => 7756814 пъти => 2,99%
м => 5906208 пъти => 2,28%
б => 5726892 пъти => 2,21%
г => 4740094 пъти => 1,83%
з => 4382215 пъти => 1,69%
я => 4367464 пъти => 1,68%
ъ => 3673393 пъти => 1,42%
у => 3623023 пъти => 1,40%
ч => 2484600 пъти => 0,96%
ц => 2333927 пъти => 0,90%
й => 1696822 пъти => 0,65%
ж => 1533117 пъти => 0,59%
ф => 1517443 пъти => 0,58%
х => 1108573 пъти => 0,43%
щ => 1062451 пъти => 0,41%
ш => 1033321 пъти => 0,40%
ю => 516766 пъти => 0,20%
ь => 165126 пъти => 0,06%
Общо: 259452643 букви
на => 2299352 пъти
и => 1228974 пъти
в => 1155405 пъти
потребител => 972950 пъти
е => 843001 пъти
от => 771623 пъти
за => 541691 пъти
се => 534455 пъти
пр => 502970 пъти
беседа => 488892 пъти
б => 478232 пъти
специални => 475226 пъти
приноси => 458098 пъти
с => 415268 пъти
да => 360815 пъти
г => 357602 пъти
категория => 329792 пъти
по => 311804 пъти
през => 268270 пъти
са => 205503 пъти
като => 187945 пъти
а => 157099 пъти
си => 148075 пъти
не => 142846 пъти
година => 140927 пъти
до => 131248 пъти
българия => 120406 пъти
шаблон => 118392 пъти
че => 111265 пъти
след => 108299 пъти
име => 108121 пъти
това => 102096 пъти
му => 100706 пъти
при => 96585 пъти
най => 94397 пъти
към => 92054 пъти
български => 88771 пъти
език => 88496 пъти
или => 85181 пъти
картинка => 84771 пъти
флаг => 81194 пъти
има => 77141 пъти
които => 76721 пъти
но => 75737 пъти
дата => 71732 пъти
място => 70713 пъти
той => 69956 пъти
софия => 68527 пъти
който => 68059 пъти
мъниче => 67803 пъти
град => 66775 пъти
н => 66245 пъти
роден => 65361 пъти
те => 64738 пъти
община => 63671 пъти
във => 63266 пъти
област => 60594 пъти
икона => 60303 пъти
време => 57472 пъти
години => 56731 пъти
македония => 55292 пъти
война => 54894 пъти
част => 53917 пъти
виж => 53028 пъти
век => 52999 пъти
население => 52339 пъти
което => 50802 пъти
село => 50443 пъти
която => 50163 пъти
със => 49840 пъти
много => 48210 пъти
сащ => 46604 пъти
описание => 46483 пъти
други => 45956 пъти
може => 45390 пъти
окръг => 44525 пъти
код => 44177 пъти
уикипедия => 43859 пъти
препратки => 43822 пъти
един => 42952 пъти
история => 42765 пъти
външни => 42401 пъти
също => 41582 пъти
американски => 41546 пъти
този => 41256 пъти
вид => 40615 пъти
всички => 40306 пъти
около => 40125 пъти
та => 39540 пъти
между => 39029 пъти
отбор => 38536 пъти
още => 38478 пъти
починал => 37560 пъти
карта => 36234 пъти
група => 36152 пъти
инфо => 36071 пъти
страна => 36061 пъти
селото => 35585 пъти
само => 35239 пъти
го => 35147 пъти
Първите няколко думи, както се очаква, са предимно предлози и съюзи, тъй като и по принцип това са си най-използваните думички в българския език. Измежду тях се вмъква „пр“. Стана ми интересно от къде идват тези над 500000 срещания на тези 2 букви. Оказа се, че в Wikipedia доста често се срещат съкращенията „пр.н.е.“ и „пр.Хр.“, което изтласква „пр“ в челните места. Думите „потребител“, „беседа“, „специални“, „приноси“, „категория”, „шаблон“, „мъниче“ и „картинка“ са основни за Wikipedia и това обяснява честото им срещане в статиите. Отделните букви „б“ и „г“ идват от съкращения (на имена „Б.“ и съкращението „г.“ – година). Доста често срещани са думите „България“, „български“, „език“, „година“, „дата“, „място“, „София“, „град“, „роден“, „община“, „област“, „икона“, „време“, „война“. Прави впечатление доста честото срещане на „Македония“, „САЩ“ и „американски“ в българските статии.
Прикачил съм текстов файл с пълния списък от всички 714876 намерени думи в българската Wikipedia. Форматът на файла е следният: на всеки ред има дума и нейния брой срещания, разделени със празен символ (space). Файлът е сортиран по броя срещания на всяка дума в намаляващ ред. Кодировката на файла е „UTF-8 without BOM”, което означава, че най-вероятно ще трябва ръчно да изберете UTF-8 кодировка, ако отваряте файла с някой неграмотен текстов редактор ;) Можете да свалите файла като кликнете тук или на голямата картинка отляво. Приятно четене на думички! Можете да използвате списъка, за да научите някоя нова думичка. Упражнение за ентусиасти.
Следва списък с първите 550 най-срещани думи в българската Wikipedia, подредени по брой срещания:
на, и, в, потребител, е, от, за, се, пр, беседа, б, специални, приноси, с, да, г, категория, по, през, са, като, а, си, не, година, до, българия, шаблон, че, след, име, това, му, при, най, към, български, език, или, картинка, флаг, има, които, но, дата, място, той, софия, който, мъниче, град, н, роден, те, община, във, област, икона, време, години, македония, война, част, виж, век, население, което, село, която, със, много, сащ, описание, други, може, окръг, код, уикипедия, препратки, един, история, външни, също, американски, този, вид, всички, около, та, между, отбор, още, починал, карта, група, инфо, страна, селото, само, го, п, м, става, английски, то, под, така, според, ще, източници, както, германия, република, май, август, една, файл, когато, юли, септември, биография, франция, тази, империя, юни, ширина, иван, р, височина, октомври, януари, март, където, души, намира, стр, голяма, ноември, тя, срещу, мини, им, т, април, георги, щати, награда, декември, център, тези, него, площ, футбол, портрет, над, река, км, италия, името, ако, национален, февруари, няколко, съединени, късно, жители, започва, някои, преди, сайт, българска, държава, фк, русия, тях, края, димитър, началото, световна, бъде, две, населението, градове, града, път, край, днес, без, портал, гърция, трябва, селище, състав, заедно, няма, първата, александър, дължина, район, бил, пояснение, бележки, страница, англия, върху, първенство, дем, официален, страната, македоно, регион, провинция, страници, често, филм, европа, я, поради, села, армия, вече, повече, какво, различни, литература, университет, сезон, петър, сорткат, хора, министър, българи, чрез, д, съюз, партия, география, васил, консул, българската, въпреки, два, малко, дясно, система, испания, к, наставка, света, три, данни, едно, северна, футболист, могат, албум, вижте, герб, друго, използва, южна, ги, смъртта, работи, получава, у, сайта, били, организация, статия, св, имат, българско, участва, първи, втората, ти, списък, френски, пфк, там, руски, сред, заглавие, музика, ден, римски, политик, църква, христо, прави, завършва, обаче, управление, формула, марк, пловдив, стефан, училище, информация, общо, никола, др, първа, филми, тук, места, отново, император, член, актьор, генерал, всеки, статистика, син, джон, района, свети, ми, великобритания, части, немски, надразделение, пост, левски, нова, нея, период, все, писател, тип, времето, резултат, тъй, групата, ист, втора, например, известен, освен, бразилия, начин, де, сили, аз, баща, първият, добре, първите, голям, съм, живот, купа, море, крал, превод, докато, мария, пощенски, деца, насам, шаблони, дни, рим, личности, пренасочване, гръцки, революционер, автор, дори, битка, ксн, подс, сочи, своя, защото, нови, връзка, главно, тогава, брой, събития, николай, сърбия, първо, страни, ню, гр, африка, швеция, гео, председател, остров, раждане, уеб, отбори, статии, луций, бъдат, право, варна, била, белгия, семейство, би, човек, култура, лига, умира, планина, имена, играе, против, надморска, езици, обикновено, двете, води, сан, америка, стадион, политика, периода, стара, разположение, големи, почти, актьори, о, фон, дивизия, уебсайт, заради, пред, режисьор, кръг, ссср, опълчение, щата, договор, войната, отбора, номер, щат, текст, представка, голямата, западна, било, острови, групи, световен, борис, голове, награди, значение, първия, печели, изтриване, османската, римска, позиция, михаил, год, остава, ли, цар, цска, статут, статията, полша, малки, областта, играч, москва, съвет, телефонен, работа, игри, президент, всяка, турция, историята, север, пъти, константин, румъния, гай, препратка, япония, австралия, цел, мача, италиански, стил, египет, изток, й, видове, повечето, род, жени, шампион, въстание, известни, треньор, минути, австрия, шампионат, селища, дава, включва, поле, участие, унгария, степен, тел, манастир, среща, азия, втори, вода, таблицата, административен, родени, нов, използват, етнография, николов, хората, карл, друг, църквата, песен, региона, калифорния, продължава, ред, вероятно, разположен, особено, вморо, живота, пише, сега, исторически, книга, футболисти, своята, власт.