Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет deadbeef ([info]deadbeef)
@ 2004-11-21 07:10:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Вот, сотворил. Может полезно будет.
Сотворил простейшую и кратчайшую программку, которая может помочь людям русским, в одном мутном деле.
Иногда, возникает подозрение, что под разными именами в инете пишет один и тот же человек. Это подозрение бывает достаточно сложно проверить, однако и на такую хитрую задницу с лабиринтом, найдётся русский лом.


Нижеприведённая программка делает очень простую вещь - считает, сколько в тексте есть разных буквосочетаний. Из соображений скорости и простоты она учитывает только 512 наиболее распространённых в русском языке буквосочетаний. На выходе получаем простой список из 512 относительных величин в экспоненциальном формате - количество буквосочетаний одного типа отнесённое к общему количеству буквосочетаний. Теперь остаётся только загнать этот список в какую-нибудь программку для построения графиков, чтобы она нарисовала нам спектр текста (я пользую gnuplot).
А главное, и самое интересное, что этот самый спектр текста будет почти одинаков для разных текстов одного автора и будет отличаться для текстов разных авторов. Нарисовав в одном графике спектры для двух текстов, мы без особого труда можем определить, принадлежат ли тексты разным людям, или они были написаны одним человеком (ну или нелюдем). Тексты, правда, должны быть достаточно длинными, чтобы дать спектр действительно характерный для изучаемого автора - книга, например, или собранные в один файл сотни комментариев.

Вот, например, участок спектра с 100-го по 200-е буквосочетания для двух разных кусков Лукьяненки:
Image

А вот, тот же участок для Лукьяненки и Неведимова (Лукьяненка - красный):
Image

Посмотрев на картинки, разобраться, что на первой картинке - автор один, а на второй - авторы разные, не так уж и сложно.


#include <locale.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <getopt.h>

#define SLOG_COUNT  (512)

char *slog[SLOG_COUNT] = {
"ст","то","ен","но","ни","ов","на","ра","ос","пр","ро","ко","ан","ли","по","во",
"ес","ре","не","от","ол","од","ор","ть","ва","го","ер","ит","ет","ти","об","ел",
"он","та","ри","ль","ны","те","ал","ат","де","ка","ом","ис","тв","ве","ин","ие",
"ло","ми","со","ав","ог","ме","ем","ия","им","ле","ас","из","ив","ла","ак","че",
"мо","да","ии","ед","за","тр","ой","ск","ар","нн","до","ки","ам","оп","ил","ик",
"ви","бо","ма","тс","ьн","ся","ев","аз","оз","ек","ир","же","ои","бы","си","ег",
"ич","ци","вс","еп","ап","зн","ди","ад","ид","ип","сл","вы","вн","ру","ля","ые",
"ей","ое","ок","се","их","оч","вл","ож","ят","хо","эт","пе","тн","ых","ры","уд",
"чт","ио","ще","ку","аб","дн","сп","ьс","ео","ая","чи","ий","му","св","ги","ду",
"ае","йс","це","нт","ча","ше","оо","лю","сс","ют","вр","яв","жн","уп","ез","ус",
"зв","ым","ыл","мы","кр","ян","ну","ее","па","иа","еб","ую","аи","нс","са","ьк",
"га","иг","ыв","еи","еч","кт","жи","аж","ты","ый","уч","ут","ту","иб","яс","мн",
"ач","су","чн","яп","ыс","зм","бе","дл","зо","ац","сь","пи","мп","лу","дс","ах",
"ын","бр","ям","ня","ур","щи","гр","яз","ун","бщ","жд","еж","аю","ши","уж","ыт",
"нк","нь","бу","зд","тк","вп","ьв","яи","гл","йн","сн","вт","би","мс","ды","ук",
"ып","др","ул","зи","рн","вк","кл","ао","хр","ех","кс","юд","ию","аг","тп","уг",
"пл","ву","ьп","ув","бл","см","йв","йп","яо","ьт","як","мв","ьш","ьи","хи","ёт",
"иц","фи","ря","яд","ср","ум","ба","йи","рс","вв","вя","рт","хс","рм","яе","оц",
"жа","ью","оя","йт","иу","гд","ке","нц","ыи","нд","ош","йк","ущ","дв","ау","мм",
"оу","ющ","ша","рп","хп","ьм","лл","эк","зы","бс","иж","рк","уб","мк","вм","тд",
"кн","хв","ык","еа","ьо","рв","ай","уе","еш","ьз","ох","зк","кв","вд","ён","хн",
"яр","аш","ыо","фо","йм","сч","еу","лн","зу","ец","ащ","пу","ца","рг","ьд","оэ",
"зр","йо","тт","мч","йд","ял","лж","иф","ьг","ыр","кп","ыд","гу","чё","йр","иэ",
"вг","мя","юб","хк","яч","ьб","тя","ыш","чк","зе","уи","кц","ыч","ыб","ещ","лы",
"яб","оф","мб","ях","сё","юс","бн","тм","ём","вз","сы","ха","пы","уа","лс","шл",
"рь","сх","рж","рд","нг","хт","рх","сд","ух","мд","ьч","яю","ье","уш","уз","ща",
"ге","еф","аэ","фр","бъ","дя","тч","тб","мт","км","уо","мл","ьр","йб","вш","юп",
"фе","йч","тл","яу","нв","мр","юв","еэ","дё","яц","ыз","сш","дп","аа","ья","зя",
"юч","иш","дь","ху","яэ","бм","гн","кд","шн","вб","хд","йз","ящ","ъе","фа","хл",
"ёр","её","хм","дк","аф","ою","лк","лг","цы","юи","йг","вэ","бх","хг","ьл","ощ",
"зл","яг","йц","щё","оа","тз","ея","юз","аё","бя","ыу","кк","вц","нп","юо","лё",
"чу","нф","чш","йш","ьу","йэ","йа","юр","юн","юк","мг","юц","шк","пн","ыг","мз",
};

