PHP, 326 320 318318 315 chars
$h=array(qs,vhn,vxf,sefx,wrd,drgc,fthv,gyjb,uko,hukn,jilm,ok,nk,bjm,ilp,o,aw,etf,awdz,rgy,yji,cgb,qse,zdc,thu,sx);$a=x.$argv[1];for(;$d=$a[++$b];)echo!rand(0,9)&&($c=ord($d)-65)?(!($g=rand(0,($e=($c>-1&&$c<26)or$c>31&&$c<58)+1))?$d.$d:($g<2?"":(($j=$i[rand(0,strlen($i=$h[$c-($e?0:32)]!$e*32]))])&&$e?strtoupper($j):$j))):$d;
// $a input
// $b char iterator
// $c current char ascii value
// $d current char
// $e is uppercase
// $g rand() output
// $h char displacement
// $i current character in $h
// $j temporary var for uppercasing
// the neighbouring characters of a-z, in alphabetical (and ASCII) order
$h=array(qs,vhn,vxf,sefx,wrd,
drgc,fthv,gyjb,uko,hukn,
jilm,ok,nk,bjm,ilp,
o,aw,etf,awdz,rgy,
yji,cgb,qse,zdc,thu,
sx);
// input from argument
$a=x.$argv[1];
for(;$d=$a[++$b];)
echo!rand(0,9)&&($c=ord($d)-65)? /* 10% chance, read char ASCII value - 65 into $c */
(!($g=rand(0,($e=($c>-1&&$c<26)or$c>31&&$c<58)+1))?
/* random number from 0 to 2 (if alphabetic) or 0 to 1 stored in $g */
$d.$d: /* double char if $g = 0 */
($g<2?
"": /* omit char if $g = 1*/
(($j=$i[rand(0,strlen($i=$h[$c-($e?0:32)]!$e*32]))])&&$e?
/* $j = random neighbour of the current char */
strtoupper($j): /* uppercase $j */
$j)))
:$d; /* keep char */
-2, -3 thanks to Ismael Miguel