int spectrum[SLOG_COUNT];

void usage(char *name)
{
	printf("Usage: %s [--verbose] [--help] [file]\n", name);
}
   
int main(int argc, char *argv[]) {
 char                   c1 = 0, c2 = 0, buf[256], *src, *prog;
 int                    ret, i, verbose = 0, count = 0;
 FILE			*fd;
 static struct option   long_options[] =
 {
   {"verbose", no_argument,       0, 'v'},
   {"help",    no_argument,       0, 'h'},
   {0, 0, 0, 0}
 };

	setlocale(LC_ALL, "" );

	prog = strrchr(argv[0],'/');
	if(!prog) prog = argv[0];
	else      prog++;

	while ((ret = getopt_long (argc, argv, "vh", long_options, NULL)) != -1)
	{
		switch(ret)
		{
			case 'v': verbose = 1; break;
			case 'h': usage(prog); break;
			default: usage(prog); return 1;
		}
	}

	if(verbose) printf("Cleaning spectrum...\n");

	for(i = 0; i < SLOG_COUNT; i++) spectrum[i] = 0;

	if(argc > optind)
	{
		if(verbose) printf("Reading file %s\n",argv[optind]);
		fd = fopen(argv[optind],"r");
	}
	else
	{
		if(verbose) printf("Reading stdin\n");
		fd = stdin;
	}

	while(fgets(buf,sizeof(buf),fd))
	{
		src = buf;
		while(*src)
		{
			c2 = tolower(*src);
			if(c1 && isalpha(c2))
			{
				for(i = 0; i < SLOG_COUNT; i++)
				{
					if(slog[i][0] == c1 && slog[i][1] == c2)
					{
	        				spectrum[i]++;
	        				count++;
						break;
					}
				}
			}
			c1 = c2;
			src++;
		}
	}

	if(count > 0) 
	{
		for(i = 0; i < SLOG_COUNT; i++)
		{
			printf("%e # %s\n", (double)spectrum[i] / (double)count, slog[i]);
		}
	}

	if(fd != stdin) fclose(fd);

	return 0;
}


Вот собственно и всё.

Программка читает либо стандартный ввод, либо файл, если он указан в качестве аргумента. Выдаёт результат на терминал, ну или куда там перенаправишь - в файл, например. А можно сразу скормить рисовалке графиков.

Клоны могут отдыхать.
Лицензия - GNU, автор - я.



(Читать комментарии) - (Добавить комментарий)


[info]trankov@lj
2004-11-21 19:03 (ссылка)
Я всё понимаю, конечно. Только я ведь тоже могу картинки выкладывать в битмапе цифровом.

Си-компиляторы далеко не у всех есть. Мне вот, к примеру, совершенно ломает качать и ставить.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]vchk@lj
2004-11-21 19:24 (ссылка)
Ну нету компилятора и ладно, в чём проблема-то?

Ах програмка заинтересовала? Тогда извольте установить нормальную систему и нормальный компилятор. Или потрахаться с ненормальной системой и ненормальным компилятором. Такие правила.

Вы же не возмущаетесь, что в магазине Вам без денег хлеба не дадут. Даже в голову не придёт сказать продавцу - "дайте мне хлеба просто так, потому что меня ломает деньги зарабатывать". А тут почему-то вынь, да положь.

ЗЫ: Картинки, чтоб Вы знали - выложены в совершенно обычном формате GIF, а не в каком-то там битмапе.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]trankov@lj
2004-11-21 19:31 (ссылка)
1. я про свои картинки. к примеру типа.
2. сопоставление неуместное. деньги вещь универсальная, компилятор - специфическая.
3. у вас пост о чём, о методах анализа текста или о программировании? если о первом, то непрограммеры обсудить тему не смогут. если о втором, то графики неуместны.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]vchk@lj
2004-11-21 19:41 (ссылка)
1. Ну и выкладывайте. Ваши картинки - что угодно с ними делайте.
2. Сопоставление какое есть. Считаете его неуместным - считайте, не вопрос.
3. Пост у меня с предложением совершенно конкретного, практического и простого решения проблемы определения авторства текстов. С описанием принципа, наглядными примерами и текстом программы. Всё.
Мнения неких "специалистов в области анализа текстов", которые не способны собрать простейшую программку, меня не интересуют вообще, в связи с их заведомой некомпетентностью.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]trankov@lj
2004-11-21 19:46 (ссылка)
Хе-хе. Принцип-то Ваш гавённенький, много раз залажанный и не нов совсем, компетентный Вы наш. Спецыалист, хе-хе.

Программку Вашу я кстати прекрасно прочитал, не Бог весть что. Уровень начала XX века Ваш метод. Заявите его на Нобелевскую премию.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]vchk@lj
2004-11-21 19:55 (ссылка)
Ну конечно же гавённенький. Даже до древнючих цепей Маркова не дотягивает - ещё более тупой и простой.

Только вот он принцип, вот пример, и вот программка. Всё доступно и работает. Бери и пользуй.

А где другие, не гавённенькие, более новые принципы реализованные в программах, которые можно взять вот прямо и использовать? А может Вы чем-то похвастаетесь, критик любезный? Программку продемонстрируете, может, сравним, у кого лучше работат и надёжнее?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]trankov@lj
2004-11-21 19:58 (ссылка)
(как бы к слову) Сюжет очень волнующий...

(Ответить) (Уровень выше)


[info]vchk@lj
2004-11-21 19:30 (ссылка)
И потом - вот Вы даже не задумались - а что у меня за ОС? а какая версия? а что если у меня вообще не x86 ?
Ну соберу я бинарник под Альфу. А дальше что Вы с ним делать будете???

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]trankov@lj
2004-11-21 19:34 (ссылка)
Вы тему-то какую обсудить хотите?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]vchk@lj
2004-11-21 19:44 (ссылка)
Обсудить что-то хотите тут Вы. Совершенно необдуманно предлагаете весьма дебильные вещи (скомпилировать и выложить бинарник) и ещё возмущаетесь тем, что я такие предложения не принимаю.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]trankov@lj
2004-11-21 19:48 (ссылка)
Я Ваш бинарник раком в попу тыкал. Да ведь?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]vchk@lj
2004-11-21 19:58 (ссылка)
Вот уж не знаю, как у вас там в солнечном Техасе принято с бинарниками обращаться...

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]trankov@lj
2004-11-21 20:01 (ссылка)
(в сторону) Вы что ж, против эксперимента? «Не тужьтесь, мои дорогие, над формой, не напрягайтесь»...

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]vchk@lj
2004-11-21 20:05 (ссылка)
Эксперименты по засовыванию бинарников в жопу проводите сами.
Меня такие ебанутые эксперименты не интересуют вообще.
Я, знаете ли, гнушаюсь.

(Ответить) (Уровень выше)


(Читать комментарии) -